/*---------------------------------------------------------------------------- * Copyright (c) TJD Technologies Co., Ltd. 2020. All rights reserved. * * Description: service_bt.c * * Author: linzhaocheng * * Create: 2024-7-24 *--------------------------------------------------------------------------*/ #include #include #include #include "service_bt.h" #include "securec.h" #include "common_def.h" #include "debug_print.h" #include "soc_osal.h" #include "cmsis_os2.h" #include "sys_typedef.h" #include "task_service_timer.h" #include "sys_config.h" #include "sql_bt.h" #include "a2dp_service.h" #include "bts_a2dp_sink.h" #include "ble_api.h" #include "fs_api_ext.h" #include #include #include "sql_fit.h" #include "rtc_api.h" #include "ble_port_protocol.h" #include "cJSON.h" #include "dirent.h" #define ENABLE_PRINT_INFO 1 #if ENABLE_PRINT_INFO #define static_print_debug(...) sys_bt_log_d(__VA_ARGS__) // 一般信息打印宏控制 #define static_print_warn(...) sys_bt_log_w(__VA_ARGS__) // 警告信息打印一般常开 #define static_print_error(...) sys_bt_log_e(__VA_ARGS__) // 错误信息打印一般常开 #else #define static_print_debug(...) #define static_print_warn(...) #define static_print_error(...) #endif #define TJD_ADDRESS_BOOK_PATH "/user/tjd_phone/addressbook.bin" #define TJD_CUSTOM_DIAL_PREVIEW_PATH "/user/tjd_wfc/wfc_preview.hbm" #define TJD_CUSTOM_DIAL_BG_RES_PATH "/user/tjd_wfc/wfc_bg.bin" #define TJD_CUSTOM_DIAL_VIDEO_PREVIEW_PATH "/user/tjd_wfc/wfc_preview_frame.hbm" #define TJD_CUSTOM_DIAL_WF_CONFIG_PATH "/user/tjd_wf/wf_config_0.json" #define PV_LRC_LEN 128 #define LOOP_INTERVAL_TIME 1000*60*5 #define LOOP_PERIOD_TIME 1000*30 #define LOOP_SMALL_TIME 1000 // #define HEADSET_COD 0x240418 #define TJD_FS_DIR_SPORT "/system/tjd_sport" osal_event g_sport_record_event; osal_event g_js_app_list_event; osal_event g_crash_log_event; uint8_t * g_pv_lrc = NULL; pthread_mutex_t g_music_mutex; pthread_mutex_t g_ble_mutex; #define is_limied_discoverable_mode(cod) (((cod) & 0x2000) != 0) bool g_tjd_found_list_init = false; struct osal_list_head g_tjd_found_dev_list_head; static bd_addr_t g_tjd_headset_lastconned_addr = {0}; // extern bool g_tjd_bt_is_connected; // extern bool g_tjd_ble_is_connected; static bool g_a2dp_src_is_connected = false; static bool g_a2dp_snk_is_connected = false; static contacts_sync_callback_t g_contacts_sync_callback = NULL; typedef struct { unsigned char deviceName[BD_NAME_LEN]; /* Name of the device record, must be in UTF-8 */ unsigned char addr[BD_ADDR_LEN]; int16_t index; int16_t connIndex; int16_t temp; } BluetoothCaseInfo; typedef struct { struct osal_list_head node; BluetoothCaseInfo info; } bt_pair_dev_list_node; bool g_tjd_pair_list_init = false; struct osal_list_head g_tjd_pair_dev_list_head; // bd_addr_t g_tjd_lastconned_addr = {0}; void tjd_service_bt_register_contacts_event(contacts_sync_callback_t callback) { g_contacts_sync_callback = callback; } void tjd_service_bt_unregister_contacts_event(void) { g_contacts_sync_callback = NULL; } static void contacts_sync_event(void) { if (g_contacts_sync_callback != NULL) { g_contacts_sync_callback(); } } void tjd_music_mutex_init(void) { // pthread_mutex_t *mutexId = (pthread_mutex_t *)osal_kmalloc(sizeof(pthread_mutex_t),OSAL_GFP_KERNEL); // if (mutexId == NULL) { // return NULL; // } pthread_mutexattr_t mutexAttr = {0}; pthread_mutexattr_t *pAttr = NULL; (void)pthread_mutex_init(&g_music_mutex, pAttr); } void tjd_music_mutex_lock(pthread_mutex_t *mutex) { if (mutex == NULL) { return; } (void)pthread_mutex_lock((pthread_mutex_t *)mutex); } void tjd_music_mutex_unlock(pthread_mutex_t *mutex) { if (mutex == NULL) { return; } (void)pthread_mutex_unlock((pthread_mutex_t *)mutex); } void tjd_ble_mutex_init(void) { // pthread_mutex_t *mutexId = (pthread_mutex_t *)osal_kmalloc(sizeof(pthread_mutex_t),OSAL_GFP_KERNEL); // if (mutexId == NULL) { // return NULL; // } pthread_mutexattr_t mutexAttr = {0}; pthread_mutexattr_t *pAttr = NULL; (void)pthread_mutex_init(&g_ble_mutex, pAttr); } void tjd_ble_mutex_lock(void) { (void)pthread_mutex_lock(&g_ble_mutex); } void tjd_ble_mutex_unlock(void) { (void)pthread_mutex_unlock(&g_ble_mutex); } void tjd_music_mutex_deinit(void) { (void)pthread_mutex_destroy(&g_music_mutex); } void tjd_ble_mutex_deinit(void) { (void)pthread_mutex_destroy(&g_ble_mutex); } void tjd_malloc_lrc_buffer(void) { g_pv_lrc = (uint8_t *)(void *)malloc(PV_LRC_LEN); if(g_pv_lrc == NULL) { static_print_debug("malloc_lrc_buffer fail."); return; } } void tjd_free_lrc_buffer(void) { free(g_pv_lrc); g_pv_lrc = NULL; } void tjd_get_lrc_buffer(uint8_t * g_pv_lrc_) { g_pv_lrc_ = g_pv_lrc; } void tjd_set_lrc_buffer_data(uint8_t * value, size_t len) { if(len > PV_LRC_LEN) { static_print_debug("set_lrc_buffer_data len:%u > PV_LRC_LEN:%u",len,PV_LRC_LEN); return; } if (g_pv_lrc != NULL) { tjd_music_mutex_lock(&g_music_mutex); memcpy_s(g_pv_lrc,PV_LRC_LEN,value,len); tjd_music_mutex_unlock(&g_music_mutex); } } void tjd_get_music_mutex(pthread_mutex_t *mutex) { mutex = &g_music_mutex; } void tjd_get_ble_mutex(pthread_mutex_t *mutex) { mutex = &g_ble_mutex; } /************************************************ * GAP SERVICE */ /* 重置配对设备链表 */ void tjd_reset_pair_dev_list(void) { if (!g_tjd_pair_list_init) { g_tjd_pair_list_init = true; OSAL_INIT_LIST_HEAD(&g_tjd_pair_dev_list_head); return; } while (osal_list_empty(&g_tjd_pair_dev_list_head) == false) { struct osal_list_head *node = g_tjd_pair_dev_list_head.next; osal_list_del(node); free(node); node = NULL; } } bool tjd_is_pair_dev_exist(BluetoothCaseInfo caseinfo) { bt_pair_dev_list_node *tmp = NULL; struct osal_list_head *pos = NULL; struct osal_list_head *n = NULL; if (osal_list_empty(&g_tjd_pair_dev_list_head) == true) { return false; } osal_list_for_each_safe(pos, n, &g_tjd_pair_dev_list_head) { tmp = osal_list_entry(pos, bt_pair_dev_list_node, node); if ((caseinfo.addr[0] == tmp->info.addr[0]) && (caseinfo.addr[1] == tmp->info.addr[1]) && (caseinfo.addr[2] == tmp->info.addr[2]) && (caseinfo.addr[3] == tmp->info.addr[3]) && (caseinfo.addr[4] == tmp->info.addr[4]) && (caseinfo.addr[5] == tmp->info.addr[5])) { static_print_debug("pair dev exist"); return true; } // if(&(tmp->node) != &g_tjd_pair_dev_list_head) // { // if (memcmp(tmp->info.addr, caseinfo->addr, BD_ADDR_LEN) == 0) { // return true; // } // } } return false; } /* 新增节点 */ void add_node_to_pair_dev_list(BluetoothCaseInfo caseinfo) { // 如果链表节点数量大于20,则返回 struct osal_list_head *pos = NULL; uint8_t list_len = 0; osal_list_for_each(pos, &g_tjd_pair_dev_list_head) { list_len++; if (list_len > 20) { return; } } bt_pair_dev_list_node *node = (bt_pair_dev_list_node *)(void *)malloc(sizeof(bt_pair_dev_list_node)); if (node == NULL) { return; } (void)memset_s(node, sizeof(bt_pair_dev_list_node), 0, sizeof(bt_pair_dev_list_node)); if (memcpy_s(node->info.addr, BD_ADDR_LEN, caseinfo.addr, BD_ADDR_LEN) != EOK) { free(node); return; } if (memcpy_s(node->info.deviceName, BD_NAME_LEN, caseinfo.deviceName, BD_NAME_LEN) != EOK) { free(node); return; } node->info.index = caseinfo.index; node->info.connIndex = caseinfo.connIndex; node->info.temp = caseinfo.temp; osal_list_add_tail((struct osal_list_head *)node, &g_tjd_pair_dev_list_head); static_print_debug("add node name:%s, rssi:%d , success", node->info.deviceName, node->info.temp); return; } /* 删除节点 */ static void del_node_from_pair_dev_list(BluetoothCaseInfo caseinfo) { bt_pair_dev_list_node *node = NULL; struct osal_list_head *pos = NULL; struct osal_list_head *n = NULL; if (osal_list_empty(&g_tjd_pair_dev_list_head) == true) { return; } osal_list_for_each_safe(pos, n, &g_tjd_pair_dev_list_head) { node = (bt_pair_dev_list_node *)pos; if (memcmp_s(node->info.addr, BD_ADDR_LEN, caseinfo.addr, BD_ADDR_LEN) == EOK) { osal_list_del(pos); free(node); node = NULL; return; } } return; } // 获取已配对设备链表 struct osal_list_head tjd_get_pair_dev_list(void) { return g_tjd_pair_dev_list_head; } // 对配对设备链表排序 void tjd_sort_pair_dev_list(void) { if (osal_list_empty(&g_tjd_pair_dev_list_head) == true) { return; } struct osal_list_head *list_head = &g_tjd_pair_dev_list_head; for (struct osal_list_head *node1 = list_head->next; node1 != NULL && node1 != list_head; node1 = node1->next) { bt_pair_dev_list_node *dev_info1 = (bt_pair_dev_list_node *)node1; for (struct osal_list_head *node2 = node1->next; node2 != NULL && node2 != list_head; node2 = node2->next) { bt_pair_dev_list_node *dev_info2 = (bt_pair_dev_list_node *)node2; /* 同为limited或非limited模式时,node1的rssi比node2小,rssi小的在前,无需交换位置 */ if (dev_info1->info.temp <= dev_info2->info.temp) { continue; } /* 交换两个节点的信息 */ bt_pair_dev_list_node tmp_node; uint32_t ret = (uint32_t)memcpy_s(&tmp_node, sizeof(tmp_node), dev_info1, sizeof(found_dev_list_node)); ret |= (uint32_t)memcpy_s(&dev_info1->info, sizeof(bt_pair_dev_list_node) - sizeof(struct osal_list_head), &dev_info2->info, sizeof(bt_pair_dev_list_node) - sizeof(struct osal_list_head)); ret |= (uint32_t)memcpy_s(&dev_info2->info, sizeof(bt_pair_dev_list_node) - sizeof(struct osal_list_head), &tmp_node.info, sizeof(bt_pair_dev_list_node) - sizeof(struct osal_list_head)); if (ret != EOK) { static_print_debug("swap fail %x", ret); } } } } // 初始化已配对设备链表 void tjd_pair_dev_list_init(void) { tjd_reset_pair_dev_list(); uint8_t pair_num = 0; bool ret = gap_get_paired_devices_num(&pair_num); static_print_debug("gap_get_paired_devices_num ret:%d, num: %d", ret, pair_num); if (ret == false || pair_num == 0) { gap_paired_device_info_t *devInfo = (gap_paired_device_info_t *)malloc(sizeof(gap_paired_device_info_t) * pair_num); if (devInfo == NULL) { static_print_debug("DevInfo malloc failed %u", sizeof(gap_paired_device_info_t) * pair_num); return; } ret = gap_get_paired_devices_list(devInfo, (int *)&pair_num); static_print_debug("SetUpConnedDevicesList gap_get_paired_devices_list ret = %d", ret); for (int i = 0; i < pair_num; ++i) { if ((gap_get_device_class((const bd_addr_t *)devInfo[i].addr.addr) & 0x200) != 0) { continue; } BluetoothCaseInfo caseInfo; memset_s(&caseInfo, sizeof(BluetoothCaseInfo), 0, sizeof(BluetoothCaseInfo)); (void)memcpy_s(caseInfo.addr, BD_ADDR_LEN, devInfo[i].addr.addr, BD_ADDR_LEN); (void)memcpy_s(caseInfo.deviceName, BD_NAME_LEN, devInfo[i].device_name, BD_NAME_LEN); AddConnedDevicesCase(caseInfo); } free(devInfo); } } /* 重置发现设备链表 */ void tjd_reset_found_dev_list(void) { if (!g_tjd_found_list_init) { g_tjd_found_list_init = true; OSAL_INIT_LIST_HEAD(&g_tjd_found_dev_list_head); } // tjd_music_mutex_lock(&g_music_mutex); while (osal_list_empty(&g_tjd_found_dev_list_head) == false) { struct osal_list_head *node = g_tjd_found_dev_list_head.next; osal_list_del(node); free(node); node = NULL; } // uint8_t g_tjd_headset_lastconned_addr[BD_ADDR_LEN] = {0}; // bd_addr_t addr = {0}; // if(sql_bt_get_headset_lastconnect_addr(addr.addr)){ // uint8_t name[BD_NAME_LEN] = {0}; // gap_get_device_name(&addr, name, NULL); // int cod = gap_get_device_class(&addr); // tjd_add_node_to_found_dev_list(&addr, name, true, true, cod, 0); // } unsigned int number = 0; bool ret = gap_get_paired_devices_num(&number); static_print_debug("get_paired_devices_num ret(bool): %d, num of paired devices:%u", ret, number); gap_paired_device_info_t *paired_list = NULL; if(number > 0) { paired_list = (gap_paired_device_info_t *)(void *)malloc((uint32_t)number * sizeof(gap_paired_device_info_t)); if (paired_list == NULL) { static_print_error("get_paired_devices_list malloc error!"); return; } (void)memset_s(paired_list,(size_t)number * sizeof(gap_paired_device_info_t),0,(size_t)number * sizeof(gap_paired_device_info_t)); ret = gap_get_paired_devices_list(paired_list, (int *)&number); static_print_debug("gap_get_paired_devices_list ret(bool): %d", ret); if (ret && paired_list) { static_print_debug("number: %d paired_list:", number); for (int i = 0; i < number; i++) { static_print_debug("\t%d name: \"%s\" addr: ****%02x%02x%02x%02x", i, paired_list[i].device_name, paired_list[i].addr.addr[3], paired_list[i].addr.addr[2], paired_list[i].addr.addr[1], paired_list[i].addr.addr[0]); int cod = gap_get_device_class((const bd_addr_t *)paired_list[i].addr.addr); if(cod == HEADSET_COD_1 || cod == HEADSET_COD_2 || cod == HEADSET_COD_3){ bool isConnected = bt_is_acl_connected((const bd_addr_t *)paired_list[i].addr.addr); tjd_add_node_to_found_dev_list((const bd_addr_t *)paired_list[i].addr.addr, paired_list[i].device_name, true, isConnected, cod, 0); } } } if (paired_list) { free(paired_list); } paired_list = NULL; } // tjd_music_mutex_unlock(&g_music_mutex); } /* 新增节点 */ void tjd_add_node_to_found_dev_list(const bd_addr_t *bd_addr, const uint8_t *name, bool isPaired ,bool isConnected, int32_t cod, int32_t rssi) { //根据cod判断是否是headset if(cod != HEADSET_COD_1 && cod != HEADSET_COD_2 && cod != HEADSET_COD_3){ return; } found_dev_list_node *node = (found_dev_list_node *)(void *)malloc(sizeof(found_dev_list_node)); if (node == NULL) { return; } (void)memset_s(node, sizeof(found_dev_list_node), 0, sizeof(found_dev_list_node)); if (memcpy_s(&node->bd_addr, sizeof(node->bd_addr), bd_addr, sizeof(bd_addr_t)) != EOK) { free(node); node = NULL; return; } if (memcpy_s(node->name, sizeof(node->name), name, BD_NAME_LEN) != EOK) { free(node); node = NULL; return; } node->isPaired = isPaired; node->isConnected = isConnected; node->cod = cod; node->rssi = rssi; tjd_music_mutex_lock(&g_music_mutex); osal_list_add_tail((struct osal_list_head *)node, &g_tjd_found_dev_list_head); tjd_music_mutex_unlock(&g_music_mutex); static_print_debug("add node name:%s, rssi:%d , success", node->name, node->rssi); } /* 更新RSSI */ void tjd_update_found_dev_node_rssi(const bd_addr_t *bd_addr, int32_t rssi) { struct osal_list_head *list_head = &g_tjd_found_dev_list_head; struct osal_list_head *node = list_head->next; tjd_music_mutex_lock(&g_music_mutex); while (node != NULL && node != list_head) { found_dev_list_node *dev_info = (found_dev_list_node *)node; if (memcmp(dev_info->bd_addr.addr, bd_addr->addr, BD_ADDR_LEN) == 0) { dev_info->rssi = rssi; break; } node = node->next; } tjd_music_mutex_unlock(&g_music_mutex); static_print_debug("dev not found addr: ****%02x%02x%02x%02x\n", bd_addr->addr[3], bd_addr->addr[2], bd_addr->addr[1], bd_addr->addr[0]); /* addr下标 0 1 2 3 */ } /* 刷新发现设备列表 */ void tjd_update_found_dev_list(void) { static_print_debug("update found dev list"); struct osal_list_head *list_head = &g_tjd_found_dev_list_head; struct osal_list_head *node = list_head->next; tjd_music_mutex_lock(&g_music_mutex); while (node != NULL && node != list_head) { found_dev_list_node *dev_info = (found_dev_list_node *)node; size_t len = sizeof(dev_info->name); if (!gap_get_device_name(&dev_info->bd_addr, dev_info->name, &len)) { static_print_debug("get name fail"); } dev_info->cod = gap_get_device_class(&dev_info->bd_addr); if (dev_info->cod == 0) { static_print_debug("get cod fail"); } if (!gap_read_remote_rssi_value(&dev_info->bd_addr)) { static_print_debug("get rssi fail"); } node = node->next; } tjd_music_mutex_unlock(&g_music_mutex); } /* 对发现设备列表排序 */ static void sort_found_dev_list(void) { static_print_debug("sort found dev list"); struct osal_list_head *list_head = &g_tjd_found_dev_list_head; tjd_music_mutex_lock(&g_music_mutex); for (struct osal_list_head *node1 = list_head->next; node1 != NULL && node1 != list_head; node1 = node1->next) { found_dev_list_node *dev_info1 = (found_dev_list_node *)node1; for (struct osal_list_head *node2 = node1->next; node2 != NULL && node2 != list_head; node2 = node2->next) { found_dev_list_node *dev_info2 = (found_dev_list_node *)node2; /* node1是limited模式,node2不是,node1在前,无需交换位置 */ if (is_limied_discoverable_mode((uint32_t)dev_info1->cod) && !is_limied_discoverable_mode((uint32_t)dev_info2->cod)) { continue; } /* 同为limited或非limited模式时,node1的rssi比node2大,rssi大的在前,无需交换位置 */ if (((is_limied_discoverable_mode((uint32_t)dev_info1->cod) && is_limied_discoverable_mode((uint32_t)dev_info2->cod)) || (!is_limied_discoverable_mode((uint32_t)dev_info1->cod) && !is_limied_discoverable_mode((uint32_t)dev_info2->cod))) && dev_info1->rssi >= dev_info2->rssi) { continue; } /* 交换两个节点的信息 */ found_dev_list_node tmp_node; uint32_t ret = (uint32_t)memcpy_s(&tmp_node, sizeof(tmp_node), dev_info1, sizeof(found_dev_list_node)); ret |= (uint32_t)memcpy_s( &dev_info1->bd_addr, sizeof(found_dev_list_node) - sizeof(struct osal_list_head), &dev_info2->bd_addr, sizeof(found_dev_list_node) - sizeof(struct osal_list_head)); ret |= (uint32_t)memcpy_s( &dev_info2->bd_addr, sizeof(found_dev_list_node) - sizeof(struct osal_list_head), &tmp_node.bd_addr, sizeof(found_dev_list_node) - sizeof(struct osal_list_head)); if (ret != EOK) { static_print_debug("swap fail %x\n", ret); } } } tjd_music_mutex_unlock(&g_music_mutex); } /* 展示发现设备列表 */ void tjd_show_found_dev_list(void) { /* 对发现设备列表排序 */ sort_found_dev_list(); struct osal_list_head *list_head = &g_tjd_found_dev_list_head; /* 展示发现设备列表 */ int32_t i = 0; static_print_debug("found_device_list:"); tjd_music_mutex_lock(&g_music_mutex); for (struct osal_list_head *node = list_head->next; node != NULL && node != list_head; node = node->next) { found_dev_list_node *dev_info = (found_dev_list_node *)node; static_print_debug( "found_device[%d]: addr: ****%02x%02x%02x%02x name: \"%s\" cod: %x rssi: %d limited_mdoe: %d", i, dev_info->bd_addr.addr[3], dev_info->bd_addr.addr[2], /* addr下标 3 2 */ dev_info->bd_addr.addr[1], dev_info->bd_addr.addr[0], /* addr下标 1 0 */ dev_info->name, dev_info->cod, dev_info->rssi, (is_limied_discoverable_mode((uint32_t)dev_info->cod) ? 1 : 0)); i++; if (dev_info->cod == HEADSET_COD_1 || dev_info->cod == HEADSET_COD_2 || dev_info->cod == HEADSET_COD_3) { errcode_t ret = gap_connect_remote_device(&dev_info->bd_addr); if (ret != ERRCODE_SUCC) { static_print_debug("gap_connect_remote_device fail, ret:%x.", ret); } int rets = a2dp_src_connect(&dev_info->bd_addr); if (rets != ERRCODE_SUCC) { static_print_debug("a2dp_src_connect fail, ret:%x.", rets); } static_print_debug("gap_connect_remote_device and a2dp_src_connect success."); } } tjd_music_mutex_unlock(&g_music_mutex); } // 获取已发现设备链表 struct osal_list_head * tjd_get_found_dev_list(void) { return &g_tjd_found_dev_list_head; } //删除配对 bool tjd_remove_paired_device(const bd_addr_t *bd_addr) { return gap_remove_pair(bd_addr); } void tjd_set_headset_last_connected_addr(bd_addr_t *bd_addr) { (void)memcpy_s(&g_tjd_headset_lastconned_addr, sizeof(bd_addr_t), bd_addr, sizeof(bd_addr_t)); } bool tjd_get_headset_last_connected_addr(bd_addr_t *bd_addr) { for(int i = 0; i < MAC_ADDR_LEN; i++) { if(g_tjd_headset_lastconned_addr.addr[i] != 0){ memcpy(bd_addr, &g_tjd_headset_lastconned_addr, sizeof(bd_addr_t)); return true; } } return false; } bool tjd_check_bt_is_acl_connected() { return g_a2dp_src_is_connected; } void tjd_a2dp_src_get_active_device(bd_addr_t * addr_) { bd_addr_t addr = a2dp_src_get_active_device(); memcpy_s(addr_, sizeof(bd_addr_t), &addr, sizeof(bd_addr_t)); } /*****运动数据相关接口*****/ // 定义路径 #define TJD_FS_DIR_SPORT "/system/tjd_sport" // 动态数组结构体 typedef struct { char **data; size_t capacity; size_t size; } StringArray; // 初始化动态数组 void init_string_array(StringArray *array) { array->data = NULL; array->capacity = 0; array->size = 0; } // 释放动态数组 void free_string_array(StringArray *array) { for (size_t i = 0; i < array->size; ++i) { free(array->data[i]); } free(array->data); } // 向动态数组中添加元素 bool add_to_string_array(StringArray *array, const char *str) { if (array->size >= array->capacity) { size_t new_capacity = array->capacity == 0 ? 1 : array->capacity * 2; char **new_data = realloc(array->data, new_capacity * sizeof(char *)); if (new_data == NULL) { return false; } array->data = new_data; array->capacity = new_capacity; } array->data[array->size] = strdup(str); if (array->data[array->size] == NULL) { return false; } array->size++; return true; } // 检查文件名是否以 "sport_record_" 开头且以 ".json" 结尾 bool is_sport_record_file(const char *filename) { size_t len = strlen(filename); if (len < 5 || strncmp(filename, "sport_record_", 13) != 0) { return false; } return strcmp(filename + len - 5, ".json") == 0; } // 搜索并记录文件路径 StringArray search_and_record_filepath(void) { StringArray fileList; init_string_array(&fileList); DIR *dp = opendir(TJD_FS_DIR_SPORT); if (dp == NULL) { fprintf(stderr, "SearchAndRecordFilepath 无法打开目录\n"); return fileList; } struct dirent *entry; while ((entry = readdir(dp)) != NULL) { const char *filename = entry->d_name; if (is_sport_record_file(filename)) { char *full_path = malloc(strlen(TJD_FS_DIR_SPORT) + strlen(filename) + 2); if (full_path == NULL) { closedir(dp); free_string_array(&fileList); return fileList; } sprintf(full_path, "%s/%s", TJD_FS_DIR_SPORT, filename); if (!add_to_string_array(&fileList, full_path)) { free(full_path); closedir(dp); free_string_array(&fileList); return fileList; } free(full_path); } } closedir(dp); return fileList; } /*****运动数据相关接口*****/ static signed int tjd_task_service_timer_scan_start(void *param) { ble_api_cmd_start_discovery(); return 0; } static signed int tjd_task_service_timer_scan_stop(void *param) { ble_api_cmd_stop_discovery(); return 0; } static signed int tjd_task_service_timer_connect(void *param) { static_print_debug("tjd_task_service_timer_connect %p", (const bd_addr_t *)param); gap_connect_remote_device((const bd_addr_t *)param); return 0; } static signed int tjd_task_service_timer_is_connect(void *param) { g_a2dp_src_is_connected = false; g_a2dp_src_is_connected = bt_is_acl_connected((const bd_addr_t *)param); return 0; } static signed int tjd_task_service_timer_snk_connect(void *param) { bd_addr_t * addr = tjd_get_lastconned_addr(); for (size_t i = 0; i < 6; i++) { static_print_debug("addr[%d]:%x", i, addr->addr[i]); } int ret = a2dp_snk_connect(addr); if (ret != ERRCODE_SUCC){ printf("a2dp_snk_connect fail, ret:%x.", ret); } return 0; } static signed int tjd_task_service_timer_snk_disconnect(void *param) { bd_addr_t *addr = tjd_get_lastconned_addr(); for (size_t i = 0; i < 6; i++) { static_print_debug("addr[%d]:%x", i, addr->addr[i]); } int ret = a2dp_snk_disconnect(addr); if (ret != ERRCODE_SUCC){ printf("a2dp_snk_disconnect fail, ret:%x.", ret); } return 0; } static signed int tjd_task_service_timer_file_append(void *param) { file_append_data_t *filedata = (file_append_data_t *)param; int ret = tjd_fs_api_file_append(filedata->path, filedata->buffer, filedata->size); if(ret != ERRCODE_SUCC){ printf("file append ret:%x.", ret); } return 0; } static signed int tjd_task_service_timer_contacts_data_append(void *param) { file_append_data_t *filedata = (file_append_data_t *)param; //读取通讯录文件数据,与要写入的数据作比较,如果数据已存在,则不写入,否则用追加方式写入 //判断通讯录文件是否存在 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); Contact * contact_data_buffer = (Contact *)malloc(sizeof(Contact) * contact_num); memset(contact_data_buffer, 0, sizeof(Contact) * contact_num); //读取通讯录全部数据 if(fseek(fp, 0, SEEK_SET) != 0){ static_print_error("fseek file head failed!"); fclose(fp); free(contact_data_buffer); contact_data_buffer = NULL; return -1; } ret = fread(contact_data_buffer, sizeof(Contact),contact_num,fp); if(ret != contact_num){ static_print_error("fread all block contact data failed! ret : %d" , ret); fclose(fp); free(contact_data_buffer); contact_data_buffer = NULL; return -1; } uint8_t rel_contact_num = contact_num; for(int i = 0; i < filedata->size; i++){ bool is_exist = false; const char *phone_ptr = NULL; if(rel_contact_num >= 100){ static_print_error("contact num is too big! contact_num : %d", rel_contact_num); break; } for(int j = 0; j < contact_num; j++){ // 将 void * 转换为 char * 进行指针运算 const char *buffer_ptr = (const char *)filedata->buffer; phone_ptr = buffer_ptr + sizeof(Contact) * i + sizeof(uint8_t) + NAME_SIZE; // static_print_debug("phone_ptr: %s , contact_data_buffer[j].phone: %s", phone_ptr, contact_data_buffer[j].phone); if((memcmp(contact_data_buffer[j].phone, phone_ptr, sizeof(contact_data_buffer[j].phone)) == 0)){ // (memcmp(contact_data_buffer[i].name, filedata->buffer + sizeof(Contact) * j + sizeof(uint8_t), sizeof(contact_data_buffer[i].name)) == 0)){ static_print_debug("contact data already exist, no need to write."); is_exist = true; break; } } if(is_exist == false){ static_print_debug("contact data not exist, write it. phone : %s",phone_ptr); ret = fwrite(phone_ptr - sizeof(uint8_t) - NAME_SIZE, sizeof(Contact),1,fp); if(ret != 1){ static_print_error("fwrite failed!"); fclose(fp); free(contact_data_buffer); contact_data_buffer = NULL; return -1; } rel_contact_num++; } } fclose(fp); free(contact_data_buffer); contact_data_buffer = NULL; }else if(ret == -1){ //通讯录文件不存在,直接写入 FILE *fp = NULL; size_t ret; fp = fopen(TJD_ADDRESS_BOOK_PATH, "ab"); if (fp == NULL) { static_print_error("fopen %s failed!", TJD_ADDRESS_BOOK_PATH); return -1; } ret = fwrite(filedata->buffer, sizeof(Contact), filedata->size, fp); if (ret != filedata->size) { static_print_error("fwrite failed! ret:%d", ret); } fclose(fp); } /* 每次同步完成后更新List */ contacts_sync_event(); return 0; } static signed int tjd_task_service_timer_dial_param_json(void *param) { if(param == NULL){ static_print_error("tjd_task_service_timer_dial_param_json param is NULL"); return -1; } custom_dial_parameter_t *filedata = (custom_dial_parameter_t *)param; custom_dial_parameter_t param_data = { .setting_mode = filedata->setting_mode, .images_number = filedata->images_number, .switching_mode = filedata->switching_mode, }; // memcpy(¶m_data, filedata, sizeof(custom_dial_parameter_t)); static_print_debug("dial_param_data setting_mode: %x ,images_number: %x,switch mode:%x ", param_data.setting_mode, param_data.images_number, param_data.switching_mode); // 创建 JSON 对象 cJSON *json = cJSON_CreateObject(); if (!json) { static_print_error("Error creating JSON object"); return -1; } // 将 wf_type 添加到 JSON 对象中 switch(param_data.setting_mode){ case 0x01: cJSON_AddNumberToObject(json, "wf_type", 0); break; case 0x02: cJSON_AddNumberToObject(json, "wf_type", 1); break; case 0x03: cJSON_AddNumberToObject(json, "wf_type", 2); break; default: static_print_error("Invalid wf_type value ! setting_mode: %u",param_data.setting_mode); break; } // cJSON_AddNumberToObject(json, "wf_type", param_data.setting_mode); // 将 wf_preview 添加到 JSON 对象中 cJSON_AddStringToObject(json, "wf_preview", TJD_CUSTOM_DIAL_PREVIEW_PATH); // 将 bg_res 添加到 JSON 对象中 cJSON_AddStringToObject(json, "bg_res", TJD_CUSTOM_DIAL_BG_RES_PATH); // 将 img_number 添加到 JSON 对象中 cJSON_AddNumberToObject(json, "img_number", param_data.images_number); // 将 video_preview 添加到 JSON 对象中 if(param_data.setting_mode == 0x03){ cJSON_AddStringToObject(json, "video_preview", TJD_CUSTOM_DIAL_VIDEO_PREVIEW_PATH); }else{ cJSON_AddNullToObject(json, "video_preview"); } // tjd_set_custom_dial_file_num(0); // tjd_set_custom_dial_file_mask(false); // 打开文件以写入 JSON 数据 FILE *file = fopen(TJD_CUSTOM_DIAL_WF_CONFIG_PATH, "w"); if (!file) { static_print_error("Error opening file: "); cJSON_Delete(json); return -1; } // 将 JSON 对象转换为字符串并写入文件 char *jsonString = cJSON_Print(json); if (jsonString) { fprintf(file, "%s\n", jsonString); free(jsonString); // 释放 JSON 字符串 } // 关闭文件和删除 JSON 对象 fclose(file); cJSON_Delete(json); return 0; } static signed int tjd_task_service_timer_measurement_spo2_data(void *param) { static_print_debug("read device oxygen measurement data"); uint8_t *spo2_array = NULL; sql_fit_get_spo2_daydata(&spo2_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 = SPO2_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; uint8_t data[12] = {0}; for(int i = 0; i < SPO2_DAY_MAX_NUM; i++){ if(spo2_array[cur_number] != 0){ memset(data, 0, sizeof(data)); data[0] = 0x04; 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] = spo2_array[cur_number]; data[10] = (total_number >> 8) & 0xFF; data[11] = (cur_number >> 8) & 0xFF; tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data),MEASUREMENT_DATA_SYNCHRONIZATION, gatt_server_id,g_server_conn_id); } time_minute += 5; if(time_minute >= 60){ time_minute = 0; time_hour += 1; if(time_hour >= 24){ time_hour = 0; time_day += 1; } } cur_number += 1; // osDelay(20); } return 0; } static signed int tjd_task_service_timer_measurement_hr_data(void *param) { static_print_debug("read device heartrate measurement data"); uint8_t *heartrate_array = NULL; sql_fit_get_hr_daydata(&heartrate_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 = HR_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 < HR_DAY_MAX_NUM; i++){ if(heartrate_array[cur_number] != 0){ uint8_t data[12] = {0}; data[0] = 0x01; 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] = heartrate_array[cur_number]; data[10] = (total_number >> 8) & 0xFF; data[11] = (cur_number >> 8) & 0xFF; tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, data, sizeof(data),MEASUREMENT_DATA_SYNCHRONIZATION, gatt_server_id, g_server_conn_id); } time_minute += 5; if(time_minute >= 60){ time_minute = 0; time_hour += 1; if(time_hour >= 24){ time_hour = 0; time_day += 1; } } cur_number += 1; osDelay(10); } return 0; } static signed int tjd_task_service_timer_current_measurement_hr_data(void *param) { uint8_t retData[12] = {0}; send_measure_data_t *measure_data = (send_measure_data_t *)param; if(tjd_service_hrs_get_ops()->hrs_wear_status()){ if(measure_data->mode == MeasureMode_Heart){ retData[0] = measure_data->mode; retData[1] = measure_data->vlue & 0xFF; tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, retData, strlen((char *)retData), MEASUREMENT_DATA_UPLOAD, gatt_server_id, g_server_conn_id); }else if(measure_data->mode == MeasureMode_Spo2){ retData[0] = measure_data->mode; retData[1] = measure_data->vlue & 0xFF; tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, retData, strlen((char *)retData), MEASUREMENT_DATA_UPLOAD, gatt_server_id, g_server_conn_id); }else if(measure_data->mode == MeasureMode_Blood){ retData[0] = measure_data->mode; retData[1] = (measure_data->vlue >> 8) & 0xFF; retData[2] = measure_data->vlue & 0xFF; tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD, retData, strlen((char *)retData), MEASUREMENT_DATA_UPLOAD, gatt_server_id, g_server_conn_id); } } return 0; } static signed int tjd_task_service_timer_handle_step_data(void *param) { static_print_debug("handle step data"); uint32_t step_data = sql_fit_get_currentStepNum_data(); static_print_debug("step data: %d",step_data); //获取当日时间 struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops(); struct rtc_time time_info = {0}; rtc_api->get_rtc_time(&time_info); uint8_t time_hour = time_info.tm_hour; uint8_t time_minute = time_info.tm_min; // uint8_t time_second = 0; sql_fit_set_step_curdata(time_hour, step_data); return 0; } static signed int tjd_task_service_timer_handle_excise_data(void *param) { static_print_debug("handle excise data"); uint8_t excise_data = sql_fit_get_currentStrengthTime_data(); //获取当日时间 struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops(); struct rtc_time time_info = {0}; rtc_api->get_rtc_time(&time_info); uint8_t time_hour = time_info.tm_hour; uint8_t time_minute = time_info.tm_min; // uint8_t time_second = 0; sql_fit_set_exertime_curdata(time_hour, excise_data); return 0; } static signed int tjd_task_service_timer_handle_calorie_data(void *param) { static_print_debug("handle calorie data"); uint16_t calorie_data = sql_fit_get_currentCalorieNum_data(); //获取当日时间 struct rtc_class_ops *rtc_api = tjd_driver_rtc_get_ops(); struct rtc_time time_info = {0}; rtc_api->get_rtc_time(&time_info); uint8_t time_hour = time_info.tm_hour; uint8_t time_minute = time_info.tm_min; // uint8_t time_second = 0; sql_fit_set_calorie_curdata(time_hour, calorie_data); return 0; } static signed int tjd_task_service_timer_handle_send_sport_record_data(void *param) { static_print_debug("send sport record data"); //初始化事件标志组 int ret = osal_event_init(&g_sport_record_event); if (ret != EXT_ERR_SUCCESS) { static_print_error("send sport record data osal_event_init fail! ret=0x%x", ret); return ret; } //读取"/system/tjd_sport" 下的文件名包含 sport_record_ 开头的文件,然后发送文件内容 StringArray fileList = search_and_record_filepath(); unsigned int event_mask = FILE_SEND_FAILE | FILE_SEND_SUCCESS | FILE_SEND_SKIP | FILE_SEND_NOSPACE | FILE_SEND_NOSUPPORT; tjd_ble_mutex_lock(); for (size_t i = 0; i < fileList.size; ++i) { static_print_debug("%s ", fileList.data[i]); tjd_ble_upload_file(fileList.data[i],TYPE_SPORT_RECORD); ret = osal_event_read(&g_sport_record_event, event_mask, 1000 * 60 * 1, OSAL_WAITMODE_OR | OSAL_WAITMODE_CLR); if(ret & FILE_SEND_SKIP || ret & FILE_SEND_SUCCESS || ret & FILE_SEND_NOSUPPORT) continue; if(ret & FILE_SEND_FAILE || ret & FILE_SEND_NOSPACE ) break; if(ret == OSAL_FAILURE){ static_print_error("osal_event_read timeout or error!"); break; } } tjd_ble_mutex_unlock(); free_string_array(&fileList); ret = osal_event_clear(&g_sport_record_event, event_mask); if(ret != OSAL_SUCCESS){ static_print_error("osal_event_clear failed"); return -1; } ret = osal_event_destroy(&g_sport_record_event); if(ret != OSAL_SUCCESS){ static_print_error("osal_event_destroy failed"); return -1; } return 0; } #define TJD_JSON_FILE_PATH "/system/app_list.json" static signed int tjd_task_timer_handle_get_js_app_list(void *param) { static_print_debug("handle get js app list"); //初始化事件标志组 int ret = osal_event_init(&g_js_app_list_event); //暂时不使用 if (ret != EXT_ERR_SUCCESS) { static_print_error("send js app list osal_event_init fail! ret=0x%x", ret); return 0; } unsigned int event_mask = FILE_SEND_FAILE | FILE_SEND_SUCCESS | FILE_SEND_SKIP | FILE_SEND_NOSPACE | FILE_SEND_NOSUPPORT; char file_name[] = TJD_JSON_FILE_PATH; //全路径 tjd_ble_mutex_lock(); if(access(TJD_JSON_FILE_PATH, 0) != 0){ FILE *file = fopen(TJD_JSON_FILE_PATH, "w+"); if (file != NULL) { fclose(file); } } tjd_ble_upload_file((const char *)file_name,TYPE_JS_APP_LIST); tjd_ble_mutex_unlock(); osal_event_clear(&g_js_app_list_event, event_mask); osal_event_destroy(&g_js_app_list_event); return 0; } #define CUR_FILE_IDX_LEN 4 //%04u-9999 #define TJD_JSON_CRASH_LOG_PATH "/user/log" static signed int tjd_task_timer_handle_get_crash_log(void *param) { static_print_debug("%s",__func__); int file_idx = 0; char file_name[128] = {0}; //初始化事件标志组 int ret = osal_event_init(&g_crash_log_event); //暂时不使用 if (ret != EXT_ERR_SUCCESS) { static_print_error("send crash log osal_event_init fail! ret=0x%x", ret); return 0; } unsigned int event_mask = FILE_SEND_FAILE | FILE_SEND_SUCCESS | FILE_SEND_SKIP | FILE_SEND_NOSPACE | FILE_SEND_NOSUPPORT; tjd_ble_mutex_lock(); struct dirent *ptr; DIR *dir = opendir(TJD_JSON_CRASH_LOG_PATH); if(dir != NULL){ while ((ptr = readdir(dir)) != NULL) { if (strstr(ptr->d_name, "log_file_diag") != NULL && strlen(strrchr(ptr->d_name, '.')+1) >= CUR_FILE_IDX_LEN){ static_print_debug("log name: %s",ptr->d_name); char *dot = strrchr(ptr->d_name, '.'); if(dot == NULL) continue; int idx_temp = atoi(dot+1); static_print_debug("log idx: %d",idx_temp); file_idx = (idx_temp > file_idx)? idx_temp : file_idx; } } sprintf(file_name, "%s/log_file_diag.bin.%04u", TJD_JSON_CRASH_LOG_PATH, file_idx); static_print_debug("file name: %s",file_name); }else{ static_print_debug("%s opendir err!", __func__); } closedir(dir); tjd_ble_upload_file((const char *)file_name,TYPE_LOG); tjd_ble_mutex_unlock(); osal_event_clear(&g_crash_log_event, event_mask); osal_event_destroy(&g_crash_log_event); return 0; } #define TJD_SLEEP_JSON_PATH "/system/service_sleep.json" static signed int tjd_task_timer_handle_send_sleep_json(void *param) { static_print_debug("%s",__func__); tjd_ble_mutex_lock(); if(access(TJD_JSON_FILE_PATH, 0) != 0){ FILE *file = fopen(TJD_SLEEP_JSON_PATH, "w+"); if (file != NULL) { fclose(file); } } tjd_ble_upload_file((const char *)TJD_SLEEP_JSON_PATH,TYPE_SLEEP_JSON); tjd_ble_mutex_unlock(); return 0; } static signed int tjd_task_service_timer_handle_send_sport_end_record_data(void *param) { static_print_debug("send sport end record data"); if(param == NULL) return -1; tjd_ble_upload_file((char *)param,TYPE_SPORT_RECORD); return 0; } uint8_t tjd_service_bt_scan_start(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_scan_start, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_bt_scan_stop(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_scan_stop, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_bt_scan_connect(const bd_addr_t *addr) { static_print_debug("%s, param %p", __func__, addr); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_connect, addr, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_bt_is_connect(const bd_addr_t *addr) { static_print_debug("%s, param %p", __func__, addr); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_is_connect, addr, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_snk_connect(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_snk_connect, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_snk_disconnect(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_snk_disconnect, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_file_append(file_append_data_t *filedata) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_file_append, filedata, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_contact_append(file_append_data_t *filedata) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_contacts_data_append, filedata, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_save_dial_parameter(custom_dial_parameter_t *param) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_dial_param_json, param, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_handle_step_data(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_handle_step_data, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_handle_excise_data(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_handle_excise_data, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_handle_calorie_data(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_handle_calorie_data, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_send_measurement_data(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_measurement_spo2_data, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_send_hr_measurement_data(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_measurement_hr_data, NULL, LOOP_INTERVAL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_send_current_measurement_data(const send_measure_data_t *measure_data) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_current_measurement_hr_data, measure_data, 0, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_send_sport_record_data(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_handle_send_sport_record_data, NULL, LOOP_SMALL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_send_sport_end_record_data(char * file_name) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_service_timer_handle_send_sport_end_record_data, file_name, LOOP_SMALL_TIME, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_send_js_app_list(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_timer_handle_get_js_app_list, NULL, 0, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_send_crash_log(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_timer_handle_get_crash_log, NULL, 0, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } uint8_t tjd_service_send_sleep_week_data(void) { static_print_debug("%s", __func__); int ret = OSAL_FAILURE; queue_default_info_t msg_data = { tjd_task_timer_handle_send_sleep_json, NULL, 0, NULL}; ret = osal_msg_queue_write_copy(tjd_task_ancillary_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0); if(ret != OSAL_SUCCESS) { static_print_error("[%s] osal_msg_queue_write_copy fail", __func__); } return ret; } static struct timespec last_time = {0}; void tjd_service_bt_sync_ephemeris_event(void) { struct timespec time = {0}; clock_gettime(CLOCK_MONOTONIC, &time); if (last_time.tv_sec != 0 && (time.tv_sec - last_time.tv_sec) < 60 * 5) { static_print_debug("tjd_service_bt_sync_ephemeris_event too fast"); return; } static_print_debug("tjd_service_bt_sync_ephemeris_event"); last_time = time; tjd_ble_request_synchrodata(); } #define BLE_SYNC_EPH_TIME (30 * 60 * 1000) #define BLE_SYNC_EPH_ERR_TIME (10 * 60 * 1000) // #define BLE_SYNC_EPH_TIME (2 * 60 * 1000) // #define BLE_SYNC_EPH_ERR_TIME (5 * 60 * 1000) static signed int tjd_service_ble_sync_handle(void *param) { static_print_debug("tjd_service_gps_sync_handle"); if (tjd_get_ble_is_connect()) { tjd_service_bt_sync_ephemeris_event(); } else { return BLE_SYNC_EPH_ERR_TIME; } return BLE_SYNC_EPH_TIME; } void tjd_service_ble_sync_data_open(void) { queue_default_info_t msg_data = {tjd_service_ble_sync_handle, NULL, BLE_SYNC_EPH_TIME, NULL}; osal_msg_queue_write_copy(tjd_task_service_timer_get_queue_id(), (void *)&msg_data, sizeof(msg_data), 0); } void tjd_service_ble_sync_data_close(void) { queue_default_info_t msg_data = {tjd_service_ble_sync_handle, NULL, 0, NULL}; osal_msg_queue_write_copy(tjd_task_service_timer_get_queue_id(), (void *)&msg_data, sizeof(msg_data), 0); }