hi,各位大牛!
请问一下,在定义Profile Attributes的时候为什么把handle都设置为0,client发送数据的时候handle该如何确定。
/*********************************************************************
* Profile Attributes – Table
*/
static gattAttribute_t accelAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] ={
// Accelerometer Service
{ { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8 *)&accelService /* pValue */
},
// Accel Enabler Characteristic Declaration
{ { ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ, 0,
&accelEnabledCharProps },
…….
}
在Btools工具中,为什么Characteristic Read时需要填入Characteristic UUID,而Characteristic Write时需要填入Attribute Handle,该Attribute Handle怎么确定,在定义Profile Attributes时Handle都设为了0. Characteristic UUID和Attribute Handle都是标示属性的吗,两者有什么不同?
Yue TANG:
我的理解是,handle开始是不确定的,你可以尝试,不同的addservice顺序,handle就不一样。而UUID是SIG制定的,为了互操作性,它是确定的。 所以一般Client端会通过确定的UUID从server端获得感兴趣的characteristic(RSP中包含对应的Handle)。
看一下GlucoseCollector例子,这是一个central设备,看看它如何处理。
lee jason:
回复 Yue TANG:
那么按你的意思是不是必须线读一次characteristic获得对应的Handle之后,才能对该characteristic进行写操作,否则一开始并不知道handle号。
另外请教一下:
在GATT Server端通过 status = GATTServApp_RegisterService( accelAttrTbl, GATT_NUM_ATTRS( accelAttrTbl ), accel_ReadAttrCB, accel_WriteAttrCB, NULL );注册Server端的读写回调函数响应Client的读写操作, 那么GATT Client的读写函数是怎样。
typedef bStatus_t (*pfnGATTReadAttrCB_t)( uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen );
typedef bStatus_t (*pfnGATTWriteAttrCB_t)( uint16 connHandle, gattAttribute_t *pAttr, uint8 *pValue, uint8 len, uint16 offset );
这两个回调函数:pfnGATTReadAttrCB是通过pValue等数据填充好pAttr吗?pAttr会自动发送出去吗
相应的pfnGATTWriteAttrCB是将pAtrr中的数据放到pValue中然后有app解析吗?
lee jason:
回复 Yue TANG:
我不理解的是,既然UUID可以代表每个characteristic,那为什么还需要handle呢?而且是在写数据的时候才要。
lee jason:
回复 Yue TANG:
我看GlucoseCollector例子中,glucsevice.c中如下三个函数是干什么用的,没有看到在项目中其他文件中调用
bStatus_t Glucose_MeasSend( uint16 connHandle, attHandleValueNoti_t *pNoti, uint8 taskId )是不是用来发数据给GATT Client的?该函数的第一个参数connHandle如何获得?
bStatus_t Glucose_MeasSend( uint16 connHandle, attHandleValueNoti_t *pNoti, uint8 taskId ){ uint16 value = GATTServApp_ReadCharCfg( connHandle, glucoseMeasConfig ); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { // Set the handle pNoti->handle = glucoseAttrTbl[GLUCOSE_MEAS_VALUE_POS].handle; // Send the Indication return GATT_Notification( connHandle, pNoti, FALSE ); } return bleNotReady; }
bStatus_t Glucose_ContextSend( uint16 connHandle, attHandleValueNoti_t *pNoti, uint8 taskId )
bStatus_t Glucose_CtlPntIndicate( uint16 connHandle, attHandleValueInd_t *pInd, uint8 taskId )