mcu_hi3321_watch/tjd/ble/ble_port_protocol.c
2025-05-26 20:15:20 +08:00

4089 lines
184 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* Copyright (c) Fenda Technologies Co., Ltd. 2022. All rights reserved.
*
* Description: ble_port_protocol.c
*
* Author: lzc
*
* Create: 2024-05-27
*--------------------------------------------------------------------------*/
#include "ble_port_protocol.h"
#include "ble_api.h"
#include "ble_port.h"
#include "bts_br_gap.h"
#include "bts_gatt_server.h"
#include "bts_le_gap.h"
#include "ctype.h"
#include "osal_addr.h"
#include "rtc_api.h"
#include "securec.h"
#include "sql_all.h"
#include "stdlib.h"
#include "string.h"
#include "sys_config.h"
#include "sys_typedef.h"
#include "time.h"
// #include "TjdUiMessagePopUpPage.h"
#include "fcntl.h"
#include "fs_api_ext.h"
#include "fs_user_common.h"
#include "linux/crc32.h"
#include "los_ringbuf.h"
#include "sys/statfs.h"
#include "unistd.h"
#include <stdio.h>
#include <sys/stat.h>
#include "power_display_service.h"
#include "service_bt.h"
#include "thread_init.h"
// #include "semaphore.h"
#include "upg_porting.h"
#include "osal_task.h"
#include "osal_semaphore.h"
#include "soc_osal.h"
#include <dirent.h>
#include "service_lucky_clover.h"
#include "broadcast_feature.h"
#include "service_charger.h"
#include "service_sleep.h"
#include "ble_protocol_file_download.h"
#include "ble_protocol_file_upload.h"
#include "bundle_install_msg.h"
#include "TjdAppStore.h"
#include "parameter.h"
#ifdef __cplusplus
extern "C"
{
#endif
#include "TjdUiAppCameraToC.h"
// #include "TjdUiWatchFaceCtrl.h"
#include "service_gps.h"
#ifdef __cplusplus
}
#endif
#define ENABLE_STATIC_PRINT 0
#define static_print_error(...) sys_bt_log_e(__VA_ARGS__) //错误信息打印一般常开
#define static_print_warn(...) sys_bt_log_w(__VA_ARGS__) //警告信息打印一般常开
#if ENABLE_STATIC_PRINT
#define static_print_debug(...) sys_bt_log_d(__VA_ARGS__)
#define static_print_info(...) sys_bt_log_i(__VA_ARGS__)
#else
#define static_print_debug(...)
#define static_print_info(...)
#endif
// #ifdef __cplusplus
// extern "C"
// {
// #endif
#define ENABLE_SWITCH 1
#define DISABLE_SWITCH 0
#define PROTOCOL_FRAME_HEAD 0xAB
#define PROTOCOL_FRAME_HEAD_2 0xAC
#define PROTOCOL_MAX_LEN 23
#define PROTOCOL_DATA_LEN 16
#define PROTOCOL_BUFFER_MAX_LEN 256
#define BT_MAC_ADDR_LEN 6
#define Day_Hours 24
#define MAX_CONTACTS 50
#define PACKET_DATA_SIZE 517
#define FILE_TRAN_RINGBUFFER_SIZE 5000
#define TJD_MAX_FILE_PATH_LEN 128
#define TJD_DEFAULT_FILE_PATH_LEN 64
#define F_OK 0
#define MTU_SIZE 517
#define FS_VOLUMES_NUM 4
#define FS_VOLUME_STRS "/system/", "/update/", "/music/", "/user/"
#define FS_VOLUME_USER "/user/"
#define FS_VOLUME_UPDATE "/update/"
#define FS_NODE_INFO_SPACE 16
#define CONTACTS_DATA_LEN 20
#define TJD_FS_DIR_GPS_BAT TJD_FS_DIR_GPS"bat"
#define PATH_MAX 4096
#define TJD_ADDRESS_BOOK_PATH "/user/tjd_phone/addressbook.bin"
#define TJD_SCREEN_RESOLUTION_HEIGHT 466
#define TJD_SCREEN_RESOLUTION_WEIGHT 466
#define TJD_QRCODE_TYPE_QQ 0x0c
// 宏定义用于设置分辨率
#define SET_RESOLUTION(data, index, resolution) \
do { \
(data)[(index)++] = (resolution >> 8) & 0xFF; \
(data)[(index)++] = (resolution) & 0xFF; \
} while (0)
// 宏定义用于设置分辨率的一半
#define SET_HALF_RESOLUTION(data, index, resolution) \
do { \
uint16_t half_resolution = (resolution) / 2; \
(data)[(index)++] = (half_resolution >> 8) & 0xFF; \
(data)[(index)++] = (half_resolution) & 0xFF; \
} while (0)
//宏定义用于数据拷贝
#define PROCESS_DATA(ctx, write_cb_para, data_index, write_len, remaining_size, rec_offset, total_len, cmd_id, server_id, conn_id) \
do { \
size_t copy_len = (remaining_size > write_len) ? write_len : remaining_size; \
memcpy_s((ctx).buffer + (rec_offset), (remaining_size), &(write_cb_para)[(data_index) + 2], (copy_len)); \
if ((ctx).buffer_offset != (rec_offset)) { \
static_print_error("ctx.buffer_offset != rec_offset"); \
free((ctx).buffer); \
(ctx).buffer = NULL; \
uint8_t data[2] = {0x00, (ctx).buffer_offset}; \
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), (cmd_id), (server_id), (conn_id)); \
(ctx).buffer_offset = 0; \
return; \
} \
(ctx).buffer_offset += copy_len; \
} while (0)
extern void TjdUiMsgCenterMessagePopUpTrigger(void);
extern void TjdUiMsgCenterFindDeviceTrigger(void);
extern uint32_t TjdUiWfGetNumberMax(void);
extern uint32_t* TjdUiWfGetIDList(uint32_t* len);
extern bool TjdUiWfGeUninstallbyID(uint32_t id); //表盘可卸载查询。=true可卸载;=false,不可卸载。
extern bool TjdUiWfDeletebyID(uint32_t id); //表盘删除通过ID
extern bool TjdUiWfInstallBeforNotify(uint32_t id); //表盘安装前通知
extern bool TjdUiWfInstallAfterNotify(uint32_t id);
extern bool TjdUiWfUninstallBeforNotify(uint32_t id); //表盘卸载前通知
extern bool TjdUiWfUninstallAfterNotify(uint32_t id); //表盘卸载后通知
extern bool TjdUiWfIsLocalID(uint32_t id); //表盘是否是本地表盘
extern DirDescriptionInfo_t *tjd_ble_get_dir_description(void);
extern FileTransferInfo_t *tjd_ble_get_transfer_info(void);
void tjd_ble_loop_send_data(uint8_t * pack_head_, uint8_t *data, uint16_t len, uint8_t cmd);
typedef struct
{
uint8_t year;
uint8_t month;
uint8_t dateth;
uint8_t hour;
uint8_t minute;
uint8_t second;
} TimeData;
typedef struct {
service_sleep_time_t time;
sleep_status_t status;
} sleep_status_dada;
typedef struct {
uint8_t flag; //0x00: 读 0x01: 写
uint16_t switch_data;
} set_read_function_switch_dada;
enum
{
SHORT_PROTOCOL = 0,
LONG_PROTOCOL = 1,
MAX_PROTOCOL
};
typedef void (*BLECreateQueueFunction_t)(void);
typedef struct {
osThreadAttr_t attr;
osThreadFunc_t func;
uint32_t *task_handle;
BLECreateQueueFunction_t create_queue_handle;
uint32_t use_mem;
} ble_task_definition_t;
// ble_task_definition_t g_ble_thread_upload_file_data = { { "thread_upload_file_data", 0, NULL, 0, NULL, (0x1000), (osPriority_t)(32), 0, 0 },
// (osThreadFunc_t)upload_file_data, NULL, NULL, USE_DTCM_MEM };
extern uint16_t gatt_server_id;
extern uint16_t g_server_conn_id;
extern uint16_t g_server_handle;
extern const bd_addr_t g_conn_addr;
extern bool g_tjd_ble_into_camera_flag;
bool g_tjd_ble_ai_audio_trans_flag = false;
uint8_t g_res_protoclo_title = 0;
uint8_t g_tjd_ble_data_flow_id = 0;
static uint16_t g_dial_push_data_pkg = 0;
static uint16_t g_wallpaper_push_data_pkg = 0;
static uint16_t g_contacts_push_data_pkg = 0;
static uint16_t g_qrcode_push_data_pkg = 0;
static uint8_t g_dial_push_data_mask = 0; // 表盘推送数据标志位
static uint8_t g_wallpaper_push_data_mask = 0; // 壁纸推送数据标志位
static uint8_t g_contacts_push_data_mask = 0; // 壁纸推送数据标志位
static uint8_t g_qrcode_push_data_mask = 0; // 二维码推送数据标志位
static bool g_fiel_decription_push_data_mask = false; // 文件描述数据推送标志位
static bool g_weather_data_mask = false; // 天气数据推送标志位
static bool g_weather_today_synchronization_data_mask = false; // 天气今日同步数据标志位
static bool g_dial_parameters_data_mask = false; // 表盘数据推送标志位
// uint8_t * ota_upgrade_data_pkg = NULL;
UpgradeContext upgrade_context;
UpgradeContext dial_context;
UpgradeContext wallpaper_context;
UpgradeContext contacts_context;
UpgradeContext addr_context;
UpgradeContext message_context;
UpgradeContext qrcode_context;
UpgradeContext lucky_flover_context;
UpgradeContext weather_data_context;
UpgradeContext dial_parameters_data_context;
uint32_t g_upload_breakpoint_resume_offset = 0; // 文件上传断点续传切换偏移值
static uint16_t g_file_trasmit_breakpoint_len = 0;
custom_dial_parameter_t dial_param = {0};
static lefun_ai_data_callback_t g_lefun_ai_data_callback = NULL;
static lefun_ai_data_callback_t g_lefun_ai_data_end_callback = NULL;
static fine_phone_end_callback_t g_fine_phone_end_callback = NULL;
static play_dial_original_callback_t g_play_dial_original_callback = NULL;
static play_dial_preview_callback_t g_play_dial_preview_callback = NULL;
static play_dial_request_generate_picture_callback_t g_play_dial_request_generate_picture_callback = NULL;
struct data_flow g_data_flow = {
.data_flow_id = 0,
.data_flow_type = 0,
.data = NULL,
.len = 0,
};
uint8_t pack_data[64] = {0};
Packet g_packet_data = {
.pck_data = pack_data,
.pck_len = 0,
};
// Ringbuf g_file_transport_ringbuf_ctrl = {0};
// static char *g_file_transport_ringbuf = NULL;
// static char g_file_transport_ringbuf[FILE_TRAN_RINGBUFFER_SIZE] = {0};
static uint16_t ring_buffer_size = 0;
static const char * const g_volume_names[FS_VOLUMES_NUM] = { FS_VOLUME_STRS };
Contact contacts[MAX_CONTACTS];
file_append_data_t file_append_data = {0};
// breakpoint_info_t g_ota_breakpoint_info = {0};
// static const uint8_t g_ble_send_protocol_cmd[][2] = {
// [0] = {0x5A, 0x04, 0x8C, 0x05},
// // [1] = {0x5B, 0x5A}
// };
// CRC-8 查表
static const uint8_t crc8_table[256] = {
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};
// 查表计算法计算crc
uint8_t do_crc(uint8_t *ptr, uint32_t len)
{
uint8_t i;
uint8_t crc = 0x00;
while (len--) {
crc = crc8_table[(crc ^ *ptr++) & 0xFF];
}
return crc;
}
// 分块读取文件并计算CRC32值的函数
uint32_t calculateFileCRC32(const char *filename, size_t fileSize)
{
const size_t bufferSize = 4096; // 缓冲区大小,可根据实际情况调整
uint8_t *buffer = malloc(bufferSize);
if (buffer == NULL) {
static_print_error("malloc failed");
return 0; // 或者返回一个错误CRC32值
}
memset_s(buffer, bufferSize, 0, bufferSize);
uint32_t crc32Value = 0xffffffff; // 初始CRC32值
size_t offset = 0; // 当前读取位置
int32_t fd = open(filename, O_RDONLY);
if (fd < 0) {
static_print_error("open file failed");
free(buffer);
buffer = NULL;
return 0; // 或者返回一个错误CRC32值
}
int ret = 0;
while (offset < fileSize) {
size_t bytesToRead = (fileSize - offset > bufferSize) ? bufferSize : (fileSize - offset);
ret = lseek(fd, offset, SEEK_SET);
size_t bytesRead = read(fd, buffer, bytesToRead);
if(bytesRead == 0){
break;
}
// 更新CRC32
crc32Value = crc32(crc32Value, buffer, bytesRead);
offset += bytesRead;
// static_print_debug("offset : %d, bytesToRead : %d, bytesRead : %d, crc32Value : %8x", offset, bytesToRead, bytesRead, crc32Value);
}
close(fd);
// 释放内存
free(buffer);
buffer = NULL;
return crc32Value;
}
// 文件装载
uint32_t tjd_ble_load_file_data(const char *path, uint32_t oft, void *buffer, uint32_t size)
{
int ret = RET_SUCCESS;
// int len;
static_print_debug("tjd_fs_api_file_load_1:%s-%d-%d\r\n",path,oft,size);
FILE * fp = fopen(path, "rb");
if(fp == NULL) {
static_print_error("fopen %s failed!", path);
return ret;
}
if(oft >= 0) {
ret = fseek(fp, oft, SEEK_SET);
if(ret != 0) {
static_print_error("fseek %d oft file data failed! ret : %d" , oft , ret);
fclose(fp);
fp = NULL;
return ret;
}
}
if(size > 0) {
ret = fread(buffer, size, 1 , fp);
if(ret != 1){
static_print_error("fread %d size file data failed! ret : %d" , size , ret);
fclose(fp);
fp = NULL;
return ret;
}
}
fclose(fp);
return ret;
}
static char *hex_to_string(const char *hex_str)
{
size_t len = strlen(hex_str);
if (len % 3 != 0) {
static_print_error("Error: Hex string length must be odd number.");
return NULL;
}
size_t str_len = len / 3;
char *decoded_str = (char *)malloc(str_len + 1); // +1 for null terminator
if (decoded_str == NULL) {
static_print_error("Error: Failed to allocate memory for decoded string.");
return NULL;
}
decoded_str[str_len] = '\0';
for (size_t i = 0, j = 0; i < len; i += 2, ++j) {
char byte[3] = {hex_str[i], hex_str[i + 1], '\0'};
decoded_str[j] = strtol(byte, NULL, 16);
}
return decoded_str;
}
//获取文件大小
int tjd_ble_get_file_size(const char *filename)
{
int len = 0;
// FILE *fp = fopen(filename, "rb");
// if (fp == NULL) {
// static_print_error("fopen %s failed", filename);
// return 0;
// }
// fseek(fp, 0, SEEK_END);
// len = ftell(fp);
// fseek(fp, 0, SEEK_SET);
// fclose(fp);
struct stat fileStat = {0};
int ret = stat(filename,&fileStat);
if(ret == 0){
len = fileStat.st_size;
}
static_print_debug(" %s len:%d", filename ,len);
return len;
}
//删除文件
int tjd_remove_rsvd_part(char *base_dir, char *filename)
{
char file_path[TJD_MAX_FILE_PATH_LEN] = {0};
int size = sprintf_s(file_path, sizeof(file_path), "%s/%s", base_dir, filename);
if (size < 0) {
return -1;
}
int ret = unlink(file_path);
if (ret < 0) {
return -1;
} else {
return 0;
}
}
// 安全地拼接路径
char* safe_path_join(const char *path, const char *name) {
char *result = malloc(PATH_MAX);
if (result == NULL) {
static_print_error("malloc error");
return NULL;
}
snprintf(result, PATH_MAX, "%s/%s", path, name);
return result;
}
// 删除单个文件或目录
int delete_file_or_directory(const char *path) {
struct stat st;
if (stat(path, &st) == -1) {
static_print_error("stat error");
return -1;
}
if (S_ISREG(st.st_mode)) {
if (remove(path) == -1) {
static_print_error("remove error");
return -1;
}
} else if (S_ISDIR(st.st_mode)) {
if (rmdir(path) == -1) {
static_print_error("rmdir error");
return -1;
}
} else {
fprintf(stderr, "Unsupported file type: %s\n", path);
return -1;
}
return 0;
}
// 递归删除目录
int delete_directory(const char *path)
{
DIR *dir;
struct dirent *entry;
if ((dir = opendir(path)) == NULL) {
static_print_error("opendir error");
return -1;
}
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char *fullPath = safe_path_join(path, entry->d_name);
if (fullPath == NULL) {
closedir(dir);
return -1;
}
if (delete_file_or_directory(fullPath) == -1) {
free(fullPath);
closedir(dir);
return -1;
}
free(fullPath);
}
closedir(dir);
// 最后删除当前目录
if (rmdir(path) == -1) {
static_print_error("rmdir error");
return -1;
}
return 0;
}
// 应答封包
static Packet *tjd_ble_protocol_pack_data(uint8_t pack_head,uint8_t *data, uint16_t len, uint8_t cmd_id)
{
uint8_t res_data[PROTOCOL_MAX_LEN] = {0};
uint16_t res_data_len = 0;
res_data[0] = pack_head;
if (res_data[0] == PROTOCOL_RES_FRAME_HEAD) {
res_data_len = 0x04 + len;
res_data[1] = 0x04 + len;
res_data[2] = cmd_id;
memcpy_s(&res_data[3], PROTOCOL_DATA_LEN, data, (size_t)len);
} else if (res_data[0] == PROTOCOL_RES_FRAME_HEAD_2) {
res_data_len = 0x05 + len;
res_data[1] = res_data_len >> 8;
res_data[2] = res_data_len & 0xff;
res_data[3] = cmd_id;
memcpy_s(&res_data[4], PROTOCOL_DATA_LEN, data, (size_t)len);
}
res_data[res_data_len - 1] = do_crc(res_data, res_data_len - 1);
memset(g_packet_data.pck_data, 0, PROTOCOL_MAX_LEN);
memcpy_s(g_packet_data.pck_data, PROTOCOL_MAX_LEN, res_data, res_data_len);
g_packet_data.pck_len = res_data_len;
// static_print_debug("pack data len: %d", pkt->pck_len);
return &g_packet_data;
}
// 主动封包
static Packet *tjd_ble_protocol_pack_data_with_malloc(uint8_t * pack_head , uint8_t *data, uint16_t len, uint8_t cmd_id)
{
uint8_t res_data[PROTOCOL_BUFFER_MAX_LEN] = {0};
uint16_t res_data_len = 0;
res_data[0] = *pack_head;
if (res_data[0] == PROTOCOL_RES_FRAME_HEAD) {
res_data_len = 0x04 + len;
res_data[1] = 0x04 + len;
res_data[2] = cmd_id;
memcpy(&res_data[3], data, (size_t)len);
} else if (res_data[0] == PROTOCOL_RES_FRAME_HEAD_2) {
res_data_len = 0x05 + len;
res_data[1] = res_data_len >> 8;
res_data[2] = res_data_len & 0xff;
res_data[3] = cmd_id;
memcpy(&res_data[4], data, (size_t)len);
}
res_data[res_data_len - 1] = do_crc(res_data, res_data_len - 1);
Packet *pkt = malloc(sizeof(Packet));
if (pkt == NULL) {
static_print_error("pkt is NULL");
return NULL;
}
pkt->pck_data = malloc(res_data_len);
if (pkt->pck_data == NULL) {
static_print_error("pkt.pck_data is NULL");
return NULL;
}
memcpy(pkt->pck_data, res_data, res_data_len);
pkt->pck_len = res_data_len;
// static_print_debug("pack data len: %d", pkt->pck_len);
return pkt;
}
void gatt_send_response(uint8_t *res_value, uint16_t res_len, uint8_t server_id, uint16_t conn_id)
{
gatts_ntf_ind_t param = {0};
param.attr_handle = g_server_handle;
param.value = (uint16_t *)malloc(res_len);
if (param.value == NULL) {
static_print_error("param.value is NULL");
return;
}
memcpy_s(param.value, res_len, res_value, res_len);
// param.value = res_value;
param.value_len = res_len;
static_print_debug("gatt_send_response(server_id:%d,conn_id:%d),res_len=%d", server_id, conn_id, res_len);
for (int i = 0; i < param.value_len;) {
static_print_info("%02x", param.value[i]);
i++;
if(i % 10 == 0){
static_print_info("\r\n");
}
if(i >= 30) {break;}
}
static_print_info("\r\n");
errcode_t ret;
ret = gatts_notify_indicate(server_id, conn_id, &param);
static_print_info("gatts_notify_indicate()=%d\r\n", ret);
free(param.value);
return;
}
// 封包,发送数据
void tjd_ble_protocol_send_data(uint8_t pack_head,uint8_t *data, uint16_t len, uint8_t cmd_id, uint8_t server_id, uint16_t conn_id)
{
Packet *notify_data = tjd_ble_protocol_pack_data(pack_head, data, len, cmd_id);
if (notify_data == NULL) {
static_print_error("pkt is NULL");
return;
}
gatt_send_response(notify_data->pck_data, notify_data->pck_len, server_id, conn_id);
// free(notify_data->pck_data);
// free(notify_data);
return;
}
// 封包,发送数据,释放堆内存
void tjd_ble_protocol_send_lefun_data(uint8_t *pack_head, uint8_t *data, uint16_t len, uint8_t cmd_id)
{
Packet *notify_data = tjd_ble_protocol_pack_data_with_malloc(pack_head, data, len, cmd_id);
if (notify_data == NULL) {
static_print_error("pkt is NULL");
return;
}
gatt_send_response(notify_data->pck_data, notify_data->pck_len,gatt_server_id,g_server_conn_id);
free(notify_data->pck_data);
free(notify_data);
return;
}
void handle_device_dial_information_cmd(uint8_t server_id, uint16_t conn_id, uint8_t * write_cb_para, uint16_t len, uint8_t cmd_id)
{
static_print_debug("upload device_dial_information");
uint32_t device_dial_support_num = TjdUiWfGetNumberMax();
uint32_t device_dial_cur_num = 0;
uint32_t * watchfaceidarray = TjdUiWfGetIDList(&device_dial_cur_num);
// device_dial_cur_num--;
uint8_t ltv_type_num = 2;
static_print_info("watchfaceidarray data ");
for(int i = 0; i < device_dial_cur_num; i++){
static_print_info("%d ", watchfaceidarray[i]);
if(i % 4 == 0){
static_print_info("\n");
}
static_print_info("\n");
}
static_print_debug("device_dial_support_num: %d , cur_num: %d", device_dial_support_num, device_dial_cur_num);
uint8_t lt_len = 2 * ((device_dial_cur_num * ltv_type_num) + 1); // 2 : type + len 6: FileDescriptionPacket的字段个数
uint16_t data_len = lt_len + 1 + ((sizeof(uint32_t) + sizeof(uint8_t)) * device_dial_cur_num);
uint8_t *device_dial_info_data = malloc(data_len);
memset_s(device_dial_info_data, data_len, 0, data_len);
int data_index = 0;
device_dial_info_data[data_index++] = sizeof(uint8_t) + 2;
device_dial_info_data[data_index++] = 0x01;
device_dial_info_data[data_index++] = device_dial_support_num;
for(int i = 0 ; i < device_dial_cur_num; i++){
// static_print_debug("%s , line is %d", __FUNCTION__, __LINE__);
device_dial_info_data[data_index++] = sizeof(watchfaceidarray[i]) + 2;
device_dial_info_data[data_index++] = 0x10;
// memcpy_s(&device_dial_info_data[data_index], 4, &watchfaceidarray[i], 4);
device_dial_info_data[data_index++] = (watchfaceidarray[i] >> 24) & 0xFF;
device_dial_info_data[data_index++] = (watchfaceidarray[i] >> 16) & 0xFF;
device_dial_info_data[data_index++] = (watchfaceidarray[i] >> 8) & 0xFF;
device_dial_info_data[data_index++] = watchfaceidarray[i] & 0xFF;
device_dial_info_data[data_index++] = 0x03;
device_dial_info_data[data_index++] = 0x11;
device_dial_info_data[data_index++] = TjdUiWfGeUninstallbyID(watchfaceidarray[i]) ? 0x01 : 0x00;
}
uint8_t *sub_package_data = malloc(data_len + 5);
int index = 0;
sub_package_data[index++] = PROTOCOL_RES_FRAME_HEAD_2;
sub_package_data[index++] = (data_len + 5) >> 8;
sub_package_data[index++] = (data_len + 5) & 0xff;
sub_package_data[index++] = cmd_id;
memcpy_s(&sub_package_data[index], data_len, &device_dial_info_data[0],
data_len);
index += data_len;
sub_package_data[index] = do_crc(sub_package_data, data_len + 4);
gatt_send_response(sub_package_data, data_len + 5,gatt_server_id,g_server_conn_id);
free(sub_package_data);
sub_package_data = NULL;
free(device_dial_info_data);
device_dial_info_data = NULL;
}
void handle_app_issue_dial_parameters_cmd(uint8_t server_id, uint16_t conn_id, uint8_t * write_cb_para, uint16_t len, uint8_t cmd_id)
{
static_print_debug("app issue dial parameters data");
for(int i = 0 ; i < len; i++){
static_print_info("%02x", write_cb_para[i]);
if( i % 10 == 0){
static_print_info("\r\n");
}
}
static_print_info("\r\n");
uint8_t data_index = 4;
uint8_t dial_parameters_data_total_len = write_cb_para[data_index];
uint8_t rec_dial_parameters_data_offset = write_cb_para[data_index + 1];
uint16_t write_len = len - 7;
uint16_t remaining_size = dial_parameters_data_total_len - rec_dial_parameters_data_offset;
if (!g_dial_parameters_data_mask) {
// static_print_debug("%s , line is %d", __FUNCTION__, __LINE__);
memset_s(&dial_parameters_data_context, sizeof(dial_parameters_data_context), 0, sizeof(dial_parameters_data_context));
dial_parameters_data_context.buffer_offset = 0;
dial_parameters_data_context.buffer = (uint8_t *)malloc(dial_parameters_data_total_len);
memset_s(dial_parameters_data_context.buffer, dial_parameters_data_total_len, 0, dial_parameters_data_total_len);
static_print_debug("weather_data_total_len : %d, rec_weather_data_offset : %d", dial_parameters_data_total_len,
rec_dial_parameters_data_offset);
PROCESS_DATA(dial_parameters_data_context,write_cb_para,data_index,write_len,remaining_size,
rec_dial_parameters_data_offset,dial_parameters_data_total_len,cmd_id,server_id,conn_id);
g_dial_parameters_data_mask = true;
} else {
PROCESS_DATA(dial_parameters_data_context,write_cb_para,data_index,write_len,remaining_size,
rec_dial_parameters_data_offset,dial_parameters_data_total_len,cmd_id,server_id,conn_id);
}
if (dial_parameters_data_context.buffer_offset == dial_parameters_data_total_len) {
g_dial_parameters_data_mask = false;
// uint8_t setting_pattern = 0;
// uint8_t images_number = 0;
// uint8_t switching_mode = 0;
static_print_info("dial_parameters_data : \n");
for(int i = 0; i < dial_parameters_data_total_len ; i++){
static_print_info(" %02x",dial_parameters_data_context.buffer[i]);
}
static_print_info("\n");
for (int i = 0; i < dial_parameters_data_total_len;) { // 遍历表盘参数数据
uint8_t len = dial_parameters_data_context.buffer[i];
uint8_t type = dial_parameters_data_context.buffer[i + 1];
// static_print_debug("i : %u, type : %u, len : %u", i, type, len);
switch (type) {
case 0x83: { // uint8_t设置模式
// setting_pattern = dial_parameters_data_context.buffer[i + 2];
// static_print_debug("setting_pattern : %u", setting_pattern);
dial_param.setting_mode = dial_parameters_data_context.buffer[i + 2];
static_print_debug("setting_mode : %u",dial_param.setting_mode);
break;
}
case 0x84: { // uint8_t多图文件中图片数量
// images_number = dial_parameters_data_context.buffer[i + 2];
// static_print_debug("images_number : %u", images_number);
dial_param.images_number = dial_parameters_data_context.buffer[i + 2];
static_print_debug("images_number : %u",dial_param.images_number);
break;
}
case 0x85: { // uint8_t多图切换方式
// switching_mode = dial_parameters_data_context.buffer[i + 2];
// static_print_debug("switching_mode : %u", switching_mode);
dial_param.switching_mode = dial_parameters_data_context.buffer[i + 2];
static_print_debug("switching_mode : %u",dial_param.switching_mode);
break;
}
default: {
static_print_error("unknown type : %u", type);
break;
}
}
i += len;
}
free(dial_parameters_data_context.buffer);
uint8_t data[2] ={0};
data[0] = 0x02;
data[1] = dial_parameters_data_context.buffer_offset & 0xFF;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
dial_parameters_data_context.buffer = NULL;
dial_parameters_data_context.buffer_offset = 0;
dial_parameters_data_context.expected_seq = 0;
return;
} else {
uint8_t data[2] ={0};
data[0] = 0x01;
data[1] = dial_parameters_data_context.buffer_offset & 0xFF;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
return;
}
}
void handle_weather_data_cmd(uint8_t server_id, uint16_t conn_id, uint8_t * write_cb_para, uint16_t len, uint8_t cmd_id)
{
// uint8_t weather_data_total_len = write_cb_para[4];
// uint8_t cur_offest = write_cb_para[5];
// uint16_t data_len = len - 7;
static_print_debug("weather data :");
for(int i = 0 ; i < len; i++){
static_print_info("%02x", write_cb_para[i]);
if( i % 10 == 0){
static_print_info("\r\n");
}
}
static_print_info("\r\n");
uint8_t data_index = 4;
uint16_t weather_data_total_len = write_cb_para[data_index] << 8 | write_cb_para[data_index + 1];
uint16_t rec_weather_data_offset = write_cb_para[data_index + 2] << 8| write_cb_para[data_index + 3];
uint16_t write_len = len - 7;
uint16_t remaining_size = weather_data_total_len - rec_weather_data_offset;
if (!g_weather_data_mask) {
// static_print_debug("%s , line is %d", __FUNCTION__, __LINE__);
memset_s(&weather_data_context, sizeof(weather_data_context), 0, sizeof(weather_data_context));
weather_data_context.buffer_offset = 0;
weather_data_context.buffer = (uint8_t *)malloc(weather_data_total_len);
memset_s(weather_data_context.buffer, weather_data_total_len, 0, weather_data_total_len);
static_print_debug("weather_data_total_len : %d, rec_weather_data_offset : %d", weather_data_total_len,
rec_weather_data_offset);
if(remaining_size > write_len){
memcpy_s(weather_data_context.buffer + rec_weather_data_offset,
weather_data_total_len - rec_weather_data_offset, &write_cb_para[data_index + 4], write_len);
}else{
memcpy_s(weather_data_context.buffer + rec_weather_data_offset,
weather_data_total_len - rec_weather_data_offset, &write_cb_para[data_index + 4],
weather_data_total_len - rec_weather_data_offset);
}
if (weather_data_context.buffer_offset != rec_weather_data_offset) {
static_print_error("weather_data_context.buffer_offset != rec_weather_data_offset");
free(weather_data_context.buffer);
weather_data_context.buffer = NULL;
uint8_t data[2] = {0x00 , weather_data_context.buffer_offset};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
weather_data_context.buffer_offset = 0;
return;
}
weather_data_context.buffer_offset += weather_data_total_len - rec_weather_data_offset;
g_weather_data_mask = true;
} else {
// static_print_debug("%s , line is %d", __FUNCTION__, __LINE__);
if(remaining_size > write_len){
memcpy_s(weather_data_context.buffer + rec_weather_data_offset,
remaining_size, &write_cb_para[data_index + 4], write_len);
}else{
memcpy_s(weather_data_context.buffer + rec_weather_data_offset,
remaining_size, &write_cb_para[data_index + 4], remaining_size);
}
if (weather_data_context.buffer_offset != rec_weather_data_offset) {
static_print_error("weather_data_context.buffer_offset != rec_weather_data_offset");
free(weather_data_context.buffer);
weather_data_context.buffer = NULL;
uint8_t data[2] = {0x00 , weather_data_context.buffer_offset};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
weather_data_context.buffer_offset = 0;
return;
}
weather_data_context.buffer_offset += weather_data_total_len - rec_weather_data_offset;
}
if (weather_data_context.buffer_offset == weather_data_total_len) {
static uint8_t cur_date = 0;
g_weather_data_mask = false;
// for(int i = 0; i < file_description_len; i++){
// static_print_debug("file_description_buffer[%d] : %02x", i,file_decription_context.buffer[i]);
// }
// 表盘LTV文件描述如 0301040602123456780603F1F1F1F10804313233343536
// 0301040602123456780603F1F1F1F10804313233343536
// for(int i = 0 ; i < weather_data_total_len; i++){
// static_print_debug("weather_data_buffer[%d] : %02x", i,weather_data_context.buffer[i]);
// }
for (int i = 0; i < weather_data_total_len;) { // 遍历天气数据
uint8_t len = weather_data_context.buffer[i];
uint8_t type = weather_data_context.buffer[i + 1];
// static_print_debug("i : %u, type : %u, len : %u", i, type, len);
switch (type) {
case 0x01: { // 天气时间类型
cur_date = weather_data_context.buffer[i + 2];
static_print_debug("cur_date : %u", cur_date);
break;
}
case 0x02: { // 和风天气类型
// memcpy_s(&g_file_description_packet.file_size, sizeof(g_file_description_packet.file_size),
// &file_decription_context.buffer[i + 2], len - 2);
sql_weather_set_forecast_protocol_value(cur_date, weather_data_context.buffer[i + 2]);
static_print_debug("set_forecast_protocol_value : %u ", weather_data_context.buffer[i + 2]);
break;
}
case 0x03: { // 当前温度
// memcpy_s(&g_file_description_packet.file_crc32, sizeof(g_file_description_packet.file_crc32),
// &file_decription_context.buffer[i + 2], len - 2);
if(cur_date == 0){
sql_weather_set_now_temperature(weather_data_context.buffer[i + 2]);
static_print_debug("set_now_temperature : %u", weather_data_context.buffer[i + 2]);
}
break;
}
case 0x04: { // 最高温度
sql_weather_set_forecast_temperature_max(cur_date, weather_data_context.buffer[i + 2]);
static_print_debug("set_forecast_temperature_max : %u", weather_data_context.buffer[i + 2]);
break;
}
case 0x05: { // 最低温度
sql_weather_set_forecast_temperature_min(cur_date, weather_data_context.buffer[i + 2]);
static_print_debug("set_forecast_temperature_min : %u", weather_data_context.buffer[i + 2]);
break;
}
case 0x06: { // 湿度
if(cur_date == 0){
sql_weather_set_humidity(weather_data_context.buffer[i + 2]);
static_print_debug("humidity : %u", weather_data_context.buffer[i + 2]);
}
break;
}
case 0x07: { // 风速
if(cur_date == 0){
sql_weather_set_wind_speed(weather_data_context.buffer[i + 2]);
static_print_debug("wind_speed : %u", weather_data_context.buffer[i + 2]);
}
break;
}
case 0x08: { //位置信息
// sql_weather_set_location(write_cb_para[i + 2]);
char location[32] = {0};
memcpy_s(location, sizeof(location), &weather_data_context.buffer[i + 2], len - 2);
static_print_debug("location : %s", location);
break;
}
case 0x09: { //降雨量
int16_t rain_value = weather_data_context.buffer[i + 2] << 8 | weather_data_context.buffer[i + 3];
// memcpy_s(&rain_value, sizeof(rain_value), &weather_data_context.buffer[i + 2], len - 2);
static_print_debug("rain_value : %u", rain_value);
break;
}
case 0x10: { //日出时间 日落时间
int16_t sunrise_time = weather_data_context.buffer[i + 2] << 8 | weather_data_context.buffer[i + 3];
// memcpy_s(&sunrise_time, sizeof(sunrise_time), &weather_data_context.buffer[i + 2], sizeof(sunrise_time));
int16_t sunset_time = weather_data_context.buffer[i + 4] << 8 | weather_data_context.buffer[i + 5];
// memcpy_s(&sunset_time, sizeof(sunset_time), &weather_data_context.buffer[i + 2 + sizeof(sunrise_time)],sizeof(sunset_time));
static_print_debug("sunrise_time : %u , sunset_time : %u ", sunrise_time , sunset_time);
if(cur_date == 0){
sql_weather_set_sunrise_time(sunrise_time);
sql_weather_set_sunset_time(sunset_time);
}
break;
}
case 0x11: { //气压
int16_t pressure = weather_data_context.buffer[i + 2] << 8 | weather_data_context.buffer[i + 3];
// memcpy_s(&pressure, sizeof(pressure), &weather_data_context.buffer[i + 2], len - 2);
static_print_debug("pressure : %u", pressure);
break;
}
case 0x12: { //海拔
int16_t altitude = weather_data_context.buffer[i + 2] << 8 | weather_data_context.buffer[i + 3];
// memcpy_s(&altitude, sizeof(altitude), &weather_data_context.buffer[i + 2], len - 2);
static_print_debug("altitude : %u", altitude);
break;
}
default: {
static_print_error("unknown type : %u", type);
break;
}
}
i += len;
}
free(weather_data_context.buffer);
uint8_t data[3] ={0};
data[0] = 0x02;
data[1] = weather_data_context.buffer_offset << 8;
data[2] = weather_data_context.buffer_offset & 0xFF;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
weather_data_context.buffer = NULL;
weather_data_context.buffer_offset = 0;
weather_data_context.expected_seq = 0;
g_weather_today_synchronization_data_mask = true;
struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops();
struct rtc_time tm_info = {0};
rtc_api->get_rtc_time(&tm_info);
sql_weather_set_update_hour(tm_info.tm_hour);
sql_weather_set_update_minute(tm_info.tm_min);
return;
} else {
uint8_t data[3] ={0};
data[0] = 0x01;
data[1] = weather_data_context.buffer_offset << 8;
data[2] = weather_data_context.buffer_offset & 0xFF;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
return;
}
}
static void handle_push_data_cmd(UpgradeContext *upgrade_context, uint8_t cmd, uint16_t * push_data_pkg,
uint8_t *write_cb_para, uint16_t len ,uint8_t server_id, uint8_t conn_id)
{
// TODO: 接收表盘推送数据
uint16_t received_seq = (write_cb_para[2] << 8) | write_cb_para[3];
if (received_seq != upgrade_context->expected_seq) {
// 错误处理:包序号不匹配
static_print_debug("received_seq(%d) != expected_seq(%d)", received_seq, upgrade_context->expected_seq);
// 通知app接收表盘推送失败
// uint8_t data[6] = {0};
// data[0] = 0x5A;
// data[1] = cmd;
// data[2] = (received_seq >> 8) & 0xFF;
// data[3] = received_seq & 0xFF;
// data[4] = 0x00;
// data[5] = do_crc(data, 5);
// gatt_send_response(data, sizeof(data), server_id, conn_id);
}
memcpy_s(upgrade_context->buffer + upgrade_context->buffer_offset, PACKET_DATA_SIZE, &write_cb_para[4],
len - 4);
upgrade_context->buffer_offset += (len - 4);
upgrade_context->expected_seq++;
// 回复app接收壁纸推送成功
// uint8_t data[5] = {0};
// data[0] = 0x5A;
// data[1] = cmd;
// data[2] = (received_seq >> 8) & 0xFF;
// data[3] = received_seq & 0xFF;
// data[4] = 0x01;
// // data[5] = do_crc(data, 5);
// gatt_send_response(data, sizeof(data), server_id, conn_id);
static_print_debug("receive data success, prepare to send next data ! expected seq: %d , push_data_pkg : %d " , upgrade_context->expected_seq , *push_data_pkg);
if (*push_data_pkg == upgrade_context->expected_seq) {
// push_data_mask = 0;
// if (g_contacts_push_data_mask) {
static_print_debug("contacts push data mask is true, prepare to analyze data");
for(int i = 0; i < upgrade_context->buffer_offset; i++){
static_print_debug("contacts data : %02x", upgrade_context->buffer[i]);
}
// TODO: 解析contacts推送数据
if(cmd == CONTACTS_PUSH_DATA_COMMAND){
memset(contacts, 0 , sizeof(contacts));
int num_contacts = 0;
// Check start and end markers
if (strncmp((const char *)upgrade_context->buffer, "{*$#", 4) != 0 ||
strstr((const char *)upgrade_context->buffer, "#$*}") == NULL) {
static_print_debug("Invalid data format");
return;
}
char *token = strtok((char *)upgrade_context->buffer + 4, "[@");
while (token != NULL && num_contacts < MAX_CONTACTS) {
if (sscanf(token, "%hhu%49[^%&]%*[^&]&%14s", &contacts[num_contacts].id, contacts[num_contacts].name,
contacts[num_contacts].phone) != 3) {
printf("Failed to parse contact data");
return;
}
// 去除phone字段末尾的特殊字符
char *end = contacts[num_contacts].phone + strlen(contacts[num_contacts].phone) - 1;
while (end >= contacts[num_contacts].phone && !isdigit(*end)) {
*end = '\0'; // 将非数字字符替换为字符串结束符
end--;
}
num_contacts++;
token = strtok(NULL, "[@");
}
for (int i = 0; i < num_contacts; ++i) {
static_print_debug("Contact %d: ID=%d, Name=%s, Phone=%s", i + 1, contacts[i].id,
contacts[i].name, contacts[i].phone);
}
static_print_debug("receive all data, exit dial push data mask");
static_print_debug("upgrade_context.buffer_offset: %d, push_data_pkg: %d, upgrade_context.expected_seq: %d",
upgrade_context->buffer_offset, *push_data_pkg, upgrade_context->expected_seq);
file_append_data.buffer = contacts;
file_append_data.size = num_contacts;
tjd_service_contact_append(&file_append_data);
}
free(upgrade_context->buffer);
upgrade_context->buffer = NULL;
upgrade_context->buffer_offset = 0;
upgrade_context->expected_seq = 0;
*push_data_pkg = 0;
}
return;
}
static void get_addrbook_cnt(uint8_t cmd, uint8_t server_id, uint8_t conn_id)
{
uint8_t data[6] = {0};
uint16_t free_num = MAX_CONTACTS;
long long file_size = 0;
struct stat fileStat = {0};
int ret = stat(TJD_ADDRESS_BOOK_PATH,&fileStat);
static_print_debug("access ret is %d", ret);
if(ret == 0){
file_size = fileStat.st_size;
static_print_debug("file size is %lld", file_size);
uint8_t contact_num = file_size/sizeof(Contact);
if(contact_num > MAX_CONTACTS){
free_num = 0;
}else{
free_num = MAX_CONTACTS - contact_num;
}
}
data[0] = PROTOCOL_FRAME_RSP_HEAD;
data[1] = 0x08;
data[2] = cmd;
data[3] = (free_num >> 8) & 0xFF;
data[4] = free_num & 0xFF;
data[5] = do_crc(data, sizeof(data) - 1);
gatt_send_response(data, sizeof(data), server_id, conn_id);
}
static void handle_push_addrbook_data_cmd(UpgradeContext *upgrade_context, uint8_t cmd, uint16_t * push_data_pkg,
uint8_t *write_cb_para, uint16_t len ,uint8_t server_id, uint8_t conn_id)
{
uint8_t ret = true;
uint8_t data[8] = {0};
// TODO: 接收表盘推送数据
uint16_t received_seq = (write_cb_para[2] << 8) | write_cb_para[3];
if (received_seq != upgrade_context->expected_seq) {
// 错误处理:包序号不匹配
static_print_debug("received_seq(%d) != expected_seq(%d)", received_seq, upgrade_context->expected_seq);
received_seq = upgrade_context->expected_seq;
ret = false;
goto __exit;
}else if (received_seq >= *push_data_pkg) {
printf("[%s %d][total exceed(%d-MAX:%d)]\n", __func__, __LINE__, received_seq, *push_data_pkg);
return;
}
memcpy_s(upgrade_context->buffer + upgrade_context->buffer_offset, PACKET_DATA_SIZE, &write_cb_para[4],
len - 4);
upgrade_context->buffer_offset += (len - 4);
upgrade_context->expected_seq++;
static_print_debug("receive data success, prepare to send next data ! expected seq: %d , push_data_pkg : %d " , upgrade_context->expected_seq , *push_data_pkg);
if (*push_data_pkg == upgrade_context->expected_seq) {
static_print_debug("contacts push data mask is true, prepare to analyze data");
for(int i = 0; i < upgrade_context->buffer_offset; i++){
static_print_debug("contacts data : %02x", upgrade_context->buffer[i]);
}
// TODO: 解析contacts推送数据
if(cmd == CONTACTS_PUSH_DATA_COMMAND){
int num_contacts = 0;
memset(contacts, 0 , sizeof(contacts));
// 检测数据有效性
if (strncmp((const char *)upgrade_context->buffer, "{*$#", 4) != 0 ||
strstr((const char *)upgrade_context->buffer, "#$*}") == NULL) {
static_print_debug("Invalid data format");
goto __analyze_end;
}
char *token = strtok((char *)upgrade_context->buffer + 4, "[@");
while (token != NULL && num_contacts < MAX_CONTACTS) {
if (sscanf(token, "%hhu%49[^%&]%*[^&]&%14s", &contacts[num_contacts].id, contacts[num_contacts].name,
contacts[num_contacts].phone) != 3) {
printf("Failed to parse contact data");
return;
}
// 去除phone字段末尾的特殊字符
char *end = contacts[num_contacts].phone + strlen(contacts[num_contacts].phone) - 1;
while (end >= contacts[num_contacts].phone && !isdigit(*end)) {
*end = '\0'; // 将非数字字符替换为字符串结束符
end--;
}
num_contacts++;
token = strtok(NULL, "[@");
}
for (int i = 0; i < num_contacts; ++i) {
static_print_debug("Contact %d: ID=%d, Name=%s, Phone=%s", i + 1, contacts[i].id,
contacts[i].name, contacts[i].phone);
}
static_print_debug("receive all data, exit dial push data mask");
static_print_debug("upgrade_context.buffer_offset: %d, push_data_pkg: %d, upgrade_context.expected_seq: %d",
upgrade_context->buffer_offset, *push_data_pkg, upgrade_context->expected_seq);
file_append_data.buffer = contacts;
file_append_data.size = num_contacts;
tjd_service_contact_append(&file_append_data);
}
__analyze_end:
free(upgrade_context->buffer);
upgrade_context->buffer = NULL;
upgrade_context->buffer_offset = 0;
upgrade_context->expected_seq = 0;
*push_data_pkg = 0;
}
__exit:
/* 回复当前包序号 */
data[0] = PROTOCOL_FRAME_RSP_HEAD;
data[1] = 0x08;
data[2] = cmd;
data[3] = (received_seq >> 8) & 0xFF;
data[4] = received_seq & 0xFF;
data[5] = (ret >> 8) & 0xFF;
data[6] = ret & 0xFF;
data[7] = do_crc(data, sizeof(data) - 1);
gatt_send_response(data, sizeof(data), server_id, conn_id);
return;
}
void tjd_ble_rec_lucky_clover_data(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para, uint16_t len ,uint8_t cmd_id)
{
// TODO: app下发四叶草数据
static_print_debug("rec ltv file description");
uint8_t data_index = 4;
uint16_t lucky_clover_len = (write_cb_para[data_index] << 8) | write_cb_para[data_index + 1];
// uint16_t rec_lucky_clover_offset = 0;
uint16_t write_len = write_cb_para[1] << 8 | write_cb_para[2];
uint16_t remaining_size = lucky_clover_len - lucky_flover_context.buffer_offset;
if (!g_qrcode_push_data_mask) {
memset_s(&lucky_flover_context, sizeof(lucky_flover_context), 0, sizeof(lucky_flover_context));
lucky_flover_context.buffer_offset = 0;
lucky_flover_context.expected_seq = lucky_clover_len;
lucky_flover_context.buffer = (uint8_t *)malloc(lucky_clover_len);
// rec_lucky_clover_offset =
// (write_cb_para[data_index + 2] << 8) | write_cb_para[data_index + 3];
memset_s(lucky_flover_context.buffer, lucky_clover_len, 0, lucky_clover_len);
static_print_debug("lucky_clover_len : %d, lucky_flover_context.buffer_offset : %d", lucky_clover_len,
lucky_flover_context.buffer_offset);
if(remaining_size > write_len - 7){
memcpy_s(lucky_flover_context.buffer + lucky_flover_context.buffer_offset,
lucky_clover_len - lucky_flover_context.buffer_offset, &write_cb_para[data_index + 2],
write_len - 7);
lucky_flover_context.buffer_offset += write_len - 7;
}else{
memcpy_s(lucky_flover_context.buffer + lucky_flover_context.buffer_offset,
lucky_clover_len - lucky_flover_context.buffer_offset, &write_cb_para[data_index + 2],
remaining_size);
lucky_flover_context.buffer_offset += remaining_size;
}
g_qrcode_push_data_mask = true;
} else {
if(remaining_size > write_len - 7){
memcpy_s(lucky_flover_context.buffer + lucky_flover_context.buffer_offset,
lucky_clover_len - lucky_flover_context.buffer_offset, &write_cb_para[data_index + 2],
write_len - 7);
lucky_flover_context.buffer_offset += write_len - 7;
}else{
memcpy_s(lucky_flover_context.buffer + lucky_flover_context.buffer_offset,
lucky_clover_len - lucky_flover_context.buffer_offset, &write_cb_para[data_index + 2],
remaining_size);
lucky_flover_context.buffer_offset += remaining_size;
}
}
if (lucky_flover_context.buffer_offset == lucky_clover_len) {
g_qrcode_push_data_mask = false;
// for(int i = 0; i < file_description_len; i++){
// static_print_debug("file_description_buffer[%d] : %02x", i,file_decription_context.buffer[i]);
// }
static_print_info("lucky_flover_context.buffer_offset : %d , lucky_flover_context.buffer : \r\n",lucky_flover_context.buffer_offset);
for(int i = 0; i < lucky_flover_context.buffer_offset; i++){
static_print_info("%02x ",lucky_flover_context.buffer[i]);
if(i % 10 == 0){
static_print_info("\r\n");
}
}
static_print_info("\r\n");
// 表盘LTV文件描述如 0301040602123456780603F1F1F1F10804313233343536
// 0301040602123456780603F1F1F1F10804313233343536
uint8_t cur_task_num = 0;
uint8_t goal_task_num = 0;
// lucky_clover_msg_t lucky_clover_msg = {0};
for (int i = 0; i < lucky_flover_context.buffer_offset;) { // 遍历文件描述
uint8_t len = lucky_flover_context.buffer[i];
uint8_t type = lucky_flover_context.buffer[i + 1];
static_print_debug("i : %u, type : %u, len : %u", i, type, len);
switch (type) {
case 0x01: { // 站立活动
goal_task_num++;
uint8_t standing_activity_cur = lucky_flover_context.buffer[i + 2];
uint8_t standing_activity_goal = lucky_flover_context.buffer[i + 3];
// lucky_clover_msg.lucky_clover_data.currentStandNum = standing_activity_cur;
// lucky_clover_msg.lucky_clover_data.goalStandNum = standing_activity_goal;
if(standing_activity_cur >= standing_activity_goal){
cur_task_num++;
}
uint16_t standing_activity_reminder_time = (lucky_flover_context.buffer[i + 4] << 8) |
lucky_flover_context.buffer[i + 5];
sql_fit_set_currentStandNum_data(standing_activity_cur);
sql_fit_set_goalStandNum_data(standing_activity_goal);
static_print_warn("standing activity cur : %u, standing activity goal : %u, standing activity reminder time : %u",
standing_activity_cur, standing_activity_goal, standing_activity_reminder_time);
break;
}
case 0x02: { // 活动热量
goal_task_num++;
uint16_t activity_heat_cur = (lucky_flover_context.buffer[i + 2] << 8) |
lucky_flover_context.buffer[i + 3];
uint16_t activity_heat_goal = (lucky_flover_context.buffer[i + 4] << 8) |
lucky_flover_context.buffer[i + 5];
// lucky_clover_msg.lucky_clover_data.currentCalorieNum = activity_heat_cur;
// lucky_clover_msg.lucky_clover_data.goalCalorieNum = activity_heat_goal;
if(activity_heat_cur >= activity_heat_goal){
cur_task_num++;
}
uint16_t activity_heat_reminder_time = (lucky_flover_context.buffer[i + 6] << 8) |
lucky_flover_context.buffer[i + 7];
sql_fit_set_currentCalorieNum_data(activity_heat_cur);
sql_fit_set_goalCalorieNum_data(activity_heat_goal);
static_print_debug("activity heat cur : %u, activity heat goal : %u, activity heat reminder time : %u",
activity_heat_cur, activity_heat_goal, activity_heat_reminder_time);
tjd_service_handle_calorie_data();
break;
}
case 0x03: { // 中高强度
goal_task_num++;
uint8_t high_intensity_cur = lucky_flover_context.buffer[i + 2];
uint8_t high_intensity_goal = lucky_flover_context.buffer[i + 3];
// lucky_clover_msg.lucky_clover_data.currentStrengthTime = high_intensity_cur;
// lucky_clover_msg.lucky_clover_data.goalStrengthTime = high_intensity_goal;
if(high_intensity_cur >= high_intensity_goal){
cur_task_num++;
}
uint16_t high_intensity_reminder_time = (lucky_flover_context.buffer[i + 4] << 8) |
lucky_flover_context.buffer[i + 5];
sql_fit_set_currentStrengthTime_data(high_intensity_cur);
sql_fit_set_goalStrengthTime_data(high_intensity_goal);
static_print_debug("high intensity cur : %u, high intensity goal : %u, high intensity reminder time : %u",
high_intensity_cur, high_intensity_goal, high_intensity_reminder_time);
tjd_service_handle_excise_data();
break;
}
case 0x04: { // 步数
goal_task_num++;
uint16_t step_cur = (lucky_flover_context.buffer[i + 2] << 8) |
lucky_flover_context.buffer[i + 3];
uint16_t step_goal = (lucky_flover_context.buffer[i + 4] << 8) |
lucky_flover_context.buffer[i + 5];
// lucky_clover_msg.lucky_clover_data.currentStepNum = step_cur;
// lucky_clover_msg.lucky_clover_data.goalStepNum = step_goal;
if(step_cur >= step_goal){
cur_task_num++;
}
uint16_t step_reminder_time = (lucky_flover_context.buffer[i + 6] << 8) | lucky_flover_context.buffer[i + 7];
sql_fit_set_currentStepNum_data(step_cur);
sql_fit_set_goalStepNum_data(step_goal);
static_print_debug("step cur : %u, step goal : %u, step reminder time : %u", step_cur, step_goal, step_reminder_time);
tjd_service_handle_step_data();
break;
}
case 0x05: { // 每日喝水
goal_task_num++;
uint16_t drink_water_cur = (lucky_flover_context.buffer[i + 2] << 8) |
lucky_flover_context.buffer[i + 3];
uint16_t drink_water_goal = (lucky_flover_context.buffer[i + 4] << 8) |
lucky_flover_context.buffer[i + 5];
// lucky_clover_msg.lucky_clover_data.currentDrinkNum = drink_water_cur;
// lucky_clover_msg.lucky_clover_data.goalDrinkNum = drink_water_goal;
if(drink_water_cur >= drink_water_goal){
cur_task_num++;
}
uint8_t is_drink_water_reminder_on = lucky_flover_context.buffer[i + 6];
uint16_t drink_water_reminder_time_start = (lucky_flover_context.buffer[i + 7] << 8) |
lucky_flover_context.buffer[i + 8];
uint16_t drink_water_reminder_time_end = (lucky_flover_context.buffer[i + 9] << 8) |
lucky_flover_context.buffer[i + 10];
sql_fit_set_currentDrinkNum_data(drink_water_cur);
sql_fit_set_goalDrinkNum_data(drink_water_goal);
static_print_debug("drink water cur : %u, drink water goal : %u, drink water reminder on : %u, drink water reminder time start : %u, drink water reminder time end : %u",
drink_water_cur, drink_water_goal, is_drink_water_reminder_on, drink_water_reminder_time_start, drink_water_reminder_time_end);
break;
}
case 0x06: { // 早睡
goal_task_num++;
uint8_t is_early_sleep_reminder_on = lucky_flover_context.buffer[i + 2];
if(is_early_sleep_reminder_on){
cur_task_num++;
}
uint16_t early_sleep_cur_time = (lucky_flover_context.buffer[i + 3] << 8) | lucky_flover_context.buffer[i + 4];
uint16_t early_sleep_goal_time = (lucky_flover_context.buffer[i + 5] << 8) |
lucky_flover_context.buffer[i + 6];
uint16_t early_sleep_reminder_time = (lucky_flover_context.buffer[i + 7] << 8) |
lucky_flover_context.buffer[i + 8];
sql_fit_set_curEarlySleepTime_data(early_sleep_cur_time);
sql_fit_set_goalEarlySleepTime_data(early_sleep_goal_time);
// lucky_clover_msg.lucky_clover_data.sleepEarly = is_early_sleep_reminder_on == 0 ? false : true;
sql_fit_set_sleepEarly_data(is_early_sleep_reminder_on);
static_print_debug("is early sleep reminder on : %u, early_sleep_cur_time : %u, early sleep goal time : %u, early sleep reminder time : %u",
is_early_sleep_reminder_on, early_sleep_cur_time ,early_sleep_goal_time, early_sleep_reminder_time);
break;
}
case 0x07: { // 睡眠时长
goal_task_num++;
uint16_t sleep_duration_cur = (lucky_flover_context.buffer[i + 2] << 8) |
lucky_flover_context.buffer[i + 3];
uint16_t sleep_duration_goal = (lucky_flover_context.buffer[i + 4] << 8) |
lucky_flover_context.buffer[i + 5];
// lucky_clover_msg.lucky_clover_data.currentSleepTime = sleep_duration_cur;
// lucky_clover_msg.lucky_clover_data.goalSleepTime = sleep_duration_goal;
if(sleep_duration_cur >= sleep_duration_goal){
cur_task_num++;
}
sql_fit_set_currentSleepTime_data(sleep_duration_cur);
sql_fit_set_goalSleepTime_data(sleep_duration_goal);
static_print_debug("sleep duration cur : %u, sleep duration goal : %u", sleep_duration_cur, sleep_duration_goal);
break;
}
case 0x08: { //血压测量时间
goal_task_num++;
uint8_t current_punch_clock_time = lucky_flover_context.buffer[i + 2];
uint8_t goal_punch_clock_time = lucky_flover_context.buffer[i + 3];
if(current_punch_clock_time >= goal_punch_clock_time){
cur_task_num++;
}
sql_fit_set_curBloodPressureMeasurTime_data(current_punch_clock_time);
sql_fit_set_goalBloodPressureMeasurTime_data(goal_punch_clock_time);
// lucky_clover_msg.lucky_clover_data.curBloodPressureMeasurTime = current_punch_clock_time;
// lucky_clover_msg.lucky_clover_data.goalBloodPressureMeasurTime = goal_punch_clock_time;
uint16_t blood_pressure_matinal_measure_time = (lucky_flover_context.buffer[i + 4] << 8) |
lucky_flover_context.buffer[i + 5];
uint16_t blood_pressure_before_sleep_measure_time = (lucky_flover_context.buffer[i + 6] << 8) |
lucky_flover_context.buffer[i + 7];
static_print_debug("current_punch_clock_time : %u, goal_punch_clock_time : %u, blood pressure matinal measure time : %u, blood pressure before sleep measure time : %u",
current_punch_clock_time,goal_punch_clock_time,blood_pressure_matinal_measure_time,blood_pressure_before_sleep_measure_time);
uint8_t custom_measure_tiemrs = (len - 8);
for(uint8_t j = 0; j < custom_measure_tiemrs; j++){
uint16_t custom_measure_time = (lucky_flover_context.buffer[i + 8 + (j * 2)] << 8) |
lucky_flover_context.buffer[i + 9 + (j * 2)];
static_print_debug("custom measure time : %u", custom_measure_time);
}
break;
}
case 0x09: { // 自定义打卡任务
//data .eg : 150902 E7A4BCE4BD9B250000 E7A5B7E5918A250000
//len : 0x15 type : 0x09
//自定义任务名与提醒时间以 “%” 作分隔 即 0x25
uint8_t custom_task_name_len = 0;
uint8_t custom_task_num = lucky_flover_context.buffer[i + 2];
custom_task_num == 0 ? sql_fit_set_has_custom_task(false) : sql_fit_set_has_custom_task(true);
uint8_t k = i;
goal_task_num += custom_task_num;
static_print_debug("custom task num : %u", custom_task_num);
for(uint8_t j = 0; j < custom_task_num; j++){
uint8_t custom_task_name[32] = {0};
char * custom_task_name_ptr = strchr((char *)lucky_flover_context.buffer + k + 3, 0x25);
if(custom_task_name_ptr == NULL){
continue;
}
custom_task_name_len = custom_task_name_ptr - (char *)(lucky_flover_context.buffer + i + 3);
memcpy(custom_task_name, lucky_flover_context.buffer + k + 3, custom_task_name_len);
uint16_t custom_task_reminder_time = (lucky_flover_context.buffer[k + 3 + custom_task_name_len + 1 ] << 8) |
lucky_flover_context.buffer[k + 3 + custom_task_name_len + 2];
bool is_custom_task_punch_clock = lucky_flover_context.buffer[k + 3 + custom_task_name_len + 3];
if(is_custom_task_punch_clock){
cur_task_num++;
}
k += custom_task_name_len + 4;
sql_fit_set_custom_task(j, (char *)custom_task_name, is_custom_task_punch_clock ,custom_task_reminder_time);
static_print_debug("custom task name : %s, custom task reminder time : %u, is_custom_task_punch_clock : %u", custom_task_name, custom_task_reminder_time,
is_custom_task_punch_clock);
}
break;
}
default: {
static_print_error("unknown type : %u", type);
break;
}
}
i += len;
}
// for(int i = 0 ; i < cur_task_num; i++){
// lucky_clover_msg.msg_type = i;
// TjdUiMsgEventPublish(TJDUI_TOPIC_EVENT_LUCKY_CLOVER, &lucky_clover_msg, sizeof(lucky_clover_msg));
// }
sql_fit_set_currentTaskNum_data(cur_task_num);
sql_fit_set_goalTaskNum_data(goal_task_num);
free(lucky_flover_context.buffer);
lucky_flover_context.buffer = NULL;
lucky_flover_context.buffer_offset = 0;
lucky_flover_context.expected_seq = 0;
return;
}
}
//AC XXXX CB XXXX LTV030101 1202xxxxxxxxxxxxxxxxxxxx 0402xxxxCRC
#define OPRATION_INSTALL 0x01
#define OPRATION_UNINSTALL 0x00
#define LTV_DEFAULT_LEN 10
#define LTV_OFFSET_LEN 2
#define PACKAGE_DEFAULT_LEN 7
bool uninstall_by_protocol = false;
void tjd_ble_uninstall_js_app(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para, uint16_t len ,uint8_t cmd_id)
{
uint8_t operation = write_cb_para[8];
uint16_t package_len = (write_cb_para[1] << 8) | write_cb_para[2];
uint16_t ltv_len = (write_cb_para[4] << 8) | write_cb_para[5];
uint8_t bundleName_len = write_cb_para[9] - LTV_OFFSET_LEN;
uint8_t lable_len = write_cb_para[11 + bundleName_len] - LTV_OFFSET_LEN;
char bundleName[PROTOCOL_BUFFER_MAX_LEN] = {0};
char lable[PROTOCOL_BUFFER_MAX_LEN] = {0};
char pkg_path[PROTOCOL_BUFFER_MAX_LEN] = {0};
memcpy_s(bundleName,bundleName_len,&write_cb_para[11],bundleName_len);
memcpy_s(lable,lable_len,&write_cb_para[11+bundleName_len],lable_len);
printf("uninstall bundleName_len:%d lable_len:%d\r\n",bundleName_len,lable_len);
printf("uninstall bundleName:%s lable:%s\r\n",bundleName,lable);
if(operation == OPRATION_UNINSTALL){
// TODO: 删除安装包
// sprintf_s(pkg_path, PROTOCOL_BUFFER_MAX_LEN, "%s/%s.bin", TJD_FS_DIR_JS, (char *)bundleName);
// printf("uninstall pkg_path:%s\r\n",pkg_path);
// if(access((char *)pkg_path, 0) == 0){
// tjd_fs_api_path_remove((char *)pkg_path);
// }
// TODO: 卸载JS应用
uninstall_by_protocol = true;
TjdAppStorePkgOperation(PKG_OPERATION_TYPE_UNINSTALL,(const char *)bundleName,false);
}
}
void tjd_ble_protocol_get_openharmony_version(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para, uint16_t len, uint8_t cmd_id)
{
int version = GetSdkApiVersion();
uint8_t data[] = {(uint8_t)version};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
}
void tjd_ble_protocol_ctrlcmd_ab(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para , uint16_t len)
{
static_print_info(" tjd_ble_protocol_ctrlcmd_ab(len:%d):\r\n",len);
for(int i = 0 ; i < len ; ){
static_print_info("%02x", write_cb_para[i]);
i++;
if(i % 10 == 0){
static_print_info("\r\n");
}
if(i>=20){ break;}
}
static_print_info("\r\n");
switch (write_cb_para[1]) {
case DIAL_PUSH_DIAL_DATA_COMMAND: {
static_print_debug("dial push data mask is true, prepare to receive data");
handle_push_data_cmd(&dial_context, DIAL_PUSH_DIAL_DATA_COMMAND, g_dial_push_data_pkg, write_cb_para, CONTACTS_DATA_LEN,
server_id, conn_id);
return;
}
case WALLPAPER_PUSH_DATA_COMMAND: {
static_print_debug("wallpaper push data mask is true, prepare to receive data");
handle_push_data_cmd(&wallpaper_context, WALLPAPER_PUSH_DATA_COMMAND, g_wallpaper_push_data_pkg,
write_cb_para, CONTACTS_DATA_LEN, server_id, conn_id);
return;
}
case CONTACTS_PUSH_DATA_COMMAND: {
static_print_debug("CONTACTS_PUSH_DATA_COMMAND prepare to receive data");
handle_push_addrbook_data_cmd(&contacts_context, CONTACTS_PUSH_DATA_COMMAND, &g_contacts_push_data_pkg, write_cb_para, CONTACTS_DATA_LEN,
server_id, conn_id);
return;
}
default:
break;
}
uint8_t crc = write_cb_para[len - 1];
uint8_t crc_cal = do_crc(write_cb_para, len - 1);
uint8_t cmd_id = write_cb_para[2];
if (crc != crc_cal && cmd_id != REC_QR_CODE_INFORMATION) {
static_print_error("control command crc error crc : %d, crc_cal : %d", crc, crc_cal);
uint8_t data = 0x00;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, &data, sizeof(data), cmd_id, server_id, conn_id);
return;
}
switch (cmd_id) {
case READ_DEVICE_INFO: {
static_print_debug("Read basic device information");
uint8_t data[] = {0xFF, 0xE7, 0x00, 0x50, 0x48, 0x31, 0x38, 0x00,
DEVICE_HARD_VERSION_H, DEVICE_HARD_VERSION_L, DEVICE_SOFT_VERSION_H, DEVICE_SOFT_VERSION_L, 0x54, 0x4a, 0x44, 0x50};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), READ_DEVICE_INFO, server_id, conn_id);
break;
}
case 0x01: {
static_print_debug("turn on led");
break;
}
case SET_READ_DEVICE_FORMAT: {
if(write_cb_para[3] == 0x01){
static_print_debug("set device format");
// TODO: 设置设备制式
sql_setting_set_language(write_cb_para[4]);
sql_setting_set_time_format(write_cb_para[5]);
sql_setting_set_distance_unit(write_cb_para[6]);
// language_enum lanuage = sql_setting_get_language();
// uint8_t time_format = sql_setting_get_time_format();
// uint8_t distance_unit = sql_setting_get_distance_unit();
// static_print_debug("language: %d, time_format: %d, distance_unit: %d", lanuage,
// time_format,distance_unit);
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_DEVICE_FORMAT, server_id, conn_id);
break;
}else if(write_cb_para[3] == 0x00){
static_print_debug("read device format");
// TODO: 读取设备制式
uint8_t language = sql_setting_get_language();
uint8_t time_format = sql_setting_get_time_format();
uint8_t distance_unit = sql_setting_get_distance_unit();
uint8_t data[] = {0x00, language, time_format, distance_unit};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_DEVICE_FORMAT, server_id, conn_id);
break;
}
}
case POWER_SYNCHRONIZATION: {
static_print_debug("power synchronization");
// TODO: 电源同步
// uint32_t utc_timestamp = 0;
// uint8_t charge_status = 0;
// uint8_t percent = tjd_service_charger_get_battery();
uint8_t percent = 100;
static_print_debug("battery percent: %d", percent);
// uint16_t voltage = 0;
// sql_setting_get_battery_info(&utc_timestamp, &charge_status, &percent, &voltage);
// uint8_t hex_num = 0;
// sprintf(hex_num, "%02X", percent);
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, &percent, sizeof(percent), POWER_SYNCHRONIZATION, server_id, conn_id);
break;
}
case TIME_SETTING_READ: {
struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops();
struct rtc_time *time_info;
switch (write_cb_para[3]) {
case 0x00: { // 读取设备时间
static_print_debug("read device time");
// TODO: 读取设备时间
uint64_t time_stamp = 0;
sql_setting_get_system_time(&time_stamp);
rtc_api->get_rtc_time(time_info);
uint8_t data[6] = {0};
data[0] = time_info->tm_year & 0xFF;
data[1] = time_info->tm_mon;
data[2] = time_info->tm_mday;
data[3] = time_info->tm_hour;
data[4] = time_info->tm_min;
data[5] = time_info->tm_sec;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), TIME_SETTING_READ, server_id, conn_id);
break;
}
case 0x01: { // 设置设备时间
static_print_debug("set device time");
// TODO: 设置设备时间
tjd_driver_rtc_sync_bt_time(write_cb_para, len);
uint64_t time_stamp = 0;
rtc_api->get_timestamp(&time_stamp);
static_print_debug("time_stamp: %lld", time_stamp);
sql_setting_set_system_time(time_stamp);
tjd_service_timing_init();
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), TIME_SETTING_READ, server_id, conn_id);
break;
}
default:
static_print_error("unknown time setting read");
break;
}
break;
}
case SET_READ_DEVICE_ALARM: {
switch (write_cb_para[3]) {
case 0x00: { // 读取设备闹钟
static_print_debug("read device alarm");
// 获取设备闹钟相关信息
bool is_alarm_full = false;
uint8_t alarm_number = sql_alarm_get_alarm_number(&is_alarm_full);
for (uint8_t i = 0; i < alarm_number; i++) {
uint8_t alarm_enable = sql_alarm_get_switch(i);
uint8_t alarm_hour = 0;
uint8_t alarm_minute = 0;
sql_alarm_get_time(i, &alarm_hour, &alarm_minute);
uint8_t alarm_cycle = sql_alarm_get_cycle(i);
uint8_t alarm_repeat_times = sql_alarm_get_repeat_times(i);
uint8_t alarm_repeat_interval = sql_alarm_get_repeat_interval(i);
uint8_t data[8] = {0};
data[0] = 0x00;
data[1] = i;
data[2] = alarm_enable;
data[3] = alarm_repeat_times;
data[4] = alarm_repeat_interval;
data[5] = alarm_cycle;
data[6] = alarm_hour;
data[7] = alarm_minute;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_DEVICE_ALARM, server_id, conn_id);
}
break;
}
case 0x01: { // 设置设备闹钟
static_print_debug("set device time");
// TODO: 设置设备时间
sql_alarm_set_switch(write_cb_para[4], write_cb_para[5]);
sql_alarm_set_repeat_times(write_cb_para[4], write_cb_para[6]);
sql_alarm_set_repeat_interval(write_cb_para[4], write_cb_para[7]);
sql_alarm_set_cycle(write_cb_para[4], write_cb_para[8]);
sql_alarm_set_time(write_cb_para[4], write_cb_para[9], write_cb_para[10]);
uint8_t data[] = {0x01, write_cb_para[4], 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_DEVICE_ALARM, server_id, conn_id);
break;
}
default:
static_print_error("unknown time setting read");
break;
}
break;
}
case SET_READ_USER_PARAMETERS: {
if (write_cb_para[3] == 0x00) {
static_print_debug("read user parameters success");
// 通知app读取用户参数成功
uint8_t data[] = {0x00, 0x01, 0xAA, 0x3C, 0x12, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_USER_PARAMETERS, server_id, conn_id);
} else if (write_cb_para[3] == 0x01) {
static_print_debug("set read user parameters");
// TODO: 设置用户参数
sql_fit_set_user_gender(write_cb_para[4]);
sql_fit_set_user_height(write_cb_para[5]);
sql_fit_set_user_weight(write_cb_para[6]);
sql_fit_set_user_age(write_cb_para[7]);
// uint8_t sex = sql_fit_get_user_gender();
// uint8_t height = sql_fit_get_user_height();
// uint8_t weight = sql_fit_get_user_weight();
// uint8_t age = sql_fit_get_user_age();
// static_print_debug("sex: %d, height: %d, weight: %d, age: %d", sex, height, weight, age);
// 通知app设置用户参数成功
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_USER_PARAMETERS, server_id, conn_id);
}
break;
}
// case SET_READ_UI_INTERFACE_DISPLAYED: {
// switch (write_cb_para[3]) {
// case 0x00: { // 读取要显示的UI界面
// static_print_debug("read device alarm");
// uint8_t data[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// tjd_ble_protocol_send_data(data, sizeof(data), SET_READ_UI_INTERFACE_DISPLAYED, server_id,
// conn_id); break;
// }
// case 0x01: { // 设置要显示的UI界面
// static_print_debug("set device time");
// TimeData time_data = {0};
// time_data.year = write_cb_para[4];
// time_data.month = write_cb_para[5];
// time_data.dateth = write_cb_para[6];
// time_data.hour = write_cb_para[7];
// time_data.minute = write_cb_para[8];
// time_data.second = write_cb_para[9];
// static_print_debug("year: %d, month: %d, dateth: %d, hour: %d, minute: %d, second: %d",
// time_data.year,
// time_data.month, time_data.dateth, time_data.hour, time_data.minute,
// time_data.second);
// uint8_t data[] = {0x01, 0x01};
// tjd_ble_protocol_send_data(data, sizeof(data), SET_READ_UI_INTERFACE_DISPLAYED, server_id,
// conn_id); break;
// }
// default:
// static_print_error("unknown time setting read");
// break;
// }
// break;
// }
case FIND_DEVICE:{
TjdUiMsgCenterFindDeviceTrigger();
break;
}
case SET_READ_FUNCTION_SWITCH:{
switch (write_cb_para[3]){
case 0x00:{ //读取功能开关
static_print_debug("read function switch");
set_read_function_switch_dada data = {0};
if(sql_fit_get_switch_bright_screen()){
data.switch_data |= 0x01;
}
if(sql_fit_get_switch_sedentary_remind_sw()){
data.switch_data |= 0x02;
}
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, (uint8_t *)&data, 3, SET_READ_FUNCTION_SWITCH, server_id,
conn_id);
break;
}
case 0x01:{ //设置功能开关
static_print_debug("set function switch");
uint16 _value = write_cb_para[4] << 8 | write_cb_para[5];
// 注3:设备功能开关
// 0x01 抬手亮屏
// 0x02 久坐提醒
// 0x04 喝水提醒
// 0x08 拍照
// 0x10 电话挂断
// 0x20 防丢
if(_value & 0x01){
static_print_debug("set bright screen switch enable");
sql_fit_set_switch_bright_screen(ENABLE_SWITCH);
}else{
static_print_debug("set bright screen switch disable");
sql_fit_set_switch_bright_screen(DISABLE_SWITCH);
}
if(_value & 0x02){
static_print_debug("set sedentary remind switch enable");
sql_fit_set_switch_sedentary_remind_sw(ENABLE_SWITCH);
}else{
static_print_debug("set sedentary remind switch disable");
sql_fit_set_switch_sedentary_remind_sw(DISABLE_SWITCH);
}
uint8_t data[2] = {0x01,0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_FUNCTION_SWITCH, server_id, conn_id);
break;
}
default:
static_print_error("unknown time setting read");
break;
}
break;
}
case FIND_MOBILE_PHONE: {
switch (write_cb_para[3]) {
case 0x00: {
static_print_debug("find mobile phone faile");
break;
}
case 0x01: {
static_print_debug("find mobile phone success");
break;
}
case 0x02: {
static_print_debug("find mobile phone end");
if(g_fine_phone_end_callback != NULL){
g_fine_phone_end_callback();
}
break;
}
}
break;
}
case SET_READ_SEDENTARY_REMINDER_PARAMETERS: {
switch (write_cb_para[3]) {
case 0x00: { // 读取久坐提醒功能参数
static_print_debug("read sedentary reminder parameters");
uint8_t data[] = {0x00, 0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_SEDENTARY_REMINDER_PARAMETERS, server_id,
conn_id);
break;
}
case 0x01: { // 设置久坐提醒功能参数
static_print_debug("set sedentary reminder parameters");
uint8_t sedentary_reminder_parameters = write_cb_para[4];
static_print_debug("sedentary_reminder_parameters: %d", sedentary_reminder_parameters);
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_SEDENTARY_REMINDER_PARAMETERS, server_id,
conn_id);
break;
}
default:
static_print_error("unknown sedentary reminder parameters setting read");
break;
}
break;
}
case SET_READ_WATER_DRINKING_REMINDER_PARAMETERS: {
switch (write_cb_para[3]) {
case 0x00: { // 读取喝水提醒功能参数
static_print_debug("read sedentary reminder parameters");
uint8_t data[] = {0x00, 0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_WATER_DRINKING_REMINDER_PARAMETERS, server_id,
conn_id);
break;
}
case 0x01: { // 设置喝水提醒功能参数
static_print_debug("set sedentary reminder parameters");
uint8_t sedentary_reminder_parameters = write_cb_para[4];
static_print_debug("sedentary_reminder_parameters: %d", sedentary_reminder_parameters);
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_WATER_DRINKING_REMINDER_PARAMETERS, server_id,
conn_id);
break;
}
default:
static_print_error("unknown sedentary reminder parameters setting read");
break;
}
break;
}
case ENTER_PHOTO_MODE: {
static_print_debug("enter photo mode");
// TODO: 进入拍照模式
switch (write_cb_para[3]) {
case 0x00: { // 退出相机
uint8_t data = 0x01;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, &data, sizeof(data), ENTER_PHOTO_MODE, server_id, conn_id);
g_tjd_ble_into_camera_flag = false;
tjd_exit_app_view();
break;
}
case 0x01: { // 进入相机
uint8_t data = 0x01;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, &data, sizeof(data), ENTER_PHOTO_MODE, server_id, conn_id);
g_tjd_ble_into_camera_flag = true;
tjd_into_photo();
break;
}
default:
break;
}
break;
}
case RESPOND_PHOTO_COMMAND: {
static_print_debug("respond photo command");
// TODO: 响应拍照命令
switch (write_cb_para[3]) {
}
break;
}
case MEASUREMENT_DATA_SYNCHRONIZATION: {
static_print_debug("measurement data synchronization");
// TODO: 同步测量数据
switch (write_cb_para[3]) {
case 0x01: { // App读取设备心率测量数据
tjd_service_send_hr_measurement_data();
break;
}
case 0x04: { // App读取设备血氧测量数据
tjd_service_send_measurement_data();
break;
}
case 0x82: { // App读取设备压力测量数据
static_print_debug("read device stress measurement data");
// uint8_t stress_array[STRESS_DAY_MAX_NUM] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
uint8_t *stress_array = NULL;
sql_fit_get_sterss_daydata(&stress_array);
//获取当日时间
struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops();
struct rtc_time time_info = {0};
uint64_t time_stamp = 0;
rtc_api->get_rtc_time(&time_info);
uint16_t total_number = STRESS_DAY_MAX_NUM;
uint16_t cur_number = 0;
int time_year = time_info.tm_year;
int time_month = time_info.tm_mon;
int time_day = time_info.tm_mday;
uint8_t time_hour = 0;
uint8_t time_minute = 0;
uint8_t time_second = 0;
for(int i = 0; i < STRESS_DAY_MAX_NUM; i++){
if(stress_array[cur_number] != 0){
uint8_t data[10] = {0};
data[0] = 0x82;
data[1] = total_number & 0xFF;
data[2] = cur_number & 0xFF;
data[3] = (time_year - 2000) & 0xFF;
data[4] = time_month & 0xFF;
data[5] = time_day & 0xFF;
data[6] = time_hour;
data[7] = time_minute;
data[8] = time_second;
data[9] = stress_array[cur_number];
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data),MEASUREMENT_DATA_SYNCHRONIZATION, server_id, conn_id);
}
time_hour += 1;
if(time_hour >= 24){
time_hour = 0;
time_day += 1;
}
cur_number += 1;
}
break;
}
}
break;
}
case READ_DETAILED_MOTION_DATA: {
static_print_debug("read detailed motion data");
// TODO: 读取详细运动数据
// 获取当天时间
// struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops();
// struct rtc_time *time_info;
// uint64_t time_stamp = 0;
// rtc_api->get_rtc_time(time_info);
// uint32_t step_daydata[Day_Hours] = {0};
// uint16_t distance_daydata[Day_Hours] = {0};
// uint16_t calorie_daydata[Day_Hours] = {0};
// sql_fit_get_step_daydata(step_daydata);
// sql_fit_get_distance_daydata(distance_daydata);
// sql_fit_get_calorie_daydata(calorie_daydata);
// for (uint8_t i = 0; i < Day_Hours; i++) {
// // 获取当天详细运动数据
// uint8_t data[] = {0x00,0x18,i,time_info->tm_year,time_info->tm_mon,time_info->tm_mday,i,0x00,
// step_daydata[i] & (0xFF << 8),step_daydata[i] & 0xFF,
// distance_daydata[i] & (0xFF << 8),distance_daydata[i] & 0xFF,
// calorie_daydata[i] & (0xFF << 8),calorie_daydata[i] & 0xFF};
// tjd_ble_protocol_send_data(data, sizeof(data), READ_DETAILED_MOTION_DATA, server_id, conn_id);
// }
// uint8_t pack_head = 0x5B;
// tjd_ble_protocol_send_lefun_data(&pack_head,NULL,0,REQUEST_LUCKY_CLOVER_DATA);
// static_print_debug("ble_request_flover");
break;
}
case READ_TOTAL_SLEEP_DATA: {
static_print_debug("read total sleep data");
// TODO: 读取指定日期睡眠总数据
switch (write_cb_para[3]) {
case 0x00: {
// 读取当天睡眠总数据
//获取当日时间
// struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops();
// struct rtc_time time_info = {0};
// uint64_t time_stamp = 0;
// rtc_api->get_rtc_time(&time_info);
// uint16_t total_number = STRESS_DAY_MAX_NUM;
// uint16_t cur_number = 0;
// int time_year = time_info.tm_year;
// int time_month = time_info.tm_mon;
// int time_day = time_info.tm_mday;
// uint8_t data[6] = {0};
// data[0] = 0x00;
// data[1] = (time_year - 2000) & 0xFF;
// data[2] = time_month & 0xFF;
// data[3] = time_day & 0xFF;
// tjd_ble_protocol_send_data(data, sizeof(data), READ_TOTAL_SLEEP_DATA, server_id, conn_id);
break;
}
default:
break;
}
break;
}
case READ_SLEEP_DATA: {
static_print_debug("read sleep data ");
switch (write_cb_para[3]) {
case 0x00: {
// 读取当天详细睡眠数据
//获取当日时间
struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops();
struct tm time_in = {0};
rtc_api->get_standard_time(&time_in);
time_t time_sec = mktime(&time_in); // 将时间转换为日历时间
if (time_sec == -1) {
static_print_error("Error: unable to make time using mktime");
}
struct tm *time_out = localtime(&time_sec);
// return time_out->tm_wday; // 返回星期几0-6分别代表周日到周六
sleep_status_dada_t null_head;
memset(&null_head, 0, sizeof(sleep_status_dada_t));
// load_sleep_data_from_json(&null_head, time_out->tm_wday);
load_sleep_data_from_json(&null_head, 4);
sleep_status_dada_t *p = &null_head;
uint16 total_number = 0;
sleep_status_dada *data_buf = malloc(sizeof(sleep_status_dada) * 100);
while(p->next != NULL) {
p = p->next;
if((p->status != SLEEP_LIGHT) && (p->status != SLEEP_DEEP) && (p->status != SLEEP_WAKE)) continue;
static_print_debug("sleep_status_daydata:%d %d %d %d %d %d", p->status, p->time.year,
p->time.mon, p->time.day, p->time.hour, p->time.min);
// if(p->time.day == time_out->tm_mday){
memcpy(&data_buf[total_number], p, sizeof(sleep_status_dada));
total_number++;
// }else if(p->time.day > time_out->tm_mday){
// static_print_debug("sleep_status_daydata is not match");
// break;
// }
}
if(total_number > 100) total_number = 100;
static_print_debug("total_number:%d", total_number);
for(int i = 0; i < total_number; i++){
uint8_t data[11] = {0};
int index = 0;
data[index++] = 0x00;
data[index++] = total_number >> 8 & 0xFF;
data[index++] = total_number & 0xFF;
data[index++] = (i + 1) >> 8 & 0xFF;
data[index++] = (i + 1) & 0xFF;
data[index++] = (data_buf[i].time.year - 2000) & 0xFF;
data[index++] = data_buf[i].time.mon & 0xFF;
data[index++] = data_buf[i].time.day & 0xFF;
data[index++] = data_buf[i].time.hour;
data[index++] = data_buf[i].time.min;
data[index++] = data_buf[i].status;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), READ_SLEEP_DATA, server_id, conn_id);
}
sleep_status_dada_t *current = null_head.next;
while (current != NULL) {
sleep_status_dada_t *temp = current;
current = current->next;
free(temp);
}
free(data_buf);
// uint8_t sleep_data[5][15] = {
// [0] = {0x5A,0x0F,0x15,0x00,0x00,0x05,0x00,0x01,0x18,0x09,0x1e,0x16,0x1e,0x02,0x00},
// [1] = {0x5A,0x0F,0x15,0x00,0x00,0x05,0x00,0x02,0x18,0x09,0x1e,0x17,0x1e,0x03,0x00},
// [2] = {0x5A,0x0F,0x15,0x00,0x00,0x05,0x00,0x03,0x18,0x0A,0x01,0x00,0x1e,0x02,0x00},
// [3] = {0x5A,0x0F,0x15,0x00,0x00,0x05,0x00,0x04,0x18,0x0A,0x01,0x01,0x1e,0x03,0x00},
// [4] = {0x5A,0x0F,0x15,0x00,0x00,0x05,0x00,0x05,0x18,0x0A,0x01,0x02,0x1e,0x01,0x00}
// };
// for(int i = 0; i < 5; i++){
// sleep_data[i][14] = do_crc(sleep_data[i],14);
// gatt_send_response(sleep_data[i],sizeof(sleep_data[i]),server_id,conn_id);
// }
break;
}
}
break;
// TODO: 读取指定日期详细睡眠数据
}
case TOTAL_NUMBER_ANDROID_PUSH_MESSAGES: {
// 通知app获取消息总数成功
uint8_t message_type = write_cb_para[3];
uint8_t total_number_android_push_messages = write_cb_para[4];
static_print_debug("total number of android push messages : %d , message type : %d",
total_number_android_push_messages, message_type);
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), TOTAL_NUMBER_ANDROID_PUSH_MESSAGES, server_id, conn_id);
break;
}
case ANDROID_PUSH_MESSAGES: {
// app开始分包发送消息我要接收分包数据
static_print_debug("android push messages");
message_enum message_type = 0;
uint16_t message_len = len - 7;
switch (write_cb_para[3]) {
case 0x01:
message_type = MESSAGE_TELEPHONE;
break;
case 0x02:
message_type = MESSAGE_SHORT_MESSAGE;
break;
case 0x04:
message_type = MESSAGE_QQ2;
break;
case 0x08:
message_type = MESSAGE_WECHAT2;
break;
case 0x10: {
message_len = len - 8;
switch (write_cb_para[6]) {
case 0x01:
message_type = MESSAGE_FACEBOOK;
break;
case 0x02:
message_type = MESSAGE_TWITTER;
break;
case 0x03:
message_type = MESSAGE_LINKEDIN;
break;
case 0x04:
message_type = MESSAGE_WHATSAPP;
break;
case 0x05:
message_type = MESSAGE_LINE;
break;
case 0x06:
message_type = MESSAGE_KAKAOTALK;
break;
case 0x07:
message_type = MESSAGE_FACEBOOK_MESSENGER;
break;
case 0x08:
message_type = MESSAGE_INSTAGRAM;
break;
case 0x09:
message_type = MESSAGE_WHATSAPP_BUSINESS;
break;
case 0x0A:
message_type = MESSAGE_VIBER;
break;
case 0x0B:
message_type = MESSAGE_TELEGRAM;
break;
case 0x0C:
message_type = MESSAGE_SNAPCHAT;
break;
case 0x0D:
message_type = MESSAGE_ZALO;
break;
case 0x0E:
message_type = MESSAGE_OUTLOOK;
break;
case 0x0F:
message_type = MESSAGE_SINA_WEIBO;
break;
case 0x10:
message_type = MESSAGE_VK;
break;
case 0x11:
message_type = MESSAGE_END_CALL;
break;
case 0x12:
message_type = MESSAGE_YOUTUBE;
break;
case 0x13:
message_type = MESSAGE_TIKTOK;
break;
default:
break;
}
} break;
default:
break;
}
static uint8_t index = 0;
uint8_t message_all_index = write_cb_para[4];
uint8_t message_index = write_cb_para[5];
if (message_index == 0x01) {
index = sql_message_new_message();
message_context.buffer_offset = 0;
message_context.expected_seq = 1;
message_context.buffer = malloc(message_len * message_all_index);
if (message_context.buffer == NULL) {
static_print_error("malloc message buffer error");
return;
}
memset_s(message_context.buffer, message_len * message_all_index, 0, message_len * message_all_index);
}
static_print_debug("message_type: %d, message_all_index: %d, message_index: %d", message_type,
message_all_index, message_index);
if (message_index == message_context.expected_seq++ && message_all_index != message_index) {
if (message_context.buffer_offset + message_len > PROTOCOL_BUFFER_MAX_LEN) {
static_print_error("message buffer overflow");
return;
}
memcpy_s(message_context.buffer + message_context.buffer_offset, message_len * message_all_index,
write_cb_para[3] == 0x10 ? &write_cb_para[7] : &write_cb_para[6],
message_len);
message_context.buffer_offset += message_len;
} else if (message_all_index == message_index) {
if (message_context.buffer_offset + message_len < PROTOCOL_BUFFER_MAX_LEN) {
memcpy_s(message_context.buffer + message_context.buffer_offset, message_len * message_all_index,
write_cb_para[3] == 0x10 ? &write_cb_para[7] : &write_cb_para[6],
message_len);
message_context.buffer_offset += message_len;
}
static_print_debug("message_data:");
for (uint32_t i = 0; i < message_context.buffer_offset; i++) {
static_print_info("%02x ", message_context.buffer[i]);
if(i != 0 && i % 10 == 0){
static_print_info("\r\n");
}
}
static_print_info("\r\n");
static_print_debug("message_context.buffer_offset = %d", message_context.buffer_offset);
int mask_i = strchr((const char *)message_context.buffer, ':') - (char *)message_context.buffer;
int mask_j = mask_i;
if(strchr((const char *)message_context.buffer + mask_i + 1, ':') != NULL){
mask_j = strchr((const char *)message_context.buffer + mask_i + 1, ':') - (char *)message_context.buffer;
}
static_print_debug("mask_i = %d, mask_j = %d", mask_i, mask_j);
char *buff = malloc(mask_i + 2);
memset_s(buff, mask_i + 2, 0, mask_i + 2);
memcpy_s(buff, mask_i + 1, message_context.buffer, mask_i);
buff[mask_i + 1] = '\0';
if (sql_message_set_type(index, message_type) == RET_ERROR) {
static_print_error("set message type error");
return;
}
if (sql_message_set_user_name(index, buff) == RET_ERROR) {
static_print_error("set message name error");
return;
}
char *detail_info = malloc(message_context.buffer_offset - mask_j + 1);
memset_s(detail_info, message_context.buffer_offset - mask_j + 1, 0, message_context.buffer_offset - mask_j + 1);
if(detail_info == NULL){
static_print_error("detail_info malloc error");
return;
}
memcpy_s(detail_info, message_context.buffer_offset - mask_j, message_context.buffer + mask_j + 1,
message_context.buffer_offset - mask_j);
detail_info[message_context.buffer_offset - mask_j] = '\0';
// printf("origin hex text:\r\n");
// uint8_t originlen = message_context.buffer_offset - mask_j + 1;
// for (int i = 0; i < originlen; i++)
// {
// printf("--0x%02x",(uint8_t)detail_info[i]);
// }
// printf("\r\n");
// 保存消息到数据库
static_print_debug("save message [%d] to database ", index);
static_print_debug("detail info: %s", detail_info);
static_print_debug("orignal hex data:");
for(uint8_t i = 0; i < message_context.buffer_offset - mask_j; i++)
{
static_print_info("--%02x",detail_info[i]);
if(i != 0 && i % 10 == 0){
static_print_info("\r\n");
}
}
static_print_info("\r\n");
if (sql_message_set_detail_info(index, detail_info) == RET_ERROR) {
static_print_error("set message detail info error");
return;
}
struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops();
uint64_t time_stamp = 0;
rtc_api->get_timestamp(&time_stamp);
if (sql_message_set_timestamp(index, time_stamp) == RET_ERROR) {
static_print_error("set message timestamp error");
return;
}
if (sql_message_set_valid(index, true) == RET_ERROR) {
static_print_error("set message valid error");
return;
}
message_context.buffer_offset = 0;
message_context.expected_seq = 1;
free(detail_info);
detail_info = NULL;
free(buff);
buff = NULL;
free(message_context.buffer);
message_context.buffer = NULL;
#if 1
// 从数据库读取消息
// char txt[100] = {0};
char * txt = NULL;
if (sql_message_get_detail_info(index, &txt) == RET_ERROR) {
static_print_error("get message detail info error");
return;
}
static_print_debug("message [%d] detail info: %s", index, txt);
// memset_s(txt, 100, 0, 100);
if (sql_message_get_user_name(index, &txt) == RET_ERROR) {
static_print_error("get message name error");
return;
}
static_print_debug("message [%d] name: %s", index, txt);
#endif
// 通知app获取消息成功
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), ANDROID_PUSH_MESSAGES, server_id, conn_id);
TjdUiMsgCenterMessagePopUpTrigger();
}
break;
}
case READ_MOBILE_PHONE_STEP_DATA: {
static_print_debug("read mobile phone step data");
// TODO: 读取手机APP步数数据
uint32_t step_data = write_cb_para[3] << 24 | write_cb_para[4] << 16 |
write_cb_para[5] << 8 | write_cb_para[6];
static_print_debug("step data: %d", step_data);
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), READ_MOBILE_PHONE_STEP_DATA, server_id, conn_id);
break;
}
case READ_SET_SYSTEM_LANGUAGE: {
static_print_debug("set system language");
sql_setting_set_language(write_cb_para[3]);
uint8_t system_language = sql_setting_get_language();
static_print_debug("system language: %d", system_language);
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), READ_SET_SYSTEM_LANGUAGE, server_id, conn_id);
break;
}
case READ_SET_IOS_PUSH_SWITCH: {
switch (write_cb_para[3]) {
case 0x00: { // 读取ios推送开关
static_print_debug("read ios push switch");
uint8_t data[] = {0x00, 0x00, 0x00, 0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), READ_SET_IOS_PUSH_SWITCH, server_id, conn_id);
break;
}
case 0x01: { // 设置ios推送开关
static_print_debug("set ios push switch");
uint32_t ios_push_switch = write_cb_para[4] << 24 | write_cb_para[5] << 16 |
write_cb_para[6] << 8 | write_cb_para[7];
static_print_debug("ios push switch: %d", ios_push_switch);
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), READ_SET_IOS_PUSH_SWITCH, server_id, conn_id);
break;
}
default:
static_print_error("unknown ios push switch setting read");
break;
}
break;
}
case SET_READ_STEP_GOAL: {
switch (write_cb_para[3]) {
case 0x00: { // 读取步数目标
static_print_debug("read step goal");
uint32_t step_goal_th = sql_fit_get_goal_step_th();
uint8_t data[] = {0x00, (step_goal_th >> 24) & 0xff, (step_goal_th >> 16) & 0xff, (step_goal_th >> 8) & 0xff , step_goal_th & 0xff};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_STEP_GOAL, server_id, conn_id);
break;
}
case 0x01: { // 设置步数目标
static_print_debug("set step goal");
uint32_t step_goal = write_cb_para[4] << 24 | write_cb_para[5] << 16 |
write_cb_para[6] << 8 | write_cb_para[7];
sql_fit_set_goal_step_th(step_goal);
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READ_STEP_GOAL, server_id, conn_id);
break;
}
default:
static_print_error("unknown step goal setting read");
break;
}
break;
}
case SET_READING_SCREEN_BRIGHTNESS_LEVEL: {
switch (write_cb_para[3]) {
case 0x00: { // 读取屏幕亮度等级
static_print_debug("read screen brightness level");
uint8_t data[] = {0x00, 0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READING_SCREEN_BRIGHTNESS_LEVEL, server_id, conn_id);
break;
}
case 0x01: { // 设置屏幕亮度等级
static_print_debug("set screen brightness level");
uint8_t sedentary_reminder_parameters = write_cb_para[4];
static_print_debug("screen brightness level: %d", sedentary_reminder_parameters);
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), SET_READING_SCREEN_BRIGHTNESS_LEVEL, server_id, conn_id);
break;
}
default:
static_print_error("unknown screen brightness level setting read");
break;
}
break;
}
case DIAL_PUSH_DIAL_START_COMMAND: {
static_print_debug("dial push dial start command");
// 表盘数据推送开始命令
g_dial_push_data_pkg = write_cb_para[3] << 8 | write_cb_para[4];
static_print_debug("dial push data pkg: %d", g_dial_push_data_pkg);
// 电量检测
// 空间检测
// 更改MTU大小
dial_context.buffer_offset = 0;
dial_context.expected_seq = 0;
dial_context.buffer = malloc(517 * g_dial_push_data_pkg);
if (dial_context.buffer == NULL) {
static_print_error("malloc failed");
return;
}
memset_s(dial_context.buffer, 517 * g_dial_push_data_pkg, 0, 517 * g_dial_push_data_pkg);
uint8_t data[] = {0x01, 0x02, 0x05};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), DIAL_PUSH_DIAL_START_COMMAND, server_id, conn_id);
g_dial_push_data_mask = 1;
break;
}
case GET_WEATHER_DATA: {
static_print_debug("get weather data");
// 从 app 获取天气数据
switch (write_cb_para[7]) {
case 0x00: { // 今天
sql_weather_set_now_temperature(write_cb_para[4]);
sql_weather_set_forecast_protocol_value(write_cb_para[7], write_cb_para[3]);
sql_weather_set_forecast_temperature_max(write_cb_para[7], write_cb_para[5]);
sql_weather_set_forecast_temperature_min(write_cb_para[7], write_cb_para[6]);
break;
}
case 0x01: { // 明天
sql_weather_set_forecast_protocol_value(write_cb_para[7], write_cb_para[3]);
sql_weather_set_forecast_temperature_max(write_cb_para[7], write_cb_para[5]);
sql_weather_set_forecast_temperature_min(write_cb_para[7], write_cb_para[6]);
break;
}
case 0x02: { // 后天
sql_weather_set_forecast_protocol_value(write_cb_para[7], write_cb_para[3]);
sql_weather_set_forecast_temperature_max(write_cb_para[7], write_cb_para[5]);
sql_weather_set_forecast_temperature_min(write_cb_para[7], write_cb_para[6]);
struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops();
struct rtc_time tm_info = {0};
rtc_api->get_rtc_time(&tm_info);
sql_weather_set_update_hour(tm_info.tm_hour);
sql_weather_set_update_minute(tm_info.tm_min);
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), GET_WEATHER_DATA, server_id, conn_id);
break;
}
default:
break;
}
break;
}
case WALLPAPER_PUSH_START_COMMAND: {
static_print_debug("wallpaper push start command");
// 壁纸数据推送开始命令
g_wallpaper_push_data_pkg = write_cb_para[3] << 8 | write_cb_para[4];
static_print_debug("dial push data pkg: %d", g_wallpaper_push_data_pkg);
// 电量检测
// 空间检测
// 更改MTU大小
wallpaper_context.buffer_offset = 0;
wallpaper_context.expected_seq = 0;
wallpaper_context.buffer = malloc(517 * g_wallpaper_push_data_pkg);
if (wallpaper_context.buffer == NULL) {
static_print_error("malloc failed");
return;
}
memset_s(wallpaper_context.buffer, 517 * g_wallpaper_push_data_pkg, 0, 517 * g_wallpaper_push_data_pkg);
uint8_t data[] = {0x01, 0x02, 0x05};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), WALLPAPER_PUSH_START_COMMAND, server_id, conn_id);
g_wallpaper_push_data_mask = 1;
break;
}
case DO_NOT_DISTURB_MODE: {
switch (write_cb_para[3]) {
case 0x00: { // 读取勿扰模式设置
static_print_debug("read do not disturb mode");
uint8_t data[] = {0x00, 0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), DO_NOT_DISTURB_MODE, server_id, conn_id);
break;
}
case 0x01: { // 设置勿扰模式
static_print_debug("set do not disturb mode");
uint8_t sedentary_reminder_parameters = write_cb_para[4];
static_print_debug("screen brightness level: %d", sedentary_reminder_parameters);
uint8_t data[] = {0x01, 0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), DO_NOT_DISTURB_MODE, server_id, conn_id);
break;
}
default:
static_print_error("unknown screen brightness level setting read");
break;
}
break;
}
case CONTACTS_PUSH_START_COMMAND: {
static_print_debug("contacts push start command");
// 通讯录数据推送开始命令
g_contacts_push_data_pkg = write_cb_para[3] << 8 | write_cb_para[4];
static_print_debug("dial push data pkg: %d", g_contacts_push_data_pkg);
// 电量检测
uint8_t vbat_present = tjd_service_charger_get_battery();
if (vbat_present <= 20){
static_print_debug("battery is low cant rev addressbook data");
uint8_t data[] = {0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), CONTACTS_PUSH_START_COMMAND, server_id, conn_id);
return;
}
// 空间检测
// 更改MTU大小
// 获取通讯录文件目前储存的通讯录条数
struct stat fileStat = {0};
int ret = stat(TJD_ADDRESS_BOOK_PATH,&fileStat);
static_print_debug("access ret is %d", ret);
if(ret == 0){
static_print_debug("file exist");
//获取文件大小
FILE *fp = NULL;
size_t ret;
fp = fopen(TJD_ADDRESS_BOOK_PATH, "a+");
if (fp == NULL) {
static_print_error("fopen %s failed!", TJD_ADDRESS_BOOK_PATH);
// return -1;
}
long long file_size = 0;
file_size = fileStat.st_size;
static_print_debug("file size is %lld", file_size);
Contact contact_buffer = {0};
uint8_t contact_num = file_size/sizeof(Contact);
static_print_debug("addressbook has %d numbers contact data", contact_num);
if(contact_num >= MAX_CONTACTS){
static_print_debug("addressbook has more than MAX_CONTACTS numbers contact data, so we only use MAX_CONTACTS numbers");
uint8_t data[] = {0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), CONTACTS_PUSH_START_COMMAND, server_id, conn_id);
}else{
contacts_context.buffer_offset = 0;
contacts_context.expected_seq = 0;
contacts_context.buffer = malloc(23 * g_contacts_push_data_pkg);
if (contacts_context.buffer == NULL) {
static_print_error("malloc failed");
return;
}
memset_s(contacts_context.buffer, 23 * g_contacts_push_data_pkg, 0, 23 * g_contacts_push_data_pkg);
// uint8_t data[] = {0x01, 0x02, 0x05};
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), CONTACTS_PUSH_START_COMMAND, server_id, conn_id);
g_contacts_push_data_mask = 1;
}
fclose(fp);
}else if (ret == -1){
//通讯录文件不存在
contacts_context.buffer_offset = 0;
contacts_context.expected_seq = 0;
contacts_context.buffer = malloc(23 * g_contacts_push_data_pkg);
if (contacts_context.buffer == NULL) {
static_print_error("malloc failed");
return;
}
memset_s(contacts_context.buffer, 23 * g_contacts_push_data_pkg, 0, 23 * g_contacts_push_data_pkg);
// uint8_t data[] = {0x01, 0x02, 0x05};
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), CONTACTS_PUSH_START_COMMAND, server_id, conn_id);
g_contacts_push_data_mask = 1;
}
break;
}
case GET_BLUETOOTH_MAC_ADDRESS: {
static_print_debug("get bluetooth mac address");
// 获取蓝牙地址
uint8_t *mac_addr = sql_bt_get_mac_addr();
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, mac_addr, BT_MAC_ADDR_LEN, GET_BLUETOOTH_MAC_ADDRESS, server_id, conn_id);
// errcode_t ret = gap_ble_set_ctkd_enable(false);
// static_print_debug("gap_ble_set_ctkd_enable ret = %u", ret);
break;
}
case REC_QR_CODE_INFORMATION: {
// app开始分包发送消息我要接收分包数据
static_print_debug("android push qrcode information");
uint8_t qrcode_all_index = write_cb_para[4];
uint8_t qrcode_index = write_cb_para[5];
uint8_t qrcode_len = len - 6;
uint8_t qrcode_type = write_cb_para[3];
// if (qrcode_type > 10) {
// static_print_error("unknown qrcode type");
// return;
// }
if(qrcode_type == TJD_QRCODE_TYPE_QQ){
qrcode_type = QRCODE_QQ;
}
if (qrcode_index == 0x01) {
qrcode_context.buffer_offset = 0;
qrcode_context.expected_seq = 1;
qrcode_context.buffer = malloc(qrcode_len * qrcode_all_index);
if (qrcode_context.buffer == NULL) {
static_print_error("malloc qrcode buffer error");
return;
}
memset_s(qrcode_context.buffer, qrcode_len * qrcode_all_index, 0, qrcode_len * qrcode_all_index);
}
static_print_debug("qrcode_type: %d, qrcode_all_index: %d, qrcode_index: %d", qrcode_type, qrcode_all_index,
qrcode_index);
if (qrcode_index == qrcode_context.expected_seq++ && qrcode_all_index != qrcode_index) {
if (qrcode_context.buffer_offset + qrcode_len > PROTOCOL_BUFFER_MAX_LEN) {
static_print_error("qrcode buffer overflow");
return;
}
memcpy_s(qrcode_context.buffer + qrcode_context.buffer_offset, qrcode_len * qrcode_all_index,
&write_cb_para[6], qrcode_len);
qrcode_context.buffer_offset += qrcode_len;
} else if (qrcode_all_index == qrcode_index) {
if (qrcode_context.buffer_offset + qrcode_len < PROTOCOL_BUFFER_MAX_LEN) {
memcpy_s(qrcode_context.buffer + qrcode_context.buffer_offset, qrcode_len * qrcode_all_index,
&write_cb_para[6], qrcode_len);
qrcode_context.buffer_offset += qrcode_len;
}
static_print_debug("qrcode_data:");
for (uint32_t i = 0; i < qrcode_context.buffer_offset; i++) {
static_print_debug("%02x", qrcode_context.buffer[i]);
}
static_print_debug("qrcode_context.buffer_offset = %d", qrcode_context.buffer_offset);
// 保存消息到数据库
static_print_debug("save qrcode info [%d] to database ", qrcode_type);
if (sql_bt_set_qrcode_exist(true, qrcode_type) == RET_ERROR) {
static_print_error("set qrcode exist error");
return;
}
if (sql_bt_set_qrcode_info(qrcode_type, qrcode_context.buffer, qrcode_context.buffer_offset) ==
RET_ERROR) {
static_print_error("set qrcode detail info error");
return;
}
qrcode_context.buffer_offset = 0;
qrcode_context.expected_seq = 1;
free(qrcode_context.buffer);
qrcode_context.buffer = NULL;
#if 0
// 从数据库读取二维码信息
uint8_t qrcode_data[256] = {0};
uint16_t qrcode_len = 0;
if (sql_bt_get_qrcode_info(qrcode_type, qrcode_data, &qrcode_len) == RET_ERROR) {
static_print_error("get qrcode detail info error");
return;
}
static_print_debug("qrcode [%d] detail info: %s", qrcode_type, qrcode_data);
#endif
// 通知app获取消息成功
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), REC_QR_CODE_INFORMATION, server_id, conn_id);
}
break;
}
case IOS_GETS_DEV_BLUETOOTH_CONNEC_STATUS: {
static_print_debug("ios gets dev bluetooth connec status");
// 通知app获取蓝牙连接状态
bool aclConnected = bt_is_acl_connected(&g_conn_addr);
uint8_t data[] = {0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), IOS_GETS_DEV_BLUETOOTH_CONNEC_STATUS, server_id,
conn_id);
break;
}
case APP_READS_DIAL_PARAMETERS: {
static_print_debug("app reads dial parameters");
// 通知app表盘推送参数
uint8_t data[] = {0x02, 0x01, 0xd2, 0x01, 0xD2, 0x03, 0xE8};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), APP_READS_DIAL_PARAMETERS, server_id, conn_id);
break;
}
// case MODIFY_BLUETOOTH_NAME: {
// static_print_debug("modify bluetooth name");
// static_print_debug("set local name: %s", &write_cb_para[3]);
// errcode_t ret = gap_ble_set_local_name(&write_cb_para[3],len - 4);
// if(ret != ERRCODE_SUCC){
// static_print_error("set local name error");
// uint8_t data[] = {0x00};
// tjd_ble_protocol_send_data(data, sizeof(data), MODIFY_BLUETOOTH_NAME, server_id, conn_id);
// }else{
// uint8_t data[] = {0x01};
// tjd_ble_protocol_send_data(data, sizeof(data), MODIFY_BLUETOOTH_NAME, server_id, conn_id);
// }
// }
case DEVICE_OTHER_FUNCTION_EXTENSION: {
static_print_debug("device other function extension");
// 通知app设备其他功能扩展
uint8_t data[] = {0x40, 0xC9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), DEVICE_OTHER_FUNCTION_EXTENSION, server_id, conn_id);
break;
}
case FIRST_CONNECTION_RESPONSE: {
static_print_debug("first connection response");
// 通知app首次连接成功
uint8_t data = 0x01;
// uint8_t *send_data = malloc(sizeof(data));
// if (send_data == NULL) {
// static_print_debug("malloc send_data fail");
// return;
// }
// memcpy_s(send_data, sizeof(data), data, sizeof(data));
// static_print_debug("send_data: %02x ", send_data[0]);
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, &data, sizeof(uint8_t), FIRST_CONNECTION_RESPONSE, server_id, conn_id);
break;
}
case GET_DEVICE_ID: {
static_print_debug("get device id");
// 获取设备id
uint8_t data[] = {0x34, 0xe6};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), GET_DEVICE_ID, server_id, conn_id);
break;
}
case APP_GETS_SPORT_DATA: {
static_print_debug("app gets sport data");
//app获取运动记录数据
tjd_service_send_sport_record_data();
break;
}
case APP_SENDING_ADDRESS: {
static_print_debug("app sending address");
// TODO: 接收app下发的地址
uint8_t received_seq = write_cb_para[4];
if (received_seq != addr_context.expected_seq) {
// 错误处理:包序号不匹配
static_print_debug("received_seq(%d) != expected_seq(%d)", received_seq, addr_context.expected_seq);
}
if (received_seq == 0x00) {
addr_context.buffer_offset = 0;
addr_context.expected_seq = 0x00;
addr_context.buffer = malloc(PROTOCOL_DATA_LEN * write_cb_para[3]);
if (addr_context.buffer == NULL) {
static_print_error("malloc failed");
return;
}
}
memcpy_s(addr_context.buffer + addr_context.buffer_offset, PROTOCOL_MAX_LEN, &write_cb_para[5],
len - 6);
addr_context.buffer_offset += (len - 6);
addr_context.expected_seq++;
if (write_cb_para[3] == addr_context.expected_seq) {
static_print_debug("receive all data");
static_print_debug("addr_context.buffer_offset: %d, push_data_pkg: %d, addr_context.expected_seq: %d",
addr_context.buffer_offset, write_cb_para[3], addr_context.expected_seq);
uint8_t mask_i = 0;
uint8_t mask_j = 0;
char *decode_str = NULL;
for (uint32_t i = 0; i < addr_context.buffer_offset; i += 3) {
if (addr_context.buffer[i] == 0xe7 && addr_context.buffer[i + 1] == 0x9c &&
addr_context.buffer[i + 2] == 0x81) {
mask_i = i + 3;
} else if (addr_context.buffer[i] == 0xe5 && addr_context.buffer[i + 1] == 0xb8 &&
addr_context.buffer[i + 2] == 0x82) {
mask_j = i;
decode_str = (char *)malloc(mask_j - mask_i + 3 + 1); // 多加1是为了解码后字符串末尾加上\0
if (decode_str == NULL) {
static_print_error("decode_str malloc failed");
return;
}
memcpy(decode_str, addr_context.buffer + mask_i, mask_j - mask_i + 3);
decode_str[mask_j - mask_i + 3] = '\0';
for (int j = 0; j < mask_j - mask_i + 3; j++) {
static_print_debug("decode_str[%d]: %02x ", j, decode_str[j]);
}
break;
}
}
sql_weather_set_location_txt((char *)decode_str, mask_j - mask_i + 3);
free(decode_str);
// char * location_txt = sql_weather_get_location_txt();
// static_print_debug("location_txt: %s",location_txt);
free(addr_context.buffer);
addr_context.buffer = NULL;
addr_context.buffer_offset = 0;
addr_context.expected_seq = 0;
uint8_t data1[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data1, sizeof(data1), APP_SENDING_ADDRESS, server_id, conn_id);
}
break;
}
case MS_GAME_MODE: {
static_print_debug("ms game mode");
// 通知app进入游戏模式
if(write_cb_para[3] == 0x03){
tjd_into_msgame_view();
}else if(write_cb_para[3] == 0x04){
tjd_exit_app_view();
}
uint8_t data = 0x01;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(uint8_t), MS_GAME_MODE, server_id, conn_id);
break;
}
case SEND_GSENSOR_DATA:{
static_print_debug("send gsensor data station");
if(write_cb_para[3] == 0x01){
static_print_debug("send gsensor data station success");
}else{
static_print_debug("send gsensor data station faile");
}
}
case APP_SENDING_DEVICE_TYPE:{
static_print_debug("send deveice type");
gap_ble_set_ctkd_enable(true);
gap_ble_pair_remote_device(tjd_get_lastconned_addr());
break;
}
case GET_MTU_SIZE: {
static_print_debug("get mtu size");
// app获取mtu大小
uint32_t mtu_size = tjd_ble_get_mtu_size() - 3 > 509 ? 509 : tjd_ble_get_mtu_size() - 3; // 减去协议头长度
uint8_t data[2] = {(uint8_t)(mtu_size), (uint8_t)(mtu_size >> 8)};
// uint8_t data[2] = {(uint8_t)(mtu_size >> 8), (uint8_t)(mtu_size)};
static_print_debug("mtu_size: %d, data: %02x %02x", mtu_size, data[0], data[1]);
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), GET_MTU_SIZE, server_id, conn_id);
break;
}
case GET_MAILLIST_FREE_NUM:{
static_print_debug("get maillist free num");
get_addrbook_cnt(GET_MAILLIST_FREE_NUM,server_id, conn_id);
break;
}
case GET_USER_NAME: {
static_print_debug("get user name");
// 获取用户名
char user_name[32] = {0};
memcpy_s(user_name, 32 ,write_cb_para + 3 ,len - 4);
static_print_debug("user name: %s", user_name);
sql_fit_set_user_name(user_name);
#if 1
char user_name_get[32] = {0};
sql_fit_get_user_name(user_name_get);
static_print_debug("user name get: %s", user_name_get);
#endif
// uint8_t data_len = strlen(user_name) + 1;
uint8_t data = 0x01;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(uint8_t), GET_USER_NAME, server_id, conn_id);
tjd_service_gps_sync_ephemeris_event();
// tjd_ble_request_gps();
break;
}
case GET_BLE_NAME: {
static_print_debug("get ble name");
char local_name[13] = {0};
memcpy_s(local_name, 13, &write_cb_para[3],len - 4);
static_print_debug("set local name: %s , len : %d", local_name, strlen(local_name));
errcode_t bt_ret = bluetooth_set_local_name((const unsigned char *)local_name, strlen(local_name) + 1);
static_print_debug("bt_set_local_name ret(errcode_t): %x ", bt_ret);
uint8_t local_bt_name[32] = {0};
uint8 local_name_len = 0;
bt_ret = bluetooth_get_local_name(local_bt_name,&local_name_len);
static_print_debug("bluetooth_get_local_name ret : %x ,local_name: %s, local_name_len:%d",bt_ret, local_bt_name, local_name_len);
errcode_t ret = gap_ble_set_local_name((const uint8_t *)local_name,strlen(local_name) + 1);
if(ret != ERRCODE_SUCC || bt_ret != ERRCODE_SUCC){
static_print_error("set local name error");
uint8_t data[] = {0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), GET_BLE_NAME, server_id, conn_id);
}else{
static_print_debug("set local name success");
sql_bt_set_ble_name((const uint8_t *)local_name,strlen(local_name));
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data), GET_BLE_NAME, server_id, conn_id);
}
ret = gap_ble_disconnect_remote_device(tjd_get_lastconned_addr());
if(ret != ERRCODE_SUCC){
static_print_debug("disconnect remote device faile ret: %x", ret);
}else{
static_print_debug("disconnect remote device success");
}
break;
}
default:
static_print_debug("unknown control command");
break;
}
}
void tjd_ble_upload_ai_func_attribute(void)
{
uint8 send_data[32] = {0};
int index = 0;
send_data[index++] = 0x0C;
send_data[index++] = 0x00;
send_data[index++] = 0x06;
send_data[index++] = 0x01;
// 设置屏幕分辨率
SET_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_WEIGHT);
SET_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_HEIGHT);
send_data[index++] = 0x03;
send_data[index++] = 0x02;
send_data[index++] = 0x00;
send_data[index++] = 0x03;
send_data[index++] = 0x03;
send_data[index++] = 0x03;
uint8_t pack_head = 0x5B;
tjd_ble_protocol_send_lefun_data(&pack_head,send_data,index,REPORT_AI_FUNCTION_ATTRIBUTES);
}
void tjd_ble_loop_send_data(uint8_t * pack_head_, uint8_t *data, uint16_t len, uint8_t cmd)
{
uint8_t pack_head = *pack_head_;
uint8_t head_tail_len = 0;
uint32_t mtu_size = tjd_ble_get_mtu_size() - 3 > 509 ? 509 : tjd_ble_get_mtu_size() - 3;
uint8_t cur_offset = 0;
uint8_t cur_pack_num = 0;
uint8_t total_pack_num = 0;
uint32_t total_data_len = 0;
if(pack_head == PROTOCOL_RES_FRAME_HEAD){
head_tail_len = 4;
}else if(pack_head == PROTOCOL_RES_FRAME_HEAD_2){
head_tail_len = 5;
}
total_data_len = len + head_tail_len;
total_pack_num = total_data_len / mtu_size;
uint8_t * send_data_buf_head = (uint8_t *)malloc(mtu_size);
memset(send_data_buf_head, 0, mtu_size);
uint16_t send_buffer_len = mtu_size;
while(cur_pack_num <= total_pack_num){
if(cur_pack_num == total_pack_num){
send_buffer_len = total_data_len - cur_offset;
}
memset_s(send_data_buf_head, mtu_size, 0, mtu_size);
int index = 0;
send_data_buf_head[index++] = pack_head;
if(head_tail_len == 4){
send_data_buf_head[index++] = send_buffer_len & 0xFF;
}else{
send_data_buf_head[index++] = send_buffer_len >> 8 & 0xFF;
send_data_buf_head[index++] = send_buffer_len & 0xFF;
}
send_data_buf_head[index++] = cmd;
memcpy_s(send_data_buf_head + head_tail_len - 1, mtu_size - head_tail_len, data + cur_offset, send_buffer_len - head_tail_len);
index+= send_buffer_len - head_tail_len;
send_data_buf_head[index] = do_crc(send_data_buf_head, index);
cur_offset += send_buffer_len - head_tail_len;
cur_pack_num++;
gatt_send_response(send_data_buf_head, send_buffer_len,gatt_server_id,g_server_conn_id);
}
}
void tjd_ble_upload_custom_dial_attribute(void)
{
uint8 send_data[32] = {0};
int index = 0;
//设置数据长度
send_data[index++] = 0x18;
// 设置固定值
send_data[index++] = 0x00;
send_data[index++] = 0x06;
send_data[index++] = 0x01;
// 设置屏幕分辨率
SET_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_WEIGHT);
SET_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_HEIGHT);
// 设置固定值
send_data[index++] = 0x06;
send_data[index++] = 0x02;
// 设置屏幕分辨率的一半
SET_HALF_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_WEIGHT);
SET_HALF_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_WEIGHT);
// 设置支持的背景模式
send_data[index++] = 0x05;
send_data[index++] = 0x03;
send_data[index++] = 0x01;
send_data[index++] = 0x02;
send_data[index++] = 0x03;
// 设置多图模式的最大图片数
send_data[index++] = 0x03;
send_data[index++] = 0x04; //支持多图模式最大图片数 type
send_data[index++] = 0x05; //支持多图模式最大图片数 value
// 设置切换方式
send_data[index++] = 0x04;
send_data[index++] = 0x05;
send_data[index++] = 0x01; //切换方式 : 00 自动 01 手动 02 抬腕切图
send_data[index++] = 0x02; //切换方式 : 00 自动 01 手动 02 抬腕切图
uint8_t pack_head = 0x5B;
// tjd_ble_protocol_send_lefun_data(&pack_head,send_data,index,REPORTED_CUSTOM_DIAL_PROPERTIES);
tjd_ble_loop_send_data(&pack_head, send_data, index,REPORTED_CUSTOM_DIAL_PROPERTIES);
}
void tjd_ble_cpy_utf8_data(uint8_t *dest, uint16_t *len , uint8_t *data_type)
{
if(g_data_flow.data == NULL) return;
*len = g_data_flow.len;
*data_type = g_data_flow.data_flow_type;
memcpy_s(dest, g_data_flow.len, g_data_flow.data, g_data_flow.len);
}
void tjd_ble_protocol_ctrlcmd_ac(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para , uint16_t len)
{
static_print_info(" tjd_ble_protocol_ctrlcmd_ac(len:%d):\r\n",len);
for(int i = 0 ; i < len ; ){
static_print_info("%02x", write_cb_para[i]);
i++;
if(i % 10 == 0){
static_print_info("\r\n");
}
if(i>=60){ break;}
}
static_print_info("\r\n");
uint8_t crc = write_cb_para[len - 1];
uint8_t crc_cal = do_crc(write_cb_para, len - 1);
uint8_t cmd_id = write_cb_para[3];
if (crc != crc_cal) {
static_print_error("control command crc error");
if(cmd_id == 0xB3){
uint8_t data[9] = {0};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, &data, sizeof(data), cmd_id, server_id, conn_id);
}else{
uint8_t data = 0x00;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, &data, sizeof(data), cmd_id, server_id, conn_id);
}
return;
}
switch (cmd_id) {
case CUSTOM_DIAL_REQUEST: {
static_print_debug("custom dial request");
if(write_cb_para[4] == 0x01){ //APP主动下发请求
if(write_cb_para[5] == 0x00){ //APP请求属性
//回复请求属性
static_print_debug("custom dial request, app request attribute");
uint8_t data[3] = {0x00,0x00,0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
tjd_ble_upload_custom_dial_attribute(); //设备上报自定义表盘属性
}else if(write_cb_para[5] == 0x01){ //APP请求进入自定义表盘模式
static_print_debug("custom dial request, app request enter custom dial mode");
uint8_t data[3] = {0x00,0x01,0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
//待实现 ChangeSlice 到自定义表盘页面
}else if(write_cb_para[5] == 0x02){ //APP请求退出自定义表盘模式
static_print_debug("custom dial request, app request exit custom dial mode");
uint8_t data[3] = {0x00,0x02,0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
tjd_exit_app_view();
}
}else if(write_cb_para[4] == 0x00){ //APP回复设备请求
if(write_cb_para[5] == 0x00){ //APP回复设备请求属性
if(write_cb_para[6] == 0x00){
static_print_debug("app reply device request property failed");
}else{
static_print_debug("app reply device request property success");
}
}else if(write_cb_para[5] == 0x01){ //APP回复设备进入自定义表盘模式
if(write_cb_para[6] == 0x00){
static_print_debug("app reply device request enter custom watch face mode failed");
}else{
static_print_debug("app reply device request enter custom watch face mode success");
}
}else if(write_cb_para[5] == 0x02){ //APP回复设备退出自定义表盘模式
if(write_cb_para[6] == 0x00){
static_print_debug("app reply device request exit custom watch face mode failed");
}else{
static_print_debug("app reply device request exit custom watch face mode success");
}
}
}
break;
}
case REPORTED_CUSTOM_DIAL_PROPERTIES: {
if(write_cb_para[4] == 0x00){ //App回复设备上报自定义表盘参数失败
static_print_debug("app reply device report custom dial properties failed");
}else if(write_cb_para[4] == 0x01){ //App回复设备上报自定义表盘参数成功
static_print_debug("app reply device report custom dial properties success");
}else if(write_cb_para[4] == 0x02){ //App回复设备上报自定义表盘参数接收完成
static_print_debug("app reply device report custom dial properties complete");
}
break;
}
case ISSUE_DIAL_PARAMETERS: {
handle_app_issue_dial_parameters_cmd(server_id,conn_id,write_cb_para,len,ISSUE_DIAL_PARAMETERS);
break;
}
case AI_FUNCTION_REQUEST: {
static_print_debug("ai function request");
if(write_cb_para[5] == 0xF1){
if(write_cb_para[6] == 0x00){
//请求属性
}else if(write_cb_para[6] == 0x01){
//请求进入音生文模式
if(write_cb_para[7] == 0x00){
//失败
static_print_debug("Request to enter voice mode failed!");
}else if(write_cb_para[7] == 0x01){
//成功
static_print_debug("Request to enter voice mode success!");
}
}else if(write_cb_para[6] == 0x02){
//请求退出音生文模式
if(write_cb_para[7] == 0x00){
//失败
static_print_debug("Request to exit voice mode failed!");
}else if(write_cb_para[7] == 0x01){
//成功
static_print_debug("Request to exit voice mode success!");
}
}
}else if(write_cb_para[5] == 0xF2){
if(write_cb_para[6] == 0x00){
//请求属性
}else if(write_cb_para[6] == 0x01){
//请求进入AI文生图模式
if(write_cb_para[7] == 0x00){
//失败
static_print_debug("Request to enter AI Vincennes diagram mode failed!");
}else if(write_cb_para[7] == 0x01){
//成功
static_print_debug("Request to enter AI Vincennes diagram mode success!");
}
}else if(write_cb_para[6] == 0x02){
//请求退出AI文生图模式
}
}
break;
}
case REPORT_AI_FUNCTION_ATTRIBUTES: {
static_print_debug("report ai function attributes");
if(write_cb_para[4] == 0x00){
static_print_debug("report ai function attributes failed");
}else if(write_cb_para[4] == 0x01){
static_print_debug("report ai function attributes success");
}else if(write_cb_para[4] == 0x02){
static_print_debug("report ai function attributes received complete");
}
break;
}
case AI_AUDIO_TRANSMISSION_MANAGEMENT: {
static_print_debug("ai audio transmission management");
//App回复设备 请求进入 音源传输管理
if(write_cb_para[6] == 0x00){
//失败
g_tjd_ble_ai_audio_trans_flag = false;
static_print_debug("ai audio transmission management fail");
}else if(write_cb_para[6] == 0x01){
//成功
g_tjd_ble_ai_audio_trans_flag = true;
static_print_debug("ai audio transmission management success");
}
break;
}
case REQUEST_DIAGRAM_GENERATION: {
static_print_debug("request diagram generation");
uint8_t data_flow_id = write_cb_para[4];
static_print_debug("data flow id: %d", data_flow_id);
bool is_success = false;
if(write_cb_para[5] == 0x00){
if(write_cb_para[6] == 0x00){
static_print_debug("first request diagram generation failed");
}else if(write_cb_para[6] == 0x01){
//成功
static_print_debug("first request diagram generation success");
is_success = true;
}
}else if(write_cb_para[5] == 0x01){
if(write_cb_para[6] == 0x00){
static_print_debug("retry request diagram generation failed");
}else if(write_cb_para[6] == 0x01){
//成功
static_print_debug("retry request diagram generation success");
is_success = true;
}
}
if(g_play_dial_request_generate_picture_callback != NULL){
g_play_dial_request_generate_picture_callback(is_success);
}
break;
}
case REPORT_DIAGRAM_TRANSMIT: {
static_print_debug("request diagram transmit");
if(write_cb_para[4] == 0x00){
if(write_cb_para[5] == 0x00){
static_print_debug("request background diagram transmit failed");
}else if(write_cb_para[5] == 0x01){
static_print_debug("request background diagram transmit success");
// if(g_file_description_packet.file_type == TYPE_AIDIAL_PREVIEW && g_play_dial_preview_callback != NULL){
// g_play_dial_preview_callback((char *)g_file_description_packet.file_name);
// }
}
}else if(write_cb_para[4] == 0x01){
if(write_cb_para[5] == 0x00){
static_print_debug("request background thumbnail diagram transmit failed");
}else if(write_cb_para[5] == 0x01){
static_print_debug("request background thumbnail diagram transmit success");
}
}
break;
}
case REQUEST_DEVICE_DIAL_INFORMATION: {
static_print_debug("request device dial information");
//获取表盘信息
handle_device_dial_information_cmd(server_id, conn_id, write_cb_para,len,REQUEST_DEVICE_DIAL_INFORMATION);
break;
}
case REQUEST_TO_DELETE_DIAL: {
static_print_debug("request to delete dial");
//删除表盘
uint32_t id = write_cb_para[4] << 24 | (write_cb_para[5] << 16) | (write_cb_para[6] << 8) | write_cb_para[7];
if(TjdUiWfUninstallBeforNotify(id)){
static_print_debug("delete dial before notify success");
}else{
static_print_debug("delete dial before notify fail");
}
uint8_t data[5] = {0};
if(TjdUiWfUninstallBeforNotify(id)){
static_print_debug("delete dial before notify success");
}else{
static_print_debug("delete dial before notify fail");
}
if(TjdUiWfDeletebyID(id)){
static_print_debug("delete dial success");
data[0] = 0x01;
if(TjdUiWfUninstallAfterNotify(id)){
static_print_debug("delete dial after notify success");
}else{
static_print_debug("delete dial after notify fail");
}
}else{
static_print_debug("delete dial fail");
data[0] = 0x00;
}
data[1] = (id >> 24) & 0xFF;
data[2] = (id >> 16) & 0xFF;
data[3] = (id >> 8) & 0xFF;
data[4] = id & 0xFF;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, &data, sizeof(data), cmd_id, server_id, conn_id);
break;
}
case REQUEST_WEATHER_DATA: {
static_print_debug("request weather data");
handle_weather_data_cmd(server_id, conn_id, write_cb_para,len,REQUEST_WEATHER_DATA);
break;
}
case OTA_MODE_SWITCH_NEW: {
static_print_debug("OTA mode switch new");
tjd_ble_protocol_switch_ota(server_id, conn_id, write_cb_para,len,OTA_MODE_SWITCH_NEW);
break;
}
case DOWNLOAD_FILE_DESCRIPTION: {
static_print_debug("send file description");
tjd_ble_protocol_file_description(server_id, conn_id, write_cb_para, len, cmd_id);
break;
}
case DOWNLOAD_FILE_SRART: {
static_print_debug("send file start");
tjd_ble_protocol_file_start(server_id, conn_id, write_cb_para, len, cmd_id);
break;
}
case DOWNLOAD_FILE_END_DATA: {
static_print_debug("send file end data");
tjd_ble_protocol_file_end(server_id, conn_id, write_cb_para, len, cmd_id);
break;
}
case DOWNLOAD_FILE_DATA: {
// static_print_debug("download file data");
tjd_ble_protocol_file_data(server_id, conn_id, write_cb_para, len , cmd_id);
break;
}
case UPLOAD_FILE_DESCRIPTION: {
static_print_debug("upload file description");
tjd_ble_protocol_file_upload_description_recover_handle(server_id, conn_id, write_cb_para, len , cmd_id);
break;
}
case UPLOAD_FILE_SRART: {
static_print_debug("upload file start");
tjd_ble_protocol_file_upload_start_recover_handle(server_id, conn_id, write_cb_para, len , cmd_id);
break;
}
case UPLOAD_FILE_END_DATA: {
static_print_debug("upload file end data");
tjd_ble_protocol_file_upload_end_recover_handle(server_id, conn_id, write_cb_para, len , cmd_id);
break;
}
case UPLOAD_FILE_DATA: {
static_print_debug("upload file data");
tjd_ble_protocol_file_upload_data_recover_handle(server_id, conn_id, write_cb_para, len , cmd_id);
break;
}
case DATA_FLOW_DOWNLOAD_STARTS: {
static_print_debug("data flow download starts");
uint8_t data_flow_type = write_cb_para[5];
// memset(&g_data_flow, 0, sizeof(g_data_flow));
if(g_data_flow.data_flow_id + 1 == write_cb_para[4]){
g_data_flow.data_flow_id++;
g_data_flow.data_flow_type = 1;
}else{
g_data_flow.data_flow_id = write_cb_para[4];
g_data_flow.data_flow_type = 0;
}
if(g_data_flow.data == NULL){
g_data_flow.data = (uint8_t *)malloc(512);
if(g_data_flow.data == NULL){
static_print_error("malloc data flow data fail");
free(g_data_flow.data);
g_data_flow.data = NULL;
uint8_t data[] = {write_cb_para[4],data_flow_type,0x00};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DATA_FLOW_DOWNLOAD_STARTS, server_id, conn_id);
return;
}
memset(g_data_flow.data, 0, 512);
static_print_debug("malloc data flow data success");
}
uint8_t data[] = {write_cb_para[4],data_flow_type,0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DATA_FLOW_DOWNLOAD_STARTS, server_id, conn_id);
// if(write_cb_para[5] == 0x00){
// //文本UTF-8 数据流类型
// static_print_debug("text utf-8 data flow starts");
// // 回复app 数据流下发开始
// }else if(write_cb_para[5] == 0x10){
// //音频 数据流类型
// static_print_debug("audio data flow starts");
// // 回复app 数据流下发开始
// g_data_flow.data_flow_id = write_cb_para[4];
// uint8_t data[] = {g_data_flow.data_flow_id,0x10,0x01};
// tjd_ble_protocol_send_data(data, sizeof(data), DATA_FLOW_STARTS, server_id, conn_id);
// }else if(write_cb_para[5] == 0x20){
// //视频 数据流类型
// static_print_debug("video data flow starts");
// // 回复app 数据流下发开始
// g_data_flow.data_flow_id = write_cb_para[4];
// uint8_t data[] = {g_data_flow.data_flow_id,0x20,0x01};
// tjd_ble_protocol_send_data(data, sizeof(data), DATA_FLOW_STARTS, server_id, conn_id);
// }
break;
}
case DATA_FLOW_DOWNLOAD_ENDS: {
static_print_debug("data flow download ends");
//回复app 数据流下发成功结束
if(g_data_flow.data != NULL){
// static_print_debug("g_data_flow.data : %s",g_data_flow.data);
if(g_lefun_ai_data_end_callback != NULL){
g_lefun_ai_data_end_callback(&g_data_flow);
}
}
uint8_t data[] = {write_cb_para[4],0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DATA_FLOW_DOWNLOAD_ENDS, server_id, conn_id);
break;
}
case DATA_FLOW_DOWNLOAD_SENDS_DATA: {
static_print_debug("data flow download sends data");
if(g_data_flow.data != NULL){
uint16_t data_len = write_cb_para[1] << 8 | write_cb_para[2];
memset(g_data_flow.data, 0 , 512);
memcpy_s(g_data_flow.data, data_len - 7, &write_cb_para[6], data_len - 7);
g_data_flow.len += data_len - 7;
static_print_debug("g_data_flow.data : %s",g_data_flow.data);
if(g_lefun_ai_data_callback != NULL){
g_lefun_ai_data_callback(&g_data_flow);
}
uint8_t data[3] = {0};
data[0] = write_cb_para[4];
data[1] = write_cb_para[5];
data[2] = 0x01;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DATA_FLOW_DOWNLOAD_SENDS_DATA, server_id, conn_id);
}
break;
}
case DATA_FLOW_UPLOAD_STARTS: {
static_print_debug("data flow upload starts");
if(write_cb_para[6] == 0x10){
static_print_debug("data flow type is audio...");
if(write_cb_para[7] == 0x01){
static_print_debug("data flow is start...");
}else if(write_cb_para[7] == 0x00){
static_print_debug("data flow is failed...");
}
}
break;
}
case DATA_FLOW_UPLOAD_ENDS: {
static_print_debug("data flow upload ends");
// tjd_lefun_ai_request_exit_audio_transmit();
break;
}
case REQUEST_LUCKY_CLOVER_DATA: {
static_print_debug("request lucky clover data");
tjd_ble_rec_lucky_clover_data(server_id, conn_id, write_cb_para, len , REQUEST_LUCKY_CLOVER_DATA);
// uint8_t data[] = {0x01};
// tjd_ble_protocol_send_data(data, sizeof(data), REQUEST_LUCKY_CLOVER_DATA, server_id, conn_id);
break;
}
case REQUEST_GPS_INFORMATION: {
static_print_debug("request gps information");
uint8_t pgs_file_num = write_cb_para[5];
uint32_t gps_file_size = write_cb_para[6] << 24 | write_cb_para[7] << 16 | write_cb_para[8] << 8 | write_cb_para[9];
tjd_ble_protocol_dir_transfer_enter_handle(TYPE_GPS, pgs_file_num, gps_file_size);
static_print_debug("g_gps_file_all_num: %d, g_gps_file_all_size: %d", pgs_file_num, gps_file_size);
break;
}
case REQUEST_SYNCHRONOUS_DATA: {
static_print_debug("request synchronous data");
switch(write_cb_para[4]){
case 0x00:
static_print_debug("request synchronous data failed");
break;
case 0x01:
static_print_debug("request synchronous data success");
break;
default:
static_print_debug("request synchronous data unknown");
break;
}
}
case REPORTED_JS_APP_INSTALL_STATUS: {
static_print_debug("reported js app uninstall");
tjd_ble_uninstall_js_app(server_id, conn_id, write_cb_para, len , REPORTED_JS_APP_INSTALL_STATUS);
break;
}
case GET_JS_APP_LIST: {
static_print_debug("get js app list");
bool ret = TjdAppStorePkgUpdateList();
tjd_service_send_js_app_list();
break;
}
case GET_DEVICE_CRASH_LOG: {
static_print_debug("get device crash log");
tjd_service_send_crash_log();
break;
}
case GET_SLEEP_WEEK_DATA: {
static_print_debug("get sleep js list");
tjd_service_send_sleep_week_data();
}
case GET_OPENHARMONY_VERSION: {
static_print_debug("get openharmony version");
tjd_ble_protocol_get_openharmony_version(server_id, conn_id, write_cb_para, len, GET_OPENHARMONY_VERSION);
}
default:
static_print_debug("unknown control command");
break;
}
}
void upload_file_end(uint8_t server_id, uint8_t conn_id)
{
static_print_debug("upload file end");
uint8_t data[4] = {0};
data[0] = 0x5A;
data[1] = 0x04;
data[2] = 0xB6;
data[3] = do_crc(data, 3);
gatt_send_response(data, sizeof(data), server_id, conn_id);
}
void register_lefun_ai_data_callback(lefun_ai_data_callback_t callback) { g_lefun_ai_data_callback = callback; }
void unregister_lefun_ai_data_callback(void) { g_lefun_ai_data_callback = NULL; }
void register_lefun_ai_data_end_callback(lefun_ai_data_callback_t callback) { g_lefun_ai_data_end_callback = callback; }
void unregister_lefun_ai_data_end_callback(void) { g_lefun_ai_data_end_callback = NULL; }
void register_find_phone_end_callback(fine_phone_end_callback_t callback) { g_fine_phone_end_callback = callback; }
void unregister_find_phone_end_callback(void) { g_fine_phone_end_callback = NULL; }
play_dial_original_callback_t get_play_dial_original_callback(void) { return g_play_dial_original_callback; }
void register_play_dial_original_callback(play_dial_original_callback_t callback) { g_play_dial_original_callback = callback; }
void unregister_play_dial_original_callback(void) { g_play_dial_original_callback = NULL; }
void register_play_dial_preview_callback(play_dial_preview_callback_t callback) { g_play_dial_preview_callback = callback; }
void unregister_play_dial_preview_callback(void) { g_play_dial_preview_callback = NULL; }
void register_play_dial_request_generate_picture_callback(play_dial_request_generate_picture_callback_t callback)
{
g_play_dial_request_generate_picture_callback = callback;
}
void unregister_play_dial_request_generate_picture_callback(void)
{
g_play_dial_request_generate_picture_callback = NULL;
}
void tjd_msgame_send_gesensor_data(uint8_t *data, uint8_t len)
{
static_print_debug("send gesensor data");
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD;
tjd_ble_protocol_send_lefun_data(&pack_head, data, len, SEND_GSENSOR_DATA);
}
void tjd_msgame_into(void)
{
static_print_debug("into msgame");
uint8_t data = 0x01;
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD;
tjd_ble_protocol_send_lefun_data(&pack_head, &data,sizeof(uint8_t), MS_GAME_MODE);
}
void tjd_msgame_exit(void)
{
static_print_debug("exit msgame");
uint8_t data = 0x02;
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD;
tjd_ble_protocol_send_lefun_data(&pack_head, &data,sizeof(uint8_t), MS_GAME_MODE);
}
/*Lefun AI相关接口*/
void tjd_lefun_ai_request_into_lefun_ai(void)
{
static_print_debug("request into lefun ai");
uint8_t data[3] = {0x01,0xF1,0x01};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, &data,sizeof(data), AI_FUNCTION_REQUEST);
}
void tjd_lefun_ai_request_exit_lefun_ai(void)
{
static_print_debug("request into lefun ai");
uint8_t data[3] = {0x01,0xF1,0x02};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, &data,sizeof(data), AI_FUNCTION_REQUEST);
}
void tjd_lefun_ai_request_start_audio_transmit(void)
{
static_print_debug("into lefun ai audio transmit");
uint8_t data[2] = {g_tjd_ble_data_flow_id,0x10};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, data, sizeof(data), DATA_FLOW_UPLOAD_STARTS);
}
void tjd_lefun_ai_request_end_audio_transmit(void)
{
static_print_debug("end lefun ai audio transmit");
uint8_t data = g_tjd_ble_data_flow_id;
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, &data, sizeof(data), DATA_FLOW_UPLOAD_ENDS);
g_tjd_ble_data_flow_id++;
if(g_tjd_ble_data_flow_id == 0xff){
g_tjd_ble_data_flow_id = 0;
}
}
void tjd_lefun_ai_request_into_audio_transmit(void)
{
static_print_debug("into lefun ai audio transmit");
uint8_t data[2] = {0x01,0x01};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, data, sizeof(data), AI_AUDIO_TRANSMISSION_MANAGEMENT);
}
void tjd_lefun_ai_request_exit_audio_transmit(void)
{
static_print_debug("exit lefun ai audio transmit");
uint8_t data[2] = {0x01,0x00};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, data, sizeof(data), AI_AUDIO_TRANSMISSION_MANAGEMENT);
}
void tjd_lefun_request_weather_data(void)
{
static_print_debug("request weather data");
uint8_t data[2] = {0x10,0x01};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, data, sizeof(data), REQUEST_WEATHER_DATA);
}
void tjd_lefun_request_find_phone(void)
{
static_print_debug("request_find_phone");
// uint8_t data[2] = {0x10,0x01};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD;
tjd_ble_protocol_send_lefun_data(&pack_head, NULL, 0, FIND_MOBILE_PHONE);
}
void tjd_lefun_request_find_phone_cancel(void)
{
static_print_debug("request_find_phone_cancel");
// uint8_t data[2] = {0x10,0x01};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD;
tjd_ble_protocol_send_lefun_data(&pack_head, NULL, 0, STOP_FINE_PHONE);
}
bool tjd_ble_get_weather_today_synchronization(void)
{
return g_weather_today_synchronization_data_mask;
}
void tjd_ble_set_weather_today_synchronization(bool flag)
{
if(g_weather_today_synchronization_data_mask != flag){
g_weather_today_synchronization_data_mask = flag;
}
}
void tjd_ble_transmit_audio_data(uint8_t *data, uint16_t len)
{
uint16_t mtu_size = 167;
uint8_t all_package_num = len / (mtu_size - 7);
uint8_t cur_package_num = 0;
// uint8_t * send_buffer = malloc(mtu_size);
uint8_t send_buffer[167] = {0};
uint16_t send_buffer_len = mtu_size;
uint16_t cur_offset = 0;
// if(send_buffer == NULL){
// static_print_error("ble_transmit_audio_malloc_fail");
// return;
// }
while(cur_package_num < all_package_num){
// if(cur_package_num == all_package_num){//最后一包
// send_buffer_len = (len % (mtu_size - 6 - 1)) + 6 + 1;
// }
memset_s(send_buffer, mtu_size, 0, mtu_size);
int index = 0;
send_buffer[index++] = PROTOCOL_RES_FRAME_HEAD_2;
send_buffer[index++] = send_buffer_len >> 8 & 0xFF;
send_buffer[index++] = send_buffer_len & 0xFF;
send_buffer[index++] = DATA_FLOW_UPLOAD_SENDS_DATA;
send_buffer[index++] = g_tjd_ble_data_flow_id;
send_buffer[index++] = cur_package_num;
memcpy_s(send_buffer + 6, mtu_size - 7, data + cur_offset, send_buffer_len - 7);
index+= send_buffer_len - 7;
send_buffer[index] = do_crc(send_buffer, index);
cur_offset += send_buffer_len - 7;
cur_package_num++;
gatt_send_response(send_buffer, send_buffer_len,gatt_server_id,g_server_conn_id);
osDelay(20);
}
static_print_debug("send lefun ai audio data success!");
// uint8_t send_data = g_tjd_ble_data_flow_id;
// uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
// tjd_ble_protocol_send_lefun_data(&pack_head, &send_data, sizeof(uint8_t), DATA_FLOW_UPLOAD_ENDS);
// tjd_lefun_ai_request_end_audio_transmit();
}
bool tjd_ble_get_ai_audio_trans_flag(void)
{
return g_tjd_ble_ai_audio_trans_flag;
}
/*玩转表盘相关接口*/
void tjd_lefun_ai_request_into_play_dial(void)
{
static_print_debug("request into play dial");
uint8_t data[3] = {0x01,0xF2,0x01};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, &data,sizeof(data), AI_FUNCTION_REQUEST);
}
void tjd_lefun_ai_request_exit_play_dial(void)
{
static_print_debug("request exit play dial");
uint8_t data[3] = {0x01,0xF2,0x02};
uint8_t pack_head = PROTOCOL_RES_FRAME_HEAD_2;
tjd_ble_protocol_send_lefun_data(&pack_head, &data,sizeof(data), AI_FUNCTION_REQUEST);
}
void tjd_ble_upload_play_dial_func_attribute(ai_picture_style_t style_type, uint8_t language_to_translated, uint8_t translation_language)
{
uint8 send_data[32] = {0};
int index = 0;
send_data[index++] = 0x19;
send_data[index++] = 0x00;
//TYPE : 0x01 上报屏幕分辨率
send_data[index++] = 0x06;
send_data[index++] = 0x01;
// 设置屏幕分辨率 466 x 466
SET_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_WEIGHT);
SET_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_HEIGHT);
//TYPE : 0x02 上报固件支持背景模式 0x00:平台自定义bin格式 0x01:单图
send_data[index++] = 0x03;
send_data[index++] = 0x02;
send_data[index++] = 0x00;
//TYPE : 0x03 上报固件支持音源类型 0x01:APP录音源 0x02:BT音源 0x03:BLE音源
send_data[index++] = 0x03;
send_data[index++] = 0x03;
send_data[index++] = 0x03;
//TYPE : 0x04 上报固件所选AI图片风格
send_data[index++] = 0x03;
send_data[index++] = 0x04;
send_data[index++] = style_type;
//TYPE : 0x05 待翻译语言 翻译语言
send_data[index++] = 0x04;
send_data[index++] = 0x05;
send_data[index++] = language_to_translated;
send_data[index++] = translation_language;
//TYPE : 0x06 上报预览图分辨率
send_data[index++] = 0x06;
send_data[index++] = 0x06;
// 设置屏幕分辨率 233 x 233
SET_HALF_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_WEIGHT);
SET_HALF_RESOLUTION(send_data, index, TJD_SCREEN_RESOLUTION_HEIGHT);
uint8_t pack_head = 0x5B;
tjd_ble_protocol_send_lefun_data(&pack_head,&send_data,index,REPORT_AI_FUNCTION_ATTRIBUTES);
}
void tjd_play_dial_request_diagram_generation(uint8_t data_flow_id, uint8_t isFirstRequest)
{
uint8_t send_data[4] = {0};
uint8_t index = 0;
send_data[index++] = data_flow_id;
send_data[index++] = isFirstRequest;
uint8_t pack_head = 0x5B;
tjd_ble_protocol_send_lefun_data(&pack_head,send_data,index,REQUEST_DIAGRAM_GENERATION);
}
void tjd_play_dial_request_diagram_transmit(uint8_t background_type)
{
uint8_t send_data = background_type;
uint8_t pack_head = 0x5B;
tjd_ble_protocol_send_lefun_data(&pack_head,&send_data,sizeof(uint8_t),REPORT_DIAGRAM_TRANSMIT);
}
//JS应用相关接口 5B XXXX CB XXXX LTV030101 1202xxxxxxxxxxxxxxxxxxxx 0402xxxx 030401CRC
void tjd_js_install_status_request(const uint8_t resultCode, const void *resultMessage)
{
//参数不带bin后缀 包名:cn.weaher 名称:js天气
printf("request bundleName:%s, label:%s uninstall_by_protocol:%d\r\n", ((BundleInstallMsg *)resultMessage)->bundleName, ((BundleInstallMsg *)resultMessage)->label, uninstall_by_protocol);
BundleInstallMsg *installMsg = (BundleInstallMsg *)resultMessage;
uint8_t send_data[PROTOCOL_BUFFER_MAX_LEN] = {0};
int index = 0;
uint8_t status = installMsg->installState; //操作状态
bool send_opration_res = (status <= BUNDLE_INSTALL_FAIL)? true : (uninstall_by_protocol)? true : false;
static_print_debug("status:%d, send_opration_res:%d", status, send_opration_res);
uint8_t name_len = strlen(installMsg->bundleName);
uint8_t lable_len = strlen(installMsg->label);
uint16_t ltv_len = LTV_DEFAULT_LEN + name_len + lable_len + (send_opration_res? 0 : -3);
uint16_t package_len = PACKAGE_DEFAULT_LEN + ltv_len;
send_data[index++] = PROTOCOL_RES_FRAME_HEAD_2;
send_data[index++] = (package_len >> 8 ) & 0xFF;
send_data[index++] = package_len & 0xFF;
send_data[index++] = REPORTED_JS_APP_INSTALL_STATUS;
send_data[index++] = (ltv_len >> 8 ) & 0xFF;
send_data[index++] = ltv_len & 0xFF;
//LTV数据类型
send_data[index++] = 0x03;
send_data[index++] = 0x01;
send_data[index++] = (status <= BUNDLE_INSTALL_FAIL)? OPRATION_INSTALL : OPRATION_UNINSTALL;
//包名:
send_data[index++] = LTV_OFFSET_LEN + name_len;
send_data[index++] = 0x02;
memcpy_s(&send_data[index], name_len, installMsg->bundleName, name_len);
index += name_len;
//名称:
send_data[index++] = LTV_OFFSET_LEN + lable_len;
send_data[index++] = 0x03;
memcpy_s(&send_data[index], lable_len, installMsg->label, lable_len);
index += lable_len;
if(send_opration_res){
//状态:
send_data[index++] = 0x03;
send_data[index++] = 0x04;
send_data[index++] = status;
}
send_data[index] = do_crc(send_data, package_len - 1);
// uninstall_by_protocol = false;
gatt_send_response(&send_data, package_len,gatt_server_id,g_server_conn_id);
}
//通用文件下载回调处理
void file_download_callback_start_type_dial_original(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
}
void file_download_callback_end_type_dial_original(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
if(p_transfer->operation_file_size == p_description->file_size) {
if(get_play_dial_original_callback() != NULL){
get_play_dial_original_callback()((char *)p_description->file_name);
}
}else{
int ret = unlink((char *)p_description->file_name);
}
}
void file_download_callback_start_type_dial_doc(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
}
void file_download_callback_end_type_dial_doc(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
char * token = NULL;
char path_copy[64] = {0};
uint32_t dial_id = 0;
if(p_transfer->operation_file_size == p_description->file_size) {
strcpy(path_copy, (const char *)p_description->file_name);
token = strtok(path_copy, "/");
while(token != NULL){
if (strstr(token, "hi_") == token) {
// 提取数字部分
dial_id = atoi(token + 3); // 跳过 "hi_"
static_print_debug("Extracted ID: %d", dial_id);
}
token = strtok(NULL, "/");
}
if(token == NULL){
static_print_debug("Failed to extract ID");
}
if(dial_id) {
if(TjdUiWfIsLocalID(dial_id)){
char bakpath[64] = {0};
strcpy(bakpath, (const char *)p_description->file_name);
char *dot = strrchr(bakpath, '.');
if (dot != NULL) {
strcpy(dot, ".bak");
}
if(access((const char*)bakpath, F_OK) == 0){ //备份文件存在,则删除新下载的文件,使用备份文件
unlink((char *)p_description->file_name);
rename((const char *)bakpath, (const char *)p_description->file_name);
}
}
TjdUiWfInstallAfterNotify(dial_id);
}
}else{
int ret = unlink((char *)p_description->file_name);
}
}
void file_download_callback_end_type_dial_custom(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
if(p_transfer->operation_file_size == p_description->file_size) {
tjd_service_save_dial_parameter(&dial_param);
if(TjdUiWfInstallAfterNotify(0)){
static_print_debug("install after notify success");
}else{
static_print_debug("install after notify failed");
}
}else{
int ret = unlink((char *)p_description->file_name);
}
}
void file_download_callback_end_type_gps(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
static_print_debug("total file size is %d-%d,file number:%d-%d", tjd_ble_get_transfer_info()->operation_total_size, tjd_ble_get_dir_description()->file_total_size, tjd_ble_get_transfer_info()->operation_total_number, tjd_ble_get_dir_description()->file_total_number);
if(p_transfer->operation_total_number == tjd_ble_get_dir_description()->file_total_number && p_transfer->operation_total_size >= tjd_ble_get_dir_description()->file_total_size){
if(access(TJD_FS_DIR_GPS,0) == 0){
delete_directory(TJD_FS_DIR_GPS);
}
if(access(TJD_FS_DIR_GPS_BAT,0) == 0){
//重命名 TJD_FS_DIR_GPS_BAT to TJD_FS_DIR_GPS
if(rename(TJD_FS_DIR_GPS_BAT,TJD_FS_DIR_GPS) != 0){
static_print_error("rename gps dir fail");
}else{
static_print_debug("rename gps dir success");
}
}
p_transfer->file_status = FileTransfer_NULL;
p_description->file_type = FileType_MAX;
tjd_ble_protocol_dir_transfer_exit_handle();
}
}
void file_download_callback_end_type_js(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
if(p_transfer->file_status == FileTransfer_Timeout){ //目前这种状态控制逻辑不明确,暂定
return;
}
// /user/tjd_js/xxx.bin
char pkg_name[50] = {0};
char *file_name = strrchr((const char *)(p_description->file_name), '/') + 1;
char *temp_point = strrchr((const char *)(file_name), '.');
int len = temp_point - file_name;
strncpy(pkg_name,file_name,len);
pkg_name[len] = '\0';
static_print_debug("file_name:%s",p_description->file_name);
static_print_debug("pkg_name:%s",pkg_name);
TjdAppStorePkgOperation(PKG_OPERATION_TYPE_INSTALL,(const char *)pkg_name,false);
}
//通用文件上传回调处理
static upload_file_end_callback_t g_upload_file_recode_end_callback = NULL;
upload_file_end_callback_t get_upload_file_recode_end_callback(void) { return g_upload_file_recode_end_callback; }
void register_upload_file_recode_end_callback(upload_file_end_callback_t callback) { g_upload_file_recode_end_callback = callback; }
void file_upload_callback_start_type_recode(uint8_t cmd_ret)
{
static_print_debug("file_upload_callback_start_type_recode(cmd_ret=%d):", cmd_ret);
if (cmd_ret == 0x02) //文件存在结束
{
if(get_upload_file_recode_end_callback() != NULL){
get_upload_file_recode_end_callback()(UPLOAD_END_EXIST);
}
}
}
void file_upload_callback_end_type_recode(FileUploadEndEnum value)
{
static_print_debug("file_upload_callback_end_type_recode(value=%d):", value);
if(get_upload_file_recode_end_callback() != NULL){
get_upload_file_recode_end_callback()(value);
}
}
extern osal_event g_sport_record_event;
void file_upload_callback_start_type_sport_record(uint8_t cmd_ret)
{
if (cmd_ret == 0x02) {
static_print_debug("upload file start faile! app has exisit file!");
int ret = osal_event_write(&g_sport_record_event, FILE_SEND_SKIP);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_SKIP failed!");
}
} else if (cmd_ret == 0x03){
static_print_debug("upload file start faile! app has no enough space!");
int ret = osal_event_write(&g_sport_record_event, FILE_SEND_NOSPACE);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_NOSPACE failed!");
}
} else if (cmd_ret == 0x04){
static_print_debug("upload file start faile! app has no support file type!");
int ret = osal_event_write(&g_sport_record_event, FILE_SEND_NOSUPPORT);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_NOSUPPORT failed!");
}
} else if(cmd_ret == 0x00){
static_print_debug("upload file start faile!");
int ret = osal_event_write(&g_sport_record_event, FILE_SEND_FAILE);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_NOSUPPORT failed!");
}
}
}
void file_upload_callback_end_type_sport_record(FileUploadEndEnum value)
{
if(value == UPLOAD_END_SUCCEED) {
int ret = osal_event_write(&g_sport_record_event, FILE_SEND_SUCCESS);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_SUCCESS failed!");
}
} else{
int ret = osal_event_write(&g_sport_record_event, FILE_SEND_FAILE);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_FAILE failed!");
}
}
}
extern osal_event g_js_app_list_event;
void file_upload_callback_start_type_js_app_list(uint8_t cmd_ret)
{
if (cmd_ret == 0x02) {
static_print_debug("upload file start faile! app has exisit file!");
int ret = osal_event_write(&g_js_app_list_event, FILE_SEND_SKIP);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_SKIP failed!");
}
} else if (cmd_ret == 0x03){
static_print_debug("upload file start faile! app has no enough space!");
int ret = osal_event_write(&g_js_app_list_event, FILE_SEND_NOSPACE);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_NOSPACE failed!");
}
} else if (cmd_ret == 0x04){
static_print_debug("upload file start faile! app has no support file type!");
int ret = osal_event_write(&g_js_app_list_event, FILE_SEND_NOSUPPORT);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_NOSUPPORT failed!");
}
} else if(cmd_ret == 0x00){
static_print_debug("upload file start faile!");
int ret = osal_event_write(&g_js_app_list_event, FILE_SEND_FAILE);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_NOSUPPORT failed!");
}
}
}
void file_upload_callback_end_type_js_app_list(FileUploadEndEnum value)
{
if(value == UPLOAD_END_SUCCEED) {
int ret = osal_event_write(&g_js_app_list_event, FILE_SEND_SUCCESS);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_SUCCESS failed!");
}
} else{
int ret = osal_event_write(&g_js_app_list_event, FILE_SEND_FAILE);
if(ret != OSAL_SUCCESS){
static_print_error("write event FILE_SEND_FAILE failed!");
}
}
}