GATT_Notification vs. GATTServApp_ProcessCharCfg

A:Notification连接后,从机向主机发送的数据包,不需要主机确认收到,适合大量数据快速发送。
从机 Notification发送方式有两种,用户根据自身要求选择:
(1)调用GATT_Notification( uint16 connHandle, attHandleValueNoti_t *pNoti, uint8 authenticated );直接发送
(2)调用GATTServApp_ProcessCharCfg函数,这个函数内部最终会导致master那边调用一个read请求,回调到simpleProfile_ReadAttrCB()。用这个函数,只有master向Peripheral的Notification允许位写1,才能使能从机,从而调用GATT_Notification向主机发送Notification。

//声明attHandleValueNoti_t这个结构体
static attHandleValueNoti_t pReport ;
//存放handle
uint16 noti_cHandle; 
//读取notification对应的handle
pReport.handle = simpleProfileAttrTbl[11].handle;
//获取Connection Handle
GAPRole_GetParameter( GAPROLE_CONNHANDLE, &noti_cHandle);
pReport.len = 1;            //数据长度
pReport.value[0] = 0x03;    //赋值
GATT_Notification(noti_cHandle,&pReport,FALSE);
//!< Connection Handle. Read Only. Size is uint16.
#define GAPROLE_CONNHANDLE          0x30E 
//eg: 
GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );

simpleBLECentral
1、添加notification的接收
simpleBLECentralProcessGATTMsg()
类似
if ( ( pMsg->method == ATT_READ_RSP ) || ........)
添加
else if ( ( pMsg->method == ATT_HANDLE_VALUE_NOTI ) ||......)

2、启用notification
simpleProfileAttrTbl 的位置12 是CHAR4 的Client Characteristic Configuration, 发Notification 之前, 通过master设备把这个值设置成 0x0001, 打开notification.这个handle应该是相应的characteristic value的handle的后面一个, 就是characteristic value的handle加 1 .

attWriteReq_t writeReq;
writeReq.handle = 0x002f;
writeReq.len = 2;
writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY);        //这里是 0x01
writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);        //这里是 0x00
writeReq.sig = 0;
writeReq.cmd = 0;
GATT_WriteCharValue( simpleBLEConnHandle, &writeReq, simpleBLETaskId );

这两个值目的是打开Notification功能. CCC的参数有两个, 一个Notification, 一个indication. value[0]就是打开关闭notification, value[1]是打开关闭indication.

3、使用UUID获取simpleBLEConnHandle
a. simpleBLECentralStartDiscovery
b. simpleBLECentralProcessGATTMsg
-> simpleBLEGATTDiscoveryEvent

static void simpleBLECentralStartDiscovery( void )
{
  uint8 uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(SIMPLEPROFILE_SERV_UUID),
                                   HI_UINT16(SIMPLEPROFILE_SERV_UUID) };

  // Initialize cached handles
  simpleBLESvcStartHdl = simpleBLESvcEndHdl = simpleBLECharHdl = 0;

  simpleBLEDiscState = BLE_DISC_STATE_SVC;

  // Discovery simple BLE service
  GATT_DiscPrimaryServiceByUUID( simpleBLEConnHandle,
                                 uuid,
                                 ATT_BT_UUID_SIZE,
                                 simpleBLETaskId );
}

static void simpleBLEGATTDiscoveryEvent( gattMsgEvent_t *pMsg )
{
  attReadByTypeReq_t req;

  if ( simpleBLEDiscState == BLE_DISC_STATE_SVC )
  {
    // Service found, store handles
    if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
         pMsg->msg.findByTypeValueRsp.numInfo > 0 )
    {
      simpleBLESvcStartHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle;
      simpleBLESvcEndHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;
    }

    // If procedure complete
    if ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP  && 
           pMsg->hdr.status == bleProcedureComplete ) ||
         ( pMsg->method == ATT_ERROR_RSP ) )
    {
      if ( simpleBLESvcStartHdl != 0 )
      {
        // Discover characteristic
        simpleBLEDiscState = BLE_DISC_STATE_CHAR;

        req.startHandle = simpleBLESvcStartHdl;
        req.endHandle = simpleBLESvcEndHdl;
        req.type.len = ATT_BT_UUID_SIZE;
        req.type.uuid[0] = LO_UINT16(SIMPLEPROFILE_CHAR1_UUID);
        req.type.uuid[1] = HI_UINT16(SIMPLEPROFILE_CHAR1_UUID);

        GATT_ReadUsingCharUUID( simpleBLEConnHandle, &req, simpleBLETaskId );
      }
    }
  }
  else if ( simpleBLEDiscState == BLE_DISC_STATE_CHAR )
  {
    // Characteristic found, store handle
    if ( pMsg->method == ATT_READ_BY_TYPE_RSP && 
         pMsg->msg.readByTypeRsp.numPairs > 0 )
    {
      simpleBLECharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.dataList[0],
                                       pMsg->msg.readByTypeRsp.dataList[1] );

      LCD_WRITE_STRING( "Simple Svc Found", HAL_LCD_LINE_1 );
      simpleBLEProcedureInProgress = FALSE;
    }

    simpleBLEDiscState = BLE_DISC_STATE_IDLE;


  }    
}

simpleBLEPeripheral
simpleGATTProfile.c
里面有个SimpleProfile_SetParameter(), 这个就是间隔性被调用的函数.里面有
case SIMPLEPROFILE_CHAR4:
调用
GATTServApp_ProcessCharCfg()
这个函数内部最终会回调到
simpleProfile_ReadAttrCB()

1、SimpleProfile_SetParameter

SimpleProfile_SetParameter( uint8 param, uint8 len, void *value ){
    case SIMPLEPROFILE_CHAR4:
      if ( len == sizeof ( uint8 ) )
      {
        simpleProfileChar4 = *((uint8*)value);

        // See if Notification has been enabled
        GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,
                                    simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                    INVALID_TASK_ID );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;
}

2、simpleProfile_ReadAttrCB()

simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
                            uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen ){
      case SIMPLEPROFILE_CHAR4_UUID:
        *pLen = 1;
        pValue[0] = *pAttr->pValue;
        break;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值