@iotize/device-com-ble.cordova 3.0.0 → 3.3.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.
Files changed (145) hide show
  1. package/README.md +174 -177
  2. package/bundles/iotize-device-com-ble.cordova.umd.js +1113 -129
  3. package/bundles/iotize-device-com-ble.cordova.umd.js.map +1 -1
  4. package/bundles/iotize-device-com-ble.cordova.umd.min.js +15 -1
  5. package/bundles/iotize-device-com-ble.cordova.umd.min.js.map +1 -1
  6. package/esm2015/iotize-device-com-ble.cordova.js +5 -1
  7. package/esm2015/iotize-device-com-ble.cordova.js.map +1 -0
  8. package/esm2015/iotize-device-com-ble.cordova.metadata.json +1 -0
  9. package/esm2015/iotize-device-com-ble.cordova.ngsummary.json +1 -1
  10. package/esm2015/lib/ble-com-protocol.js +68 -0
  11. package/esm2015/lib/ble-com-protocol.js.map +1 -0
  12. package/esm2015/lib/ble-com-protocol.metadata.json +1 -0
  13. package/esm2015/lib/ble-com-protocol.ngsummary.json +1 -0
  14. package/esm2015/lib/cordova-ble-error.js +36 -0
  15. package/esm2015/lib/cordova-ble-error.js.map +1 -0
  16. package/esm2015/lib/cordova-ble-error.metadata.json +1 -0
  17. package/esm2015/lib/cordova-ble-error.ngsummary.json +1 -0
  18. package/esm2015/lib/cordova-interface.js +2 -0
  19. package/esm2015/lib/cordova-interface.js.map +1 -0
  20. package/esm2015/lib/cordova-interface.metadata.json +1 -0
  21. package/esm2015/lib/cordova-interface.ngsummary.json +1 -0
  22. package/esm2015/lib/cordova-service-adapter.js +214 -0
  23. package/esm2015/lib/cordova-service-adapter.js.map +1 -0
  24. package/esm2015/lib/cordova-service-adapter.metadata.json +1 -0
  25. package/esm2015/lib/cordova-service-adapter.ngsummary.json +1 -0
  26. package/esm2015/lib/definitions.js +2 -0
  27. package/esm2015/lib/definitions.js.map +1 -0
  28. package/esm2015/lib/definitions.metadata.json +1 -0
  29. package/esm2015/lib/definitions.ngsummary.json +1 -0
  30. package/esm2015/lib/iotize-ble-cordova-plugin.js +170 -0
  31. package/esm2015/lib/iotize-ble-cordova-plugin.js.map +1 -0
  32. package/esm2015/lib/iotize-ble-cordova-plugin.metadata.json +1 -0
  33. package/esm2015/lib/iotize-ble-cordova-plugin.ngsummary.json +1 -0
  34. package/esm2015/lib/logger.js +3 -0
  35. package/esm2015/lib/logger.js.map +1 -0
  36. package/esm2015/lib/logger.metadata.json +1 -0
  37. package/esm2015/{www → lib}/logger.ngsummary.json +1 -1
  38. package/esm2015/lib/scanner.js +151 -0
  39. package/esm2015/lib/scanner.js.map +1 -0
  40. package/esm2015/lib/scanner.metadata.json +1 -0
  41. package/esm2015/lib/scanner.ngsummary.json +1 -0
  42. package/esm2015/lib/utility.js +8 -0
  43. package/esm2015/lib/utility.js.map +1 -0
  44. package/esm2015/lib/utility.metadata.json +1 -0
  45. package/esm2015/lib/utility.ngsummary.json +1 -0
  46. package/esm2015/public_api.js +5 -2
  47. package/esm2015/public_api.js.map +1 -0
  48. package/esm2015/public_api.metadata.json +1 -0
  49. package/esm2015/public_api.ngsummary.json +1 -1
  50. package/fesm2015/iotize-device-com-ble.cordova.js +543 -75
  51. package/fesm2015/iotize-device-com-ble.cordova.js.map +1 -1
  52. package/iotize-device-com-ble.cordova.d.ts +5 -0
  53. package/iotize-device-com-ble.cordova.metadata.json +1 -1
  54. package/lib/ble-com-protocol.d.ts +20 -0
  55. package/lib/cordova-ble-error.d.ts +29 -0
  56. package/lib/cordova-interface.d.ts +5 -0
  57. package/lib/cordova-service-adapter.d.ts +58 -0
  58. package/lib/definitions.d.ts +39 -0
  59. package/lib/iotize-ble-cordova-plugin.d.ts +27 -0
  60. package/lib/logger.d.ts +1 -0
  61. package/lib/scanner.d.ts +55 -0
  62. package/lib/utility.d.ts +2 -0
  63. package/package.json +10 -11
  64. package/plugin.xml +9 -11
  65. package/public_api.d.ts +5 -1
  66. package/src/android/.gradle/4.8.1/fileChanges/last-build.bin +0 -0
  67. package/src/android/.gradle/4.8.1/fileHashes/fileHashes.bin +0 -0
  68. package/src/android/.gradle/4.8.1/fileHashes/fileHashes.lock +0 -0
  69. package/src/android/.gradle/6.8.2/fileChanges/last-build.bin +0 -0
  70. package/src/android/.gradle/6.8.2/fileHashes/fileHashes.lock +0 -0
  71. package/src/android/.gradle/6.8.2/gc.properties +0 -0
  72. package/src/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  73. package/src/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  74. package/src/android/.gradle/checksums/checksums.lock +0 -0
  75. package/src/android/.gradle/configuration-cache/gc.properties +0 -0
  76. package/src/android/.gradle/vcs-1/gc.properties +0 -0
  77. package/src/android/.gradle/vcsWorkingDirs/gc.properties +0 -0
  78. package/src/android/.idea/android.iml +9 -0
  79. package/src/android/.idea/gradle.xml +16 -0
  80. package/src/android/.idea/modules.xml +8 -0
  81. package/src/android/.idea/vcs.xml +6 -0
  82. package/src/android/build.gradle +5 -4
  83. package/src/android/gradle/wrapper/gradle-wrapper.properties +1 -2
  84. package/src/android/src/ble/ArgsHelper.java +73 -0
  85. package/src/android/src/ble/BLECom.java +559 -0
  86. package/src/android/src/{BLEComError.java → ble/BLEComError.java} +22 -10
  87. package/src/android/src/{JSONBuilder.java → ble/JSONBuilder.java} +20 -5
  88. package/src/android/src/{PluginResponse.java → ble/PluginResponse.java} +51 -2
  89. package/src/android/src/ble/UUIDHelper.java +33 -0
  90. package/src/android/src/ble/models/CharacteristicDescription.java +39 -0
  91. package/src/android/src/ble/models/CharacteristicProperties.java +41 -0
  92. package/src/android/src/ble/models/DescriptorDescription.java +21 -0
  93. package/src/android/src/ble/models/RequestDeviceOptions.java +45 -0
  94. package/src/android/src/ble/models/ServiceDescription.java +51 -0
  95. package/src/ios/BLECom.swift +562 -124
  96. package/src/ios/BLEGenericPeripheral.swift +479 -0
  97. package/src/ios/BLEManager.swift +142 -47
  98. package/src/ios/{BLEPeripheral.swift → BLETapPeripheral.swift} +22 -85
  99. package/src/ios/CBPeripheralConverter.swift +86 -1
  100. package/src/ios/Queue.swift +71 -0
  101. package/src/windows/iotize-ble-com.js +159 -179
  102. package/www/plugin.js +2 -0
  103. package/www/plugin.js.LICENSE.txt +14 -0
  104. package/CHANGELOG.md +0 -42
  105. package/esm2015/www/ble-com-protocol.js +0 -75
  106. package/esm2015/www/ble-com-protocol.ngsummary.json +0 -1
  107. package/esm2015/www/cordova-interface.js +0 -1
  108. package/esm2015/www/cordova-interface.ngsummary.json +0 -1
  109. package/esm2015/www/definitions.js +0 -1
  110. package/esm2015/www/definitions.ngsummary.json +0 -1
  111. package/esm2015/www/index.js +0 -3
  112. package/esm2015/www/index.ngsummary.json +0 -1
  113. package/esm2015/www/logger.js +0 -3
  114. package/esm2015/www/scanner.js +0 -89
  115. package/esm2015/www/scanner.ngsummary.json +0 -1
  116. package/esm5/iotize-device-com-ble.cordova.js +0 -2
  117. package/esm5/public_api.js +0 -2
  118. package/esm5/www/ble-com-protocol.js +0 -121
  119. package/esm5/www/cordova-interface.js +0 -1
  120. package/esm5/www/definitions.js +0 -1
  121. package/esm5/www/index.js +0 -3
  122. package/esm5/www/logger.js +0 -3
  123. package/esm5/www/scanner.js +0 -111
  124. package/fesm5/iotize-device-com-ble.cordova.js +0 -233
  125. package/fesm5/iotize-device-com-ble.cordova.js.map +0 -1
  126. package/src/android/.project +0 -17
  127. package/src/android/.settings/org.eclipse.buildship.core.prefs +0 -13
  128. package/src/android/src/ArgsHelper.java +0 -30
  129. package/src/android/src/BLECom.java +0 -375
  130. package/src/public_api.ts +0 -1
  131. package/src/www/ble-com-protocol.spec.ts +0 -9
  132. package/src/www/ble-com-protocol.ts +0 -114
  133. package/src/www/cordova-interface.ts +0 -29
  134. package/src/www/definitions.ts +0 -11
  135. package/src/www/index.ts +0 -4
  136. package/src/www/logger.ts +0 -3
  137. package/src/www/scanner.spec.ts +0 -98
  138. package/src/www/scanner.ts +0 -132
  139. package/www/ble-com-protocol.d.ts +0 -16
  140. package/www/cordova-interface.d.ts +0 -11
  141. package/www/definitions.d.ts +0 -6
  142. package/www/index.d.ts +0 -4
  143. package/www/iotize-ble.js +0 -55
  144. package/www/logger.d.ts +0 -2
  145. package/www/scanner.d.ts +0 -18
@@ -1,18 +1,71 @@
1
- import { bufferToHexString, hexStringToBuffer } from '@iotize/common/byte-converter';
2
- import { safeEnumValue } from '@iotize/common/utility';
3
1
  import { ConnectionState } from '@iotize/tap/protocol/api';
4
2
  import { QueueComProtocol } from '@iotize/tap/protocol/core';
5
- import { Subject, from, BehaviorSubject } from 'rxjs';
6
- import { filter, first } from 'rxjs/operators';
3
+ import { defer, BehaviorSubject, Subject } from 'rxjs';
4
+ import { tap, filter, first, distinctUntilChanged, shareReplay, map, switchMap } from 'rxjs/operators';
7
5
  import { createDebugger } from '@iotize/common/debug';
6
+ import { CodeError } from '@iotize/common/error';
7
+ import { BleComError } from '@iotize/tap/protocol/ble/common';
8
+ import { hexStringToBuffer as hexStringToBuffer$1, bufferToHexString } from '@iotize/common/byte-converter';
9
+ import { safeEnumValue } from '@iotize/common/utility';
8
10
 
9
11
  const debug = createDebugger(`@iotize/device-com-ble.cordova`);
10
12
 
13
+ class CordovaBLEError extends CodeError {
14
+ static invalidErrorResult(errObject) {
15
+ return new CordovaBLEError(`Internal error: ble cordova plugin returned an unexpected error object`, CordovaBLEError.Code.InternalError);
16
+ }
17
+ static invalidErrorCode(errObject) {
18
+ return new CordovaBLEError(`Internal error: ble cordova plugin returned an invalid error code ${errObject.code} with message ${errObject.message}`, CordovaBLEError.Code.InternalError);
19
+ }
20
+ static invalidNativeCallResult(result, cause) {
21
+ return new CordovaBLEError(`Internal error: native call returned an invalid data type. ${cause.message}`, CordovaBLEError.Code.InternalError);
22
+ }
23
+ static isValidErrorCode(code) {
24
+ return code in CordovaBLEError.Code;
25
+ }
26
+ static iotizeBLEMissing() {
27
+ return new CordovaBLEError(`iotizeBLE global variable does not exist. Are you sure app is running inside a Cordova application ?`, CordovaBLEError.Code.InternalError);
28
+ }
29
+ }
30
+ /* istanbul ignore next */
31
+ (function (CordovaBLEError) {
32
+ let Code;
33
+ (function (Code) {
34
+ Code["InternalError"] = "CordovaBLEErrorInternalError";
35
+ Code["IllegalArgument"] = "CordovaBLEErrorIllegalArgument";
36
+ Code["BLENotAvailable"] = "CordovaBLEErrorBLENotAvailable";
37
+ Code["InvalidMacAddress"] = "InvalidMacAddressInvalidMacAddress";
38
+ Code["ConnectionError"] = "CordovaBLEErrorConnectionError";
39
+ Code["RequestError"] = "CordovaBLEErrorRequestError";
40
+ Code["LocationServiceDisabled"] = "CordovaBLEErrorLocationServiceDisabled";
41
+ Code["DisconnectError"] = "CordovaBLEErrorDisconnectError";
42
+ Code["IllegalAction"] = "CordovaBLEErrorIllegalAction";
43
+ Code["NotConnectedError"] = "CordovaBLEErrorNotConnectedError";
44
+ Code["StatusCodeError"] = "CordovaBLEErrorStatusCodeError";
45
+ })(Code = CordovaBLEError.Code || (CordovaBLEError.Code = {}));
46
+ })(CordovaBLEError || (CordovaBLEError = {}));
47
+
48
+ function getIoTizeBleCordovaPlugin() {
49
+ if (typeof iotizeBLE !== "object") {
50
+ throw CordovaBLEError.iotizeBLEMissing();
51
+ }
52
+ return iotizeBLE;
53
+ }
54
+
55
+ var __awaiter$3 = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
56
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
57
+ return new (P || (P = Promise))(function (resolve, reject) {
58
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
59
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
60
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
61
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
62
+ });
63
+ };
11
64
  class BLEComProtocol extends QueueComProtocol {
12
- constructor(deviceId, comProtocolOptions) {
65
+ constructor(deviceId, comProtocolOptions, cordovaInterfaceOverwrite) {
13
66
  super();
14
- this.deviceId = "";
15
67
  this.deviceId = deviceId;
68
+ this.cordovaInterfaceOverwrite = cordovaInterfaceOverwrite;
16
69
  if (comProtocolOptions) {
17
70
  this.options = comProtocolOptions;
18
71
  }
@@ -20,98 +73,338 @@ class BLEComProtocol extends QueueComProtocol {
20
73
  this.options.connect.timeout = 60000;
21
74
  }
22
75
  }
23
- get connectionStateSubject() {
24
- if (!this._connectionStateSubject) {
25
- this._connectionStateSubject = new Subject();
26
- }
27
- return this._connectionStateSubject;
76
+ /**
77
+ * Lazy reference to iotizeBLE.
78
+ * We don't want to reference iotizeBLE in constructor as it may be referenced
79
+ * before cordova plugin is loaded
80
+ */
81
+ get pluginInterface() {
82
+ return this.cordovaInterfaceOverwrite || getIoTizeBleCordovaPlugin();
28
83
  }
29
84
  _connect(options) {
30
- debug('_connect', options);
31
- const connectionStateSubject = this.connectionStateSubject;
32
- this._connectionStateSubscription = connectionStateSubject.subscribe((val) => this.setConnectionState(val));
33
- const onConnectionStateChange = (val) => {
34
- debug('_connect observable: onConnect "', val, '"');
35
- connectionStateSubject.next(safeEnumValue(ConnectionState, val));
36
- };
37
- const onError = (error) => {
38
- debug('_connect observable: onError', error);
39
- connectionStateSubject.error(error);
40
- };
41
- iotizeBLE.connect(this.deviceId, onConnectionStateChange, onError);
42
- return connectionStateSubject.pipe(filter(state => state === ConnectionState.CONNECTED), first());
85
+ debug("_connect", options);
86
+ return this.pluginInterface
87
+ .connectAndDiscoverTapServices(this.deviceId)
88
+ .pipe(tap((state) => {
89
+ this.setConnectionState(state);
90
+ }), filter((state) => state === ConnectionState.CONNECTED), first());
43
91
  }
44
92
  _disconnect(options) {
45
- debug('_disconnect', options);
46
- return from(this._cordovaCallToPromise(iotizeBLE.disConnect, this.deviceId));
93
+ debug("_disconnect", options);
94
+ return defer(() => this.pluginInterface.disConnect(this.deviceId));
47
95
  }
48
96
  write(data) {
49
- throw new Error("Method not implemented.");
97
+ return __awaiter$3(this, void 0, void 0, function* () {
98
+ throw new Error("Method not implemented.");
99
+ });
50
100
  }
51
101
  read() {
52
- throw new Error("Method not implemented.");
102
+ return __awaiter$3(this, void 0, void 0, function* () {
103
+ throw new Error("Method not implemented.");
104
+ });
53
105
  }
54
106
  send(data, options) {
55
- const promise = this._cordovaCallToPromise(iotizeBLE.send, this.deviceId, bufferToHexString(data))
56
- .then((hexString) => hexStringToBuffer(hexString));
57
- return from(promise);
107
+ return defer(() => this.pluginInterface.send(this.deviceId, data));
58
108
  }
59
- _cordovaCallToPromise(cordovaFct, ...args) {
60
- if (!cordovaFct) {
61
- return Promise.reject(new Error(`INTERNAL ERROR UNKOWN CORDOVA FUNCTION`));
62
- }
63
- debug('Call to ', cordovaFct.name, ...args);
64
- return new Promise((resolve, reject) => {
65
- args.push((result) => {
66
- debug('success handler ', result);
67
- resolve(result);
68
- });
69
- args.push((err) => {
70
- debug('error handler ', err);
71
- reject(err);
109
+ }
110
+
111
+ var __awaiter$2 = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
112
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
113
+ return new (P || (P = Promise))(function (resolve, reject) {
114
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
115
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
116
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
117
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
118
+ });
119
+ };
120
+ class CordovaPeripheralAdapter {
121
+ constructor(deviceId, cordovaPlugin = getIoTizeBleCordovaPlugin()) {
122
+ this.deviceId = deviceId;
123
+ this.cordovaPlugin = cordovaPlugin;
124
+ this._stateChange = new BehaviorSubject(ConnectionState.DISCONNECTED);
125
+ }
126
+ get stateChange() {
127
+ return this._stateChange.asObservable().pipe(distinctUntilChanged());
128
+ }
129
+ get name() {
130
+ // TODO device name ?
131
+ return this.id;
132
+ }
133
+ get id() {
134
+ return this.deviceId;
135
+ }
136
+ get state() {
137
+ return ConnectionState[this._stateChange.value];
138
+ }
139
+ discoverServices(serviceUUIDs) {
140
+ return __awaiter$2(this, void 0, void 0, function* () {
141
+ this.serviceListCache = yield this.cordovaPlugin.discoverServices(this.deviceId);
142
+ const result = {};
143
+ if (serviceUUIDs) {
144
+ for (const uuid of serviceUUIDs) {
145
+ const servicDefinition = this.serviceListCache.find((def) => def.uuid === uuid);
146
+ if (servicDefinition) {
147
+ result[uuid] = new CordovaServiceAdapter(servicDefinition, this);
148
+ }
149
+ }
150
+ }
151
+ else {
152
+ for (const serviceDefinition of this.serviceListCache) {
153
+ result[serviceDefinition.uuid] = new CordovaServiceAdapter(serviceDefinition, this);
154
+ }
155
+ }
156
+ return result;
157
+ });
158
+ }
159
+ connect() {
160
+ var _a;
161
+ return __awaiter$2(this, void 0, void 0, function* () {
162
+ (_a = this.connectionStateSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
163
+ const connectObservable = this.cordovaPlugin
164
+ .connect(this.deviceId)
165
+ .pipe(shareReplay());
166
+ this.connectionStateSubscription = connectObservable.subscribe((state) => {
167
+ this._stateChange.next(state);
72
168
  });
73
- cordovaFct.apply(iotizeBLE, args);
169
+ yield connectObservable
170
+ .pipe(filter((state) => state === ConnectionState.CONNECTED), first())
171
+ .toPromise();
172
+ });
173
+ }
174
+ disconnect() {
175
+ var _a;
176
+ return __awaiter$2(this, void 0, void 0, function* () {
177
+ yield this.cordovaPlugin.disConnect(this.deviceId);
178
+ this._stateChange.next(ConnectionState.DISCONNECTED);
179
+ (_a = this.connectionStateSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
180
+ });
181
+ }
182
+ close() {
183
+ var _a;
184
+ return __awaiter$2(this, void 0, void 0, function* () {
185
+ yield this.cordovaPlugin.close(this.deviceId);
186
+ this._stateChange.next(ConnectionState.DISCONNECTED);
187
+ (_a = this.connectionStateSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
188
+ });
189
+ }
190
+ getService(uuid) {
191
+ return __awaiter$2(this, void 0, void 0, function* () {
192
+ if (!this.serviceListCache) {
193
+ yield this.discoverServices([uuid]);
194
+ }
195
+ const serviceDefinition = this.serviceListCache.find((s) => s.uuid === uuid);
196
+ if (!serviceDefinition) {
197
+ throw BleComError.serviceNotFound(uuid);
198
+ }
199
+ return new CordovaServiceAdapter(serviceDefinition, this);
200
+ });
201
+ }
202
+ }
203
+ class CordovaServiceAdapter {
204
+ constructor(config, peripheral) {
205
+ this.config = config;
206
+ this.peripheral = peripheral;
207
+ }
208
+ get uuid() {
209
+ return this.config.uuid;
210
+ }
211
+ getCharacteristic(charcUUID) {
212
+ var _a;
213
+ return __awaiter$2(this, void 0, void 0, function* () {
214
+ const characteristicDescription = (_a = this.config.characteristics) === null || _a === void 0 ? void 0 : _a.find((c) => c.uuid === charcUUID);
215
+ if (!characteristicDescription) {
216
+ throw BleComError.charcacteristicNotFound(charcUUID);
217
+ }
218
+ return new CordovaCharacteristicAdapter(this, characteristicDescription);
219
+ });
220
+ }
221
+ getCharacteristics() {
222
+ return __awaiter$2(this, void 0, void 0, function* () {
223
+ if (!this.config.characteristics) {
224
+ return [];
225
+ }
226
+ return this.config.characteristics.map((c) => new CordovaCharacteristicAdapter(this, c));
74
227
  });
75
228
  }
76
229
  }
77
- ;
230
+ class CordovaCharacteristicAdapter {
231
+ constructor(service, config) {
232
+ this.service = service;
233
+ this.config = config;
234
+ }
235
+ get uuid() {
236
+ return this.config.uuid;
237
+ }
238
+ get properties() {
239
+ return this.config.properties;
240
+ }
241
+ get data() {
242
+ return this.setupDataStreamIfRequired().pipe(map((data) => ({
243
+ data,
244
+ isNotification: true,
245
+ })));
246
+ }
247
+ get deviceId() {
248
+ return this.service.peripheral.deviceId;
249
+ }
250
+ get pluginInterface() {
251
+ return this.service.peripheral.cordovaPlugin;
252
+ }
253
+ read() {
254
+ return __awaiter$2(this, void 0, void 0, function* () {
255
+ return this.pluginInterface.characteristicReadValue(this.deviceId, this.service.uuid, this.uuid);
256
+ });
257
+ }
258
+ getDescriptor() {
259
+ return __awaiter$2(this, void 0, void 0, function* () {
260
+ throw new Error(`Not implemented yet`);
261
+ });
262
+ }
263
+ getDescriptors() {
264
+ return __awaiter$2(this, void 0, void 0, function* () {
265
+ if (!this.config.descriptors) {
266
+ return [];
267
+ }
268
+ return this.config.descriptors.map((descriptor) => new CordovaDescriptorAdapter(descriptor, this));
269
+ });
270
+ }
271
+ write(data, writeWithoutResponse) {
272
+ return __awaiter$2(this, void 0, void 0, function* () {
273
+ if (writeWithoutResponse) {
274
+ yield this.pluginInterface.characteristicWriteWithoutResponse(this.deviceId, this.service.uuid, this.uuid, data);
275
+ }
276
+ else {
277
+ yield this.pluginInterface.characteristicWrite(this.deviceId, this.service.uuid, this.uuid, data);
278
+ }
279
+ return data;
280
+ });
281
+ }
282
+ enableNotifications(enabled) {
283
+ return __awaiter$2(this, void 0, void 0, function* () {
284
+ if (enabled) {
285
+ this.setupDataStreamIfRequired();
286
+ yield this.pluginInterface.characteristicStartNotification(this.deviceId, this.service.uuid, this.uuid);
287
+ }
288
+ else {
289
+ yield this.pluginInterface.characteristicStopNotification(this.deviceId, this.service.uuid, this.uuid);
290
+ }
291
+ });
292
+ }
293
+ setupDataStreamIfRequired() {
294
+ if (!this._dataStream) {
295
+ this._dataStream = this.pluginInterface.characteristicChanged(this.deviceId, this.service.uuid, this.uuid);
296
+ }
297
+ return this._dataStream;
298
+ }
299
+ }
300
+ class CordovaDescriptorAdapter {
301
+ constructor(config, characteristic) {
302
+ this.config = config;
303
+ this.characteristic = characteristic;
304
+ }
305
+ get uuid() {
306
+ return this.config.uuid;
307
+ }
308
+ readValue() {
309
+ return __awaiter$2(this, void 0, void 0, function* () {
310
+ throw new Error(`Reading descriptor value is not implemented yet`);
311
+ });
312
+ }
313
+ writeValue(data) {
314
+ return __awaiter$2(this, void 0, void 0, function* () {
315
+ throw new Error(`Writing descriptor value is not implemented yet`);
316
+ });
317
+ }
318
+ }
78
319
 
320
+ //
321
+ // Copyright 2018 IoTize SAS Inc. Licensed under the MIT license.
322
+ //
323
+ // scanner.ts
324
+ // device-com-ble.cordova BLE Cordova Plugin
325
+ //
326
+ var __awaiter$1 = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
327
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
328
+ return new (P || (P = Promise))(function (resolve, reject) {
329
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
330
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
331
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
332
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
333
+ });
334
+ };
335
+ /**
336
+ * BLE Tap scanner for cordova apps
337
+ */
79
338
  class BLEScanner {
80
- constructor(cordovaInterface = iotizeBLE) {
81
- this.cordovaInterface = cordovaInterface;
339
+ /**
340
+ *
341
+ * @param cordovaInterfaceOverwrite overwrite cordova interface. Used for testing
342
+ */
343
+ constructor(cordovaInterfaceOverwrite,
344
+ /**
345
+ * Request device options used to filter scan results
346
+ */
347
+ requestDeviceOptions) {
348
+ this.cordovaInterfaceOverwrite = cordovaInterfaceOverwrite;
349
+ this.requestDeviceOptions = requestDeviceOptions;
82
350
  this._results = new BehaviorSubject([]);
83
351
  this._scanning$ = new BehaviorSubject(false);
84
352
  }
353
+ /**
354
+ * Lazy reference to iotizeBLE.
355
+ * We don't want to reference iotizeBLE in constructor as it may be referenced
356
+ * before cordova plugin is loaded
357
+ */
358
+ get cordovaInterface() {
359
+ return this.cordovaInterfaceOverwrite || getIoTizeBleCordovaPlugin();
360
+ }
85
361
  get scanning() {
86
362
  return this._scanning$.asObservable();
87
363
  }
88
364
  get isScanning() {
89
365
  return this._scanning$.value;
90
366
  }
367
+ /**
368
+ * Gets the observable on the devices$ Subject
369
+ * @return
370
+ */
91
371
  get results() {
92
372
  return this._results.asObservable();
93
373
  }
374
+ /**
375
+ * Launches the scan for BLE devices
376
+ * Throws if BLE is not available
377
+ */
94
378
  start(options) {
95
- return this.checkAvailable().then(isAvailable => {
379
+ var _a;
380
+ return __awaiter$1(this, void 0, void 0, function* () {
381
+ (_a = this.scanSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
382
+ this.scanSubscription = undefined;
383
+ this.clearResults();
384
+ const isAvailable = yield this.checkAvailable();
96
385
  if (!isAvailable) {
97
- return Promise.reject("BLE is not available");
386
+ throw BleComError.bleNotAvailable(`BLE is not available. Make sure that BLE is enabled on your device`);
98
387
  }
99
388
  debug("Start Scanning ...");
100
389
  this._scanning$.next(true);
101
390
  return new Promise((resolve, reject) => {
102
- this.cordovaInterface.startScan((result) => {
103
- debug('iotizeBLE.startScan', result);
104
- if (result == 'Ok') {
391
+ this.scanSubscription = this.cordovaInterface
392
+ .startScan(this.requestDeviceOptions)
393
+ .subscribe((result) => {
394
+ if (result == "Ok") {
105
395
  resolve();
106
396
  return;
107
397
  }
108
398
  this.addOrRefreshDevice(result);
109
399
  }, (error) => {
400
+ debug("Start scan failed with error: ", error);
110
401
  this.cordovaInterface
111
- .getLastError((lasterror) => {
112
- debug("let BLE error " + lasterror);
113
- }, (err) => {
114
- debug('cannot get last BLE error: ', err);
402
+ .getLastError()
403
+ .then((lasterror) => {
404
+ debug("Last BLE error " + lasterror);
405
+ })
406
+ .catch((err) => {
407
+ debug("Cannot get last BLE error: ", err);
115
408
  });
116
409
  reject(error);
117
410
  this._scanning$.next(false);
@@ -119,39 +412,47 @@ class BLEScanner {
119
412
  });
120
413
  });
121
414
  }
415
+ /**
416
+ *
417
+ */
122
418
  stop() {
123
- debug("Stop Scanning ...");
124
- return new Promise((resolve, reject) => {
125
- this.cordovaInterface
126
- .stopScan((result) => {
419
+ var _a;
420
+ return __awaiter$1(this, void 0, void 0, function* () {
421
+ debug("Stop Scanning ...");
422
+ try {
423
+ (_a = this.scanSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
424
+ this.scanSubscription = undefined;
425
+ yield this.cordovaInterface.stopScan();
127
426
  this._scanning$.next(false);
128
- resolve();
129
- }, (error) => {
427
+ return;
428
+ }
429
+ catch (err) {
130
430
  this._scanning$.next(false);
131
- reject(error);
132
- });
431
+ throw err;
432
+ }
133
433
  });
134
434
  }
435
+ /**
436
+ * Returns true if this scanner is available
437
+ */
135
438
  checkAvailable() {
136
- return new Promise((resolve, reject) => {
137
- this.cordovaInterface.checkAvailable((result) => {
138
- debug('checkAvailable result', result);
139
- resolve(result);
140
- }, (error) => {
141
- reject(error);
142
- });
143
- });
439
+ return this.cordovaInterface.checkAvailable();
144
440
  }
145
441
  get devices() {
146
442
  return this._results.value;
147
443
  }
444
+ clearResults() {
445
+ this._results.next([]);
446
+ }
148
447
  addOrRefreshDevice(newDevice) {
149
448
  let storedDeviceIndex = this.devices.findIndex((entry) => entry.address == newDevice.address);
150
449
  if (storedDeviceIndex >= 0) {
151
450
  let storedDevice = this.devices[storedDeviceIndex];
152
- if (storedDevice.name != newDevice.name || storedDevice.rssi != newDevice.rssi) {
451
+ if (storedDevice.name != newDevice.name ||
452
+ storedDevice.rssi != newDevice.rssi) {
153
453
  debug(`Updating device at index ${storedDeviceIndex}, name=${storedDevice.name} with rssi=${storedDevice.rssi}`);
154
454
  this.devices[storedDeviceIndex] = newDevice;
455
+ // this.devices = [...this.devices];
155
456
  this._results.next(this.devices);
156
457
  }
157
458
  }
@@ -163,5 +464,172 @@ class BLEScanner {
163
464
  }
164
465
  }
165
466
 
166
- export { BLEComProtocol, BLEScanner };
467
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
468
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
469
+ return new (P || (P = Promise))(function (resolve, reject) {
470
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
471
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
472
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
473
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
474
+ });
475
+ };
476
+ function hexStringToBuffer(str) {
477
+ try {
478
+ return hexStringToBuffer$1(str);
479
+ }
480
+ catch (err) {
481
+ throw CordovaBLEError.invalidNativeCallResult(str, err);
482
+ }
483
+ }
484
+ class IoTizeBleCordovaPlugin {
485
+ checkAvailable() {
486
+ return this.execSingleResult("checkAvailable", []);
487
+ }
488
+ requestEnableBle() {
489
+ return this.execSingleResult("enable", []);
490
+ }
491
+ startScan(requestDeviceOptions) {
492
+ return this.execMultipleResult("startScan", [
493
+ JSON.stringify(requestDeviceOptions),
494
+ ]);
495
+ }
496
+ stopScan() {
497
+ return this.execSingleResult("stopScan", []);
498
+ }
499
+ connect(deviceId, enableBleIfNot = true) {
500
+ return this.askBleEnable(enableBleIfNot).pipe(switchMap(() => {
501
+ return this.execMultipleResult("connect", [deviceId]).pipe(map((state) => {
502
+ if (!(state in ConnectionState)) {
503
+ console.warn(`Plugin native code returned an invalid connection state: "${state}".`);
504
+ }
505
+ return safeEnumValue(ConnectionState, state);
506
+ }));
507
+ }));
508
+ }
509
+ askBleEnable(askEnable) {
510
+ return defer(() => __awaiter(this, void 0, void 0, function* () {
511
+ if (askEnable) {
512
+ if (!(yield this.checkAvailable())) {
513
+ yield this.requestEnableBle();
514
+ }
515
+ }
516
+ }));
517
+ }
518
+ requestMTU(deviceId, mtu) {
519
+ return this.execSingleResult("requestMTU", [deviceId, mtu]);
520
+ }
521
+ connectAndDiscoverTapServices(deviceId, enableBleIfNot = true) {
522
+ return this.askBleEnable(enableBleIfNot).pipe(switchMap(() => {
523
+ return this.execMultipleResult("connectAndDiscoverTapServices", [deviceId]).pipe(map((state) => {
524
+ if (!(state in ConnectionState)) {
525
+ console.warn(`Plugin native code returned an invalid connection state: "${state}".`);
526
+ }
527
+ return safeEnumValue(ConnectionState, state);
528
+ }));
529
+ }));
530
+ }
531
+ disConnect(deviceId) {
532
+ return this.execSingleResult("disConnect", [deviceId]);
533
+ }
534
+ close(deviceId) {
535
+ return this.execSingleResult("close", [deviceId]);
536
+ }
537
+ isConnected(deviceId) {
538
+ return this.execSingleResult("isConnected", [deviceId]);
539
+ }
540
+ send(deviceId, data) {
541
+ return __awaiter(this, void 0, void 0, function* () {
542
+ const hexString = yield this.execSingleResult("sendRequest", [
543
+ deviceId,
544
+ bufferToHexString(data),
545
+ ]);
546
+ return hexStringToBuffer(hexString);
547
+ });
548
+ }
549
+ getLastError() {
550
+ return this.execSingleResult("getLastError", []);
551
+ }
552
+ characteristicStartNotification(deviceId, serviceId, characId) {
553
+ return this.execSingleResult("characteristicStartNotification", [
554
+ deviceId,
555
+ serviceId,
556
+ characId,
557
+ ]);
558
+ }
559
+ characteristicChanged(deviceId, serviceId, characId) {
560
+ return this.execMultipleResult("characteristicChanged", [
561
+ deviceId,
562
+ serviceId,
563
+ characId,
564
+ ]).pipe(map((hexString) => {
565
+ return hexStringToBuffer(hexString);
566
+ }));
567
+ }
568
+ characteristicStopNotification(deviceId, serviceId, characId) {
569
+ return this.execSingleResult("characteristicStopNotification", [
570
+ deviceId,
571
+ serviceId,
572
+ characId,
573
+ ]);
574
+ }
575
+ characteristicReadValue(deviceId, serviceId, characId) {
576
+ return __awaiter(this, void 0, void 0, function* () {
577
+ const hexString = yield this.execSingleResult("characteristicRead", [deviceId, serviceId, characId]);
578
+ return hexStringToBuffer(hexString);
579
+ });
580
+ }
581
+ characteristicWrite(deviceId, serviceId, characId, data) {
582
+ return this.execSingleResult("characteristicWrite", [
583
+ deviceId,
584
+ serviceId,
585
+ characId,
586
+ bufferToHexString(data),
587
+ ]);
588
+ }
589
+ characteristicWriteWithoutResponse(deviceId, serviceId, characId, data) {
590
+ return this.execSingleResult("characteristicWriteWithoutResponse", [
591
+ deviceId,
592
+ serviceId,
593
+ characId,
594
+ bufferToHexString(data),
595
+ ]);
596
+ }
597
+ discoverServices(deviceId) {
598
+ return __awaiter(this, void 0, void 0, function* () {
599
+ const services = yield this.execSingleResult("discoverServices", [deviceId]);
600
+ return services;
601
+ });
602
+ }
603
+ execSingleResult(methodName, args) {
604
+ return new Promise((resolve, reject) => {
605
+ cordova.exec(resolve, (errObject) => {
606
+ reject(objectErrorToError(errObject));
607
+ }, "BLECom", methodName, args);
608
+ });
609
+ }
610
+ execMultipleResult(methodName, args) {
611
+ const subject = new Subject();
612
+ cordova.exec((data) => {
613
+ subject.next(data);
614
+ }, (err) => {
615
+ subject.error(objectErrorToError(err));
616
+ }, "BLECom", methodName, args);
617
+ return subject.asObservable();
618
+ }
619
+ }
620
+ function objectErrorToError(errObject) {
621
+ if (typeof errObject !== "object" || !errObject.code || !errObject.message) {
622
+ return CordovaBLEError.invalidErrorResult(errObject);
623
+ }
624
+ if (!CordovaBLEError.isValidErrorCode(errObject.code)) {
625
+ return CordovaBLEError.invalidErrorCode(errObject);
626
+ }
627
+ return new CordovaBLEError(errObject.message, CordovaBLEError.Code[errObject.code]);
628
+ }
629
+
630
+ /**
631
+ * Generated bundle index. Do not edit.
632
+ */
633
+
634
+ export { BLEComProtocol, BLEScanner, CordovaCharacteristicAdapter, CordovaPeripheralAdapter, CordovaServiceAdapter, getIoTizeBleCordovaPlugin, IoTizeBleCordovaPlugin as ɵc };
167
635
  //# sourceMappingURL=iotize-device-com-ble.cordova.js.map