CH579 CH573 CH582 Central 例子应用说明二 (读写通知的控制说明)
以CH583EVT里面的代码为例子(实现通道读写控制的讲解)
if(events & START_READ_OR_WRITE_EVT) //对0xFFE1 属性通道的读写操作 { if(centralProcedureInProgress == FALSE) { if(centralDoWrite) //自定义标志,用于演示读写交替 { // Do a write attWriteReq_t req; req.cmd = FALSE; req.sig = FALSE; req.handle = centralCharHdl; //属性0xFFE1的handle值 req.len = 1; req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0); //申请内存 if(req.pValue != NULL) { *req.pValue = centralCharVal; //发送数赋值 if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS) //启动写,判断返回值,0成功,非0失败 { centralProcedureInProgress = TRUE; centralDoWrite = !centralDoWrite; //成功,翻转自定义标志,下个任务启动read 读 tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY); //重新启动任务 } else { GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ); //失败,主动手动释放内存 } } } else //读read操作 { // Do a read attReadReq_t req; req.handle = centralCharHdl; //属性0xFFE1的handle值 if(GATT_ReadCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS) //读数据,并判断返回值,0成功,非0失败 { centralProcedureInProgress = TRUE; centralDoWrite = !centralDoWrite; //成功翻转自定义标志,下一次进行写write演示 } } } return (events ^ START_READ_OR_WRITE_EVT); }
if(events & START_WRITE_CCCD_EVT) //0xFFE4通道Notify通知 { if(centralProcedureInProgress == FALSE) { // Do a write attWriteReq_t req; req.cmd = FALSE; req.sig = FALSE; req.handle = centralCCCDHdl; //属性0xFFE4通道的Notify handle值 req.len = 2; req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0); //内存申请 if(req.pValue != NULL) { req.pValue[0] = 1; req.pValue[1] = 0; if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS) //发送 { centralProcedureInProgress = TRUE; } else { GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ); //释放内存 } } } return (events ^ START_WRITE_CCCD_EVT); }
其中最关键的是handle值,handle值获取的方法如下
case GAP_LINK_ESTABLISHED_EVENT: //连接建立以后 { tmos_stop_task(centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT); if(pEvent->gap.hdr.status == SUCCESS) { centralState = BLE_STATE_CONNECTED; centralConnHandle = pEvent->linkCmpl.connectionHandle; centralProcedureInProgress = TRUE; // Initiate service discovery tmos_start_task(centralTaskId, START_SVC_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY); //执行 START_SVC_DISCOVERY_EVT 任务 // See if initiate connect parameter update if(centralParamUpdate) { tmos_start_task(centralTaskId, START_PARAM_UPDATE_EVT, DEFAULT_PARAM_UPDATE_DELAY); } // See if start RSSI polling if(centralRssi) { tmos_start_task(centralTaskId, START_READ_RSSI_EVT, DEFAULT_RSSI_PERIOD); } PRINT("Connected...\n"); }
if(events & START_SVC_DISCOVERY_EVT) { // start service discovery centralStartDiscovery(); //执行handle值解析 return (events ^ START_SVC_DISCOVERY_EVT); }
static void centralStartDiscovery(void) { uint8_t uuid[ATT_BT_UUID_SIZE] = {LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)}; //设置服务的UUID // Initialize cached handles centralSvcStartHdl = centralSvcEndHdl = centralCharHdl = 0;//handle值全局变量,初始化0 centralDiscState = BLE_DISC_STATE_SVC; //设置状态 // Discovery simple BLE service 启动发现服务函数 GATT_DiscPrimaryServiceByUUID(centralConnHandle, uuid, ATT_BT_UUID_SIZE, centralTaskId); }
static void centralGATTDiscoveryEvent(gattMsgEvent_t *pMsg) { attReadByTypeReq_t req; if(centralDiscState == BLE_DISC_STATE_SVC) //上面这个函数刚刚置这个标志 { // Service found, store handles if(pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->msg.findByTypeValueRsp.numInfo > 0) { centralSvcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0); centralSvcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0); // Display Profile Service handle range PRINT("Found Profile Service handle : %x ~ %x \n", centralSvcStartHdl, centralSvcEndHdl); //服务handle范围 } // If procedure complete if((pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->hdr.status == bleProcedureComplete) || (pMsg->method == ATT_ERROR_RSP)) { if(centralSvcStartHdl != 0) { // Discover characteristic centralDiscState = BLE_DISC_STATE_CHAR; req.startHandle = centralSvcStartHdl; req.endHandle = centralSvcEndHdl; req.type.len = ATT_BT_UUID_SIZE; req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID); //准备获取0xFFE1的handle值 GATT_ReadUsingCharUUID(centralConnHandle, &req, centralTaskId); } } } else if(centralDiscState == BLE_DISC_STATE_CHAR) { // Characteristic found, store handle if(pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0) { centralCharHdl = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[0], pMsg->msg.readByTypeRsp.pDataList[1]); // Start do read or write tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY); // Display Characteristic 1 handle PRINT("Found Characteristic 1 handle : %x \n", centralCharHdl); //0xFFE1的handle值 } if((pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->hdr.status == bleProcedureComplete) || (pMsg->method == ATT_ERROR_RSP)) { // Discover characteristic centralDiscState = BLE_DISC_STATE_CCCD; req.startHandle = centralSvcStartHdl; req.endHandle = centralSvcEndHdl; req.type.len = ATT_BT_UUID_SIZE; req.type.uuid[0] = LO_UINT16(GATT_CLIENT_CHAR_CFG_UUID); req.type.uuid[1] = HI_UINT16(GATT_CLIENT_CHAR_CFG_UUID); GATT_ReadUsingCharUUID(centralConnHandle, &req, centralTaskId); } } else if(centralDiscState == BLE_DISC_STATE_CCCD) { // Characteristic found, store handle if(pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0) { centralCCCDHdl = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[0], pMsg->msg.readByTypeRsp.pDataList[1]); centralProcedureInProgress = FALSE; // Start do write CCCD tmos_start_task(centralTaskId, START_WRITE_CCCD_EVT, DEFAULT_WRITE_CCCD_DELAY); // Display Characteristic 1 handle PRINT("Found client characteristic configuration handle : %x \n", centralCCCDHdl); //获取notify 0xFFE4通道的handle值 } centralDiscState = BLE_DISC_STATE_IDLE; } }