1. GAIA
CSR GAIA (Generic Application Interface Architecture)提供了一個端到端的,與主機無關的生態系統來實現主機應用程序對設備的功能集訪問。
1.1 接口實現
GAIA是處於較上層的應用層協議,其依賴的傳輸協議有多個,目前ADK支持的傳輸協議有:RFCOMM,SPP,GATT,不同的傳輸協議,實現相同的功能,但是在實現這些功能時一些機制和細節又存在着一些差異。因此ADK對傳輸層定義了多個抽象的接口,這些接口根據當前連接所采取的傳輸協議而自動映射到該協議對應的接口,具體映射關系如下圖所示:

當采用不同傳輸協議時,部分通用接口可能無法找到對應的接口,比如當采用GATT傳輸協議時,gaiaTransportGetSink()通用接口沒有對應的實現接口,因為GATT沒有SINK和SOURCE這些實體。
下面來看看GAIA庫和Sink_GAIA的主要結構體和函數接口。Sink_gaia.c主要提供了GAIA可注冊事件發生時,向GAIA_Client推送事件的接口,如gaiaReportEvent()等。另外一個主要功能是管理GAIA事務,這主要通過handleGaiaMessage()對外提供的外部鈎子函數實現。

Gaia.c提供了GAIA庫的大部分功能實現,主要包括以下幾個部分:
1.初始化GAIA庫,開啟GAIA服務器。
2.處理連接,斷開連接請求和響應。
3.構建GAIA數據包,應答包,接收並解析GAIA數據包。
4.GAIA模塊參數獲取和修改接口。
1.2 重要流程
先來看看GAIA如何建立GAIA連接的。連接通常用GAIA_Client通過調用GaiaBtConnectRequest()發起。斷開連接的請求可以有個client或者server任何一端發起。

再來看看GAIA連接建立之后,如何進行GAIA交互的。

在上圖中,上半部分展示了一次典型的GAIA交互——GAIA_Client構造一個GAIA后,通過GAIA傳輸層發送給對端,GAIA_Server在接收到GAIA命令后,進行解析,如果參數合法,處理該請求后應答該次請求的結果,如果參數有錯,則應答錯誤。
下半部分展示了GAIA_Client向GAIA_Server注冊某個事件,並得到成功應答,在后續時間里,如果該注冊的事件發生時,GAIA_Server向GAIA_Client發送notification通知。
對於到來的GAIA請求,GAIA lib庫能夠處理少部分請求(比如重啟之類),大部分請求需要轉發給應用層(sink_gaia.c)進行處理,這中情況下,只需要向應用層發送一條GAIA_UNHANDLED_COMMAND_IND消息即可。
1.3 GAIA Over GATT
下面來看看當傳輸層采用GATT時,整個流程是怎么樣的?
首先,GATT Client和GATT Server都必須支持GATT GAIA Service,GATT Server添加和初始化了GATT GAIA Service。
gaiaGattServerInitialise()->
GaiaStartGattServer()->
gaiaTransportStartGattServer();->
gaiaTransportGattRegisterServer()->
GattManagerRegisterServer(); /*GATT MANAGER Module*/
其次,如果尚未開始GATT連接,則開始GATT連接過程,GATT連接后,在建立的GATT上,通過notify或者indication的方式向BLE_Centural發送消息。
GaiaSendPacket()->
gaiaTransportSendPacket()->
gaiaTransportGattSendPacket()->
GattManagerRemoteClientNotify()||GattManagerRemoteClientIndicate();
GaiaBuildAndSendSynch ()->
gaiaTransportGattSend ()->
GattManagerRemoteClientNotify()||GattManagerRemoteClientIndicate();
如何接收來自GATT_Client(BLE_Centural)的數據呢?根據前面GATT部分的了解,那肯定是放在了GAIA GATT庫文件里面的內部回調函數里面了。GATT Service在向GATT MANAGER模塊注冊時指定了該回調函數,在該回調函數里面GATT_MANAGER_SERVER_ACCESS_IND消息提示來自GATT Client的access請求。
gaiaTransportGattRegisterServer()->
registration_params.task = &gaia->task_data;
message_handler()(gaia->task_data,gaia.c)-> GATT_MANAGER_SERVER_ACCESS_IND
gaiaHandleGattManagerAccessInd();
