1.1       GATT Manager

GATT MGR模块管理所有的GATT服务,同时也是连接GATT模块与GATT ServiceS模块的桥梁。

1.1.1    主要功能模块

先来看一张该模块的API关系图,sink_gatt_manager.c里面定义的接口主要供ApplicationLayer调用和回调,如用户(BLE Server)调用sinkGattManagerStartAdvertising()开始进行广播,用户(BLE Client)调用sinkGattManagerStartConnection()开始进行BLE连接。该该部分同时负责接收和处理来自ApplicationLayer的消息——GATT_MANAGER_DISCONNECT_IND,GATT_MANAGER_REGISTER_WITH_GATT_CFM等GATT_MANAGER_XXX系列消息。这些消息主要用来处理注册连接确认,断开连接请求等事件。

Gatt_nanager_handler.c主要定义和实现了内部回调函数gattManagerMessageHandler(),该接口主要接收来自GATT模块的GATT_XXX系列消息,以及GATT MGR内部的消息GATT_MANAGER_INTERNAL_MSG_XXX。处理这些消息的函数接口主要分布在gatt_manager_server.c和gatt_manager_client.c两个函数内部。

根据BLE工作的角色不同,BLE分别定义了两套接口,分别完成客户和服务的角色的任务。

作为BLE客户主要完成的任务有:

1.连接到服务器。这里包括主导发起连接至服务器,以及接收到服务器连接请求的确认。即:GattManagerConnectToRemoteServer()用来主动发起连接请求,在接收到GATT_CONNECT_CFM消息后,调用gattManagerClientRemoteServerConnected ()接口用于确认连接,完成连接的三次握手过程。

2. GATT支持notification和indication操作,因此客户端需要有着两种请求操作对应的接口。gattManagerClientRemoteServerNotification()和gattManagerClientRemoteServerIndication()就是为了实现这两种操作巍峨设计的。

3. 获取服务器的服务。根据GATT标准,获取服务的服务主要有:获取服务器主要GATT服务,获取某个GATT服务的所有特征值定义,获取某个GATT服务的特征值描述符,读/写某个特征值等。

作为BLE服务器主要完成的任务有:

1.广播,以及处理客户端的连接请求。gattManagerServerAdvertising()开启广播,GattManagerWaitForRemoteClient()等待远程客户发起连接,gattManagerServerConnectInd()处理连接请求。gattManagerServerRemoteClientConnected()处理连接请求确认(三次握手最后一次)消息。

2.注册GATT service。GattManagerRegisterServer()向GATT MGR模块注册一个GATT service。

3.处理来自客户端的GATT操作,如access,indication,notification等。其中indication,notification操作都是由服务器主动对客户端发起的操作,因此客户端和服务器端处理的消息刚好是互为匹配的,即服务器处理的消息有(GATT_ACCESS_IND, GATT_NOTIFICATION_CFM, GATT_INDICATION_CFM),客户端对应的处理消息有(ATT_ACCESS_RSP, GATT_NOTIFICATION_IND, GATT_INDICATION_IND)。

1.1.2    GATT数据库

作为GATT的服务器,通常需要存储比较多的数据来支撑多个不同的GATT服务,因此在GATT服务器端,建立一个数据库是必要的。在CSR的BlueCore和CSRμEnergy软件开发工具包(SDK)中使用了一种特殊的数据库目标语言。该数据库通过GATT数据库生成器(CSR提供的gattdbgen.exe)自动生成。这就允许应用程序开发者以一种简单易读,便于维护的方式来创建一个数据库,避免采用诸如SDP这种用复杂的二进制形式表示方式。

数据库的生成

GATT数据库生成器输入一个用jeason语言描述的GATT服务文件foobar.db,输出一个foobar.c和foobar.h文件,这两个文件可以作为ADK工程的一部分进行编译和链接。可见数据库的生产是在整个工程编译前,准确的说是在预编译阶段就已经完成了。显然这样生产的数据是一个准常量的数据库,不能往里面新增记录,即不能动态的添加GATT服务,所有的服务必须在编译前就已经确定好。

例如,在ADK的sink例程中,sink_gatt_db.db作为数据库生成器的输入文件,输出sink_gatt_db.c和sink_gatt_db.h。

其中xxx_db.c文件有const uint16 gattDatabase[] = {}存储数据库记录。并提供两个接口工外部操作数据库,这两个接口分别为:

uint16 *GattGetDatabase(uint16 *len);  /*获取数据库存储区首地址*/

uint16 GattGetDatabaseSize(void);      /*获取数据库大小*/

在xxx_db.h文件中,除了GattGetDatabase()和GattGetDatabaseSize()接口的声明外,还有数据库中所有ATT记录的句柄(UUID)的宏定义,通常以HANDLE_GAIA_XXX的形式定义。通过该宏,可以快速索引某条ATT记录。

BLE在初始化GATT Manager模块时,对GATT database进行了初始化:

initialiseGattWithServers()->

GattManagerRegisterConstDB(&gattDatabase[0], GattGetDatabaseSize());

例如某个gaia_db.db内容为:

primary_service {

uuid : 0x01,

name : "GAIA_SERVICE",

characteristic {

uuid        : 0x02,

name        : "GAIA_COMMAND_ENDPOINT",

flags       : [ FLAG_IRQ, FLAG_DYNLEN, FLAG_ENCR_W ],

properties  : [ write ],

value       : 0x0

}

},

则其生成的gaia_db.c文件如下:

/* Static GATT database */

const uint16 gattDatabase[] = {

/* 0001: Primary Service 0001 */

0x0002, 0x0100,

/* 0002: Characteristic Declaration 0002 */

0x3005, 0x0803, 0x0002, 0x0000,

/* 0003: . */

0xdd01, 0x0000,

};

uint16 *GattGetDatabase(uint16 *len)

{

uint16 *rc = PanicUnlessMalloc(sizeof(gattDatabase));

*len = sizeof(gattDatabase);

memmove(rc, gattDatabase, sizeof(gattDatabase));

return rc;

}

uint16 GattGetDatabaseSize(void)

{

return sizeof(gattDatabase);

}

其生成的gaia_db.h文件如下:

#define HANDLE_GAIA_SERVICE             (0x0001)

#define HANDLE_GAIA_SERVICE_END         (0xffff)

#define HANDLE_GAIA_COMMAND_ENDPOINT    (0x0003)

uint16 *GattGetDatabase(uint16 *len);

uint16 GattGetDatabaseSize(void);

数据库维护

GATT数据库的数据单元是ATT记录,通过某条ATT记录的句柄(handler)可以快速和唯一地访问该条记录,例如,如果希望访问电池服务的电量特征值,该条特征值定义封装在一条句柄为0x0003的ATT记录中,通过句柄0x0003找到该条ATT记录,ATT.value即对应着电池电量值。

四、BLE(中)的更多相关文章

  1. java编程思想第四版中net.mindview.util包下载,及源码简单导入使用

    在java编程思想第四版中需要使用net.mindview.util包,大家可以直接到http://www.mindviewinc.com/TIJ4/CodeInstructions.html 去下载 ...

  2. 用MFC完成一个简单的猜数字游戏: 输入的四位数中,位置和数字都正确为A,数字相同而位置不同的为B。

    最近学习了MFC一些比较基础的知识,所以打算通过做一个简单的数字游戏来理解MFC的流程并进一步熟悉其操作. 在这里,我做了一个猜数字的小游戏.第一步当然是设计主界面,先给大家展示一下游戏界面: 主界面 ...

  3. SLAM十四讲中Sophus库安装

    Sophus截止目前有很多版本,其中大体分为两类,一种是用模板实现的方法,一种是用非模板类实现的,SLAM十四讲中使用的是非模板类库,clone Sophus: git clone http://gi ...

  4. Java Native Interface 四--JNI中引用类型

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 JNI支持将类实例和数组类型(如jobjec ...

  5. Deep learning:四十四(Pylearn2中的Quick-start例子)

    前言: 听说Pylearn2是个蛮适合搞深度学习的库,它建立在Theano之上,支持GPU(估计得以后工作才玩这个,现在木有这个硬件条件)运算,由DL大牛Bengio小组弄出来的,再加上Pylearn ...

  6. boost.asio源码剖析(四) ---- asio中的泛型概念(concepts)

    * Protocol(通信协议) Protocol,是asio在网络编程方面最重要的一个concept.在第一章中的levelX类图中可以看到,所有提供网络相关功能的服务和I/O对象都需要Protoc ...

  7. Python学习笔记整理(四)Python中的字符串..

    字符串是一个有序的字符集合,用于存储和表现基于文本的信息. 常见的字符串常量和表达式 T1=‘’ 空字符串 T2="diege's" 双引号 T3=""&quo ...

  8. 从零学习Fluter(四):Flutter中ListView组件系列详展

    今天继续研究了一些Flutter,主要时关于ListVIew那一块的东西,有 SingleChildScrollViewListViewGridViewCustomScrollView 感觉Flutt ...

  9. Expo大作战(十四)--expo中消息推送的实现

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

随机推荐

  1. Github教程(0)

    Git下载:https://git-for-windows.github.io/ 我下载的版本是:Git-2.6.3-64-bit.exe 安装:略 默认选项点击"下一步"即可 安 ...

  2. [_CN] Eclipse精要与高级开发技术 note

    一 eclipse是基于java的 ide ,但根据其体系结构,开发插件,也可拓展到其他语言———————— 尽管如此,但还是很少听说用eclipse来写php或者c的 跨os 三个项目:eclips ...

  3. write/wall 1

    linux:/opt/software/lktest/c # wallhellllllllllllllllllllooooooooooooooooo^[[AasZZZZZZ^Clinux:/opt/s ...

  4. lua如何调用C++函数

    第一步是定义函数.所有在Lua中被调用的C/C++函数将使用下面一类指针进行调用: typedef int (*lua_CFunction) (lua_State *L); 换句话说,函数必须要以Lu ...

  5. JSON和JSONP的区别

    先前的概念中对JSON还是比较熟悉,对JSONP不是特别的清楚,整理完相关知识发现才豁然开朗.简单的说JSON是一种数据交换格式,而JSONP是 一种非官方跨域数据交互协议.JSON是“暗号”,而JS ...

  6. salesforce 零基础学习(三十七) DML及Database方法简单描述

    在apex中通过soql查询可以使用两种方式,使用DML语句或者使用Database的方法. 使用DML语句和使用Database类的方法对于我们来说用的都很多,并且都很常见.对于数据库常见的操作:增 ...

  7. salesforce 零基础开发入门学习(三)sObject简单介绍以及简单DML操作(SOQL)

    salesforce中对于数据库操作和JAVA等语言对于数据库操作是有一定区别的.salesforce中的数据库使用的是Force.com 平台的数据库,数据表一行数据可以理解成一个sObject变量 ...

  8. spring 学习

    一.spring框架介绍 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供 ...

  9. 【原创】高性能网络编程(二):上一个10年,著名的C10K并发连接问题

    1.前言 对于高性能即时通讯技术(或者说互联网编程)比较关注的开发者,对C10K问题(即单机1万个并发连接问题)应该都有所了解."C10K"概念最早由Dan Kegel发布于其个人 ...

  10. js算法之最常用的排序

    引入 大学学习计算机语言的那几年,从c语言,到c++,再到数据结构JAVA..让我印象最深刻的还是最开始老师讲冒泡算法的时候,直到现在大四快毕业了我才渐渐通窍了.刚学前端的时候以为前端就是做出好看很炫 ...