mcu_hi3321_watch/tjd/service/service_bt.c
2025-05-26 20:15:20 +08:00

1597 lines
56 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) TJD Technologies Co., Ltd. 2020. All rights reserved.
*
* Description: service_bt.c
*
* Author: linzhaocheng
*
* Create: 2024-7-24
*--------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#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 <sys/stat.h>
#include <stdio.h>
#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(&param_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);
}