已经开始广播了,广播名字修改的问题
CC2540通过I2C连接了一个温度计,我希望温度升高超过警报值时,CC2540可以改变名字,这样即使不连接也可以看到名字的变化
程序用SimplePeripheral改的,目前的情况是我用热风吹温度计时,处理函数可以闪烁LED,串口也可以输出相应信息, 但是没法改变设备的名字。
看了之前的两个贴
已经开始广播了,广播包数据能更改吗?
http://e2e.ti.com/support/wireless_connectivity/f/538/t/72681.aspx
我先修改了
case GAPROLE_ADVERT_DATA:
if ( len <= B_MAX_ADV_LEN )
{
VOID osal_memset( gapRole_AdvertData, 0, B_MAX_ADV_LEN );
VOID osal_memcpy( gapRole_AdvertData, pValue, len );
gapRole_AdvertDataLen = len;
GAP_UpdateAdvertisingData();
}
在温度事件处理函数里添加了 GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advertDisabled ); 来停掉广播
然后用GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN - 1, attDeviceName )修改了名字
最后用GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advertEnabled );来启用广播
可是实际应用时发现,运行完最后一步启用广播后,CC2540就重启了,请问问题可能出现在哪里呢?
另外我想知道,GAP_UpdateAdvertisingData()运行时,是更新了attDeviceName么?谢谢~~
Hi YY1
你修改的并非广播包数据,而是GAP GATT Server 中的设备名称,这个是需要在连接后访问对应的Server才能看的见的。
如果你想动态修改广播包数据,试试使用这个API:
GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ),advertData );
多谢回复!我现在很困惑,TI代码里面有定义scanRspData和attDeviceName两个,还有一个advertData
我用iPhone上安装的lightblue软件直接扫描,即使从来没连接过也可以看到attDeviceName,所以我想修改这个,是不是说明这个并不是要连接后才能看得见的?
scanRspData我看SWRU271里面介绍是当central device scan的时候,peripheral会回复这个,但是不清楚什么情况下手机能看到这个,有的例子里面把它叫做deviceName,我就更糊涂了
另外,advertData我看TI的guide上让去看Bluetooth 4.0的spec,可是搜索了一下也没有找到详尽的定义,请问你知道哪里有比较好的介绍么?
谢谢!
Hi YY1
1.LightBlue未连接就能看到attDeviceName是因为曾经连接过,会记住这些信息,等到连接后才会更新(需要在连接后访问Server);
2.扫描的过程是这样的:从机发送AdvData——>主机发送scanReq——>从机回应scanRspData。这个过程并不需要建立连接,所以scanRspData的数据可以在未连接时就能看到其动态更新,但是attDeviceName是需要连接后才可以看到更新的(需要访问Server)。
3.scanRspData中的设备名称叫做Local Name,是扫描数据的一部分。而attDeviceName是基于GAP GATT Server中的一个特定的Characteristic。如果你觉得麻烦可以将这两个设为一样的值。
4.scanRspData支持动态更新,所以Local Name也支持动态更新。attDeviceName我就没有试过,我觉得应该也可以的。
多谢指导!现在清楚很多了,我该改的应当是scanRspData
那就不需要在case GAPROLE_ADVERT_DATA:下面加入GAP_UpdateAdvertisingData()了对吧?
我刚刚在又试了一下,先用GAPRole_SetParameter()关掉了广播;
改了scanRspData,用GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA )设置scanRspData;
最后GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advertEnabled )开启了广播。
可是运行完最后一步之后CC2540就自动重启了,用串口打印显示又开始了SimpleBLEPeripheral_Init,我是不是漏掉了什么?
是第一次广播就重启?还是在广播中关闭广播,然后重新打开广播才重启的。
仔细检查下代码有没有什么漏洞吧。
还有检查下你的硬件有没问题。
不是第一次广播就重启,硬件应该没有问题
是广播中关闭广播时设备会重新init
// Stop advertising GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advertDisabled ); HalUARTWrite(0, "Stopped\n", 8); osal_memcpy(numberString, &scanRspData[9], 4); numberString[3] += 1; osal_memcpy(&scanRspData[9], numberString, 4); GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData ); HalUARTWrite(0, "Resumed\n", 8); // Start advertising GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advertEnabled ); HalUARTWrite(0, scanRspData, 13);
我从串口可以接收到更新后的scanRspData,但是紧跟着就是init程序的打印了
我试着把GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED)两行都注释掉,CC2540不会重启,是不是我关闭广播之后还有什么需要做的没有做?
调用API关闭广播可能不是立即就能停止的(这个需要TI专家才能证明,我只是猜测),广播关闭成功后底层会通过消息通知到任务中
uint16 GAPRole_ProcessEvent( uint8 task_id, uint16 events )。
广播关闭成功后,从机将进入新的状态,static void peripheralStateNotificationCB( gaprole_States_t newState )这个函数能跟踪当前的状态。
我的意思就是你关闭到开启能否不做在一起呢?毕竟底层的API并非如同MCU的寄存器会立即生效。不过我也不清楚为何这样会导致CC2540重启,没遇到这样的情况。