美文网首页
三、用iPhone实现一个外设CBPeripheralManag

三、用iPhone实现一个外设CBPeripheralManag

作者: LucXion | 来源:发表于2023-05-07 22:51 被阅读0次

    Peripheral规范:对外广播Peripheral,发布Characteristic,对连接的Central做读写请求的响应,发送Characteristic更新后的值给Central

    一、外设的UUID

    外设的UUID有两种:
    一:16位通用UUID,以 "180D" 为例:"180D"是Bluetooth SIG定义的16位通用UUID,用于识别心率Service,等于128位 "0000180D-0000-1000-8000-00805F9B34FB",当你使用了一些通用的UUID,那么查询服务的时候,UUID在控制台中的输出就是对应的功能,比如 Heart Rate
    二:128位 UUID,用于自定义服务、特征,可以通过 $uuidgen 在终端生成。

    二、初始化 CBPeripheralManager
    // 主服务,primary = true,主服务可以直接被扫描到
        lazy var s1:CBMutableService = CBMutableService.init(type: CBUUID.init(string: s1UUID), primary: true)
    // 特征
    // 1.value != nil ,代表特征值不可变,那么ATT的读写权限(特征许可)permissions 必须是readable,且不会响应中心设备的读取请求,直接返回值
    // 2.value = nil,我们可以通过代理- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request;动态响应中心设备的读取请求
        lazy var s1c1:CBMutableCharacteristic = CBMutableCharacteristic.init(type: CBUUID.init(string: s1c1UUID), properties: [.read], value: "123".data(using: .utf8), permissions: .readable)
    // 描述
        lazy var s1c1Des:CBMutableDescriptor = CBMutableDescriptor.init(type: CBUUID(string: CBUUIDCharacteristicUserDescriptionString), value: "我是s1c1的特征描述")
    
    // 初始化外设
        peripheralManager = CBPeripheralManager.init(delegate: self, queue: nil)
    
    三、构建服务树
    // 一、与中心设备相似,都是验证设备的可用性,但中心设备验证后会直接发起连接,而外设则是在验证设备可用性后构建服务树
        func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
            if(peripheral.state == .poweredOn){
                s1.characteristics = [s1c1 as! CBCharacteristic,s1c2 as! CBCharacteristic] 
                s2.characteristics = [s2c1]
                peripheral.add(s2)
                s1.includedServices = [s2]
                peripheral.add(s1)
            }
        }
    // 二、构建服务树成功,开始广播
        func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
            if(error == nil){
                // 构建服务树成功
                // 特别注意,服务是按添加顺序逐个响应的,只有等到最后一个添加的服务响应成功了,再去广播服务
                if(service.uuid == s1.uuid){
                   let jsonData : [String:Any] = [
                        CBAdvertisementDataServiceUUIDsKey:[s1.uuid,s2.uuid]
                    ]
                     // 发布服务以后,设备将服务、特征保存,不能再改变
                    peripheral.startAdvertising(jsonData)
                }
            }
        }
    
    // 三、广播服务回调
        func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {
            
            if(error != nil){
                appendPeripheralInfo(content: "广播服务失败 \(error.debugDescription)")
            }else {
                appendPeripheralInfo(content: "广播服务成功")
            }
        }
    
    四、只需要对中心设备的请求做出响应

    每个请求都要有respond与之对应

    // appendPeripheralInfo 是输出内容到控制台的方法,直接忽略,可帮助理解
        func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
            appendPeripheralInfo(content: "接到读请求")
            // 接到读写请求的正确处理流程
            // 1.判断是否是需要我们处理的 characteristic
            if(request.characteristic.uuid.isEqual(s1c1.uuid)){
                // 2.判断请求offset是否越界
                if(request.offset > s1c1.value?.count ?? 0){
                    peripheral.respond(to: request, withResult: .invalidOffset)
                }else {
    
                    let maxLength = s1c1.value?.count ?? 0 - request.offset
                    let dataLength = min(request.value?.count ?? 0, maxLength)
                    let data = s1c1.value?.subdata(in: request.offset..<request.offset+dataLength)
                    
                    request.value = data
                    peripheral.respond(to: request, withResult: .success)
                }
            }
        }
    
        func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
            appendPeripheralInfo(content: "接到写请求")
            let a = requests.first!.value!
            appendPeripheralInfo(content: String.init(data: a, encoding: .utf8)!)
            peripheral.respond(to: requests.first!, withResult: CBATTError.success)
            appendPeripheralInfo(content: " success")
        }
    
        func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
            appendPeripheralInfo(content: "接到订阅请求")
            let updatedValue = "订阅信息".data(using: .utf8)
            peripheral.updateValue(updatedValue!, for: s1c2!, onSubscribedCentrals: nil)
        }
    

    相关文章

      网友评论

          本文标题:三、用iPhone实现一个外设CBPeripheralManag

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