如何通过CBL2CAPChannel发送和接收数据

问题描述 投票:0回答:1

我正在尝试在2个iOS设备之间打开L2CAP通道并以两种方式传输数据。其中一个设备充当另一个设备作为外围设备。

在外围方面:

我发布了一个像这样的L2CAPChannel:

func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
    if peripheral.state == .poweredOn {
        peripheral.publishL2CAPChannel(withEncryption: false)
    }
}

尝试加密的真假。

然后,一旦频道发布,我从didPublishL2CAPChannel委托方法获取PSM,并创建一个具有包含PSM作为其值的特征的服务并开始宣传它。

在中央一侧:

我扫描外围设备,找到正确的外围设备,连接到它,开始发现服务,然后一旦发现服务我发现了特征。我找到了特征,读取它的值并得到了PSM。然后我这样做:

self.peripheral.openL2CAPChannel(psm)

然后我在委托方法中回调通道已打开并执行此操作:

func peripheral(_ peripheral: CBPeripheral, didOpen channel: CBL2CAPChannel?, error: Error?) {
    guard error == nil else {
        print("Couldn't open channel. Error: \(error!.localizedDescription)")
        return
    }
    self.l2capChannel = channel
    self.l2capChannel?.inputStream.delegate = self
    self.l2capChannel?.outputStream.delegate = self
    print("L2CAP channel opened with \(peripheral.name ?? "unknown")")
}

这打印:

L2CAP channel opened with mrsta’s iPad

再次在外围方面:

我在委托方法中收到回调:

func peripheralManager(_ peripheral: CBPeripheralManager, didOpen channel: CBL2CAPChannel?, error: Error?) {
    guard error == nil else {
        print("Couldn't open channel. Error: \(error!.localizedDescription)")
        return
    }
    self.l2capChannel = channel
    self.l2capChannel?.inputStream.delegate = self
    self.l2capChannel?.outputStream.delegate = self
    print("L2CAP channel opened")
}

这打印:

[CoreBluetooth] No central present! Creating a new object. This shouldn't happen.
L2CAP channel opened

到目前为止,似乎双方都打开了通道。我只是想知道上面的那条信息是什么?“没有中心礼物!......”

过了一会儿,我开始在控制台中收到这样的消息:

[CoreBluetooth] WARNING: Unknown error: 436
[CoreBluetooth] No known channel matching peer <CBPeripheral: 0x2829de120, identifier = 241BAA6F-0BFD-9F5A-1EC9-35A4FD246DF5, name = mrsta’s iPad, state = connected> with psm 192
[CoreBluetooth] WARNING: Unknown error: 431

我不知道这些是什么意思。有什么建议?

我还在双方都实现了StreamDelegate方法:

func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
    print("Stream Event occurred: \(eventCode)")
    if eventCode == .hasSpaceAvailable {
        self.tryToWrite()
    }
}

但是从不调用上面的委托方法。我尝试写这样的输出流(tryToWrite从中心侧的didOpen通道委托方法调用):

func tryToWrite() {
    let string = "Hello"
    let stringData = Data(from: string)
    let _ = stringData.withUnsafeBytes { write(stuff: $0, to: self.l2capChannel, withMaxLength: stringData.count) }
}

func write(stuff: UnsafePointer<UInt8>, to channel: CBL2CAPChannel?, withMaxLength maxLength: Int) {
    let result = channel?.outputStream.write(stuff, maxLength: maxLength)
    print("Write result: \(String(describing: result))")
}

结果是:

Write result: Optional(-1)

哪个基于文档意味着写入失败。

请告诉我,我错过了什么?打开频道后我得到的错误是什么?写入和读取数据的正确方法是什么?

ios swift core-bluetooth l2cap
1个回答
2
投票

我使用L2CAP,它正在工作。我在“didOpen”函数中所做的是

self.l2capChannel = channel

self.l2capChannel?.inputStream.delegate = self 
self.l2capChannel?.inputStream.schedule(in: .main, forMode: .defaultRunLoopMode)
self.l2capChannel?.inputStream.open()

self.l2capChannel?.outputStream.delegate = self
self.l2capChannel?.outputStream.schedule(in: .main, forMode: .defaultRunLoopMode)
self.l2capChannel?.outputStream.open()

当我不再需要它时,我关闭它们

self.l2capChannel?.inputStream.close()
self.l2capChannel?.inputStream.remove(from: .main, forMode: .defaultRunLoopMode)

self.l2capChannel?.outputStream.close()
self.l2capChannel?.outputStream.remove(from: .main, forMode: .defaultRunLoopMode)

self.l2capChannel? = nil
© www.soinside.com 2019 - 2024. All rights reserved.