首页 > 代码库 > BLE固件开发--如何获取当前连接状态

BLE固件开发--如何获取当前连接状态

    在一个 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变量来实时获取当前的连接状态了。

BLE固件开发--如何获取当前连接状态