1、Notification与Indication的区别
GATT_Indication:
从机通知主机后,主机需要调用simpleprofile_writeattrcb,读取从机的数据。
GATT_Notification:
从机直接发送数据给主机。
从机和主机连接后,从手机端打开indication的功能,从机会调用simpleprofile_writeattrcb去通过GATTServApp_ProcessCCCWriteReq函数配置当前功能是indication还是notification;
配置好后,GATT_Indication(有确认信息)和GATT_Notification的区别就在于主机是否回confirm(确认)。
2、设备通讯过程
前提需要确保主从机绑定连接,本篇只讨论数据交互过程。
2.1、主机
2.1.1、发送数据
uint8 sbpGattWriteString(uint8 *pBuffer, uint16 length)
{
uint8 status;
uint8 len;
// 数据包长度最大20字节
if(length > 20)
len = 20;
else
len = length;
attWriteReq_t req;
req.handle = simpleBLECharHdl;
req.len = len;
req.sig = 0; //必须要填
req.cmd = 0; //必须要填
osal_memcpy(req.value,pBuffer,len);
// 发送数据
status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );
return status;
}
2.1.2、接收数据
static void simpleBLECentral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
{
switch ( pMsg->event )
{
case KEY_CHANGE:
simpleBLECentral_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
break;
case GATT_MSG_EVENT:
// 触发接收数据消息
simpleBLECentralProcessGATTMsg( (gattMsgEvent_t *) pMsg );
break;
}
}
static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg )
{
if ( simpleBLEState != BLE_STATE_CONNECTED )
{
return;
}
static int dataCount=0;
// 处理接收到的数据
if ( pMsg->method == ATT_HANDLE_VALUE_NOTI ||
pMsg->method == ATT_HANDLE_VALUE_IND )
{
attHandleValueNoti_t noti;
dataCount = dataCount+ 1;
// 获取handle
noti.handle = pMsg->msg.handleValueNoti.handle;
noti.len = pMsg->msg.handleValueNoti.len;
// 将接收到的数据发送到串口
osal_memcpy(¬i.value, &pMsg->msg.handleValueNoti.value,noti.len);
sbpSerialAppWrite(noti.value,noti.len);
}
......
else if ( simpleBLEDiscState != BLE_DISC_STATE_IDLE )
{
simpleBLEGATTDiscoveryEvent( pMsg );
}
}
2.2、从机
2.2.1、数据发送函数
void sbpSerialAppSendNoti(uint8 *pBuffer,uint16 length)
{
uint8 len;
// 判断数据包长度,最大为20字节
if(length > 20)
len = 20;
else
len = length;
static attHandleValueNoti_t pReport;
pReport.handle=0x2E;
pReport.len = len;
osal_memcpy(pReport.value, pBuffer, len);
// 通过noti方式发送数据
GATT_Notification( 0, &pReport, FALSE );
}
2.2.2、数据接收回调函数
// Simple GATT Profile Callbacks
static simpleProfileCBs_t simpleBLEPeripheral_SimpleProfileCBs =
{
simpleProfileChangeCB // Charactersitic value change callback
};
static void simpleProfileChangeCB( uint8 paramID )
{
uint8 newValue;
uint8 newValueBuf[20]={0};
switch( paramID )
{
case SIMPLEPROFILE_CHAR1:
// 获取数据
SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR1, newValueBuf );
// 发送串口显示
sbpSerialAppWrite (newValueBuf, 20);
break;
case SIMPLEPROFILE_CHAR3:
SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, &newValue );
break;
default:
break;
}
}
卫朋
人人都是产品经理受邀专栏作家,CSDN 嵌入式领域新星创作者、资深技术博主。2020 年 8 月开始写产品相关内容,截至目前,人人都是产品经理单渠道阅读 56 万+,鸟哥笔记单渠道阅读200 万+,CSDN 单渠道阅读 210 万+,51CTO单渠道阅读 180 万+。
卫朋入围2021/2022年人人都是产品经理平台年度作者,光环国际学习社区首批原创者、知识合作伙伴,商业新知 2021 年度产品十佳创作者,腾讯调研云2022年达人榜第三名。
文章被人人都是产品经理、CSDN、华为云、运营派、产品壹佰、鸟哥笔记、光环国际、商业新知、腾讯调研云等头部垂直类媒体转载。文章见仁见智,各位看官可策略性选择对于自己有用的部分。