微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI无线射频设计 > GATTServApp_ProcessCharCfg和 GATT_NOTIFICATION()区别

GATTServApp_ProcessCharCfg和 GATT_NOTIFICATION()区别

时间:12-23 整理:3721RD 点击:

大神们:

         GATTServApp_ProcessCharCfg(  )和GATT_Notification俩接口函数 流程是什么样子?

              GATT_Notification:是直接将数据发送给master?

              GATTServApp_ProcessCharCfg:最终会导致master那边调用一个read请求, 然后调用到keyfob这边的sk_ReadAttrCB()?

请指教。

Hi mac,

你说的正确.

你想用Notification的话最好用GATT_Notification(), 这个直接发送Notification, 不会像GATTServApp_ProcessCharCfg再会让master向slave去发送一个读的请求.

Yan

           我刚刚开始看CC2540相关的内容,假如我使用GATT_Notification()这个函数的话,我循环发送数据,在BTOOL上怎样才能看到效果呢?

hi rivers,

你会在BTool的接收窗口间隔性的看到收到的数据.

Hi Yan,

Notification 是用GATT_Notofication()发送的?

simpleBLEperipheral例子程序里是用SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof(uint8), &valueToCopy);这个函数吗?在周期函数里,每隔5秒发送notification啊?我找了一下没有找到用GATT_Notification()发送SIMPLEPROFILE_CHAR4啊?这是为什么呢?

谢谢!

hi xie,

请看 simpleGATTProfile.c, 

里面有个SimpleProfile_SetParameter(),  这个就是间隔性被调用的函数.

里面有 case SIMPLEPROFILE_CHAR4: 

调用 GATTServApp_ProcessCharCfg(...........................), 这个函数内部最终会回调到simpleProfile_ReadAttrCB(),

里面的下面代码会设置CHAR4的值.

case SIMPLEPROFILE_CHAR4_UUID:
*pLen = 1;
pValue[0] = *pAttr->pValue;
break;

最后, 如果notification是打开的, GATTServApp_ProcessCharCfg(...........................)内部会调用GATT_Notification().

都在内部封装好了, 所以你看不到, 但是过程是很清楚在那里的.

清楚了?

Hi Yan,

非常感谢!我清楚了。隐藏的太深,哈哈。流程有点复杂,我使用的时候可以直接调用GATT_Notification();发送Notification吗?而不走那么复杂的流程呢?谢谢!

xie,

可以, 直接用GATT_Notification()可以.

你好YAN,我也出现了这个问题,我不知道Notification中的handle应该是哪个handle?我就是想使用CHAR4这个UUID。

attHandleValueNoti_t noti;

noti.handle = simpleProfileAttrTbl[11].handle;
noti.len = 7;
noti.value[0] = "hello";

GATT_Notification( pLinkItem->connectionHandle, &noti, FALSE );

就是这个高亮这个应该怎么写呢?keyfob中发现是个连接的结构体,在Peripheral中有这中结构体吗?

还有就是value的值我可以这样赋值吗? 麻烦您了。。。

static void performPeriodicTask( void )
{

if (gapProfileState == GAPROLE_CONNECTED)
{
if ( GATT_CLIENT_CFG_NOTIFY )
{
attHandleValueNoti_t noti;

noti.handle = simpleProfileAttrTbl[11].handle;
noti.len = 7;
noti.value[0] = "hello";

GATT_Notification( pLinkItem->connectionHandle, &noti, FALSE );
}
}
}

这是我的代码,麻烦你了,看看可行不行。

lele,

 pLinkItem->connectionHandle 是指连接的Handle, 你跟对方设备连上以后会产生一个Handle. 这个Handle在连接建立成功的事件中可以找到, 你仔细看一下代码.

value的默认值是一个字节的, 你要这样赋值的话得改一下, 改成数组.

simpleProfileAttrTbl, 的位置12 是CHAR4 的Client Characteristic Configuration, 记得发Notification 之前, 通过master设备把这个值设置成 0x0001, 打开notification.

hi leleli: 我之前也在找这handle来至于哪里。如果你看的是从机代码可以在:

static void peripheralStateNotificationCB( gaprole_States_t newState )函数中

case GAPROLE_CONNECTED:

{ #if (defined HAL_LCD) && (HAL_LCD == TRUE)

GAPRole_GetParameter( GAPROLE_CONNHANDLE, &gapConnHandle );

HalLcdWriteString( "Connected", HAL_LCD_LINE_3 );

#endif // (defined HAL_LCD) && (HAL_LCD == TRUE) } break;

标红色字体地方获取handle

Hi Yan:

      打扰一下,再问一个关于此的基础性问题,如果在slave端采用GATT_Notification,master端会直接收到Notification的数据包,如果slave端采用GATTServApp_ProcessCharCfg,则需要把simpleProfileChar4Config写成0x0001,master端才会收到Notification的数据包。这里收到的数据包是指通过sniffer监控到的数据包,如下图:

现在的问题是,我在simpleBLECentralProcessGATTMsg中添加如下蓝色代码:

  else if ( ( pMsg->method == ATT_WRITE_RSP ) ||
       ( ( pMsg->method == ATT_ERROR_RSP ) &&
         ( pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ ) ) )
  {
   
    if ( pMsg->method == ATT_ERROR_RSP == ATT_ERROR_RSP )
    {
      uint8 status = pMsg->msg.errorRsp.errCode;
     
      LCD_WRITE_STRING_VALUE( "Write Error", status, 10, HAL_LCD_LINE_1 );
    }
    else
    {
      // After a succesful write, display the value that was written and increment value
      LCD_WRITE_STRING_VALUE( "Write sent:", simpleBLECharVal++, 10, HAL_LCD_LINE_1 );     
    }
   
    simpleBLEProcedureInProgress = FALSE;   

  }
  
  else if (  pMsg->method == ATT_HANDLE_VALUE_NOTI   )
  {
      HalUARTWrite(HAL_UART_PORT_0,"noti",5);

  }

没有执行HalUARTWrite,HalUARTWrite本身没有问题,在该工程其他地方执行是正确的,请问可能的原因是?谢谢!
 

hey peng,

首先, 不管GATT_Notification() 还是GATTServApp_ProcessCharCfg(), 本质上都是notification, 都需要master 那边先打开slave 这边的notification 功能.

你这段代码加的是正确的. 我看不出有什么问题. 

是否你其他地方还有问题? 请再仔细看一下代码.

另外你在salve 端是怎么发送notification 的? 一次发了5个字节?

Hi Yan,

    程序功能还没正常, 所以目前在使用sniffer配合调试。我的想法是这样的,连接成功后,slave自动发送notification给master。

现在发现如果在slave端采用GATT_Notification

  attHandleValueNoti_t noti;

  noti.handle = 0x002E;
  noti.len = 1;
  noti.value[0] = 0x01;

 GATT_Notification( 0x0000, &noti, FALSE );

连接成功后sniffer就可监控到数据长度为1的那个notify数据包。

另外我想试一下GATTServApp_ProcessCharCfg函数,自己修改了simpleGATTprofile.c,定义了1个4个字节的数据包,该部分已经通过BTOOL验证功能正常(使用BTOOL写入0x0001到对应地址可以收到4字节的notify数据包)。

把master工程模板切换成BLEcentral,连接成功后sniffer还是只能监控到GATT_Notification的数据包,只有在central中加入:

      attWriteReq_t writeReq;
      writeReq.handle = 0x002F;
      writeReq.len = 2;
      writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY);
      writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);
      writeReq.sig = 0;
      writeReq.cmd = 0;
      GATT_WriteCharValue( 0x0000, &writeReq, simpleBLETaskId );

才能监控到那个4个字节的数据包。sniffer虽然监控到这两个数据包了,但central的程序好像没有执行到函数simpleBLECentralProcessGATTMsg中。刚刚在central中试了一下GATT_ReadCharValue,额,好像也没跳转进去,正在看代码中......

hi peng,

从空中的包看, notification 是肯定发送过去了, simpleBLECentralProcessGATTMsg 也应该别调用到了.

只是默认central 工程没有在这个函数里面定义如何去处理收到的notification 事件, 请参考下面这个帖子, 有你要的答案:

http://www.deyisupport.com/question_answer/analog/wireless_connectivity/f/45/p/23013/77181.aspx#77181

Hi Yan

    谢谢你的帮助,问题已经解决,是自己在一主多从的模式下误操作了simpleBLEState。非常感谢!

您好Yan:

我刚刚做了个关于GATTServApp_ProcessCharCfg和GATT_NOTIFICATION 的实验。

1.当使用GATTServApp_ProcessCharCfg时master必须向SIMPLEPROFILE_CHAR4发送命令(向handle 4 写0x0001),即进入了程序

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 );
GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,
simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
INVALID_TASK_ID );
}中,进行判断正确后,在上位机端BTool软件中,每隔5秒接收一次数据。

2.当使用GATT_NOTIFICATION 时我发现,只要dongle和keyfob建立连接后,上位机BTool就一直接收数据。

关于这两个函数的使用我感觉还算是清楚,但是我有一点搞不明白:

就是我使用GATT_NOTIFICATION 函数时,是在总体程序的随便一个地方添加的,添加的前面还有判断条件,但是运行的时候好像程序没有管这些判断条件就直接向后运行了,这是怎么回事,恩~ 我想问下关于GATT_NOTIFICATION 函数的具体一个调用方法(是类似中断么?)。

这是我的程序

else if( len == 12)//len长度都没有输入判断就直接进入了
{
temp = (uint8*)value;
attHandleValueNoti_t noti;

noti.handle = 0x002E;
noti.len = 12;

noti.value[0] = *temp++;
noti.value[1] = *temp++;
noti.value[2] = *temp++;
noti.value[3] = *temp++;
noti.value[4] = *temp++;
noti.value[5] = *temp++;
noti.value[6] = *temp++;
noti.value[7] = *temp++;
noti.value[8] = *temp++;
noti.value[9] = *temp++;
noti.value[10] = *temp++;
noti.value[11] = *temp++;
GATT_Notification( 0x0000, &noti, FALSE );
}

不清楚你的意思.

len的长度没判断, 貌似是代码的逻辑问题?

Notification 是Master和slave 通信的一种方式, 开关由Master 来控制, master打开slave 的某个 Notification 开关后, slave 就可以发送数据.

这是双方的一种通信协议, 以起到同步信息以及状态的作用.

请问notification在程序的那个地方打开?

hi yan,

        问您个问题,我设置好了notification,本来默认的是一个字节,我5秒发一次,后来我修改代码改成了每次发送8个字节,还是5秒发一次,但是程序执行起来不到一秒就发一次,定时器都跟着出问题了,请问我改了什么东西还会产生这种效果?

SimpleProfile_SetParameter()为什么调用simpleProfile_ReadAttrCB()呢,不应该是simpleProfile_WriteAttrCB()吗?

嗨Yan,你不是说

调用 GATTServApp_ProcessCharCfg(...........................), 该函数处理客户端特征改变(来自BLE官方html文档)

这个函数内部最终会回调simpleProfile_ReadAttrCB(),里面的下面代码会设置CHAR4的值.

case SIMPLEPROFILE_CHAR4_UUID:
*pLen = 1;
pValue[0] = *pAttr->pValue;
break;

最后, 如果notification是打开的, GATTServApp_ProcessCharCfg(...........................)

内部会调用GATT_Notification().

这里完全就没有master什么事啊?那你为什么说调用这个 GATTServApp_ProcessCharCfg函数会引起主机master发出一个Read请求。再说Notification在主机方面没有Read的权限啊!你说不是吗?


我是较真的啊。

Hi Yan!

我用串口助手扫描出某个透传模块的特征值为:FFF1可通知,FFF2可写。请问从“FFF1可通知”这一点是否可以看出该模块数据传输采用哪种方式?是否为GATT_Indication方式?

谢谢!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top