TI BLE CC2541 關於Notification的設定及應用
其中, clientCharCfgUUID值如下,它是uint16型別的值,具體表示為GATT_CLIENT_CHAR_CFG_UUID巨集的值
#define GATT_CLIENT_CHAR_CFG_UUID 0x2902 說白了,上面在profile中新增的configuration的UUID為GATT_CLIENT_CHAR_CFG_UUID (0x2902),主機若一搜到就知道它指的是什麼了(當然是notification) 需要主機的client端對它進行開啟通知操作後,從機才能notification通知到主機client. B 初始化這個client配置特徵表
當然是呼叫這個了。不過在例程中並不是直接呼叫,而是在回撥函式中被執行呼叫。
上面這個函式是個回撥函式,它是在下面函式中註冊的。
linkDB_Register()函式中,simpleProfile_HandleConnStatusCB作為引數進行註冊。 下面看看linkDB_Register介面的含義:
也就是說當底層的鏈路連線狀態發生變化時回撥函式就會被執行,也就是說,如果未來主從建立連線,斷開連線等狀態,此回撥函式就會被觸發,而在回撥中繼續執行client配置表的初始化操作。 雖然過程比較曲折,不過最終目標是執行了初始化。 C Client端需要開啟Server端的Notification通知功能
TI CC2541軟體開發指南中有如下英文描述,上面執行的程式碼就是開啟通知。GATT_CLIENT_CFG_NOTIY巨集為0x0001
一旦操作成功後,如果Server要想主動的給Client發資料,只需要呼叫SimpleProfile_SetParameter方法即可。 D Server端主動通知Client 下面來看看這個方法的實現:
如果是操作CHAR4,則會呼叫GATTServApp_ProcessCharCfg()方法,這是一個間接的notification方式。 注:上面程式碼中最好加入是否新增NOTIFICATION開關通知的判斷,如果client沒有開啟,則不允許主動通知
- value = GATTServApp_ReadCharCfg( connHandle, simpleProfileChar6Config );//讀出CCC的值
- if ( value & GATT_CLIENT_CFG_NOTIFY ) //判斷是否開啟通知開關,打開了則傳送資料
- {
- noti.handle = simpleProfileAttrTbl[ATTRTBL_CHAR6_IDX].handle;
- noti.len = len;
- osal_memcpy( noti.value, pValue, len); //資料
- GATT_Notification( connHandle, ¬i, FALSE );
- }
二、修改主機端程式碼(Client) A 通過Server端Client Config的UUID獲取其Handle 使用介面GATT_DiscCharsByUUID()來獲取相應的Handle B 開啟Notification功能 使用介面GATT_WriteCharValue 前期先通過A操作獲取到對應的Handle,這個handle一般是characteristic value的handle+1,控制代碼的順序是characteristic declaration, characteristic value, 然後是 CCC.
CCC是指Client Characteristic Configuration 的這個descriptor.
下面是個例子:
attWriteReq_t writeReq;
writeReq.handle = 0x002f;
writeReq.len = 2;
writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); // 0x01 【1:開啟Notification 0:關閉Notify】
writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); // 0x00 【1:開啟Indification 0:關閉Indi】
writeReq.sig = 0;
writeReq.cmd = 0;
GATT_WriteCharValue( simpleBLEConnHandle, &writeReq, simpleBLETaskId );
C 接收來自Server的Notification訊息 當Client端接收到來自對方的訊息,系統會產生一個事件GATT_MSG_EVENT告之, 方法如下:static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg )所有通過藍芽傳送的資料都會讓GATT這個函式來處理.因此,傳送的資料就到這裡了。gattMsgEvent_t是個很大的聯合體程式碼中都有註釋,只要找到相應的結構體就行了。
typedef union
{
// Request messages
attExchangeMTUReq_t exchangeMTUReq; //!<
ATT Exchange MTU Request
attFindInfoReq_t findInfoReq; //!<
ATT Find Information Request
attFindByTypeValueReq_t findByTypeValueReq; //!<
ATT Find By Type Vaue Request
attReadByTypeReq_t readByTypeReq; //!<
ATT Read By Type Request
attReadReq_t readReq; //!<
ATT Read Request
attReadBlobReq_t readBlobReq; //!<
ATT Read Blob Request
attReadMultiReq_t readMultiReq; //!<
ATT Read Multiple Request
attReadByGrpTypeReq_t readByGrpTypeReq; //!<
ATT Read By Group Type Request
attWriteReq_t writeReq; //!<
ATT Write Request
attPrepareWriteReq_t prepareWriteReq; //!<
ATT Prepare Write Request
attExecuteWriteReq_t executeWriteReq; //!<
ATT Execute Write Request
gattReadByTypeReq_t gattReadByTypeReq; //!<
GATT Read By Type Request
gattWriteLongReq_t gattWriteLongReq; //!<
GATT Long Write Request
gattReliableWritesReq_t gattReliableWritesReq; //!< GATT Reliable Writes Request
// Response messages
attErrorRsp_t errorRsp; //!<
ATT Error Response
attExchangeMTURsp_t exchangeMTURsp; //!<
ATT Exchange MTU Response