TI中文支持网
TI专业的中文技术问题搜集分享网站

关于simpleGATTprofile的Characteristic

simpleGATTprofile中有5个Characteristic,第4个需要启用通知才能收到,在simpleBLECentral工程中,当启用通知后,是在哪里收到数据?

求各位大神指教。

bamboo:

回复 Yan:

使能通知是向handle为0x002f写入0x0001

gattPrepareWriteReq_t req;                

req.handle = 0x002f;        

req.len = 2;        

req.pValue[0] = 0x00;        

req.pValue[1] = 0x01;        

 req.offset = 0;        

GATT_WriteLongCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );

但还是无法收到?

Yan:

回复 bamboo:

Hi x, 

首先请确定你找的handle是正确的. 这个handle应该是相应的characteristic value的handle的后面一个, 就是characteristic valude的handle加 1 .

另外, 你的 req.pValue 填错了, 上下两个请反一下.

最后, 这里不要用write long, 用一般的写就行, 就两个字节的内容.

下面是个例子:

attWriteReq_t writeReq;

writeReq.handle = 0x002f;

writeReq.len = 2;

writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY);        这里是 0x01

writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);          这里是 0x00

writeReq.sig = 0;

writeReq.cmd = 0;

GATT_WriteCharValue( simpleBLEConnHandle, &writeReq, simpleBLETaskId );

xie weiping:

回复 Yan:

Hi Yan,

notification发送和接收都是在第四通道channel 4吗?

在simpleBLEcenter例子程序里有个按键触发读写的代码:     

 // Do a read or write as long as no other read or write is in progress      if ( simpleBLEDoWrite )      {        // Do a write        attWriteReq_t req;                req.handle = simpleBLECharHdl;        req.len = 1;        req.value[0] = simpleBLECharVal;        req.sig = 0;        req.cmd = 0;        status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );               }

 simpleBLECharHdl 应该是第一通道 channel 1的句柄吧。

 req.value[0] = simpleBLECharVal应该是要发送的值。

跟踪发现句柄获得,其中句柄simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0],                                       pMsg->msg.readByTypeRsp.dataList[1] );

那我该如何获得第四通道数据的句柄?

还有你上面notification的例子怎么是

writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY);        这里是 0x01

writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);          这里是 0x00

notification的要发送的值写在哪里呢?比如我要发送一个数值0xFF,我该怎么用notification发送?

谢谢!

Yan:

回复 xie weiping:

Hi xie,

你说的channel是什么? 第四个channel说的是第四个characteristic?

simpleBLECharHdl这里必须是你对应的characteristic的CCC的那个句柄. CCC指的是Client Characteristic Configuration 的这个descriptor.

CCC句柄一般是在characteristic value的句柄后面.

句柄的顺序是characteristic declaration, characteristic  value, 然后是 CCC.

你这个0xFF的value就填写在simpleBLECharVal里面啊.

xie weiping:

回复 Yan:

Hi Yan,

我还是不懂,我说的channel是指

// Profile Parameters#define SIMPLEPROFILE_CHAR1                   0  // RW uint8 – Profile Characteristic 1 value #define SIMPLEPROFILE_CHAR2                   1  // RW uint8 – Profile Characteristic 2 value#define SIMPLEPROFILE_CHAR3                   2  // RW uint8 – Profile Characteristic 3 value#define SIMPLEPROFILE_CHAR4                   3  // RW uint8 – Profile Characteristic 4 value#define SIMPLEPROFILE_CHAR5                   4  // RW uint8 – Profile Characteristic 4 value

第四个SIMPLEPROFILE_CHAR4 是GATT profile的第四个值,他是一个可以通过通知发送给GATT客户端设备。

在simpleBLEcenter例子程序中有一段按键读写第一个SIMPLEPROFILE_CHAR1的值的代码,如下:

// Do a read or write as long as no other read or write is in progress      if ( simpleBLEDoWrite )      {        // Do a write        attWriteReq_t req;                req.handle = simpleBLECharHdl;        req.len = 1;        req.value[0] = simpleBLECharVal;        req.sig = 0;        req.cmd = 0;        status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );               }      else      {        // Do a read        attReadReq_t req;                req.handle = simpleBLECharHdl;        status = GATT_ReadCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );      }

这段代码很好理解,SIMPLEPROFILE_CHAR1的句柄和value值都在代码中体现了。

但是notification的代码我就很难理解,句柄和value值还有0x01和0x00(

writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY);        这里是 0x01

writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);          这里是 0x00

)

不明白什么意思。

Yan:

回复 xie weiping:

writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY);        这里是 0x01

writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);          这里是 0x00

我之前解释可能有误, 没给你讲清楚.

这两个值目的是打开Notification功能. CCC的参数有两个, 一个Notification, 一个indication. value[0]就是打开关闭notification, value[1]是打开关闭indication.

至于接下来notification发的值是什么, 其实就是对应的characteristic value. 

你有空最好去看一下协议栈对spec的定义, 我这样告诉你也只是很少的比较片面的协议栈定义里面的一些内容, 如果你要更好地理解, 最好去看一下spec.

你也可以看上面的教学视频, 也可以看上面的深度培训文档,

最好是可以去blueooth sig 官网上下载spec:

https://www.bluetooth.org/en-us/specification/adopted-specifications

其中第三章 volume 3  Core System Package 里面的 part G: GENERIC ATTRIBUTE PROFILE (GATT) 里面的第三章 3 SERVICE INTEROPERABILITY REQUIREMENTS, 这里面有很详细的介绍 service, characteristic 定义的内容.

里面的 3.3.3.3, 就是Client Characteristic Configuration 

xie weiping:

回复 Yan:

好的,非常感谢!

我还想问一下,simpleBLEcenter例子程序中,有个simpleBLECharHdl 句柄的获得,这个句柄应该是SIMPLEPROFILE_CHAR1的句柄吧             

simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0],                                       pMsg->msg.readByTypeRsp.dataList[1] );

这段什么意思呢?dataList[0],dataList[1]代表什么?假如我想获得其他SIMPLEPROFILE_CHAR的句柄该如何获得呢?比如SIMPLEPROFILE_CHAR2、SIMPLEPROFILE_CHAR3等。

谢谢!

Yan:

回复 xie weiping:

是的.

如果你仔细看代码, 就应该不难看出, 这里有个状态机.

前面的状态里面的代码:

req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID); req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID);

GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId );

就是用来查找SIMPLEPROFILE_CHAR1的句柄的.

你贴的代码就是状态机进入到找到这个句柄后的状态.

dagaList, 你如果也仔细看代码的话, 这个就是peripheral那边回复过来的具体数据, 这里就是句柄.

如果你要查找SIMPLEPROFILE_CHAR2,或者SIMPLEPROFILE_CHAR3, 你可以简单替换掉前面状态机里面(就是我上面贴的代码)的查找参数.

更好的方法是你在原先的状态机里面多添加几个状态, 在查找玩CHAR1之后添加查找CHAR2, CHAR3, 等等. 也很方便, 不难.

bamboo:

回复 Yan:

在收到CHAR1的handle后立刻查找其他特征值的handle,会找不到

else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR )

{

。。。

//simpleBLEDiscState = BLE_DISC_STATE_IDLE;

接着查找

if ( simpleBLESvcStartHdl != 0 )      

 {        

// Discover characteristic         simpleBLEDiscState = BLE_DISC_STATE_CHAR6;                

 req.startHandle = simpleBLESvcStartHdl;        

req.endHandle = simpleBLESvcEndHdl;        

req.type.len = ATT_BT_UUID_SIZE;        

req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR6_UUID);        

req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR6_UUID);

GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId );                

LCD_WRITE_STRING( "Finding", HAL_LCD_LINE_1 );      

}

}

else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR6 )  

 {    

 // Characteristic found, store handle    

if ( pMsg->method == ATT_READ_BY_TYPE_RSP &&          pMsg->msg.readByTypeRsp.numPairs > 0 )    

{      

 simpleBLECharHd6 = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0],                                       

pMsg->msg.readByTypeRsp.dataList[1] );            

LCD_WRITE_STRING( "CHAR6 Found", HAL_LCD_LINE_1 );          

 }    

simpleBLEDiscState = BLE_DISC_STATE_IDLE;  

}

如果不马上查找就可以,请问是哪里有问题?

 

 

赞(0)
未经允许不得转载:TI中文支持网 » 关于simpleGATTprofile的Characteristic
分享到: 更多 (0)