【BLE4.0】CC2541从机之notify通知

一、简介

本篇介绍从机端的notify通知的两种方式,以及主机端是如何处理notify通知的


二、实验平台

协议栈版本:BLE-CC254x-1.4.0

编译软件:IAR 8.20.2

硬件平台:Smart RF开发板

 

三、简介notify通知的两种方式

1、GATT_Notification

在从机代码中使用,由从机主动通知,且不需要主机发出请求和回应。


2、GATTServApp_ProcessCharCfg

在从机代码中使用,需要主机发送一次“通知请求”给从机,从机收到“通知请求”才发送通知。

实际上这个函数里依然会调用GATT_Notification这个函数。

四、使用notify通知时的注意事项

无论是GATT_Notification,还是GATTServApp_ProcessCharCfg,都需要在定义特征值时比read、write方式的配置多一条

static gattCharCfg_t simpleProfileChar3Config[GATT_MAX_NUM_CONN];


 

例如,需要用到char4特征值通知时,需要打开char4的通知开关,也就是要向属性表中0x2F写入0x0001进行开通知。

其中0x2F就是指向

// Characteristic 4 configuration

{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE, 
0, 
(uint8 *)simpleProfileChar3Config 
},

注:直接往simpleProfileChar3Config里写0x0001开通知开关也是可行的,但尽量保证这个开关由主机来开会比较合理。

 

五、GATT_Notification范例

本范例是我自己写的,通过按下按键S1,通知发送0x01,松手发送0x00

 

按键中调用notify通知的函数(SimpleBLEPeripheral.c中)

 {
   if(KEY ==  1)
   {
 

     uint8 charValue3 = 1;
     SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, sizeof ( uint8 ), &charValue3 );
   }
   else
   {
     uint8 charValue3 = 0;
     SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, sizeof ( uint8 ), &charValue3 );
     
   }
 }

 

  SimpleProfile_SetParameter部分函数如下:

 

   case SIMPLEPROFILE_CHAR3:
      if ( len == sizeof ( uint8 ) )
      {
        simpleProfileChar3 = *((uint8*)value);
        linkDB_PerformFunc( BUTTONNotifyCB );
#if 0
     //  linkDB_PerformFunc(RSSINotifyCB);
       GAPRole_GetParameter( GAPROLE_CONNHANDLE, &connHandle);                //获取
       value0  = GATTServApp_ReadCharCfg( connHandle, simpleProfileChar3Config );//读出CCC的值 
       if ( value0 & GATT_CLIENT_CFG_NOTIFY ) //判断是否打开通知开关,打开了则发送数据  
       {
 
        attHandleValueNoti_t noti;
        noti.handle = simpleProfileAttrTbl[8].handle ;
        noti.len = len;
        osal_memcpy((uint8*)noti.value, (uint8 *)&simpleProfileChar3, len);
        VOID GATT_Notification( 0, ¬i, FALSE);    
       }
#endif      
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

每次发送数据的时候需要知道连接的handle 如上面所示:

第一种办法:

1./*********************************************************************
 * @fn          battNotifyCB
 *
 * @brief       Send a notification of the level state characteristic.
 *
 * @param       connHandle - linkDB item
 *
 * @return      None.
 */
 void BUTTONNotifyCB( linkDBItem_t *pLinkItem )
{
  if ( pLinkItem->stateFlags & LINK_CONNECTED )
  {
    uint16 value = GATTServApp_ReadCharCfg( pLinkItem->connectionHandle,
                                            simpleProfileChar3Config );
    if ( value & GATT_CLIENT_CFG_NOTIFY )
    {
        attHandleValueNoti_t noti;
        noti.handle = simpleProfileAttrTbl[8].handle ;
        noti.len = 1;
        osal_memcpy((uint8*)noti.value, (uint8 *)&simpleProfileChar3, 1);
        VOID GATT_Notification( 0, ¬i, FALSE);    
    }
  }
}

2.调用  linkDB_PerformFunc( BUTTONNotifyCB ); 可以获得当前连接的所以数据数据。

然后在判断这个handle有没有被主机使能。能使了就可以发送通知了

第二种办法:

GAPRole_GetParameter( GAPROLE_CONNHANDLE, &connHandle);               

直接调用这个获取当前连接的handle,然后在判断这个handle有没有被主机使能。能使了就可以发送通知了

第三种办法:

   case SIMPLEPROFILE_CHAR3:

        GATTServApp_ProcessCharCfg( simpleProfileChar4Config, (uint8 *)&simpleProfileChar3, FALSE,
                                    simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                    INVALID_TASK_ID );

break;

调用 GATTServApp_ProcessCharCfg();函数发送数据给主机

 


注:参考了 @

feilusia的博客

 

你可能感兴趣的:(蓝牙4.0基础问题)