nativescript-bluetooth
Version:
Connect to and interact with Bluetooth LE peripherals
975 lines • 79.3 kB
JavaScript
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