--- /dev/null
+/*
+ * Copyright (c) CompanyNameMagicTag 2024. All rights reserved.
+ * Description: This module include test function of ANCS Client module.
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <td_base.h>
+#include "common_def.h"
+#include "bts_def.h"
+#include "bts_gatt_stru.h"
+#include "bts_a2dp_source.h"
+#include "bts_gatt_server.h"
+#include "bts_le_gap.h"
+#include "osal_task.h"
+#include "securec.h"
+#include "wearable_log.h"
+#include <stdint.h>
+#include <stdio.h>
+#include "stdbool.h"
+
+#include "bts_le_gap.h"
+#include "bts_br_gap.h"
+#include "battery_hal.h"
+#include "bleService.h"
+#include "alipay_feature.h"
+#include "alipay_bluetooth.h"
+#include "bts_a2dp_sink.h"
+#include "osal_timer.h"
+#include "bleEvent.h"
+#include "hidService.h"
+#include "factorytestService.h"
+#include "ppgBleService.h"
+#include "build_version.h"
+#include "custom_runtime.h"
+#include "custom_utils.h"
+#include "bletest.h"
+#ifdef SUPPORT_AT_OHOSFWK
+#include "BluetoothWrapper.h"
+#endif
+
+#include "ble_ancs_client.h"
+#include "bleANCS.h"
+#include "ble_gatts_callbacks.h"
+#include "bleEvent.h"
+
+#define TEN 10
+#define ANCS_ATT_BYTE_LENGTH 6
+#define ANCS_DEC_CHAR_COUNT 2
+#define BYTE_BIT_COUNT 8
+
+/* ANCS客户端接口命令id */
+typedef enum {
+ BLE_SAMPLE_ANCS_CLIENT_REGISTER_CBK = 1, /* 1 注册ANCS客户端回调函数 */
+ BLE_SAMPLE_ANCS_CLIENT_SETUP, /* 2 ANCS客户端连接服务端 */
+ BLE_SAMPLE_ANCS_CLIENT_SUBSCRIBE_NOTITY, /* 3 订阅通知 */
+ BLE_SAMPLE_ANCS_CLIENT_SUBSCRIBE_DATA, /* 4 订阅数据 */
+ BLE_SAMPLE_ANCS_CLIENT_PERFORM_ACTION, /* 5 执行操作 */
+ BLE_SAMPLE_ANCS_CLIENT_NOTIFY_ATT_GET, /* 6 执行操作 */
+ BLE_SAMPLE_ANCS_CLIENT_APP_ATT_GET /* 7 执行操作 */
+} ble_ancs_client_at_cmd_id_t;
+
+
+static uint8_t g_client_id=0;
+/* 命令处理函数接口 */
+
+
+/* 获取通知属性 */
+static uint8_t ble_ancs_client_at_cmd_get_notify_att(uint16_t conn_id,uint32_t notify_uid)
+{
+
+ /* 获取来电通知属性 */
+ ble_ancs_notification_attr_req_t *notify_attr_req = bt_os_new(
+ sizeof(ble_ancs_notification_attr_req_t) + (5 * sizeof(ble_ancs_attr_req_t)));
+ notify_attr_req->att_num = 5;
+ notify_attr_req->notification_uid = notify_uid;
+
+ (notify_attr_req->attr)->att_id=0x00;
+ (notify_attr_req->attr)->att_max_length=2;
+
+ (notify_attr_req->attr+1)->att_id=0x01;
+ (notify_attr_req->attr+1)->att_max_length=256;
+
+ (notify_attr_req->attr+2)->att_id=0x03;
+ (notify_attr_req->attr+2)->att_max_length=256;
+
+ (notify_attr_req->attr+3)->att_id=0x05;
+ (notify_attr_req->attr+3)->att_max_length=64;
+
+ (notify_attr_req->attr+4)->att_id=0x06;
+ (notify_attr_req->attr+4)->att_max_length=10;
+
+ //decode_att_req_from_str(argv[BT_INDEX_4], notify_attr_req->attr);
+ errcode_t ret = ble_ancs_client_send_get_notify_att_cmd(g_client_id, conn_id, notify_attr_req);
+ bt_os_free(notify_attr_req);
+ printf("ble ancs client notify att get ret:0x%x\r\n", ret);
+ return 0;
+}
+
+
+
+/* 执行消息行为(积极或消极行为) */
+static uint8_t ble_ancs_client_at_cmd_perform_action(uint16_t conn_id,uint32_t notify_uid,uint8_t action_id)
+{
+ ble_ancs_notification_action_req_t action_cmd = {0};
+ action_cmd.notification_uid = notify_uid;
+ action_cmd.action_id = action_id;
+ errcode_t ret = ble_ancs_client_send_perform_notify_action_cmd(g_client_id, conn_id, &action_cmd);
+ printf("ble ancs client perform action ret:0x%x\r\n", ret);
+ return 0;
+}
+
+//过滤掉之前的通知,只接收后发的
+static uint32_t subscribe_notify_creationTime=0;
+/* ANCS服务建立结果回调 */
+static void ble_ancs_client_setup_result_cbk(uint8_t client_id, uint16_t conn_id, errcode_t status)
+{
+ printf("[ANCSClientSetupCBK]conn_id:%d status:0x%x\r\n", conn_id, status);
+
+
+ int ret = uapi_get_timestampe_ss(&subscribe_notify_creationTime);
+
+ ble_ancs_client_subscribe_notify(conn_id,1);
+
+
+
+ //if(status==ERRCODE_BT_SUCCESS)
+
+}
+
+/* ANCS服务订阅结果回调 */
+static void ble_ancs_client_subscribe_result_cbk(uint8_t client_id, uint16_t conn_id,
+ ancs_client_subscribe_type_t type, gatt_status_t status)
+{
+ printf("[ANCSClientSubscribeResultCBK]conn_id:%d type:%d status:0x%x\r\n", conn_id, type, status);
+ if(type==ANCS_CLIENT_SUBSCRIBE_NOTIFY)
+ ble_ancs_client_subscribe_data(conn_id,1);
+}
+
+/* ANCS服务命令执行结果回调 */
+static void ble_ancs_client_write_result_cbk(uint8_t client_id, uint16_t conn_id, gatt_status_t status)
+{
+ printf("[ANCSClientCMDResultCBK]conn_id:%d status:0x%x\r\n", conn_id, status);
+
+}
+
+/* ANCS服务消息通知回调 */
+static void ble_ancs_client_notify_source_cbk(uint8_t client_id, uint16_t conn_id,
+ ble_ancs_notification_src_t *notify_src, errcode_t status)
+{
+ if (status == ERRCODE_BT_SUCCESS) {
+ printf(
+ "[ANCSClientNotifySRCCBK]conn_id:%d status:0x%x notify_id:%lu "
+ "eventId:%d eventFlags:0x%x category_id:%d\r\n",
+ conn_id, status,
+ notify_src->notification_uid,
+ notify_src->event_id,
+ notify_src->event_flags,
+ notify_src->category_id);
+ //ble_ancs_client_at_cmd_perform_action(conn_id,notify_src->notification_uid,ANCS_ACTION_POSITIVE);
+
+
+ uint32_t creationTime=0;
+ int ret = uapi_get_timestampe_ss(&creationTime);
+ //当前时间戳减去订阅通知时间戳10s以上的通知,才要求数据(过滤ios将所有未查看消息发过来)
+ if(creationTime-subscribe_notify_creationTime>=10)
+ ble_ancs_client_at_cmd_get_notify_att(conn_id, notify_src->notification_uid);
+ //
+
+ } else {
+ printf("[ANCSClientNotifySRCCBK]conn_id:%d status:0x%x.\r\n",
+ conn_id, status);
+ }
+}
+static char old_time_buf[64]={0};
+
+//"20240709T093253"
+/* ANCS服务通知属性响应结果回调 */
+static void ble_ancs_client_notification_attr_rsp_cbk(uint8_t client_id, uint16_t conn_id,
+ ble_ancs_notification_attr_rsp_t *notify_attr_rsp, errcode_t status)
+{
+ if (status == ERRCODE_BT_SUCCESS) {
+ printf("[ANCSClientNotifyATTRSPCBK]conn_id:%d status:0x%x notify_uid:%lu\r\n",
+ conn_id, status, notify_attr_rsp->notification_uid);
+
+ ble_ancs_attr_rsp_t *node = (ble_ancs_attr_rsp_t *)notify_attr_rsp->attr_rsp_lst.head;
+ uint16_t att_num = 1;
+ char title_buf[256]={0};
+ char msg_buf[256]={0};
+ char new_msg_buf[64]={0};
+ while (node != NULL) {
+ if (node != NULL) {
+ printf("[ANCSClientNotifyATTRSPCBK]att id:%d length:%lu att_value:%s\r\n",
+ node->att_id, node->att_length, node->att);
+ if( node->att_id==1)
+ {
+ sprintf_s(title_buf,256,"%s",node->att);
+ }
+ if(node->att_id==3)
+ {
+ sprintf_s(msg_buf,256,"%s",node->att);
+ }
+ if(node->att_id==5)
+ {
+ sprintf_s(new_msg_buf,64,"%s",node->att);
+ }
+ }
+ node = lnext(node);
+ if (att_num == notify_attr_rsp->att_num) {
+ break;
+ }
+ att_num = att_num + 1;
+ }
+
+ printf("ble_ancs_client_notification_attr_rsp_cbk test\r\n");
+
+
+ if(strcmp(old_time_buf,new_msg_buf)!=0)
+ {
+ memset(old_time_buf,0,64);
+ memcpy_s(old_time_buf,64,new_msg_buf,64);
+
+ printf("ble_ancs_client_notification_attr_rsp_cbk test 2\r\n");
+ message_data(notify_attr_rsp->notification_uid,0,title_buf,msg_buf,0);
+ //CustomEventPublish_TOPIC_EVENT_MESSAGENOTE();
+
+
+ }
+
+ } else {
+ printf("[ANCSClientNotifyATTRSPCBK]conn_id:%d status:0x%x.\r\n",
+ conn_id, status);
+ }
+}
+
+/* ANCS服务应用属性响应结果回调 */
+static void ble_ancs_client_app_attr_rsp_cbk(uint8_t client_id, uint16_t conn_id,
+ ble_ancs_app_attr_rsp_t *app_attr_rsp, errcode_t status)
+{
+ printf("[ANCSClientAPPATTRSPCBK]conn_id:%d status:0x%x\r\n", conn_id, status);
+ if (status == ERRCODE_BT_SUCCESS) {
+ ble_ancs_attr_rsp_t *node = (ble_ancs_attr_rsp_t *)app_attr_rsp->attr_rsp_lst.head;
+ uint16_t att_num = 1;
+ while (node != NULL) {
+ if (node != NULL && node->att_id == ANCS_APP_ATT_DISPLAY_NAME) {
+ printf("[ANCSClientAPPATTRSPCBK]app id:%s length:%lu app name:%s\r\n",
+ app_attr_rsp->app_id.id, node->att_length, node->att);
+ }
+ node = lnext(node);
+ if (att_num == app_attr_rsp->att_num) {
+ break;
+ }
+ att_num = att_num + 1;
+ }
+ } else {
+ printf("[ANCSClientAPPATTRSPCBK]conn_id:%d status:0x%x.\r\n",
+ conn_id, status);
+ }
+}
+
+
+
+
+
+/* 注册ancs服务回调 */
+static uint8_t ble_ancs_client_at_cmd_register_cbk()
+{
+ ble_ancs_client_callbacks_t cbk = {0};
+ cbk.setup_cb = ble_ancs_client_setup_result_cbk;
+ cbk.subscribe_cb = ble_ancs_client_subscribe_result_cbk;
+ cbk.write_result_cb = ble_ancs_client_write_result_cbk;
+ cbk.notify_source_cb = ble_ancs_client_notify_source_cbk;
+ cbk.notify_attr_cb = ble_ancs_client_notification_attr_rsp_cbk;
+ cbk.app_attr_cb = ble_ancs_client_app_attr_rsp_cbk;
+
+ errcode_t ret = ble_ancs_client_register_callbacks(&cbk);
+ printf("ble ancs client register cbk ret:0x%x\r\n", ret);
+ return 0;
+}
+
+/*注册客户端,初始化ANCS服务*/
+void gattc_reg_id(void)
+{
+ ble_client_register_gatt_callbacks();
+
+ ble_ancs_client_at_cmd_register_cbk();
+ bt_uuid_t uuid={0};
+ uuid.uuid[0]=0;
+ uuid.uuid[1]=1;
+
+ uuid.uuid_len=2;
+
+ uint8_t client_id;
+ errcode_t ret = gattc_register_client(&uuid, &client_id);
+
+ g_client_id=client_id;
+ printf("[GATTClient]gattc_register ret(errcode_t): %x client_id:%u\n", ret, client_id);
+}
+
+
+
+
+/* ANCS服务建立 */
+static uint8_t ble_ancs_client_at_cmd_setup(uint16_t conn_id)
+{
+ errcode_t ret = ble_ancs_client_setup_service(g_client_id, conn_id);
+ printf("ble ancs client setup ret:0x%x %d\r\n", ret,conn_id);
+ return 0;
+}
+
+/* 订阅数据 */
+static uint8_t ble_ancs_client_at_cmd_subscribe_data(uint16_t conn_id,uint8_t sub_flag)
+{
+
+ errcode_t ret = ble_ancs_client_subscribe_data_source(g_client_id, conn_id, sub_flag);
+ printf("ble ancs client sub data ret:0x%x %d\r\n", ret,sub_flag);
+ return 0;
+}
+
+/* 订阅 */
+uint8_t ble_ancs_client_subscribe_notify(uint16_t conn_id,uint8_t sub_flag)
+{
+
+ errcode_t ret = ble_ancs_client_subscribe_notification_source(g_client_id, conn_id, sub_flag);
+ printf("ble ancs client sub notify ret:0x%x %d\r\n", ret,sub_flag);
+
+
+ return 0;
+}
+
+uint8_t ble_ancs_client_subscribe_data(uint16_t conn_id,uint8_t sub_flag)
+{
+
+ errcode_t ret = ble_ancs_client_subscribe_data_source(g_client_id, conn_id, sub_flag);
+ printf("ble ancs client sub data ret:0x%x %d\r\n", ret,sub_flag);
+ return 0;
+}
+
+
+
+uint8_t ble_ancs_client_cmd_setup_and_subscribe(uint16_t conn_id)
+{
+ ble_ancs_client_at_cmd_setup(conn_id);
+ return 0;
+}
+
+
+
+
+/* 十六进制字符转数值 */
+static uint8_t char_2_num(int8_t c)
+{
+ if (c >= '0' && c <= '9') {
+ return (uint8_t)(c - '0');
+ } else if (c >= 'A' && c <= 'F') {
+ return (uint8_t)(c - 'A' + TEN);
+ } else if (c >= 'a' && c <= 'f') {
+ return (uint8_t)(c - 'a' + TEN);
+ } else {
+ return TD_U8_MAX;
+ }
+}
+
+/* 十六进制字符转数值 */
+static uint8_t str_2_byte(const char *str)
+{
+ return ((char_2_num(str[0]) << TD_U4_BITS) + char_2_num(str[1]));
+}
+
+/* 十六进制字符转属性请求参数结构体 */
+static void decode_att_req_from_str(const char *str, ble_ancs_attr_req_t *nums)
+{
+ uint32_t len = strlen(str);
+ uint32_t cnt = 0;
+ char *ptr_str = NULL;
+ uint16_t length_big_byte = 0;
+ uint16_t length_little_byte = 0;
+ ptr_str = str;
+ for (uint32_t i = 0; i < len - 1; i += ANCS_ATT_BYTE_LENGTH) { /* 6个字符为1组,2个字符为一个字节 */
+ nums[cnt].att_id = str_2_byte(ptr_str);
+ ptr_str += ANCS_DEC_CHAR_COUNT;
+ length_big_byte = (((uint16_t)str_2_byte(ptr_str)) << BYTE_BIT_COUNT);
+ ptr_str += ANCS_DEC_CHAR_COUNT;
+ length_little_byte = ((uint16_t)str_2_byte(ptr_str));
+ nums[cnt].att_max_length = (uint16_t)(length_big_byte | length_little_byte);
+ ptr_str += ANCS_DEC_CHAR_COUNT;
+ cnt++;
+ }
+}
+
+
+
+/* 解析应用属性参数 */
+static uint8_t parse_app_att_req_param(ble_ancs_app_attr_req_t *app_attr_req,
+ uint16_t app_id_len, uint16_t att_num, char **argv)
+{
+ // app_attr_req->att_num = att_num;
+ // app_attr_req->app_id.len = app_id_len + 1;
+ // uint8_t *id = bt_os_new(app_attr_req->app_id.len);
+ // if (id == NULL) {
+ // bts_error("[ANCSClientSample]app id memnew error!\r\n");
+ // app_attr_req->app_id.id = NULL;
+ // return MPC_BT_FAIL;
+ // }
+ // if (memcpy_s(id, app_attr_req->app_id.len, (uint8_t *)argv[BT_INDEX_2], app_id_len) != EOK) {
+ // bts_error("[ANCSClientSample]app id memcpy error!\r\n");
+ // bt_os_free(id);
+ // app_attr_req->app_id.id = NULL;
+ // return MPC_BT_FAIL;
+ // }
+ // *(id + app_id_len) = 0; /* This string is NULL-terminated */
+ // app_attr_req->app_id.id = id;
+
+ // /* 解析应用属性参数 */
+ // decode_att_req_from_str(argv[BT_INDEX_4], app_attr_req->attr_id);
+ return 0;
+}
+
+/* 获取应用属性 */
+static uint8_t ble_ancs_client_at_cmd_get_app_att(uint8_t argc, char **argv)
+{
+ //if (argc != BT_AT_PARAM_LEN5) {
+ // bts_error("ble ancs client argc num invalid :%u\r\n", argc);
+ // return MPC_BT_FAIL;
+ // }
+
+ // uint8_t client_id = 0;
+ // uint16_t conn_id = 0;
+ // uint8_t att_num = 0;
+ // uint16_t app_id_len = 0;
+ // client_id = (uint8_t)atoi(argv[BT_INDEX_0]);
+ // conn_id = (uint16_t)atoi(argv[BT_INDEX_1]);
+ // app_id_len = strlen(argv[BT_INDEX_2]);
+ // att_num = (uint8_t)atoi(argv[BT_INDEX_3]);
+ // if (att_num == 0) {
+ // bts_error("ble ancs client notify att req att num is zero!\r\n");
+ // return MPC_BT_FAIL;
+ // }
+ // uint32_t len = strlen(argv[BT_INDEX_4]);
+ // if ((att_num * ANCS_ATT_BYTE_LENGTH) != len) {
+ // bts_error("ble ancs client notify att req att num is wrong!\r\n");
+ // return MPC_BT_FAIL;
+ // }
+
+ // /* 获取应用属性 */
+ // ble_ancs_app_attr_req_t *app_attr_req = bt_os_new(sizeof(ble_ancs_app_attr_req_t) + (att_num * sizeof(uint8_t)));
+ // uint8_t result = parse_app_att_req_param(app_attr_req, app_id_len, att_num, argv);
+ // if (result != MPC_BT_SUCC) {
+ // if (app_attr_req->app_id.id != NULL) {
+ // bt_os_free(app_attr_req->app_id.id);
+ // }
+ // bt_os_free(app_attr_req);
+ // return result;
+ // }
+ // errcode_t ret = ble_ancs_client_send_get_app_att_cmd(client_id, conn_id, app_attr_req);
+ // printf("ble ancs client app att get ret:0x%x\r\n", ret);
+ // bt_os_free(app_attr_req->app_id.id);
+ // bt_os_free(app_attr_req);
+ return 0;
+}
+
+/* ANCS客户端AT命令与接口对应关系 */
+// static ble_ancs_client_at_hdl_info_t g_ble_ancs_client_at_hdl[] = {
+// { BLE_SAMPLE_ANCS_CLIENT_REGISTER_CBK, ble_ancs_client_at_cmd_register_cbk },
+// { BLE_SAMPLE_ANCS_CLIENT_SETUP, ble_ancs_client_at_cmd_setup },
+// { BLE_SAMPLE_ANCS_CLIENT_SUBSCRIBE_NOTITY, ble_ancs_client_at_cmd_subscribe_notify },
+// { BLE_SAMPLE_ANCS_CLIENT_SUBSCRIBE_DATA, ble_ancs_client_at_cmd_subscribe_data },
+// { BLE_SAMPLE_ANCS_CLIENT_NOTIFY_ATT_GET, ble_ancs_client_at_cmd_get_notify_att },
+// { BLE_SAMPLE_ANCS_CLIENT_APP_ATT_GET, ble_ancs_client_at_cmd_get_app_att },
+// { BLE_SAMPLE_ANCS_CLIENT_PERFORM_ACTION, ble_ancs_client_at_cmd_perform_action },
+// };
+
+// void ble_ancs_client_at_cmd(uint8_t cmd_id, char **params, uint8_t params_cnt)
+// {
+// size_t hdl_cnt = sizeof(g_ble_ancs_client_at_hdl) / sizeof(ble_ancs_client_at_hdl_info_t);
+// for (uint8_t i = 0; i < hdl_cnt; i++) {
+// if (g_ble_ancs_client_at_hdl[i].id == cmd_id && g_ble_ancs_client_at_hdl[i].func != NULL) {
+// (void)g_ble_ancs_client_at_hdl[i].func(params_cnt, params);
+// return;
+// }
+// }
+// }
+
+