2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 var T = xwalk.utils.type;
18 var Converter = xwalk.utils.converter;
19 var AV = xwalk.utils.validator;
20 var Privilege = xwalk.utils.privilege;
21 var privUtils_ = xwalk.utils;
22 var native = new xwalk.utils.NativeManager(extension);
24 var AbortError = new WebAPIException('AbortError', 'An unknown error occurred');
26 // class BluetoothClassDeviceMajor /////////////////////////////////////////
27 var BluetoothClassDeviceMajor = function() {
28 Object.defineProperties(this, {
29 MISC: { value: 0x00, writable: false, enumerable: true },
30 COMPUTER: { value: 0x01, writable: false, enumerable: true },
31 PHONE: { value: 0x02, writable: false, enumerable: true },
32 NETWORK: { value: 0x03, writable: false, enumerable: true },
33 AUDIO_VIDEO: { value: 0x04, writable: false, enumerable: true },
34 PERIPHERAL: { value: 0x05, writable: false, enumerable: true },
35 IMAGING: { value: 0x06, writable: false, enumerable: true },
36 WEARABLE: { value: 0x07, writable: false, enumerable: true },
37 TOY: { value: 0x08, writable: false, enumerable: true },
38 HEALTH: { value: 0x09, writable: false, enumerable: true },
39 UNCATEGORIZED: { value: 0x1f, writable: false, enumerable: true }
43 // class BluetoothClassDeviceMinor /////////////////////////////////////////
44 var BluetoothClassDeviceMinor = function() {
45 Object.defineProperties(this, {
46 COMPUTER_UNCATEGORIZED: { value: 0x00, writable: false, enumerable: true },
47 COMPUTER_DESKTOP: { value: 0x01, writable: false, enumerable: true },
48 COMPUTER_SERVER: { value: 0x02, writable: false, enumerable: true },
49 COMPUTER_LAPTOP: { value: 0x03, writable: false, enumerable: true },
50 COMPUTER_HANDHELD_PC_OR_PDA: { value: 0x04, writable: false, enumerable: true },
51 COMPUTER_PALM_PC_OR_PDA: { value: 0x05, writable: false, enumerable: true },
52 COMPUTER_WEARABLE: { value: 0x06, writable: false, enumerable: true },
54 PHONE_UNCATEGORIZED: { value: 0x00, writable: false, enumerable: true },
55 PHONE_CELLULAR: { value: 0x01, writable: false, enumerable: true },
56 PHONE_CORDLESS: { value: 0x02, writable: false, enumerable: true },
57 PHONE_SMARTPHONE: { value: 0x03, writable: false, enumerable: true },
58 PHONE_MODEM_OR_GATEWAY: { value: 0x04, writable: false, enumerable: true },
59 PHONE_ISDN: { value: 0x05, writable: false, enumerable: true },
61 AV_UNRECOGNIZED: { value: 0x00, writable: false, enumerable: true },
62 AV_WEARABLE_HEADSET: { value: 0x01, writable: false, enumerable: true },
63 AV_HANDSFREE: { value: 0x02, writable: false, enumerable: true },
64 AV_MICROPHONE: { value: 0x04, writable: false, enumerable: true },
65 AV_LOUDSPEAKER: { value: 0x05, writable: false, enumerable: true },
66 AV_HEADPHONES: { value: 0x06, writable: false, enumerable: true },
67 AV_PORTABLE_AUDIO: { value: 0x07, writable: false, enumerable: true },
68 AV_CAR_AUDIO: { value: 0x08, writable: false, enumerable: true },
69 AV_SETTOP_BOX: { value: 0x09, writable: false, enumerable: true },
70 AV_HIFI: { value: 0x0a, writable: false, enumerable: true },
71 AV_VCR: { value: 0x0b, writable: false, enumerable: true },
72 AV_VIDEO_CAMERA: { value: 0x0c, writable: false, enumerable: true },
73 AV_CAMCORDER: { value: 0x0d, writable: false, enumerable: true },
74 AV_MONITOR: { value: 0x0e, writable: false, enumerable: true },
75 AV_DISPLAY_AND_LOUDSPEAKER: { value: 0x0f, writable: false, enumerable: true },
76 AV_VIDEO_CONFERENCING: { value: 0x10, writable: false, enumerable: true },
77 AV_GAMING_TOY: { value: 0x12, writable: false, enumerable: true },
79 PERIPHERAL_UNCATEGORIZED: { value: 0x00, writable: false, enumerable: true },
80 PERIPHERAL_KEYBOARD: { value: 0x10, writable: false, enumerable: true },
81 PERIPHERAL_POINTING_DEVICE: { value: 0x20, writable: false, enumerable: true },
82 PERIPHERAL_KEYBOARD_AND_POINTING_DEVICE: {
87 PERIPHERAL_JOYSTICK: { value: 0x01, writable: false, enumerable: true },
88 PERIPHERAL_GAMEPAD: { value: 0x02, writable: false, enumerable: true },
89 PERIPHERAL_REMOTE_CONTROL: { value: 0x03, writable: false, enumerable: true },
90 PERIPHERAL_SENSING_DEVICE: { value: 0x04, writable: false, enumerable: true },
91 PERIPHERAL_DEGITIZER_TABLET: { value: 0x05, writable: false, enumerable: true },
92 PERIPHERAL_CARD_READER: { value: 0x06, writable: false, enumerable: true },
93 PERIPHERAL_DIGITAL_PEN: { value: 0x07, writable: false, enumerable: true },
94 PERIPHERAL_HANDHELD_SCANNER: { value: 0x08, writable: false, enumerable: true },
95 PERIPHERAL_HANDHELD_INPUT_DEVICE: {
101 IMAGING_UNCATEGORIZED: { value: 0x00, writable: false, enumerable: true },
102 IMAGING_DISPLAY: { value: 0x04, writable: false, enumerable: true },
103 IMAGING_CAMERA: { value: 0x08, writable: false, enumerable: true },
104 IMAGING_SCANNER: { value: 0x10, writable: false, enumerable: true },
105 IMAGING_PRINTER: { value: 0x20, writable: false, enumerable: true },
107 WEARABLE_WRITST_WATCH: { value: 0x01, writable: false, enumerable: true },
108 WEARABLE_PAGER: { value: 0x02, writable: false, enumerable: true },
109 WEARABLE_JACKET: { value: 0x03, writable: false, enumerable: true },
110 WEARABLE_HELMET: { value: 0x04, writable: false, enumerable: true },
111 WEARABLE_GLASSES: { value: 0x05, writable: false, enumerable: true },
113 TOY_ROBOT: { value: 0x01, writable: false, enumerable: true },
114 TOY_VEHICLE: { value: 0x02, writable: false, enumerable: true },
115 TOY_DOLL: { value: 0x03, writable: false, enumerable: true },
116 TOY_CONTROLLER: { value: 0x04, writable: false, enumerable: true },
117 TOY_GAME: { value: 0x05, writable: false, enumerable: true },
119 HEALTH_UNDEFINED: { value: 0x00, writable: false, enumerable: true },
120 HEALTH_BLOOD_PRESSURE_MONITOR: { value: 0x01, writable: false, enumerable: true },
121 HEALTH_THERMOMETER: { value: 0x02, writable: false, enumerable: true },
122 HEALTH_WEIGHING_SCALE: { value: 0x03, writable: false, enumerable: true },
123 HEALTH_GLUCOSE_METER: { value: 0x04, writable: false, enumerable: true },
124 HEALTH_PULSE_OXIMETER: { value: 0x05, writable: false, enumerable: true },
125 HEALTH_PULSE_RATE_MONITOR: { value: 0x06, writable: false, enumerable: true },
126 HEALTH_DATA_DISPLAY: { value: 0x07, writable: false, enumerable: true },
127 HEALTH_STEP_COUNTER: { value: 0x08, writable: false, enumerable: true },
128 HEALTH_BODY_COMPOSITION_ANALYZER: {
133 HEALTH_PEAK_FLOW_MONITOR: { value: 0x0a, writable: false, enumerable: true },
134 HEALTH_MEDICATION_MONITOR: { value: 0x0b, writable: false, enumerable: true },
135 HEALTH_KNEE_PROSTHESIS: { value: 0x0c, writable: false, enumerable: true },
136 HEALTH_ANKLE_PROSTHESIS: { value: 0x0d, writable: false, enumerable: true }
140 // class BluetoothClassDeviceService ///////////////////////////////////////
141 var BluetoothClassDeviceService = function() {
142 Object.defineProperties(this, {
143 LIMITED_DISCOVERABILITY: { value: 0x0001, writable: false, enumerable: true },
144 POSITIONING: { value: 0x0008, writable: false, enumerable: true },
145 NETWORKING: { value: 0x0010, writable: false, enumerable: true },
146 RENDERING: { value: 0x0020, writable: false, enumerable: true },
147 CAPTURING: { value: 0x0040, writable: false, enumerable: true },
148 OBJECT_TRANSFER: { value: 0x0080, writable: false, enumerable: true },
149 AUDIO: { value: 0x0100, writable: false, enumerable: true },
150 TELEPHONY: { value: 0x0200, writable: false, enumerable: true },
151 INFORMATION: { value: 0x0400, writable: false, enumerable: true }
155 //class tizen.BluetoothLEServiceData ///////////////////////////
156 tizen.BluetoothLEServiceData = function(d) {
157 AV.isConstructorCall(this, tizen.BluetoothLEServiceData);
161 Object.defineProperties(this, {
168 uuid_ = Converter.toString(v);
178 data_ = BluetoothManager_toDOMString(v);
180 data_ = Converter.toString(v);
186 if (arguments.length >= 2) {
187 // public constructor
188 this.uuid = arguments[0];
189 this.data = arguments[1];
190 } else if (d && T.isObject(d)) {
191 // internal constructor
200 //class BluetoothLEAdvertiseData ///////////////////////////
201 tizen.BluetoothLEAdvertiseData = function(dict) {
202 AV.isConstructorCall(this, tizen.BluetoothLEAdvertiseData);
203 var includeName_ = false;
205 var solicitationuuids_ = null;
206 var appearance_ = null;
207 var includeTxPowerLevel_ = false;
208 var serviceData_ = null;
209 var servicesData_ = null;
210 var manufacturerData_ = null;
212 Object.defineProperties(this, {
219 includeName_ = Converter.toBoolean(v, true);
230 } else if (T.isArray(v)) {
231 for (var i = 0; i < v.length; ++i) {
232 if (!T.isString(v[i])) {
233 v[i] = Converter.toString(v[i]);
243 return solicitationuuids_;
247 solicitationuuids_ = v;
248 } else if (T.isArray(v)) {
249 for (var i = 0; i < v.length; ++i) {
250 if (!T.isString(v[i])) {
251 v[i] = Converter.toString(v[i]);
254 solicitationuuids_ = v;
264 appearance_ = Converter.toUnsignedLong(v, true);
267 includeTxPowerLevel: {
270 return includeTxPowerLevel_;
273 includeTxPowerLevel_ = Converter.toBoolean(v, true);
282 if (T.isNull(v) || v instanceof tizen.BluetoothLEServiceData) {
290 return servicesData_;
295 } else if (T.isArray(v)) {
297 for (var i = 0; i < v.length; ++i) {
298 if (v[i] instanceof tizen.BluetoothLEServiceData) {
302 servicesData_ = tmpArray;
309 return manufacturerData_;
312 if (T.isNull(v) || v instanceof tizen.BluetoothLEManufacturerData) {
313 manufacturerData_ = v;
319 if (T.isObject(dict)) {
323 if (T.isNull(dict.includeName) || T.isBoolean(dict.includeName)) {
324 o.includeName = dict.includeName;
325 } else if (!T.isUndefined(dict.includeName)) {
330 if (T.isNull(dict.uuids)) {
331 o.uuids = dict.uuids;
332 } else if (T.isArray(dict.uuids)) {
333 for (var i = 0; i < dict.uuids.length; ++i) {
334 if (!T.isString(dict.uuids[i])) {
338 o.uuids = dict.uuids;
339 } else if (!T.isUndefined(dict.uuids)) {
344 if (T.isNull(dict.solicitationuuids)) {
345 o.solicitationuuids = dict.solicitationuuids;
346 } else if (T.isArray(dict.solicitationuuids)) {
347 for (var i = 0; i < dict.solicitationuuids.length; ++i) {
348 if (!T.isString(dict.solicitationuuids[i])) {
352 o.solicitationuuids = dict.solicitationuuids;
353 } else if (!T.isUndefined(dict.solicitationuuids)) {
358 if (T.isNull(dict.appearance) || T.isNumber(dict.appearance)) {
359 o.appearance = dict.appearance;
360 } else if (!T.isUndefined(dict.appearance)) {
364 // includeTxPowerLevel
365 if (T.isNull(dict.includeTxPowerLevel) || T.isBoolean(dict.includeTxPowerLevel)) {
366 o.includeTxPowerLevel = dict.includeTxPowerLevel;
367 } else if (!T.isUndefined(dict.includeTxPowerLevel)) {
373 T.isNull(dict.serviceData) ||
374 dict.serviceData instanceof tizen.BluetoothLEServiceData
376 o.serviceData = dict.serviceData;
377 } else if (!T.isUndefined(dict.serviceData)) {
382 if (T.isNull(dict.servicesData) || T.isArray(dict.servicesData)) {
383 // additional validation is done in setter of BluetoothLEAdvertiseData.servicesData
384 o.servicesData = dict.servicesData;
389 T.isNull(dict.manufacturerData) ||
390 dict.manufacturerData instanceof tizen.BluetoothLEManufacturerData
392 o.manufacturerData = dict.manufacturerData;
393 } else if (!T.isUndefined(dict.manufacturerData)) {
397 for (var prop in o) {
398 if (o.hasOwnProperty(prop) && this.hasOwnProperty(prop)) {
399 this[prop] = o[prop];
405 //class tizen.BluetoothLEManufacturerData ///////////////////////////
406 tizen.BluetoothLEManufacturerData = function(d) {
407 AV.isConstructorCall(this, tizen.BluetoothLEManufacturerData);
411 Object.defineProperties(this, {
418 id_ = Converter.toString(v);
428 data_ = BluetoothManager_toDOMString(v);
430 data_ = Converter.toString(v);
436 if (arguments.length >= 2) {
437 // public constructor
438 this.id = arguments[0];
439 this.data = arguments[1];
440 } else if (d && T.isObject(d)) {
441 // internal constructor
450 // class BluetoothClass ///////////////////////////
451 var BluetoothClass = function(data) {
454 services = data.services;
457 Object.defineProperties(this, {
458 major: { value: data.major, writable: false, enumerable: true },
459 minor: { value: data.minor, writable: false, enumerable: true },
464 return services.slice();
470 var BluetoothClass_hasService = function() {
471 privUtils_.log('Entered BluetoothClass.hasService()');
472 privUtils_.checkPrivilegeAccess4Ver(
475 Privilege.BLUETOOTH_GAP
478 var args = AV.validateArgs(arguments, [
481 type: AV.Types.UNSIGNED_LONG
485 var size = this.services.length;
486 for (var i = 0; i < size; i++) {
487 if (this.services[i] === args.service) {
494 BluetoothClass.prototype.hasService = function() {
495 return BluetoothClass_hasService.apply(this, arguments);
498 // class BluetoothSocket ///////////////////////////
499 var _BLUETOOTH_SOCKET_STATE_CLOSED = 'CLOSED';
501 function BluetoothSocketListeners() {
503 this.socketCallback = function(data) {
505 var socket = that.sockets[event.id];
508 if ('onclose' === event.event) {
510 that.removeListener(event.id);
512 Object.defineProperty(socket, 'state', {
513 value: _BLUETOOTH_SOCKET_STATE_CLOSED
517 var callback = socket[event.event];
518 if (T.isFunction(callback)) {
522 privUtils_.log('Received event for an unknown socket: ' + event.id);
527 BluetoothSocketListeners.prototype.sockets = {};
529 BluetoothSocketListeners.prototype.addListener = function(socket) {
530 if (T.isEmptyObject(this.sockets)) {
531 native.addListener('BLUETOOTH_SOCKET_STATE_CHANGED', this.socketCallback);
534 this.sockets[socket._id] = socket;
537 BluetoothSocketListeners.prototype.removeListener = function(id) {
538 delete this.sockets[id];
540 if (T.isEmptyObject(this.sockets)) {
541 native.removeListener('BLUETOOTH_SOCKET_STATE_CHANGED', this.socketCallback);
545 var _bluetoothSocketListeners = new BluetoothSocketListeners();
547 var BluetoothSocket = function(data) {
548 Object.defineProperties(this, {
549 uuid: { value: data.uuid, writable: false, enumerable: true },
557 value: new BluetoothDevice(data.peer),
561 onmessage: { value: null, writable: true, enumerable: true },
562 onclose: { value: null, writable: true, enumerable: true },
563 _id: { value: data.id, writable: false, enumerable: false }
566 _bluetoothSocketListeners.addListener(this);
569 BluetoothSocket.prototype.writeData = function(data) {
570 privUtils_.log('Entered BluetoothSocket.writeData()');
572 var byteData = BluetoothManager_toByteArray(data);
579 var result = native.callSync('BluetoothSocketWriteData', callArgs);
581 if (native.isFailure(result)) {
582 throw native.getErrorObject(result);
584 return native.getResultObject(result);
588 BluetoothSocket.prototype.readData = function() {
589 privUtils_.log('Entered BluetoothSocket.readData()');
595 var result = native.callSync('BluetoothSocketReadData', callArgs);
597 if (native.isFailure(result)) {
598 throw native.getErrorObject(result);
600 return native.getResultObject(result);
604 BluetoothSocket.prototype.close = function() {
605 privUtils_.log('Entered BluetoothSocket.close()');
607 if (_BLUETOOTH_SOCKET_STATE_CLOSED !== this.state) {
612 var result = native.callSync('BluetoothSocketClose', callArgs);
614 if (native.isFailure(result)) {
615 throw native.getErrorObject(result);
619 Object.defineProperty(this, 'state', { value: _BLUETOOTH_SOCKET_STATE_CLOSED });
623 //class BluetoothLEDevice ///////////////////////////
624 var BluetoothLEDevice = function(data) {
630 solicitationuuids = null,
632 manufacturerData = null,
636 address = data.address;
637 name = data.name || null;
638 txpowerlevel = data.txpowerlevel || null;
639 appearance = data.appearance || null;
640 uuids = data.uuids || null;
641 solicitationuuids = data.solicitationuuids || null;
642 if (data.serviceData) {
644 data.serviceData.forEach(function(d) {
645 serviceData.push(new tizen.BluetoothLEServiceData(d));
648 if (data.manufacturerData) {
649 manufacturerData = new tizen.BluetoothLEManufacturerData(
650 data.manufacturerData
658 Object.defineProperties(this, {
659 address: { value: address, writable: false, enumerable: true },
660 name: { value: name, writable: false, enumerable: true },
661 txpowerlevel: { value: txpowerlevel, writable: false, enumerable: true },
662 appearance: { value: appearance, writable: false, enumerable: true },
667 var service_uuids = uuids ? uuids.slice() : null;
668 return service_uuids;
675 return solicitationuuids ? solicitationuuids.slice() : null;
682 return serviceData ? serviceData.slice() : null;
686 value: manufacturerData,
690 rssi: { value: rssi, writable: false, enumerable: true }
694 BluetoothLEDevice.prototype.connect = function() {
695 privUtils_.log('Entered BluetoothLEDevice.connect()');
696 var args = AV.validateArgs(arguments, [
698 name: 'successCallback',
699 type: AV.Types.FUNCTION,
704 name: 'errorCallback',
705 type: AV.Types.FUNCTION,
711 var callback = function(result) {
712 if (native.isFailure(result)) {
713 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
715 native.callIfPossible(args.successCallback);
718 // Errors are handled by error callback
719 var result = native.call(
720 'BluetoothLEDeviceConnect',
721 { address: this.address },
724 if (native.isFailure(result)) {
725 throw native.getErrorObject(result);
729 BluetoothLEDevice.prototype.disconnect = function() {
730 privUtils_.log('Entered BluetoothLEDevice.disconnect()');
731 var args = AV.validateArgs(arguments, [
733 name: 'successCallback',
734 type: AV.Types.FUNCTION,
739 name: 'errorCallback',
740 type: AV.Types.FUNCTION,
745 var callback = function(result) {
746 if (native.isFailure(result)) {
747 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
749 native.callIfPossible(args.successCallback);
753 var result = native.call(
754 'BluetoothLEDeviceDisconnect',
755 { address: this.address },
758 if (native.isFailure(result)) {
759 throw native.getErrorObject(result);
763 BluetoothLEDevice.prototype.getService = function() {
764 privUtils_.log('Entered BluetoothLEDevice.getService()');
765 var args = AV.validateArgs(arguments, [
768 type: AV.Types.STRING
774 address: this.address
777 var result = native.callSync('BluetoothLEDeviceGetService', callArgs);
778 if (native.isFailure(result)) {
779 throw native.getErrorObject(result);
781 return new BluetoothGATTService(native.getResultObject(result));
785 BluetoothLEDevice.prototype.getServiceAllUuids = function() {
786 privUtils_.log('Entered BluetoothLEDevice.getServiceAllUuids()');
789 address: this.address
792 var result = native.callSync('BluetoothLEDeviceGetServiceAllUuids', callArgs);
793 if (native.isFailure(result)) {
794 throw native.getErrorObject(result);
796 var uuids = native.getResultObject(result);
801 BluetoothLEDevice.prototype.isConnected = function() {
802 privUtils_.log('Entered BluetoothLEDevice.isConnected()');
805 address: this.address
808 var result = native.callSync('BluetoothLEDeviceIsConnected', callArgs);
809 if (native.isFailure(result)) {
810 throw native.getErrorObject(result);
812 return native.getResultObject(result);
815 BluetoothLEDevice.prototype.addConnectStateChangeListener = function() {
816 privUtils_.log('Entered BluetoothLEDevice.addConnectStateChangeListener()');
817 var args = AV.validateArgs(arguments, [
820 type: AV.Types.LISTENER,
821 values: ['onconnected', 'ondisconnected']
827 var func = function(event) {
828 if (event.address === that.address && args.listener[event.action]) {
829 args.listener[event.action](that);
833 var watchId = _bleConnectChangeListener.addListener(func);
838 BluetoothLEDevice.prototype.removeConnectStateChangeListener = function() {
839 privUtils_.log('Entered BluetoothLEDevice.removeConnectStateChangeListener()');
841 var args = AV.validateArgs(arguments, [
848 _bleConnectChangeListener.removeListener(args.watchID);
851 BluetoothLEDevice.prototype.getAttMtu = function() {
852 privUtils_.log('Entered BluetoothLEDevice.getAttMtu()');
855 address: this.address
858 var result = native.callSync('BluetoothLEDeviceGetAttMtu', callArgs);
859 if (native.isFailure(result)) {
860 throw native.getErrorObject(result);
862 return native.getResultObject(result);
865 BluetoothLEDevice.prototype.requestAttMtuChange = function() {
866 privUtils_.log('Entered BluetoothLEDevice.requestAttMtuChange()');
868 var args = AV.validateArgs(arguments, [
876 address: this.address,
880 var result = native.callSync('BluetoothLEDeviceRequestAttMtuChange', callArgs);
881 if (native.isFailure(result)) {
882 throw native.getErrorObject(result);
884 return native.getResultObject(result);
887 BluetoothLEDevice.prototype.addAttMtuChangeListener = function() {
888 privUtils_.log('Entered BluetoothLEDevice.addAttMtuChangeListener()');
889 var args = AV.validateArgs(arguments, [
892 type: AV.Types.FUNCTION
896 var callArgs = { address: this.address };
898 var callback = function(result) {
899 privUtils_.log('Entered BluetoothLEDevice.addAttMtuChangeListener() callback');
900 args.callback(result.attMtuValue);
903 var watchId = _bleAttMtuChangeListener.addListener(callback, callArgs);
908 BluetoothLEDevice.prototype.removeAttMtuChangeListener = function() {
909 privUtils_.log('Entered BluetoothLEDevice.removeAttMtuChangeListener()');
911 var args = AV.validateArgs(arguments, [
918 var callArgs = { address: this.address };
920 _bleAttMtuChangeListener.removeListener(args.watchID, callArgs);
923 // class BluetoothDevice ///////////////////////////
924 var BluetoothDevice = function(data) {
926 function _getter(field) {
929 callArgs.address = self.address;
930 callArgs.field = field;
932 var result = native.callSync('BluetoothDeviceGetBoolValue', callArgs);
934 if (native.isFailure(result)) {
937 return native.getResultObject(result);
941 function isBondedGetter() {
942 return _getter('isBonded');
945 function isTrustedGetter() {
946 return _getter('isTrusted');
949 function isConnectedGetter() {
950 return _getter('isConnected');
958 Object.defineProperties(this, {
959 name: { value: data.name, writable: false, enumerable: true },
960 address: { value: data.address, writable: false, enumerable: true },
962 value: new BluetoothClass(data.deviceClass),
979 get: isConnectedGetter
985 return uuids.slice();
991 BluetoothDevice.prototype.connectToServiceByUUID = function() {
992 privUtils_.log('Entered BluetoothDevice.connectToServiceByUUID()');
994 var args = AV.validateArgs(arguments, [
997 type: AV.Types.STRING
1000 name: 'successCallback',
1001 type: AV.Types.FUNCTION
1004 name: 'errorCallback',
1005 type: AV.Types.FUNCTION,
1012 address: this.address,
1015 var callback = function(result) {
1016 if (native.isFailure(result)) {
1017 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
1019 args.successCallback(new BluetoothSocket(native.getResultObject(result)));
1023 var result = native.call('BluetoothDeviceConnectToServiceByUUID', callArgs, callback);
1024 if (native.isFailure(result)) {
1025 throw native.getErrorObject(result);
1029 // class BluetoothServiceHandler ///////////////////////////
1030 function BluetoothServiceListeners() {
1032 this.serviceCallback = function(data) {
1034 var service = that.services[e.uuid];
1035 var result = new BluetoothSocket(e);
1038 privUtils_.log(service);
1039 service.onconnect(result);
1044 BluetoothServiceListeners.prototype.services = {};
1046 BluetoothServiceListeners.prototype.addListener = function(service) {
1047 if (T.isEmptyObject(this.services)) {
1048 native.addListener('BLUETOOTH_SERVICE_ONCONNECT', this.serviceCallback);
1051 this.services[service.uuid] = service;
1054 BluetoothServiceListeners.prototype.removeListener = function(uuid) {
1055 delete this.services[uuid];
1057 if (T.isEmptyObject(this.services)) {
1058 native.removeListener('BLUETOOTH_SERVICE_ONCONNECT', this.serviceCallback);
1062 var _bluetoothServiceListeners = new BluetoothServiceListeners();
1064 var BluetoothServiceHandler = function(data) {
1065 function isConnectedGetter() {
1070 var result = native.callSync('BluetoothAdapterIsServiceConnected', {
1074 if (native.isFailure(result)) {
1077 return native.getResultObject(result);
1081 Object.defineProperties(this, {
1082 uuid: { value: data.uuid, writable: false, enumerable: true },
1083 name: { value: data.name, writable: false, enumerable: true },
1087 get: isConnectedGetter
1089 onconnect: { value: null, writable: true, enumerable: true }
1092 _bluetoothServiceListeners.addListener(this);
1095 BluetoothServiceHandler.prototype.unregister = function() {
1096 privUtils_.log('Entered BluetoothServiceHandler.unregister()');
1097 var args = AV.validateArgs(arguments, [
1099 name: 'successCallback',
1100 type: AV.Types.FUNCTION,
1105 name: 'errorCallback',
1106 type: AV.Types.FUNCTION,
1116 var callback = function(result) {
1117 if (native.isFailure(result)) {
1118 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
1120 native.callIfPossible(args.successCallback);
1124 var result = native.call('BluetoothServiceHandlerUnregister', callArgs, callback);
1125 if (native.isFailure(result)) {
1126 throw native.getErrorObject(result);
1129 _bluetoothServiceListeners.removeListener(this.uuid);
1132 // class BluetoothHealthApplication ///////////////////////////
1133 function BluetoothHealthApplicationListeners() {
1135 this.appCallback = function(data) {
1137 var app = that.apps[event.id];
1140 var callback = app[event.event];
1141 if (T.isFunction(callback)) {
1143 switch (event.event) {
1145 param = new BluetoothHealthChannel(native.getResultObject(event));
1149 privUtils_.log('Unknown event: ' + event.event);
1155 privUtils_.log('Received event for an unknown application: ' + event.id);
1160 BluetoothHealthApplicationListeners.prototype.apps = {};
1162 BluetoothHealthApplicationListeners.prototype.addListener = function(app) {
1163 if (T.isEmptyObject(this.apps)) {
1164 native.addListener('BLUETOOTH_HEALTH_APPLICATION_CHANGED', this.appCallback);
1167 this.apps[app._id] = app;
1170 BluetoothHealthApplicationListeners.prototype.removeListener = function(id) {
1171 delete this.apps[id];
1173 if (T.isEmptyObject(this.apps)) {
1174 native.removeListener('BLUETOOTH_HEALTH_APPLICATION_CHANGED', this.appCallback);
1178 var _bluetoothHealthApplicationListeners = new BluetoothHealthApplicationListeners();
1180 var BluetoothHealthApplication = function(data) {
1181 Object.defineProperties(this, {
1182 dataType: { value: data.dataType, writable: false, enumerable: true },
1183 name: { value: data.name, writable: false, enumerable: true },
1184 onconnect: { value: null, writable: true, enumerable: true },
1185 _id: { value: data._id, writable: false, enumerable: false }
1188 _bluetoothHealthApplicationListeners.addListener(this);
1191 BluetoothHealthApplication.prototype.unregister = function() {
1192 privUtils_.log('Entered BluetoothHealthApplication.unregister()');
1193 privUtils_.printDeprecationWarningFor('BluetoothHealthApplication');
1194 var args = AV.validateArgs(arguments, [
1196 name: 'successCallback',
1197 type: AV.Types.FUNCTION,
1202 name: 'errorCallback',
1203 type: AV.Types.FUNCTION,
1209 var callArgs = { id: this._id };
1211 var callback = function(result) {
1212 if (native.isFailure(result)) {
1213 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
1215 native.callIfPossible(args.successCallback);
1219 var result = native.call('BluetoothHealthApplicationUnregister', callArgs, callback);
1220 if (native.isFailure(result)) {
1221 throw native.getErrorObject(result);
1224 _bluetoothHealthApplicationListeners.removeListener(this._id);
1227 // class BluetoothProfileHandler ///////////////////////////
1228 var _BluetoothProfileType = {
1232 var BluetoothProfileHandler = function(data) {
1234 var profileType = data.profileType;
1235 function profileTypeGetter() {
1236 privUtils_.printDeprecationWarningFor('profileType');
1239 Object.defineProperties(this, {
1240 profileType: { enumerable: true, set: function() {}, get: profileTypeGetter }
1245 // class BluetoothHealthProfileHandler ///////////////////////////
1246 var BluetoothHealthProfileHandler = function(data) {
1247 BluetoothProfileHandler.call(this, data);
1250 BluetoothHealthProfileHandler.prototype = new BluetoothProfileHandler();
1252 BluetoothHealthProfileHandler.prototype.constructor = BluetoothProfileHandler;
1254 BluetoothHealthProfileHandler.prototype.registerSinkApplication = function() {
1255 privUtils_.log('Entered BluetoothHealthProfileHandler.registerSinkApplication()');
1256 privUtils_.printDeprecationWarningFor('BluetoothHealthProfileHandler');
1258 var args = AV.validateArgs(arguments, [
1261 type: AV.Types.LONG // there's no short type
1265 type: AV.Types.STRING
1268 name: 'successCallback',
1269 type: AV.Types.FUNCTION
1272 name: 'errorCallback',
1273 type: AV.Types.FUNCTION,
1280 dataType: args.dataType,
1284 var callback = function(result) {
1285 if (native.isFailure(result)) {
1286 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
1288 args.successCallback(
1289 new BluetoothHealthApplication(native.getResultObject(result))
1294 var result = native.call(
1295 'BluetoothHealthProfileHandlerRegisterSinkApp',
1299 if (native.isFailure(result)) {
1300 throw native.getErrorObject(result);
1304 BluetoothHealthProfileHandler.prototype.connectToSource = function() {
1305 privUtils_.log('Entered BluetoothHealthProfileHandler.connectToSource()');
1306 privUtils_.printDeprecationWarningFor('BluetoothHealthProfileHandler');
1308 var args = AV.validateArgs(arguments, [
1311 type: AV.Types.PLATFORM_OBJECT,
1312 values: BluetoothDevice
1315 name: 'application',
1316 type: AV.Types.PLATFORM_OBJECT,
1317 values: BluetoothHealthApplication
1320 name: 'successCallback',
1321 type: AV.Types.FUNCTION
1324 name: 'errorCallback',
1325 type: AV.Types.FUNCTION,
1332 address: args.peer.address,
1333 appId: args.application._id
1336 var callback = function(result) {
1337 if (native.isFailure(result)) {
1338 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
1340 var channel = native.getResultObject(result);
1341 channel.peer = args.peer;
1342 channel.appId = args.application._id;
1343 args.successCallback(new BluetoothHealthChannel(channel));
1347 var result = native.call(
1348 'BluetoothHealthProfileHandlerConnectToSource',
1352 if (native.isFailure(result)) {
1353 throw native.getErrorObject(result);
1357 // class BluetoothHealthChannel ///////////////////////////
1358 var BluetoothHealthChannel = function(data) {
1359 Object.defineProperties(this, {
1360 peer: { value: data.peer, writable: false, enumerable: true },
1361 channelType: { value: data.channelType, writable: false, enumerable: true },
1363 value: _bluetoothHealthApplicationListeners.apps[data.appId],
1368 value: data.isConnected,
1373 _id: { value: data._id, writable: false, enumerable: false }
1377 BluetoothHealthChannel.prototype.close = function() {
1378 privUtils_.log('Entered BluetoothHealthChannel.close()');
1379 privUtils_.printDeprecationWarningFor('BluetoothHealthChannel');
1381 if (this.isConnected) {
1384 address: this.peer.address
1387 var result = native.callSync('BluetoothHealthChannelClose', callArgs);
1389 if (native.isFailure(result)) {
1390 throw native.getErrorObject(result);
1393 Object.defineProperty(this, 'isConnected', { value: false });
1397 BluetoothHealthChannel.prototype.sendData = function() {
1398 privUtils_.log('Entered BluetoothHealthChannel.sendData()');
1399 privUtils_.printDeprecationWarningFor('BluetoothHealthChannel');
1401 var args = AV.validateArgs(arguments, [
1404 type: AV.Types.ARRAY,
1405 values: AV.Types.BYTE
1414 var result = native.callSync('BluetoothHealthChannelSendData', callArgs);
1416 if (native.isFailure(result)) {
1417 throw native.getErrorObject(result);
1419 return native.getResultObject(result);
1423 var _healthListeners = {};
1425 function _BluetoothHealthChannelChangeCallback(event) {
1427 var callback = _healthListeners[e.id];
1439 privUtils_.log('Unknown mode: ' + e.event);
1443 if (callback[e.event]) {
1444 callback[e.event](d);
1448 var BluetoothHealthChannel_setListener = function() {
1449 privUtils_.log('Entered BluetoothHealthChannel.setListener()');
1450 privUtils_.printDeprecationWarningFor('BluetoothHealthChannel');
1451 privUtils_.checkPrivilegeAccess4Ver(
1453 Privilege.BLUETOOTH,
1454 Privilege.BLUETOOTH_HEALTH
1456 var args = AV.validateArgs(arguments, [
1458 name: 'changeCallback',
1459 type: AV.Types.LISTENER,
1460 values: ['onmessage', 'onclose']
1464 if (T.isEmptyObject(_healthListeners)) {
1466 'BluetoothHealthChannelChangeCallback',
1467 _BluetoothHealthChannelChangeCallback
1470 _healthListeners[this._id] = args.changeCallback;
1473 BluetoothHealthChannel.prototype.setListener = function() {
1474 BluetoothHealthChannel_setListener.apply(this, arguments);
1477 var BluetoothHealthChannel_unsetListener = function() {
1478 privUtils_.log('Entered BluetoothHealthChannel.unsetListener ()');
1479 privUtils_.printDeprecationWarningFor('BluetoothHealthChannel');
1480 if (T.isEmptyObject(_healthListeners)) {
1481 privUtils_.checkPrivilegeAccess4Ver(
1483 Privilege.BLUETOOTH,
1484 Privilege.BLUETOOTH_HEALTH
1488 delete _healthListeners[this._id];
1490 if (T.isEmptyObject(_healthListeners)) {
1491 native.removeListener(
1492 'BluetoothHealthChannelChangeCallback',
1493 _BluetoothHealthChannelChangeCallback
1498 BluetoothHealthChannel.prototype.unsetListener = function() {
1499 privUtils_.printDeprecationWarningFor('BluetoothHealthChannel');
1500 BluetoothHealthChannel_unsetListener.apply(this, arguments);
1504 * Creates a manager for specified listener event.
1506 * @param {string} name - name of the listener this manager handles
1507 * @param {function} callback - function to be invoked when event specified by the name
1509 * This function should return false if the callback
1510 * doesn't want to handle the event anymore, true otherwise.
1511 * This function should have following signature:
1512 * bool callback(event, successCallback, errorCallback);
1514 * @return {object} object which allows to add or remove callbacks for specified listener
1516 function _singleListenerBuilder(name, callback) {
1517 var listenerName = name;
1518 var successCallback;
1520 var callbackFunction = callback;
1521 var listenerRegistered = false;
1523 function innerCallback(event) {
1524 if (!callbackFunction(event, successCallback, errorCallback)) {
1529 function addListener(s, e) {
1530 successCallback = s;
1533 if (!listenerRegistered) {
1534 native.addListener(listenerName, innerCallback);
1535 listenerRegistered = true;
1539 function removeListener() {
1540 if (listenerRegistered) {
1541 native.removeListener(listenerName, innerCallback);
1542 listenerRegistered = false;
1545 successCallback = undefined;
1546 errorCallback = undefined;
1550 addListener: addListener,
1551 removeListener: removeListener
1555 var _bleScanListener = _singleListenerBuilder('BluetoothLEScanCallback', function(
1563 switch (event.action) {
1565 d = new BluetoothLEDevice(event.data);
1569 if (errorCallback) {
1570 errorCallback(native.getErrorObject(event));
1575 privUtils_.log('Unknown mode: ' + event.action);
1578 if (successCallback) {
1585 var _bleAdvertiseListener = _singleListenerBuilder(
1586 'BluetoothLEAdvertiseCallback',
1587 function(event, successCallback, errorCallback) {
1591 switch (event.action) {
1593 if (successCallback) {
1594 successCallback(native.getResultObject(event));
1595 if (native.getResultObject(event) == 'STOPPED') {
1596 _bleAdvertiseListener.removeListener();
1602 if (errorCallback) {
1603 errorCallback(native.getErrorObject(event));
1608 privUtils_.log('Unknown mode: ' + event.action);
1614 //class BluetoothLEAdapter ///////////////////////////
1615 var BluetoothLEAdapter = function() {};
1617 BluetoothLEAdapter.prototype.startScan = function() {
1618 privUtils_.log('Entered BluetoothLEAdapter.startScan()');
1619 var args = AV.validateArgs(arguments, [
1621 name: 'successCallback',
1622 type: AV.Types.FUNCTION
1625 name: 'errorCallback',
1626 type: AV.Types.FUNCTION,
1632 var result = native.callSync('BluetoothLEAdapterStartScan', {});
1633 if (native.isFailure(result)) {
1634 throw native.getErrorObject(result);
1637 _bleScanListener.addListener(args.successCallback, args.errorCallback);
1640 BluetoothLEAdapter.prototype.stopScan = function() {
1641 privUtils_.log('Entered BluetoothLEAdapter.stopScan()');
1643 _bleScanListener.removeListener();
1645 var result = native.callSync('BluetoothLEAdapterStopScan', {});
1646 if (native.isFailure(result)) {
1647 throw native.getErrorObject(result);
1651 BluetoothLEAdapter.prototype.isScanning = function() {
1652 privUtils_.log('Entered BluetoothLEAdapter.isScanning()');
1654 var result = native.callSync('BluetoothLEAdapterIsScanning', {});
1655 if (native.isFailure(result)) {
1656 throw native.getErrorObject(result);
1658 return native.getResultObject(result);
1661 var _BluetoothAdvertisePacketType = {
1662 ADVERTISE: 'ADVERTISE',
1663 SCAN_RESPONSE: 'SCAN_RESPONSE'
1666 var _BluetoothAdvertisingMode = {
1667 BALANCED: 'BALANCED',
1668 LOW_LATENCY: 'LOW_LATENCY',
1669 LOW_ENERGY: 'LOW_ENERGY'
1672 BluetoothLEAdapter.prototype.startAdvertise = function() {
1673 privUtils_.log('Entered BluetoothLEAdapter.startAdvertise()');
1674 var args = AV.validateArgs(arguments, [
1676 name: 'advertiseData',
1677 type: AV.Types.PLATFORM_OBJECT,
1678 values: tizen.BluetoothLEAdvertiseData
1682 type: AV.Types.ENUM,
1683 values: T.getValues(_BluetoothAdvertisePacketType)
1686 name: 'successCallback',
1687 type: AV.Types.FUNCTION
1690 name: 'errorCallback',
1691 type: AV.Types.FUNCTION,
1697 type: AV.Types.ENUM,
1698 values: T.getValues(_BluetoothAdvertisingMode),
1703 name: 'connectable',
1704 type: AV.Types.BOOLEAN,
1711 advertiseData: args.advertiseData,
1712 packetType: args.packetType,
1713 mode: T.isNullOrUndefined(args.mode)
1714 ? _BluetoothAdvertisingMode.BALANCED
1716 connectable: T.isNullOrUndefined(args.connectable) ? true : args.connectable
1719 var result = native.callSync('BluetoothLEAdapterStartAdvertise', callArgs);
1721 if (native.isFailure(result)) {
1722 throw native.getErrorObject(result);
1725 _bleAdvertiseListener.addListener(args.successCallback, args.errorCallback);
1728 BluetoothLEAdapter.prototype.stopAdvertise = function() {
1729 privUtils_.log('Entered BluetoothLEAdapter.stopAdvertise()');
1731 var result = native.callSync('BluetoothLEAdapterStopAdvertise', {});
1733 if (native.isFailure(result)) {
1734 throw native.getErrorObject(result);
1738 BluetoothLEAdapter.prototype.addConnectStateChangeListener = function() {
1739 privUtils_.log('Entered BluetoothLEAdapter.addClientConnectStateChaneListener()');
1740 var args = AV.validateArgs(arguments, [
1743 type: AV.Types.LISTENER,
1744 values: ['onconnected', 'ondisconnected']
1748 var func = function(event) {
1749 if (args.listener[event.action]) {
1750 args.listener[event.action](new BluetoothLEDevice(event.address));
1754 return _bleConnectChangeListener.addListener(func);
1757 BluetoothLEAdapter.prototype.removeConnectStateChangeListener = function() {
1758 privUtils_.log('Entered BluetoothLEAdapter.removeConnectStateChangeListener()');
1760 var args = AV.validateArgs(arguments, [
1767 _bleConnectChangeListener.removeListener(args.watchID);
1770 //class BluetoothGATTService ///////////////////////////
1771 var BluetoothGATTService = function(data, address) {
1772 var handle_ = data.handle;
1773 var uuid_ = data.uuid;
1774 var serviceUuid_ = data.serviceUuid;
1775 //address_ is needed to control if device is still connected
1776 var address_ = address || data.address;
1778 function servicesGetter() {
1780 var result = native.callSync('BluetoothGATTClientServiceGetServices', {
1784 if (native.isSuccess(result)) {
1785 var resultObject = native.getResultObject(result);
1786 resultObject.forEach(function(s) {
1787 services.push(new BluetoothGATTService(s, address_));
1792 function characteristicsGetter() {
1793 var characteristics = [];
1794 var result = native.callSync('BluetoothGATTClientServiceGetCharacteristics', {
1799 if (native.isSuccess(result)) {
1800 var resultObject = native.getResultObject(result);
1801 resultObject.forEach(function(c) {
1802 if (!T.isNullOrUndefined(c)) {
1803 characteristics.push(new BluetoothGATTCharacteristic(c, address_));
1807 return characteristics;
1811 * If this function is called as a constructor of BluetoothGATTServerService's
1812 * base class, some properties have to be left configurable, to enable redefinition.
1813 * Otherwise, if this function is called to create BluetoothGATTService,
1814 * they are left non-configurable.
1816 * If BluetoothGATTService will be a base for any other class in the future,
1817 * the line below may have to be updated to take into account the new class.
1819 var isConfigurable = this instanceof BluetoothGATTServerService;
1821 Object.defineProperties(this, {
1822 uuid: { value: uuid_, writable: false, enumerable: true },
1823 serviceUuid: { value: serviceUuid_, writable: false, enumerable: true },
1826 configurable: isConfigurable,
1832 configurable: isConfigurable,
1834 get: characteristicsGetter
1839 var CurrentGATTServerEntityId = 0;
1840 function NextGattServerEntityID() {
1841 return ++CurrentGATTServerEntityId;
1844 function IsUuidValid(uuid) {
1846 BluetoothManager_UUIDIsValid16Bit(uuid) ||
1847 BluetoothManager_UUIDIsValid32Bit(uuid) ||
1848 BluetoothManager_UUIDIsValid128Bit(uuid)
1852 var ValidateBluetoothGATTServerServiceInit = function(initData) {
1853 initData = AV.validateArgs(
1855 initData['serviceUuid'],
1856 initData['isPrimary'] || true,
1857 initData['includedServices'] || [],
1858 initData['characteristics'] || []
1862 name: 'serviceUuid',
1863 type: AV.Types.STRING,
1864 validator: IsUuidValid
1868 type: AV.Types.BOOLEAN
1871 name: 'includedServices',
1872 type: AV.Types.ARRAY
1875 name: 'characteristics',
1876 type: AV.Types.ARRAY
1881 // "uuid" field is used to construct BluetoothGATTService, but it's not a part
1882 // of BluetoothGATTServerServiceInit dictionary.
1883 // In case of BluetoothGATTServerServices, its value is always the same as
1885 initData.uuid = initData.serviceUuid;
1889 //class BluetoothGATTServerService ///////////////////////////
1890 var BluetoothGATTServerService = function(data) {
1891 data = ValidateBluetoothGATTServerServiceInit(data);
1893 BluetoothGATTService.call(this, data, null);
1895 var services_ = data.includedServices.map(function(serviceData) {
1896 return new BluetoothGATTServerService(serviceData, null);
1898 var characteristics_ = data.characteristics.map(function(characteristicData) {
1899 return new BluetoothGATTServerCharacteristic(characteristicData, null);
1902 Object.defineProperties(this, {
1903 isPrimary: { value: data.isPrimary, writable: false, enumerable: true },
1907 return services_.slice();
1914 return characteristics_.slice();
1918 // This property is "private" and meant not to be used by users
1920 // It has to be enumerable, to be serialized with JSON.stringify()
1922 value: NextGattServerEntityID()
1927 BluetoothGATTServerService.prototype = Object.create(BluetoothGATTService.prototype);
1929 Object.defineProperty(BluetoothGATTServerService.prototype, 'constructor', {
1930 value: BluetoothGATTServerService,
1935 function _getIncludedServicesAndItsComponentsIdsRecursively(service) {
1938 for (var serviceIndex = 0; serviceIndex < service.services.length; ++serviceIndex) {
1939 ids.push(service.services[serviceIndex]._id);
1941 _getIncludedServicesAndItsComponentsIdsRecursively(
1942 service.services[serviceIndex]
1948 var characteristicIndex = 0;
1949 characteristicIndex < service.characteristics.length;
1950 ++characteristicIndex
1952 ids.push(service.characteristics[characteristicIndex]._id);
1955 var descriptorIndex = 0;
1957 service.characteristics[characteristicIndex].descriptors.length;
1961 service.characteristics[characteristicIndex].descriptors[descriptorIndex]
1970 var BluetoothGATTServer_valid_unregisterService_errors = [
1971 'InvalidStateError',
1974 var BluetoothGATTServer_valid_unregisterService_exceptions = [
1975 'TypeMismatchError',
1979 BluetoothGATTServerService.prototype.unregister = function() {
1980 var args = AV.validateArgs(arguments, [
1982 name: 'successCallback',
1983 type: AV.Types.FUNCTION,
1988 name: 'errorCallback',
1989 type: AV.Types.FUNCTION,
1995 var serviceIndex = _BluetoothGATTServerServices.findIndex(
1997 return service._id === this._id;
2001 if (serviceIndex === -1) {
2002 throw new WebAPIException(
2004 'The service is not registered in the local GATT server or is included in another service'
2008 function removeFromJSArrayAndCallSuccessCb() {
2009 _BluetoothGATTServerServices.splice(serviceIndex, 1);
2010 native.callIfPossible(args.successCallback);
2013 if (!_BluetoothGATTServerServicesRegisteredInNativeLayer[this._id]) {
2014 removeFromJSArrayAndCallSuccessCb();
2018 var callback = function(result) {
2019 if (native.isFailure(result)) {
2020 native.callIfPossible(
2022 native.getErrorObjectAndValidate(
2024 BluetoothGATTServer_valid_unregisterService_errors,
2029 delete _BluetoothGATTServerServicesRegisteredInNativeLayer[this._id];
2030 removeFromJSArrayAndCallSuccessCb();
2036 idsToRemoveFromNativeLayer: _getIncludedServicesAndItsComponentsIdsRecursively(
2040 var result = native.call('BluetoothGATTServerUnregisterService', callArgs, callback);
2042 if (native.isFailure(result)) {
2043 throw native.getErrorObjectAndValidate(
2045 BluetoothGATTServer_valid_unregisterService_errors,
2051 var numberArrayToByteArray = function(array) {
2054 array.forEach(function(b) {
2055 d.push(Converter.toOctet(b));
2060 //class BluetoothGATTCharacteristic ///////////////////////////
2061 var BluetoothGATTCharacteristic = function(data, address) {
2062 if (!T.isObject(data)) {
2065 var address_ = address;
2066 var handle_ = data.handle;
2067 var descriptors_ = data.descriptors.map(function(descriptor_data) {
2068 return new BluetoothGATTDescriptor(descriptor_data, address_);
2070 var isBroadcast_ = data.isBroadcast;
2071 var hasExtendedProperties_ = data.hasExtendedProperties;
2072 var isNotify_ = data.isNotify;
2073 var isIndication_ = data.isIndication;
2074 var isReadable_ = data.isReadable;
2075 var isSignedWrite_ = data.isSignedWrite;
2076 var isWritable_ = data.isWritable;
2077 var isWriteNoResponse_ = data.isWriteNoResponse;
2078 var uuid_ = data.uuid;
2081 * If this function is called as a constructor of BluetoothGATTServerCharacteristic's
2082 * base class, some properties have to be left configurable, to enable redefinition.
2083 * Otherwise, if this function is called to create BluetoothGATTCharacteristic,
2084 * they are left non-configurable.
2086 * If BluetoothGATTCharacteristic will be a base for any other class in the future,
2087 * the line below may have to be updated to take into account the new class.
2089 var isConfigurable = this instanceof BluetoothGATTServerCharacteristic;
2091 Object.defineProperties(this, {
2094 configurable: isConfigurable,
2096 return descriptors_.slice();
2103 return isBroadcast_;
2107 hasExtendedProperties: {
2110 return hasExtendedProperties_;
2124 return isIndication_;
2138 return isSignedWrite_;
2149 isWriteNoResponse: {
2152 return isWriteNoResponse_;
2165 this.readValue = function() {
2166 privUtils_.log('Entered BluetoothGATTCharacteristic.readValue()');
2167 var args = AV.validateArgs(arguments, [
2169 name: 'successCallback',
2170 type: AV.Types.FUNCTION
2173 name: 'errorCallback',
2174 type: AV.Types.FUNCTION,
2180 var callback = function(result) {
2181 if (native.isFailure(result)) {
2182 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
2184 var d = numberArrayToByteArray(native.getResultObject(result));
2185 args.successCallback(d);
2189 var callArgs = { handle: handle_, address: address_ };
2191 var result = native.call(
2192 'BluetoothGATTClientServiceReadValue',
2197 if (native.isFailure(result)) {
2198 throw native.getErrorObject(result);
2202 this.writeValue = function(value, successCallback, errorCallback) {
2203 privUtils_.log('Entered BluetoothGATTCharacteristic.writeValue()');
2204 var args = AV.validateArgs(Array.prototype.slice.call(arguments, 1), [
2206 name: 'successCallback',
2207 type: AV.Types.FUNCTION,
2212 name: 'errorCallback',
2213 type: AV.Types.FUNCTION,
2219 var callback = function(result) {
2220 if (native.isFailure(result)) {
2221 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
2223 native.callIfPossible(args.successCallback);
2229 value: BluetoothManager_toByteArray(value),
2233 var result = native.call(
2234 'BluetoothGATTClientServiceWriteValue',
2239 if (native.isFailure(result)) {
2240 throw native.getErrorObject(result);
2244 var addValueChangeListener = function() {
2245 privUtils_.log('Entered BluetoothGATTCharacteristic.addValueChangeListener()');
2246 privUtils_.checkPrivilegeAccess4Ver(
2248 Privilege.BLUETOOTH,
2249 Privilege.BLUETOOTH_ADMIN
2251 var args = AV.validateArgs(arguments, [
2254 type: AV.Types.FUNCTION
2258 var callArgs = { handle: handle_, address: address_ };
2260 var callback = function(event) {
2261 if (event.handle === handle_) {
2262 args.callback(numberArrayToByteArray(native.getResultObject(event)));
2266 return _bluetoothGATTCharacteristicListener.addListener(callback, callArgs);
2269 this.addValueChangeListener = function() {
2270 return addValueChangeListener.apply(this, arguments);
2273 this.removeValueChangeListener = function() {
2274 privUtils_.log('Entered BluetoothGATTCharacteristic.removeValueChangeListener()');
2276 var args = AV.validateArgs(arguments, [
2283 var callArgs = { handle: handle_, address: address_ };
2285 return _bluetoothGATTCharacteristicListener.removeListener(
2292 var ValidateBluetoothGATTServerCharacteristicInit = function(initData) {
2293 return AV.validateArgs(
2296 initData['descriptors'] || [],
2297 initData['isBroadcast'] || false,
2298 initData['hasExtendedProperties'] || false,
2299 initData['isNotify'] || false,
2300 initData['isIndication'] || false,
2301 initData['isReadable'] || false,
2302 initData['isSignedWrite'] || false,
2303 initData['isWritable'] || false,
2304 initData['isWriteNoResponse'] || false,
2305 initData['readPermission'] || false,
2306 initData['writePermission'] || false,
2307 initData['encryptedReadPermission'] || false,
2308 initData['encryptedWritePermission'] || false,
2309 initData['encryptedSignedReadPermission'] || false,
2310 initData['encryptedSignedWritePermission'] || false,
2311 initData['readValueRequestCallback'] || null,
2312 initData['writeValueRequestCallback'] || null
2317 type: AV.Types.STRING,
2318 validator: IsUuidValid
2321 name: 'descriptors',
2322 type: AV.Types.ARRAY
2325 name: 'isBroadcast',
2326 type: AV.Types.BOOLEAN
2329 name: 'hasExtendedProperties',
2330 type: AV.Types.BOOLEAN
2334 type: AV.Types.BOOLEAN
2337 name: 'isIndication',
2338 type: AV.Types.BOOLEAN
2342 type: AV.Types.BOOLEAN
2345 name: 'isSignedWrite',
2346 type: AV.Types.BOOLEAN
2350 type: AV.Types.BOOLEAN
2353 name: 'isWriteNoResponse',
2354 type: AV.Types.BOOLEAN
2357 name: 'readPermission',
2358 type: AV.Types.BOOLEAN
2361 name: 'writePermission',
2362 type: AV.Types.BOOLEAN
2365 name: 'encryptedReadPermission',
2366 type: AV.Types.BOOLEAN
2369 name: 'encryptedWritePermission',
2370 type: AV.Types.BOOLEAN
2373 name: 'encryptedSignedReadPermission',
2374 type: AV.Types.BOOLEAN
2377 name: 'encryptedSignedWritePermission',
2378 type: AV.Types.BOOLEAN
2381 name: 'readValueRequestCallback',
2382 type: AV.Types.FUNCTION,
2386 name: 'writeValueRequestCallback',
2387 type: AV.Types.FUNCTION,
2394 //class BluetoothGATTServerCharacteristic ///////////////////////////
2395 var BluetoothGATTServerCharacteristic = function(data) {
2396 data = ValidateBluetoothGATTServerCharacteristicInit(data);
2398 BluetoothGATTCharacteristic.call(this, data, null);
2400 var descriptors_ = data.descriptors.map(function(descriptor_data) {
2401 return new BluetoothGATTServerDescriptor(descriptor_data, null);
2404 Object.defineProperties(this, {
2408 return descriptors_.slice();
2415 return data.readPermission;
2422 return data.writePermission;
2426 encryptedReadPermission: {
2429 return data.encryptedReadPermission;
2433 encryptedWritePermission: {
2436 return data.encryptedWritePermission;
2440 encryptedSignedReadPermission: {
2443 return data.encryptedSignedReadPermission;
2447 encryptedSignedWritePermission: {
2450 return data.encryptedSignedWritePermission;
2454 // This property is "private" and meant not to be used by users
2456 // It has to be enumerable, to be serialized with JSON.stringify()
2458 value: NextGattServerEntityID()
2462 this.readValue = function() {
2463 throw new WebAPIException(
2464 'NotSupportedError',
2465 'This method cannot be called on BluetoothGATTServerCharacteristic'
2469 this.writeValue = function() {
2470 throw new WebAPIException(
2471 'NotSupportedError',
2472 'This method cannot be called on BluetoothGATTServerCharacteristic'
2476 this.addValueChangeListener = function() {
2477 throw new WebAPIException(
2478 'NotSupportedError',
2479 'This method cannot be called on BluetoothGATTServerCharacteristic'
2483 this.removeValueChangeListener = function() {
2484 /* Intended no operation */
2487 this.notifyAboutValueChange = function(
2493 var args = AV.validateArgs(
2494 Array.prototype.slice.call(arguments, 1),
2497 name: 'clientAddress',
2498 type: AV.Types.STRING,
2503 name: 'notificationCB',
2504 type: AV.Types.LISTENER,
2506 'onnotificationsuccess',
2507 'onnotificationfail',
2508 'onnotificationfinish'
2515 type: AV.Types.FUNCTION,
2523 value: BluetoothManager_toByteArray(value),
2524 client: args.clientAddress || null,
2526 notifyId: _BluetoothGATTServerCharacteristicNotifyId++
2529 var callback = function(result) {
2530 if (native.isFailure(result)) {
2531 native.callIfPossible(args.errorCB, native.getErrorObject(result));
2535 var result = native.call(
2536 'BluetoothGATTServerCharacteristicNotifyAboutValueChange',
2541 if (native.isFailure(result)) {
2542 throw native.getErrorObject(result);
2546 'BluetoothGATTServerCharacteristicNotifyCallback_' + callArgs.notifyId,
2547 _BluetoothGATTServerCharacteristicNotifyCallback
2550 _BluetoothGATTServerCharacteristicNotifyListeners[callArgs.notifyId] =
2551 args.notificationCB;
2555 BluetoothGATTServerCharacteristic.prototype = Object.create(
2556 BluetoothGATTCharacteristic.prototype
2559 Object.defineProperty(BluetoothGATTServerCharacteristic.prototype, 'constructor', {
2560 value: BluetoothGATTServerCharacteristic,
2565 tizen.GATTRequestReply = function(statusCode, data) {
2566 AV.isConstructorCall(this, tizen.GATTRequestReply);
2568 var statusCode_ = Converter.toLong(statusCode);
2569 var data_ = T.isNullOrUndefined(data) ? null : BluetoothManager_toByteArray(data);
2571 Object.defineProperties(this, {
2578 statusCode_ = Converter.toLong(v);
2587 data_ = T.isNullOrUndefined(v) ? null : numberArrayToByteArray(v);
2593 function _createReadValueRequestCallback(
2595 sendResponseSuccessCallback,
2596 sendResponseErrorCallback
2598 return _singleListenerBuilder(
2599 'ReadValueRequestCallback_' + _id,
2601 * _singleListenerBuilder requires 2 callbacks, the second of which
2602 * is an error callback.
2603 * Read value request events coming from the native layer
2605 * Hence, we don't use the second callback here.
2607 function(event, readValueRequestCallback, unusedErrorCallback) {
2608 var clientAddress = event.clientAddress;
2609 var offset = event.offset;
2611 if (readValueRequestCallback) {
2612 var requestReply = readValueRequestCallback(clientAddress, offset);
2615 requestId: event.requestId,
2616 requestType: event.requestType,
2618 statusCode: requestReply.statusCode,
2619 data: requestReply.data
2621 var callback = function(result) {
2622 if (native.isFailure(result)) {
2623 native.callIfPossible(
2624 sendResponseErrorCallback,
2625 native.getErrorObject(result)
2628 native.callIfPossible(sendResponseSuccessCallback);
2631 var result = native.call(
2632 'BluetoothGATTServerSendResponse',
2642 function _createWriteValueRequestCallback(
2644 sendResponseSuccessCallback,
2645 sendResponseErrorCallback
2647 return _singleListenerBuilder(
2648 'WriteValueRequestCallback_' + _id,
2650 * _singleListenerBuilder requires 2 callbacks, the second of which
2651 * is an error callback.
2652 * Write value request events coming from the native layer
2654 * Hence, we don't use the second callback here.
2656 function(event, writeValueRequestCallback, unusedErrorCallback) {
2657 var clientAddress = event.clientAddress;
2658 var value = event.value;
2659 var offset = event.offset;
2660 var replyRequired = event.replyRequired;
2662 if (writeValueRequestCallback) {
2663 var requestReply = writeValueRequestCallback(
2665 BluetoothManager_toByteArray(value),
2671 requestId: event.requestId,
2672 requestType: event.requestType,
2673 value: null, // Responses to write requests don't contain value
2675 statusCode: requestReply.statusCode,
2676 data: requestReply.data
2678 var callback = function(result) {
2679 if (native.isFailure(result)) {
2680 native.callIfPossible(
2681 sendResponseErrorCallback,
2682 native.getErrorObject(result)
2685 native.callIfPossible(sendResponseSuccessCallback);
2688 var result = native.call(
2689 'BluetoothGATTServerSendResponse',
2699 var _BluetoothGATTServerReadWriteValueRequestCallbacks = {};
2701 var _setReadValueRequestCallbackCommon = function() {
2702 var args = AV.validateArgs(arguments, [
2704 name: 'readValueRequestCallback',
2705 type: AV.Types.FUNCTION
2708 name: 'successCallback',
2709 type: AV.Types.FUNCTION,
2714 name: 'errorCallback',
2715 type: AV.Types.FUNCTION,
2720 name: 'sendResponseSuccessCallback',
2721 type: AV.Types.FUNCTION,
2726 name: 'sendResponseErrorCallback',
2727 type: AV.Types.FUNCTION,
2733 var entityId = this._id;
2735 var callback = function(result) {
2736 if (native.isFailure(result)) {
2737 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
2739 var readValueRequestCallback = _createReadValueRequestCallback(
2741 args.sendResponseSuccessCallback,
2742 args.sendResponseErrorCallback
2744 readValueRequestCallback.addListener(
2745 args.readValueRequestCallback,
2746 function unusedErrorCallback() {
2747 /* Intentionally no operation */
2750 _BluetoothGATTServerReadWriteValueRequestCallbacks[
2751 'ReadValueCallback' + entityId
2752 ] = readValueRequestCallback;
2753 native.callIfPossible(args.successCallback, native.getErrorObject(result));
2757 var callArgs = { _id: this._id };
2758 var result = native.call(
2759 'BluetoothGATTServerSetReadValueRequestCallback',
2764 if (native.isFailure(result)) {
2765 throw native.getErrorObject(result);
2769 var _setWriteValueRequestCallbackCommon = function() {
2770 var args = AV.validateArgs(arguments, [
2772 name: 'writeValueRequestCallback',
2773 type: AV.Types.FUNCTION
2776 name: 'successCallback',
2777 type: AV.Types.FUNCTION,
2782 name: 'errorCallback',
2783 type: AV.Types.FUNCTION,
2788 name: 'sendResponseSuccessCallback',
2789 type: AV.Types.FUNCTION,
2794 name: 'sendResponseErrorCallback',
2795 type: AV.Types.FUNCTION,
2801 var entityId = this._id;
2803 var callback = function(result) {
2804 if (native.isFailure(result)) {
2805 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
2807 var writeValueRequestCallback = _createWriteValueRequestCallback(
2809 args.sendResponseSuccessCallback,
2810 args.sendResponseErrorCallback
2812 writeValueRequestCallback.addListener(
2813 args.writeValueRequestCallback,
2814 function unusedErrorCallback() {
2815 /* Intentionally no operation */
2818 _BluetoothGATTServerReadWriteValueRequestCallbacks[
2819 'WriteValueCallback' + entityId
2820 ] = writeValueRequestCallback;
2821 native.callIfPossible(args.successCallback, native.getErrorObject(result));
2825 var callArgs = { _id: this._id };
2826 var result = native.call(
2827 'BluetoothGATTServerSetWriteValueRequestCallback',
2832 if (native.isFailure(result)) {
2833 throw native.getErrorObject(result);
2837 BluetoothGATTServerCharacteristic.prototype.setReadValueRequestCallback = _setReadValueRequestCallbackCommon;
2838 BluetoothGATTServerCharacteristic.prototype.setWriteValueRequestCallback = _setWriteValueRequestCallbackCommon;
2840 var _BluetoothGATTServerCharacteristicNotifyId = 0;
2841 var _BluetoothGATTServerCharacteristicNotifyListeners = {};
2842 var _BluetoothGATTServerCharacteristicNotifyCallback = function(event) {
2843 privUtils_.log('Got notification about characteristic\'s value change');
2845 T.isNullOrUndefined(
2846 _BluetoothGATTServerCharacteristicNotifyListeners[event.notifyId]
2849 privUtils_.log('Notification callback is not set, skipping');
2853 var callback = _BluetoothGATTServerCharacteristicNotifyListeners[event.notifyId];
2855 if (event.type === 'onnotificationsuccess') {
2856 native.callIfPossible(callback.onnotificationsuccess, event.clientAddress);
2860 if (event.type === 'onnotificationfail') {
2861 native.callIfPossible(
2862 callback.onnotificationfail,
2863 event.clientAddress,
2864 native.getErrorObject(event)
2869 if (event.type === 'onnotificationfinish') {
2870 native.callIfPossible(callback.onnotificationfinish, event.clientAddress);
2873 native.removeListener(
2874 'BluetoothGATTServerCharacteristicNotifyCallback_' + event.notifyId
2879 * Creates a manager for specified listener event. Manager handles multiple
2880 * registered listeners
2882 * @param {string} name - name of the listener this manager handles
2883 * @param {function} callback - function to be invoked when event specified by the name
2885 * This function should have following signature:
2886 * void callback(listener, event);
2887 * @param {string} addListenerId - optional parameter. If specified, this native
2888 * method will be called synchronously when
2889 * listener is added.
2890 * @param {string} removeListenerId - optional parameter. If specified, this native
2891 * method will be called synchronously when
2892 * listener is removed.
2893 * @param {bool} repeatNativeCall - optional parameter. If specified, the addListenerId
2894 * and removeListenerId methods will be called
2895 * synchronously each time listener is added/removed.
2896 * Otherwise they are going to be called just once: when
2897 * first listener is added and last listener is removed.
2899 * @return {object} object which allows to add or remove callbacks for specified listener
2901 function _multipleListenerBuilder(
2908 var listenerName = name;
2909 var addId = addListenerId;
2910 var removeId = removeListenerId;
2911 var callbackFunction = callback;
2914 var jsListenerRegistered = false;
2915 var nativeListenerRegistered = false;
2916 var repeatNativeListenerCall = repeatNativeCall;
2918 function innerCallback(event) {
2919 for (var watchId in listeners) {
2920 if (listeners.hasOwnProperty(watchId)) {
2921 callbackFunction(listeners[watchId], event);
2926 function addListener(callback, args) {
2929 if (addId && (!nativeListenerRegistered || repeatNativeListenerCall)) {
2930 var result = native.callSync(addId, args || {});
2931 if (native.isFailure(result)) {
2932 throw native.getErrorObject(result);
2934 nativeListenerRegistered = true;
2937 if (!jsListenerRegistered) {
2938 native.addListener(listenerName, innerCallback);
2939 jsListenerRegistered = true;
2942 listeners[id] = callback;
2946 function removeListener(watchId, args) {
2947 if (listeners.hasOwnProperty(watchId)) {
2948 delete listeners[watchId];
2953 ((nativeListenerRegistered && T.isEmptyObject(listeners)) ||
2954 repeatNativeListenerCall)
2956 var result = native.callSync(removeId, args || {});
2957 if (native.isFailure(result)) {
2958 throw native.getErrorObject(result);
2960 nativeListenerRegistered = false;
2963 if (jsListenerRegistered && T.isEmptyObject(listeners)) {
2964 native.removeListener(listenerName, innerCallback);
2965 jsListenerRegistered = false;
2970 addListener: addListener,
2971 removeListener: removeListener
2975 var _bluetoothGATTCharacteristicListener = _multipleListenerBuilder(
2976 'BluetoothGATTCharacteristicValueChangeListener',
2977 function(listener, event) {
2980 'BluetoothGATTClientServiceAddValueChangeListener',
2981 'BluetoothGATTClientServiceRemoveValueChangeListener',
2986 * This object is used by:
2987 * - BluetoothLEDevice.addConnectStateChangeListener()
2988 * - BluetoothLEAdapter.addConnectStateChangeListener()
2990 var _bleConnectChangeListener = _multipleListenerBuilder(
2991 'BluetoothLEConnectChangeCallback',
2992 function(listener, event) {
2995 'BluetoothLEDeviceAddConnectStateChangeListener',
2996 'BluetoothLEDeviceRemoveConnectStateChangeListener'
2999 var _bleAttMtuChangeListener = _multipleListenerBuilder(
3000 'BluetoothLEAttMtuChangeCallback',
3001 function(listener, event) {
3004 'BluetoothLEDeviceAddAttMtuChangeListener',
3005 'BluetoothLEDeviceRemoveAttMtuChangeListener'
3008 //class BluetoothGATTDescriptor ///////////////////////////
3009 var BluetoothGATTDescriptor = function(data, address) {
3010 var handle_ = data.handle;
3011 //address_ is needed to control if device is still connected
3012 var address_ = address;
3013 var uuid_ = data.uuid;
3015 this.readValue = function() {
3016 privUtils_.log('Entered BluetoothGATTDescriptor.readValue()');
3017 var args = AV.validateArgs(arguments, [
3019 name: 'successCallback',
3020 type: AV.Types.FUNCTION
3023 name: 'errorCallback',
3024 type: AV.Types.FUNCTION,
3030 var callback = function(result) {
3031 if (native.isFailure(result)) {
3032 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3034 var d = numberArrayToByteArray(native.getResultObject(result));
3035 args.successCallback(d);
3039 var callArgs = { handle: handle_, address: address_ };
3041 var result = native.call(
3042 'BluetoothGATTClientServiceReadValue',
3047 if (native.isFailure(result)) {
3048 throw native.getErrorObject(result);
3052 this.writeValue = function(value, successCallback, errorCallback) {
3053 privUtils_.log('Entered BluetoothGATTDescriptor.writeValue()');
3054 var args = AV.validateArgs(Array.prototype.slice.call(arguments, 1), [
3056 name: 'successCallback',
3057 type: AV.Types.FUNCTION,
3062 name: 'errorCallback',
3063 type: AV.Types.FUNCTION,
3069 var callback = function(result) {
3070 if (native.isFailure(result)) {
3071 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3073 native.callIfPossible(args.successCallback);
3079 value: BluetoothManager_toByteArray(value),
3083 var result = native.call(
3084 'BluetoothGATTClientServiceWriteValue',
3089 if (native.isFailure(result)) {
3090 throw native.getErrorObject(result);
3094 Object.defineProperties(this, {
3105 var ValidateBluetoothGATTServerDescriptorInit = function(initData) {
3106 return AV.validateArgs(
3109 initData['readPermission'] || false,
3110 initData['writePermission'] || false,
3111 initData['encryptedReadPermission'] || false,
3112 initData['encryptedWritePermission'] || false,
3113 initData['encryptedSignedReadPermission'] || false,
3114 initData['encryptedSignedWritePermission'] || false,
3115 initData['readValueRequestCallback'] || null,
3116 initData['writeValueRequestCallback'] || null
3121 type: AV.Types.STRING,
3122 validator: IsUuidValid
3125 name: 'readPermission',
3126 type: AV.Types.BOOLEAN
3129 name: 'writePermission',
3130 type: AV.Types.BOOLEAN
3133 name: 'encryptedReadPermission',
3134 type: AV.Types.BOOLEAN
3137 name: 'encryptedWritePermission',
3138 type: AV.Types.BOOLEAN
3141 name: 'encryptedSignedReadPermission',
3142 type: AV.Types.BOOLEAN
3145 name: 'encryptedSignedWritePermission',
3146 type: AV.Types.BOOLEAN
3149 name: 'readValueRequestCallback',
3150 type: AV.Types.FUNCTION,
3154 name: 'writeValueRequestCallback',
3155 type: AV.Types.FUNCTION,
3162 var BluetoothGATTServerDescriptor = function(data, address) {
3163 data = ValidateBluetoothGATTServerDescriptorInit(data);
3165 BluetoothGATTDescriptor.call(this, data, null);
3167 Object.defineProperties(this, {
3171 return data.readPermission;
3178 return data.writePermission;
3182 encryptedReadPermission: {
3185 return data.encryptedReadPermission;
3189 encryptedWritePermission: {
3192 return data.encryptedWritePermission;
3196 encryptedSignedReadPermission: {
3199 return data.encryptedSignedReadPermission;
3203 encryptedSignedWritePermission: {
3206 return data.encryptedSignedWritePermission;
3210 // This property is "private" and meant not to be used by users
3212 // It has to be enumerable, to be serialized with JSON.stringify()
3214 value: NextGattServerEntityID()
3218 this.readValue = function() {
3219 throw new WebAPIException(
3220 'NotSupportedError',
3221 'This method cannot be called on BluetoothGATTServerDescriptor'
3225 this.writeValue = function() {
3226 throw new WebAPIException(
3227 'NotSupportedError',
3228 'This method cannot be called on BluetoothGATTServerDescriptor'
3233 BluetoothGATTServerDescriptor.prototype = Object.create(
3234 BluetoothGATTDescriptor.prototype
3237 Object.defineProperty(BluetoothGATTServerDescriptor.prototype, 'constructor', {
3238 value: BluetoothGATTServerDescriptor,
3243 BluetoothGATTServerDescriptor.prototype.setReadValueRequestCallback = _setReadValueRequestCallbackCommon;
3244 BluetoothGATTServerDescriptor.prototype.setWriteValueRequestCallback = _setWriteValueRequestCallbackCommon;
3246 // class BluetoothAdapter ///////////////////////////
3247 var BluetoothAdapter = function() {
3248 function nameGetter() {
3249 var result = native.callSync('BluetoothAdapterGetName', {});
3251 if (native.isFailure(result)) {
3254 return native.getResultObject(result);
3258 function addressGetter() {
3259 var result = native.callSync('BluetoothAdapterGetAddress', {});
3261 if (native.isFailure(result)) {
3264 return native.getResultObject(result);
3268 function poweredGetter() {
3269 var result = native.callSync('BluetoothAdapterGetPowered', {});
3271 if (native.isFailure(result)) {
3274 return native.getResultObject(result);
3278 function visibleGetter() {
3279 var result = native.callSync('BluetoothAdapterGetVisible', {});
3281 if (native.isFailure(result)) {
3284 return native.getResultObject(result);
3288 Object.defineProperties(this, {
3312 BluetoothAdapter.prototype.setName = function() {
3313 privUtils_.log('Entered BluetoothAdapter.setName()');
3314 var args = AV.validateArgs(arguments, [
3317 type: AV.Types.STRING
3320 name: 'successCallback',
3321 type: AV.Types.FUNCTION,
3326 name: 'errorCallback',
3327 type: AV.Types.FUNCTION,
3337 var callback = function(result) {
3338 if (native.isFailure(result)) {
3339 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3341 native.callIfPossible(args.successCallback);
3345 var result = native.call('BluetoothAdapterSetName', callArgs, callback);
3346 if (native.isFailure(result)) {
3347 throw native.getErrorObject(result);
3351 BluetoothAdapter.prototype.setPowered = function() {
3352 privUtils_.log('Entered BluetoothAdapter.setPowered()');
3353 privUtils_.printDeprecationWarningFor('setPowered()');
3355 'Let the user turn on/off Bluetooth through the Settings application instead.'
3358 var args = AV.validateArgs(arguments, [
3361 type: AV.Types.BOOLEAN
3364 name: 'successCallback',
3365 type: AV.Types.FUNCTION,
3370 name: 'errorCallback',
3371 type: AV.Types.FUNCTION,
3378 powered: args.powered
3381 var callback = function(result) {
3382 if (native.isFailure(result)) {
3383 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3385 native.callIfPossible(args.successCallback);
3389 var result = native.call('BluetoothAdapterSetPowered', callArgs, callback);
3390 if (native.isFailure(result)) {
3391 throw native.getErrorObject(result);
3395 // This method is deprecated since Tizen 2.3.
3396 BluetoothAdapter.prototype.setVisible = function() {
3397 privUtils_.log('Entered BluetoothAdapter.setVisible()');
3398 privUtils_.printDeprecationWarningFor('setVisible()');
3400 'Let the user change the Bluetooth visibility through the Settings ' +
3401 'application instead.'
3404 var args = AV.validateArgs(arguments, [
3407 type: AV.Types.BOOLEAN
3410 name: 'successCallback',
3411 type: AV.Types.FUNCTION,
3416 name: 'errorCallback',
3417 type: AV.Types.FUNCTION,
3423 type: AV.Types.UNSIGNED_LONG,
3430 visible: args.visible
3433 if (args.visible === true) {
3434 if (T.isNullOrUndefined(args.timeout)) {
3435 callArgs.timeout = 0;
3437 callArgs.timeout = args.timeout > 65535 ? 180 : args.timeout;
3441 var callback = function(result) {
3442 if (native.isFailure(result)) {
3443 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3445 native.callIfPossible(args.successCallback);
3449 var result = native.call('BluetoothAdapterSetVisible', callArgs, callback);
3450 if (native.isFailure(result)) {
3451 throw native.getErrorObject(result);
3457 function _BluetoothAdapterChangeCallback(event) {
3458 privUtils_.log('_BluetoothAdapterChangeCallback');
3464 case 'onstatechanged':
3468 case 'onnamechanged':
3472 case 'onvisibilitychanged':
3477 privUtils_.log('Unknown mode: ' + e.action);
3481 if (_listener[e.action]) {
3482 _listener[e.action](d);
3486 BluetoothAdapter.prototype.setChangeListener = function() {
3487 privUtils_.log('Entered BluetoothAdapter.setChangeListener()');
3488 var args = AV.validateArgs(arguments, [
3490 name: 'changeCallback',
3491 type: AV.Types.LISTENER,
3492 values: ['onstatechanged', 'onnamechanged', 'onvisibilitychanged']
3496 if (T.isNullOrUndefined(_listener)) {
3498 'BluetoothAdapterChangeCallback',
3499 _BluetoothAdapterChangeCallback
3501 native.callSync('BluetoothAdapterSetChangeListener', {});
3503 _listener = args.changeCallback;
3506 BluetoothAdapter.prototype.unsetChangeListener = function() {
3507 privUtils_.log('Entered BluetoothAdapter.unsetChangeListener()');
3508 if (!T.isNullOrUndefined(_listener)) {
3509 native.removeListener(
3510 'BluetoothAdapterChangeCallback',
3511 _BluetoothAdapterChangeCallback
3513 native.callSync('BluetoothAdapterUnsetChangeListener', {});
3514 _listener = undefined;
3518 var _discoverDevicesSuccessCallback;
3519 var _discoverDevicesErrorCallback;
3521 function _BluetoothDiscoverDevicesSuccessCallback(event) {
3529 case 'ondevicefound':
3530 d = new BluetoothDevice(e.data);
3533 case 'ondevicedisappeared':
3538 var result = e.data;
3540 result.forEach(function(data) {
3541 d.push(new BluetoothDevice(data));
3544 //remove listeners after discovering
3545 native.removeListener(
3546 'BluetoothDiscoverDevicesSuccessCallback',
3547 _BluetoothDiscoverDevicesSuccessCallback
3549 native.removeListener(
3550 'BluetoothDiscoverDevicesErrorCallback',
3551 _BluetoothDiscoverDevicesErrorCallback
3556 privUtils_.log('Unknown mode: ' + e.action);
3560 if (_discoverDevicesSuccessCallback[e.action]) {
3561 _discoverDevicesSuccessCallback[e.action](d);
3565 function _BluetoothDiscoverDevicesErrorCallback(event) {
3567 setTimeout(function() {
3568 native.callIfPossible(_discoverDevicesErrorCallback, native.getErrorObject(e));
3572 BluetoothAdapter.prototype.discoverDevices = function() {
3573 privUtils_.log('Entered BluetoothAdapter.discoverDevices()');
3574 var args = AV.validateArgs(arguments, [
3576 name: 'successCallback',
3577 type: AV.Types.LISTENER,
3578 values: ['onstarted', 'ondevicefound', 'ondevicedisappeared', 'onfinished']
3581 name: 'errorCallback',
3582 type: AV.Types.FUNCTION,
3588 _discoverDevicesSuccessCallback = args.successCallback;
3589 _discoverDevicesErrorCallback = args.errorCallback;
3591 'BluetoothDiscoverDevicesSuccessCallback',
3592 _BluetoothDiscoverDevicesSuccessCallback
3595 'BluetoothDiscoverDevicesErrorCallback',
3596 _BluetoothDiscoverDevicesErrorCallback
3599 var result = native.callSync('BluetoothAdapterDiscoverDevices', {});
3601 if (native.isFailure(result)) {
3602 native.removeListener(
3603 'BluetoothDiscoverDevicesSuccessCallback',
3604 _BluetoothDiscoverDevicesSuccessCallback
3606 native.removeListener(
3607 'BluetoothDiscoverDevicesErrorCallback',
3608 _BluetoothDiscoverDevicesErrorCallback
3610 throw native.getErrorObject(result);
3614 BluetoothAdapter.prototype.stopDiscovery = function() {
3615 privUtils_.log('Entered BluetoothAdapter.stopDiscovery()');
3616 var args = AV.validateArgs(arguments, [
3618 name: 'successCallback',
3619 type: AV.Types.FUNCTION,
3624 name: 'errorCallback',
3625 type: AV.Types.FUNCTION,
3631 var callback = function(result) {
3632 if (native.isFailure(result)) {
3633 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3635 native.callIfPossible(args.successCallback);
3639 var result = native.call('BluetoothAdapterStopDiscovery', {}, callback);
3640 if (native.isFailure(result)) {
3641 throw native.getErrorObject(result);
3645 BluetoothAdapter.prototype.getKnownDevices = function() {
3646 privUtils_.log('Entered BluetoothAdapter.getKnownDevices()');
3647 var args = AV.validateArgs(arguments, [
3649 name: 'successCallback',
3650 type: AV.Types.FUNCTION
3653 name: 'errorCallback',
3654 type: AV.Types.FUNCTION,
3660 var callback = function(result) {
3661 if (native.isFailure(result)) {
3662 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3664 var r = native.getResultObject(result).devices;
3666 r.forEach(function(data) {
3667 devices.push(new BluetoothDevice(data));
3669 args.successCallback(devices);
3673 var result = native.call('BluetoothAdapterGetKnownDevices', {}, callback);
3674 if (native.isFailure(result)) {
3675 throw native.getErrorObject(result);
3679 BluetoothAdapter.prototype.getDevice = function() {
3680 privUtils_.log('Entered BluetoothAdapter.getDevice()');
3681 var args = AV.validateArgs(arguments, [
3684 type: AV.Types.STRING
3687 name: 'successCallback',
3688 type: AV.Types.FUNCTION
3691 name: 'errorCallback',
3692 type: AV.Types.FUNCTION,
3698 var callback = function(result) {
3699 if (native.isFailure(result)) {
3700 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3702 args.successCallback(new BluetoothDevice(native.getResultObject(result)));
3706 var result = native.call(
3707 'BluetoothAdapterGetDevice',
3708 { address: args.address },
3711 if (native.isFailure(result)) {
3712 throw native.getErrorObject(result);
3716 BluetoothAdapter.prototype.createBonding = function() {
3717 privUtils_.log('Entered BluetoothAdapter.createBonding()');
3718 var args = AV.validateArgs(arguments, [
3721 type: AV.Types.STRING
3724 name: 'successCallback',
3725 type: AV.Types.FUNCTION,
3730 name: 'errorCallback',
3731 type: AV.Types.FUNCTION,
3738 address: args.address
3741 var callback = function(result) {
3742 if (native.isFailure(result)) {
3743 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3745 args.successCallback(new BluetoothDevice(native.getResultObject(result)));
3749 var result = native.call('BluetoothAdapterCreateBonding', callArgs, callback);
3750 if (native.isFailure(result)) {
3751 throw native.getErrorObject(result);
3755 BluetoothAdapter.prototype.destroyBonding = function() {
3756 privUtils_.log('Entered BluetoothAdapter.destroyBonding()');
3757 var args = AV.validateArgs(arguments, [
3760 type: AV.Types.STRING
3763 name: 'successCallback',
3764 type: AV.Types.FUNCTION,
3769 name: 'errorCallback',
3770 type: AV.Types.FUNCTION,
3777 address: args.address
3780 var callback = function(result) {
3781 if (native.isFailure(result)) {
3782 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3784 native.callIfPossible(args.successCallback);
3788 var result = native.call('BluetoothAdapterDestroyBonding', callArgs, callback);
3789 if (native.isFailure(result)) {
3790 throw native.getErrorObject(result);
3794 BluetoothAdapter.prototype.registerRFCOMMServiceByUUID = function() {
3795 privUtils_.log('Entered BluetoothAdapter.registerRFCOMMServiceByUUID()');
3796 var args = AV.validateArgs(arguments, [
3799 type: AV.Types.STRING
3803 type: AV.Types.STRING
3806 name: 'successCallback',
3807 type: AV.Types.FUNCTION
3810 name: 'errorCallback',
3811 type: AV.Types.FUNCTION,
3822 var callback = function(result) {
3823 if (native.isFailure(result)) {
3824 native.callIfPossible(args.errorCallback, native.getErrorObject(result));
3826 // if registration was finished with success create BluetoothServiceHandler
3827 // with parameters passed to this function (uuid and name).
3828 args.successCallback(new BluetoothServiceHandler(callArgs));
3832 var result = native.call(
3833 'BluetoothAdapterRegisterRFCOMMServiceByUUID',
3837 if (native.isFailure(result)) {
3838 throw native.getErrorObject(result);
3842 BluetoothAdapter.prototype.getBluetoothProfileHandler = function() {
3843 privUtils_.log('Entered BluetoothAdapter.getBluetoothProfileHandler()');
3844 privUtils_.printDeprecationWarningFor('getBluetoothProfileHandler');
3845 var args = AV.validateArgs(arguments, [
3847 name: 'profileType',
3848 type: AV.Types.ENUM,
3849 values: T.getValues(_BluetoothProfileType)
3853 var callArgs = { profileType: args.profileType };
3855 var result = native.callSync('BluetoothAdapterGetBluetoothProfileHandler', callArgs);
3857 if (native.isFailure(result)) {
3858 throw native.getErrorObject(result);
3860 switch (args.profileType) {
3861 case _BluetoothProfileType.HEALTH:
3862 return new BluetoothHealthProfileHandler(callArgs);
3865 throw new WebAPIException(
3866 'NotSupportedError',
3867 'Profile ' + args.profileType + ' is not supported.'
3873 // class BluetoothGATTServer ////////////////////////
3874 var _BluetoothGATTServerServices = [];
3875 var _isBluetoothGATTServerRunning = false;
3877 function _BluetoothGattServerIsRunningChangeListener(result) {
3878 _isBluetoothGATTServerRunning = result.state;
3881 function _BluetoothGattServerBluetoothAdapterStateChangeListener(result) {
3882 if (_isBluetoothGATTServerRunning && false === result.state) {
3883 _BluetoothGATTServerServicesRegisteredInNativeLayer = {};
3888 * This set is used in BluetoothGATTServer::start() to check which services
3889 * from BluetoothGATTServer::services have already been registered in native
3890 * layer and which have to be registered.
3892 var _BluetoothGATTServerServicesRegisteredInNativeLayer = {};
3894 var BluetoothGATTServer = function() {
3895 Object.defineProperties(this, {
3899 return _BluetoothGATTServerServices;
3906 return _isBluetoothGATTServerRunning;
3912 // Register listener for managing GATTServer start / stop
3914 'BluetoothGattServerIsRunningChangeListener',
3915 _BluetoothGattServerIsRunningChangeListener
3918 // Register listener for managing BluetoothAdapter power off
3920 'BluetoothGattServerBluetoothAdapterStateChangeListener',
3921 _BluetoothGattServerBluetoothAdapterStateChangeListener
3925 var BluetoothGATTServer_valid_registerService_errors = [
3926 'InvalidStateError',
3927 'NotSupportedError',
3928 'InvalidValuesError',
3931 var BluetoothGATTServer_valid_registerService_exceptions = [
3932 'InvalidStateError',
3933 'TypeMismatchError',
3937 BluetoothGATTServer.prototype.registerService = function() {
3938 var args = AV.validateArgs(arguments, [
3941 type: AV.Types.DICTIONARY
3944 name: 'successCallback',
3945 type: AV.Types.FUNCTION,
3950 name: 'errorCallback',
3951 type: AV.Types.FUNCTION,
3957 var service = new BluetoothGATTServerService(args.service);
3959 var callback = function(result) {
3960 if (native.isFailure(result)) {
3961 native.callIfPossible(
3963 native.getErrorObjectAndValidate(
3965 BluetoothGATTServer_valid_registerService_errors,
3970 _BluetoothGATTServerServicesRegisteredInNativeLayer[service._id] = true;
3971 _BluetoothGATTServerServices.push(service);
3972 native.callIfPossible(args.successCallback);
3976 var result = native.call('BluetoothGATTServerRegisterService', service, callback);
3977 if (native.isFailure(result)) {
3978 throw native.getErrorObjectAndValidate(
3980 BluetoothGATTServer_valid_registerService_exceptions,
3987 * Objects of this class are used to wait for multiple callbacks results.
3989 * Its successCallback and errorCallback members should be passed as
3990 * the success and error callbacks, respectively, to the functions we wait for.
3991 * When the functions we wait for are called callbacksNum times, either
3992 * onAllSucceeded or onFailure is called, depending on whether only
3993 * successCallback was called or not.
3995 * For the usage example, take a look at BluetoothGATTServer.prototype.start,
3996 * where it's used to wait for registration of multiple services.
3998 var ResultCallbacksAggregator = function(callbacksNum, onAllSucceeded, onFailure) {
3999 var _callbacksNum = callbacksNum;
4000 var _allSucceeded = true;
4003 this.successCallback = function() {
4006 if (!_callbacksNum) {
4007 if (_allSucceeded) {
4015 this.errorCallback = function(error) {
4017 _allSucceeded = false;
4020 if (!_callbacksNum) {
4026 function _getServicesUnregisteredInNativeLayer() {
4027 var servicesUnregisteredInNativeLayer = [];
4028 for (var i = 0; i < _BluetoothGATTServerServices.length; ++i) {
4030 !_BluetoothGATTServerServicesRegisteredInNativeLayer[
4031 _BluetoothGATTServerServices[i]._id
4034 servicesUnregisteredInNativeLayer.push(_BluetoothGATTServerServices[i]);
4037 return servicesUnregisteredInNativeLayer;
4040 function _getIdsToReregisterReadWriteCallbacks(servicesUnregisteredInNativeLayer) {
4041 var idsToRegisterWriteValueCallbacks = [];
4042 var idsToRegisterReadValueCallbacks = [];
4044 for (var i = 0; i < servicesUnregisteredInNativeLayer.length; ++i) {
4045 var serviceComponentIds = _getIncludedServicesAndItsComponentsIdsRecursively(
4046 servicesUnregisteredInNativeLayer[i]
4049 for (var j = 0; j < serviceComponentIds.length; ++j) {
4050 var _id = serviceComponentIds[j];
4051 var callbackName = 'ReadValueCallback' + _id;
4054 * Only some of the serviceComponentIds are characteristics and descriptors
4055 * and within them, only some have read/write callbacks registered.
4056 * We have to check if the callbacks were registered for each id.
4058 if (callbackName in _BluetoothGATTServerReadWriteValueRequestCallbacks) {
4059 idsToRegisterReadValueCallbacks.push(_id);
4062 callbackName = 'WriteValueCallback' + _id;
4063 if (callbackName in _BluetoothGATTServerReadWriteValueRequestCallbacks) {
4064 idsToRegisterWriteValueCallbacks.push(_id);
4069 return [idsToRegisterReadValueCallbacks, idsToRegisterWriteValueCallbacks];
4072 var BluetoothGATTServer_valid_start_errors = [
4073 'InvalidStateError',
4074 'NotSupportedError',
4077 var BluetoothGATTServer_valid_start_exceptions = [
4078 'InvalidStateError',
4079 'TypeMismatchError',
4083 function _reregisterCallback(_id, nativeFunction, successCallback, errorCallback) {
4085 * This function should only be used to reregister read/write value request
4086 * callbacks in native layer for characteristics/descriptors, that have
4087 * had such callbacks registered before the last server's stop().
4088 * As JS listeners corresponding to these callbacks already exist in JS,
4089 * only C++ callbacks have to be reregistered.
4091 var callback = function(result) {
4092 if (native.isFailure(result)) {
4093 errorCallback(native.getErrorObject(result));
4099 var result = native.call(nativeFunction, { _id: _id }, callback);
4101 if (native.isFailure(result)) {
4102 throw native.getErrorObjectAndValidate(
4104 BluetoothGATTServer_valid_start_exceptions,
4110 BluetoothGATTServer.prototype.start = function() {
4111 privUtils_.log('Entered BluetoothGATTServer.start()');
4112 var args = AV.validateArgs(arguments, [
4114 name: 'successCallback',
4115 type: AV.Types.FUNCTION,
4120 name: 'errorCallback',
4121 type: AV.Types.FUNCTION,
4127 var servicesUnregisteredInNativeLayer = _getServicesUnregisteredInNativeLayer();
4129 * Characteristics and descriptors that were registered in the server before the last stop() call
4130 * could have had read/write value request callbacks registered.
4131 * These callbacks have to be reregistered (only) in native layer.
4132 * These arrays contain _ids of characteristics and descriptors, that will have their callbacks
4135 var idsToReregisterReadWriteValueCallbacks = _getIdsToReregisterReadWriteCallbacks(
4136 servicesUnregisteredInNativeLayer
4138 var idsToReregisterReadValueCallbacks = idsToReregisterReadWriteValueCallbacks[0];
4139 var idsToReregisterWriteValueCallbacks = idsToReregisterReadWriteValueCallbacks[1];
4141 var startServerCallback = function(result) {
4142 if (native.isFailure(result)) {
4143 native.callIfPossible(
4145 native.getErrorObjectAndValidate(
4147 BluetoothGATTServer_valid_start_errors,
4152 native.callIfPossible(args.successCallback);
4156 if (servicesUnregisteredInNativeLayer.length) {
4157 var numberOfCallbacksToWaitFor =
4158 servicesUnregisteredInNativeLayer.length +
4159 idsToReregisterReadValueCallbacks.length +
4160 idsToReregisterWriteValueCallbacks.length;
4161 var registerServiceCallbacksAggregator = new ResultCallbacksAggregator(
4162 numberOfCallbacksToWaitFor,
4163 function onAllSucceeded() {
4164 var result = native.call(
4165 'BluetoothGATTServerStart',
4170 if (native.isFailure(result)) {
4171 throw native.getErrorObjectAndValidate(
4173 BluetoothGATTServer_valid_start_exceptions,
4178 function onFailure(error) {
4179 native.callIfPossible(
4181 native.getErrorObjectAndValidate(
4183 BluetoothGATTServer_valid_start_errors,
4190 var registerServicesCallback = function(result) {
4191 if (native.isFailure(result)) {
4192 registerServiceCallbacksAggregator.errorCallback(result);
4194 registerServiceCallbacksAggregator.successCallback();
4198 for (var i = 0; i < servicesUnregisteredInNativeLayer.length; ++i) {
4199 var result = native.call(
4200 'BluetoothGATTServerRegisterService',
4201 servicesUnregisteredInNativeLayer[i],
4202 registerServicesCallback
4204 if (native.isFailure(result)) {
4205 throw native.getErrorObjectAndValidate(
4207 BluetoothGATTServer_valid_registerService_exceptions,
4213 for (var i = 0; i < idsToReregisterReadValueCallbacks.length; ++i) {
4214 _reregisterCallback(
4215 idsToReregisterReadValueCallbacks[i],
4216 'BluetoothGATTServerSetReadValueRequestCallback',
4217 registerServiceCallbacksAggregator.successCallback,
4218 registerServiceCallbacksAggregator.errorCallback
4222 for (var i = 0; i < idsToReregisterWriteValueCallbacks.length; ++i) {
4223 _reregisterCallback(
4224 idsToReregisterWriteValueCallbacks[i],
4225 'BluetoothGATTServerSetWriteValueRequestCallback',
4226 registerServiceCallbacksAggregator.successCallback,
4227 registerServiceCallbacksAggregator.errorCallback
4231 var result = native.call('BluetoothGATTServerStart', {}, startServerCallback);
4233 if (native.isFailure(result)) {
4234 throw native.getErrorObjectAndValidate(
4236 BluetoothGATTServer_valid_start_exceptions,
4243 var BluetoothGATTServer_valid_stop_errors = [
4244 'InvalidStateError',
4245 'NotSupportedError',
4248 var BluetoothGATTServer_valid_stop_exceptions = [
4249 'InvalidStateError',
4250 'TypeMismatchError',
4254 BluetoothGATTServer.prototype.stop = function() {
4255 privUtils_.log('Entered BluetoothGATTServer.stop()');
4256 var args = AV.validateArgs(arguments, [
4258 name: 'successCallback',
4259 type: AV.Types.FUNCTION,
4264 name: 'errorCallback',
4265 type: AV.Types.FUNCTION,
4271 var callback = function(result) {
4272 if (native.isFailure(result)) {
4273 native.callIfPossible(
4275 native.getErrorObjectAndValidate(
4277 BluetoothGATTServer_valid_stop_errors,
4282 _BluetoothGATTServerServicesRegisteredInNativeLayer = {};
4283 native.callIfPossible(args.successCallback);
4287 var result = native.call('BluetoothGATTServerStop', {}, callback);
4288 if (native.isFailure(result)) {
4289 throw native.getErrorObjectAndValidate(
4291 BluetoothGATTServer_valid_stop_exceptions,
4297 var BluetoothGATTServer_valid_getConnectionMtu_errors = [
4298 'InvalidStateError',
4299 'NotSupportedError',
4302 var BluetoothGATTServer_valid_getConnectionMtu_exceptions = [
4303 'TypeMismatchError',
4307 BluetoothGATTServer.prototype.getConnectionMtu = function() {
4308 privUtils_.log('Entered BluetoothGATTServer.getConnectionMtu()');
4309 var args = AV.validateArgs(arguments, [
4311 name: 'clientAddress',
4312 type: AV.Types.STRING
4315 name: 'successCallback',
4316 type: AV.Types.FUNCTION
4319 name: 'errorCallback',
4320 type: AV.Types.FUNCTION,
4325 var callback = function(result) {
4326 if (native.isFailure(result)) {
4327 native.callIfPossible(
4329 native.getErrorObjectAndValidate(
4331 BluetoothGATTServer_valid_getConnectionMtu_errors,
4336 args.successCallback(native.getResultObject(result));
4340 var result = native.call(
4341 'BluetoothGATTServerGetConnectionMtu',
4342 { clientAddress: args.clientAddress },
4345 if (native.isFailure(result)) {
4346 throw native.getErrorObjectAndValidate(
4348 BluetoothGATTServer_valid_getConnectionMtu_exceptions,
4354 var GATTServer = new BluetoothGATTServer();
4356 // class BluetoothManager ///////////////////////////
4357 var BluetoothManager = function() {
4358 Object.defineProperties(this, {
4360 value: new BluetoothClassDeviceMajor(),
4365 value: new BluetoothClassDeviceMinor(),
4370 value: new BluetoothClassDeviceService(),
4375 value: '00000000-0000-1000-8000-00805F9B34FB',
4382 var BluetoothManager_getDefaultAdapter = function() {
4383 privUtils_.checkPrivilegeAccess4Ver(
4385 Privilege.BLUETOOTH,
4386 Privilege.BLUETOOTH_GAP
4389 return new BluetoothAdapter();
4392 BluetoothManager.prototype.getDefaultAdapter = function() {
4393 privUtils_.log('Entered BluetoothManager.getDefaultAdapter()');
4394 return BluetoothManager_getDefaultAdapter();
4397 var BluetoothManager_getLEAdapter = function() {
4398 privUtils_.checkPrivilegeAccess4Ver(
4400 Privilege.BLUETOOTH,
4401 Privilege.BLUETOOTH_ADMIN
4404 return new BluetoothLEAdapter();
4407 BluetoothManager.prototype.getLEAdapter = function() {
4408 privUtils_.log('Entered BluetoothManager.getLEAdapter()');
4409 return BluetoothManager_getLEAdapter();
4412 var BluetoothManager_checkAndNormalizeHexString = function(hexString) {
4413 hexString = hexString.toLowerCase();
4414 if (hexString.startsWith('0x')) {
4415 hexString = hexString.substring(2);
4417 if (!/^[0-9a-f]+$/.test(hexString)) {
4418 throw new WebAPIException(
4419 WebAPIException.TYPE_MISMATCH_ERR,
4420 'Given string is not hexadecimal value'
4423 if ('0' === hexString) {
4426 if (1 === hexString.length % 2) {
4427 // to save consistency with BluetoothLEManufacturerData, last character is omitted
4428 hexString = hexString.replace(/.$/, '');
4433 var BluetoothManager_HexStringToUint8Array = function(hexString) {
4434 hexString = BluetoothManager_checkAndNormalizeHexString(hexString);
4435 if (0 === hexString.length) {
4436 return new Uint8Array([]);
4438 var data = hexString.match(/[0-9a-f]{2}/g).map(function(byte) {
4439 return parseInt(byte, 16);
4441 return new Uint8Array(data);
4444 var BluetoothManager_byteArrayToHexString = function(bytes) {
4445 if (0 == bytes.length) {
4451 .call(bytes, function(byte) {
4452 return ('0' + (byte & 0xff).toString(16)).slice(-2);
4458 var BluetoothManager_toByteArray = function(data) {
4459 if (data && String === data.constructor) {
4460 return numberArrayToByteArray(BluetoothManager_HexStringToUint8Array(data));
4463 data = numberArrayToByteArray(data);
4465 throw new WebAPIException(
4466 WebAPIException.TYPE_MISMATCH_ERR,
4467 'argument is not a valid Bytes type'
4474 BluetoothManager.prototype.toByteArray = function(data) {
4475 privUtils_.log('Entered BluetoothManager.toByteArray()');
4476 return BluetoothManager_toByteArray(data);
4479 var BluetoothManager_toDOMString = function(data) {
4480 if (data && String === data.constructor) {
4481 data = BluetoothManager_checkAndNormalizeHexString(data);
4482 if (0 !== data.length) {
4488 data = numberArrayToByteArray(data);
4490 throw new WebAPIException(
4491 WebAPIException.TYPE_MISMATCH_ERR,
4492 'argument is not a valid Bytes type'
4495 return BluetoothManager_byteArrayToHexString(data);
4498 BluetoothManager.prototype.toDOMString = function(data) {
4499 privUtils_.log('Entered BluetoothManager.toDOMString()');
4500 return BluetoothManager_toDOMString(data);
4503 var BluetoothManager_toUint8Array = function(data) {
4504 if (data && String === data.constructor) {
4505 return BluetoothManager_HexStringToUint8Array(data);
4508 data = new Uint8Array(numberArrayToByteArray(data));
4510 throw new WebAPIException(
4511 WebAPIException.TYPE_MISMATCH_ERR,
4512 'argument is not a valid Bytes type'
4519 BluetoothManager.prototype.toUint8Array = function(data) {
4520 privUtils_.log('Entered BluetoothManager.toUint8Array()');
4521 return BluetoothManager_toUint8Array(data);
4524 var BluetoothManager_UUIDIsValid128Bit = function(uuid) {
4525 var re128BitFormat = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
4526 if (re128BitFormat.test(uuid)) {
4532 var BluetoothManager_UUIDIsValid32Bit = function(uuid) {
4533 var re32BitFormat = /^[0-9a-f]{8}$/;
4534 if (re32BitFormat.test(uuid)) {
4540 var BluetoothManager_UUIDIsValid16Bit = function(uuid) {
4541 var re16BitFormat = /^[0-9a-f]{4}$/;
4542 if (re16BitFormat.test(uuid)) {
4548 var BluetoothManager_UUIDIsConvertibleTo16Bit = function(uuid) {
4549 var re128BitFormat = /^0000[0-9a-f]{4}-0000-1000-8000-00805f9b34fb$/;
4550 if (re128BitFormat.test(uuid)) {
4553 var re32BitFormat = /^0000[0-9a-f]{4}$/;
4554 if (re32BitFormat.test(uuid)) {
4560 var BluetoothManager_UUIDIsConvertibleTo32Bit = function(uuid) {
4561 var re = /^[0-9a-f]{8}-0000-1000-8000-00805f9b34fb$/;
4562 if (re.test(uuid)) {
4568 var BluetoothManager_UUIDTo128bit = function(uuid) {
4569 uuid = Converter.toString(uuid).toLowerCase();
4570 if (BluetoothManager_UUIDIsValid128Bit(uuid)) {
4573 var baseUuidLast96Bits = '-0000-1000-8000-00805f9b34fb';
4574 if (BluetoothManager_UUIDIsValid16Bit(uuid)) {
4575 return '0000' + uuid + baseUuidLast96Bits;
4577 if (BluetoothManager_UUIDIsValid32Bit(uuid)) {
4578 return uuid + baseUuidLast96Bits;
4580 throw new WebAPIException(
4581 WebAPIException.INVALID_VALUES_ERR,
4582 'Given parameter is not a supported uuid format: ' + uuid
4586 var BluetoothManager_UUIDToShortestPossible = function(uuid) {
4587 uuid = uuid.toLowerCase();
4588 if (BluetoothManager_UUIDIsValid16Bit(uuid)) {
4591 if (BluetoothManager_UUIDIsValid32Bit(uuid)) {
4592 if (BluetoothManager_UUIDIsConvertibleTo16Bit(uuid)) {
4593 return uuid.substring(4, 8);
4596 if (!BluetoothManager_UUIDIsValid128Bit(uuid)) {
4597 throw new WebAPIException(
4598 WebAPIException.INVALID_VALUES_ERR,
4599 'Given parameter is not a supported uuid format: ' + uuid
4602 if (BluetoothManager_UUIDIsConvertibleTo16Bit(uuid)) {
4603 return uuid.substring(4, 8);
4605 if (BluetoothManager_UUIDIsConvertibleTo32Bit(uuid)) {
4606 return uuid.substring(0, 8);
4611 var BluetoothManager_UUIDsEqual = function(uuid1, uuid2) {
4612 uuid1 = Converter.toString(uuid1).toLowerCase();
4613 uuid1 = BluetoothManager_UUIDTo128bit(uuid1);
4614 uuid2 = Converter.toString(uuid2).toLowerCase();
4615 uuid2 = BluetoothManager_UUIDTo128bit(uuid2);
4616 return uuid1 === uuid2;
4619 BluetoothManager.prototype.uuidTo128bit = function(uuid) {
4620 privUtils_.log('Entered BluetoothManager.uuidTo128bit()');
4621 var args = AV.validateArgs(arguments, [
4624 type: AV.Types.STRING
4627 return BluetoothManager_UUIDTo128bit(args.uuid);
4630 BluetoothManager.prototype.uuidToShortestPossible = function(uuid) {
4631 privUtils_.log('Entered BluetoothManager.uuidToShortestPossible()');
4632 var args = AV.validateArgs(arguments, [
4635 type: AV.Types.STRING
4638 return BluetoothManager_UUIDToShortestPossible(args.uuid);
4641 BluetoothManager.prototype.uuidsEqual = function(uuid1, uuid2) {
4642 privUtils_.log('Entered BluetoothManager.uuidsEqual()');
4643 var args = AV.validateArgs(arguments, [
4646 type: AV.Types.STRING
4650 type: AV.Types.STRING
4653 return BluetoothManager_UUIDsEqual(args.uuid1, args.uuid2);
4655 BluetoothManager.prototype.getGATTServer = function() {
4656 privUtils_.log('Entered BluetoothManager.getGATTServer()');
4657 return BluetoothManager_getGATTServer();
4660 var BluetoothManager_getGATTServer = function() {
4664 // exports //////////////////////////////////////////
4665 exports = new BluetoothManager();