#include "aicare_profile.h" /* * INCLUDES (包含头文件) */ #include #include #include "co_printf.h" #include "gap_api.h" #include "gatt_api.h" #include "gatt_sig_uuid.h" #include "co_log.h" #include "aicare_handler.h" /* * MACROS (宏定义) */ /* * CONSTANTS (常量定义) */ static uint8_t user_ntf_enable_flag=0; // Simple GATT Profile Service UUID: 0xFFE0 const static uint8_t user_svc_uuid[] = AICARE_SVC_UUID; /******************************* Characteristic 1 defination *******************************/ // Characteristic 1 UUID: 0xFFE1 // Characteristic 1 data #define AICARE_CHAR1_VALUE_LEN 600 #define AICARE_CHAR2_VALUE_LEN 600 static uint8_t user_char1_value[AICARE_CHAR1_VALUE_LEN] = {0}; //Characteristic 1 User Description #define AICARE_CHAR1_DESC_LEN 6 #define AICARE_CHAR_CCC_LEN 2 /* * TYPEDEFS (类型定义) */ /* * GLOBAL VARIABLES (全局变量) */ static uint8_t aicare_svc_id = 0; static uint8_t conn_svc_idx = 0; /* * LOCAL VARIABLES (本地变量) */ static gatt_service_t aicare_profile_svc; /********************************************************************* * Profile Attributes - Table * 每一项都是一个attribute的定义。 * 第一个attribute为Service 的的定义。 * 每一个特征值(characteristic)的定义,都至少包含三个attribute的定义; * 1. 特征值声明(Characteristic Declaration) * 2. 特征值的值(Characteristic value) * 3. 特征值描述符(Characteristic description) * 如果有notification 或者indication 的功能,则会包含四个attribute的定义,除了前面定义的三个,还会有一个特征值客户端配置(client characteristic configuration)。 * */ const gatt_attribute_t aicare_profile_att_table[AICARE_IDX_NB] = { // userr gatt Service Declaration [AICARE_IDX_SERVICE]={ { UUID_SIZE_2, UUID16_ARR(GATT_PRIMARY_SERVICE_UUID) }, /* UUID */ GATT_PROP_READ, /* Permissions */ UUID_SIZE_16, /* Max size of the value */ /* Service UUID size in service declaration */ (uint8_t*)user_svc_uuid, /* Value of the attribute */ /* Service UUID value in service declaration */ }, // Characteristic 1 Declaration [AICARE_IDX_CHAR1_DECLARATION] = { { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) }, /* UUID */ GATT_PROP_READ, /* Permissions */ 0, /* Max size of the value */ NULL, /* Value of the attribute */ }, // Characteristic 1 Value [AICARE_IDX_CHAR1_VALUE] = { { UUID_SIZE_16,AICARE_CHAR1_UUID }, /* UUID */ GATT_PROP_WRITE, /* Permissions */ /* Permissions */ AICARE_CHAR1_VALUE_LEN, /* Max size of the value */ NULL, /* Value of the attribute */ /* Can assign a buffer here, or can be assigned in the application by user */ }, // Characteristic 2 Declaration [AICARE_IDX_CHAR2_DECLARATION] = { { UUID_SIZE_2, UUID16_ARR(GATT_CHARACTER_UUID) }, /* UUID */ GATT_PROP_READ, /* Permissions */ 0, /* Max size of the value */ NULL, /* Value of the attribute */ }, // Characteristic 2 Value [AICARE_IDX_CHAR2_VALUE] = { { UUID_SIZE_16,AICARE_CHAR2_UUID }, /* UUID */ GATT_PROP_READ|GATT_PROP_NOTI, /* Permissions */ /* Permissions */ AICARE_CHAR2_VALUE_LEN, /* Max size of the value */ NULL, /* Value of the attribute */ /* Can assign a buffer here, or can be assigned in the application by user */ }, // Characteristic 2 client characteristic configuration [AICARE_IDX_CHAR2_CFG] = { { UUID_SIZE_2, UUID16_ARR(GATT_CLIENT_CHAR_CFG_UUID) }, /* UUID */ GATT_PROP_READ | GATT_PROP_WRITE, /* Permissions */ 0, /* Max size of the value */ NULL, /* Value of the attribute */ /* Can assign a buffer here, or can be assigned in the application by user */ }, }; void aicare_send_notify(uint8_t *p_data,uint16_t len) { // if(user_ntf_enable_flag) { gatt_ntf_t ntf_att; ntf_att.att_idx = AICARE_IDX_CHAR2_VALUE; ntf_att.conidx = conn_svc_idx; ntf_att.svc_id = aicare_svc_id; ntf_att.data_len = len ; ntf_att.p_data = p_data; gatt_notification(ntf_att); } } /********************************************************************* * @fn aicare_gatt_read_cb * * @brief Simple Profile user application handles read request in this callback. * 应用层在这个回调函数里面处理读的请求。 * * @param p_read - the pointer to read buffer. NOTE: It's just a pointer from lower layer, please create the buffer in application layer. * 指向读缓冲区的指针。 请注意这只是一个指针,请在应用程序中分配缓冲区. 为输出函数, 因此为指针的指针. * len - the pointer to the length of read buffer. Application to assign it. * 读缓冲区的长度,用户应用程序去给它赋值. * att_idx - index of the attribute value in it's attribute table. * Attribute的偏移量. * * @return 读请求的长度. */ static void aicare_gatt_read_cb(uint8_t *p_read, uint16_t *len, uint16_t att_idx) { switch (att_idx) { case AICARE_IDX_CHAR1_VALUE: break; case AICARE_IDX_CHAR2_VALUE: break; default: break; } co_printf("\r\n Read request idx:%d \r\n", att_idx); } /********************************************************************* * @fn aicare_gatt_write_cb * * @brief Simple Profile user application handles write request in this callback. * 应用层在这个回调函数里面处理写的请求。 * * @param write_buf - the buffer for write * 写操作的数据. * * len - the length of write buffer. * 写缓冲区的长度. * att_idx - index of the attribute value in it's attribute table. * Attribute的偏移量. * * @return 写请求的长度.GATT_PROP_NOTI */ static void aicare_gatt_write_cb(uint8_t *write_buf, uint16_t len, uint16_t att_idx) { co_printf("\r\n Write request idx:%d \r\n", att_idx); switch(att_idx) { case AICARE_IDX_CHAR1_VALUE: show_reg(write_buf,len,1); aicare_app_data_recv(write_buf,len); // break; case AICARE_IDX_CHAR2_VALUE: show_reg(write_buf,len,1); break; case AICARE_IDX_CHAR2_CFG: co_printf("AICARE_IDX_CHAR2_CFG\r\n"); show_reg(write_buf,len,1); break; } } /********************************************************************* * @fn aicare_gatt_msg_handler * * @brief Simple Profile callback funtion for GATT messages. GATT read/write * operations are handeled here. * * @param p_msg - GATT messages from GATT layer. * * @return uint16_t - Length of handled message. */ static uint16_t aicare_gatt_msg_handler(gatt_msg_t *p_msg) { co_printf("\r\naicare_gatt_msg_handler evt:%d conn_idx:%d\r\n",p_msg->msg_evt,p_msg->conn_idx); conn_svc_idx = p_msg->conn_idx; switch(p_msg->msg_evt) { case GATTC_MSG_READ_REQ: aicare_gatt_read_cb((uint8_t *)(p_msg->param.msg.p_msg_data), &(p_msg->param.msg.msg_len), p_msg->att_idx); break; case GATTC_MSG_WRITE_REQ: aicare_gatt_write_cb((uint8_t*)(p_msg->param.msg.p_msg_data), (p_msg->param.msg.msg_len), p_msg->att_idx); break; case GATTC_MSG_NTF_REQ: user_ntf_enable_flag=0; break; default: break; } return p_msg->param.msg.msg_len; } void aicare_gatt_add_service(void) { aicare_profile_svc.p_att_tb = aicare_profile_att_table; aicare_profile_svc.att_nb = AICARE_IDX_NB; aicare_profile_svc.gatt_msg_handler = aicare_gatt_msg_handler; aicare_svc_id = gatt_add_service(&aicare_profile_svc); co_printf("aicare_svc_id:%d",aicare_svc_id); }