android  蓝牙ble app开发中 经常会遇到很多问题,这个时候就需要用到抓包软件进行分析,单单从现象上很难鉴定是设备固件端的问题,还是我们自己app写的不对的问题。这一点是做android的是比较纠结的,因为固件端经常是和ios通信没毛问题,android问题偶尔,这个偶尔很经常出现。(固件基于cc2540 2541)

这篇记录的内容是android app开发时遇到的,但是本身的内容却是ble协议的一些内容,ios 也是一样的下一篇会记录下抓包过程与分析。

1、知识储备:

要分析ble蓝牙包 需要懂一些ble蓝牙协议栈的内容,和一些核心概念。

最关键的几个概念


Connection Events:连接事件

这个概念比较抽象,之前看了很多解释不明白,ti 宣讲会上讲ppt讲的很清楚

简单的说就是通信建立在连接事件上,每次连接事件时才是真正的通信事件,其余时间时休眠的(低功耗)

对应在程序上就是如果连接间隔的时间设置的大于 通信间隔,就会出现数据通信不流畅,没有接收到周期性数据,数据一卡顿一卡顿时而没有时而很多

android ble蓝牙服务端开发 ble蓝牙app开发教程_android

Supervision Timeout:超时时间(在这个时间内没有接收到响应就会断开)

Slave Latency:这个不好翻译,看图最实在了

理解成可以忽略的空白响应数吧

android ble蓝牙服务端开发 ble蓝牙app开发教程_ti_02

Connection Interval:连接间隔




另外还有:Advertisement InterVals 广播间隔,和名字一个意思


2、关于更新连接参数

ConnectionParameter Update Request

有阅读蓝牙协议栈和一些材料,简单的说就是主机决定连接参数的值( connection interval, slave latency, timeout),从机可以请求更新这些参数,主机决定是不是接受,接受的值是多少。所以是会出现手机接受参数后和从机请求的参数有偏差,或者甚至是拒绝(ios)。

这里不得不提到:android 和 ios  的ble开发与兼容不是一个等级。

相同点:android 和 ios 都是在手机和设备建立连接时就会默认设置这些参数,app开发是无法修改这些参数的,这些默认参数由手机厂商决定。

不同点:当产品基于功耗等的考虑是应该要修改这些参数的,都是由从机提出更新申请,ios 有保护机制当从机给的参数超过它的范围它会拒绝这些不合理参数,然后使用默认值。而android 目前(4.3 4.4)是都会接受从机的更新参数,即使不合理。这里就会照成一种 设备通信 ios可以  android出问题 而且android即使接受参数并且使用这些参数更新后还会出现和参数不和的现象,典型的就在这个timeOut上,是会比更新请求里的timeOut长而且不同手机长的时间不一样。ios 好像是长5秒


ios 的参数范围还是很有参考价值的,不然在这个范围外,ios拒绝了 ,android接受了问题就蛋疼了。

The connection parameter request may be rejected if it does not comply with all of these rules:

Interval Max * (Slave Latency + 1) ≤ 2 seconds

Interval Min ≥ 20 ms   

Interval Min + 20 ms ≤ Interval Max

Slave Latency ≤ 4

connSupervisionTimeout ≤ 6 seconds

Interval Max * (Slave Latency + 1) * 3 < connSupervisionTimeout

注:ble协议里interVal   的范围是7.5ms - 32s 


3、android连接参数的补充

ble 协议里主机是对连接参数的绝对设置权,从机只能提出更新请求是否被接受是主机决定。

手机app开发里是不存在修改这个值的api的,至少4.3 4.4 没见到,5.0不知道。BlueDroid的android ble栈源码是驱动级的,即使改了,也没用,要重新改手机的驱动文件,我是这么理解的,也不知道对不对


另外在做android ble OAD 在线更新固件时,阅读TI的sensorTag 的源码时发现它里面有个 CC_SERVICE_UUID 服务可以设置OAD连接参数。而这个连接参数修改了也就修改了我们的固件的连接参数。参看ti 的回答:

The connection control service is a separate service, and can be added by adding ccservice.c/h from Profiles/SensorProfile/. Have a look in the SensorTag project to see how it's added to the GATT server and otherwise used.

ti 的demo里有这个cc服务的添加方法,虽然和他们的回答方法不大一样,添加后确实能实现app更改更新参数的目的。


cc服务的流程也比较清晰,android主机告诉ble固件我要更新参数参数是什么什么,然后固件拿着这个参数来进行更新参请求,adnroid设备再把这个请求设成此次通信的连接参数。这个和前面所描述的android手机app开发没有主动设置连接参数的api没有矛盾,它是通过高数ble从机,从机提出更新,再完成更新确认



4、补充附件

有一些朋友像我讨要这份ti 宣讲的ppt,附在这里: