react-native-ble-manager 10.1.4 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/android/src/main/java/it/innove/BleManager.java +5 -5
- package/android/src/main/java/it/innove/DefaultPeripheral.java +10 -5
- package/android/src/main/java/it/innove/DefaultScanManager.java +8 -5
- package/android/src/main/java/it/innove/Peripheral.java +21 -17
- package/dist/cjs/index.js +8 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types.d.ts +3 -2
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/index.js +8 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types.d.ts +3 -2
- package/dist/esm/types.js.map +1 -1
- package/ios/BleManager-Bridging-Header.h +1 -0
- package/ios/BleManager.h +0 -28
- package/ios/BleManager.m +126 -1186
- package/ios/BleManager.swift +1185 -0
- package/ios/BleManager.xcodeproj/project.pbxproj +21 -18
- package/ios/BleManager.xcodeproj/project.xcworkspace/xcuserdata/marco.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Helper.swift +364 -0
- package/package.json +1 -1
- package/react-native-ble-manager.podspec +2 -2
- package/src/index.ts +7 -3
- package/src/types.ts +3 -2
- package/ios/BLECommandContext.h +0 -10
- package/ios/BLECommandContext.m +0 -5
- package/ios/CBPeripheral+Extensions.h +0 -16
- package/ios/CBPeripheral+Extensions.m +0 -309
- package/ios/NSData+Conversion.h +0 -11
- package/ios/NSData+Conversion.m +0 -41
package/ios/BleManager.m
CHANGED
|
@@ -1,1191 +1,131 @@
|
|
|
1
|
-
#import
|
|
2
|
-
#import "React/
|
|
3
|
-
#import "React/RCTConvert.h"
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import "React/RCTBridgeModule.h"
|
|
4
3
|
#import "React/RCTEventDispatcher.h"
|
|
5
|
-
#import "NSData+Conversion.h"
|
|
6
|
-
#import "CBPeripheral+Extensions.h"
|
|
7
|
-
#import "BLECommandContext.h"
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
@interface RCT_EXTERN_MODULE(BleManager, NSObject)
|
|
6
|
+
|
|
7
|
+
RCT_EXTERN_METHOD(start:
|
|
8
|
+
(NSDictionary *)options
|
|
9
|
+
callback:(RCTResponseSenderBlock) callback)
|
|
10
|
+
|
|
11
|
+
RCT_EXTERN_METHOD(scan:
|
|
12
|
+
(NSArray *)serviceUUIDStrings
|
|
13
|
+
timeoutSeconds:(nonnull NSNumber *)timeoutSeconds
|
|
14
|
+
allowDuplicates:(BOOL)allowDuplicates
|
|
15
|
+
scanningOptions:(nonnull NSDictionary*)scanningOptions
|
|
16
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
17
|
+
|
|
18
|
+
RCT_EXTERN_METHOD(connect:
|
|
19
|
+
(NSString *)peripheralUUID
|
|
20
|
+
options:(NSDictionary *)options
|
|
21
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
22
|
+
|
|
23
|
+
RCT_EXTERN_METHOD(disconnect:
|
|
24
|
+
(NSString *)peripheralUUID
|
|
25
|
+
force:(BOOL)force
|
|
26
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
27
|
+
|
|
28
|
+
RCT_EXTERN_METHOD(retrieveServices:
|
|
29
|
+
(NSString *)peripheralUUID
|
|
30
|
+
services:(NSArray<NSString *> *)services
|
|
31
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
32
|
+
|
|
33
|
+
RCT_EXTERN_METHOD(readRSSI:
|
|
34
|
+
(NSString *)peripheralUUID
|
|
35
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
36
|
+
|
|
37
|
+
RCT_EXTERN_METHOD(readDescriptor:
|
|
38
|
+
(NSString *)peripheralUUID
|
|
39
|
+
serviceUUID:(NSString*)serviceUUID
|
|
40
|
+
characteristicUUID:(NSString*)characteristicUUID
|
|
41
|
+
descriptorUUID:(NSString*)descriptorUUID
|
|
42
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
43
|
+
|
|
44
|
+
RCT_EXTERN_METHOD(getDiscoveredPeripherals:
|
|
45
|
+
(nonnull RCTResponseSenderBlock)callback)
|
|
46
|
+
|
|
47
|
+
RCT_EXTERN_METHOD(checkState:
|
|
48
|
+
(nonnull RCTResponseSenderBlock)callback)
|
|
49
|
+
|
|
50
|
+
RCT_EXTERN_METHOD(write:
|
|
51
|
+
(NSString *)peripheralUUID
|
|
52
|
+
serviceUUID:(NSString*)serviceUUID
|
|
53
|
+
characteristicUUID:(NSString*)characteristicUUID
|
|
54
|
+
message:(NSArray*)message
|
|
55
|
+
maxByteSize:(NSInteger)maxByteSize
|
|
56
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
57
|
+
|
|
58
|
+
RCT_EXTERN_METHOD(writeWithoutResponse:
|
|
59
|
+
(NSString *)peripheralUUID
|
|
60
|
+
serviceUUID:(NSString*)serviceUUID
|
|
61
|
+
characteristicUUID:(NSString*)characteristicUUID
|
|
62
|
+
message:(NSArray*)message
|
|
63
|
+
maxByteSize:(NSInteger)maxByteSize
|
|
64
|
+
queueSleepTime:(NSInteger)queueSleepTime
|
|
65
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
66
|
+
|
|
67
|
+
RCT_EXTERN_METHOD(read:(NSString *)peripheralUUID
|
|
68
|
+
serviceUUID:(NSString*)serviceUUID
|
|
69
|
+
characteristicUUID:(NSString*)characteristicUUID
|
|
70
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
71
|
+
|
|
72
|
+
RCT_EXTERN_METHOD(startNotification:
|
|
73
|
+
(NSString *)peripheralUUID
|
|
74
|
+
serviceUUID:(NSString*)serviceUUID
|
|
75
|
+
characteristicUUID:(NSString*)characteristicUUID
|
|
76
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
77
|
+
|
|
78
|
+
RCT_EXTERN_METHOD(stopNotification:
|
|
79
|
+
(NSString *)peripheralUUID
|
|
80
|
+
serviceUUID:(NSString*)serviceUUID
|
|
81
|
+
characteristicUUID:(NSString*)characteristicUUID
|
|
82
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
83
|
+
|
|
84
|
+
RCT_EXTERN_METHOD(getConnectedPeripherals:(NSArray *)serviceUUIDStrings
|
|
85
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
86
|
+
|
|
87
|
+
RCT_EXTERN_METHOD(isPeripheralConnected:
|
|
88
|
+
(NSString *)peripheralUUID
|
|
89
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
90
|
+
|
|
91
|
+
RCT_EXTERN_METHOD(getMaximumWriteValueLengthForWithoutResponse:
|
|
92
|
+
(NSString *)peripheralUUID
|
|
93
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
94
|
+
|
|
95
|
+
RCT_EXTERN_METHOD(getMaximumWriteValueLengthForWithResponse:
|
|
96
|
+
(NSString *)deviceUUID
|
|
97
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
98
|
+
|
|
99
|
+
// Not supported
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
RCT_EXTERN_METHOD(enableBluetooth:(nonnull RCTResponseSenderBlock)callback)
|
|
103
|
+
|
|
104
|
+
RCT_EXTERN_METHOD(getBondedPeripherals:(nonnull RCTResponseSenderBlock)callback)
|
|
105
|
+
|
|
106
|
+
RCT_EXTERN_METHOD(createBond:(NSString *)peripheralUUID
|
|
107
|
+
devicePin:(NSString *)devicePin
|
|
108
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
109
|
+
|
|
110
|
+
RCT_EXTERN_METHOD(removeBond:(NSString *)peripheralUUID
|
|
111
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
112
|
+
|
|
113
|
+
RCT_EXTERN_METHOD(removePeripheral:(NSString *)peripheralUUID
|
|
114
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
115
|
+
|
|
116
|
+
RCT_EXTERN_METHOD(requestMTU:(NSString *)peripheralUUID
|
|
117
|
+
mtu:(NSInteger)mtu
|
|
118
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
119
|
+
|
|
120
|
+
RCT_EXTERN_METHOD(requestConnectionPriority:(NSString *)peripheralUUID
|
|
121
|
+
connectionPriority:(NSInteger)connectionPriority
|
|
122
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
123
|
+
|
|
124
|
+
RCT_EXTERN_METHOD(refreshCache:(NSString *)peripheralUUID
|
|
125
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
126
|
+
|
|
127
|
+
RCT_EXTERN_METHOD(setName:(NSString *)name
|
|
128
|
+
callback:(nonnull RCTResponseSenderBlock)callback)
|
|
11
129
|
|
|
12
|
-
@implementation BleManager
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
RCT_EXPORT_MODULE();
|
|
16
|
-
|
|
17
|
-
@synthesize manager;
|
|
18
|
-
@synthesize peripherals;
|
|
19
|
-
@synthesize scanTimer;
|
|
20
|
-
static bool hasListeners = NO;
|
|
21
|
-
|
|
22
|
-
- (instancetype)init
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
if (self = [super init]) {
|
|
26
|
-
peripherals = [NSMutableSet set];
|
|
27
|
-
connectCallbacks = [NSMutableDictionary new];
|
|
28
|
-
retrieveServicesLatches = [NSMutableDictionary new];
|
|
29
|
-
readCallbacks = [NSMutableDictionary new];
|
|
30
|
-
readRSSICallbacks = [NSMutableDictionary new];
|
|
31
|
-
readDescriptorCallbacks = [NSMutableDictionary new];
|
|
32
|
-
retrieveServicesCallbacks = [NSMutableDictionary new];
|
|
33
|
-
writeCallbacks = [NSMutableDictionary new];
|
|
34
|
-
writeQueue = [NSMutableArray array];
|
|
35
|
-
notificationCallbacks = [NSMutableDictionary new];
|
|
36
|
-
stopNotificationCallbacks = [NSMutableDictionary new];
|
|
37
|
-
_instance = self;
|
|
38
|
-
NSLog(@"BleManager created");
|
|
39
|
-
|
|
40
|
-
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bridgeReloading) name:RCTBridgeWillReloadNotification object:nil];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return self;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
-(void)startObserving {
|
|
47
|
-
hasListeners = YES;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
-(void)stopObserving {
|
|
51
|
-
hasListeners = NO;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
-(void)bridgeReloading {
|
|
55
|
-
if (manager) {
|
|
56
|
-
if (self.scanTimer) {
|
|
57
|
-
[self.scanTimer invalidate];
|
|
58
|
-
self.scanTimer = nil;
|
|
59
|
-
[manager stopScan];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
manager.delegate = nil;
|
|
63
|
-
}
|
|
64
|
-
@synchronized(peripherals) {
|
|
65
|
-
for (CBPeripheral* p in peripherals) {
|
|
66
|
-
p.delegate = nil;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
peripherals = [NSMutableSet set];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
+(BOOL)requiresMainQueueSetup
|
|
74
|
-
{
|
|
75
|
-
return YES;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
- (NSArray<NSString *> *)supportedEvents
|
|
79
|
-
{
|
|
80
|
-
return @[@"BleManagerDidUpdateValueForCharacteristic", @"BleManagerStopScan", @"BleManagerDiscoverPeripheral", @"BleManagerConnectPeripheral", @"BleManagerDisconnectPeripheral", @"BleManagerDidUpdateState", @"BleManagerCentralManagerWillRestoreState", @"BleManagerDidUpdateNotificationStateFor"];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
|
|
85
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic];
|
|
86
|
-
|
|
87
|
-
if (error) {
|
|
88
|
-
NSLog(@"Error %@ :%@", characteristic.UUID, error);
|
|
89
|
-
[self invokeAndClearDictionary:readCallbacks withKey:key usingParameters:@[error, [NSNull null]]];
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
NSLog(@"Read value [%@]: (%lu) %@", characteristic.UUID, [characteristic.value length], characteristic.value);
|
|
93
|
-
|
|
94
|
-
NSMutableArray* peripheralReadCallbacks = [readCallbacks objectForKey:key];
|
|
95
|
-
if (peripheralReadCallbacks != NULL) {
|
|
96
|
-
[self invokeAndClearDictionary:readCallbacks withKey:key usingParameters:@[[NSNull null], ([characteristic.value length] > 0) ? [characteristic.value toArray] : [NSNull null]]];
|
|
97
|
-
} else {
|
|
98
|
-
if (hasListeners) {
|
|
99
|
-
[self sendEventWithName:@"BleManagerDidUpdateValueForCharacteristic" body:@{@"peripheral": peripheral.uuidAsString, @"characteristic":characteristic.UUID.UUIDString.lowercaseString, @"service":characteristic.service.UUID.UUIDString.lowercaseString, @"value": ([characteristic.value length] > 0) ? [characteristic.value toArray] : [NSNull null]}];
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(nonnull CBDescriptor *)descriptor error:(nullable NSError *)error {
|
|
105
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:descriptor.characteristic andDescriptor:descriptor];
|
|
106
|
-
|
|
107
|
-
if (error) {
|
|
108
|
-
NSLog(@"Error reading descriptor value for %@ on characteristic %@ :%@",
|
|
109
|
-
descriptor.UUID,
|
|
110
|
-
descriptor.characteristic.UUID,
|
|
111
|
-
error);
|
|
112
|
-
[self invokeAndClearDictionary:readDescriptorCallbacks withKey:key usingParameters:@[error, [NSNull null]]];
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if ([descriptor.value isKindOfClass:[NSData class]]) {
|
|
117
|
-
NSLog(@"Read value [descriptor: %@, characteristic: %@]: (%lu) %@",
|
|
118
|
-
descriptor.UUID,
|
|
119
|
-
descriptor.characteristic.UUID,
|
|
120
|
-
[(NSData *)descriptor.value length],
|
|
121
|
-
descriptor.value);
|
|
122
|
-
} else {
|
|
123
|
-
NSLog(@"Read value [descriptor: %@, characteristic: %@]: %@",
|
|
124
|
-
descriptor.UUID,
|
|
125
|
-
descriptor.characteristic.UUID,
|
|
126
|
-
descriptor.value);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
NSMutableArray* peripheralReadDescriptorCallbacks = [readDescriptorCallbacks objectForKey:key];
|
|
130
|
-
if (peripheralReadDescriptorCallbacks != NULL) {
|
|
131
|
-
// The most future proof way of doing this that I could find, other option would be running strcmp on CBUUID strings
|
|
132
|
-
// https://developer.apple.com/documentation/corebluetooth/cbuuid/characteristic_descriptors
|
|
133
|
-
if ([descriptor.value isKindOfClass:[NSData class]]) {
|
|
134
|
-
[self invokeAndClearDictionary:readDescriptorCallbacks withKey:key usingParameters:@[[NSNull null], ([descriptor.value length] > 0) ? [descriptor.value toArray] : [NSNull null]]];
|
|
135
|
-
} else if ([descriptor.value isKindOfClass:[NSNumber class]]) {
|
|
136
|
-
NSMutableData *byteData = [NSMutableData new];
|
|
137
|
-
if (descriptor.value != nil) {
|
|
138
|
-
NSNumber *number = descriptor.value;
|
|
139
|
-
unsigned long long value = number.unsignedLongLongValue;
|
|
140
|
-
[byteData appendBytes:&value length:sizeof(value)];
|
|
141
|
-
}
|
|
142
|
-
[self invokeAndClearDictionary:readDescriptorCallbacks withKey:key usingParameters:@[[NSNull null], ([byteData length] > 0) ? [byteData toArray] : [NSNull null]]];
|
|
143
|
-
} else if ([descriptor.value isKindOfClass:[NSString class]]) {
|
|
144
|
-
NSData *byteData = [descriptor.value dataUsingEncoding:NSUTF8StringEncoding];
|
|
145
|
-
[self invokeAndClearDictionary:readDescriptorCallbacks withKey:key usingParameters:@[[NSNull null], ([byteData length] > 0) ? [byteData toArray] : [NSNull null]]];
|
|
146
|
-
} else {
|
|
147
|
-
NSLog(@"Unrecognized type of descriptor: (UUID: %@, value type: %@, value: %@)", descriptor.UUID, [descriptor.value class], descriptor.value);
|
|
148
|
-
[self invokeAndClearDictionary:readDescriptorCallbacks withKey:key usingParameters:@[[NSNull null], ([descriptor.value length] > 0) ? [descriptor.value toArray] : [NSNull null]]];
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
|
|
154
|
-
if (error) {
|
|
155
|
-
NSLog(@"Error in didUpdateNotificationStateForCharacteristic: %@", error);
|
|
156
|
-
if (characteristic == nil){
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (hasListeners) {
|
|
160
|
-
[self sendEventWithName:@"BleManagerDidUpdateNotificationStateFor" body:@{@"peripheral": peripheral.uuidAsString, @"characteristic": characteristic.UUID.UUIDString.lowercaseString, @"isNotifying": @(false), @"domain": [error domain], @"code": @(error.code)}];
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic];
|
|
165
|
-
|
|
166
|
-
if (characteristic.isNotifying) {
|
|
167
|
-
NSMutableArray* peripheralNotificationCallbacks = [notificationCallbacks objectForKey:key];
|
|
168
|
-
if (peripheralNotificationCallbacks != nil) {
|
|
169
|
-
if (error) {
|
|
170
|
-
[self invokeAndClearDictionary:notificationCallbacks withKey:key usingParameters:@[error]];
|
|
171
|
-
} else {
|
|
172
|
-
NSLog(@"Notification began on %@", characteristic.UUID);
|
|
173
|
-
[self invokeAndClearDictionary:notificationCallbacks withKey:key usingParameters:@[]];
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
} else {
|
|
177
|
-
// Notification has stopped
|
|
178
|
-
NSMutableArray* peripheralStopNotificationCallbacks = [stopNotificationCallbacks objectForKey:key];
|
|
179
|
-
if (peripheralStopNotificationCallbacks != nil) {
|
|
180
|
-
if (error) {
|
|
181
|
-
[self invokeAndClearDictionary:stopNotificationCallbacks withKey:key usingParameters:@[error]];
|
|
182
|
-
} else {
|
|
183
|
-
NSLog(@"Notification ended on %@", characteristic.UUID);
|
|
184
|
-
[self invokeAndClearDictionary:stopNotificationCallbacks withKey:key usingParameters:@[]];
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (hasListeners) {
|
|
189
|
-
[self sendEventWithName:@"BleManagerDidUpdateNotificationStateFor" body:@{@"peripheral": peripheral.uuidAsString, @"characteristic": characteristic.UUID.UUIDString.lowercaseString, @"isNotifying": @(characteristic.isNotifying)}];
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
- (NSString *) centralManagerStateToString: (CBManagerState)state
|
|
197
|
-
{
|
|
198
|
-
switch (state) {
|
|
199
|
-
case CBManagerStateUnknown:
|
|
200
|
-
return @"unknown";
|
|
201
|
-
case CBManagerStateResetting:
|
|
202
|
-
return @"resetting";
|
|
203
|
-
case CBManagerStateUnsupported:
|
|
204
|
-
return @"unsupported";
|
|
205
|
-
case CBManagerStateUnauthorized:
|
|
206
|
-
return @"unauthorized";
|
|
207
|
-
case CBManagerStatePoweredOff:
|
|
208
|
-
return @"off";
|
|
209
|
-
case CBManagerStatePoweredOn:
|
|
210
|
-
return @"on";
|
|
211
|
-
default:
|
|
212
|
-
return @"unknown";
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return @"unknown";
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
- (NSString *) periphalStateToString: (int)state
|
|
219
|
-
{
|
|
220
|
-
switch (state) {
|
|
221
|
-
case CBPeripheralStateDisconnected:
|
|
222
|
-
return @"disconnected";
|
|
223
|
-
case CBPeripheralStateDisconnecting:
|
|
224
|
-
return @"disconnecting";
|
|
225
|
-
case CBPeripheralStateConnected:
|
|
226
|
-
return @"connected";
|
|
227
|
-
case CBPeripheralStateConnecting:
|
|
228
|
-
return @"connecting";
|
|
229
|
-
default:
|
|
230
|
-
return @"unknown";
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return @"unknown";
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
- (NSString *) periphalManagerStateToString: (int)state
|
|
237
|
-
{
|
|
238
|
-
switch (state) {
|
|
239
|
-
case CBManagerStateUnknown:
|
|
240
|
-
return @"unknown";
|
|
241
|
-
case CBManagerStateResetting:
|
|
242
|
-
return @"resetting";
|
|
243
|
-
case CBManagerStateUnsupported:
|
|
244
|
-
return @"unsupported";
|
|
245
|
-
case CBManagerStateUnauthorized:
|
|
246
|
-
return @"unauthorized";
|
|
247
|
-
case CBManagerStatePoweredOff:
|
|
248
|
-
return @"off";
|
|
249
|
-
case CBManagerStatePoweredOn:
|
|
250
|
-
return @"on";
|
|
251
|
-
default:
|
|
252
|
-
return @"unknown";
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return @"unknown";
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
- (CBPeripheral*)findPeripheralByUUID:(NSString*)uuid {
|
|
259
|
-
|
|
260
|
-
CBPeripheral *peripheral = nil;
|
|
261
|
-
@synchronized(peripherals) {
|
|
262
|
-
for (CBPeripheral *p in peripherals) {
|
|
263
|
-
|
|
264
|
-
NSString* other = p.identifier.UUIDString.lowercaseString;
|
|
265
|
-
|
|
266
|
-
if ([uuid isEqualToString:other]) {
|
|
267
|
-
peripheral = p;
|
|
268
|
-
break;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
return peripheral;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
-(CBService *) findServiceFromUUID:(CBUUID *)UUID p:(CBPeripheral *)p
|
|
276
|
-
{
|
|
277
|
-
for(int i = 0; i < p.services.count; i++)
|
|
278
|
-
{
|
|
279
|
-
CBService *s = [p.services objectAtIndex:i];
|
|
280
|
-
if ([self compareCBUUID:s.UUID UUID2:UUID])
|
|
281
|
-
return s;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return nil; //Service not found on this peripheral
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
-(int) compareCBUUID:(CBUUID *) UUID1 UUID2:(CBUUID *)UUID2
|
|
288
|
-
{
|
|
289
|
-
char b1[16];
|
|
290
|
-
char b2[16];
|
|
291
|
-
[UUID1.data getBytes:b1 length:16];
|
|
292
|
-
[UUID2.data getBytes:b2 length:16];
|
|
293
|
-
|
|
294
|
-
if (memcmp(b1, b2, UUID1.data.length) == 0)
|
|
295
|
-
return 1;
|
|
296
|
-
else
|
|
297
|
-
return 0;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
RCT_EXPORT_METHOD(getDiscoveredPeripherals:(nonnull RCTResponseSenderBlock)callback)
|
|
301
|
-
{
|
|
302
|
-
NSLog(@"Get discovered peripherals");
|
|
303
|
-
NSMutableArray *discoveredPeripherals = [NSMutableArray array];
|
|
304
|
-
@synchronized(peripherals) {
|
|
305
|
-
for(CBPeripheral *peripheral in peripherals){
|
|
306
|
-
NSDictionary * obj = [peripheral asDictionary];
|
|
307
|
-
[discoveredPeripherals addObject:obj];
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
callback(@[[NSNull null], [NSArray arrayWithArray:discoveredPeripherals]]);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
RCT_EXPORT_METHOD(getConnectedPeripherals:(NSArray *)serviceUUIDStrings callback:(nonnull RCTResponseSenderBlock)callback)
|
|
314
|
-
{
|
|
315
|
-
NSLog(@"Get connected peripherals");
|
|
316
|
-
NSMutableArray *serviceUUIDs = [NSMutableArray new];
|
|
317
|
-
for(NSString *uuidString in serviceUUIDStrings){
|
|
318
|
-
CBUUID *serviceUUID =[CBUUID UUIDWithString:uuidString];
|
|
319
|
-
[serviceUUIDs addObject:serviceUUID];
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
NSMutableArray *foundedPeripherals = [NSMutableArray array];
|
|
323
|
-
if ([serviceUUIDs count] == 0){
|
|
324
|
-
@synchronized(peripherals) {
|
|
325
|
-
for(CBPeripheral *peripheral in peripherals){
|
|
326
|
-
if([peripheral state] == CBPeripheralStateConnected){
|
|
327
|
-
NSDictionary * obj = [peripheral asDictionary];
|
|
328
|
-
[foundedPeripherals addObject:obj];
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
} else {
|
|
333
|
-
NSArray *connectedPeripherals = [manager retrieveConnectedPeripheralsWithServices:serviceUUIDs];
|
|
334
|
-
for(CBPeripheral *peripheral in connectedPeripherals){
|
|
335
|
-
NSDictionary * obj = [peripheral asDictionary];
|
|
336
|
-
[foundedPeripherals addObject:obj];
|
|
337
|
-
@synchronized(peripherals) {
|
|
338
|
-
[peripherals addObject:peripheral];
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
callback(@[[NSNull null], [NSArray arrayWithArray:foundedPeripherals]]);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
RCT_EXPORT_METHOD(start:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
347
|
-
{
|
|
348
|
-
NSLog(@"BleManager initialized");
|
|
349
|
-
NSMutableDictionary *initOptions = [[NSMutableDictionary alloc] init];
|
|
350
|
-
|
|
351
|
-
if ([[options allKeys] containsObject:@"showAlert"]){
|
|
352
|
-
[initOptions setObject:[NSNumber numberWithBool:[[options valueForKey:@"showAlert"] boolValue]]
|
|
353
|
-
forKey:CBCentralManagerOptionShowPowerAlertKey];
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
dispatch_queue_t queue;
|
|
357
|
-
if ([[options allKeys] containsObject:@"queueIdentifierKey"]) {
|
|
358
|
-
dispatch_queue_attr_t queueAttributes = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_BACKGROUND, 0);
|
|
359
|
-
queue = dispatch_queue_create([[options valueForKey:@"queueIdentifierKey"] UTF8String], queueAttributes);
|
|
360
|
-
} else {
|
|
361
|
-
queue = dispatch_get_main_queue();
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if ([[options allKeys] containsObject:@"restoreIdentifierKey"]) {
|
|
365
|
-
|
|
366
|
-
[initOptions setObject:[options valueForKey:@"restoreIdentifierKey"]
|
|
367
|
-
forKey:CBCentralManagerOptionRestoreIdentifierKey];
|
|
368
|
-
|
|
369
|
-
if (_sharedManager) {
|
|
370
|
-
manager = _sharedManager;
|
|
371
|
-
manager.delegate = self;
|
|
372
|
-
} else {
|
|
373
|
-
manager = [[CBCentralManager alloc] initWithDelegate:self queue:queue options:initOptions];
|
|
374
|
-
_sharedManager = manager;
|
|
375
|
-
}
|
|
376
|
-
} else {
|
|
377
|
-
manager = [[CBCentralManager alloc] initWithDelegate:self queue:queue options:initOptions];
|
|
378
|
-
_sharedManager = manager;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
callback(@[]);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
RCT_EXPORT_METHOD(scan:(NSArray *)serviceUUIDStrings timeoutSeconds:(nonnull NSNumber *)timeoutSeconds allowDuplicates:(BOOL)allowDuplicates options:(nonnull NSDictionary*)scanningOptions callback:(nonnull RCTResponseSenderBlock)callback)
|
|
385
|
-
{
|
|
386
|
-
NSLog(@"scan with timeout %@", timeoutSeconds);
|
|
387
|
-
|
|
388
|
-
// Clear the peripherals before scanning again, otherwise cannot connect again after disconnection
|
|
389
|
-
// Only clear peripherals that are not connected - otherwise connections fail silently (without any
|
|
390
|
-
// onDisconnect* callback).
|
|
391
|
-
@synchronized(peripherals) {
|
|
392
|
-
NSMutableArray *connectedPeripherals = [NSMutableArray array];
|
|
393
|
-
for (CBPeripheral *peripheral in peripherals) {
|
|
394
|
-
if (([peripheral state] != CBPeripheralStateConnected) &&
|
|
395
|
-
([peripheral state] != CBPeripheralStateConnecting)) {
|
|
396
|
-
[connectedPeripherals addObject:peripheral];
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
for (CBPeripheral *p in connectedPeripherals) {
|
|
400
|
-
[peripherals removeObject:p];
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
NSArray * services = [RCTConvert NSArray:serviceUUIDStrings];
|
|
405
|
-
NSMutableArray *serviceUUIDs = [NSMutableArray new];
|
|
406
|
-
NSDictionary *options = nil;
|
|
407
|
-
if (allowDuplicates){
|
|
408
|
-
options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
for (int i = 0; i < [services count]; i++) {
|
|
412
|
-
CBUUID *serviceUUID =[CBUUID UUIDWithString:[serviceUUIDStrings objectAtIndex: i]];
|
|
413
|
-
[serviceUUIDs addObject:serviceUUID];
|
|
414
|
-
}
|
|
415
|
-
[manager scanForPeripheralsWithServices:serviceUUIDs options:options];
|
|
416
|
-
|
|
417
|
-
if ([timeoutSeconds floatValue] > 0) {
|
|
418
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
419
|
-
self.scanTimer = [NSTimer scheduledTimerWithTimeInterval:[timeoutSeconds floatValue] target:self selector:@selector(stopScanTimer:) userInfo: nil repeats:NO];
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
callback(@[]);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
RCT_EXPORT_METHOD(stopScan:(nonnull RCTResponseSenderBlock)callback)
|
|
426
|
-
{
|
|
427
|
-
if (self.scanTimer) {
|
|
428
|
-
[self.scanTimer invalidate];
|
|
429
|
-
self.scanTimer = nil;
|
|
430
|
-
}
|
|
431
|
-
[manager stopScan];
|
|
432
|
-
if (hasListeners) {
|
|
433
|
-
[self sendEventWithName:@"BleManagerStopScan" body:@{@"status": @0}];
|
|
434
|
-
}
|
|
435
|
-
callback(@[[NSNull null]]);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
-(void)stopScanTimer:(NSTimer *)timer {
|
|
440
|
-
NSLog(@"Stop scan");
|
|
441
|
-
self.scanTimer = nil;
|
|
442
|
-
[manager stopScan];
|
|
443
|
-
if (hasListeners) {
|
|
444
|
-
if (self.bridge) {
|
|
445
|
-
[self sendEventWithName:@"BleManagerStopScan" body:@{@"status": @10}];
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
|
|
451
|
-
advertisementData:(NSDictionary *)advertisementData
|
|
452
|
-
RSSI:(NSNumber *)RSSI
|
|
453
|
-
{
|
|
454
|
-
@synchronized(peripherals) {
|
|
455
|
-
[peripherals addObject:peripheral];
|
|
456
|
-
}
|
|
457
|
-
[peripheral setAdvertisementData:advertisementData RSSI:RSSI];
|
|
458
|
-
|
|
459
|
-
NSLog(@"Discover peripheral: %@", [peripheral name]);
|
|
460
|
-
if (hasListeners) {
|
|
461
|
-
[self sendEventWithName:@"BleManagerDiscoverPeripheral" body:[peripheral asDictionary]];
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
RCT_EXPORT_METHOD(connect:(NSString *)peripheralUUID options:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
466
|
-
{
|
|
467
|
-
NSLog(@"Connect");
|
|
468
|
-
CBPeripheral *peripheral = [self findPeripheralByUUID:peripheralUUID];
|
|
469
|
-
if (peripheral == nil){
|
|
470
|
-
// Try to retrieve the peripheral
|
|
471
|
-
NSLog(@"Retrieving peripheral with UUID : %@", peripheralUUID);
|
|
472
|
-
NSUUID *uuid = [[NSUUID alloc]initWithUUIDString:peripheralUUID];
|
|
473
|
-
if (uuid != nil) {
|
|
474
|
-
NSArray<CBPeripheral *> *peripheralArray = [manager retrievePeripheralsWithIdentifiers:@[uuid]];
|
|
475
|
-
if([peripheralArray count] > 0){
|
|
476
|
-
peripheral = [peripheralArray objectAtIndex:0];
|
|
477
|
-
@synchronized(peripherals) {
|
|
478
|
-
[peripherals addObject:peripheral];
|
|
479
|
-
}
|
|
480
|
-
NSLog(@"Successfull retrieved peripheral with UUID : %@", peripheralUUID);
|
|
481
|
-
}
|
|
482
|
-
} else {
|
|
483
|
-
NSString *error = [NSString stringWithFormat:@"Wrong UUID format %@", peripheralUUID];
|
|
484
|
-
callback(@[error, [NSNull null]]);
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
if (peripheral) {
|
|
489
|
-
NSLog(@"Connecting to peripheral with UUID : %@", peripheralUUID);
|
|
490
|
-
|
|
491
|
-
[self insertCallback:callback intoDictionary:connectCallbacks withKey:[peripheral uuidAsString]];
|
|
492
|
-
[manager connectPeripheral:peripheral options:nil];
|
|
493
|
-
|
|
494
|
-
} else {
|
|
495
|
-
NSString *error = [NSString stringWithFormat:@"Could not find peripheral %@.", peripheralUUID];
|
|
496
|
-
NSLog(@"%@", error);
|
|
497
|
-
callback(@[error, [NSNull null]]);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
RCT_EXPORT_METHOD(disconnect:(NSString *)peripheralUUID force:(BOOL)force callback:(nonnull RCTResponseSenderBlock)callback)
|
|
502
|
-
{
|
|
503
|
-
CBPeripheral *peripheral = [self findPeripheralByUUID:peripheralUUID];
|
|
504
|
-
if (peripheral) {
|
|
505
|
-
NSLog(@"Disconnecting from peripheral with UUID : %@", peripheralUUID);
|
|
506
|
-
|
|
507
|
-
if (peripheral.services != nil) {
|
|
508
|
-
for (CBService *service in peripheral.services) {
|
|
509
|
-
if (service.characteristics != nil) {
|
|
510
|
-
for (CBCharacteristic *characteristic in service.characteristics) {
|
|
511
|
-
if (characteristic.isNotifying) {
|
|
512
|
-
NSLog(@"Remove notification from: %@", characteristic.UUID);
|
|
513
|
-
[peripheral setNotifyValue:NO forCharacteristic:characteristic];
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
[manager cancelPeripheralConnection:peripheral];
|
|
521
|
-
callback(@[]);
|
|
522
|
-
|
|
523
|
-
} else {
|
|
524
|
-
NSString *error = [NSString stringWithFormat:@"Could not find peripheral %@.", peripheralUUID];
|
|
525
|
-
NSLog(@"%@", error);
|
|
526
|
-
callback(@[error]);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
RCT_EXPORT_METHOD(checkState:(nonnull RCTResponseSenderBlock)callback)
|
|
531
|
-
{
|
|
532
|
-
if (manager != nil){
|
|
533
|
-
[self centralManagerDidUpdateState:self.manager];
|
|
534
|
-
|
|
535
|
-
NSString *stateName = [self centralManagerStateToString:self.manager.state];
|
|
536
|
-
callback(@[stateName]);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
|
|
541
|
-
{
|
|
542
|
-
NSString *errorStr = [NSString stringWithFormat:@"Peripheral connection failure: %@. (%@)", peripheral, [error localizedDescription]];
|
|
543
|
-
NSLog(@"%@", errorStr);
|
|
544
|
-
|
|
545
|
-
[self invokeAndClearDictionary:connectCallbacks withKey:[peripheral uuidAsString] usingParameters:@[errorStr]];
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
RCT_EXPORT_METHOD(write:(NSString *)deviceUUID serviceUUID:(NSString*)serviceUUID characteristicUUID:(NSString*)characteristicUUID message:(NSArray*)message maxByteSize:(NSInteger)maxByteSize callback:(nonnull RCTResponseSenderBlock)callback)
|
|
549
|
-
{
|
|
550
|
-
NSLog(@"Write");
|
|
551
|
-
|
|
552
|
-
BLECommandContext *context = [self getData:deviceUUID serviceUUIDString:serviceUUID characteristicUUIDString:characteristicUUID prop:CBCharacteristicPropertyWrite callback:callback];
|
|
553
|
-
|
|
554
|
-
unsigned long c = [message count];
|
|
555
|
-
uint8_t *bytes = malloc(sizeof(*bytes) * c);
|
|
556
|
-
|
|
557
|
-
unsigned i;
|
|
558
|
-
for (i = 0; i < c; i++)
|
|
559
|
-
{
|
|
560
|
-
NSNumber *number = [message objectAtIndex:i];
|
|
561
|
-
int byte = [number intValue];
|
|
562
|
-
bytes[i] = byte;
|
|
563
|
-
}
|
|
564
|
-
NSData *dataMessage = [NSData dataWithBytesNoCopy:bytes length:c freeWhenDone:YES];
|
|
565
|
-
|
|
566
|
-
if (context) {
|
|
567
|
-
RCTLogInfo(@"Message to write(%lu): %@ ", (unsigned long)[message count], message);
|
|
568
|
-
CBPeripheral *peripheral = [context peripheral];
|
|
569
|
-
CBCharacteristic *characteristic = [context characteristic];
|
|
570
|
-
|
|
571
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic];
|
|
572
|
-
[self insertCallback:callback intoDictionary:writeCallbacks withKey:key];
|
|
573
|
-
|
|
574
|
-
RCTLogInfo(@"Message to write(%lu): %@ ", (unsigned long)[dataMessage length], [dataMessage hexadecimalString]);
|
|
575
|
-
if ([dataMessage length] > maxByteSize){
|
|
576
|
-
int dataLength = (int)dataMessage.length;
|
|
577
|
-
int count = 0;
|
|
578
|
-
NSData* firstMessage;
|
|
579
|
-
while(count < dataLength && (dataLength - count > maxByteSize)){
|
|
580
|
-
if (count == 0){
|
|
581
|
-
firstMessage = [dataMessage subdataWithRange:NSMakeRange(count, maxByteSize)];
|
|
582
|
-
}else{
|
|
583
|
-
NSData* splitMessage = [dataMessage subdataWithRange:NSMakeRange(count, maxByteSize)];
|
|
584
|
-
[writeQueue addObject:splitMessage];
|
|
585
|
-
}
|
|
586
|
-
count += maxByteSize;
|
|
587
|
-
}
|
|
588
|
-
if (count < dataLength) {
|
|
589
|
-
NSData* splitMessage = [dataMessage subdataWithRange:NSMakeRange(count, dataLength - count)];
|
|
590
|
-
[writeQueue addObject:splitMessage];
|
|
591
|
-
}
|
|
592
|
-
NSLog(@"Queued splitted message: %lu", (unsigned long)[writeQueue count]);
|
|
593
|
-
[peripheral writeValue:firstMessage forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
|
|
594
|
-
} else {
|
|
595
|
-
[peripheral writeValue:dataMessage forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
RCT_EXPORT_METHOD(writeWithoutResponse:(NSString *)deviceUUID serviceUUID:(NSString*)serviceUUID characteristicUUID:(NSString*)characteristicUUID message:(NSArray*)message maxByteSize:(NSInteger)maxByteSize queueSleepTime:(NSInteger)queueSleepTime callback:(nonnull RCTResponseSenderBlock)callback)
|
|
602
|
-
{
|
|
603
|
-
NSLog(@"writeWithoutResponse");
|
|
604
|
-
|
|
605
|
-
BLECommandContext *context = [self getData:deviceUUID serviceUUIDString:serviceUUID characteristicUUIDString:characteristicUUID prop:CBCharacteristicPropertyWriteWithoutResponse callback:callback];
|
|
606
|
-
unsigned long c = [message count];
|
|
607
|
-
uint8_t *bytes = malloc(sizeof(*bytes) * c);
|
|
608
|
-
|
|
609
|
-
unsigned i;
|
|
610
|
-
for (i = 0; i < c; i++)
|
|
611
|
-
{
|
|
612
|
-
NSNumber *number = [message objectAtIndex:i];
|
|
613
|
-
int byte = [number intValue];
|
|
614
|
-
bytes[i] = byte;
|
|
615
|
-
}
|
|
616
|
-
NSData *dataMessage = [NSData dataWithBytesNoCopy:bytes length:c freeWhenDone:YES];
|
|
617
|
-
if (context) {
|
|
618
|
-
if ([dataMessage length] > maxByteSize) {
|
|
619
|
-
NSUInteger length = [dataMessage length];
|
|
620
|
-
NSUInteger offset = 0;
|
|
621
|
-
CBPeripheral *peripheral = [context peripheral];
|
|
622
|
-
CBCharacteristic *characteristic = [context characteristic];
|
|
623
|
-
|
|
624
|
-
do {
|
|
625
|
-
NSUInteger thisChunkSize = length - offset > maxByteSize ? maxByteSize : length - offset;
|
|
626
|
-
NSData* chunk = [NSData dataWithBytesNoCopy:(char *)[dataMessage bytes] + offset length:thisChunkSize freeWhenDone:NO];
|
|
627
|
-
|
|
628
|
-
offset += thisChunkSize;
|
|
629
|
-
[peripheral writeValue:chunk forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
|
|
630
|
-
NSTimeInterval sleepTimeSeconds = (NSTimeInterval) queueSleepTime / 1000;
|
|
631
|
-
[NSThread sleepForTimeInterval: sleepTimeSeconds];
|
|
632
|
-
} while (offset < length);
|
|
633
|
-
|
|
634
|
-
NSLog(@"Message to write(%lu): %@ ", (unsigned long)[dataMessage length], [dataMessage hexadecimalString]);
|
|
635
|
-
callback(@[]);
|
|
636
|
-
} else {
|
|
637
|
-
|
|
638
|
-
CBPeripheral *peripheral = [context peripheral];
|
|
639
|
-
CBCharacteristic *characteristic = [context characteristic];
|
|
640
|
-
|
|
641
|
-
NSLog(@"Message to write(%lu): %@ ", (unsigned long)[dataMessage length], [dataMessage hexadecimalString]);
|
|
642
|
-
[peripheral writeValue:dataMessage forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
|
|
643
|
-
callback(@[]);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
RCT_EXPORT_METHOD(read:(NSString *)deviceUUID serviceUUID:(NSString*)serviceUUID characteristicUUID:(NSString*)characteristicUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
650
|
-
{
|
|
651
|
-
NSLog(@"read");
|
|
652
|
-
|
|
653
|
-
BLECommandContext *context = [self getData:deviceUUID serviceUUIDString:serviceUUID characteristicUUIDString:characteristicUUID prop:CBCharacteristicPropertyRead callback:callback];
|
|
654
|
-
if (context) {
|
|
655
|
-
|
|
656
|
-
CBPeripheral *peripheral = [context peripheral];
|
|
657
|
-
CBCharacteristic *characteristic = [context characteristic];
|
|
658
|
-
|
|
659
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic];
|
|
660
|
-
[self insertCallback:callback intoDictionary:readCallbacks withKey:key];
|
|
661
|
-
|
|
662
|
-
[peripheral readValueForCharacteristic:characteristic]; // callback sends value
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
RCT_EXPORT_METHOD(getMaximumWriteValueLengthForWithResponse:(NSString *)deviceUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
668
|
-
{
|
|
669
|
-
NSLog(@"getMaximumWriteValueLengthForWithResponse");
|
|
670
|
-
|
|
671
|
-
CBPeripheral *peripheral = [self findPeripheralByUUID:deviceUUID];
|
|
672
|
-
|
|
673
|
-
if (peripheral && peripheral.state == CBPeripheralStateConnected) {
|
|
674
|
-
[self insertCallback:callback intoDictionary:readRSSICallbacks withKey:[peripheral uuidAsString]];
|
|
675
|
-
NSNumber *max = [NSNumber numberWithInteger:[peripheral maximumWriteValueLengthForType:(CBCharacteristicWriteWithResponse)]];
|
|
676
|
-
callback(@[[NSNull null], max]);
|
|
677
|
-
} else {
|
|
678
|
-
callback(@[@"Peripheral not found or not connected"]);
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
RCT_EXPORT_METHOD(getMaximumWriteValueLengthForWithoutResponse:(NSString *)deviceUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
684
|
-
{
|
|
685
|
-
NSLog(@"getMaximumWriteValueLengthForWithoutResponse");
|
|
686
|
-
|
|
687
|
-
CBPeripheral *peripheral = [self findPeripheralByUUID:deviceUUID];
|
|
688
|
-
|
|
689
|
-
if (peripheral && peripheral.state == CBPeripheralStateConnected) {
|
|
690
|
-
[self insertCallback:callback intoDictionary:readRSSICallbacks withKey:[peripheral uuidAsString]];
|
|
691
|
-
NSNumber *max = [NSNumber numberWithInteger:[peripheral maximumWriteValueLengthForType:(CBCharacteristicPropertyWriteWithoutResponse)]];
|
|
692
|
-
callback(@[[NSNull null], max]);
|
|
693
|
-
} else {
|
|
694
|
-
callback(@[@"Peripheral not found or not connected"]);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
RCT_EXPORT_METHOD(readRSSI:(NSString *)deviceUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
701
|
-
{
|
|
702
|
-
NSLog(@"readRSSI");
|
|
703
|
-
|
|
704
|
-
CBPeripheral *peripheral = [self findPeripheralByUUID:deviceUUID];
|
|
705
|
-
|
|
706
|
-
if (peripheral && peripheral.state == CBPeripheralStateConnected) {
|
|
707
|
-
[self insertCallback:callback intoDictionary:readRSSICallbacks withKey:[peripheral uuidAsString]];
|
|
708
|
-
[peripheral readRSSI];
|
|
709
|
-
} else {
|
|
710
|
-
callback(@[@"Peripheral not found or not connected"]);
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
RCT_EXPORT_METHOD(readDescriptor:(NSString *)deviceUUID serviceUUID:(NSString*)serviceUUID characteristicUUID:(NSString*)characteristicUUID descriptorUUID:(NSString*)descriptorUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
716
|
-
{
|
|
717
|
-
NSLog(@"readDescriptor");
|
|
718
|
-
|
|
719
|
-
BLECommandContext *context = [self getData:deviceUUID serviceUUIDString:serviceUUID characteristicUUIDString:characteristicUUID prop:CBCharacteristicPropertyRead callback:callback];
|
|
720
|
-
if (context) {
|
|
721
|
-
|
|
722
|
-
CBPeripheral *peripheral = [context peripheral];
|
|
723
|
-
CBCharacteristic *characteristic = [context characteristic];
|
|
724
|
-
CBDescriptor *descriptor = [self findDescriptorFromUUID:[CBUUID UUIDWithString:descriptorUUID] characteristic:characteristic];
|
|
725
|
-
if (!descriptor) {
|
|
726
|
-
NSString* err = [NSString stringWithFormat:@"Could not find descriptor with UUID %@ on characteristic with UUID %@ on peripheral with UUID %@",
|
|
727
|
-
descriptorUUID,
|
|
728
|
-
characteristic.UUID,
|
|
729
|
-
peripheral.identifier.UUIDString];
|
|
730
|
-
NSLog(@"Could not find descriptor with UUID %@ on characteristic with UUID %@ on peripheral with UUID %@",
|
|
731
|
-
descriptorUUID,
|
|
732
|
-
characteristic.UUID,
|
|
733
|
-
peripheral.identifier.UUIDString);
|
|
734
|
-
callback(@[err]);
|
|
735
|
-
} else {
|
|
736
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic andDescriptor:descriptor];
|
|
737
|
-
[self insertCallback:callback intoDictionary:readDescriptorCallbacks withKey:key];
|
|
738
|
-
|
|
739
|
-
[peripheral readValueForDescriptor:descriptor]; // callback sends value
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
RCT_EXPORT_METHOD(retrieveServices:(NSString *)deviceUUID services:(NSArray<NSString *> *)services callback:(nonnull RCTResponseSenderBlock)callback)
|
|
746
|
-
{
|
|
747
|
-
NSLog(@"retrieveServices %@", services);
|
|
748
|
-
|
|
749
|
-
CBPeripheral *peripheral = [self findPeripheralByUUID:deviceUUID];
|
|
750
|
-
|
|
751
|
-
if (peripheral && peripheral.state == CBPeripheralStateConnected) {
|
|
752
|
-
[self insertCallback:callback intoDictionary:retrieveServicesCallbacks withKey:[peripheral uuidAsString]];
|
|
753
|
-
|
|
754
|
-
NSMutableArray<CBUUID *> *uuids = [NSMutableArray new];
|
|
755
|
-
for ( NSString *string in services ) {
|
|
756
|
-
CBUUID *uuid = [CBUUID UUIDWithString:string];
|
|
757
|
-
[uuids addObject:uuid];
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
if ( uuids.count > 0 ) {
|
|
761
|
-
[peripheral discoverServices:uuids];
|
|
762
|
-
} else {
|
|
763
|
-
[peripheral discoverServices:nil];
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
} else {
|
|
767
|
-
callback(@[@"Peripheral not found or not connected"]);
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
RCT_EXPORT_METHOD(startNotification:(NSString *)deviceUUID serviceUUID:(NSString*)serviceUUID characteristicUUID:(NSString*)characteristicUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
772
|
-
{
|
|
773
|
-
NSLog(@"startNotification");
|
|
774
|
-
|
|
775
|
-
BLECommandContext *context = [self getData:deviceUUID serviceUUIDString:serviceUUID characteristicUUIDString:characteristicUUID prop:CBCharacteristicPropertyNotify callback:callback];
|
|
776
|
-
|
|
777
|
-
if (context) {
|
|
778
|
-
CBPeripheral *peripheral = [context peripheral];
|
|
779
|
-
CBCharacteristic *characteristic = [context characteristic];
|
|
780
|
-
|
|
781
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic];
|
|
782
|
-
[self insertCallback:callback intoDictionary:notificationCallbacks withKey:key];
|
|
783
|
-
|
|
784
|
-
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
RCT_EXPORT_METHOD(stopNotification:(NSString *)deviceUUID serviceUUID:(NSString*)serviceUUID characteristicUUID:(NSString*)characteristicUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
790
|
-
{
|
|
791
|
-
NSLog(@"stopNotification");
|
|
792
|
-
|
|
793
|
-
BLECommandContext *context = [self getData:deviceUUID serviceUUIDString:serviceUUID characteristicUUIDString:characteristicUUID prop:CBCharacteristicPropertyNotify callback:callback];
|
|
794
|
-
|
|
795
|
-
if (context) {
|
|
796
|
-
CBPeripheral *peripheral = [context peripheral];
|
|
797
|
-
CBCharacteristic *characteristic = [context characteristic];
|
|
798
|
-
|
|
799
|
-
if ([characteristic isNotifying]){
|
|
800
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic];
|
|
801
|
-
[self insertCallback:callback intoDictionary:stopNotificationCallbacks withKey:key];
|
|
802
|
-
[peripheral setNotifyValue:NO forCharacteristic:characteristic];
|
|
803
|
-
NSLog(@"Characteristic stopped notifying");
|
|
804
|
-
} else {
|
|
805
|
-
NSLog(@"Characteristic is not notifying");
|
|
806
|
-
callback(@[]);
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
RCT_EXPORT_METHOD(enableBluetooth:(nonnull RCTResponseSenderBlock)callback)
|
|
814
|
-
{
|
|
815
|
-
callback(@[@"Not supported"]);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
RCT_EXPORT_METHOD(getBondedPeripherals:(nonnull RCTResponseSenderBlock)callback)
|
|
819
|
-
{
|
|
820
|
-
callback(@[@"Not supported"]);
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
RCT_EXPORT_METHOD(createBond:(NSString *)deviceUUID devicePin:(NSString *)devicePin callback:(nonnull RCTResponseSenderBlock)callback)
|
|
824
|
-
{
|
|
825
|
-
callback(@[@"Not supported"]);
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
RCT_EXPORT_METHOD(removeBond:(NSString *)deviceUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
829
|
-
{
|
|
830
|
-
callback(@[@"Not supported"]);
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
RCT_EXPORT_METHOD(removePeripheral:(NSString *)deviceUUID callback:(nonnull RCTResponseSenderBlock)callback)
|
|
834
|
-
{
|
|
835
|
-
callback(@[@"Not supported"]);
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
RCT_EXPORT_METHOD(requestMTU:(NSString *)deviceUUID mtu:(NSInteger)mtu callback:(nonnull RCTResponseSenderBlock)callback)
|
|
839
|
-
{
|
|
840
|
-
callback(@[@"Not supported"]);
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
|
|
844
|
-
NSLog(@"didWrite");
|
|
845
|
-
|
|
846
|
-
NSString *key = [self keyForPeripheral: peripheral andCharacteristic:characteristic];
|
|
847
|
-
NSMutableArray* peripheralWriteCallbacks = [writeCallbacks objectForKey:key];
|
|
848
|
-
|
|
849
|
-
if (peripheralWriteCallbacks) {
|
|
850
|
-
if (error) {
|
|
851
|
-
NSLog(@"%@", error);
|
|
852
|
-
[self invokeAndClearDictionary:writeCallbacks withKey:key usingParameters:@[error.localizedDescription]];
|
|
853
|
-
} else {
|
|
854
|
-
if ([writeQueue count] == 0) {
|
|
855
|
-
[self invokeAndClearDictionary:writeCallbacks withKey:key usingParameters:@[]];
|
|
856
|
-
}else{
|
|
857
|
-
// Remove and write the queud message
|
|
858
|
-
NSData *message = [writeQueue objectAtIndex:0];
|
|
859
|
-
[writeQueue removeObjectAtIndex:0];
|
|
860
|
-
[peripheral writeValue:message forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
- (void)peripheral:(CBPeripheral*)peripheral didReadRSSI:(NSNumber*)rssi error:(NSError*)error {
|
|
870
|
-
NSLog(@"didReadRSSI %@", rssi);
|
|
871
|
-
NSString *key = [peripheral uuidAsString];
|
|
872
|
-
[self invokeAndClearDictionary:readRSSICallbacks withKey:key usingParameters:@[[NSNull null], [NSNumber numberWithInteger:[rssi integerValue]]]];
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
|
|
878
|
-
{
|
|
879
|
-
NSLog(@"Peripheral Connected: %@", [peripheral uuidAsString]);
|
|
880
|
-
peripheral.delegate = self;
|
|
881
|
-
|
|
882
|
-
// The state of the peripheral isn't necessarily updated until a small delay after didConnectPeripheral is called
|
|
883
|
-
// and in the meantime didFailToConnectPeripheral may be called
|
|
884
|
-
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.002 * NSEC_PER_SEC),
|
|
885
|
-
dispatch_get_main_queue(), ^(void){
|
|
886
|
-
// didFailToConnectPeripheral should have been called already if not connected by now
|
|
887
|
-
|
|
888
|
-
[self invokeAndClearDictionary:self->connectCallbacks withKey:[peripheral uuidAsString] usingParameters:@[[NSNull null], [peripheral asDictionary]]];
|
|
889
|
-
|
|
890
|
-
if (hasListeners) {
|
|
891
|
-
[self sendEventWithName:@"BleManagerConnectPeripheral" body:@{@"peripheral": [peripheral uuidAsString]}];
|
|
892
|
-
}
|
|
893
|
-
});
|
|
894
|
-
|
|
895
|
-
[writeQueue removeAllObjects];
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
|
|
899
|
-
NSLog(@"Peripheral Disconnected: %@", [peripheral uuidAsString]);
|
|
900
|
-
|
|
901
|
-
if (error) {
|
|
902
|
-
NSLog(@"Error: %@", error);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
NSString *peripheralUUIDString = [peripheral uuidAsString];
|
|
906
|
-
|
|
907
|
-
NSString *errorStr = [NSString stringWithFormat:@"Peripheral did disconnect: %@", peripheralUUIDString];
|
|
908
|
-
|
|
909
|
-
[self invokeAndClearDictionary:connectCallbacks withKey:peripheralUUIDString usingParameters:@[errorStr]];
|
|
910
|
-
[self invokeAndClearDictionary:readRSSICallbacks withKey:peripheralUUIDString usingParameters:@[errorStr]];
|
|
911
|
-
[self invokeAndClearDictionary:retrieveServicesCallbacks withKey:peripheralUUIDString usingParameters:@[errorStr]];
|
|
912
|
-
|
|
913
|
-
NSArray* ourReadCallbacks = readCallbacks.allKeys;
|
|
914
|
-
for (id key in ourReadCallbacks) {
|
|
915
|
-
if ([key hasPrefix:peripheralUUIDString]) {
|
|
916
|
-
[self invokeAndClearDictionary:readCallbacks withKey:key usingParameters:@[errorStr]];
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
NSArray* ourWriteCallbacks = writeCallbacks.allKeys;
|
|
921
|
-
for (id key in ourWriteCallbacks) {
|
|
922
|
-
if ([key hasPrefix:peripheralUUIDString]) {
|
|
923
|
-
[self invokeAndClearDictionary:writeCallbacks withKey:key usingParameters:@[errorStr]];
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
NSArray* ourNotificationCallbacks = notificationCallbacks.allKeys;
|
|
928
|
-
for (id key in ourNotificationCallbacks) {
|
|
929
|
-
if ([key hasPrefix:peripheralUUIDString]) {
|
|
930
|
-
[self invokeAndClearDictionary:notificationCallbacks withKey:key usingParameters:@[errorStr]];
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
NSArray* ourReadDescriptorCallbacks = readDescriptorCallbacks.allKeys;
|
|
935
|
-
for (id key in ourReadDescriptorCallbacks) {
|
|
936
|
-
if ([key hasPrefix:peripheralUUIDString]) {
|
|
937
|
-
[self invokeAndClearDictionary:readDescriptorCallbacks withKey:key usingParameters:@[errorStr]];
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
NSArray* ourStopNotificationsCallbacks = stopNotificationCallbacks.allKeys;
|
|
942
|
-
for (id key in ourStopNotificationsCallbacks) {
|
|
943
|
-
if ([key hasPrefix:peripheralUUIDString]) {
|
|
944
|
-
[self invokeAndClearDictionary:stopNotificationCallbacks withKey:key usingParameters:@[errorStr]];
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
if (hasListeners) {
|
|
949
|
-
if (error) {
|
|
950
|
-
[self sendEventWithName:@"BleManagerDisconnectPeripheral" body:@{@"peripheral": [peripheral uuidAsString], @"domain": [error domain], @"code": @(error.code)}];
|
|
951
|
-
} else {
|
|
952
|
-
[self sendEventWithName:@"BleManagerDisconnectPeripheral" body:@{@"peripheral": [peripheral uuidAsString]}];
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
|
|
958
|
-
if (error) {
|
|
959
|
-
NSLog(@"Error: %@", error);
|
|
960
|
-
return;
|
|
961
|
-
}
|
|
962
|
-
NSLog(@"Services Discover");
|
|
963
|
-
|
|
964
|
-
NSMutableSet *servicesForPeriperal = [NSMutableSet new];
|
|
965
|
-
[servicesForPeriperal addObjectsFromArray:peripheral.services];
|
|
966
|
-
[retrieveServicesLatches setObject:servicesForPeriperal forKey:[peripheral uuidAsString]];
|
|
967
|
-
for (CBService *service in peripheral.services) {
|
|
968
|
-
NSLog(@"Service %@ %@", service.UUID, service.description);
|
|
969
|
-
[peripheral discoverIncludedServices:nil forService:service]; // discover included services
|
|
970
|
-
[peripheral discoverCharacteristics:nil forService:service]; // discover characteristics for service
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverIncludedServicesForService:(CBService *)service error:(NSError *)error {
|
|
975
|
-
[peripheral discoverCharacteristics:nil forService:service]; // discover characteristics for included service
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
|
|
979
|
-
if (error) {
|
|
980
|
-
NSLog(@"Error: %@", error);
|
|
981
|
-
return;
|
|
982
|
-
}
|
|
983
|
-
NSLog(@"Characteristics For Service Discover");
|
|
984
|
-
|
|
985
|
-
NSMutableSet *characteristicsForService = [NSMutableSet new];
|
|
986
|
-
[characteristicsForService addObjectsFromArray:service.characteristics];
|
|
987
|
-
[retrieveServicesLatches setObject:characteristicsForService forKey:service.UUID.UUIDString];
|
|
988
|
-
|
|
989
|
-
for (CBCharacteristic *characteristic in service.characteristics) {
|
|
990
|
-
[peripheral discoverDescriptorsForCharacteristic:characteristic];
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error {
|
|
995
|
-
if (error) {
|
|
996
|
-
NSLog(@"Error: %@", error);
|
|
997
|
-
return;
|
|
998
|
-
}
|
|
999
|
-
NSLog(@"Descriptor For Characteristic Discover");
|
|
1000
|
-
|
|
1001
|
-
NSString *peripheralUUIDString = [peripheral uuidAsString];
|
|
1002
|
-
NSString *serviceUUIDString = characteristic.service.UUID.UUIDString;
|
|
1003
|
-
NSMutableSet *peripheralLatch = [retrieveServicesLatches valueForKey:peripheralUUIDString];
|
|
1004
|
-
NSMutableSet *serviceLatch = [retrieveServicesLatches valueForKey:serviceUUIDString];
|
|
1005
|
-
[serviceLatch removeObject:characteristic];
|
|
1006
|
-
|
|
1007
|
-
if ([serviceLatch count] == 0) {
|
|
1008
|
-
// All characteristics for this service have been checked
|
|
1009
|
-
[peripheralLatch removeObject:characteristic.service];
|
|
1010
|
-
|
|
1011
|
-
if ([peripheralLatch count] == 0) {
|
|
1012
|
-
// Call success callback for connect
|
|
1013
|
-
[self invokeAndClearDictionary:retrieveServicesCallbacks withKey:peripheralUUIDString usingParameters:@[[NSNull null], [peripheral asDictionary]]];
|
|
1014
|
-
[retrieveServicesLatches removeObjectForKey:peripheralUUIDString];
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
// Find a characteristic in service with a specific property
|
|
1020
|
-
-(CBCharacteristic *) findCharacteristicFromUUID:(CBUUID *)UUID service:(CBService*)service prop:(CBCharacteristicProperties)prop
|
|
1021
|
-
{
|
|
1022
|
-
NSLog(@"Looking for %@ with properties %lu", UUID, (unsigned long)prop);
|
|
1023
|
-
for(int i=0; i < service.characteristics.count; i++)
|
|
1024
|
-
{
|
|
1025
|
-
CBCharacteristic *c = [service.characteristics objectAtIndex:i];
|
|
1026
|
-
if ((c.properties & prop) != 0x0 && [c.UUID.UUIDString.lowercaseString isEqualToString: UUID.UUIDString.lowercaseString]) {
|
|
1027
|
-
NSLog(@"Found %@", UUID);
|
|
1028
|
-
return c;
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
return nil; //Characteristic with prop not found on this service
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
// Find a characteristic in service by UUID
|
|
1035
|
-
-(CBCharacteristic *) findCharacteristicFromUUID:(CBUUID *)UUID service:(CBService*)service
|
|
1036
|
-
{
|
|
1037
|
-
NSLog(@"Looking for %@", UUID);
|
|
1038
|
-
for(int i=0; i < service.characteristics.count; i++)
|
|
1039
|
-
{
|
|
1040
|
-
CBCharacteristic *c = [service.characteristics objectAtIndex:i];
|
|
1041
|
-
if ([c.UUID.UUIDString.lowercaseString isEqualToString: UUID.UUIDString.lowercaseString]) {
|
|
1042
|
-
NSLog(@"Found %@", UUID);
|
|
1043
|
-
return c;
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
return nil; //Characteristic not found on this service
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
-(CBDescriptor *) findDescriptorFromUUID:(CBUUID *)UUID characteristic:(CBCharacteristic*)characteristic
|
|
1050
|
-
{
|
|
1051
|
-
NSLog(@"Looking for descriptor %@ on characteristic %@", UUID, characteristic.UUID);
|
|
1052
|
-
for (int i=0; i < characteristic.descriptors.count; i++)
|
|
1053
|
-
{
|
|
1054
|
-
CBDescriptor *d = [characteristic.descriptors objectAtIndex:i];
|
|
1055
|
-
if ([d.UUID.UUIDString isEqualToString: UUID.UUIDString]) {
|
|
1056
|
-
NSLog(@"Found descriptor %@", UUID);
|
|
1057
|
-
return d;
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
return nil; // Descriptor not found on this characteristic
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
|
-
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
|
|
1064
|
-
{
|
|
1065
|
-
NSString *stateName = [self centralManagerStateToString:central.state];
|
|
1066
|
-
if (hasListeners) {
|
|
1067
|
-
[self sendEventWithName:@"BleManagerDidUpdateState" body:@{@"state":stateName}];
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
// expecting deviceUUID, serviceUUID, characteristicUUID in command.arguments
|
|
1072
|
-
-(BLECommandContext*) getData:(NSString*)deviceUUIDString serviceUUIDString:(NSString*)serviceUUIDString characteristicUUIDString:(NSString*)characteristicUUIDString prop:(CBCharacteristicProperties)prop callback:(nonnull RCTResponseSenderBlock)callback
|
|
1073
|
-
{
|
|
1074
|
-
CBUUID *serviceUUID = [CBUUID UUIDWithString:serviceUUIDString];
|
|
1075
|
-
CBUUID *characteristicUUID = [CBUUID UUIDWithString:characteristicUUIDString];
|
|
1076
|
-
|
|
1077
|
-
CBPeripheral *peripheral = [self findPeripheralByUUID:deviceUUIDString];
|
|
1078
|
-
|
|
1079
|
-
if (!peripheral) {
|
|
1080
|
-
NSString* err = [NSString stringWithFormat:@"Could not find peripherial with UUID %@", deviceUUIDString];
|
|
1081
|
-
NSLog(@"Could not find peripherial with UUID %@", deviceUUIDString);
|
|
1082
|
-
callback(@[err]);
|
|
1083
|
-
|
|
1084
|
-
return nil;
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
CBService *service = [self findServiceFromUUID:serviceUUID p:peripheral];
|
|
1088
|
-
|
|
1089
|
-
if (!service)
|
|
1090
|
-
{
|
|
1091
|
-
NSString* err = [NSString stringWithFormat:@"Could not find service with UUID %@ on peripheral with UUID %@",
|
|
1092
|
-
serviceUUIDString,
|
|
1093
|
-
peripheral.identifier.UUIDString.lowercaseString];
|
|
1094
|
-
NSLog(@"Could not find service with UUID %@ on peripheral with UUID %@",
|
|
1095
|
-
serviceUUIDString,
|
|
1096
|
-
peripheral.identifier.UUIDString.lowercaseString);
|
|
1097
|
-
callback(@[err]);
|
|
1098
|
-
return nil;
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
CBCharacteristic *characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service prop:prop];
|
|
1102
|
-
|
|
1103
|
-
// Special handling for INDICATE. If charateristic with notify is not found, check for indicate.
|
|
1104
|
-
if (prop == CBCharacteristicPropertyNotify && !characteristic) {
|
|
1105
|
-
characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service prop:CBCharacteristicPropertyIndicate];
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
// As a last resort, try and find ANY characteristic with this UUID, even if it doesn't have the correct properties
|
|
1109
|
-
if (!characteristic) {
|
|
1110
|
-
characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service];
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
if (!characteristic)
|
|
1114
|
-
{
|
|
1115
|
-
NSString* err = [NSString stringWithFormat:@"Could not find characteristic with UUID %@ on service with UUID %@ on peripheral with UUID %@", characteristicUUIDString,serviceUUIDString, peripheral.identifier.UUIDString.lowercaseString];
|
|
1116
|
-
NSLog(@"Could not find characteristic with UUID %@ on service with UUID %@ on peripheral with UUID %@",
|
|
1117
|
-
characteristicUUIDString,
|
|
1118
|
-
serviceUUIDString,
|
|
1119
|
-
peripheral.identifier.UUIDString.lowercaseString);
|
|
1120
|
-
callback(@[err]);
|
|
1121
|
-
return nil;
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
BLECommandContext *context = [[BLECommandContext alloc] init];
|
|
1125
|
-
[context setPeripheral:peripheral];
|
|
1126
|
-
[context setService:service];
|
|
1127
|
-
[context setCharacteristic:characteristic];
|
|
1128
|
-
return context;
|
|
1129
|
-
|
|
1130
|
-
}
|
|
1131
|
-
|
|
1132
|
-
-(NSString *) keyForPeripheral: (CBPeripheral *)peripheral andCharacteristic:(CBCharacteristic *)characteristic {
|
|
1133
|
-
return [NSString stringWithFormat:@"%@|%@", [peripheral uuidAsString], [characteristic UUID]];
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
-(NSString *) keyForPeripheral: (CBPeripheral *)peripheral andCharacteristic:(CBCharacteristic *)characteristic andDescriptor:(CBDescriptor *)descriptor {
|
|
1137
|
-
return [NSString stringWithFormat:@"%@|%@|%@", [peripheral uuidAsString], [characteristic UUID], [descriptor UUID]];
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
-(void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary<NSString *,id> *)dict
|
|
1141
|
-
{
|
|
1142
|
-
NSArray<CBPeripheral *> *restoredPeripherals = dict[CBCentralManagerRestoredStatePeripheralsKey];
|
|
1143
|
-
|
|
1144
|
-
if (restoredPeripherals.count > 0) {
|
|
1145
|
-
@synchronized(peripherals) {
|
|
1146
|
-
peripherals = [restoredPeripherals mutableCopy];
|
|
1147
|
-
|
|
1148
|
-
NSMutableArray *data = [NSMutableArray new];
|
|
1149
|
-
for (CBPeripheral *peripheral in peripherals) {
|
|
1150
|
-
[data addObject:[peripheral asDictionary]];
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
[self sendEventWithName:@"BleManagerCentralManagerWillRestoreState" body:@{@"peripherals": data}];
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
+(CBCentralManager *)getCentralManager
|
|
1159
|
-
{
|
|
1160
|
-
return _sharedManager;
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
+(BleManager *)getInstance
|
|
1164
|
-
{
|
|
1165
|
-
return _instance;
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
-(void) insertCallback:(nonnull RCTResponseSenderBlock)callback intoDictionary:(NSMutableDictionary *)dictionary withKey:(NSString *)key
|
|
1169
|
-
{
|
|
1170
|
-
NSMutableArray* peripheralCallbacks = [dictionary objectForKey:key];
|
|
1171
|
-
if (!peripheralCallbacks) {
|
|
1172
|
-
peripheralCallbacks = [NSMutableArray array];
|
|
1173
|
-
[dictionary setObject:peripheralCallbacks forKey:key];
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
[peripheralCallbacks addObject:callback];
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
-(void) invokeAndClearDictionary:(NSMutableDictionary *)dictionary withKey:(NSString *)key usingParameters:(NSArray *)parameters
|
|
1180
|
-
{
|
|
1181
|
-
NSMutableArray* peripheralCallbacks = [dictionary objectForKey:key];
|
|
1182
|
-
if (peripheralCallbacks) {
|
|
1183
|
-
for (RCTResponseSenderBlock callback in peripheralCallbacks) {
|
|
1184
|
-
callback(parameters);
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
[dictionary removeObjectForKey:key];
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
130
|
|
|
1191
131
|
@end
|