2

I have set up some data transfer function, using CoreBluetooth CBL2CAPChannel, in a Swift iOS app. Here is the function for sending data:

func sendData(_ outStream: OutputStream) -> Bool {
    let data = tranferBlock! // tranferBlock holds some .utf8 data.
    let bytesWritten = data.withUnsafeBytes {outStream.write($0, maxLength: data.count)}

    if bytesWritten > 0 {
        tranferBlock = nil
        return true
    }

    return false
}

And here is the function for receiving data:

func receiveData(_ inStream: InputStream) {
    let bufLength = 1024
    let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufLength)
    let bytesRead = inStream.read(buffer, maxLength: bufLength)

    if let string = String(bytesNoCopy: buffer,
                           length: bytesRead,
                           encoding: .utf8,
                           freeWhenDone: false) {
        print("READ-L2CAPData:\(bytesRead):\(string)")
        if bytesRead != 0 {
            receiveBuffer = string // receiveBuffer holds the received data.
            let ntfc = NotificationCenter.default
            ntfc.post(name:Notification.Name(rawValue: "DATACAMEIN"),
                      object: nil, userInfo: nil)
        }
    }
}

I can say, it is working, because this allows me to transfer data. But there is one issue: I do not receive data the same way I send it. For example, let us say I send data in 3 packets, like this:

.......
tranferBlock = Data("aaaAAAaaa".utf8)
sendData(outStream)
tranferBlock = Data("bbbBBBbbb".utf8)
sendData(outStream)
tranferBlock = Data("cccCCCccc".utf8)
sendData(outStream)
.......

I would expect, in that case to receive the data in 3 packets, at about the same pace I have sent them:

aaaAAAaaa
bbbBBBbbb
cccCCCccc

But instead I receive one packet:

aaaAAAaaabbbBBBbbbcccCCCccc

And very often, for some reason that I do not know, only when I kill the sending app.

I would like to know what I need to change to receive the data the way I expect.

Michel
  • 10,303
  • 17
  • 82
  • 179
  • L2CAP provides a *stream* similar to TCP, it is not a datagram service like UDP. You will need to add your own framing in order to recover message blocks from the stream. – Paulw11 Aug 24 '19 at 12:47
  • Have you scheduled the streams in the runloop? If you have based your code on my L2CapDemo code then I assume you have. – Paulw11 Aug 24 '19 at 12:56
  • I don't think I have scheduled the streams in the runloop (At least not that I am aware of). – Michel Aug 24 '19 at 17:33
  • You need to. That may be why you aren't getting the delegate callbacks. See https://github.com/paulw11/L2CapDemo/blob/master/L2CapDemo/CentralViewController.swift – Paulw11 Aug 24 '19 at 20:46
  • OK I will take a look. But which "delegate callbacks" are you referring to that I am not getting? (I mean a callback to which function?) – Michel Aug 25 '19 at 03:04
  • In your previous question you said you weren't getting calls to the stream handle functions; this is a symptom of not having scheduled the stream on the runloop. – Paulw11 Aug 25 '19 at 03:25
  • Right, that was the previous question. But in the current situation I am getting the call. So this issue is solved. As a matter of fact, the reason was different. I only needed to make a (manual) call to sendData, a return of false automatically initiating a later call to the stream handle functions. – Michel Aug 25 '19 at 03:33
  • @Paulw11. I just had a look at the link you mention. I suppose when you write "scheduled the streams in the runloop"; you are referring to these lines of your code: "channel.in(out)putStream.schedule(in: RunLoop.current, forMode: .default)". After also checking my own code for comparison, I found that I also use similar lines of code. So I assume my problem must be due to some other issue. – Michel Aug 25 '19 at 03:33

1 Answers1

0

Stream-based protocols do not support the framing you're after. You can't rely on the amount of bytes that are coalesced into one logical packet in the underlying protocol layers. If you need a framing, define one on the application layer.

DrMickeyLauer
  • 4,455
  • 3
  • 31
  • 67