蓝牙

iOS蓝牙4.0 BLE开发总结

非自写,转过来做个笔记,原文来自这里

关于具体如何开发 iOS 蓝牙,推荐如下一些博客。

Core Bluetooth框架之一:Central与Peripheral

Core Bluetooth框架之二:后台处理

Core Bluetooth框架之三:最佳实践

为什么选择蓝牙技术,目前主流三种无线技术(WIFI,蓝牙,Zigbee)对比

要了解一项技术,最好先了解一下历史。1994年,爱立信一位工程师,为了解除日益增多的连接线缆的烦恼,发明了一种名为蓝牙的短距离无线通信技术。自2001年发布蓝牙1.1版本技术规范,一群诺基亚的工程师就开始畅想,在若干年后,如何让智能移动设备与周边的嵌入式设备连接的时间更长,从而使得智能移动设备成为与周边10m范围内各种电子产品通信的中枢。经过10年的努力,蓝牙技术联盟终于在2011年发布了里程碑版本的蓝牙4.0技术规范,其中最具吸引力的就是低功耗蓝牙技术规范。

在无线技术迅猛发展的今天 ,蓝牙技术到底是一个什么位置,可以通过下图做一个简单的了解。

[图片上传失败...(image-445440-1645415989275)]

目前市场上影响力最大的三种无线技术,蓝牙,WIFI和Zigbee。

[图片上传失败...(image-6a3f3e-1645415989275)]

为什么要选择蓝牙,不用 WIFI(尤其是一些可穿戴设备),很关键的原因是因为蓝牙成本比 WIFI 低,而且非常省电,相信你并不期望你的手环要每天充电一次吧,那蓝牙传输速度慢怎么办呢,对于一些可穿戴设备而言,监控个心跳,看看每天走了多少步,这个有多少大数据要去传输呢?再说蓝牙传输速度也还好,慢是 iOS 系统限制的问题,不是蓝牙标准本身的问题,下文会说明。

什么是蓝牙4.0

蓝牙4.0是蓝牙3.0+HS规范的补充,专门面向对成本和功耗都有较高要求的无线方案,可广泛用于卫生保健、体育健身、家庭娱乐、安全保障等诸多领域。

它支持两种部署方式:双模式和单模式。双模式中,低功耗蓝牙功能集成在现有的经典蓝牙控制器中,或再在现有经典蓝牙技术(2.1+EDR/3.0+HS)芯片上增加低功耗堆栈,整体架构基本不变,因此成本增加有限。

单模式面向高度集成、紧凑的设备,使用一个轻量级连接层(Link Layer)提供超低功耗的待机模式操作、简单设备恢复和可靠的点对多点数据传输,还能让联网传感器在蓝牙传输中安排好低功耗蓝牙流量的次序,同时还有高级节能和安全加密连接。

并不是所有手机都支持蓝牙4.0技术,iPhone需要4S以上的手机,安卓需要系统4.3及以上的版本。

蓝牙4.0的三种模式

[图片上传失败...(image-f36469-1645415989275)]

从上图我们可以发现,全新的蓝牙4.0技术并不是一种技术,而是由传统蓝牙,高速蓝牙和低功耗蓝牙合而为一的一种标准。并且这三种蓝牙可以组合使用,也可以单独使用。

其中,低功耗蓝牙即BLE是蓝牙4.0的核心规范。毫不夸张的说,蓝牙4.0为什么可以成为改变生活的原因,就是因为BLE,低功耗蓝牙的产生。因为一切智能设备,都需要电,电量用完,设备就是一堆废铁。

然而,低功耗是硬件上的事情,跟我们手机 APP 有什么关系,APP 根本就不关心你耗电不耗电,我只写我的客户端就好了啊。实际上,与 APP 还是有关系的,正是因为有 BLE 和传统蓝牙,市场上是有三类蓝牙产品的。如果你不知道你在为哪一类产品开发程序,你会遇到很多麻烦。

比如说,要你用 BLE 传输音频数据,如果你不知道传音频是传统蓝牙的功能,你可能会白辛苦很久而达不到效果。

再举个例子,如果要你监控来电短信或者邮件等其他信息,然后通过 APP 发送到蓝牙设备。如果你不知道这是 ANCS(Apple Notification Center Service)的工作(该工作需要在蓝牙外设上直接根据蓝牙协议来实现,没 APP 什么事情),而自己傻傻的去找检测来电短信的办法,然后还要在程序退到后台依然能起作用,并通过 BLE 发送到设备,那可能你的工作中会充满烦恼。

所以,作为 iOS 工程师,第一件事情,就是要区分你正在开发的 APP 是为单模蓝牙,还是双模蓝牙;仅传统蓝牙是不需要 APP 的,譬如市面上大多数的蓝牙音箱,只要连上电脑或者手机,在电脑或者手机设备上播放音乐,系统底层就可以通过传统蓝牙协议,将音频数据传到蓝牙音箱上播放(这里并没有 APP 什么事情)。

总的来说,就是传统蓝牙部分在APP上不可控,在 iOS 上,更是连判断在设置中是否连接了传统蓝牙都办不到,iOS 可控的部分,系统提供接口去给工程师开发 APP 的部分,只有 BLE 部分(这才是大家在iPhone上使用蓝牙,觉得速度慢的原因,因为iOS系统根本没开放高速蓝牙和传统蓝牙)。

那为什么还要区分单模,双模呢,知道又如何,传统蓝牙部分都无法控制,原因在哪?答案在于这里说的不可控,是指在 iOS 上限制了,但是在 iPhone 硬件上是可以知道的(所以 iPhone 越狱之后,会有一些第三方插件如AIRBLUE SHARING,可以支持两个手机之间用蓝牙传输文件,速度也不慢)。

关于 iPhone 蓝牙开发注意事项

1)iOS 系统本身只开放了 蓝牙 BLE 部分,而且蓝牙 BLE 并不是用来给你传输文件的,指望使用 iOS 蓝牙开发两个手机之间能快速传输文件这种 APP 的同学就算了。

这点你要深切的理解,苹果之所以给他们装上蓝牙不过是让你练练蓝牙耳机啊,蓝牙音箱,玩玩可穿戴设备之类的。为什么苹果要这样限制呢?因为早期非越狱苹果上,用户听音乐都是要从商店花钱购买的,如果你用蓝牙把歌曲传给别人,那不是侵权了么,所以,苹果在硬件上面就把你传输文件给限制了。

当然,也不是完全没办法,越狱安装第三方蓝牙插件,就可以使用蓝牙4.0所有功能,传输文件当然也没压力,甚至 iPhone 和 Android 之间都能配对并且传输文件。

那不越狱,要开发传输文件的功能呢?也能传输,无非是速度奇慢无比,实测只有 1-2k/s,所以要传也只能传输很小的文件,想传输一首 mp3,就算了吧。(有没有私有蓝牙 Api 可以调用的呢,应该有吧,没研究过,被拒风险大)

2)iPhone 手机最多能同时连接多少蓝牙设备

官方文档,以及蓝牙底层协议,说明理论上可以支持到同时连接 7 个,但这 7 个能同时正常工作么?不得而知,毕竟对于 iOS 而言,蓝牙也是一种资源,同时连接和同时使用消耗,占用的资源肯定不同,而且不同手机,性能也不同,说不定 iPhone 5 同时能正常使用 3 个连接,iPhone 6s 能同时支持 5 个,这个需要进一步实际测试。

3)开发完了蓝牙 APP,有什么工具可以协助蓝牙测试

Xcode 模拟器并不能来测试蓝牙,蓝牙需要在真机上调测。

如果你开发的蓝牙 APP 是作为设备端(CBPeripheral),那很幸运,在 Mac 电脑上可以安装一款叫做 LightBlue 的应用,该应用作为中心端,扫描周边设备,同时扫描设备的服务和特征,可以读取和发送任意数据来进行交互测试(注意这里,可以发送任意数据,这样对调测而言是非常方便的)。这样的话,你只需要你的 iPhone 手机装上你的 APP,你的 Mac 电脑装上 LightBlue 软件,你的电脑和手机之间就可以进行测试,一个手机足够。

如果你开发的蓝牙 APP 是作为中心端(CBCentral),那很不幸(实际上大部分蓝牙 APP 都是作为中心端来使用),至少我目前没有发现哪个 APP 可以模拟设备端来提供测试(后续有谁发现了可以分享下)。这时候你只能拿事先准备好的蓝牙外设去对接调测,但这个多少有些麻烦,比如你无法抓包去判断双方通信的协议(可能需要比较洋气的专业蓝牙测试仪器),发送的数据包是否正确,调测比较慢,短时间无法判断是哪里没对接成功。当然你自己开发一个 APP 作为设备端,提供服务,供另外一个手机来调测,这样的话,设备端 APP 可以实时打印收到的消息格式,错误等问题,调测更直观,当然这时候至少需要两个手机才能完成测试。

4)虽然 iOS 系统限制了只能使用蓝牙 BLE,但蓝牙 BLE 的传输速率到底如何呢

  • 目前用一个 iPhone 4s(iOS 7.1.2)和一个 iPhone 5(iOS 9.2) 之间做一个文件传输测试,发现平均速率只有 1 k/s,相当缓慢
  • 如果用一个 iPhone 6(iOS 9.2) 和一个 iPhone 5(iOS 9.2) 之间做一个文件传输测试,发现平均速率只有 1.8 k/s,相对于上面而言略有提升

该文件传输测试,是在一个特征值上重复写数据来测试了,可能有人会想到如果同时写多个特征值呢,速度会不会提升?答案是不会,同时写 2 个特征值,原有每个特征值的速率会减半,也就是总的速率并不会改变。

5)关于 iOS 上蓝牙 BLE 一次读写(注意是一次读写,不是一共读写)最大能读写多少个字节的疑问

这个在网上搜了一些资料,发现没有一个统一的说法,说法都有些偏差,不知道是不是因为对接了不同的蓝牙外设带来的差异,此处给出一个用两个 iPhone 手机测试,一个做中心端,一个做设备端得到的结论,仅供参考。

目前用一个 iPhone 4s(iOS 7.1.2)和一个 iPhone 5(iOS 9.2) 之间做一个一次读写最大字节数的测试:

  • 在 iOS 7 上,一次读的数据最大只能读到 134 个字节(包括 134),大于 134 的,系统直接截断,导致数据丢失
  • 在 iOS 9 上,一次读的最大数据只能读到 628 个字节(包括 628),大于 628 的,系统直接截断,导致数据丢失
  • 如果是 iOS 9 和 iOS 7 蓝牙互通,iOS 9 上读取数据范围在(156,628)之间的,iOS 7 系统会自己拆分为 157 字节一个包后,再发往 iOS 9 这边,所以 iOS 7 这边会收到多次读请求,但请求里的 offset 不同,所以 iOS 7 这边需要根据 offset 来计算偏移并多次发送数据,iOS 9 那边并不会多次收到读数据回调,只会收到一次回调
  • 在 iOS 7 上,一次写的数据最大只能写 155 个字节(包括 155),大于 155 的,系统直接返回错误 Unknown error
  • 在 iOS 9 上,一次写的最大数据只能写 512 个字节(包括 512),大于 512 的,系统直接返回错误 Unknown error
  • 如果是 iOS 9 和 iOS 7 蓝牙互通,iOS 9 上发送数据范围在(155,512)之间的,iOS 7 系统收到之后会自己拆分为 153 字节一个包再报给上层,所以 iOS 7 这边会收到多次写请求,但请求里的 offset 不同,iOS 7 这边需要根据 offset 来合并数据

6)开发 iOS 蓝牙设备端(CBPeripheral)过程中遇到的问题

相对于开发中心端,从 CBPeripheralManager 相关接口来看,作为设备端,以下几种场景 iOS 并没有提供接口(作为中心端都可以实现)

  • 设备端无法知道当前有中心端连接上来了,除非中心端发起订阅,读写请求,才知道有中心端连上来
  • 设备端不知道中心端断开,如果是中心端主动发起断开,设备端无法得知
  • 设备端不能主动断开与中心端的连接

对于以上几种情况,iOS 没有提供相关的接口来处理,如果是作为设备端,此时要维护和保存一些中心端相关的数据,但又不知道中心端已经断开的情况下,可能会导致设备端资源无法释放和保存,状态也没办法同步。

在系统没有提供接口的情况下,如果要实现该需求,可以参考以下的思路(底层没有接口,只能在上层数据包里自己设计协议来处理)

  • 设备端和中心端约定某个可以订阅的特征,中心端连接成功就订阅这个特征,通知设备端中心端连接上来,断开之前取消订阅这个特征
  • 不采用订阅特征,也可以采用读或者写某个特征,来通知设备端连上以及断开

7)作为中心端,连接上蓝牙设备之后,如何获取蓝牙设备的 MAC 地址

据说安卓有系统接口直接可以获取蓝牙外设的 MAC 地址,但很遗憾,iOS 没有提供这样的机制,如果要获取外设的 MAC 地址,有两种做法(都需要和外设硬件工程师商量方案):

  • 在蓝牙外设广播里,提供 MAC 地址,这样中心端在扫描外设的时候,可以直接读取该广播上的值,从而拿到 MAC 地址
  • 可以在外设的某个服务的特征里,提供 MAC 的地址的读取,但前提是要先协商好读取哪个特征,UUID是多少

8)为什么两个 iPhone 手机都打开蓝牙之后,还是相互搜不到对方呢

两台设备,要相互知道对方,唯一的办法,只能是至少有一个人告诉对方,我是谁。如果两台设备都不说话,那肯定不知道对方是蓝牙设备的身份。所以,蓝牙连接的过程,实际上就是一个沟通的过程,在蓝牙设备中,说话是通过广播一段无线信号实现,一台蓝牙设备是不能同时广播和接收广播,因为目前芯片还没那么强大。

在蓝牙通信中,分为中心端和设备端。而通常手机都处在中心端状态,也就是只能接收广播,而自己没有向周围发送广播。所以两台手机之间一般是无法发现对方的(因为大家都是中心端)。除非,你写一段程序,让手机向周围发送广播。

目前,作为中心端的设备,是可以与多个设备端进行连接的,而作为设备端的设备,通常只能与一个中心端进行连接,通常在与一个中心端相连后,设备就会关闭广播。

所以,在开发过程中,可能你的身边有多个蓝牙设备处于运行状态,但是一个也搜索不到,那就是因为别人的手机已经连接了。然而,在蓝牙设备上,并不是在连接之后就必须关闭广播,是可以在芯片上实现让他继续广播的,也就是其它中心端还是可以搜到这个设备,这个取决于应用场景。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容