UNPKG

nativescript-bluetooth

Version:
975 lines 79.3 kB
Object.defineProperty(exports, "__esModule", { value: true }); var bluetooth_common_1 = require("./bluetooth.common"); function nativeEncoding(encoding) { switch (encoding) { case 'utf-8': return NSUTF8StringEncoding; case 'latin2': case 'iso-8859-2': return NSISOLatin2StringEncoding; case 'shift-jis': return NSShiftJISStringEncoding; case 'iso-2022-jp': return NSISO2022JPStringEncoding; case 'euc-jp': return NSJapaneseEUCStringEncoding; case 'windows-1250': return NSWindowsCP1250StringEncoding; case 'windows-1251': return NSWindowsCP1251StringEncoding; case 'windows-1252': return NSWindowsCP1252StringEncoding; case 'windows-1253': return NSWindowsCP1253StringEncoding; case 'windows-1254': return NSWindowsCP1254StringEncoding; case 'utf-16be': return NSUTF16BigEndianStringEncoding; case 'utf-16le': return NSUTF16LittleEndianStringEncoding; default: case 'iso-8859-1': case 'latin1': return NSISOLatin1StringEncoding; } } function valueToNSData(value, encoding) { if (encoding === void 0) { encoding = 'iso-8859-1'; } if (value instanceof NSData) { return value; } else if (value instanceof ArrayBuffer) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion return NSData.dataWithData(value); } else if (value.buffer) { return NSData.dataWithData(value.buffer); } else if (Array.isArray(value)) { return NSData.dataWithData(new Uint8Array(value).buffer); } var type = typeof value; if (type === 'string') { return NSString.stringWithString(value).dataUsingEncoding(nativeEncoding(encoding)); } else if (type === 'number') { return NSData.dataWithData(new Uint8Array([value]).buffer); } return null; } function valueToString(value) { if (value instanceof NSData) { var data = new Uint8Array(interop.bufferFromData(value)); var result_1 = []; data.forEach(function (v, i) { return (result_1[i] = v); }); return result_1; } return value; } function stringToUint8Array(value, encoding) { if (encoding === void 0) { encoding = 'iso-8859-1'; } var nativeArray = NSString.stringWithString(value).dataUsingEncoding(nativeEncoding(encoding)); return new Uint8Array(interop.bufferFromData(nativeArray)); } exports.stringToUint8Array = stringToUint8Array; var utils_1 = require("@nativescript/core/utils/utils"); /** * @link - https://developer.apple.com/documentation/corebluetooth/cbperipheraldelegate * The delegate of a CBPeripheral object must adopt the CBPeripheralDelegate protocol. * The delegate uses this protocol’s methods to monitor the discovery, exploration, and interaction of a remote peripheral’s services and properties. * There are no required methods in this protocol. */ var CBPeripheralDelegateImpl = /** @class */ (function (_super) { __extends(CBPeripheralDelegateImpl, _super); function CBPeripheralDelegateImpl() { return _super !== null && _super.apply(this, arguments) || this; } CBPeripheralDelegateImpl.prototype.addSubDelegate = function (delegate) { var index = this.subDelegates.indexOf(delegate); if (index === -1) { this.subDelegates.push(delegate); } }; CBPeripheralDelegateImpl.prototype.removeSubDelegate = function (delegate) { var index = this.subDelegates.indexOf(delegate); if (index !== -1) { this.subDelegates.splice(index, 1); } }; CBPeripheralDelegateImpl.new = function () { return _super.new.call(this); }; CBPeripheralDelegateImpl.prototype.initWithOwner = function (owner) { this._owner = owner; this.subDelegates = []; this.onNotifyCallbacks = {}; bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.initWithOwner: " + owner.get()); return this; }; /** * Invoked when you discover the peripheral’s available services. * This method is invoked when your app calls the discoverServices(_:) method. * If the services of the peripheral are successfully discovered, you can access them through the peripheral’s services property. * If successful, the error parameter is nil. * If unsuccessful, the error parameter returns the cause of the failure. * @param peripheral [CBPeripheral] - The peripheral that the services belong to. * @param error [NSError] - If an error occurred, the cause of the failure. */ CBPeripheralDelegateImpl.prototype.peripheralDidDiscoverServices = function (peripheral, error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidDiscoverServices ---- peripheral: " + peripheral + ", " + error + ", " + this); this.subDelegates.forEach(function (d) { if (d.peripheralDidDiscoverServices) { d.peripheralDidDiscoverServices(peripheral, error); } }); }; /** * Invoked when you discover the included services of a specified service. * @param peripheral [CBPeripheral] - The peripheral providing this information. * @param service [CBService] - The CBService object containing the included service. * @param error [NSError] - If an error occurred, the cause of the failure. */ CBPeripheralDelegateImpl.prototype.peripheralDidDiscoverIncludedServicesForServiceError = function (peripheral, service, error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidDiscoverIncludedServicesForServiceError ---- peripheral: " + peripheral + ", service: " + service + ", error: " + error); this.subDelegates.forEach(function (d) { if (d.peripheralDidDiscoverIncludedServicesForServiceError) { d.peripheralDidDiscoverIncludedServicesForServiceError(peripheral, service, error); } }); }; /** * Invoked when you discover the characteristics of a specified service. * @param peripheral [CBPeripheral] - The peripheral providing this information. * @param service [CBService] - The CBService object containing the included service. * @param error [NSError] - If an error occurred, the cause of the failure. */ CBPeripheralDelegateImpl.prototype.peripheralDidDiscoverCharacteristicsForServiceError = function (peripheral, service, error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidDiscoverCharacteristicsForServiceError ---- peripheral: " + peripheral + ", service: " + service + ", error: " + error); this.subDelegates.forEach(function (d) { if (d.peripheralDidDiscoverCharacteristicsForServiceError) { d.peripheralDidDiscoverCharacteristicsForServiceError(peripheral, service, error); } }); }; /** * Invoked when you discover the descriptors of a specified characteristic. * @param peripheral [CBPeripheral] - The peripheral providing this information. * @param characteristic [CBCharacteristic] - The characteristic that the characteristic descriptors belong to. * @param error [NSError] - If an error occurred, the cause of the failure. */ CBPeripheralDelegateImpl.prototype.peripheralDidDiscoverDescriptorsForCharacteristicError = function (peripheral, characteristic, error) { // NOTE that this cb won't be invoked bc we currently don't discover descriptors bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidDiscoverDescriptorsForCharacteristicError ---- peripheral: " + peripheral + ", characteristic: " + characteristic + ", error: " + error); this.subDelegates.forEach(function (d) { if (d.peripheralDidDiscoverDescriptorsForCharacteristicError) { d.peripheralDidDiscoverDescriptorsForCharacteristicError(peripheral, characteristic, error); } }); }; /** * Invoked when you retrieve a specified characteristic’s value, or when * the peripheral device notifies your app that the characteristic’s * value has changed. */ CBPeripheralDelegateImpl.prototype.peripheralDidUpdateValueForCharacteristicError = function (peripheral, characteristic, error) { if (!characteristic) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.warning, 'CBPeripheralDelegateImpl.peripheralDidUpdateValueForCharacteristicError ---- No CBCharacteristic.'); return; } this.subDelegates.forEach(function (d) { if (d.peripheralDidUpdateValueForCharacteristicError) { d.peripheralDidUpdateValueForCharacteristicError(peripheral, characteristic, error); } }); if (error !== null) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.error, "CBPeripheralDelegateImpl.peripheralDidUpdateValueForCharacteristicError ---- " + error); return; } if (characteristic.isNotifying) { var cUUID = CBUUIDToString(characteristic.UUID); var sUUID = CBUUIDToString(characteristic.service.UUID); var key = sUUID + '/' + cUUID; if (this.onNotifyCallbacks[key]) { this.onNotifyCallbacks[key]({ // type: 'notification', serviceUUID: sUUID, characteristicUUID: cUUID, ios: characteristic.value, value: toArrayBuffer(characteristic.value), }); } else { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, '----- CALLBACK IS GONE -----'); } } }; /** * Invoked when you retrieve a specified characteristic descriptor’s value. */ CBPeripheralDelegateImpl.prototype.peripheralDidUpdateValueForDescriptorError = function (peripheral, descriptor, error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidUpdateValueForDescriptorError ---- peripheral: " + peripheral + ", descriptor: " + descriptor + ", error: " + error); this.subDelegates.forEach(function (d) { if (d.peripheralDidUpdateValueForDescriptorError) { d.peripheralDidUpdateValueForDescriptorError(peripheral, descriptor, error); } }); }; /** * Invoked when you write data to a characteristic’s value. */ CBPeripheralDelegateImpl.prototype.peripheralDidWriteValueForCharacteristicError = function (peripheral, characteristic, error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidWriteValueForCharacteristicError ---- peripheral: " + peripheral + ", characteristic: " + characteristic + ", error: " + error); this.subDelegates.forEach(function (d) { if (d.peripheralDidWriteValueForCharacteristicError) { d.peripheralDidWriteValueForCharacteristicError(peripheral, characteristic, error); } }); }; /** * Invoked when the peripheral receives a request to start or stop * providing notifications for a specified characteristic’s value. */ CBPeripheralDelegateImpl.prototype.peripheralDidUpdateNotificationStateForCharacteristicError = function (peripheral, characteristic, error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidUpdateNotificationStateForCharacteristicError ---- peripheral: " + peripheral + ", characteristic: " + characteristic + ", error: " + error); this.subDelegates.forEach(function (d) { if (d.peripheralDidUpdateNotificationStateForCharacteristicError) { d.peripheralDidUpdateNotificationStateForCharacteristicError(peripheral, characteristic, error); } }); if (error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.error, "CBPeripheralDelegateImpl.peripheralDidUpdateNotificationStateForCharacteristicError ---- " + error); } else { if (characteristic.isNotifying) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidUpdateNotificationStateForCharacteristicError ---- Notification began on " + characteristic); } else { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidUpdateNotificationStateForCharacteristicError ---- Notification stopped on " + characteristic); // Bluetooth._manager.cancelPeripheralConnection(peripheral); } } }; /** * IInvoked when you write data to a characteristic descriptor’s value. */ CBPeripheralDelegateImpl.prototype.peripheralDidWriteValueForDescriptorError = function (peripheral, descriptor, error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBPeripheralDelegateImpl.peripheralDidWriteValueForDescriptorError ---- peripheral: " + peripheral + ", descriptor: " + descriptor + ", error: " + error); this.subDelegates.forEach(function (d) { if (d.peripheralDidWriteValueForDescriptorError) { d.peripheralDidWriteValueForDescriptorError(peripheral, descriptor, error); } }); }; CBPeripheralDelegateImpl.ObjCProtocols = [CBPeripheralDelegate]; return CBPeripheralDelegateImpl; }(NSObject)); exports.CBPeripheralDelegateImpl = CBPeripheralDelegateImpl; /** * @link - https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerdelegate * The CBCentralManagerDelegate protocol defines the methods that a delegate of a CBCentralManager object must adopt. * The optional methods of the protocol allow the delegate to monitor the discovery, connectivity, and retrieval of peripheral devices. * The only required method of the protocol indicates the availability of the central manager, and is called when the central manager’s state is updated. */ var CBCentralManagerDelegateImpl = /** @class */ (function (_super) { __extends(CBCentralManagerDelegateImpl, _super); function CBCentralManagerDelegateImpl() { return _super !== null && _super.apply(this, arguments) || this; } CBCentralManagerDelegateImpl.prototype.addSubDelegate = function (delegate) { var index = this.subDelegates.indexOf(delegate); if (index === -1) { this.subDelegates.push(delegate); } }; CBCentralManagerDelegateImpl.prototype.removeSubDelegate = function (delegate) { var index = this.subDelegates.indexOf(delegate); if (index !== -1) { this.subDelegates.splice(index, 1); } }; CBCentralManagerDelegateImpl.new = function () { return _super.new.call(this); }; CBCentralManagerDelegateImpl.prototype.initWithOwner = function (owner) { this._owner = owner; this.subDelegates = []; bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBCentralManagerDelegateImpl.initWithOwner: " + this._owner); // this._callback = callback; return this; }; /** * Invoked when a connection is successfully created with a peripheral. * This method is invoked when a call to connect(_:options:) is successful. * You typically implement this method to set the peripheral’s delegate and to discover its services. * @param central [CBCentralManager] - The central manager providing this information. * @param peripheral [CBPeripheral] - The peripheral that has been connected to the system. */ CBCentralManagerDelegateImpl.prototype.centralManagerDidConnectPeripheral = function (central, peripheral) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "----- CBCentralManagerDelegateImpl centralManager:didConnectPeripheral: " + peripheral); this._owner.get().onPeripheralConnected(peripheral); bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "----- CBCentralManagerDelegateImpl centralManager:didConnectPeripheral, let's discover service"); this.subDelegates.forEach(function (d) { if (d.centralManagerDidConnectPeripheral) { d.centralManagerDidConnectPeripheral(central, peripheral); } }); }; /** * Invoked when an existing connection with a peripheral is torn down. * This method is invoked when a peripheral connected via the connect(_:options:) method is disconnected. * If the disconnection was not initiated by cancelPeripheralConnection(_:), the cause is detailed in error. * After this method is called, no more methods are invoked on the peripheral device’s CBPeripheralDelegate object. * Note that when a peripheral is disconnected, all of its services, characteristics, and characteristic descriptors are invalidated. * @param central [CBCentralManager] - The central manager providing this information. * @param peripheral [CBPeripheral] - The peripheral that has been disconnected. * @param error? [NSError] - If an error occurred, the cause of the failure. */ CBCentralManagerDelegateImpl.prototype.centralManagerDidDisconnectPeripheralError = function (central, peripheral, error) { // this event needs to be honored by the client as any action afterwards crashes the app var UUID = NSUUIDToString(peripheral.identifier); bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, 'CBCentralManagerDelegate.centralManagerDidDisconnectPeripheralError ----', central, peripheral, error); this._owner.get().onPeripheralDisconnected(peripheral); this.subDelegates.forEach(function (d) { if (d.centralManagerDidDisconnectPeripheralError) { d.centralManagerDidDisconnectPeripheralError(central, peripheral, error); } }); }; /** * Invoked when the central manager fails to create a connection with a peripheral. * This method is invoked when a connection initiated via the connect(_:options:) method fails to complete. * Because connection attempts do not time out, a failed connection usually indicates a transient issue, in which case you may attempt to connect to the peripheral again. * @param central [CBCentralManager] - The central manager providing this information. * @param peripheral [CBPeripheral] - The peripheral that failed to connect. * @param error? [NSError] - The cause of the failure. */ CBCentralManagerDelegateImpl.prototype.centralManagerDidFailToConnectPeripheralError = function (central, peripheral, error) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, 'CBCentralManagerDelegate.centralManagerDidFailToConnectPeripheralError ----', central, peripheral, error); this.subDelegates.forEach(function (d) { if (d.centralManagerDidDisconnectPeripheralError) { d.centralManagerDidFailToConnectPeripheralError(central, peripheral, error); } }); }; /** * Invoked when the central manager discovers a peripheral while scanning. * The advertisement data can be accessed through the keys listed in Advertisement Data Retrieval Keys. * You must retain a local copy of the peripheral if any command is to be performed on it. * In use cases where it makes sense for your app to automatically connect to a peripheral that is located within a certain range, you can use RSSI data to determine the proximity of a discovered peripheral device. * @param central [CBCentralManager] - The central manager providing the update. * @param peripheral [CBPeripheral] - The discovered peripheral. * @param advData [NSDictionary<string, any>] - A dictionary containing any advertisement data. * @param RSSI [NSNumber] - The current received signal strength indicator (RSSI) of the peripheral, in decibels. */ CBCentralManagerDelegateImpl.prototype.centralManagerDidDiscoverPeripheralAdvertisementDataRSSI = function (central, peripheral, advData, RSSI) { var UUIDString = NSUUIDToString(peripheral.identifier); bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBCentralManagerDelegateImpl.centralManagerDidDiscoverPeripheralAdvertisementDataRSSI ---- " + peripheral.name + " @ " + UUIDString + " @ " + RSSI + " @ " + advData); var owner = this._owner && this._owner.get(); if (!owner) { return; } owner.adddDiscoverPeripheral(peripheral); var advertismentData = new AdvertismentData(advData); var payload = { UUID: UUIDString, name: peripheral.name, localName: advertismentData.localName, RSSI: RSSI, advertismentData: advertismentData, state: this._owner.get()._getState(peripheral.state), manufacturerId: advertismentData.manufacturerId, }; owner._advData[UUIDString] = advertismentData; if (owner._onDiscovered) { owner._onDiscovered(payload); } owner.sendEvent(Bluetooth.device_discovered_event, payload); }; /** * Invoked when the central manager’s state is updated. * You implement this required method to ensure that Bluetooth low energy is supported and available to use on the central device. * You should issue commands to the central manager only when the state of the central manager is powered on, as indicated by the poweredOn constant. * A state with a value lower than poweredOn implies that scanning has stopped and that any connected peripherals have been disconnected. * If the state moves below poweredOff, all CBPeripheral objects obtained from this central manager become invalid and must be retrieved or discovered again. * For a complete list and discussion of the possible values representing the state of the central manager, see the CBCentralManagerState enumeration in CBCentralManager. * @param central [CBCentralManager] - The central manager providing this information. */ CBCentralManagerDelegateImpl.prototype.centralManagerDidUpdateState = function (central) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBCentralManagerDelegateImpl.centralManagerDidUpdateState: " + central.state); if (central.state === 2 /* Unsupported */) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.warning, 'CBCentralManagerDelegateImpl.centralManagerDidUpdateState ---- This hardware does not support Bluetooth Low Energy.'); } this._owner.get().state = central.state; }; /** * Invoked when the central manager is about to be restored by the system. * @param central [CBCentralManager] - The central manager providing this information. * @param dict [NSDictionary<string, any>] - A dictionary containing information about the central manager that was preserved by the system at the time the app was terminated. * For the available keys to this dictionary, see Central Manager State Restoration Options. * @link - https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerdelegate/central_manager_state_restoration_options */ CBCentralManagerDelegateImpl.prototype.centralManagerWillRestoreState = function (central, dict) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "CBCentralManagerDelegateImpl.centralManagerWillRestoreState ---- central: " + central + ", dict: " + dict); }; CBCentralManagerDelegateImpl.ObjCProtocols = [CBCentralManagerDelegate]; return CBCentralManagerDelegateImpl; }(NSObject)); exports.CBCentralManagerDelegateImpl = CBCentralManagerDelegateImpl; var AdvertismentData = /** @class */ (function () { function AdvertismentData(advData) { this.advData = advData; } Object.defineProperty(AdvertismentData.prototype, "manufacturerData", { get: function () { var data = this.advData.objectForKey(CBAdvertisementDataManufacturerDataKey); if (data && data.length > 2) { return toArrayBuffer(data.subdataWithRange(NSMakeRange(2, data.length - 2))); } return undefined; }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "data", { get: function () { return toArrayBuffer(this.advData); }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "manufacturerId", { get: function () { var data = this.advData.objectForKey(CBAdvertisementDataManufacturerDataKey); if (data && data.length >= 2) { var manufacturerIdBuffer = toArrayBuffer(data.subdataWithRange(NSMakeRange(0, 2))); return new DataView(manufacturerIdBuffer, 0).getUint16(0, true); } return -1; }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "txPowerLevel", { get: function () { return this.advData.objectForKey(CBAdvertisementDataTxPowerLevelKey) || Number.MIN_VALUE; }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "localName", { get: function () { return this.advData.objectForKey(CBAdvertisementDataLocalNameKey); }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "flags", { get: function () { return -1; }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "serviceUUIDs", { get: function () { var result = []; var serviceUuids = this.advData.objectForKey(CBAdvertisementDataServiceUUIDsKey); if (serviceUuids) { for (var i = 0; i < serviceUuids.count; i++) { result.push(serviceUuids[i].toString()); } } return result; }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "overtflow", { get: function () { var result = []; var serviceUuids = this.advData.objectForKey(CBAdvertisementDataOverflowServiceUUIDsKey); if (serviceUuids) { for (var i = 0; i < serviceUuids.count; i++) { result.push(CBUUIDToString(serviceUuids[i])); } } return result; }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "solicitedServices", { get: function () { var result = []; var serviceUuids = this.advData.objectForKey(CBAdvertisementDataSolicitedServiceUUIDsKey); if (serviceUuids) { for (var i = 0; i < serviceUuids.count; i++) { result.push(CBUUIDToString(serviceUuids[i])); } } return result; }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "connectable", { get: function () { return this.advData.objectForKey(CBAdvertisementDataIsConnectable); }, enumerable: true, configurable: true }); Object.defineProperty(AdvertismentData.prototype, "serviceData", { get: function () { var result = {}; var obj = this.advData.objectForKey(CBAdvertisementDataServiceDataKey); if (obj) { obj.enumerateKeysAndObjectsUsingBlock(function (key, data) { result[CBUUIDToString(key)] = toArrayBuffer(data); }); } return result; }, enumerable: true, configurable: true }); return AdvertismentData; }()); exports.AdvertismentData = AdvertismentData; var _bluetoothInstance; function getBluetoothInstance() { if (!_bluetoothInstance) { _bluetoothInstance = new Bluetooth(); } return _bluetoothInstance; } exports.getBluetoothInstance = getBluetoothInstance; function toArrayBuffer(value) { return value ? interop.bufferFromData(value) : null; } exports.toArrayBuffer = toArrayBuffer; function _getProperties(characteristic) { var props = characteristic.properties; return { // broadcast: (props & CBCharacteristicPropertyBroadcast) === CBCharacteristicPropertyBroadcast, broadcast: (props & 1 /* PropertyBroadcast */) === 1 /* PropertyBroadcast */, read: (props & 2 /* PropertyRead */) === 2 /* PropertyRead */, broadcast2: (props & 1 /* PropertyBroadcast */) === 1 /* PropertyBroadcast */, read2: (props & 2 /* PropertyRead */) === 2 /* PropertyRead */, write: (props & 8 /* PropertyWrite */) === 8 /* PropertyWrite */, writeWithoutResponse: (props & 4 /* PropertyWriteWithoutResponse */) === 4 /* PropertyWriteWithoutResponse */, notify: (props & 16 /* PropertyNotify */) === 16 /* PropertyNotify */, indicate: (props & 32 /* PropertyIndicate */) === 32 /* PropertyIndicate */, authenticatedSignedWrites: (props & 64 /* PropertyAuthenticatedSignedWrites */) === 64 /* PropertyAuthenticatedSignedWrites */, extendedProperties: (props & 128 /* PropertyExtendedProperties */) === 128 /* PropertyExtendedProperties */, notifyEncryptionRequired: (props & 256 /* PropertyNotifyEncryptionRequired */) === 256 /* PropertyNotifyEncryptionRequired */, indicateEncryptionRequired: (props & 512 /* PropertyIndicateEncryptionRequired */) === 512 /* PropertyIndicateEncryptionRequired */, }; } function NSUUIDToString(uuid) { return uuid.toString().toLowerCase(); } exports.NSUUIDToString = NSUUIDToString; function CBUUIDToString(uuid) { return uuid.UUIDString.toLowerCase(); } exports.CBUUIDToString = CBUUIDToString; var Bluetooth = /** @class */ (function (_super) { __extends(Bluetooth, _super); function Bluetooth(restoreIdentifier, showPowerAlertPopup) { if (restoreIdentifier === void 0) { restoreIdentifier = 'ns_bluetooth'; } if (showPowerAlertPopup === void 0) { showPowerAlertPopup = false; } var _this = _super.call(this) || this; _this.restoreIdentifier = restoreIdentifier; _this.showPowerAlertPopup = showPowerAlertPopup; _this._centralDelegate = null; _this._centralManager = null; _this._discoverPeripherals = {}; _this._connectedPeripherals = {}; _this._connectCallbacks = {}; _this._disconnectCallbacks = {}; // _advData is used to store Advertisment Data so that we can send it to connection callback _this._advData = {}; _this._onDiscovered = null; // needed for consecutive calls to isBluetoothEnabled. Until readyToAskForEnabled, everyone waits! _this.readyToAskForEnabled = false; console.log("*** iOS Bluetooth Constructor *** " + restoreIdentifier); return _this; } Bluetooth.prototype.clear = function () { // doing nothing on ios }; Object.defineProperty(Bluetooth.prototype, "state", { get: function () { return this._state; }, set: function (state) { if (this._state !== state) { this._state = state; this.sendEvent(bluetooth_common_1.BluetoothCommon.bluetooth_status_event, { state: state === 2 /* Unsupported */ ? 'unsupported' : state === 5 /* PoweredOn */ ? 'on' : 'off', }); } }, enumerable: true, configurable: true }); Object.defineProperty(Bluetooth.prototype, "centralDelegate", { get: function () { if (!this._centralDelegate) { this._centralDelegate = CBCentralManagerDelegateImpl.new().initWithOwner(new WeakRef(this)); } return this._centralDelegate; }, enumerable: true, configurable: true }); Object.defineProperty(Bluetooth.prototype, "centralManager", { get: function () { var _this = this; if (!this._centralManager) { var options = new NSMutableDictionary([this.showPowerAlertPopup], [CBCentralManagerOptionShowPowerAlertKey]); if (this.restoreIdentifier) { options.setObjectForKey(this.restoreIdentifier, CBCentralManagerOptionRestoreIdentifierKey); } this._centralManager = CBCentralManager.alloc().initWithDelegateQueueOptions(this.centralDelegate, null, options); setTimeout(function () { _this.state = _this._centralManager.state; }, 100); bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, "this._centralManager: " + this._centralManager); } return this._centralManager; }, enumerable: true, configurable: true }); Bluetooth.prototype.onListenerAdded = function (eventName, count) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, 'onListenerAdded', eventName, count); if (eventName === Bluetooth.bluetooth_status_event) { // ensure centralManager is set var result = this.centralManager; } }; Bluetooth.prototype._getState = function (state) { if (state === 1 /* Connecting */) { return 'connecting'; } else if (state === 2 /* Connected */) { return 'connected'; } else if (state === 0 /* Disconnected */) { return 'disconnected'; } else { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.warning, '_getState ---- Unexpected state, returning "disconnected" for state of', state); return 'disconnected'; } }; Bluetooth.prototype.prepareConnectedPeripheralDelegate = function (peripheral) { if (!peripheral.delegate) { var UUID = NSUUIDToString(peripheral.identifier); var delegate = CBPeripheralDelegateImpl.new().initWithOwner(new WeakRef(this)); CFRetain(delegate); peripheral.delegate = delegate; } }; Bluetooth.prototype.onPeripheralDisconnected = function (peripheral) { var UUID = NSUUIDToString(peripheral.identifier); var cb = this._disconnectCallbacks[UUID]; if (cb) { cb({ UUID: UUID, name: peripheral.name, }); delete this._disconnectCallbacks[UUID]; } this.sendEvent(Bluetooth.device_disconnected_event, { UUID: UUID, name: peripheral.name, }); if (peripheral.delegate) { CFRelease(peripheral.delegate); peripheral.delegate = null; } delete this._connectedPeripherals[UUID]; }; Bluetooth.prototype.onPeripheralConnected = function (peripheral) { var UUID = NSUUIDToString(peripheral.identifier); this.prepareConnectedPeripheralDelegate(peripheral); this._connectedPeripherals[UUID] = peripheral; }; Bluetooth.prototype.isBluetoothEnabled = function () { var _this = this; var methodName = 'isBluetoothEnabled'; // CLog(CLogTypes.info, 'isBluetoothEnabled', !!this._centralManager); return Promise.resolve() .then(function () { if (!_this.readyToAskForEnabled) { // the centralManager return wrong state just after initialization // so create it and wait a bit // eslint-disable-next-line no-unused-expressions _this.centralManager; bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, methodName, 'waiting a bit'); return new Promise(function (resolve) { return setTimeout(resolve, 500); }).then(function () { return (_this.readyToAskForEnabled = true); }); } return null; }) .then(function () { return _this._isEnabled(); }); }; Bluetooth.prototype.startScanning = function (args) { var _this = this; var methodName = 'startScanning'; return new Promise(function (resolve, reject) { try { _this._discoverPeripherals = {}; _this._onDiscovered = args.onDiscovered; var services_1 = null; if (args.filters) { services_1 = []; args.filters.forEach(function (f) { if (f.serviceUUID) { services_1.push(CBUUID.UUIDWithString(f.serviceUUID)); } }); } bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, methodName, '---- services:', services_1); // TODO: check on the services as any casting _this.centralManager.scanForPeripheralsWithServicesOptions(services_1, null); if (_this.scanningReferTimer) { clearTimeout(_this.scanningReferTimer.timer); _this.scanningReferTimer.resolve(); } _this.scanningReferTimer = {}; if (args.seconds) { _this.scanningReferTimer.timer = setTimeout(function () { // note that by now a manual 'stop' may have been invoked, but that doesn't hurt _this.centralManager.stopScan(); resolve(); }, args.seconds * 1000); _this.scanningReferTimer.resolve = resolve; } else { resolve(); } } catch (ex) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.error, methodName, '---- error:', ex); reject(new bluetooth_common_1.BluetoothError(ex.message, { stack: ex.stack, nativeException: ex.nativeException, method: methodName, arguments: args, })); } }); }; Bluetooth.prototype.enable = function () { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, 'enable ---- Not possible on iOS'); return this.isBluetoothEnabled(); }; Bluetooth.prototype.openBluetoothSettings = function (url) { return Promise.reject(new bluetooth_common_1.BluetoothError(bluetooth_common_1.BluetoothCommon.msg_cant_open_settings)); // return this.isBluetoothEnabled().then(isEnabled => { // if (!isEnabled) { // return Promise.resolve().then(() => { // const settingsUrl = NSURL.URLWithString(url || UIApplicationOpenSettingsURLString); // if (UIApplication.sharedApplication.canOpenURL(settingsUrl)) { // UIApplication.sharedApplication.openURLOptionsCompletionHandler(settingsUrl, null, function(success) { // // we get the callback for opening the URL, not enabling the bluetooth! // if (success) { // return Promise.reject(undefined); // } else { // return Promise.reject(BluetoothCommon.msg_cant_open_settings); // } // }); // } // }); // } // return null; // }); }; Bluetooth.prototype.stopScanning = function () { var _this = this; var methodName = 'stopScanning'; return new Promise(function (resolve, reject) { try { _this.centralManager.stopScan(); if (_this.scanningReferTimer) { _this.scanningReferTimer.resolve && _this.scanningReferTimer.resolve(); clearTimeout(_this.scanningReferTimer.timer); _this.scanningReferTimer = null; } resolve(); } catch (ex) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.error, methodName, '---- error:', ex); reject(new bluetooth_common_1.BluetoothError(ex.message, { stack: ex.stack, nativeException: ex.nativeException, method: methodName, })); } }); }; Bluetooth.prototype.clearAdvertismentCache = function () { this._advData = {}; }; Bluetooth.prototype.connect = function (args) { var _this = this; var methodName = 'connect'; try { if (!args.UUID) { return Promise.reject(new bluetooth_common_1.BluetoothError(bluetooth_common_1.BluetoothCommon.msg_missing_parameter, { method: methodName, type: bluetooth_common_1.BluetoothCommon.UUIDKey, arguments: args, })); } var connectingUUID_1 = args.UUID; bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, methodName, '----', args.UUID); var peripheral_1 = this.findDiscoverPeripheral(args.UUID); bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, methodName, '---- peripheral found', peripheral_1); if (!peripheral_1) { return Promise.reject(new bluetooth_common_1.BluetoothError(bluetooth_common_1.BluetoothCommon.msg_no_peripheral, { method: methodName, arguments: args, })); } else { return new Promise(function (resolve, reject) { var subD = { centralManagerDidConnectPeripheral: function (central, peripheral) { var UUID = NSUUIDToString(peripheral.identifier); if (UUID === connectingUUID_1) { resolve(); _this._centralDelegate.removeSubDelegate(subD); } }, centralManagerDidFailToConnectPeripheralError: function (central, peripheral, error) { var UUID = NSUUIDToString(peripheral.identifier); if (UUID === connectingUUID_1) { reject(new bluetooth_common_1.BluetoothError(error.localizedDescription, { method: methodName, status: error.code, })); _this._centralDelegate.removeSubDelegate(subD); } }, }; bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, methodName, '---- Connecting to peripheral with UUID:', connectingUUID_1, _this._centralDelegate, _this._centralManager); _this.centralDelegate.addSubDelegate(subD); _this._connectCallbacks[connectingUUID_1] = args.onConnected; _this._disconnectCallbacks[connectingUUID_1] = args.onDisconnected; bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, methodName, '----about to connect:', connectingUUID_1, _this._centralDelegate, _this._centralManager); _this.centralManager.connectPeripheralOptions(peripheral_1, null); }) .then(function () { if (args.autoDiscoverAll !== false) { return _this.discoverAll({ peripheralUUID: connectingUUID_1 }); } return undefined; }) .then(function (result) { var _a, _b, _c; var adv = _this._advData[connectingUUID_1]; var dataToSend = { UUID: connectingUUID_1, name: peripheral_1.name, state: _this._getState(peripheral_1.state), services: (_a = result) === null || _a === void 0 ? void 0 : _a.services, localName: (_b = adv) === null || _b === void 0 ? void 0 : _b.localName, manufacturerId: (_c = adv) === null || _c === void 0 ? void 0 : _c.manufacturerId, advertismentData: adv, }; // delete this._advData[connectingUUID]; var cb = _this._connectCallbacks[connectingUUID_1]; if (cb) { cb(dataToSend); delete _this._connectCallbacks[connectingUUID_1]; } _this.sendEvent(Bluetooth.device_connected_event, dataToSend); return dataToSend; }); } } catch (ex) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.error, methodName, '---- error:', ex); return Promise.reject(new bluetooth_common_1.BluetoothError(ex.message, { stack: ex.stack, nativeException: ex.nativeException, method: methodName, arguments: args, })); } }; Bluetooth.prototype.disconnect = function (args) { var _this = this; var methodName = 'disconnect'; try { if (!args.UUID) { return Promise.reject(new bluetooth_common_1.BluetoothError(bluetooth_common_1.BluetoothCommon.msg_missing_parameter, { method: methodName, type: bluetooth_common_1.BluetoothCommon.UUIDKey, arguments: args, })); } var pUUID_1 = args.UUID; var peripheral_2 = this.findPeripheral(pUUID_1); if (!peripheral_2) { return Promise.reject(new bluetooth_common_1.BluetoothError(bluetooth_common_1.BluetoothCommon.msg_no_peripheral, { method: methodName, arguments: args, })); } else { // no need to send an error when already disconnected, but it's wise to check it if (peripheral_2.state !== 0 /* Disconnected */) { return new Promise(function (resolve, reject) { var subD = { centralManagerDidDisconnectPeripheralError: function (central, peripheral, error) { var UUID = NSUUIDToString(peripheral.identifier); if (UUID === pUUID_1) { if (error) { reject(new bluetooth_common_1.BluetoothError(error.localizedDescription, { method: methodName, status: error.code, })); } else { resolve(); } _this._centralDelegate.removeSubDelegate(subD); } }, }; _this.centralDelegate.addSubDelegate(subD); bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.info, methodName, '---- Disconnecting peripheral with UUID', pUUID_1); _this.centralManager.cancelPeripheralConnection(peripheral_2); }); } return Promise.resolve(); } } catch (ex) { bluetooth_common_1.CLog(bluetooth_common_1.CLogTypes.error, methodName, '---- error:', ex); return Promise.reject(new bluetooth_common_1.BluetoothError(ex.message, { stack: ex.stack, nativeException: ex.nativeException, method: methodName, arguments: args, })); } }; Bluetooth.prototype.isConnected = function (args) { var methodName = 'isConnected'; try { if (!args.UUID) { return Promise.reject(new bluetooth_common_1.BluetoothError(bluetooth_common_1.BluetoothCommon.msg_missing_parameter, { method: methodName, type: bluetooth_common_1.BluetoothCommon.UUIDKey, arguments: args, })); } var peripheral = this.findPeripheral(args.UUID); if (peripheral === null) { return Promise.reject(new bluetooth_common_1.BluetoothError(bluetooth_common_1.BluetoothCommon.msg_no_peri