1.1       GATT server Service

通过走读代码, GATT Server作为一个GATT service,我是没有发现其发挥了多大功能,其负责处理的消息GATT_SERVER_SERVICE_CHANGED_INDICATION_CFM,GATT_SERVER_READ_CLIENT_CONFIG_IND,GATT_SERVER_WRITE_CLIENT_CONFIG_IND都没有定义对应的handler。

1.2       GATT Service(Battery Service)

GATT Battery Servce是ADK4.0 sink例程中默认添加的一个比较简单和常用的服务,该服务只有一个设备电量(batteryLevel)的特征值。纵观GATT Battery Servce模块的接口可以大致看出该模块完成的主要功能有:

1.2.1    服务初始化

GattBatteryServerInit(GBASS *battery_server, Task app_task, init_params, start_h,  end_h);

该接口主要用来初始化指定(#battery_server) GATT Battery Service实例,如lib_task和app_task。初始化实例之后,通过GattManagerRegisterServer()将其添加到GATT MGR模块。

1.2.2    回调函数

前面也提到过,这里涉及到两个回调函数,外部钩子函数主要用来接收application layer的数据,而内部钩子函数,则用来接收上级管理模块的信息。

内部钩子函数与外部钩子函数对应的函数名称以及处理的信号如下:

batteryServerMsgHandler();  /*内部钩子函数*/

--GATT_MANAGER_SERVER_ACCESS_IND

-- HANDLE_BATTERY_SERVICE

-- HANDLE_BATTERY_LEVEL à GATT_BATTERY_SERVER_READ_LEVEL_IND

-- HANDLE_BATTERY_LEVEL_CLIENT_CONFIG à GATT_BATTERY_SERVER_READ_CLIENT_CONFIG_IND / GATT_BATTERY_SERVER_WRITE_CLIENT_CONFIG_IND

-- HANDLE_BATTERY_LEVEL_PRESENTATIONà GATT_BATTERY_SERVER_READ_PRESENTATION_IND

-- GATT_MANAGER_REMOTE_CLIENT_NOTIFICATION_CFM

sinkGattBatteryServerMsgHandler();  /*外部钩子函数*/

-- GATT_BATTERY_SERVER_READ_LEVEL_IND

-- GATT_BATTERY_SERVER_READ_CLIENT_CONFIG_IND

-- GATT_BATTERY_SERVER_WRITE_CLIENT_CONFIG_IND

-- GATT_BATTERY_SERVER_READ_PRESENTATION_IND

从上面的分析可以看出,内部钩子函数在接收到的GATT请求,如果能够自己处理,则直接进行处理和应答,如HANDLE_BATTERY_SERVICE,其他大部分情况还需要application Layer的介入,因此将其映射为外部钩子函数对应的信号后转发给application Layer(通过app_task),application Layer通过直接调用外部钩子函数,进行请求转发,在外部钩子函数里面,实现大部分的GATT请求。

1.2.3    服务参数配置,特征值获取接口

实现内部钩子函数和外部钩子函数对GATT请求的处理接口。在Battery Service中主要有:

-- HANDLE_BATTERY_SERVICEà查询Battery Service,主要用于获取Battery Service句柄

-- HANDLE_BATTERY_LEVEL à获取电量特征值

--HANDLE_BATTERY_LEVEL_CLIENT_CONFIG à 获取电量特征值的客户端配置参数

-- HANDLE_BATTERY_LEVEL_PRESENTATIONà获取电量特征值的表示方式

1.3       初始化

The local database and the GATT Server libraries to manage the local GATT database must be registered. This section describes the procedure required to do this, a few points to note are:

§ The local GATT Database must be registered first.

§ Each required GATT Server library must be individually registered:

§ Only GATT Server Libraries that manage a section of the registered GATT database should be registered.

§ The handle range for each GATT Server library must not overlap.

§ When the local GATT database and all the required GATT Server libraries have been registered, the device can be registered with GATT (and the ATT firmware layer):

§ If a local GATT database is registered, but no GATT Server libraries have been registered, this request fails.

1.4       GATT Request Handle

当一个GATT客户设备与一个GATT服务设备建立连接后,就可以开始GATT操作。GATT MGR模块对每个到来的GATT请求,通过查询已注册的服务列表,经过一定的匹配算法寻找到合适GATT Service后将该请求分发给它。GATT Service模块对于到来的请求通常有两种不同的处理方式:

1.少数情况,GATT Service模块有能力可以立即对到来的GATT请求作出回应,例如,GATT请求时获取软件版本,确认某个服务等,这种情况无需Application Layer介入。

2.大多数情况下,GATT Service模块将到来的请求传递给Application Layer, Application Layer通过该模块的外部钩子函数API处理该请求,这也是为什么通常GATT Service模块需要提供外部钩子函数的原因(The GATT Server library should provide a downstream API for the application to respond to the request)。

下图分别展示上述两种不同的GATT请求的处理方式。上半部分展示了读取GATT Battery Service的电池电量的操作,在该GATT请求中,GATT Battery Service模块将该请求传递个Application Layer,后者通过GATT Battery Service模块提供的外部回调函数(downstream API) sinkGattBatteryServerMsgHandler()来处理请求。下半部分展示了一个简单的GATT请求,该请求无需Application Layer处理。

获取BatteryService的电量特征值的函数调用过程如下图:

gattMessageHandler();  (ATT_ACCESS_IND)->

gattHandleAttAccessInd((ATT_ACCESS_IND_T *) message);

MessageSend(gattGetCidMappedTask(ind->cid), GATT_ACCESS_IND, message);

gattManagerMessageHandler(); /* gatt_manager_data->gatt_manager_task.handler */

gattMessageHandler();  (GATT_ACCESS_IND)->

gattManagerServerAccessInd();

gattManagerDataResolveServerHandle(&discover);

serverAccessInd(ind, discover.task, discover.adjusted);

MessageSend(task, GATT_MANAGER_SERVER_ACCESS_IND, message);

batteryServerMsgHandler();->GATT_MANAGER_SERVER_ACCESS_IND

handleBatteryAccess()->HANDLE_BATTERY_LEVEL

batteryLevelAccess();->GATT_BATTERY_SERVER_READ_LEVEL_IND

MessageSend(battery_server->app_task, , message);-à

sinkBleMsgHandler()->GATT_BATTERY_SERVER_READ_LEVEL_IND

sinkGattBatteryServerMsgHandler()->

handleReadBatteryLevel();->

getBatteryLevelAsPercentage();

sendBatteryLevelAccessRsp(battery_server, cid, battery_level);->

sendBatteryLevelAccessRsp(); (HANDLE_BATTERY_LEVEL)

sendBatteryAccessRsp(&battery_server->lib_task, , , &battery_level);

GattAccessResponse();  (GATT_INTERNAL_ACCESS_RES)

MessageSend(&theGatt->task, GATT_INTERNAL_ACCESS_RES);

gattMessageHandler()->

gattHandleInternalAccessRes()->

VmSendAttPrim(prim);

1.5       Service Discovery

关于这一节,ADK提供的使用手册表诉的比较详细,这里就直接摘抄过来。

When a GATT Server device has been successfully connected, the Audio Sink application starts discovering which primary services are supported by the connected device. The procedure for discovering the GATT Primary Services of a remote GATT Server is:

§ The Audio Sink application discovers all primary services defined on the remote GATT Server:

§ Discovered primary services that are supported by the Audio Sink application is temporarily stored in a list.

§ Discovered primary services that are not supported by the Audio Sink application are ignored.

§ When all primary services have been discovered:

§ For each supported primary service that has been discovered, the Audio Sink application initialises the GATT client library used to manage the service. Library initialisation is done sequentially not simultaneously.

§ If no supported primary services have been discovered, the device is disconnected.

Description

§ The Audio Sink application discovers all primary services on the remote GATT Server.

§ The Audio Sink application discovers the remote GATT Server supports Service One and temporarily stores that information.

§ The Audio Sink application ignores the discovered primary service (Service Two) that is not supported.

§ When all primary services have been discovered, the Audio Sink application initialises the GATT Client library to manage Service One.

五、BLE(下)的更多相关文章

  1. 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载

    title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...

  2. Fiddler (五) Mac下使用Fiddler

      Fiddler是用C#开发的.  所以Fiddler不能在Mac系统中运行.  没办法直接用Fiddler来截获MAC系统中的HTTP/HTTPS,    Mac 用户怎么办呢? Fiddler可 ...

  3. python学习笔记五 模块下(基础篇)

    shevle 模块 扩展pickle模块... 1.潜在的陷进 >>> import shelve>>> s = shelve.open("nb" ...

  4. Python 第五篇(下):系统标准模块(shutil、logging、shelve、configparser、subprocess、xml、yaml、自定义模块)

    目录: shutil logging模块 shelve configparser subprocess xml处理 yaml处理 自定义模块 一,系统标准模块: 1.shutil:是一种高层次的文件操 ...

  5. Linux学习之CentOS(五)--CentOS下VMware-Tools安装

    已经进入到了Linux学习之CentOS的第六篇随笔了,所以这里就介绍一下VMware-Tools的安装. VMware-Tools的安装 VMware-Tools 主要的功能就是让用户在虚拟机和真实 ...

  6. 开源框架.netCore DncZeus学习(五)下拉树的实现

    千里之行,始于足下,先从一个小功能研究起,在菜单管理页面有一个下拉树,先研究下它怎么实现的 1.先找到menu.vue页面 惯性思维先搜索请选择三个字,原来是动态生成的 再向上找DropDown组件, ...

  7. zeromq学习记录(五)vc下多线程

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  8. (十五)linux下gdb调试

    一.gdb常用命令: 命令 描述 backtrace(或bt) 查看各级函数调用及参数 finish 连续运行到当前函数返回为止,然后停下来等待命令 frame(或f) 帧编号 选择栈帧 info(或 ...

  9. 《Javascript高级程序设计》阅读记录(四):第五章 下

    这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释上我的一些想法.做这个一方面是提升了我的阅读效果以及方便我以后阅 ...

  10. SDUT-3332&3333_数据结构实验之栈与队列五:下一较大值

    数据结构实验之栈与队列六:下一较大值 Time Limit: 150 ms Memory Limit: 8000 KiB Problem Description 对于包含n(1<=n<=1 ...

随机推荐

  1. Android(5)— Mono For Android 两个功能型外包

    0.前言 距上一篇博文貌似很久了,其中原因种种,归根结底是自己没有坚持好,没有静下心来归纳总结,希望从这一刻起每个月坚持写两篇.(哈哈,突然想起老师说起一句话, 晚上在被窝里悄悄发誓好好学习,第二天涛 ...

  2. 【Win10 UWP】URI Scheme(一):Windows Store协议的解析和使用

    协议是Windows Phone和Windows Store应用的一个重要特点,可以做到在不同应用之间进行互相呼起调用.小小协议,学问大着呢.我打算写几篇关于协议在UWP中使用的文章. 这一讲的主要对 ...

  3. [.NET领域驱动设计实战系列]专题八:DDD案例:网上书店分布式消息队列和分布式缓存的实现

    一.引言 在上一专题中,商家发货和用户确认收货功能引入了消息队列来实现的,引入消息队列的好处可以保证消息的顺序处理,并且具有良好的可扩展性.但是上一专题消息队列是基于内存中队列对象来实现,这样实现有一 ...

  4. AJAX原理总结

    AJAX全称 Asynchronous JavaScript and XML(异步的JavaScript 和XML) 同步和异步 异步传输是面向字符的传输,单位是字符 同步传输是面向比特,单位是帧,传 ...

  5. ListView设置headerview和footerview

    [简介]headerview就是通常看到的那种listview手势下滑露出上面的部分,下拉到一定位置,松手会开始请求网络数据,然后刷新listview的列表.footerview一般就是listvie ...

  6. angularjs组件之input mask

    今天将奉献一个在在几个angularjs项目中抽离的angular组件 input mask.在我们开发中经常会对用户的输入进行控制,比如日期,货币格式,或者纯数字格式之类的限制,这就是input m ...

  7. [.net 面向对象编程基础] (6) 基础中的基础——运算符和表达式

    [.net 面向对象编程基础] (6) 基础中的基础——运算符和表达式 说起C#运算符和表达式,小伙伴们肯定以为很简单,其实要用好表达式,不是一件容易的事.一个好的表达式可以让你做事半功倍的效果,比如 ...

  8. 浮动ip

    浮动ip 其实就是动态ip, 静态IP是固定不变的,不管你用不用这个IP上网,这个IP都是属于你的动态IP则是在使用的时候由DHCP服务器临时分配给你的,不用则不分配在网络中如果设置了一部分静态IP地 ...

  9. 早安Visual Studio!一次重构之旅,夏洛特烦恼

    vs问题描述 我的IDE版本是vs2013,今天新开发了一个功能,是一个接口程序,当F5调试时,出现了莫名的错误,为什么呢?因为vs弹出了下面的一个框,只说是“未将对象引用设置到对象实例“. 点击”确 ...

  10. 开发者最常用的 8 款 Sublime Text 3 插件

    转载于:http://www.itxuexiwang.com/a/liunxjishu/2016/0228/177.html?1456925631Sublime Text作为一个尽为人知的代码编辑器, ...