From 0827dca729818131252b8ab52fad09afda384f50 Mon Sep 17 00:00:00 2001 From: Philip Peitsch Date: Tue, 10 Sep 2024 10:21:27 +1000 Subject: [PATCH] Fix support for 16 & 32-bit UUIDs on iOS (#1031) Additional UUID validation on iOS inadvertantly prevented 16 & 32-bit UUID formats from being accepted. --- src/ios/BLECentralPlugin.m | 64 +++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/ios/BLECentralPlugin.m b/src/ios/BLECentralPlugin.m index 086de15c..a6fc90cf 100644 --- a/src/ios/BLECentralPlugin.m +++ b/src/ios/BLECentralPlugin.m @@ -1110,6 +1110,21 @@ -(NSUUID*) getUUID:(CDVInvokedUrlCommand*)command argumentAtIndex:(NSUInteger)in return uuid; } +-(CBUUID*) getCBUUID:(CDVInvokedUrlCommand*)command argumentAtIndex:(NSUInteger)index { + NSLog(@"getCBUUID"); + + NSString *uuidString = [command argumentAtIndex:index withDefault:@"" andClass:[NSString class]]; + CBUUID *uuid = [self uuidStringToCBUUID:uuidString]; + if (uuid == nil) { + NSString *errorMessage = [NSString stringWithFormat:@"Malformed UUID: %@", [command argumentAtIndex:index]]; + NSLog(@"%@", errorMessage); + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + return nil; + } + return uuid; +} + // expecting deviceUUID, serviceUUID, characteristicUUID in command.arguments -(BLECommandContext*) getData:(CDVInvokedUrlCommand*)command prop:(CBCharacteristicProperties)prop { NSLog(@"getData"); @@ -1121,18 +1136,15 @@ -(BLECommandContext*) getData:(CDVInvokedUrlCommand*)command prop:(CBCharacteris return nil; } - NSUUID *serviceNSUUID = [self getUUID:command argumentAtIndex:1]; - if (serviceNSUUID == nil) { + CBUUID *serviceUUID = [self getCBUUID:command argumentAtIndex:1]; + if (serviceUUID == nil) { return nil; } - NSUUID *characteristicNSUUID = [self getUUID:command argumentAtIndex:2]; - if (characteristicNSUUID == nil) { + CBUUID *characteristicUUID = [self getCBUUID:command argumentAtIndex:2]; + if (characteristicUUID == nil) { return nil; } - - CBUUID *serviceUUID = [CBUUID UUIDWithNSUUID:serviceNSUUID]; - CBUUID *characteristicUUID = [CBUUID UUIDWithNSUUID:characteristicNSUUID]; CBPeripheral *peripheral = [self findPeripheralByUUID:deviceUUID]; @@ -1151,7 +1163,7 @@ -(BLECommandContext*) getData:(CDVInvokedUrlCommand*)command prop:(CBCharacteris if (!service) { NSString *errorMessage = [NSString stringWithFormat:@"Could not find service with UUID %@ on peripheral with UUID %@", - serviceNSUUID.UUIDString, + serviceUUID.UUIDString, peripheral.identifier.UUIDString]; NSLog(@"%@", errorMessage); pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage]; @@ -1175,8 +1187,8 @@ -(BLECommandContext*) getData:(CDVInvokedUrlCommand*)command prop:(CBCharacteris if (!characteristic) { NSString *errorMessage = [NSString stringWithFormat: @"Could not find characteristic with UUID %@ on service with UUID %@ on peripheral with UUID %@", - characteristicNSUUID.UUIDString, - serviceNSUUID.UUIDString, + characteristicUUID.UUIDString, + serviceUUID.UUIDString, peripheral.identifier.UUIDString]; NSLog(@"%@", errorMessage); pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage]; @@ -1281,22 +1293,38 @@ - (NSString*) centralManagerStateToString: (CBManagerState)state { return @"Unknown state"; } +- (CBUUID *) uuidStringToCBUUID: (id)uuidString { + if (![uuidString isKindOfClass:[NSString class]]) { + NSLog(@"Malformed UUID found: %@", uuidString); + return nil; + } + + if ([uuidString length] == 4 || [uuidString length] == 8) { + // For 16 & 32-bit uuids, attempt to convert directly + // This throws an unhandled internal inconsistency error if the format is not right + // that will crash the app + return [CBUUID UUIDWithString:uuidString]; + } + + NSUUID *nsuuid = [[NSUUID alloc]initWithUUIDString:uuidString]; + if (nsuuid == nil) { + NSLog(@"Malformed UUID found: %@", uuidString); + return nil; + } + + return [CBUUID UUIDWithNSUUID:nsuuid]; +} + - (NSArray *) uuidStringsToCBUUIDs: (NSArray *)uuidStrings { NSMutableArray *uuids = [NSMutableArray new]; for (int i = 0; i < [uuidStrings count]; i++) { NSString *uuidString = [uuidStrings objectAtIndex: i]; - if (![uuidString isKindOfClass:[NSString class]]) { - NSLog(@"Malformed UUID found: %@", uuidString); - return nil; - } - NSUUID *nsuuid = [[NSUUID alloc]initWithUUIDString:uuidString]; - if (nsuuid == nil) { - NSLog(@"Malformed UUID found: %@", uuidString); + CBUUID *uuid = [self uuidStringToCBUUID:uuidString]; + if (uuid == nil) { return nil; } - CBUUID *uuid = [CBUUID UUIDWithNSUUID:nsuuid]; [uuids addObject:uuid]; } return uuids;