在一个 BLE开发项目中,我采用的是TI的CC2541蓝牙BLE SoC,为了防止主从设备连接断开时数据丢失,硬件上加了一个EEPROM,当蓝牙建立连接时,通过Notify发给主机,但当蓝牙连接断开时,采集的数据要存储到EEPROM中(I2C),要实现这一点,需要实时获取蓝牙的连接状态。
在TI的BLE协议栈中,periperal.h中有如下定义:
/** * GAP Peripheral Role States. */ typedef enum { GAPROLE_INIT = 0, //!< Waiting to be started GAPROLE_STARTED, //!< Started but not advertising GAPROLE_ADVERTISING, //!< Currently Advertising GAPROLE_WAITING, //!< Device is started but not advertising, is in waiting period before advertising again GAPROLE_WAITING_AFTER_TIMEOUT, //!< Device just timed out from a connection but is not yet advertising, is in waiting period before advertising again GAPROLE_CONNECTED, //!< In a connection GAPROLE_CONNECTED_ADV, //!< In a connection + advertising GAPROLE_ERROR //!< Error occurred - invalid state } gaprole_States_t;以上枚举了从设备的几种状态,那么如何实时的获取gaprole_States_t的当前状态呢?该文件中后面由给出了一个定义:
/** * Callback structure - must be setup by the application and used when gapRoles_StartDevice() is called. */ typedef struct { gapRolesStateNotify_t pfnStateChange; //!< Whenever the device changes state gapRolesRssiRead_t pfnRssiRead; //!< When a valid RSSI is read from controller } gapRolesCBs_t;这个结构体上面的注释写的很清楚,必须在application层进行设置并在gapRoles_StartDevice()调用后使用。这里pfnStateChange成员变量是一个回调函数指针,用来处理相应状态变化下的操作。所以抓住这一点,也就实时获取到了从设备的连接状态变化。那么接下来我们只要在Application层定义一个pfnStateChange的回调函数并用来初始化一个gapRolesCBs_t的结构体即可。
回调函数定义如下:(gLinkStatus是自定义的一个变量,用来表示连接状态)
static void peripheralStateNotificationCB( gaprole_States_t newState ) { switch ( newState ) { case GAPROLE_STARTED: { uint8 ownAddress[B_ADDR_LEN]; uint8 systemId[DEVINFO_SYSTEM_ID_LEN]; GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress); // use 6 bytes of device address for 8 bytes of system ID value systemId[0] = ownAddress[0]; systemId[1] = ownAddress[1]; systemId[2] = ownAddress[2]; systemId[3] = ownAddress[3]; systemId[4] = ownAddress[4]; systemId[5] = ownAddress[5]; DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId); gLinkStatus=0; } break; case GAPROLE_ADVERTISING: gLinkStatus=0; break; case GAPROLE_CONNECTED: gLinkStatus=1; break; case GAPROLE_CONNECTED_ADV: gLinkStatus=0; break; case GAPROLE_WAITING: gLinkStatus=0; break; case GAPROLE_WAITING_AFTER_TIMEOUT: gLinkStatus=0; break; case GAPROLE_ERROR: gLinkStatus=0; break; default: break; } }然后用该回调函数初始化一个gapRolesCBs_t的结构体:
// GAP Role Callbacks static gapRolesCBs_t TemperatureSensor_PeripheralCBs = { peripheralStateNotificationCB, // Profile State Change Callbacks NULL // When a valid RSSI is read from controller (not used by application) };这样,在gapRoles_StartDevice()调用后(在应用层的任务处理函数中调用),便可以通过自定义的gLinkStatus变量来实时获取当前的连接状态了。
原文地址:http://blog.csdn.net/happytomyoung/article/details/42294175