};
};
+function _getServicesUnregisteredInNativeLayer() {
+ var servicesUnregisteredInNativeLayer = [];
+ for (var i = 0; i < _BluetoothGATTServerServices.length; ++i) {
+ if (
+ !_BluetoothGATTServerServicesRegisteredInNativeLayer[
+ _BluetoothGATTServerServices[i]._id
+ ]
+ ) {
+ servicesUnregisteredInNativeLayer.push(_BluetoothGATTServerServices[i]);
+ }
+ }
+ return servicesUnregisteredInNativeLayer;
+}
+
+function _getIdsToReregisterReadWriteCallbacks(servicesUnregisteredInNativeLayer) {
+ var idsToRegisterWriteValueCallbacks = [];
+ var idsToRegisterReadValueCallbacks = [];
+
+ for (var i = 0; i < servicesUnregisteredInNativeLayer.length; ++i) {
+ var serviceComponentIds = _getIncludedServicesAndItsComponentsIdsRecursively(
+ servicesUnregisteredInNativeLayer[i]
+ );
+
+ for (var j = 0; j < serviceComponentIds.length; ++j) {
+ var _id = serviceComponentIds[j];
+ var callbackName = 'ReadValueCallback' + _id;
+
+ /*
+ * Only some of the serviceComponentIds are characteristics and descriptors
+ * and within them, only some have read/write callbacks registered.
+ * We have to check if the callbacks were registered for each id.
+ */
+ if (callbackName in _BluetoothGATTServerReadWriteValueRequestCallbacks) {
+ idsToRegisterReadValueCallbacks.push(_id);
+ }
+
+ callbackName = 'WriteValueCallback' + _id;
+ if (callbackName in _BluetoothGATTServerReadWriteValueRequestCallbacks) {
+ idsToRegisterWriteValueCallbacks.push(_id);
+ }
+ }
+ }
+
+ return [idsToRegisterReadValueCallbacks, idsToRegisterWriteValueCallbacks];
+}
+
var BluetoothGATTServer_valid_start_errors = [
'InvalidStateError',
'NotSupportedError',
'SecurityError'
];
+function _reregisterCallback(_id, nativeFunction, successCallback, errorCallback) {
+ /*
+ * This function should only be used to reregister read/write value request
+ * callbacks in native layer for characteristics/descriptors, that have
+ * had such callbacks registered before the last server's stop().
+ * As JS listeners corresponding to these callbacks already exist in JS,
+ * only C++ callbacks have to be reregistered.
+ */
+ var callback = function(result) {
+ if (native.isFailure(result)) {
+ errorCallback(native.getErrorObject(result));
+ } else {
+ successCallback();
+ }
+ };
+
+ var result = native.call(nativeFunction, { _id: _id }, callback);
+
+ if (native.isFailure(result)) {
+ throw native.getErrorObjectAndValidate(
+ result,
+ BluetoothGATTServer_valid_start_exceptions,
+ AbortError
+ );
+ }
+}
+
BluetoothGATTServer.prototype.start = function() {
privUtils_.log('Entered BluetoothGATTServer.start()');
var args = AV.validateArgs(arguments, [
}
]);
- var servicesUnregisteredInNativeLayer = [];
- for (var i = 0; i < this.services.length; ++i) {
- if (this.services[i]) {
- if (
- !_BluetoothGATTServerServicesRegisteredInNativeLayer[this.services[i]._id]
- ) {
- servicesUnregisteredInNativeLayer.push(this.services[i]);
- }
- }
- }
+ var servicesUnregisteredInNativeLayer = _getServicesUnregisteredInNativeLayer();
+ /*
+ * Characteristics and descriptors that were registered in the server before the last stop() call
+ * could have had read/write value request callbacks registered.
+ * These callbacks have to be reregistered (only) in native layer.
+ * These arrays contain _ids of characteristics and descriptors, that will have their callbacks
+ * reregistered.
+ */
+ var idsToReregisterReadWriteValueCallbacks = _getIdsToReregisterReadWriteCallbacks(
+ servicesUnregisteredInNativeLayer
+ );
+ var idsToReregisterReadValueCallbacks = idsToReregisterReadWriteValueCallbacks[0];
+ var idsToReregisterWriteValueCallbacks = idsToReregisterReadWriteValueCallbacks[1];
var startServerCallback = function(result) {
if (native.isFailure(result)) {
};
if (servicesUnregisteredInNativeLayer.length) {
+ var numberOfCallbacksToWaitFor =
+ servicesUnregisteredInNativeLayer.length +
+ idsToReregisterReadValueCallbacks.length +
+ idsToReregisterWriteValueCallbacks.length;
var registerServiceCallbacksAggregator = new ResultCallbacksAggregator(
- servicesUnregisteredInNativeLayer.length,
+ numberOfCallbacksToWaitFor,
function onAllSucceeded() {
var result = native.call(
'BluetoothGATTServerStart',
var registerServicesCallback = function(result) {
if (native.isFailure(result)) {
- registerServiceCallbacksAggregator.errorCallback(
- native.getErrorObjectAndValidate(
- result,
- BluetoothGATTServer_valid_start_errors,
- AbortError
- )
- );
+ registerServiceCallbacksAggregator.errorCallback(result);
} else {
registerServiceCallbacksAggregator.successCallback();
}
);
}
}
+
+ for (var i = 0; i < idsToReregisterReadValueCallbacks.length; ++i) {
+ _reregisterCallback(
+ idsToReregisterReadValueCallbacks[i],
+ 'BluetoothGATTServerSetReadValueRequestCallback',
+ registerServiceCallbacksAggregator.successCallback,
+ registerServiceCallbacksAggregator.errorCallback
+ );
+ }
+
+ for (var i = 0; i < idsToReregisterWriteValueCallbacks.length; ++i) {
+ _reregisterCallback(
+ idsToReregisterWriteValueCallbacks[i],
+ 'BluetoothGATTServerSetWriteValueRequestCallback',
+ registerServiceCallbacksAggregator.successCallback,
+ registerServiceCallbacksAggregator.errorCallback
+ );
+ }
} else {
var result = native.call('BluetoothGATTServerStart', {}, startServerCallback);
auto _id = static_cast<int>(args.get(kId).get<double>());
LoggerD("Setting read value request callback for a GATT entity with _id: %d", _id);
+ if (gatt_objects_.find(_id) == gatt_objects_.end()) {
+ LoggerE("No GATT handle for entity with _id [%d]", _id);
+ return common::PlatformResult{ErrorCode::ABORT_ERR, "Failed to set read value request callback"};
+ }
+
auto gatt_handle = gatt_objects_[_id];
callback_names_[std::make_pair(gatt_handle, kReadCallback)] =
"ReadValueRequestCallback_" + std::to_string(_id);
auto _id = static_cast<int>(args.get(kId).get<double>());
LoggerD("Setting write value request callback for a GATT entity with _id: %d", _id);
+ if (gatt_objects_.find(_id) == gatt_objects_.end()) {
+ LoggerE("No GATT handle for entity with _id [%d]", _id);
+ return common::PlatformResult{ErrorCode::ABORT_ERR, "Failed to set write value request callback"};
+ }
+
auto gatt_handle = gatt_objects_[_id];
callback_names_[std::make_pair(gatt_handle, kWriteCallback)] =
"WriteValueRequestCallback_" + std::to_string(_id);