五、BLE(下)

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.

时间: 2024-11-05 18:45:40

五、BLE(下)的相关文章

Fiddler (五) Mac下使用Fiddler

Fiddler (五) Mac下使用Fiddler Fiddler是用C#开发的.  所以Fiddler不能在Mac系统中运行.  没办法直接用Fiddler来截获MAC系统中的HTTP/HTTPS,    Mac 用户怎么办呢? Fiddler可以允许“远程连接”.  我们可以利用这个间接来实现Fiddler捕获Mac系统发出的HTTP/HTTPS 阅读目录: 使用虚拟机 虚拟机的网络使用“Bridged” 模式 配置虚拟机上的Fiddler, 允许“远程连接” 获取虚拟机Windows7的I

S3C2416裸机开发系列十五_GCC下uCOS的移植(1)

S3C2416裸机开发系列十五 GCC下uCOS的移植(1) 象棋小子    1048272975 操作系统是用来管理系统硬件.软件及数据资源,控制程序运行,并为其它应用软件提供支持的一种系统软件.根据不同的种类,又可分为实时操作系统.桌面操作系统.服务器操作系统等.对于一些小型的应用,对系统实时性要求高,硬件资源有限等的情况下,应尽量避免使用复杂庞大的操作系统(如Linux),使用小型的实时操作系统(如uCOS)更能满足应用的需求.笔者此处就uCOS-II的移植作一个简单的介绍. 1. 代码准

S3C2416裸机开发系列十五_GCC下uCOS的移植(2)

S3C2416裸机开发系列十五 GCC下uCOS的移植(2) 象棋小子    1048272975 4. uCOS配置 uCOS是可裁减实时操作系统,可以根据实际的应用对内核未使用到的功能进行裁减,以进一步节省系统宝贵的硬件资源,通常可用的uCOS-II内核代码在6K~26K,这在uCOS-II配置文件os_cfg.h中进行配置,这个配置文件在源码目录为os_cfg_r.h,从目录中拷贝添加到uCOS/uCOS-II/Cfg目录中,并重命名为os_cfg.h. #ifndef OS_CFG_H

【机器学习】算法原理详细推导与实现(五):支持向量机(下)

[机器学习]算法原理详细推导与实现(五):支持向量机(下) 上一章节介绍了支持向量机的生成和求解方式,能够根据训练集依次得出\(\omega\).\(b\)的计算方式,但是如何求解需要用到核函数,将在这一章详细推导实现. 核函数 在讲核函数之前,要对上一章节得到的结果列举出来.之前需要优化的凸函数为: \[ min_{\gamma,\omega,b}->\frac{1}{2}||\omega||^2 \] \[ y^{(i)}(\omega^Tx^{(i)}+b) \geq 1 ,i=1,2,.

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

转载请注明出处:http://blog.csdn.net/lowprofile_coding/article/details/51321896 一 .前言 最近实在太忙,一个多礼拜没有更新文章了,于是今晚加班加点把demo写出来,现在都12点了才开始写文章. 1.我们的目标 把RecyclerView下拉刷新上拉加载更多加入到我们的开发者头条APP中. 2.效果图 3.实现步骤 找一个带上拉刷新下载加载更多的RecyclerView开源库,我们要站在巨人的肩膀上 下载下来自己先运行下demo,然

杭州哪里有专业的软装设计师培训机构-五色光下一个软装大师的摇篮

随着时代的不断发展,软装设计走入了人们的生活,它起源于欧陆,至今其装饰理念已然风靡了整个世界.软装是关于整体环境.空间美学.陈设艺术.生活功能.材质风格.意境体验.个性偏好,甚至风水文化等多种复杂元素的创造性融合,软装的每一个区域.每一种产品都是整体环境的有机组成部分.杭州五色光中国美院软装设计师高研班的课程是由中国美院艺术设计学院主办,艺术设计研究院承办的官方的软装研修项目,不同于社会上的其它同类项目.课程设置由吴海燕院长亲自负责,组织教学的. 五色光软装名师荟萃,主要是中国美院专家教授,硕士

linux学习(五) ubuntu下一些美化的分享

首先来一张桌面的截图,个人还是比较喜欢的这种风格: 这里主要用到的工具: Unity  Tweak  Tool   docky 启动栏 像这么好的工具,软件中心就直接可以下载啦,直接打开软件中心搜索; 第一个就是的啦,然后我们直接安装: 1. 安装完毕之后,我们就可以进入配置界面啦: 2.然后我们就可以寻找我们喜欢的主题,然后进行安装啦~我这里安装的是 gtk主题 uncomplicated 给一个网盘链接  http://pan.baidu.com/s/1bndF7gr 里面包含了四个主题;

maven学习五 Eclipse下Tomcat常用设置

Eclipse下Tomcat常用设置 1,Eclipse建立Tomcat服务 1.1 新建Server 首先这里是指,jee版的Eclipse.Eclipse是没有像MyEclipse那样集成Tomcat的,需要我们自己设置. New -> Other -> Server ,然后选择Apache下的tomcat的版本. 注意:如果Next或Finish按钮都是灰的,那么需要到Windw- > Preferences -> Server -> Runtime Environme

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

本节演示使用多线程的代码 由于示例中使用的是pthead函数 为了在windows下运行 我做了点改动 使用c++11 的thread函数 代码如下 与第一节的hwclient 配套使用 // mttest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include "zhelpers.hpp" #include <thread> void worker_routine(void* arg) { zmq::c

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

这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释上我的一些想法.做这个一方面是提升了我的阅读效果以及方便我以后阅读 另一个目的是,Javascript高级程序设计这本书内容很多也很厚,希望其他没有时间的人可以通过看这系列摘录,就可以大体学到书里面的核心内容. 绿色背景的内容是我认为比较值得注意的原著内容. 黄色背景的内容是我认为非常重要的原著内容. 我的理解会用蓝色的字体标示出来. 这章的内容较多,而且比较重要,分两篇