NEW: release DJI Payload-SDK version 3.1

Signed-off-by: DJI-Martin <DJI-Martin@dji.com>
This commit is contained in:
DJI-Martin
2022-03-21 22:25:37 +08:00
parent 7b5f853e87
commit 0e06bc3fd3
62 changed files with 9042 additions and 348 deletions

View File

@ -1234,7 +1234,8 @@ T_DjiReturnCode DjiTest_CameraEmuBaseStartService(void)
returnCode = DjiPayloadCamera_Init();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("payload camera init error:0x%08llX", returnCode);
USER_LOG_ERROR("init payload camera error:0x%08llX", returnCode);
return returnCode;
}
/* Init the SDcard parameters */

View File

@ -51,6 +51,8 @@ static const T_DjiTestCameraTypeStr s_cameraTypeStrList[] = {
{DJI_CAMERA_TYPE_H20T, "Zenmuse H20T"},
{DJI_CAMERA_TYPE_P1, "Zenmuse P1"},
{DJI_CAMERA_TYPE_L1, "Zenmuse L1"},
{DJI_CAMERA_TYPE_M30, "Zenmuse M30"},
{DJI_CAMERA_TYPE_M30T, "Zenmuse M30T"},
};
static FILE *s_downloadMediaFile = NULL;

View File

@ -48,10 +48,9 @@ static T_DjiReturnCode ReceiveDataFromPayload(const uint8_t *data, uint16_t len)
/* Private variables ---------------------------------------------------------*/
static T_DjiTaskHandle s_userDataTransmissionThread;
static T_DjiAircraftInfoBaseInfo s_aircraftInfoBaseInfo;
static DjiTestDataTransmissionConfig s_dataTransmissionConfig = {0};
/* Exported functions definition ---------------------------------------------*/
T_DjiReturnCode DjiTest_DataTransmissionStartService(DjiTestDataTransmissionConfig config)
T_DjiReturnCode DjiTest_DataTransmissionStartService(void)
{
T_DjiReturnCode djiStat;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
@ -61,8 +60,6 @@ T_DjiReturnCode DjiTest_DataTransmissionStartService(DjiTestDataTransmissionConf
char ipAddr[DJI_IP_ADDR_STR_SIZE_MAX];
uint16_t port;
memcpy(&s_dataTransmissionConfig, &config, sizeof(DjiTestDataTransmissionConfig));
djiStat = DjiLowSpeedDataChannel_Init();
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("init data transmission module error.");
@ -179,20 +176,20 @@ static void *UserDataTransmission_Task(void *arg)
USER_LOG_ERROR("get send to onboard computer channel state error.");
}
if (s_dataTransmissionConfig.isEnableHighSpeedDataChannel == true) {
djiStat = DjiHighSpeedDataChannel_SendDataStreamData(dataToBeSent, sizeof(dataToBeSent));
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
USER_LOG_ERROR("send data to data stream error.");
#ifdef SYSTEM_ARCH_LINUX
djiStat = DjiHighSpeedDataChannel_SendDataStreamData(dataToBeSent, sizeof(dataToBeSent));
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
USER_LOG_ERROR("send data to data stream error.");
djiStat = DjiHighSpeedDataChannel_GetDataStreamState(&state);
if (djiStat == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_DEBUG(
"data stream state: realtimeBandwidthLimit: %d, realtimeBandwidthBeforeFlowController: %d, busyState: %d.",
state.realtimeBandwidthLimit, state.realtimeBandwidthBeforeFlowController, state.busyState);
} else {
USER_LOG_ERROR("get data stream state error.");
}
djiStat = DjiHighSpeedDataChannel_GetDataStreamState(&state);
if (djiStat == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_DEBUG(
"data stream state: realtimeBandwidthLimit: %d, realtimeBandwidthBeforeFlowController: %d, busyState: %d.",
state.realtimeBandwidthLimit, state.realtimeBandwidthBeforeFlowController, state.busyState);
} else {
USER_LOG_ERROR("get data stream state error.");
}
#endif
} else if (s_aircraftInfoBaseInfo.mountPosition == DJI_MOUNT_POSITION_EXTENSION_PORT) {
channelAddress = DJI_CHANNEL_ADDRESS_PAYLOAD_PORT_NO1;
djiStat = DjiLowSpeedDataChannel_SendData(channelAddress, dataToBeSent, sizeof(dataToBeSent));

View File

@ -38,13 +38,10 @@ extern "C" {
/* Exported types ------------------------------------------------------------*/
typedef struct {
bool isEnableLowSpeedDataChannel;
bool isEnableHighSpeedDataChannel;
} DjiTestDataTransmissionConfig;
/* Exported functions --------------------------------------------------------*/
T_DjiReturnCode DjiTest_DataTransmissionStartService(DjiTestDataTransmissionConfig config);
T_DjiReturnCode DjiTest_DataTransmissionStartService(void);
#ifdef __cplusplus
}

View File

@ -147,7 +147,7 @@ T_DjiReturnCode DjiTest_FcSubscriptionRunSample(void)
USER_LOG_INFO("--> Step 3: Get latest value of the subscribed topics in the next 20s\r\n");
for (int i = 0; i < 20; ++i) {
for (int i = 0; i < 10; ++i) {
osalHandler->TaskSleepMs(1000 / FC_SUBSCRIPTION_TASK_FREQ);
djiStat = DjiFcSubscription_GetLatestValueOfTopic(DJI_FC_SUBSCRIPTION_TOPIC_VELOCITY,
(uint8_t *) &velocity,

View File

@ -127,6 +127,12 @@ T_DjiReturnCode DjiTest_GimbalStartService(void)
s_commonHandler.Reset = Reset;
s_commonHandler.FineTuneAngle = FineTuneAngle;
djiStat = DjiFcSubscription_Init();
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("init data subscription module error.");
return djiStat;
}
if (osalHandler->MutexCreate(&s_commonMutex) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mutex create error");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
@ -145,11 +151,13 @@ T_DjiReturnCode DjiTest_GimbalStartService(void)
djiStat = DjiGimbal_Init();
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("init gimbal module error: 0x%08llX", djiStat);
return djiStat;
}
djiStat = DjiGimbal_RegCommonHandler(&s_commonHandler);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("gimbal register common handler error: 0x%08llX", djiStat);
return djiStat;
}
if (osalHandler->TaskCreate("user_gimbal_task", UserGimbal_Task,
@ -379,6 +387,14 @@ static void *UserGimbal_Task(void *arg)
USER_UTIL_UNUSED(arg);
djiStat = DjiFcSubscription_SubscribeTopic(DJI_FC_SUBSCRIPTION_TOPIC_QUATERNION, DJI_DATA_SUBSCRIPTION_TOPIC_10_HZ,
NULL);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Subscribe topic quaternion error.");
} else {
USER_LOG_DEBUG("Subscribe topic quaternion success.");
}
while (1) {
osalHandler->TaskSleepMs(1000 / PAYLOAD_GIMBAL_TASK_FREQ);
step++;

View File

@ -78,7 +78,6 @@ T_DjiReturnCode DjiTest_GimbalManagerRunSample(E_DjiMountPosition mountPosition,
returnCode = DjiGimbalManager_Rotate(mountPosition, rotation);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Target gimbal pry = (30, 0, 0) failed, error code: 0x%08X", returnCode);
goto out;
}
osalHandler->TaskSleepMs(1000);
@ -88,7 +87,6 @@ T_DjiReturnCode DjiTest_GimbalManagerRunSample(E_DjiMountPosition mountPosition,
returnCode = DjiGimbalManager_Rotate(mountPosition, rotation);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Target gimbal pry = (0, 30, 0) failed, error code: 0x%08X", returnCode);
goto out;
}
osalHandler->TaskSleepMs(1000);
@ -97,7 +95,6 @@ T_DjiReturnCode DjiTest_GimbalManagerRunSample(E_DjiMountPosition mountPosition,
returnCode = DjiGimbalManager_Rotate(mountPosition, rotation);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Target gimbal pry = (0, 0, 30) failed, error code: 0x%08X", returnCode);
goto out;
}
osalHandler->TaskSleepMs(1000);
@ -105,7 +102,6 @@ T_DjiReturnCode DjiTest_GimbalManagerRunSample(E_DjiMountPosition mountPosition,
returnCode = DjiGimbalManager_Reset(mountPosition);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Reset gimbal failed, error code: 0x%08X", returnCode);
goto out;
}
osalHandler->TaskSleepMs(2000);
}
@ -119,7 +115,6 @@ T_DjiReturnCode DjiTest_GimbalManagerRunSample(E_DjiMountPosition mountPosition,
returnCode = DjiGimbalManager_Rotate(mountPosition, rotation);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Target gimbal pry = (30, 0, 0) failed, error code: 0x%08X", returnCode);
goto out;
}
osalHandler->TaskSleepMs(1000);
@ -129,7 +124,6 @@ T_DjiReturnCode DjiTest_GimbalManagerRunSample(E_DjiMountPosition mountPosition,
returnCode = DjiGimbalManager_Rotate(mountPosition, rotation);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Target gimbal pry = (0, 30, 0) failed, error code: 0x%08X", returnCode);
goto out;
}
osalHandler->TaskSleepMs(1000);
@ -138,7 +132,6 @@ T_DjiReturnCode DjiTest_GimbalManagerRunSample(E_DjiMountPosition mountPosition,
returnCode = DjiGimbalManager_Rotate(mountPosition, rotation);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Target gimbal pry = (0, 0, 30) failed, error code: 0x%08X", returnCode);
goto out;
}
osalHandler->TaskSleepMs(1000);
@ -146,7 +139,6 @@ T_DjiReturnCode DjiTest_GimbalManagerRunSample(E_DjiMountPosition mountPosition,
returnCode = DjiGimbalManager_Reset(mountPosition);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Reset gimbal failed, error code: 0x%08X", returnCode);
goto out;
}
osalHandler->TaskSleepMs(2000);
}

View File

@ -78,7 +78,7 @@ T_DjiReturnCode DjiTest_HmsRunSample(void)
goto out;
}
osalHandler->TaskSleepMs(30000);
osalHandler->TaskSleepMs(10000);
out:
USER_LOG_INFO("--> Step 3: Deinit hms sample");

View File

@ -0,0 +1,161 @@
/**
********************************************************************
* @file test_waypoint_v3.c
* @brief
*
* @copyright (c) 2018 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJIs authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <utils/util_file.h>
#include <utils/util_misc.h>
#include "test_waypoint_v3.h"
#include "dji_logger.h"
#include "dji_waypoint_v3.h"
#include "waypoint_file_c/waypoint_v3_test_file_kmz.h"
/* Private constants ---------------------------------------------------------*/
#define DJI_TEST_WAYPOINT_V3_KMZ_FILE_PATH_LEN_MAX (256)
/* Private types -------------------------------------------------------------*/
/* Private values -------------------------------------------------------------*/
/* Private functions declaration ---------------------------------------------*/
static T_DjiReturnCode DjiTest_WaypointV3StateCallback(T_DjiWaypointV3MissionState missionState);
/* Exported functions definition ---------------------------------------------*/
T_DjiReturnCode DjiTest_WaypointV3RunSample(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
#ifdef SYSTEM_ARCH_LINUX
FILE *kmzFile;
uint32_t kmzFileSize = 0;
uint8_t *kmzFileBuf;
uint16_t readLen;
char curFileDirPath[DJI_TEST_WAYPOINT_V3_KMZ_FILE_PATH_LEN_MAX];
char tempPath[DJI_TEST_WAYPOINT_V3_KMZ_FILE_PATH_LEN_MAX];
returnCode = DjiWaypointV3_Init();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Waypoint v3 init failed.");
return returnCode;
}
returnCode = DjiWaypointV3_RegMissionStateCallback(DjiTest_WaypointV3StateCallback);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Register waypoint v3 state callback failed.");
goto out;
}
returnCode = DjiUserUtil_GetCurrentFileDirPath(__FILE__, DJI_TEST_WAYPOINT_V3_KMZ_FILE_PATH_LEN_MAX,
curFileDirPath);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Get file current path error, stat = 0x%08llX", returnCode);
goto out;
}
/*! Attention: suggest use the exported kmz file by DJI pilot. If use this test file, you need set the longitude as
* 113.94755, latitude as 22.51853 on DJI Assistant 2 simulator */
snprintf(tempPath, DJI_TEST_WAYPOINT_V3_KMZ_FILE_PATH_LEN_MAX, "%s/waypoint_file/waypoint_v3_test_file.kmz",
curFileDirPath);
kmzFile = fopen(tempPath, "r");
if (kmzFile == NULL) {
USER_LOG_ERROR("Open kmz file failed.");
goto out;
}
returnCode = UtilFile_GetFileSize(kmzFile, &kmzFileSize);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Get kmz file size failed.");
goto out;
}
kmzFileBuf = osalHandler->Malloc(kmzFileSize);
if (kmzFileBuf == NULL) {
USER_LOG_ERROR("Malloc kmz file buf error.");
goto out;
}
readLen = fread(kmzFileBuf, 1, kmzFileSize, kmzFile);
if (readLen != kmzFileSize) {
USER_LOG_ERROR("Read kmz file data failed.");
goto out;
}
returnCode = DjiWaypointV3_UploadKmzFile(kmzFileBuf, kmzFileSize);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Upload kmz file failed.");
goto out;
}
osalHandler->Free(kmzFileBuf);
#else
returnCode = DjiWaypointV3_UploadKmzFile(waypoint_v3_test_file_kmz_fileBinaryArray,
waypoint_v3_test_file_kmz_fileSize);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Upload kmz file failed.");
goto out;
}
#endif
USER_LOG_INFO("Execute start action");
returnCode = DjiWaypointV3_Action(DJI_WAYPOINT_V3_ACTION_START);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Execute start action failed.");
goto out;
}
for (int i = 0; i < 30; ++i) {
osalHandler->TaskSleepMs(1000);
}
USER_LOG_INFO("Execute pause action");
returnCode = DjiWaypointV3_Action(DJI_WAYPOINT_V3_ACTION_PAUSE);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Execute start action failed.");
goto out;
}
for (int i = 0; i < 5; ++i) {
osalHandler->TaskSleepMs(1000);
}
USER_LOG_INFO("Execute resume action");
returnCode = DjiWaypointV3_Action(DJI_WAYPOINT_V3_ACTION_RESUME);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Execute start action failed.");
goto out;
}
out:
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/* Private functions definition-----------------------------------------------*/
static T_DjiReturnCode DjiTest_WaypointV3StateCallback(T_DjiWaypointV3MissionState missionState)
{
USER_LOG_INFO("Waypoint v3 mission state: %d, current waypoint index: %d, wayLine id: %d", missionState.state,
missionState.currentWaypointIndex, missionState.wayLineId);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/

View File

@ -0,0 +1,49 @@
/**
********************************************************************
* @file test_waypoint_v3.h
* @brief This is the header file for "test_waypoint_v3.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2018 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJIs authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef TEST_WAYPOINT_V3_H
#define TEST_WAYPOINT_V3_H
/* Includes ------------------------------------------------------------------*/
#include "dji_typedef.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
T_DjiReturnCode DjiTest_WaypointV3RunSample(void);
#ifdef __cplusplus
}
#endif
#endif // TEST_WAYPOINT_V3_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/

View File

@ -0,0 +1,245 @@
/* Generated by file2c, do not edit manually */
#ifndef __waypoint_v3_test_file_kmz_h_included
#define __waypoint_v3_test_file_kmz_h_included
#include <stdint.h>
/* Contents of file waypoint_v3_test_file.kmz */
#define waypoint_v3_test_file_kmz_fileName "waypoint_v3_test_file.kmz"
#define waypoint_v3_test_file_kmz_fileSize 3690
static const uint8_t waypoint_v3_test_file_kmz_fileBinaryArray[3690] = {
0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xA8,
0x54, 0x6C, 0xA8, 0x06, 0x00, 0x00, 0xD9, 0x59, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x77, 0x70,
0x6D, 0x7A, 0x2F, 0x74, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65, 0x2E, 0x6B, 0x6D, 0x6C, 0xED,
0x9C, 0x6D, 0x6F, 0xDB, 0x36, 0x10, 0xC7, 0xDF, 0xF7, 0x53, 0x04, 0x79, 0xDD, 0xC5, 0xBC, 0x23,
0x8F, 0x0F, 0x85, 0xEB, 0xA2, 0xE8, 0x33, 0xB0, 0xA1, 0xC1, 0x9C, 0x2D, 0xAF, 0x55, 0x5B, 0x49,
0xB4, 0xCA, 0x92, 0x61, 0xCB, 0x75, 0xB3, 0x4F, 0xBF, 0x93, 0x2D, 0xD9, 0x92, 0xAD, 0xB4, 0x03,
0x38, 0x0C, 0x20, 0xC0, 0xA2, 0x40, 0x6B, 0x1D, 0x8F, 0xA2, 0xC8, 0x1F, 0x8F, 0xC7, 0xBF, 0x1E,
0xC6, 0xAF, 0xBE, 0x2F, 0xF2, 0x8B, 0x6F, 0xE9, 0x6A, 0x9D, 0x95, 0xC5, 0xCB, 0x4B, 0xB8, 0x12,
0x97, 0x17, 0x69, 0x31, 0x2B, 0xE7, 0x59, 0x71, 0xFF, 0xF2, 0xF2, 0x8F, 0x9B, 0xF7, 0xBF, 0xD8,
0xCB, 0x57, 0x93, 0x67, 0xE3, 0xAF, 0x5C, 0x8A, 0x4B, 0x16, 0xEB, 0x97, 0x97, 0x0F, 0x55, 0xB5,
0x7C, 0x31, 0x1A, 0x6D, 0xB7, 0xDB, 0xAB, 0x72, 0x99, 0x16, 0xF7, 0xD9, 0xFA, 0xAA, 0x48, 0xAB,
0x11, 0x97, 0x18, 0xE1, 0x15, 0x5E, 0xEE, 0x8B, 0xBD, 0xD8, 0x2E, 0x17, 0x79, 0xAF, 0xEC, 0xFC,
0xAF, 0xEC, 0x6A, 0x56, 0x2E, 0x46, 0x6C, 0xF8, 0x7B, 0xC4, 0xE7, 0xE1, 0x33, 0x4D, 0x9E, 0x5D,
0x5C, 0x8C, 0xDF, 0x96, 0xB3, 0xCD, 0x22, 0x2D, 0xAA, 0xFA, 0x07, 0xFF, 0xAC, 0xFD, 0x5E, 0xCC,
0x56, 0x69, 0x52, 0xA5, 0x37, 0xD9, 0x22, 0x9D, 0x80, 0x56, 0x46, 0xA2, 0xB1, 0x92, 0xA4, 0xC3,
0xF1, 0xE8, 0xD4, 0xDC, 0x71, 0xDA, 0x2C, 0xE7, 0x27, 0x4E, 0xCE, 0x19, 0x00, 0xD3, 0x38, 0x75,
0xCC, 0x1D, 0xA7, 0x45, 0xB6, 0xAE, 0xAF, 0xFC, 0x4D, 0x59, 0xDC, 0x65, 0xF7, 0x7B, 0x43, 0x6B,
0xBA, 0xCB, 0x1F, 0x6F, 0xCA, 0xDB, 0xE4, 0x31, 0xCF, 0x8A, 0xF4, 0xB7, 0x72, 0x9E, 0x4E, 0xD6,
0xC9, 0x5D, 0x9A, 0x3F, 0x36, 0xD5, 0x9D, 0x59, 0xFB, 0xBE, 0x59, 0x91, 0xAD, 0x1F, 0x5E, 0xCF,
0x2A, 0xAE, 0x7B, 0x72, 0x5F, 0x7E, 0x2C, 0x17, 0x69, 0xEB, 0xD7, 0xB5, 0xF4, 0x7C, 0xD2, 0xEF,
0x59, 0xF5, 0xB9, 0xF8, 0xFD, 0xCD, 0xAF, 0xE5, 0xBA, 0x62, 0x1F, 0x6E, 0x52, 0x95, 0x15, 0x9B,
0xD6, 0xAF, 0x67, 0xED, 0xF9, 0x55, 0xC9, 0xD7, 0xF4, 0xF3, 0xDD, 0xDD, 0x34, 0x9D, 0x6D, 0x56,
0x59, 0xF5, 0xF8, 0x31, 0xCD, 0xEE, 0x1F, 0xAA, 0x09, 0x8A, 0xC6, 0x71, 0xD8, 0xDC, 0xAB, 0xE1,
0x3E, 0x2F, 0xBF, 0x24, 0xF9, 0xCD, 0x2A, 0x29, 0xD6, 0x59, 0xDD, 0xAE, 0x24, 0x9F, 0x2E, 0xD3,
0x74, 0x3E, 0xA1, 0xA6, 0x8A, 0xA7, 0xEC, 0xBD, 0x4A, 0xE6, 0xAB, 0xB2, 0x48, 0x3F, 0x15, 0x77,
0x65, 0x7B, 0xB8, 0x67, 0x78, 0x57, 0x6C, 0x16, 0x7F, 0x26, 0xF9, 0x26, 0x9D, 0xE8, 0x76, 0x40,
0x4E, 0x8E, 0x0F, 0x79, 0x4D, 0x37, 0x5F, 0x8E, 0x05, 0x44, 0xD7, 0xAF, 0x67, 0x69, 0xDB, 0x31,
0x1A, 0x6E, 0xC8, 0xBE, 0xC2, 0x25, 0x8F, 0x55, 0x99, 0xCC, 0x87, 0x5A, 0xD8, 0x98, 0x8E, 0x15,
0x52, 0x4B, 0xDA, 0x99, 0x65, 0xD8, 0x73, 0xB0, 0x9D, 0x43, 0xB6, 0x61, 0xF7, 0xEB, 0x72, 0xDF,
0xAF, 0x9F, 0x8A, 0x79, 0xFA, 0xFD, 0xD4, 0xBF, 0x6F, 0xEC, 0x5F, 0xEA, 0xD9, 0x35, 0x35, 0xC7,
0x07, 0xA8, 0x1E, 0xBF, 0x2F, 0xF3, 0x79, 0xBA, 0x3A, 0x41, 0x27, 0x5D, 0x2C, 0xF3, 0x7A, 0x56,
0x3C, 0x2E, 0xD3, 0xC9, 0x36, 0x79, 0x5C, 0x96, 0x59, 0x51, 0xB5, 0xDC, 0x74, 0x6D, 0x3D, 0xAF,
0xCD, 0x3A, 0xFD, 0xF0, 0x04, 0x11, 0x6D, 0xDB, 0x7F, 0x50, 0x64, 0xB0, 0x01, 0x9F, 0x8E, 0xAE,
0x9D, 0x43, 0xBD, 0xA2, 0xDB, 0xFD, 0x5C, 0x7B, 0x53, 0x96, 0x2B, 0x0E, 0x4E, 0x5C, 0x60, 0xFA,
0xB8, 0xBE, 0x4E, 0x56, 0xC9, 0xE2, 0xB4, 0x53, 0x67, 0x87, 0x12, 0xBB, 0x79, 0x79, 0xFB, 0x61,
0x6A, 0x55, 0x1B, 0x38, 0xFA, 0xA6, 0x13, 0xC7, 0x87, 0xDD, 0xD4, 0xD8, 0x59, 0x56, 0x29, 0x37,
0x21, 0xFB, 0x96, 0xDE, 0x94, 0xD3, 0x2A, 0x59, 0x55, 0xD7, 0x9D, 0x7E, 0xE9, 0x94, 0x3A, 0xF1,
0xDF, 0x4F, 0x93, 0x66, 0x82, 0x81, 0x10, 0xBD, 0xD9, 0xD3, 0x9F, 0x77, 0x07, 0x00, 0x9A, 0xC1,
0xE5, 0x68, 0xBB, 0xEB, 0xE7, 0x0F, 0xD7, 0xD3, 0x76, 0x68, 0x4F, 0x2C, 0xFD, 0x81, 0xFF, 0x69,
0x67, 0xEC, 0xAB, 0x4F, 0x36, 0x55, 0xF9, 0x3E, 0xAF, 0x4F, 0xDC, 0x9F, 0xD0, 0xA7, 0xC7, 0xFB,
0x63, 0xF2, 0x64, 0x1C, 0x38, 0xB7, 0xF4, 0x1C, 0x67, 0x49, 0x9E, 0xED, 0x6B, 0x7D, 0x57, 0x24,
0x5F, 0xF2, 0xE3, 0x4C, 0x38, 0x33, 0xF4, 0xA3, 0x4F, 0xB6, 0xE0, 0xFE, 0xB9, 0xCE, 0xAA, 0xD9,
0xC3, 0xAE, 0x57, 0x17, 0x49, 0xB1, 0x49, 0xF2, 0xB6, 0xF3, 0x4E, 0x8C, 0x03, 0x71, 0xEB, 0xB6,
0xE1, 0xF6, 0x63, 0x9A, 0xD4, 0xAB, 0xD6, 0x20, 0x13, 0xDB, 0x7E, 0x99, 0x5D, 0x55, 0x77, 0x65,
0x9E, 0x97, 0xDB, 0x26, 0x84, 0x1F, 0xFB, 0xF5, 0xAC, 0xDC, 0x8F, 0xAB, 0x7A, 0x5D, 0xDC, 0x77,
0xAE, 0x74, 0xD0, 0xF8, 0x44, 0x05, 0x0C, 0xD5, 0x8E, 0xAB, 0x09, 0x2F, 0x85, 0xBB, 0x3F, 0xCF,
0xCF, 0xFE, 0x73, 0x52, 0xEB, 0xC1, 0xE3, 0x5F, 0x34, 0xE9, 0x64, 0x08, 0x7E, 0x50, 0xA4, 0x4F,
0xD6, 0xCF, 0xFB, 0x74, 0xA8, 0xEF, 0x6F, 0x36, 0xAB, 0x62, 0xD7, 0x59, 0x55, 0xB9, 0x6B, 0xE1,
0xEB, 0x62, 0x3E, 0xAD, 0xCA, 0xE5, 0x6D, 0x56, 0x3D, 0xBC, 0xCD, 0xD6, 0xB3, 0xFD, 0x52, 0xC6,
0xAB, 0xCF, 0x9B, 0xCD, 0xEA, 0x5B, 0x52, 0x6D, 0x56, 0xE9, 0xE0, 0xD9, 0x0E, 0xB5, 0xB4, 0x67,
0xBA, 0xCE, 0x93, 0x59, 0xBA, 0x48, 0x56, 0x5F, 0x3B, 0x57, 0x7C, 0xD2, 0x03, 0x7C, 0xE4, 0x38,
0xAB, 0xD7, 0xDD, 0xE3, 0x17, 0x17, 0x00, 0xF2, 0xCA, 0x29, 0x90, 0x46, 0x81, 0xD5, 0x1A, 0xF5,
0x73, 0xC4, 0x2B, 0x42, 0x54, 0xCA, 0x29, 0x6B, 0x8D, 0x00, 0xEC, 0xD6, 0x32, 0x1A, 0xAC, 0x66,
0x3C, 0x1A, 0xEC, 0xF1, 0xAC, 0x17, 0xA9, 0xB3, 0x6E, 0x68, 0x3E, 0x2C, 0xE7, 0x79, 0x9E, 0x2D,
0xD7, 0x65, 0x36, 0x3F, 0x0B, 0x08, 0xA7, 0x96, 0xC1, 0x30, 0xD4, 0x29, 0xFF, 0x30, 0x58, 0xEC,
0x10, 0x62, 0xDB, 0xFA, 0x4F, 0x43, 0xEF, 0x70, 0xED, 0x07, 0xF3, 0x7E, 0x02, 0x9F, 0x79, 0xF5,
0xE6, 0xF5, 0xC0, 0xB9, 0x3A, 0x3C, 0x0C, 0x9C, 0xF1, 0xE9, 0x19, 0x78, 0x5C, 0x11, 0x78, 0x90,
0x9F, 0xF0, 0x3F, 0x9A, 0x0E, 0x4C, 0x9E, 0x11, 0xF0, 0xDF, 0x30, 0x81, 0x46, 0x0B, 0xC9, 0x19,
0xA2, 0x86, 0x86, 0x09, 0xD4, 0x52, 0x29, 0x44, 0x00, 0xE5, 0xC9, 0x04, 0x44, 0x26, 0x02, 0x65,
0x42, 0x82, 0x94, 0xD6, 0x2A, 0xED, 0x1A, 0x26, 0x24, 0x87, 0x0C, 0x92, 0xC6, 0x28, 0x65, 0x3D,
0x99, 0xC0, 0xC8, 0x44, 0xA0, 0x4C, 0x30, 0x05, 0xC2, 0x39, 0x74, 0xBA, 0x45, 0x82, 0x17, 0x12,
0x25, 0x94, 0x06, 0xE9, 0x89, 0x84, 0x8C, 0x48, 0x04, 0x8A, 0x84, 0xB6, 0x12, 0x09, 0x08, 0x45,
0x1B, 0x26, 0xA4, 0x26, 0xA1, 0x0C, 0xF1, 0x3F, 0x9E, 0x4C, 0xA8, 0xC8, 0x44, 0xA0, 0x4C, 0x18,
0x63, 0x90, 0x88, 0xB4, 0x38, 0xA4, 0x13, 0x0A, 0x1C, 0x2A, 0x23, 0x94, 0x6F, 0x8A, 0x49, 0x91,
0x89, 0x40, 0x99, 0xB0, 0x92, 0xFF, 0xD6, 0x4B, 0x87, 0xDA, 0x33, 0x21, 0xAC, 0x34, 0x20, 0x34,
0x0A, 0xF4, 0x4D, 0x27, 0x74, 0x64, 0x22, 0x50, 0x26, 0x8C, 0x71, 0x8E, 0x04, 0x49, 0xB1, 0xCF,
0x27, 0xC0, 0x91, 0xE2, 0xEC, 0x42, 0xF0, 0xA2, 0xE2, 0x1B, 0x27, 0x4C, 0x64, 0x22, 0x50, 0x26,
0xB4, 0x93, 0xCE, 0x5A, 0x4D, 0x68, 0x1B, 0x26, 0x94, 0x20, 0xB2, 0x28, 0xB4, 0x31, 0x9E, 0x4C,
0xD8, 0xC8, 0x44, 0xA8, 0x4C, 0x48, 0xDE, 0x67, 0x80, 0x33, 0x16, 0xF7, 0x4C, 0x58, 0x63, 0x49,
0x08, 0x29, 0xBC, 0xB7, 0x1D, 0x2E, 0x22, 0x11, 0x28, 0x12, 0xBC, 0xC3, 0xB0, 0x1C, 0x16, 0x24,
0x35, 0x4B, 0x87, 0x75, 0xC6, 0x09, 0x34, 0x02, 0x49, 0xFB, 0x2A, 0x56, 0x51, 0xC6, 0x0C, 0x15,
0x0A, 0xDE, 0x7B, 0x3A, 0x4B, 0xC8, 0xC9, 0xE6, 0x61, 0xED, 0x10, 0xC4, 0x4B, 0x09, 0x08, 0xDF,
0x40, 0x01, 0x51, 0xC7, 0x0C, 0x15, 0x0A, 0x8E, 0x11, 0x52, 0x2A, 0xA7, 0x9D, 0x6A, 0xA0, 0x70,
0x56, 0x0B, 0xAD, 0x35, 0x87, 0x0A, 0x5F, 0x28, 0xA2, 0x90, 0x19, 0x2A, 0x14, 0xC2, 0xDA, 0xFA,
0x6E, 0x87, 0x46, 0x38, 0xEC, 0x46, 0xA5, 0xA9, 0xB9, 0x00, 0xDF, 0x2C, 0x13, 0xA2, 0x94, 0x19,
0x2A, 0x14, 0x00, 0x9C, 0x63, 0x6A, 0xAB, 0x1A, 0x75, 0x1B, 0xB4, 0x96, 0x4C, 0x05, 0x48, 0xEF,
0x7B, 0x60, 0x51, 0xC9, 0x0C, 0x16, 0x09, 0x4B, 0x52, 0x5B, 0x61, 0x4C, 0xCB, 0x84, 0x33, 0x1C,
0x34, 0x38, 0xC3, 0x40, 0x6F, 0x28, 0xA2, 0x94, 0x19, 0x2A, 0x14, 0x12, 0xB5, 0x71, 0xA8, 0xAD,
0x74, 0x0D, 0x14, 0x46, 0x0A, 0x67, 0x0D, 0x90, 0xF1, 0xDE, 0x7B, 0x44, 0x2D, 0x33, 0x54, 0x28,
0x98, 0x0A, 0x09, 0xBC, 0x7A, 0x68, 0xD9, 0x46, 0x0A, 0x72, 0x68, 0x2C, 0x6A, 0xE1, 0x9D, 0x66,
0x46, 0x31, 0x33, 0x54, 0x28, 0x78, 0xF3, 0xC9, 0x04, 0x10, 0xB4, 0x48, 0xF0, 0xA6, 0x83, 0x8F,
0x09, 0xE1, 0x2B, 0x6F, 0x43, 0xD4, 0x32, 0x43, 0x45, 0x42, 0xD7, 0xB7, 0x38, 0x08, 0x8C, 0x69,
0x16, 0x0F, 0xE1, 0x48, 0xA3, 0x55, 0x40, 0xCE, 0x5B, 0xA3, 0x88, 0x6A, 0x66, 0xA8, 0x50, 0x90,
0x03, 0x52, 0x0C, 0x06, 0xB5, 0x50, 0x68, 0x24, 0x12, 0x4E, 0xF0, 0x86, 0xD4, 0x13, 0x0A, 0x8C,
0x6A, 0x66, 0xB0, 0x50, 0xA0, 0xB0, 0xAA, 0x4E, 0x2A, 0x5A, 0x28, 0x48, 0x09, 0xE4, 0xCD, 0x07,
0x38, 0xEF, 0x07, 0xF0, 0xA2, 0x9A, 0x19, 0x2A, 0x14, 0x4A, 0x73, 0x06, 0x41, 0x12, 0xC0, 0x1E,
0x84, 0x2B, 0x01, 0xC2, 0x48, 0x8E, 0x1D, 0xBE, 0x50, 0x44, 0x35, 0x33, 0x58, 0x28, 0x04, 0x20,
0x49, 0x85, 0xBA, 0x55, 0x29, 0x24, 0x3A, 0x49, 0x44, 0xCE, 0x80, 0x2F, 0x14, 0x51, 0xCD, 0x0C,
0x15, 0x0A, 0x94, 0x4E, 0x59, 0xA1, 0x00, 0xB1, 0x4D, 0x34, 0xB5, 0x95, 0xF5, 0xD3, 0x15, 0xDE,
0x81, 0x22, 0xCA, 0x99, 0xA1, 0x32, 0xC1, 0xE3, 0x4F, 0x9C, 0x51, 0x48, 0x6A, 0x90, 0x10, 0xC6,
0x10, 0xF1, 0x4F, 0xEF, 0xBB, 0x1E, 0x18, 0xD5, 0xCC, 0x50, 0x99, 0x50, 0x16, 0xD1, 0x82, 0x40,
0x69, 0x9A, 0xFB, 0xA3, 0x46, 0x2B, 0x09, 0x4A, 0xF1, 0x0E, 0xC4, 0x17, 0x8A, 0xA8, 0x66, 0x86,
0x0A, 0x85, 0x06, 0x94, 0xBB, 0xFD, 0x46, 0x0B, 0x85, 0x45, 0xCE, 0x32, 0x19, 0x13, 0xE9, 0x2B,
0x5D, 0x61, 0x54, 0x33, 0x43, 0x85, 0xC2, 0x08, 0xD2, 0x52, 0xE2, 0x31, 0xA3, 0x00, 0xB2, 0xCC,
0x88, 0xE5, 0x5D, 0xA9, 0x2F, 0x14, 0x51, 0xCF, 0x0C, 0x16, 0x0A, 0x5E, 0x2B, 0x0C, 0x10, 0xE8,
0xCE, 0x93, 0x14, 0xA0, 0x88, 0x37, 0xA8, 0xCE, 0x17, 0x8A, 0xA8, 0x67, 0x86, 0x0A, 0x05, 0x6F,
0x33, 0xAC, 0x12, 0xCA, 0x91, 0x6D, 0x1F, 0xA5, 0x20, 0xCE, 0x34, 0xAD, 0x22, 0xE1, 0x0B, 0x85,
0x8C, 0x7A, 0x66, 0xB0, 0x50, 0x28, 0x30, 0xF5, 0x77, 0x88, 0xDA, 0xE5, 0x03, 0xA9, 0xFE, 0xA6,
0x83, 0x33, 0xDE, 0xCF, 0xD7, 0xC8, 0x28, 0x67, 0x86, 0xCA, 0x04, 0x49, 0x47, 0x86, 0x14, 0xA8,
0xE6, 0xAE, 0x39, 0x1A, 0x63, 0xA0, 0xBE, 0x4B, 0x8A, 0xDE, 0x81, 0x22, 0xCA, 0x99, 0xA1, 0x42,
0xA1, 0xEA, 0x77, 0xCA, 0x9D, 0x70, 0x6D, 0x9C, 0x70, 0x00, 0xA8, 0x0D, 0xFA, 0xEF, 0x3D, 0x64,
0x54, 0x33, 0x43, 0x65, 0x42, 0x5A, 0x0D, 0x00, 0xC6, 0x08, 0x73, 0x08, 0x14, 0x0A, 0x04, 0x39,
0xAD, 0x7C, 0xA5, 0x2B, 0x19, 0xE5, 0xCC, 0x60, 0xA1, 0xC0, 0xFA, 0xE5, 0x0E, 0xB0, 0xCD, 0xFB,
0x1E, 0x58, 0x7F, 0x9D, 0x82, 0x40, 0x1A, 0xEB, 0x7D, 0x87, 0x54, 0x46, 0x3D, 0x33, 0x58, 0x28,
0xA4, 0x10, 0x48, 0x8E, 0xB3, 0x8A, 0xE6, 0xCD, 0x30, 0x5D, 0xBF, 0x52, 0x2C, 0x34, 0x79, 0x7F,
0xDF, 0x4A, 0x46, 0x3D, 0x33, 0x54, 0x28, 0xC0, 0x70, 0x3E, 0x61, 0xE1, 0xF0, 0xA6, 0xB9, 0x15,
0x86, 0x78, 0x3F, 0x22, 0xB4, 0xF2, 0xFE, 0x72, 0x4D, 0xD4, 0x33, 0x43, 0x85, 0x02, 0x95, 0x76,
0x64, 0x25, 0x6F, 0x42, 0xF6, 0xCB, 0x87, 0x62, 0x4C, 0x84, 0x04, 0xE5, 0xB4, 0x77, 0x4E, 0x11,
0xF5, 0xCC, 0xFF, 0x1B, 0x8A, 0xF1, 0xE8, 0xF8, 0x45, 0xD7, 0xF1, 0xE8, 0xF8, 0x15, 0xE5, 0x71,
0xFD, 0x25, 0xE6, 0xC9, 0xB3, 0x7F, 0x00, 0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0xB3, 0xD8, 0x8E, 0x16, 0xCE, 0x06, 0x00, 0x00, 0xD6, 0x99, 0x00,
0x00, 0x12, 0x00, 0x00, 0x00, 0x77, 0x70, 0x6D, 0x7A, 0x2F, 0x77, 0x61, 0x79, 0x6C, 0x69, 0x6E,
0x65, 0x73, 0x2E, 0x77, 0x70, 0x6D, 0x6C, 0xED, 0x9D, 0xDF, 0x6F, 0xDB, 0x36, 0x10, 0xC7, 0xDF,
0xFB, 0x57, 0x04, 0x79, 0xEE, 0xEC, 0xBB, 0x23, 0x8F, 0x3F, 0x0A, 0xD7, 0x45, 0xD1, 0x34, 0x68,
0x81, 0x0E, 0x0D, 0x96, 0x6C, 0x7D, 0x56, 0x6D, 0x25, 0xD1, 0x22, 0x4B, 0x86, 0x2C, 0x37, 0xED,
0xFE, 0xFA, 0x51, 0xB6, 0xE4, 0x58, 0x8E, 0xB3, 0x16, 0xE0, 0xA0, 0xBC, 0x5C, 0x50, 0x24, 0x15,
0xC9, 0x23, 0x29, 0x8A, 0x1F, 0x1F, 0x49, 0x7D, 0x49, 0x4F, 0xDE, 0x7C, 0x5F, 0xE4, 0x27, 0xDF,
0xD2, 0x6A, 0x95, 0x95, 0xC5, 0xEB, 0x53, 0x1C, 0xC1, 0xE9, 0x49, 0x5A, 0xCC, 0xCA, 0x79, 0x56,
0xDC, 0xBC, 0x3E, 0xFD, 0xF3, 0xEA, 0xFC, 0x37, 0x77, 0xFA, 0x66, 0xFA, 0x62, 0x72, 0x17, 0x52,
0x85, 0x94, 0xC5, 0xEA, 0xF5, 0xE9, 0x6D, 0x5D, 0x2F, 0x5F, 0x8D, 0xC7, 0xF7, 0xF7, 0xF7, 0xA3,
0x72, 0x99, 0x16, 0x37, 0xD9, 0x6A, 0x54, 0xA4, 0xF5, 0x38, 0xA4, 0x18, 0xD3, 0x88, 0x4E, 0xB7,
0xC9, 0x5E, 0xDD, 0x2F, 0x17, 0x79, 0x2F, 0xED, 0xFC, 0xEF, 0x6C, 0x34, 0x2B, 0x17, 0xE3, 0x10,
0xF1, 0xCF, 0x38, 0x94, 0x13, 0x4A, 0x9A, 0xBE, 0x38, 0x39, 0x99, 0x9C, 0x95, 0xB3, 0xF5, 0x22,
0x2D, 0xEA, 0xE6, 0x22, 0x5C, 0x36, 0x76, 0xAF, 0x16, 0xD9, 0xAA, 0xA9, 0xCF, 0xBB, 0xB2, 0xB8,
0xCE, 0x6E, 0xB6, 0x11, 0x5D, 0xD4, 0x75, 0xFE, 0xE3, 0xAA, 0xFC, 0x92, 0xFC, 0xC8, 0xB3, 0x22,
0xFD, 0xBD, 0x9C, 0xA7, 0xD3, 0x55, 0x72, 0x9D, 0xE6, 0x3F, 0x26, 0xE3, 0xE3, 0xB1, 0x7D, 0xDB,
0xAC, 0xC8, 0x56, 0xB7, 0x6F, 0x67, 0x75, 0xC8, 0x7B, 0x7A, 0x53, 0x7E, 0x28, 0x17, 0x69, 0x67,
0xB7, 0x1F, 0xD3, 0xB3, 0x49, 0xBF, 0x67, 0xF5, 0xE7, 0xE2, 0x8F, 0x77, 0x9F, 0xCA, 0x55, 0x1D,
0x6C, 0x42, 0x95, 0xEA, 0xAC, 0x58, 0x77, 0x76, 0xBD, 0xD8, 0x9E, 0x5D, 0x9D, 0xDC, 0xA5, 0x9F,
0xAF, 0xAF, 0x2F, 0xD3, 0xD9, 0xBA, 0xCA, 0xEA, 0x1F, 0x1F, 0xD2, 0xEC, 0xE6, 0xB6, 0x9E, 0x12,
0xB4, 0x86, 0xC7, 0xA3, 0x7B, 0x39, 0xDC, 0xE4, 0xE5, 0xD7, 0x24, 0xBF, 0xAA, 0x92, 0x62, 0x95,
0x35, 0xF5, 0x4A, 0xF2, 0xCB, 0x65, 0x9A, 0xCE, 0xA7, 0xDC, 0x66, 0xF1, 0x54, 0x7C, 0x2F, 0x93,
0x79, 0x55, 0x16, 0xE9, 0xC7, 0xE2, 0xBA, 0xEC, 0x82, 0x7B, 0x11, 0xEF, 0x8B, 0xF5, 0xE2, 0xAF,
0x24, 0x5F, 0xA7, 0x53, 0x63, 0xDB, 0x5C, 0x0F, 0xC2, 0x8F, 0x59, 0x5D, 0xAE, 0xBF, 0x3E, 0x24,
0x80, 0x7D, 0xBB, 0x5E, 0x4C, 0x57, 0x8F, 0xF1, 0xF1, 0x8A, 0x6C, 0x33, 0x5C, 0x86, 0x67, 0x55,
0x26, 0xF3, 0x63, 0x35, 0x6C, 0xA3, 0x1E, 0x32, 0x64, 0x6A, 0xF3, 0x7A, 0x14, 0x73, 0xDC, 0xF2,
0x68, 0x3D, 0x8F, 0xC5, 0x1D, 0x37, 0xBF, 0x28, 0xB7, 0xED, 0xFA, 0xB1, 0x98, 0xA7, 0xDF, 0x0F,
0xED, 0xFB, 0x91, 0xFD, 0x5B, 0x7D, 0x74, 0x4F, 0x6D, 0xF8, 0x91, 0x5E, 0x3D, 0x39, 0x2F, 0xF3,
0x79, 0x5A, 0x1D, 0x74, 0x9D, 0x74, 0xB1, 0xCC, 0x93, 0x3A, 0xFD, 0x38, 0xDF, 0x95, 0xBA, 0x17,
0x74, 0xD0, 0x3B, 0x43, 0x07, 0xAA, 0xD3, 0x6D, 0xF7, 0xD9, 0x74, 0xF8, 0x2A, 0x0D, 0xE9, 0xB2,
0x6F, 0xE9, 0x55, 0x79, 0x59, 0x27, 0x55, 0x7D, 0x51, 0x66, 0x45, 0xBD, 0xEB, 0xAC, 0x87, 0x89,
0x7B, 0x79, 0xDD, 0x6F, 0xB1, 0xD9, 0x2B, 0xF5, 0x21, 0xA4, 0xDF, 0xA7, 0xB2, 0x55, 0x9D, 0x14,
0xB3, 0xF0, 0x40, 0xD8, 0xE9, 0x91, 0xB7, 0x40, 0xA8, 0x9D, 0x56, 0xB6, 0xEB, 0x98, 0xBB, 0xF8,
0xBE, 0xD5, 0xBA, 0x4A, 0x36, 0x78, 0x21, 0x38, 0x35, 0x72, 0x04, 0xC6, 0x3A, 0x8B, 0xE0, 0x75,
0x67, 0xD5, 0xC5, 0xF7, 0xAC, 0x92, 0x75, 0x5D, 0x9E, 0xE7, 0x4D, 0x85, 0xFB, 0x9D, 0xFF, 0x30,
0xBC, 0x33, 0xBA, 0xC8, 0x93, 0x59, 0xBA, 0x48, 0xAA, 0xBB, 0xBD, 0x87, 0xBA, 0x69, 0x83, 0x87,
0xEB, 0x10, 0x32, 0x2B, 0xCB, 0x2A, 0x7C, 0xC2, 0x85, 0x06, 0x5D, 0xED, 0x87, 0x9F, 0x9C, 0x20,
0xAA, 0x91, 0xD7, 0xA8, 0xAC, 0x46, 0x67, 0x0C, 0x99, 0x97, 0x44, 0x23, 0x26, 0xD2, 0xDA, 0x6B,
0xE7, 0x2C, 0x20, 0xED, 0xE7, 0x32, 0x3E, 0x9A, 0xCD, 0x64, 0x7C, 0x50, 0xDE, 0xF6, 0x46, 0xB2,
0x5E, 0x2F, 0xCA, 0xF6, 0xBB, 0xCD, 0xD1, 0x87, 0x19, 0x9A, 0x09, 0x8E, 0x3D, 0xB7, 0x43, 0xA3,
0xF0, 0x8C, 0x96, 0x4D, 0x79, 0xFD, 0xE6, 0xE9, 0x87, 0x3E, 0x61, 0xF2, 0x21, 0x4D, 0x9A, 0x8F,
0xF9, 0x8B, 0xA4, 0x4A, 0x16, 0xBD, 0xE6, 0x39, 0x96, 0x6A, 0xD3, 0x5F, 0xAE, 0xCB, 0x3C, 0x2F,
0xEF, 0xDB, 0xCF, 0xD7, 0x83, 0xA2, 0xF6, 0xD3, 0xFD, 0x2C, 0xB3, 0xB7, 0xC5, 0x4D, 0x9E, 0xEE,
0x77, 0xB3, 0xC7, 0x91, 0x4F, 0x66, 0x11, 0x5A, 0x77, 0xDB, 0xC0, 0xC1, 0x83, 0x6C, 0x7E, 0x5E,
0x3E, 0xFA, 0xCF, 0x41, 0xBE, 0x3B, 0x8B, 0x5F, 0xAA, 0xD6, 0xFB, 0x22, 0xF9, 0xFA, 0x93, 0xCA,
0xB5, 0x49, 0xF6, 0x1E, 0xF9, 0x2F, 0xB4, 0x6B, 0xBF, 0xC4, 0xAB, 0x75, 0x55, 0xFC, 0xA4, 0xE1,
0x9B, 0x24, 0x9B, 0xD6, 0xAC, 0xCB, 0x4D, 0xF5, 0xDF, 0x16, 0xF3, 0xCB, 0xBA, 0x5C, 0x7E, 0xC9,
0xEA, 0xDB, 0xB3, 0x6C, 0x35, 0xDB, 0x3A, 0xA2, 0xE0, 0x3B, 0xDE, 0xAD, 0xAB, 0x6F, 0x49, 0xBD,
0xAE, 0x0E, 0x1F, 0xC8, 0xCE, 0xFE, 0x3F, 0x4B, 0x38, 0x4B, 0x16, 0xCB, 0x50, 0xD9, 0x90, 0x63,
0xFD, 0xE8, 0x9E, 0x0F, 0xE3, 0x9F, 0xBA, 0xE1, 0x23, 0x37, 0xB3, 0x2D, 0x68, 0xBD, 0x4A, 0x2F,
0xEB, 0x2A, 0x69, 0xFA, 0xED, 0xA7, 0xD0, 0x63, 0xA6, 0xD8, 0x1A, 0x1E, 0x86, 0xEF, 0x3E, 0x3F,
0x1F, 0xE1, 0xFB, 0xFF, 0x00, 0x4D, 0xD6, 0x80, 0x52, 0xE1, 0x37, 0xB6, 0x40, 0x93, 0x51, 0x5A,
0x13, 0x21, 0xEA, 0x48, 0xA0, 0x51, 0x80, 0x16, 0xA0, 0x05, 0xE8, 0xA1, 0x81, 0x56, 0xA8, 0x94,
0x73, 0xDA, 0xF8, 0x16, 0x68, 0x15, 0x9C, 0x35, 0x2B, 0x6B, 0xB5, 0x76, 0x91, 0x40, 0x93, 0x00,
0x2D, 0x40, 0x0B, 0xD0, 0x43, 0x03, 0x1D, 0x10, 0x06, 0xEF, 0xC9, 0x9B, 0x8E, 0xE7, 0x30, 0xFE,
0xD6, 0xA0, 0x0D, 0xAA, 0x48, 0x9E, 0x95, 0xF0, 0x2C, 0x3C, 0x0B, 0xCF, 0x43, 0xF3, 0x6C, 0x9C,
0x22, 0x46, 0x26, 0xE8, 0x1C, 0xB4, 0x32, 0x0C, 0xDA, 0x72, 0xF8, 0x13, 0x09, 0xB4, 0x16, 0xA0,
0x05, 0x68, 0x01, 0x7A, 0x68, 0xA0, 0xAD, 0xB5, 0xC4, 0xCC, 0x06, 0x76, 0x53, 0x68, 0x8D, 0x9E,
0xB4, 0x05, 0x1D, 0xBB, 0x26, 0xC6, 0x02, 0xB4, 0x00, 0x2D, 0x40, 0x0F, 0x0D, 0xB4, 0x53, 0xE1,
0x5F, 0x33, 0xE2, 0xD6, 0x5B, 0xA0, 0xC1, 0x29, 0x8B, 0x60, 0x08, 0x28, 0x76, 0x0A, 0x6D, 0x04,
0x68, 0x01, 0x5A, 0x80, 0x1E, 0xDE, 0x43, 0x7B, 0xCF, 0xC0, 0x0A, 0xB6, 0x73, 0x68, 0xF4, 0xAC,
0xC3, 0x8C, 0x1A, 0xC2, 0x58, 0x3C, 0xD6, 0x43, 0x5B, 0x01, 0x5A, 0x80, 0x16, 0xA0, 0x07, 0x9F,
0x43, 0x7B, 0xE5, 0x9D, 0x33, 0x4C, 0xAE, 0x05, 0x5A, 0x03, 0xF3, 0xE6, 0xC5, 0xB9, 0x8D, 0x04,
0xDA, 0x09, 0xD0, 0x02, 0xB4, 0x00, 0x3D, 0x38, 0xD0, 0x0A, 0x9D, 0x41, 0x6F, 0x1D, 0x6D, 0x81,
0x76, 0xD6, 0x31, 0x80, 0x82, 0xE8, 0x45, 0x6E, 0x2F, 0x3C, 0x0B, 0xCF, 0xC2, 0xF3, 0xD0, 0x3C,
0x6B, 0xCB, 0x2E, 0x38, 0x64, 0xC5, 0xED, 0x88, 0xDB, 0x79, 0xEB, 0x81, 0x2C, 0x10, 0x9B, 0x48,
0xA0, 0x51, 0x84, 0x62, 0x42, 0xB4, 0x10, 0x3D, 0xBC, 0xAE, 0x44, 0x19, 0xEF, 0x98, 0xBC, 0x7E,
0x18, 0x72, 0x03, 0x87, 0x11, 0x38, 0x42, 0xAC, 0x8B, 0x46, 0x51, 0x8A, 0x09, 0xD1, 0x42, 0xF4,
0xF0, 0xD2, 0x4F, 0xC5, 0x4A, 0x69, 0x6F, 0xBC, 0x6E, 0x89, 0xF6, 0xCE, 0x80, 0x31, 0x26, 0x38,
0xE9, 0x58, 0xA2, 0x45, 0x2A, 0x26, 0x44, 0x0B, 0xD1, 0x83, 0x13, 0x0D, 0xCE, 0x35, 0x4A, 0x6E,
0x43, 0xB8, 0x7B, 0x71, 0xA5, 0x6C, 0x03, 0x35, 0xC6, 0x2E, 0x8B, 0xA1, 0x88, 0xC5, 0x84, 0x68,
0x21, 0x7A, 0x70, 0xA2, 0x11, 0xD1, 0x5B, 0xE3, 0x74, 0x2B, 0xFE, 0x44, 0x63, 0x54, 0x40, 0x1A,
0x55, 0xF4, 0xE6, 0x0C, 0xD1, 0x8A, 0x09, 0xCF, 0xC2, 0xF3, 0xF0, 0x3C, 0x3B, 0x56, 0xC6, 0x81,
0xB5, 0x1D, 0xD0, 0xDE, 0x06, 0x77, 0x1D, 0x66, 0xD5, 0x14, 0x4D, 0xB4, 0x88, 0xC5, 0x84, 0x68,
0x21, 0x7A, 0xF8, 0x75, 0x31, 0x32, 0xD6, 0x93, 0x71, 0xCA, 0xB7, 0x44, 0x5B, 0x05, 0xDE, 0x59,
0x64, 0x1B, 0xBD, 0xD2, 0x2D, 0x6A, 0x31, 0x21, 0x5A, 0x88, 0x1E, 0xFE, 0xDD, 0x95, 0x22, 0x85,
0x61, 0xD0, 0x6D, 0x54, 0xE7, 0xA3, 0xD9, 0x93, 0x75, 0x64, 0x20, 0x7A, 0x5D, 0x4C, 0xE4, 0x62,
0x42, 0xB4, 0x10, 0x3D, 0xFC, 0x16, 0x4A, 0xC3, 0x01, 0x5F, 0xC6, 0x8E, 0x67, 0x03, 0x14, 0xC2,
0x00, 0x62, 0xD5, 0x9F, 0x28, 0x6A, 0x31, 0xE1, 0x59, 0x78, 0x1E, 0x5E, 0x2D, 0xD6, 0xC8, 0xB7,
0x19, 0xAD, 0x6D, 0xC7, 0xDC, 0xE0, 0xD9, 0x90, 0xD3, 0xC8, 0x3E, 0xFA, 0x5D, 0xB4, 0xE8, 0xC5,
0x84, 0x68, 0x21, 0x7A, 0x78, 0x0F, 0xED, 0x91, 0x75, 0xA0, 0x9A, 0x3B, 0xA2, 0x0D, 0x31, 0x83,
0x07, 0x03, 0xB1, 0xB3, 0xE8, 0xDD, 0xB9, 0x82, 0x42, 0xB4, 0x10, 0x2D, 0x44, 0x0F, 0x78, 0x6C,
0x09, 0x38, 0xDD, 0x4C, 0xA4, 0x3B, 0xA2, 0x59, 0x03, 0x19, 0x0A, 0xA3, 0xEF, 0xE8, 0x73, 0x88,
0x44, 0x2F, 0x26, 0x44, 0x0B, 0xD1, 0xC3, 0xAF, 0x8B, 0x99, 0x30, 0x6B, 0x66, 0x85, 0xE8, 0x76,
0xEA, 0x12, 0x40, 0xB0, 0x2A, 0x78, 0xED, 0x58, 0xA2, 0x45, 0x2F, 0x26, 0x44, 0x0B, 0xD1, 0xC3,
0x13, 0x0D, 0x48, 0xAC, 0x34, 0x99, 0xEE, 0x6D, 0xB4, 0x22, 0xAF, 0x98, 0xD9, 0x5B, 0x8C, 0x25,
0x5A, 0xF4, 0x62, 0x42, 0xB4, 0x10, 0xFD, 0x0C, 0x9A, 0x6E, 0xAF, 0x1D, 0x68, 0x24, 0xEA, 0x56,
0xC6, 0x8C, 0x53, 0xCD, 0x6E, 0xE9, 0x68, 0x17, 0x2D, 0x82, 0x31, 0x01, 0x5A, 0x80, 0x1E, 0x5E,
0x5E, 0x62, 0x3C, 0x87, 0x59, 0xB4, 0xE2, 0x96, 0x67, 0xB0, 0x96, 0x39, 0x5C, 0x46, 0x2B, 0xBA,
0x49, 0xF4, 0x62, 0x02, 0xB4, 0x00, 0x3D, 0xFC, 0x98, 0xDB, 0x11, 0x39, 0x04, 0x52, 0xB6, 0xDD,
0x75, 0x65, 0x8D, 0x56, 0xA8, 0x35, 0x71, 0xB4, 0x8B, 0x16, 0xBD, 0x98, 0x10, 0x2D, 0x44, 0x0F,
0xFF, 0x36, 0x1A, 0x49, 0x6D, 0x56, 0xB7, 0x3B, 0xA2, 0x1D, 0x21, 0xD8, 0xC0, 0xB8, 0x8A, 0xD5,
0x97, 0x90, 0xE8, 0xC5, 0x84, 0x68, 0x21, 0x7A, 0xF8, 0xF3, 0x02, 0x81, 0x8D, 0x52, 0xF4, 0x30,
0x8B, 0x46, 0x76, 0x01, 0x70, 0x07, 0x14, 0xFD, 0x36, 0x5A, 0x14, 0x63, 0x42, 0xB4, 0x10, 0x3D,
0x3C, 0xD1, 0x61, 0x88, 0x6D, 0x91, 0xD1, 0xEC, 0xED, 0x8C, 0x46, 0xCD, 0x88, 0xCE, 0xC7, 0x12,
0x2D, 0x8A, 0x31, 0x21, 0x5A, 0x88, 0x7E, 0x8E, 0x23, 0x40, 0x9D, 0x06, 0xED, 0xD9, 0x75, 0x5B,
0xA3, 0xD9, 0x5A, 0x76, 0x9A, 0x21, 0x96, 0x68, 0x25, 0x8A, 0x31, 0x21, 0x5A, 0x88, 0x7E, 0x06,
0x55, 0x37, 0xDA, 0xE0, 0xA8, 0xA9, 0x1B, 0x75, 0x13, 0x37, 0xDD, 0xC4, 0xDB, 0xE8, 0xC3, 0x0E,
0x94, 0x08, 0xC6, 0x04, 0x68, 0x01, 0x7A, 0x78, 0x09, 0xA8, 0xF2, 0x6C, 0x59, 0xA3, 0x6E, 0x37,
0x52, 0x92, 0xB5, 0x16, 0x9B, 0xBD, 0x57, 0x14, 0xED, 0xA2, 0x45, 0x30, 0x26, 0x44, 0x0B, 0xD1,
0xCF, 0x20, 0x01, 0x6D, 0x86, 0xDC, 0xE0, 0x3B, 0x0F, 0xED, 0x11, 0xC9, 0x58, 0x8A, 0x5F, 0xE9,
0x56, 0xA2, 0x17, 0x13, 0xA0, 0x05, 0xE8, 0xE1, 0xE5, 0x25, 0xCE, 0x20, 0xA2, 0xB5, 0x60, 0x77,
0x2E, 0x5A, 0x23, 0xB0, 0x37, 0x3A, 0x56, 0x5F, 0xA2, 0x44, 0x30, 0x26, 0x44, 0x0B, 0xD1, 0xCF,
0x71, 0x1E, 0x11, 0x13, 0xA2, 0x6B, 0xCF, 0xE9, 0xA6, 0xE6, 0xDB, 0xA3, 0x19, 0x95, 0x75, 0xD1,
0xFB, 0xAE, 0x94, 0x28, 0xC6, 0x84, 0x68, 0x21, 0xFA, 0x19, 0x4E, 0xDE, 0x07, 0x20, 0xF6, 0x61,
0x26, 0xDD, 0x7E, 0x97, 0x86, 0x69, 0xBE, 0xBB, 0x0E, 0x0C, 0x63, 0xF4, 0xA8, 0x5B, 0x14, 0x63,
0x42, 0xB4, 0x10, 0x3D, 0xFC, 0x29, 0xA0, 0x36, 0xCC, 0xA1, 0x1D, 0xEE, 0xBE, 0x8F, 0xD2, 0x81,
0x65, 0x13, 0xC6, 0xDD, 0x46, 0xC7, 0x9E, 0x5F, 0xA2, 0x44, 0x31, 0x26, 0x44, 0x0B, 0xD1, 0xC3,
0xEF, 0xBB, 0xD2, 0xC6, 0xB3, 0x53, 0x9A, 0xDB, 0xA5, 0x6E, 0x1D, 0x18, 0x07, 0x85, 0xDA, 0x9B,
0xE8, 0x79, 0xB4, 0x28, 0xC6, 0x84, 0x68, 0x21, 0xFA, 0x97, 0x89, 0x9E, 0x8C, 0xCF, 0xCB, 0x7C,
0x9E, 0x56, 0xCD, 0xD5, 0x64, 0x7C, 0x56, 0xCE, 0xD6, 0x8B, 0xB4, 0x79, 0x8E, 0x93, 0xF1, 0xDD,
0x22, 0x9F, 0xBE, 0xF8, 0x17, 0x50, 0x4B, 0x01, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0xA8, 0x54, 0x6C, 0xA8, 0x06, 0x00, 0x00, 0xD9, 0x59, 0x00,
0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x77, 0x70, 0x6D, 0x7A, 0x2F, 0x74, 0x65, 0x6D, 0x70, 0x6C, 0x61, 0x74, 0x65,
0x2E, 0x6B, 0x6D, 0x6C, 0x50, 0x4B, 0x01, 0x02, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0xB3, 0xD8, 0x8E, 0x16, 0xCE, 0x06, 0x00, 0x00, 0xD6, 0x99, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x06,
0x00, 0x00, 0x77, 0x70, 0x6D, 0x7A, 0x2F, 0x77, 0x61, 0x79, 0x6C, 0x69, 0x6E, 0x65, 0x73, 0x2E,
0x77, 0x70, 0x6D, 0x6C, 0x50, 0x4B, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
0x7F, 0x00, 0x00, 0x00, 0xD5, 0x0D, 0x00, 0x00, 0x00, 0x00
};
#endif /* __waypoint_v3_test_file_kmz_h_included */

View File

@ -0,0 +1,708 @@
/**
********************************************************************
* @file test_widget_speaker.c
* @brief
*
* @copyright (c) 2018 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJIs authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifdef SYSTEM_ARCH_LINUX
#include "test_widget_speaker.h"
#include "dji_logger.h"
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "utils/util_misc.h"
#include "utils/util_md5.h"
#ifdef OPUS_INSTALLED
#include <opus.h>
#endif
/* Private constants ---------------------------------------------------------*/
#define WIDGET_SPEAKER_TASK_STACK_SIZE (2048)
#define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.analog-stereo"
#define WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME "test_audio.opus"
#define WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME "test_audio.pcm"
#define WIDGET_SPEAKER_TTS_FILE_NAME "test_tts.txt"
#define WIDGET_SPEAKER_TTS_OUTPUT_FILE_NAME "tts_sample.wav"
#define WIDGET_SPEAKER_TTS_FILE_MAX_SIZE (3000)
/*The frame size is hardcoded for this sample code but it doesn't have to be*/
#define WIDGET_SPEAKER_AUDIO_OPUS_MAX_PACKET_SIZE (3 * 1276)
#define WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE (6 * 960)
#define WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE (16000)
#define WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS (1)
#define WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE (160)
/* Private types -------------------------------------------------------------*/
/* Private values -------------------------------------------------------------*/
static T_DjiWidgetSpeakerHandler s_speakerHandler = {0};
static T_DjiMutexHandle s_speakerMutex = {0};
static T_DjiWidgetSpeakerState s_speakerState = {0};
static T_DjiTaskHandle s_widgetSpeakerTestThread;
static FILE *audioFile = NULL;
static FILE *ttsFile = NULL;
/* Private functions declaration ---------------------------------------------*/
static T_DjiReturnCode GetSpeakerState(T_DjiWidgetSpeakerState *speakerState);
static T_DjiReturnCode SetWorkMode(E_DjiWidgetSpeakerWorkMode workMode);
static T_DjiReturnCode GetWorkMode(E_DjiWidgetSpeakerWorkMode *workMode);
static T_DjiReturnCode SetPlayMode(E_DjiWidgetSpeakerPlayMode playMode);
static T_DjiReturnCode GetPlayMode(E_DjiWidgetSpeakerPlayMode *playMode);
static T_DjiReturnCode StartPlay(void);
static T_DjiReturnCode StopPlay(void);
static T_DjiReturnCode SetVolume(uint8_t volume);
static T_DjiReturnCode GetVolume(uint8_t *volume);
static T_DjiReturnCode ReceiveTtsData(E_DjiWidgetTransmitDataEvent event,
uint32_t offset, uint8_t *buf, uint16_t size);
static T_DjiReturnCode ReceiveAudioData(E_DjiWidgetTransmitDataEvent event,
uint32_t offset, uint8_t *buf, uint16_t size);
static void *DjiTest_WidgetSpeakerTask(void *arg);
static uint32_t DjiTest_GetVoicePlayProcessId(void);
static uint32_t DjiTest_KillVoicePlayProcess(uint32_t pid);
static T_DjiReturnCode DjiTest_DecodeAudioData(void);
static T_DjiReturnCode DjiTest_PlayAudioData(void);
static T_DjiReturnCode DjiTest_PlayTtsData(void);
static T_DjiReturnCode DjiTest_CheckFileMd5Sum(const char *path, uint8_t *buf, uint16_t size);
/* Exported functions definition ---------------------------------------------*/
T_DjiReturnCode DjiTest_WidgetSpeakerStartService(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
s_speakerHandler.GetSpeakerState = GetSpeakerState;
s_speakerHandler.SetWorkMode = SetWorkMode;
s_speakerHandler.GetWorkMode = GetWorkMode;
s_speakerHandler.StartPlay = StartPlay;
s_speakerHandler.StopPlay = StopPlay;
s_speakerHandler.SetPlayMode = SetPlayMode;
s_speakerHandler.GetPlayMode = GetPlayMode;
s_speakerHandler.SetVolume = SetVolume;
s_speakerHandler.GetVolume = GetVolume;
s_speakerHandler.ReceiveTtsData = ReceiveTtsData;
s_speakerHandler.ReceiveVoiceData = ReceiveAudioData;
returnCode = osalHandler->MutexCreate(&s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Create speaker mutex error: 0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiWidget_RegSpeakerHandler(&s_speakerHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Register speaker handler error: 0x%08llX", returnCode);
return returnCode;
}
if (osalHandler->TaskCreate("user_widget_speaker_task", DjiTest_WidgetSpeakerTask, WIDGET_SPEAKER_TASK_STACK_SIZE,
NULL,
&s_widgetSpeakerTestThread) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Dji widget speaker test task create error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/* Private functions definition-----------------------------------------------*/
static uint32_t DjiTest_GetVoicePlayProcessId(void)
{
FILE *fp;
char cmdStr[128];
uint32_t pid;
int ret;
snprintf(cmdStr, 128, "pgrep ffplay");
fp = popen(cmdStr, "r");
if (fp == NULL) {
USER_LOG_ERROR("fp is null.");
return 0;
}
ret = fscanf(fp, "%u", &pid);
if (ret <= 0) {
USER_LOG_ERROR("get pid error.");
pid = 0;
goto out;
}
out:
pclose(fp);
return pid;
}
static uint32_t DjiTest_KillVoicePlayProcess(uint32_t pid)
{
FILE *fp;
char cmdStr[128];
snprintf(cmdStr, 128, "kill %d", pid);
fp = popen(cmdStr, "r");
if (fp == NULL) {
USER_LOG_ERROR("fp is null.");
return 0;
}
pclose(fp);
return pid;
}
static T_DjiReturnCode DjiTest_DecodeAudioData(void)
{
#ifdef OPUS_INSTALLED
FILE *fin;
FILE *fout;
OpusDecoder *decoder;
opus_int16 out[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS];
uint8_t cbits[WIDGET_SPEAKER_AUDIO_OPUS_MAX_PACKET_SIZE];
int32_t nbBytes;
int32_t err;
/*! Attention: you can use "ffmpeg -i xxx.mp3 -ar 16000 -ac 1 out.wav" and use opus-tools to generate opus file for test */
fin = fopen(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, "r");
if (fin == NULL) {
fprintf(stderr, "failed to open input file: %s\n", strerror(errno));
return EXIT_FAILURE;
}
/* Create a new decoder state. */
decoder = opus_decoder_create(WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE, WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, &err);
if (err < 0) {
fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err));
return EXIT_FAILURE;
}
fout = fopen(WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME, "w");
if (fout == NULL) {
fprintf(stderr, "failed to open output file: %s\n", strerror(errno));
return EXIT_FAILURE;
}
USER_LOG_INFO("Decode Start...");
while (1) {
int i;
unsigned char pcm_bytes[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * 2];
int frame_size;
/* Read a 16 bits/sample audio frame. */
nbBytes = fread(cbits, 1, WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE, fin);
if (feof(fin))
break;
/* Decode the data. In this example, frame_size will be constant because
the encoder is using a constant frame size. However, that may not
be the case for all encoders, so the decoder must always check
the frame size returned. */
frame_size = opus_decode(decoder, cbits, nbBytes, out, WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE, 0);
if (frame_size < 0) {
fprintf(stderr, "decoder failed: %s\n", opus_strerror(frame_size));
return EXIT_FAILURE;
}
USER_LOG_DEBUG("decode data to file: %d\r\n", frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS);
/* Convert to little-endian ordering. */
for (i = 0; i < WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * frame_size; i++) {
pcm_bytes[2 * i] = out[i] & 0xFF;
pcm_bytes[2 * i + 1] = (out[i] >> 8) & 0xFF;
}
/* Write the decoded audio to file. */
fwrite(pcm_bytes, sizeof(short), frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, fout);
}
/*Destroy the encoder state*/
opus_decoder_destroy(decoder);
fclose(fin);
fclose(fout);
USER_LOG_INFO("Decode Finished...");
#endif
return EXIT_SUCCESS;
}
static T_DjiReturnCode DjiTest_PlayAudioData(void)
{
char cmdStr[128];
memset(cmdStr, 0, sizeof(cmdStr));
snprintf(cmdStr, sizeof(cmdStr), "ffplay -nodisp -autoexit -ar 16000 -ac 1 -f s16le -i %s 2>/dev/null",
WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME);
return DjiUserUtil_RunSystemCmd(cmdStr);
}
static T_DjiReturnCode DjiTest_PlayTtsData(void)
{
FILE *txtFile;
uint8_t data[WIDGET_SPEAKER_TTS_FILE_MAX_SIZE] = {0};
int32_t readLen;
char cmdStr[WIDGET_SPEAKER_TTS_FILE_MAX_SIZE + 128];
txtFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "r");
if (txtFile == NULL) {
fprintf(stderr, "failed to open input file: %s\n", strerror(errno));
return EXIT_FAILURE;
}
readLen = fread(data, 1, WIDGET_SPEAKER_TTS_FILE_MAX_SIZE, txtFile);
if (readLen <= 0) {
USER_LOG_ERROR("Read tts file failed, error code: %d", readLen);
fclose(txtFile);
return DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
}
fclose(txtFile);
USER_LOG_INFO("Read tts file success, len: %d", readLen);
USER_LOG_INFO("Content: %s", data);
memset(cmdStr, 0, sizeof(cmdStr));
/*! Attention: you can use other tts opensource function to convert txt to speech, example used ekho v7.5 */
snprintf(cmdStr, sizeof(cmdStr), " ekho %s -s 20 -p 20 -a 100", data);
return DjiUserUtil_RunSystemCmd(cmdStr);
}
static T_DjiReturnCode DjiTest_CheckFileMd5Sum(const char *path, uint8_t *buf, uint16_t size)
{
MD5_CTX md5Ctx;
uint32_t readFileTotalSize = 0;
uint16_t readLen;
T_DjiReturnCode returnCode;
uint8_t readBuf[1024];
uint8_t md5Sum[16];
FILE *file = NULL;;
UtilMd5_Init(&md5Ctx);
file = fopen(path, "rb");
if (file == NULL) {
USER_LOG_ERROR("Open tts file error.");
}
while (1) {
returnCode = fseek(file, readFileTotalSize, SEEK_SET);
if (returnCode != 0) {
USER_LOG_INFO("fseek file error");
}
readLen = fread(readBuf, 1, sizeof(readBuf), file);
if (readLen > 0) {
readFileTotalSize += readLen;
UtilMd5_Update(&md5Ctx, readBuf, readLen);
}
if (feof(file))
break;
}
UtilMd5_Final(&md5Ctx, md5Sum);
fclose(file);
if (size == sizeof(md5Sum)) {
if (memcmp(md5Sum, buf, sizeof(md5Sum)) == 0) {
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
} else {
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
} else {
USER_LOG_ERROR("MD5 sum length error");
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetSpeakerState(T_DjiWidgetSpeakerState *speakerState)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*speakerState = s_speakerState;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetWorkMode(E_DjiWidgetSpeakerWorkMode workMode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("Set widget speaker work mode: %d", workMode);
s_speakerState.workMode = workMode;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetWorkMode(E_DjiWidgetSpeakerWorkMode *workMode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*workMode = s_speakerState.workMode;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetPlayMode(E_DjiWidgetSpeakerPlayMode playMode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("Set widget speaker play mode: %d", playMode);
s_speakerState.playMode = playMode;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetPlayMode(E_DjiWidgetSpeakerPlayMode *playMode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*playMode = s_speakerState.playMode;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StartPlay(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("Start widget speaker play");
s_speakerState.state = DJI_WIDGET_SPEAKER_STATE_PLAYING;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StopPlay(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
uint32_t pid;
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("Stop widget speaker play");
s_speakerState.state = DJI_WIDGET_SPEAKER_STATE_IDEL;
pid = DjiTest_GetVoicePlayProcessId();
if (pid != 0) {
DjiTest_KillVoicePlayProcess(pid);
}
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetVolume(uint8_t volume)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
char cmdStr[128];
int32_t ret = 0;
float realVolume;
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
realVolume = 1.5f * (float) volume;
USER_LOG_INFO("Set widget speaker volume: %d", volume);
s_speakerState.volume = volume;
memset(cmdStr, 0, sizeof(cmdStr));
snprintf(cmdStr, sizeof(cmdStr), "pactl set-sink-volume %s %d%%", WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME,
(int32_t) realVolume);
returnCode = DjiUserUtil_RunSystemCmd(cmdStr);
if (returnCode < 0) {
USER_LOG_ERROR("Set widget speaker volume error: %d", ret);
}
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetVolume(uint8_t *volume)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*volume = s_speakerState.volume;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode ReceiveTtsData(E_DjiWidgetTransmitDataEvent event,
uint32_t offset, uint8_t *buf, uint16_t size)
{
uint16_t writeLen;
T_DjiReturnCode returnCode;
if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_START) {
USER_LOG_INFO("Create tts file.");
ttsFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "wb");
if (ttsFile == NULL) {
USER_LOG_ERROR("Open tts file error.");
}
} else if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) {
USER_LOG_INFO("Transmit tts file, offset: %d, size: %d", offset, size);
if (ttsFile != NULL) {
fseek(ttsFile, offset, SEEK_SET);
writeLen = fwrite(buf, 1, size, ttsFile);
if (writeLen != size) {
USER_LOG_ERROR("Write tts file error %d", writeLen);
}
}
} else if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_FINISH) {
USER_LOG_INFO("Close tts file.");
if (ttsFile != NULL) {
fclose(ttsFile);
}
returnCode = DjiTest_CheckFileMd5Sum(WIDGET_SPEAKER_TTS_FILE_NAME, buf, size);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("File md5 sum check failed");
}
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode ReceiveAudioData(E_DjiWidgetTransmitDataEvent event,
uint32_t offset, uint8_t *buf, uint16_t size)
{
uint16_t writeLen;
T_DjiReturnCode returnCode;
if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_START) {
USER_LOG_INFO("Create voice file.");
audioFile = fopen(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, "wb");
if (audioFile == NULL) {
USER_LOG_ERROR("Create tts file error.");
}
} else if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) {
USER_LOG_INFO("Transmit voice file, offset: %d, size: %d", offset, size);
if (audioFile != NULL) {
fseek(audioFile, offset, SEEK_SET);
writeLen = fwrite(buf, 1, size, audioFile);
if (writeLen != size) {
USER_LOG_ERROR("Write tts file error %d", writeLen);
}
}
} else if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_FINISH) {
USER_LOG_INFO("Close voice file.");
if (audioFile != NULL) {
fclose(audioFile);
}
returnCode = DjiTest_CheckFileMd5Sum(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, buf, size);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("File md5 sum check failed");
}
DjiTest_DecodeAudioData();
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
#ifndef __CC_ARM
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#pragma GCC diagnostic ignored "-Wreturn-type"
#endif
static void *DjiTest_WidgetSpeakerTask(void *arg)
{
T_DjiReturnCode djiReturnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
USER_UTIL_UNUSED(arg);
while (1) {
osalHandler->TaskSleepMs(10);
if (s_speakerState.state == DJI_WIDGET_SPEAKER_STATE_PLAYING) {
if (s_speakerState.playMode == DJI_WIDGET_SPEAKER_PLAY_MODE_LOOP_PLAYBACK) {
if (s_speakerState.workMode == DJI_WIDGET_SPEAKER_WORK_MODE_VOICE) {
djiReturnCode = DjiTest_PlayAudioData();
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Play audio data failed, error: 0x%08llX.", djiReturnCode);
}
} else {
djiReturnCode = DjiTest_PlayTtsData();
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Play tts data failed, error: 0x%08llX.", djiReturnCode);
}
}
} else {
if (s_speakerState.workMode == DJI_WIDGET_SPEAKER_WORK_MODE_VOICE) {
djiReturnCode = DjiTest_PlayAudioData();
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Play audio data failed, error: 0x%08llX.", djiReturnCode);
}
} else {
djiReturnCode = DjiTest_PlayTtsData();
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Play tts data failed, error: 0x%08llX.", djiReturnCode);
}
}
djiReturnCode = osalHandler->MutexLock(s_speakerMutex);
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", djiReturnCode);
}
s_speakerState.state = DJI_WIDGET_SPEAKER_STATE_IDEL;
djiReturnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", djiReturnCode);
}
}
}
}
}
#ifndef __CC_ARM
#pragma GCC diagnostic pop
#endif
#endif
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/

View File

@ -0,0 +1,53 @@
/**
********************************************************************
* @file test_widget_speaker.h
* @brief This is the header file for "test_widget_speaker.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2018 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJIs authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef TEST_WIDGET_SPEAKER_H
#define TEST_WIDGET_SPEAKER_H
/* Includes ------------------------------------------------------------------*/
#include "dji_widget.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SYSTEM_ARCH_LINUX
/* Exported constants --------------------------------------------------------*/
T_DjiReturnCode DjiTest_WidgetSpeakerStartService(void);
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
#endif
#ifdef __cplusplus
}
#endif
#endif // TEST_WIDGET_SPEAKER_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/

View File

@ -7,6 +7,10 @@
"floating_window": {
"is_enable": true
},
"speaker": {
"is_enable_tts": true,
"is_enable_voice": true
},
"widget_list": [
{
"widget_index": 0,

View File

@ -7,6 +7,10 @@
"floating_window": {
"is_enable": true
},
"speaker": {
"is_enable_tts": true,
"is_enable_voice": true
},
"widget_list": [
{
"widget_index": 0,

View File

@ -43,6 +43,7 @@
#include "dji_aircraft_info.h"
#include "dji_core.h"
#include <payload_collaboration/test_payload_collaboration.h>
#include <waypoint_v3/test_waypoint_v3.h>
/* Private constants ---------------------------------------------------------*/
#define WIDGET_DIR_PATH_LEN_MAX (256)
@ -55,18 +56,19 @@
typedef enum {
E_DJI_SAMPLE_INDEX_FC_SUBSCRIPTION = 0,
E_DJI_SAMPLE_INDEX_WAYPOINT_V2 = 1,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_LANDING = 2,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_POSITION_CTRL_LANDING = 3,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_GO_HOME_FORCE_LANDING = 4,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_VELOCITY_CTRL_LANDING = 5,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_ARREST_FLYING = 6,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_SET_GET_PARAM = 7,
E_DJI_SAMPLE_INDEX_HMS = 8,
E_DJI_SAMPLE_INDEX_CAMERA_MANAGER = 9,
E_DJI_SAMPLE_INDEX_GIMBAL_MANAGER_FREE_MODE = 10,
E_DJI_SAMPLE_INDEX_GIMBAL_MANAGER_YAW_FOLLOW_MODE = 11,
E_DJI_SAMPLE_INDEX_LIVEVIEW = 12,
E_DJI_SAMPLE_INDEX_PERCEPTION = 13,
E_DJI_SAMPLE_INDEX_WAYPOINT_V3 = 2,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_LANDING = 3,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_POSITION_CTRL_LANDING = 4,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_GO_HOME_FORCE_LANDING = 5,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_VELOCITY_CTRL_LANDING = 6,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_ARREST_FLYING = 7,
E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_SET_GET_PARAM = 8,
E_DJI_SAMPLE_INDEX_HMS = 9,
E_DJI_SAMPLE_INDEX_CAMERA_MANAGER = 10,
E_DJI_SAMPLE_INDEX_GIMBAL_MANAGER_FREE_MODE = 11,
E_DJI_SAMPLE_INDEX_GIMBAL_MANAGER_YAW_FOLLOW_MODE = 12,
E_DJI_SAMPLE_INDEX_LIVEVIEW = 13,
E_DJI_SAMPLE_INDEX_PERCEPTION = 14,
E_DJI_SAMPLE_INDEX_UNKNOWN = 0xFF,
} E_DjiExtensionPortSampleIndex;
@ -338,6 +340,14 @@ static void *DjiTest_WidgetInteractionTask(void *arg)
USER_LOG_WARN("Please turn on the 'unlock flight control restrictions' switch.");
}
break;
case E_DJI_SAMPLE_INDEX_WAYPOINT_V3:
if (s_isallowRunFlightControlSample == true) {
DjiTest_WaypointV3RunSample();
} else {
DjiTest_WidgetLogAppend("Please turn on the 'unlock flight control restrictions'");
USER_LOG_WARN("Please turn on the 'unlock flight control restrictions' switch.");
}
break;
case E_DJI_SAMPLE_INDEX_FLIGHT_CONTROL_TAKE_OFF_LANDING:
if (s_isallowRunFlightControlSample == true) {
DjiTest_FlightControlRunSample(E_DJI_TEST_FLIGHT_CTRL_SAMPLE_SELECT_TAKE_OFF_LANDING);

View File

@ -243,6 +243,9 @@
{
"item_name": "waypoint_v2"
},
{
"item_name": "waypoint_v3"
},
{
"item_name": "flight_ctrl_takeoff_landing"
},

View File

@ -245,6 +245,9 @@
{
"item_name": "waypoint_v2"
},
{
"item_name": "waypoint_v3"
},
{
"item_name": "flight_ctrl_takeoff_landing"
},

View File

@ -271,7 +271,7 @@ T_DjiReturnCode Osal_Stat(const char *filePath, T_DjiFileInfo *fileInfo)
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
fileTm = localtime(&(st.st_ctime));
fileTm = localtime(&(st.st_mtim));
if (fileTm == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
@ -279,7 +279,7 @@ T_DjiReturnCode Osal_Stat(const char *filePath, T_DjiFileInfo *fileInfo)
fileInfo->size = st.st_size;
fileInfo->createTime.year = fileTm->tm_year + 1900 - 1980;
fileInfo->createTime.month = fileTm->tm_mon;
fileInfo->createTime.month = fileTm->tm_mon + 1;
fileInfo->createTime.day = fileTm->tm_mday;
fileInfo->createTime.hour = fileTm->tm_hour;
fileInfo->createTime.minute = fileTm->tm_min;

View File

@ -124,7 +124,7 @@ T_DjiReturnCode Osal_UdpSendData(T_DjiSocketHandle socketHandle, const char *ipA
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ipAddr);
ret = sendto(socketHandleStruct->socketFd, buf, len, MSG_DONTWAIT, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
ret = sendto(socketHandleStruct->socketFd, buf, len, 0, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
if (ret >= 0) {
*realLen = ret;
} else {

View File

@ -95,7 +95,7 @@ out:
}
T_DjiReturnCode DjiUpgradePlatformLinux_GetUpgradeRebootState(bool *isUpgradeReboot,
T_DjiUpgradeEndInfo *upgradeEndInfo)
T_DjiUpgradeEndInfo *upgradeEndInfo)
{
FILE *rebootStateFile;
size_t res;
@ -162,7 +162,7 @@ DjiUpgradePlatformLinux_WriteUpgradeProgramFile(uint32_t offset, const uint8_t *
}
T_DjiReturnCode DjiUpgradePlatformLinux_ReadUpgradeProgramFile(uint32_t offset, uint16_t readDataLen, uint8_t *data,
uint16_t *realLen)
uint16_t *realLen)
{
uint32_t readRtn;

View File

@ -38,7 +38,7 @@ extern "C" {
#endif
/* Exported constants --------------------------------------------------------*/
#define DJI_TEST_UPGRADE_OLD_FIRMWARE_PATH "/usr/local/bin/dji_sdk_demo"
#define DJI_TEST_UPGRADE_OLD_FIRMWARE_PATH "/usr/local/bin/dji_sdk_demo_linux"
#define DJI_TEST_UPGRADE_FILE_DIR "/upgrade/"
/* Exported types ------------------------------------------------------------*/

View File

@ -48,12 +48,14 @@ extern "C" {
#define CONFIG_MODULE_SAMPLE_WIDGET_ON
#define CONFIG_MODULE_SAMPLE_WIDGET_SPEAKER_ON
#define CONFIG_MODULE_SAMPLE_DATA_TRANSMISSION_ON
#define CONFIG_MODULE_SAMPLE_PAYLOAD_COLLABORATION_ON
#define CONFIG_MODULE_SAMPLE_UPGRADE_ON
#define CONFIG_MODULE_SAMPLE_PAYLOAD_COLLABORATION_ON
/*!< Attention: This function needs to be used together with mobile sdk mop sample.
* */
//#define CONFIG_MODULE_SAMPLE_MOP_CHANNEL_ON

View File

@ -30,25 +30,26 @@
#include <errno.h>
#include <signal.h>
#include <power_management/test_power_management.h>
#include <upgrade/test_upgrade.h>
#include <payload_collaboration/test_payload_collaboration.h>
#include <mop_channel/test_mop_channel.h>
#include <xport/test_payload_xport.h>
#include <gimbal_emu/test_payload_gimbal_emu.h>
#include <fc_subscription/test_fc_subscription.h>
#include <camera_emu/test_payload_cam_emu_media.h>
#include <camera_emu/test_payload_cam_emu_base.h>
#include <upgrade/test_upgrade.h>
#include <upgrade_platform_opt/upgrade_platform_opt_linux.h>
#include <mop_channel/test_mop_channel.h>
#include <payload_collaboration/test_payload_collaboration.h>
#include <xport/test_payload_xport.h>
#include "monitor/sys_monitor.h"
#include "osal/osal.h"
#include "osal/osal_fs.h"
#include "osal/osal_socket.h"
#include "upgrade_platform_opt/upgrade_platform_opt_linux.h"
#include "../hal/hal_uart.h"
#include "../hal/hal_network.h"
#include "../hal/hal_usb_bulk.h"
#include "dji_sdk_app_info.h"
#include "dji_aircraft_info.h"
#include "widget/test_widget.h"
#include "widget/test_widget_speaker.h"
#include "widget_interaction_test/test_widget_interaction.h"
#include "data_transmission/test_data_transmission.h"
#include "dji_sdk_config.h"
@ -59,9 +60,8 @@
#define DJI_LOG_FOLDER_NAME "Logs"
#define DJI_LOG_PATH_MAX_SIZE (128)
#define DJI_LOG_FOLDER_NAME_MAX_SIZE (32)
#define DJI_LOG_SYSTEM_CMD_MAX_SIZE (64)
#define DJI_LOG_MAX_COUNT (10)
#define DJI_SYSTEM_CMD_STR_MAX_SIZE (64)
#define DJI_SYSTEM_RESULT_STR_MAX_SIZE (128)
#define DJI_USE_WIDGET_INTERACTION 0
@ -78,6 +78,7 @@ static FILE *s_djiLogFileCnt;
static pthread_t s_monitorThread = 0;
/* Private functions declaration ---------------------------------------------*/
static T_DjiReturnCode DjiUser_PrepareSystemEnvironment(void);
static T_DjiReturnCode DjiUser_FillInUserInfo(T_DjiUserInfo *userInfo);
static T_DjiReturnCode DjiUser_PrintConsole(const uint8_t *data, uint16_t dataLen);
static T_DjiReturnCode DjiUser_LocalWrite(const uint8_t *data, uint16_t dataLen);
@ -85,7 +86,6 @@ static T_DjiReturnCode DjiUser_LocalWriteFsInit(const char *path);
static void *DjiUser_MonitorTask(void *argument);
static T_DjiReturnCode DjiTest_HighPowerApplyPinInit();
static T_DjiReturnCode DjiTest_WriteHighPowerApplyPin(E_DjiPowerManagementPinState pinState);
static bool DjiUser_CheckNetCableConnectStatus(void);
/* Exported functions definition ---------------------------------------------*/
int main(int argc, char **argv)
@ -93,7 +93,204 @@ int main(int argc, char **argv)
T_DjiReturnCode returnCode;
T_DjiUserInfo userInfo;
T_DjiAircraftInfoBaseInfo aircraftInfoBaseInfo;
DjiTestDataTransmissionConfig dataTransmissionConfig;
USER_UTIL_UNUSED(argc);
USER_UTIL_UNUSED(argv);
/*!< Step 1: Prepare system environment, such as osal, hal uart, console function and so on. */
returnCode = DjiUser_PrepareSystemEnvironment();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Prepare system environment error");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
/*!< Step 2: Fill your application information in dji_sdk_app_info.h and use this interface to fill it. */
returnCode = DjiUser_FillInUserInfo(&userInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Fill user info error, please check user info config");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
/*!< Step 3: Initialize the Payload SDK core by your application information. */
returnCode = DjiCore_Init(&userInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Core init error");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
returnCode = DjiAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get aircraft base info error");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
returnCode = DjiCore_SetAlias("PSDK_APPALIAS");
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("set alias error");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
/*!< Step 4: Initialize the selected modules by macros in dji_sdk_config.h . */
#ifdef CONFIG_MODULE_SAMPLE_POWER_MANAGEMENT_ON
T_DjiTestApplyHighPowerHandler applyHighPowerHandler = {
.pinInit = DjiTest_HighPowerApplyPinInit,
.pinWrite = DjiTest_WriteHighPowerApplyPin,
};
returnCode = DjiTest_RegApplyHighPowerHandler(&applyHighPowerHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("regsiter apply high power handler error");
}
returnCode = DjiTest_PowerManagementStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("power management init error");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_DATA_TRANSMISSION_ON
returnCode = DjiTest_DataTransmissionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget sample init error");
}
#endif
if (aircraftInfoBaseInfo.mountPosition == DJI_MOUNT_POSITION_EXTENSION_PORT &&
aircraftInfoBaseInfo.aircraftType == DJI_AIRCRAFT_TYPE_M300_RTK) {
returnCode = DjiTest_WidgetInteractionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget interaction sample init error");
}
} else {
#ifdef CONFIG_MODULE_SAMPLE_CAMERA_EMU_ON
returnCode = DjiTest_CameraEmuBaseStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera emu common init error");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_CAMERA_MEDIA_ON
returnCode = DjiTest_CameraEmuMediaStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera emu media init error");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_FC_SUBSCRIPTION_ON
returnCode = DjiTest_FcSubscriptionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("data subscription sample init error\n");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_GIMBAL_ON
if (aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_SKYPORT_V2 ||
aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_NONE) {
if (DjiTest_GimbalStartService() != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("psdk gimbal init error");
}
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_XPORT_ON
if (aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_XPORT) {
if (DjiTest_XPortStartService() != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("psdk xport init error");
}
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_WIDGET_ON
#if DJI_USE_WIDGET_INTERACTION
returnCode = DjiTest_WidgetInteractionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget interaction test init error");
}
#else
returnCode = DjiTest_WidgetStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget sample init error");
}
#endif
#endif
#ifdef CONFIG_MODULE_SAMPLE_WIDGET_SPEAKER_ON
if (aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_NONE) {
returnCode = DjiTest_WidgetSpeakerStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget speaker test init error");
}
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_MOP_CHANNEL_ON
if (aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_SKYPORT_V2 ||
aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_XPORT) {
returnCode = DjiTest_MopChannelStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mop channel sample init error");
}
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_PAYLOAD_COLLABORATION_ON
if (aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_SKYPORT_V2 ||
aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_XPORT) {
returnCode = DjiTest_PayloadCollaborationStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Payload collaboration sample init error\n");
}
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_UPGRADE_ON
T_DjiTestUpgradePlatformOpt linuxUpgradePlatformOpt = {
.rebootSystem = DjiUpgradePlatformLinux_RebootSystem,
.cleanUpgradeProgramFileStoreArea = DjiUpgradePlatformLinux_CleanUpgradeProgramFileStoreArea,
.createUpgradeProgramFile = DjiUpgradePlatformLinux_CreateUpgradeProgramFile,
.writeUpgradeProgramFile = DjiUpgradePlatformLinux_WriteUpgradeProgramFile,
.readUpgradeProgramFile = DjiUpgradePlatformLinux_ReadUpgradeProgramFile,
.closeUpgradeProgramFile = DjiUpgradePlatformLinux_CloseUpgradeProgramFile,
.replaceOldProgram = DjiUpgradePlatformLinux_ReplaceOldProgram,
.setUpgradeRebootState = DjiUpgradePlatformLinux_SetUpgradeRebootState,
.getUpgradeRebootState = DjiUpgradePlatformLinux_GetUpgradeRebootState,
.cleanUpgradeRebootState = DjiUpgradePlatformLinux_CleanUpgradeRebootState,
};
T_DjiTestUpgradeConfig testUpgradeConfig = {
.firmwareVersion = {1, 0, 0, 0},
.transferType = DJI_FIRMWARE_TRANSFER_TYPE_DCFTP,
.needReplaceProgramBeforeReboot = true
};
if (DjiTest_UpgradeStartService(&linuxUpgradePlatformOpt, testUpgradeConfig) !=
DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("psdk upgrade init error");
}
#endif
}
/*!< Step 5: Tell the DJI Pilot you are ready. */
returnCode = DjiCore_ApplicationStart();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("start sdk application error");
}
if (pthread_create(&s_monitorThread, NULL, DjiUser_MonitorTask, NULL) != 0) {
USER_LOG_ERROR("create monitor task fail.");
}
if (pthread_setname_np(s_monitorThread, "monitor task") != 0) {
USER_LOG_ERROR("set name for monitor task fail.");
}
while (1) {
sleep(1);
}
}
/* Private functions definition-----------------------------------------------*/
static T_DjiReturnCode DjiUser_PrepareSystemEnvironment(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler osalHandler = {
.TaskCreate = Osal_TaskCreate,
.TaskDestroy = Osal_TaskDestroy,
@ -112,6 +309,7 @@ int main(int argc, char **argv)
.GetTimeMs = Osal_GetTimeMs,
.GetTimeUs = Osal_GetTimeUs,
};
T_DjiLoggerConsole printConsole = {
.func = DjiUser_PrintConsole,
.consoleLevel = DJI_LOGGER_CONSOLE_LOG_LEVEL_INFO,
@ -121,7 +319,7 @@ int main(int argc, char **argv)
T_DjiLoggerConsole localRecordConsole = {
.consoleLevel = DJI_LOGGER_CONSOLE_LOG_LEVEL_DEBUG,
.func = DjiUser_LocalWrite,
.isSupportColor = false,
.isSupportColor = true,
};
T_DjiHalUartHandler uartHandler = {
@ -227,211 +425,15 @@ int main(int argc, char **argv)
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
returnCode = DjiUser_FillInUserInfo(&userInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
osalHandler.TaskSleepMs(1000);
USER_LOG_ERROR("fill user info error, please check user info config");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
returnCode = DjiCore_Init(&userInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("core init error");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
returnCode = DjiAircraftInfo_GetBaseInfo(&aircraftInfoBaseInfo);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get aircraft base info error");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
returnCode = DjiCore_SetAlias("PSDK_APPALIAS");
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("set alias error");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
if (aircraftInfoBaseInfo.mountPosition == DJI_MOUNT_POSITION_EXTENSION_PORT) {
dataTransmissionConfig.isEnableLowSpeedDataChannel = true;
dataTransmissionConfig.isEnableHighSpeedDataChannel = false;
returnCode = DjiTest_DataTransmissionStartService(dataTransmissionConfig);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("data transmission init error");
}
returnCode = DjiTest_WidgetInteractionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget interaction sample init error");
}
} else {
#ifdef CONFIG_MODULE_SAMPLE_POWER_MANAGEMENT_ON
T_DjiTestApplyHighPowerHandler applyHighPowerHandler = {
.pinInit = DjiTest_HighPowerApplyPinInit,
.pinWrite = DjiTest_WriteHighPowerApplyPin,
};
returnCode = DjiTest_RegApplyHighPowerHandler(&applyHighPowerHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("regsiter apply high power handler error");
}
returnCode = DjiTest_PowerManagementStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("power management init error");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_CAMERA_EMU_ON
returnCode = DjiTest_CameraEmuBaseStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera emu common init error");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_CAMERA_MEDIA_ON
if (DjiUser_CheckNetCableConnectStatus() == true) {
returnCode = DjiTest_CameraEmuMediaStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera emu media init error");
}
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_FC_SUBSCRIPTION_ON
returnCode = DjiTest_FcSubscriptionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("data subscription sample init error\n");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_GIMBAL_ON
if (aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_SKYPORT_V2 ||
aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_NONE) {
if (DjiTest_GimbalStartService() != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("psdk gimbal init error");
}
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_XPORT_ON
if (aircraftInfoBaseInfo.djiAdapterType == DJI_SDK_ADAPTER_TYPE_XPORT) {
if (DjiTest_XPortStartService() != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("psdk xport init error");
}
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_WIDGET_ON
#if DJI_USE_WIDGET_INTERACTION
returnCode = DjiTest_WidgetInteractionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget interaction test init error");
}
#else
returnCode = DjiTest_WidgetStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget sample init error");
}
#endif
#endif
#ifdef CONFIG_MODULE_SAMPLE_DATA_TRANSMISSION_ON
dataTransmissionConfig.isEnableLowSpeedDataChannel = true;
dataTransmissionConfig.isEnableHighSpeedDataChannel = DjiUser_CheckNetCableConnectStatus();
returnCode = DjiTest_DataTransmissionStartService(dataTransmissionConfig);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget sample init error");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_MOP_CHANNEL_ON
returnCode = DjiTest_MopChannelStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("mop channel sample init error");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_PAYLOAD_COLLABORATION_ON
returnCode = DjiTest_PayloadCollaborationStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Payload collaboration sample init error\n");
}
#endif
#ifdef CONFIG_MODULE_SAMPLE_UPGRADE_ON
T_DjiTestUpgradePlatformOpt linuxUpgradePlatformOpt = {
.rebootSystem = DjiUpgradePlatformLinux_RebootSystem,
.cleanUpgradeProgramFileStoreArea = DjiUpgradePlatformLinux_CleanUpgradeProgramFileStoreArea,
.createUpgradeProgramFile = DjiUpgradePlatformLinux_CreateUpgradeProgramFile,
.writeUpgradeProgramFile = DjiUpgradePlatformLinux_WriteUpgradeProgramFile,
.readUpgradeProgramFile = DjiUpgradePlatformLinux_ReadUpgradeProgramFile,
.closeUpgradeProgramFile = DjiUpgradePlatformLinux_CloseUpgradeProgramFile,
.replaceOldProgram = DjiUpgradePlatformLinux_ReplaceOldProgram,
.setUpgradeRebootState = DjiUpgradePlatformLinux_SetUpgradeRebootState,
.getUpgradeRebootState = DjiUpgradePlatformLinux_GetUpgradeRebootState,
.cleanUpgradeRebootState = DjiUpgradePlatformLinux_CleanUpgradeRebootState,
};
T_DjiTestUpgradeConfig testUpgradeConfig = {
.firmwareVersion = {1, 0, 0, 0},
.transferType = DJI_FIRMWARE_TRANSFER_TYPE_FTP,
.needReplaceProgramBeforeReboot = true
};
if (DjiTest_UpgradeStartService(&linuxUpgradePlatformOpt, testUpgradeConfig) !=
DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("psdk upgrade init error");
}
#endif
}
returnCode = DjiCore_ApplicationStart();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("start sdk application error");
}
if (pthread_create(&s_monitorThread, NULL, DjiUser_MonitorTask, NULL) != 0) {
USER_LOG_ERROR("create monitor task fail.");
}
if (pthread_setname_np(s_monitorThread, "monitor task") != 0) {
USER_LOG_ERROR("set name for monitor task fail.");
}
while (1) {
sleep(1);
}
}
/* Private functions definition-----------------------------------------------*/
static T_DjiReturnCode DjiUser_PrintConsole(const uint8_t *data, uint16_t dataLen)
{
USER_UTIL_UNUSED(dataLen);
printf("%s", data);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DjiUser_LocalWrite(const uint8_t *data, uint16_t dataLen)
{
int32_t realLen;
if (s_djiLogFile == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
realLen = fwrite(data, 1, dataLen, s_djiLogFile);
fflush(s_djiLogFile);
if (realLen == dataLen) {
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
} else {
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
}
static T_DjiReturnCode DjiUser_FillInUserInfo(T_DjiUserInfo *userInfo)
{
if (userInfo == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
memset(userInfo->appName, 0, sizeof(userInfo->appName));
memset(userInfo->appId, 0, sizeof(userInfo->appId));
memset(userInfo->appKey, 0, sizeof(userInfo->appKey));
@ -446,6 +448,7 @@ static T_DjiReturnCode DjiUser_FillInUserInfo(T_DjiUserInfo *userInfo)
strlen(USER_DEVELOPER_ACCOUNT) >= sizeof(userInfo->developerAccount) ||
strlen(USER_BAUD_RATE) > sizeof(userInfo->baudRate)) {
USER_LOG_ERROR("Length of user information string is beyond limit. Please check.");
sleep(1);
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
@ -457,6 +460,7 @@ static T_DjiReturnCode DjiUser_FillInUserInfo(T_DjiUserInfo *userInfo)
!strcmp(USER_BAUD_RATE, "your_baud_rate")) {
USER_LOG_ERROR(
"Please fill in correct user information to 'samples/sample_c/platform/linux/manifold2/application/dji_sdk_app_info.h' file.");
sleep(1);
return DJI_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
@ -471,11 +475,37 @@ static T_DjiReturnCode DjiUser_FillInUserInfo(T_DjiUserInfo *userInfo)
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DjiUser_PrintConsole(const uint8_t *data, uint16_t dataLen)
{
USER_UTIL_UNUSED(dataLen);
printf("%s", data);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode DjiUser_LocalWrite(const uint8_t *data, uint16_t dataLen)
{
uint32_t realLen;
if (s_djiLogFile == NULL) {
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
realLen = fwrite(data, 1, dataLen, s_djiLogFile);
fflush(s_djiLogFile);
if (realLen == dataLen) {
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
} else {
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
}
static T_DjiReturnCode DjiUser_LocalWriteFsInit(const char *path)
{
T_DjiReturnCode djiReturnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
char filePath[DJI_LOG_PATH_MAX_SIZE];
char systemCmd[DJI_SYSTEM_CMD_STR_MAX_SIZE];
char systemCmd[DJI_LOG_SYSTEM_CMD_MAX_SIZE];
char folderName[DJI_LOG_FOLDER_NAME_MAX_SIZE];
time_t currentTime = time(NULL);
struct tm *localTime = localtime(&currentTime);
@ -621,25 +651,4 @@ static T_DjiReturnCode DjiTest_WriteHighPowerApplyPin(E_DjiPowerManagementPinSta
#pragma GCC diagnostic pop
static bool DjiUser_CheckNetCableConnectStatus(void)
{
FILE *fp;
char *ret = NULL;
char systemCmd[DJI_SYSTEM_CMD_STR_MAX_SIZE] = {0};
char lineBuf[DJI_SYSTEM_RESULT_STR_MAX_SIZE] = {0};
sprintf(systemCmd, "ifconfig %s | grep RUNNING", LINUX_NETWORK_DEV);
fp = popen(systemCmd, "r");
if (fp == NULL) {
return false;
}
ret = fgets(lineBuf, sizeof(lineBuf), fp);
if (ret == NULL) {
return false;
}
return true;
}
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/

View File

@ -55,7 +55,6 @@ extern "C" {
/* Exported functions --------------------------------------------------------*/
T_DjiReturnCode HalNetWork_Init(const char *ipAddr, const char *netMask, T_DjiNetworkHandle *halObj);
T_DjiReturnCode HalNetWork_DeInit(T_DjiNetworkHandle halObj);
#ifdef __cplusplus

View File

@ -28,7 +28,7 @@
/* Private constants ---------------------------------------------------------*/
#define UART_DEV_NAME_STR_SIZE (128)
#define DJI_SYSTEM_CMD_STR_MAX_SIZE (64)
#define DJI_SYSTEM_CMD_MAX_SIZE (64)
#define DJI_SYSTEM_RESULT_STR_MAX_SIZE (128)
/* Private types -------------------------------------------------------------*/
@ -48,7 +48,7 @@ T_DjiReturnCode HalUart_Init(E_DjiHalUartNum uartNum, uint32_t baudRate, T_DjiUa
struct flock lock;
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
char uartName[UART_DEV_NAME_STR_SIZE];
char systemCmd[DJI_SYSTEM_CMD_STR_MAX_SIZE];
char systemCmd[DJI_SYSTEM_CMD_MAX_SIZE];
char *ret = NULL;
char lineBuf[DJI_SYSTEM_RESULT_STR_MAX_SIZE] = {0};
FILE *fp;

View File

@ -78,10 +78,6 @@ void DjiUser_StartTask(void const *argument)
T_DjiReturnCode returnCode;
T_DjiUserInfo userInfo;
T_DjiAircraftInfoBaseInfo aircraftInfoBaseInfo;
DjiTestDataTransmissionConfig dataTransmissionConfig = {
.isEnableHighSpeedDataChannel = false,
.isEnableLowSpeedDataChannel = true,
};
T_DjiOsalHandler osalHandler = {
.TaskCreate = Osal_TaskCreate,
.TaskDestroy = Osal_TaskDestroy,
@ -165,19 +161,6 @@ void DjiUser_StartTask(void const *argument)
goto out;
}
if (aircraftInfoBaseInfo.mountPosition == DJI_MOUNT_POSITION_EXTENSION_PORT) {
#if DJI_EXTENSION_PORT_SUPPORT
returnCode = DjiTest_DataTransmissionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("data transmission init error");
}
returnCode = DjiTest_WidgetStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget sample init error");
}
#endif
} else {
#ifdef CONFIG_MODULE_SAMPLE_POWER_MANAGEMENT_ON
T_DjiTestApplyHighPowerHandler applyHighPowerHandler = {
.pinInit = DjiTest_HighPowerApplyPinInit,
@ -218,7 +201,7 @@ void DjiUser_StartTask(void const *argument)
#endif
#ifdef CONFIG_MODULE_SAMPLE_DATA_TRANSMISSION_ON
returnCode = DjiTest_DataTransmissionStartService(dataTransmissionConfig);
returnCode = DjiTest_DataTransmissionStartService();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("widget sample init error");
}
@ -301,7 +284,6 @@ void DjiUser_StartTask(void const *argument)
printf("psdk upgrade init error");
}
#endif
}
returnCode = DjiCore_ApplicationStart();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {

View File

@ -34,34 +34,34 @@ extern "C" {
#endif
/* Exported constants --------------------------------------------------------*/
#define CONFIG_MODULE_SAMPLE_POWER_MANAGEMENT_ON
//#define CONFIG_MODULE_SAMPLE_POWER_MANAGEMENT_ON
#define CONFIG_MODULE_SAMPLE_CAMERA_ON
//#define CONFIG_MODULE_SAMPLE_DATA_TRANSMISSION_ON
#define CONFIG_MODULE_SAMPLE_WIDGET_ON
#ifdef USE_BOOTLOADER
//#ifdef USE_BOOTLOADER
//Attention: If you dont need to upgrade, you can uncomment it and change flash size from 0x70000 to 0xD0000 to build all functions.
#define CONFIG_MODULE_SAMPLE_UPGRADE_ON
#endif
//#define CONFIG_MODULE_SAMPLE_UPGRADE_ON
//#endif
#ifndef CONFIG_MODULE_SAMPLE_UPGRADE_ON
//#ifndef CONFIG_MODULE_SAMPLE_UPGRADE_ON
#define CONFIG_MODULE_SAMPLE_GIMBAL_ON
//#define CONFIG_MODULE_SAMPLE_GIMBAL_ON
#define CONFIG_MODULE_SAMPLE_DATA_TRANSMISSION_ON
//#define CONFIG_MODULE_SAMPLE_CAMERA_ON
#define CONFIG_MODULE_SAMPLE_FC_SUBSCRIPTION_ON
//#define CONFIG_MODULE_SAMPLE_FC_SUBSCRIPTION_ON
#define CONFIG_MODULE_SAMPLE_XPORT_ON
//#define CONFIG_MODULE_SAMPLE_XPORT_ON
#define CONFIG_MODULE_SAMPLE_PAYLOAD_COLLABORATION_ON
//#define CONFIG_MODULE_SAMPLE_PAYLOAD_COLLABORATION_ON
#define CONFIG_MODULE_SAMPLE_TIME_SYNC_ON
//#define CONFIG_MODULE_SAMPLE_TIME_SYNC_ON
#define CONFIG_MODULE_SAMPLE_POSITIONING_ON
//#define CONFIG_MODULE_SAMPLE_POSITIONING_ON
#endif
//#endif
/* Exported types ------------------------------------------------------------*/

View File

@ -500,6 +500,11 @@
</File>
<File>
<FileType>1</FileType>
<FileName>test_waypoint_v3.c</FileName>
<FilePath>..\..\..\..\..\module_sample\waypoint_v3\test_waypoint_v3.c</FilePath>
</File>
<File>
<FileType>1</FileType>
<FileName>test_widget.c</FileName>
<FilePath>..\..\..\..\..\module_sample\widget\test_widget.c</FilePath>
</File>
@ -510,6 +515,11 @@
</File>
<File>
<FileType>1</FileType>
<FileName>test_widget_speaker.c</FileName>
<FilePath>..\..\..\..\..\module_sample\widget\test_widget_speaker.c</FilePath>
</File>
<File>
<FileType>1</FileType>
<FileName>util_buffer.c</FileName>
<FilePath>..\..\..\..\..\module_sample\utils\util_buffer.c</FilePath>
</File>
@ -1025,6 +1035,11 @@
</File>
<File>
<FileType>5</FileType>
<FileName>dji_waypoint_v3.h</FileName>
<FilePath>..\..\..\..\..\..\..\psdk_lib\include\dji_waypoint_v3.h</FilePath>
</File>
<File>
<FileType>5</FileType>
<FileName>dji_widget.h</FileName>
<FilePath>..\..\..\..\..\..\..\psdk_lib\include\dji_widget.h</FilePath>
</File>