美文网首页
iOS CoreBluetooth

iOS CoreBluetooth

作者: macroC | 来源:发表于2018-01-25 14:53 被阅读0次

    iOS 蓝牙编程。

    首先,本文讲述的是对等的端到端的通信,不涉及一些蓝牙外设等的硬件编程,但读懂了本文后,蓝牙外设的原理也能推测一二。本文没有详细列举所有通信的接口,不适合作为傻瓜式教程。

    简述下 IOS 端蓝牙模块。
    1.蓝牙是一种通信工具,相比网络,由于蓝牙信号的衰减,少有中继设备参与,限制了设备间的通信距离;
    2.其通信机制类似UDP,以数据包为单位,但由于其接收端是以通知实现,且不支持消息分片(但支持通知队列),因此发送大文件需要的保障,需由应用之间协商实现(会话层);
    3.蓝牙通信双方分饰两角色,即外设(peripheral)和中心(central);
    在双方建立连接过程中,外设类似服务器,是连接建立的被动一方,而中心是主动连接方。这一点很重要,在保持连接的过程中,外设没有权限主动断开连接,但可以选择性的发送消息给某些中心设备,因此,建立连接的双方具备近乎平等的关系。
    4.外设可以提供多种服务(service),可以设置某个服务为主服务(primary),每个服务可以包含多个特征(characteristic),特征(characteristic)是连接双方通信的接口(可以想象成网络连接中的套接字),自定义的服务和特征以可添加自定义的 UUID 作为唯一标识。

    然后讲一下建立连接的细节。
    1、在外设端,初始化 peripheralManager(外设管理类),添加自定义的 service 和 characteristic,并开启广播。(广播可以展示设备的身份、展示提供的服务、列出服务中的所有特征值、展示部分广播数据)

    2、在中心端,中心设备此时,便可以连接外设,连接后可以读取到外设 所有的广播信息;但外设是否已经被连接,外设端无法收到通知;

    3、中心设备在连接成功之后,主动(这里的 主动 很重要)订阅外设的某个服务中某个特征

    setNotifyValue:YES  forCharacteristic:
    

    4、之后,外设端回调了代理方法 (外设的 characteristic 属性必须是通知的,否则无法收到characteristic 上发生的任何事情,当前代理方法亦无法回调)

    peripheralManager:central:didSubscribeToCharacteristic:
    

    在方法中可以记录已连接的中心设备(参数central)。

    5、在此时,外设可以更新特征(在此时之前,无法得知是否有中心设备连接--同时也表示,旨在实现双向通信的中心设备应该主动订阅特征)向中心设备发送数据:外设端更新被订阅的特征的值

    updateValue:forCharacteristic:onSubscribedCentrals:
    

    这里发送的 value 数据有大小限制,可以在 central 实例的 maximumUpdateValueLength 属性取得。超过大小限制的话,也是会传输失败。
    方法的第三个参数 onSubscribedCentrals,可以限制部分订阅中心收到数据,设置成 nil 则全部订阅了此 characteristic 的中心都会接收到数据。

    6、当收到中心端发送的数据时,外设端会 回调代理方法:

    peripheralManager:didReceiveWriteRequests:
    

    代理方法可以读取中心端发送的数据;

    7、外设端以以下方法主动回复中心端

    respondToRequest:withResult:
    

    result参数为 CBATTError 类型枚举,表示回答此次传输的结果。

    至此,外设端实现了双向通信,也实现了作为 server,与多个中心设备通信

    8、在中心端,连接某个外设之后,便可以遍历其所有服务,和所有特征,并可以主动读取当前特征值中的公开数据

    readValueForCharacteristic:character
    

    9、而在订阅了特征值之后,收到外设的数据是通过回调如下方法实现的。

    peripheral:didUpdateValueForCharacteristic:error:
    

    10、中心端主动发送的数据,是通过向特征中写数据实现

    writeValue:forCharacteristic:type:
    

    这里 value 参数的大小,并没有明文提示,经过在 6s 和 6 设备的测试,上限为 512bytes,超过的话传输失败。
    其中 type 参数,可选的是 CBCharacteristicWriteWithResponse 和 XXXXWithoutResponse,这里应该使用,xxxxWithResponse参数。

    之后超时10秒在回调方法:

    peripheral:didWriteValueForCharacteristic:error:
    

    中等待外设端发回的回复,若超时会受到未知错误。

    至此,中心端也完成了双向通信的过程。

    TODO
    已完成demo:外设端与中心端一对多实现连接,并通信。
    未完成demo(但理论上可行):中心端与外设一对多实现连接,并通信;同一设备,同时具备外设和中心的角色;
    未尝试:中心端是否有能力在外设无感知的情况下,读取到外设的数据。

    附一个封装的通信接口
    蓝牙通信接口

    相关文章

      网友评论

          本文标题:iOS CoreBluetooth

          本文链接:https://www.haomeiwen.com/subject/vayvaxtx.html