1. Welcome to the new MacRumors forums. See our announcement and read our FAQ

Resolved Data over bluetooth using RFCOMMChannel is split up incorrectly

Discussion in 'Mac Programming' started by Tweetdezweet, May 16, 2013.

  1. Tweetdezweet, May 16, 2013
    Last edited: Jun 10, 2013

    macrumors newbie

    #1
    Hi all, I am new to objective-c and mostly have experience in COBOL and Java.
    As part of my internship project I have to connect a Mac computer with a custom build device over bluetooth.
    All commands are sent through a bi-directional serial connection.
    (9600 baud, 8 bit, no parity, no handshake)

    The documentation on bluetooth was rather sparse but I did manage to get the devices to pair.
    The most useful example I copied and tweaked as needed I found here.

    On the Mac I am receiving data from the other device but it splits up the data incorrectly.
    For instance when the state of the device changes it sends the following command over bluetooth:
    w31CRLF, where w stands for state change and 31 are the parameters and CRLF is a Carriage Return followed by a LineFeed.

    When I log the incoming data using the rfcommChannelData delegate method it only takes the alphanumeric value and logs the numerical + Carriage return separately, following by the LineFeed as in the following output in the console:

    Code:
    2013-05-15 16:56:20.581 TimeBurger[4144:303] received: w (1)
    2013-05-15 16:56:20.589 TimeBurger[4144:303] received: 33
     (4)
    2013-05-15 16:56:21.568 TimeBurger[4144:303] received: w (1)
    2013-05-15 16:56:21.569 TimeBurger[4144:303] received: 31
     (4)
    2013-05-15 16:56:22.190 TimeBurger[4144:303] received: w (1)
    2013-05-15 16:56:22.191 TimeBurger[4144:303] received: 21
     (4)
    
    
    note that I added the length passed to rfcommChannelData in the log to doublecheck the incorrect splitting up

    the openConnection delegate method as I have it atm:
    Code:
    //Open the connection.
    -(BOOL) openConnection:(BluetoothRFCOMMChannelID *) chanId{
        IOBluetoothRFCOMMChannel *channel;
        if ([_btDevice openRFCOMMChannelAsync:&channel withChannelID:*chanId delegate:self] != kIOReturnSuccess) { // after connection it is established.. the delegates methoed are triggered.
            NSLog(@"Couldn't open channel");
            return NO;
        }
        [channel setSerialParameters: 9600 dataBits: 8 parity: kBluetoothRFCOMMParityTypeNoParity stopBits: 2];
        [channel closeChannel];
        return YES;
    }
    

    the rfcommChannelData delegate method:
    Code:
    //reading data from rfcomm
    - (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel data:(void *)dataPointer length:(size_t)dataLength {    
        NSString *newStr = [[NSString alloc] initWithBytes:dataPointer length:dataLength encoding:NSUTF8StringEncoding];
        
        NSLog(@"received: %@ (%zu)",newStr, dataLength);
        
    //    NSLog(@"received lengt: %zu",dataLength);
    }
    
    I have used the following encoding types as well during test but with the same result:
    NSASCIIStringEncoding
    NSUTF8StringEncoding
    NSWindowsCP1250StringEncoding

    I have spend a lot of time looking for a solution over the past two days so I would truely appreciate any help
     
  2. Moderator

    robbieduncan

    Staff Member

    #2
    What makes you so sure the device is not sending the string split as you see it receiving? Or perhaps this is simply timing: the Mac layer may split based on time. Can you not simply accumulate the string until the CRLF terminator is seen?
     
  3. macrumors newbie

    #3
    When I pair the device with my macbook and look for incoming commands by using the screen command in a terminal window I get the command without any splitting up.

    Accumulating the string until the CRLF terminator is seen is an option but I was hoping for a more "elegant" solution.

    Is there a way to determine if it is a timing issue and if so, is there a way to influence that timing?

    thx for your quick answer :)
     
  4. Moderator

    robbieduncan

    Staff Member

    #4
    Erm the screen command is probably just echoing exactly what comes in.

    So if it receives two data packets only one of which has a CRLF at the end this will get printed on the same line. So this does not prove that there is any different behavior from what you are seeing. Essentially it's doing the accumulation on screen...

    Unless you can alter the time the Bluetooth stack waits for more data before passing that to you there is no way. Given a long enough string before CRLF you'd always see this so the correct answer is for you to accumulate and split on CRLF.
     
  5. macrumors newbie

    #5
    oki thx, in that case I am going to accumulate and split on CRLF

    really awesome to get such a fast reply after 2 frustrating days of googling :)
     
  6. Moderator

    robbieduncan

    Staff Member

    #6
    Not a problem: I did some programming with the Bluetooth framework way back in the day so am familiar with the lack of examples!
     

Share This Page