因为学习BLE协议栈的过程中,对句柄没搞太明白,尤其是看到有些二次开发的代码直接使用了数字赋给句柄,进行数据收发,感到不解。网上搜索也没有找到相应的说明,那么在自己有了一些些了解之后,就将其记录下来,也许能帮助到其它人。
首先抛出从机发送数据函数的代码,在函数中使用了GATT_Notification()函数也就是通知函数来发送数据,函数的第一个参数是不是也疑惑为什么是0?那是因为这是连接句柄,主机因为只有一个,连接句柄为0,如果是主机发给从机就不能直接写为0了,因为一个主机最多可以连接3个从机,当然,主机发给从机并不使用这个通知函数。第二个参数需要先赋值,可以看到句柄直接被赋值为了0x35,这里就是我开头说的比较疑惑的地方。
// 发送数据到主机----使用自定义的CHAR6
void simpleBLE_SendData(uint8* buffer, uint8 sendBytes)
{
if( GAPROLE_CONNECTED == gapProfileState) // 已连接上
{
#if 0// 直接通过串口返回
NPI_WriteTransport(buffer, sendBytes);
#else// 通过CHAR6 特征值发送出去, 这里有两种方法
#if 0 // 这种速度慢 SimpleProfile_SetParameter
//simpleBLEChar6DoWrite2 = FALSE;
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR6,sendBytes, buffer );
#else // 这种速度快 GATT_Notification
static attHandleValueNoti_t pReport;
pReport.len = sendBytes;
pReport.handle = 0x0035;
osal_memcpy(pReport.value, buffer, sendBytes);
GATT_Notification( 0, &pReport, FALSE );
#endif
#endif
}
else
{
NPI_WriteTransport("Not Connected\r\n", 15);
}
}
那么这个0x35怎么来的呢?TI的协议栈安装完后,文档部分有一个软件开发手册(TI_BLE_Software_Developer's_Guide),在这个手册的3.4.5小节(我的PDF打开是23页),可以看到如下的表格:
在表格中可以看到TI提供的协议栈例程中,特征值1的句柄是0x0025,UUID是0xFFF1,特征值2的句柄是0x0028,特征值3是0x002B,特征值4是0x002E,特征值5是0x0032。乍一看以为每个特征值后一个的句柄比前一个加3?不是的,有的是加4,这主要和属性表有关。属性表中如果权限是通知,会比读写多一个config,读写在属性表中有3个条目的话,通知就是4个。
那么,如果我们增加特征值6,权限设为可读可写以及通知,它的UUID我们就可以设为0xFFF6,句柄也就是0x0035,因为特征值5是加密读,属性表中只有3个条目,所以0x0032加3也就是0x0035,这就是0x0035的来源。以此类推,再添加特征值7的话就会是0x0039,加4,因为特征值6的权限包含了通知,属性表中多了一个config条目。
属性表内容如下(添加了特征值6,TI例程特征值为1~5):
static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
{
// Simple Profile Service
{
{ ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8 *)&simpleProfileService /* pValue */
},
// Characteristic 1 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar1Props
},
// Characteristic Value 1
{
{ ATT_BT_UUID_SIZE, simpleProfilechar1UUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
&simpleProfileChar1
},
// Characteristic 1 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar1UserDesp
},
// Characteristic 2 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar2Props
},
// Characteristic Value 2
{
{ ATT_BT_UUID_SIZE, simpleProfilechar2UUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar2
},
// Characteristic 2 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar2UserDesp
},
// Characteristic 3 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar3Props
},
// Characteristic Value 3
{
{ ATT_BT_UUID_SIZE, simpleProfilechar3UUID },
GATT_PERMIT_WRITE,
0,
&simpleProfileChar3
},
// Characteristic 3 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar3UserDesp
},
// Characteristic 4 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar4Props
},
// Characteristic Value 4
{
{ ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
0,
0,
&simpleProfileChar4
},
// Characteristic 4 configuration
{
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8 *)simpleProfileChar4Config
},
// Characteristic 4 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar4UserDesp
},
// Characteristic 5 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar5Props
},
// Characteristic Value 5
{
{ ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
GATT_PERMIT_AUTHEN_READ,
0,
simpleProfileChar5
},
// Characteristic 5 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar5UserDesp
},
// Characteristic 6 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar6Props
},
// Characteristic Value 6
{
{ ATT_BT_UUID_SIZE, simpleProfilechar6UUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
simpleProfileChar6
},
// Characteristic 6 configuration
{
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8 *)simpleProfileChar6Config
},
// Characteristic 6 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar6UserDesp
},
};