'Objective-C Bluetooth: Read SERVICE DATA by advertising

I am sending Advertising-Data from an embedded device to the iPad. This data are tagged with the "Service Data"-AD type (0x16). When I am reading the advertisementData with the delegate didDiscoverPeripheral then I get the following:

 Adv.-Data: {
kCBAdvDataServiceData =     {
    "Unknown (<fdf0>)" = <01020305>;
};
kCBAdvDataServiceUUIDs =     (
    "Unknown (<fdf0>)"
);

The Service 0xFDF0 is chosen by me. And now I need to get at the bytes 0x01, 0x02, 0x03, 0x05 which are data of the service 0xFDF0 with the key kCBAdvDataServiceData.

It would be perfect if I afterwards would have an array with these 4 bytes. I tried for so long but the nearest thing i got was the string "Unknown (< fdf0>)" = <01020305>.



Solution 1:[1]

Assuming your Adv Data Dictionary is called current_adv_dic:

NSArray *aa4 = [current_adv_dic valueForKey:@"kCBAdvDataServiceData"];
NSString *ss2 = [NSString stringWithFormat:@"%@",aa4];
Byte AdvDataArray[ss2.length];
NSLog(@"AdvDataArray: ");
for(int i=0; i<ss2.length; i++){
    AdvDataArray[i]=[ss2 characterAtIndex:i];
    printf("%x,",AdvDataArray[i]);
}
printf("\r\n");

Be aware that the first Byte is the '{' char, followed by 0x0a for LineFeed, then spaces, etc .. Example: 7b,a,20,20,20,20,22,55,6e,6b,6e,6f,77,6e,20,28,3c, then you'll find your Service Data .. you can then convert UniChars to Byte / Hex values by traditional methods.

Solution 2:[2]

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    NSString *serviceData = [advertisementData valueForKey:@"kCBAdvDataServiceData"];
    NSString *devInfo = [self serviceDataValue:@"Device Information" withData:serviceData];

    devInfo = [[devInfo stringByReplacingOccurrencesOfString:@" " withString:@""] uppercaseString];

    NSLog(@"ServiceData: %@", serviceData);
    NSLog(@"Data: %@", devInfo);
}

- (NSString *)serviceDataValue:(NSString *)key withData:(NSString *)data
{
    if (!data) return NULL;

    data = [NSString stringWithFormat:@"%@", data];

    NSError *error = NULL;
    NSString *pattern = [NSString stringWithFormat:@"\"%@\" = <(.*)>", key];
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];
    if (!error)
    {
        NSTextCheckingResult *match =
        [regex firstMatchInString:data options:0 range:NSMakeRange(0, data.length)];

        if (match.numberOfRanges > 1)
        {
            return [data substringWithRange:[match rangeAtIndex:1]];
        }

    }

    return NULL;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MoonChild7th
Solution 2 pkamb