整体流程如下: 在app_gattc_sdp_svc_ind_handler()里面做如下操作: for (uint8_t idx=0; idx<(ind->end_hdl - ind->start_hdl); idx++) { // characteristic description if(ind->info[idx].att_type == GATTC_SDP_ATT_DESC) { uint16_t char_hdl = ind->start_hdl + 1 + idx; uint16_t uuid = ((ind->info[idx].att.uuid[1]<<8) | ind->info[idx].att.uuid[0]); LOG_DBG("desc: 0x%04x(%d), uuid: 0x%04x", char_hdl, char_hdl, uuid); if (uuid == ATT_DESC_CLIENT_CHAR_CFG) { //客户自己定义一个数据结构存储自己需要的东西,比如这里的notify的句柄 app_env.central.connect[index].ccc_handle[app_env.central.connect[index].ccc_handle_num++] = char_hdl; LOG_DBG("CCC handle: 0x%02x(%d)", char_hdl, char_hdl); } } } 在app_gattc_cmp_evt_handler()里面做对应的操作,这里只以下发使能notify的操作为例 __STATIC int app_gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { LOG_VBS_FUNC(); uint8_t conidx = KE_IDX_GET(src_id); uint8_t index = app_central_find_by_conidx(conidx); switch(param->operation) { case GATTC_READ: LOG_DBG("GATTC_READ"); break; case GATTC_READ_LONG: LOG_DBG("GATTC_READ_LONG"); break; case GATTC_READ_BY_UUID: LOG_DBG("GATTC_READ_BY_UUID"); break; case GATTC_READ_MULTIPLE: LOG_DBG("GATTC_READ_MULTIPLE"); break; case GATTC_WRITE: LOG_DBG("GATTC_WRITE"); break; case GATTC_WRITE_NO_RESPONSE: LOG_DBG("GATTC_WRITE_NO_RESPONSE"); break; case GATTC_SDP_DISC_SVC: LOG_DBG("GATTC_SDP_DISC_SVC"); break; case GATTC_SDP_DISC_SVC_ALL: { LOG_DBG("GATTC_SDP_DISC_SVC_ALL"); if (app_env.central.connect[index].ccc_handle_num != 0) { LOG_INF("Enable all notifications."); for (int i=0; i<app_env.central.connect[index].ccc_handle_num; i++) { LOG_INF("CCC handle: 0x%02x(%d)", app_env.central.connect[index].ccc_handle[i], app_env.central.connect[index].ccc_handle[i]); prf_gatt_write_ntf_ind(&app_env.central.prf_env, conidx, app_env.central.connect[index].ccc_handle[i], PRF_CLI_START_NTF); } } } break; default: break; } return (KE_MSG_CONSUMED); } 主机的其他读写服务依然可以参考这个思路进行操作. |