1

I successfully open RFCOMM Channel to Lego EV3 brick with code:

IOBluetoothDevice *device = [IOBluetoothDevice deviceWithAddressString:@"xxxxxxxxxxxx"];
IOBluetoothRFCOMMChannel *rfCommChannel;
IOBluetoothSDPUUID *sppServiceUUID = [IOBluetoothSDPUUID uuid16:kBluetoothSDPUUID16ServiceClassSerialPort];

IOBluetoothSDPServiceRecord *sppServiceRecord = [device getServiceRecordForUUID:sppServiceUUID];

if ( sppServiceRecord == nil )
{
    NSLog( @"Error - no spp service in selected device." );
}

UInt8   rfcommChannelID;
if ( [sppServiceRecord getRFCOMMChannelID:&rfcommChannelID] != kIOReturnSuccess )
{
    NSLog( @"Error - no spp service in selected device." );
}

if ( ( [device openRFCOMMChannelAsync:&rfCommChannel withChannelID:rfcommChannelID delegate:d] != kIOReturnSuccess ) && ( rfCommChannel != nil ) )
{
    NSLog( @"Error - open sequence failed." );
}

Now I wish to send direct command:

unsigned char play_tone[] = {0x0F,0x00,0x00,0x00,0x80,0x00,0x00,0x94,0x01,0x81,0x02,0x82,0xE8,0x03,0x82,0xE8,0x03};

over RFCOMM Channel using class IOBluetoothRFCOMMChannel method:

- (IOReturn)writeSync:(void *)data length:(UInt16)length

I tried to do send it using different ways but none of them worked. How should I do it properly?

  • Does writeSync (or anything else) return an error? Can you post a link to the entire XCode project? – David Lechner Oct 25 '14 at 22:01
  • Link to git repository: github.com/mclientx/direct-commands-over-bluetooth. writeSync returns kIOReturnSuccess. Delegates rfcommChannelOpenComplete, rfcommChannelQueueSpaceAvailable and rfcommChannelFlowControlChanged are invoked but not rfcommChannelWriteComplete. – user4053 Oct 26 '14 at 9:08
2

I have found solution. I create category NSString+NSStringHexToByte:

NSString+NSStringHexToBytes.h

#import <Foundation/Foundation.h>

@interface NSString (NSStringHexToBytes)
+ (NSData *)dataWithString:(NSString *)string;
@end

NSString+NSStringHexToBytes.m

#import "NSString+NSStringHexToBytes.h"

@implementation NSString (NSStringHexToBytes)

+ (NSData *)dataWithString:(NSString *)string
{
    string = [string stringByReplacingOccurrencesOfString:@"0x" withString:@""];

    NSCharacterSet *notAllowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:@"abcdefABCDEF1234567890"] invertedSet];
    string = [[string componentsSeparatedByCharactersInSet:notAllowedCharacters] componentsJoinedByString:@""];

    const char *cString = [string cStringUsingEncoding:NSASCIIStringEncoding];
    const char *idx = cString;
    unsigned char result[[string length] / 2];
    size_t count = 0;

    for(count = 0; count < sizeof(result)/sizeof(result[0]); count++)
    {
        sscanf(idx, "%2hhx", &result[count]);
        idx += 2 * sizeof(char);
    }

    return [[NSData alloc] initWithBytes:result length:sizeof(result)];
}

and now:

NSString* playTone= @"0f0000008000009401810282e80382e803";
NSData* data = [NSString dataWithString:playTone];
[self sendMessage:data toChannel:rfcommChannel];

where sendMessage is:

-(void)sendMessage:(NSData*)data toChannel:(IOBluetoothRFCOMMChannel*)rfcommChannel
{
    [rfcommChannel writeSync:(void*)data.bytes length:data.length];
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.