如题,GATT_DiscAllCharDescs()有两个参数分别是starting handle和ending handle。请问ending handle一般都是怎么确定的?
Susan Yang:
关于该函数的说明您可以看一下
http://dev.ti.com/tirex/content/simplelink_cc2640r2_sdk_1_50_00_58/docs/blestack/ble_user_guide/doxygen/ble/html/group___a_t_t___g_a_t_t.html#ga6d111c5d5b479a10ef92b900481b3027
ATT_FindInfoReq is used with the Starting Handle set to starting handle of the specified characteristic and the Ending Handle set to the ending handle of the specified characteristic. The UUID Filter parameter is NULL (zero length).
另外建议您看一下之前的帖子
http://www.deyisupport.com/question_answer/wireless_connectivity/bluetooth/f/103/t/109297.aspx
Alvin Chen:
回复 Susan Yang:
static uint8 TimeAppDiscDstChg( uint8 state, gattMsgEvent_t *pMsg ) {uint8 newState = state;switch ( state ){case DISC_DST_CHG_START:{uint8 uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(NEXT_DST_CHANGE_SERV_UUID),HI_UINT16(NEXT_DST_CHANGE_SERV_UUID) };// Initialize service discovery variablestimeAppSvcStartHdl = timeAppSvcEndHdl = 0;timeAppEndHdlIdx = 0;// Discover service by UUIDGATT_DiscPrimaryServiceByUUID( timeAppConnHandle, uuid,ATT_BT_UUID_SIZE, timeAppTaskId );newState = DISC_DST_CHG_SVC;}break;case DISC_DST_CHG_SVC:// Service found, store handlesif ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&pMsg->msg.findByTypeValueRsp.numInfo > 0 ){timeAppSvcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);timeAppSvcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);}// If procedure completeif ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP&&pMsg->hdr.status == bleProcedureComplete ) ||( pMsg->method == ATT_ERROR_RSP ) ){// If service foundif ( timeAppSvcStartHdl != 0 ){// Discover all characteristicsGATT_DiscAllChars( timeAppConnHandle, timeAppSvcStartHdl,timeAppSvcEndHdl, timeAppTaskId );newState = DISC_DST_CHG_CHAR;}else{// Service not foundnewState = DISC_FAILED;}}break;case DISC_DST_CHG_CHAR:{uint8i;uint8*p;uint16handle;uint16uuid;// Characteristics foundif ( pMsg->method == ATT_READ_BY_TYPE_RSP &&pMsg->msg.readByTypeRsp.numPairs > 0 &&pMsg->msg.readByTypeRsp.len == CHAR_DESC_HDL_UUID16_LEN){// For each characteristic declarationp = pMsg->msg.readByTypeRsp.pDataList;for ( i = pMsg->msg.readByTypeRsp.numPairs; i > 0; i-- ){// Parse characteristic declarationhandle = BUILD_UINT16(p[3], p[4]);uuid = BUILD_UINT16(p[5], p[6]);// If UUID is of interest, store handleswitch ( uuid ){case TIME_WITH_DST_UUID:timeAppHdlCache[HDL_DST_CHG_TIME_DST] = handle;break;default:break;}p += CHAR_DESC_HDL_UUID16_LEN;}}// If procedure completeif ( ( pMsg->method == ATT_READ_BY_TYPE_RSP&&pMsg->hdr.status == bleProcedureComplete ) ||( pMsg->method == ATT_ERROR_RSP ) ){// If didn't find DST characteristicif ( timeAppHdlCache[HDL_DST_CHG_TIME_DST] == 0 ){newState = DISC_FAILED;}else{newState = DISC_IDLE;}}}break;default:break;}return newState; }/********************************************************************** @fnTimeAppDiscRefTime()** @briefReference time service and characteristic discovery.** @paramstate - Discovery state.* @parampMsg - GATT message.** @returnNew discovery state.*/ static uint8 TimeAppDiscRefTime( uint8 state, gattMsgEvent_t *pMsg ) {uint8 newState = state;switch ( state ){case DISC_REF_TIME_START:{uint8 uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(REF_TIME_UPDATE_SERV_UUID),HI_UINT16(REF_TIME_UPDATE_SERV_UUID) };// Initialize service discovery variablestimeAppSvcStartHdl = timeAppSvcEndHdl = 0;timeAppEndHdlIdx = 0;// Discover service by UUIDGATT_DiscPrimaryServiceByUUID( timeAppConnHandle, uuid,ATT_BT_UUID_SIZE, timeAppTaskId );newState = DISC_REF_TIME_SVC;}break;case DISC_REF_TIME_SVC:// Service found, store handlesif ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&pMsg->msg.findByTypeValueRsp.numInfo > 0 ){timeAppSvcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);timeAppSvcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0);}// If procedure completeif ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP&&pMsg->hdr.status == bleProcedureComplete ) ||( pMsg->method == ATT_ERROR_RSP ) ){// If service foundif ( timeAppSvcStartHdl != 0 ){// Discover all characteristicsGATT_DiscAllChars( timeAppConnHandle, timeAppSvcStartHdl,timeAppSvcEndHdl, timeAppTaskId );newState = DISC_REF_TIME_CHAR;}else{// Service not foundnewState = DISC_FAILED;}}break;case DISC_REF_TIME_CHAR:{uint8i;uint8*p;uint16handle;uint16uuid;// Characteristics foundif ( pMsg->method == ATT_READ_BY_TYPE_RSP &&pMsg->msg.readByTypeRsp.numPairs > 0 &&pMsg->msg.readByTypeRsp.len == CHAR_DESC_HDL_UUID16_LEN){// For each characteristic declarationp = pMsg->msg.readByTypeRsp.pDataList;for ( i = pMsg->msg.readByTypeRsp.numPairs; i > 0; i-- ){// Parse characteristic declarationhandle = BUILD_UINT16(p[3], p[4]);uuid = BUILD_UINT16(p[5], p[6]);// If UUID is of interest, store handleswitch ( uuid ){case TIME_UPDATE_CTRL_PT_UUID:timeAppHdlCache[HDL_REF_TIME_UPD_CTRL] = handle;break;case TIME_UPDATE_STATE_UUID:timeAppHdlCache[HDL_REF_TIME_UPD_STATE] = handle;break;default:break;}p += CHAR_DESC_HDL_UUID16_LEN;}}// If procedure completeif ( ( pMsg->method == ATT_READ_BY_TYPE_RSP&&pMsg->hdr.status == bleProcedureComplete ) ||( pMsg->method == ATT_ERROR_RSP ) ){// If didn't find mandatory characteristicsif ( timeAppHdlCache[HDL_REF_TIME_UPD_CTRL] == 0 ||timeAppHdlCache[HDL_REF_TIME_UPD_STATE] == 0 ){newState = DISC_FAILED;}else{newState = DISC_IDLE;}}}break;default:break;}return newState; }该程序是TImeApp 你可以看一下完整的工程。
goodluck:
回复 Susan Yang:
非常感谢回答。
前一个链接介绍的内容跟core spec里面说的差不多,可惜都只是介绍了参数的意义而没有获取参数的方式。
后一个链接感觉有点靠谱了。不过那个程序似乎是在discover characteristic的时候,用所关心的characteristic后面的那个characteristic的declaration handle减1来作为ending handle。如果所关心的characteristic本身就是最后一个,或者干脆service里面就只有一个characteristic的话,是不是就行不通了呢?
如果我希望服务发现的过程能够有比较好的兼容性,不知道有没有更完善的解决方法。。。
goodluck:
回复 Alvin Chen:
非常感谢回答。
不知道TimeApp是哪个工程,不过这段程序里面好像并没有discover descriptor的步骤啊。。。
goodluck:
看来没有简便的方法准确地确定一个合适的ending handle值。不妨设为一个比较大的值(比如0xFFFF),然后在返回结果里面过滤自己感兴趣的descriptor吧。
参考:https://e2e.ti.com/support/wireless_connectivity/bluetooth_low_energy/f/538/t/305025