49typedef void (^CompletionHandler)(NSError *error);
50typedef void (^ValueReadHandler)(
SGBlePeripheralQueue *peripheral, CBCharacteristic *characteristic, NSError *error);
52static const int otherErrorsMask = 0x80000000;
53static const int unexpectedError = otherErrorsMask;
54static const int invalidPeripheralIdErrorCode = otherErrorsMask | 1;
56inline int toErrorCode(NSError *error)
62 else if (error.domain == CBErrorDomain)
65 return -1 - (int)error.code;
67 else if (error.domain == CBATTErrorDomain)
70 return (
int)error.code;
72 else if (error.domain == sgBleGetErrorDomain())
75 return otherErrorsMask | (0x100 + (int)error.code);
80 return unexpectedError;
86 return ^(NSError *error) {
88 onRequestStatus(requestIndex, toErrorCode(error));
94 ValueReadHandler handler = nil;
97 handler = ^(
SGBlePeripheralQueue *peripheral, CBCharacteristic *characteristic, NSError *error) {
98 NSData *data = characteristic.value;
99 onValueRead(requestIndex, data.bytes, data.length, toErrorCode(error));
106inline NSArray<CBUUID *> *toCBUUIDArray(
const char *serviceUuids)
108 NSMutableArray<CBUUID *> *arr = nil;
111 NSArray<NSString *> *servicesList = [[NSString stringWithUTF8String:serviceUuids] componentsSeparatedByString:
@","];
112 if (servicesList.count > 0)
114 arr = [NSMutableArray<CBUUID *> arrayWithCapacity:servicesList.count];
115 for (NSString *uuidStr in servicesList)
117 CBUUID *uuid = [CBUUID UUIDWithString:uuidStr];
120 [arr addObject:uuid];
129inline NSString *toUuidsString(NSArray<CBAttribute *> *attributes)
131 NSMutableString *uuids = [[NSMutableString alloc] initWithCapacity:36 * attributes.count];
132 for (CBService *attr in attributes)
134 if (uuids.length > 0)
136 [uuids appendString:
@","];
138 [uuids appendString:attr.UUID.UUIDString.lowercaseString];
143inline const char *allocateCStr(NSString *str)
148 const char *utf8CStr = [str UTF8String];
149 cStr = (
char *)malloc(strlen(utf8CStr) + 1);
150 std::strcpy(cStr, utf8CStr);
155inline NSString *toJsonStr(CBUUID *uuid)
157 return uuid.UUIDString.lowercaseString;
160inline void appendToJsonStr(NSMutableString *jsonStr, NSArray<CBUUID *> *uuids)
162 [jsonStr appendString:
@"["];
163 NSUInteger len = uuids.count;
164 for (NSUInteger i = 0; i < len; i++)
168 [jsonStr appendString:
@","];
170 [jsonStr appendFormat:
@"\"%@\
"", toJsonStr(uuids[i])];
172 [jsonStr appendString:
@"]"];
175inline void appendToJsonStr(NSMutableString *jsonStr,
180 [jsonStr appendString:
@"["];
181 for (NSUInteger i = start; i < end; i++)
185 [jsonStr appendString:
@","];
187 [jsonStr appendFormat:
@"%d", bytes[i]];
189 [jsonStr appendString:
@"]"];
193inline void appendToJsonStr(NSMutableString *jsonStr, NSData *data)
195 std::uint8_t *bytes = (std::uint8_t *)data.bytes;
196 appendToJsonStr(jsonStr, bytes, 0, data.length);
199inline NSString *advertisementDataToJsonString(
const char *systemId, NSDictionary<NSString *, id> *advertisementData, NSNumber *RSSI)
202 NSData *manufacturerData = advertisementData[CBAdvertisementDataManufacturerDataKey];
203 NSString *localName = advertisementData[CBAdvertisementDataLocalNameKey];
204 NSDictionary<CBUUID *, NSData *> *servicesData = advertisementData[CBAdvertisementDataServiceDataKey];
205 NSArray<CBUUID *> *serviceUUIDs = advertisementData[CBAdvertisementDataServiceUUIDsKey];
206 NSArray<CBUUID *> *overflowServiceUUIDs = advertisementData[CBAdvertisementDataOverflowServiceUUIDsKey];
207 NSNumber *txPowerLevel = advertisementData[CBAdvertisementDataTxPowerLevelKey];
208 NSNumber *isConnectable = advertisementData[CBAdvertisementDataIsConnectable];
209 NSArray<CBUUID *> *solicitedServiceUUIDs = advertisementData[CBAdvertisementDataSolicitedServiceUUIDsKey];
211 NSMutableString *jsonStr = [NSMutableString
new];
212 [jsonStr appendFormat:
@"{\"systemId\
":\"%s\",", systemId];
213 if (manufacturerData && manufacturerData.length >= 2)
216 [jsonStr appendString:
@"\"manufacturersData\
":["];
217 std::uint8_t *bytes = (std::uint8_t *)manufacturerData.bytes;
218 uint16_t companyId = bytes[1] | ((uint16_t)bytes[0] << 8);
219 [jsonStr appendFormat:
@"{\"companyId\
":%d,", companyId];
220 [jsonStr appendString:
@"\"data\
":"];
221 appendToJsonStr(jsonStr, bytes, 2, manufacturerData.length);
222 [jsonStr appendString:
@"}],"];
226 [jsonStr appendFormat:
@"\"name\
":\"%@\",", localName];
228 if (isConnectable.boolValue)
230 [jsonStr appendString:
@"\"isConnectable\
":true,"];
232 if (servicesData && servicesData.count)
234 [jsonStr appendString:
@"\"servicesData\
":["];
237 for (CBUUID *uuid in servicesData)
241 [jsonStr appendString:
@","];
244 [jsonStr appendFormat:
@"{\"uuid\
":\"%@\",", toJsonStr(uuid)];
245 [jsonStr appendString:
@"\"data\
":"];
246 appendToJsonStr(jsonStr, [servicesData objectForKey:uuid]);
247 [jsonStr appendString:
@"}"];
249 [jsonStr appendString:
@"],"];
251 if (serviceUUIDs && serviceUUIDs.count)
253 [jsonStr appendString:
@"\"services\
":"];
254 appendToJsonStr(jsonStr, serviceUUIDs);
255 [jsonStr appendString:
@","];
257 if (overflowServiceUUIDs && overflowServiceUUIDs.count)
259 [jsonStr appendString:
@"\"overflowServices\
":"];
260 appendToJsonStr(jsonStr, overflowServiceUUIDs);
261 [jsonStr appendString:
@","];
263 if (solicitedServiceUUIDs && solicitedServiceUUIDs.count)
265 [jsonStr appendString:
@"\"solicitedServices\
":"];
266 appendToJsonStr(jsonStr, solicitedServiceUUIDs);
267 [jsonStr appendString:
@","];
271 [jsonStr appendFormat:
@"\"txPowerLevel\
":%@,", txPowerLevel];
273 [jsonStr appendFormat:
@"\"rssi\
":%@", RSSI];
274 [jsonStr appendString:
@"}"];
280NSMutableDictionary<CBPeripheral *, SGBlePeripheralQueue *> *getPeripherals();
282inline const char *getPeripheralId(CBPeripheral *peripheral)
284 return [[peripheral.identifier UUIDString] UTF8String];
289 CBPeripheral *peripheral = nil;
292 NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:[NSString stringWithUTF8String:peripheralId]];
293 peripheral = [getCentral() peripheralForIdentifier:uuid];
300 return [[peripheral.
peripheral.identifier UUIDString] UTF8String];
305 return [getPeripherals() objectForKey:getCBPeripheral(peripheralId)];
311 if (!sgPeripheral && onRequestStatus)
313 onRequestStatus(requestIndex, invalidPeripheralIdErrorCode);
321 if (!sgPeripheral && onRssiRead)
323 onRssiRead(std::numeric_limits<int>::min(), requestIndex, invalidPeripheralIdErrorCode);
331 if (!sgPeripheral && onValueRead)
333 onValueRead(requestIndex,
nullptr, 0, invalidPeripheralIdErrorCode);
338inline CBService *getService(
peripheral_id_t peripheralId,
const char *serviceUuidStr)
340 if (peripheralId && serviceUuidStr)
342 CBUUID *serviceUuid = [CBUUID UUIDWithString:[NSString stringWithUTF8String:serviceUuidStr]];
343 CBPeripheral *peripheral = getCBPeripheral(peripheralId);
344 for (CBService *service in peripheral.services)
346 if ([serviceUuid isEqual:service.UUID])
357 CBService *service = getService(peripheralId, serviceUuidStr);
358 if (service && characteristicUuidStr)
360 CBUUID *characteristicUuid = [CBUUID UUIDWithString:[NSString stringWithUTF8String:characteristicUuidStr]];
361 for (CBCharacteristic *characteristic in service.characteristics)
363 if ([characteristicUuid isEqual:characteristic.UUID])
365 if (instanceIndex == 0)
367 return characteristic;
Definition of the SGBleCentralManagerDelegate class.
Definition of the SGBlePeripheralQueue class.
Definition of SGBleConnectionEvent and SGBleConnectionEventReason enumerations.
A few internal functions.
std::uint32_t request_index_t
Type for the unique index of a BLE request given to this library.
Definition UnityBridge.h:20
void(* PeripheralConnectionEventCallback)(request_index_t requestIndex, peripheral_id_t peripheralId, int connectionEvent, int reason)
Callback notifying of a change of a peripheral connection state, with the reason for the change.
Definition UnityBridge.h:38
void(* RequestStatusCallback)(request_index_t requestIndex, int errorCode)
Callback notifying of the status of a BLE request.
Definition UnityBridge.h:35
void(* ValueReadCallback)(request_index_t requestIndex, const void *data, size_t length, int errorCode)
Callback notifying of the value read from a peripheral's characteristic.
Definition UnityBridge.h:44
const char * peripheral_id_t
Type for peripheral id which is the zero terminated string of the UUID assigned by the system for the...
Definition UnityBridge.h:17
void(* DiscoveredPeripheralCallback)(const char *advertisementDataJson)
Callback notifying of the discovery of a BLE peripheral, with its advertisement data as a JSON string...
Definition UnityBridge.h:32
std::uint64_t characteristic_property_t
Type for the standard BLE properties of characteristics.
Definition UnityBridge.h:26
void(* RssiReadCallback)(request_index_t requestIndex, int rssi, int errorCode)
Callback notifying of the RSSI value read from a peripheral.
Definition UnityBridge.h:41
std::uint32_t characteristic_index_t
Type for the index of a characteristic instance in a service.
Definition UnityBridge.h:23
void(* BluetoothStateUpdateCallback)(int state)
Callback notifying of a change of the host device Bluetooth state, for example radio turned on or off...
Definition UnityBridge.h:29
Implementation of CBCentralManagerDelegate protocol. Stores and notifies of discovered Bluetooth Low ...
Definition SGBleCentralManagerDelegate.h:29
Implementation of the CBPeripheralDelegate protocol. Queues up operations to be performed with a Blue...
Definition SGBlePeripheralQueue.h:44
CBPeripheral * peripheral
Gets the CBPeripheral object for this peripheral.
Definition SGBlePeripheralQueue.h:77