From 04b8a17a66e7500b82eb913b8ae5588d15bd8466 Mon Sep 17 00:00:00 2001
From: Pawel Wasowski
Date: Mon, 6 Jul 2020 20:36:21 +0200
Subject: [PATCH] [Bluetooth] Add BluetoothGATTServer. Implement start, stop
and getServer
ACR: TWDAPI-263
This commit adds BluetoothGATTServer class in C++ and implements JS
APIs:
- tizen.bluetooth.getGATTServer()
- BluetoothGATTServer.start()
- BluetoothGATTServer.stop()
Verification: The code tested in the Chrome DevTools console works fine
Change-Id: I688df55298be1b5ec997a5ae8ff42877f1bd6a24
Signed-off-by: Pawel Wasowski
---
src/bluetooth/bluetooth.gyp | 4 +-
src/bluetooth/bluetooth_api.js | 98 ++++++++++++
src/bluetooth/bluetooth_gatt_server.cc | 283 +++++++++++++++++++++++++++++++++
src/bluetooth/bluetooth_gatt_server.h | 61 +++++++
src/bluetooth/bluetooth_instance.cc | 47 +++++-
src/bluetooth/bluetooth_instance.h | 12 ++
src/bluetooth/bluetooth_util.cc | 23 ++-
src/bluetooth/bluetooth_util.h | 2 +
8 files changed, 524 insertions(+), 6 deletions(-)
create mode 100644 src/bluetooth/bluetooth_gatt_server.cc
create mode 100644 src/bluetooth/bluetooth_gatt_server.h
diff --git a/src/bluetooth/bluetooth.gyp b/src/bluetooth/bluetooth.gyp
index 07c310e..73df5d3 100644
--- a/src/bluetooth/bluetooth.gyp
+++ b/src/bluetooth/bluetooth.gyp
@@ -42,7 +42,9 @@
'bluetooth_le_device.cc',
'bluetooth_le_device.h',
'uuid.cc',
- 'uuid.h'
+ 'uuid.h',
+ 'bluetooth_gatt_server.cc',
+ 'bluetooth_gatt_server.h'
],
'includes': [
'../common/pkg-config.gypi',
diff --git a/src/bluetooth/bluetooth_api.js b/src/bluetooth/bluetooth_api.js
index 6e55fad..37799e0 100755
--- a/src/bluetooth/bluetooth_api.js
+++ b/src/bluetooth/bluetooth_api.js
@@ -2715,6 +2715,95 @@ BluetoothAdapter.prototype.getBluetoothProfileHandler = function() {
}
};
+// class BluetoothGATTServer ////////////////////////
+var BluetoothGATTServer = function() {
+ var services_ = [];
+ Object.defineProperties(this, {
+ services: {
+ get: function() {
+ return services_;
+ },
+ set: function() {}
+ }
+ });
+}
+
+var AbortError = new WebAPIException('AbortError', 'An unknown error occurred');
+
+var BluetoothGATTServer_valid_start_errors = ['InvalidStateError', 'NotSupportedError', 'AbortError'];
+var BluetoothGATTServer_valid_start_exceptions = ['InvalidStateError', 'TypeMismatchError', 'SecurityError'];
+
+BluetoothGATTServer.prototype.start = function() {
+ privUtils_.log('Entered BluetoothGATTServer.start()');
+ var args = AV.validateArgs(arguments, [
+ {
+ name: 'successCallback',
+ type: AV.Types.FUNCTION,
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'errorCallback',
+ type: AV.Types.FUNCTION,
+ optional: true,
+ nullable: true
+ }
+ ]);
+
+ var callback = function(result) {
+ if (native.isFailure(result)) {
+ native.callIfPossible(args.errorCallback,
+ native.getErrorObjectAndValidate(result,
+ BluetoothGATTServer_valid_start_errors, AbortError));
+ } else {
+ native.callIfPossible(args.successCallback);
+ }
+ };
+
+ var result = native.call('BluetoothGATTServerStart', {}, callback);
+ if (native.isFailure(result)) {
+ throw native.getErrorObjectAndValidate(result, BluetoothGATTServer_valid_start_exceptions, AbortError);
+ }
+}
+
+var BluetoothGATTServer_valid_stop_errors = ['InvalidStateError', 'NotSupportedError', 'AbortError'];
+var BluetoothGATTServer_valid_stop_exceptions = ['InvalidStateError', 'TypeMismatchError', 'SecurityError'];
+
+BluetoothGATTServer.prototype.stop = function() {
+ privUtils_.log('Entered BluetoothGATTServer.stop()');
+ var args = AV.validateArgs(arguments, [
+ {
+ name: 'successCallback',
+ type: AV.Types.FUNCTION,
+ optional: true,
+ nullable: true
+ },
+ {
+ name: 'errorCallback',
+ type: AV.Types.FUNCTION,
+ optional: true,
+ nullable: true
+ }
+ ]);
+
+ var callback = function(result) {
+ if (native.isFailure(result)) {
+ native.callIfPossible(args.errorCallback,
+ native.getErrorObjectAndValidate(result,
+ BluetoothGATTServer_valid_stop_errors, AbortError));
+ } else {
+ native.callIfPossible(args.successCallback);
+ }
+ };
+
+ var result = native.call('BluetoothGATTServerStop', {}, callback);
+ if (native.isFailure(result)) {
+ throw native.getErrorObjectAndValidate(result, BluetoothGATTServer_valid_stop_exceptions, AbortError);
+ }
+}
+
+var GATTServer = new BluetoothGATTServer();
+
// class BluetoothManager ///////////////////////////
var BluetoothManager = function() {
Object.defineProperties(this, {
@@ -2993,5 +3082,14 @@ BluetoothManager.prototype.uuidsEqual = function(uuid1, uuid2) {
]);
return BluetoothManager_UUIDsEqual(args.uuid1, args.uuid2);
};
+BluetoothManager.prototype.getGATTServer = function() {
+ privUtils_.log('Entered BluetoothManager.getGATTServer()');
+ return BluetoothManager_getGATTServer();
+};
+
+var BluetoothManager_getGATTServer = function() {
+ return GATTServer;
+};
+
// exports //////////////////////////////////////////
exports = new BluetoothManager();
diff --git a/src/bluetooth/bluetooth_gatt_server.cc b/src/bluetooth/bluetooth_gatt_server.cc
new file mode 100644
index 0000000..255433e
--- /dev/null
+++ b/src/bluetooth/bluetooth_gatt_server.cc
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bluetooth/bluetooth_gatt_server.h"
+#include "bluetooth/bluetooth_util.h"
+
+#include "common/logger.h"
+#include "common/tools.h"
+
+using namespace extension::bluetooth::util;
+using namespace common;
+using namespace common::tools;
+
+namespace extension {
+namespace bluetooth {
+
+BluetoothGATTServer::BluetoothGATTServer(const BluetoothInstance& instance)
+ : instance_{instance}, initialized_{false}, running_{false}, handle_{nullptr} {
+ ScopeLogger();
+
+ /*
+ * TODO: register a callback, that deinitializes a server, unregisters its
+ * services, destroys handle_ and sets running_ to false
+ * when Bluetooth is turned off.
+ */
+}
+
+BluetoothGATTServer::~BluetoothGATTServer() {
+ ScopeLogger();
+
+ UnregisterAllServicesImpl();
+ DestroyAllGATTObjects();
+ Deinitialize();
+}
+
+void BluetoothGATTServer::Start(picojson::object& out) {
+ ScopeLogger();
+
+ if (running_) {
+ LoggerD("Server is running");
+ ReportSuccess(out);
+ return;
+ }
+
+ if (!initialized_) {
+ /*
+ * Server is initialized when its services are registered.
+ * However, the case when server is uninitialized until start is
+ * also valid. It happens, when user doesn't register any services
+ * and starts the server with the default ones.
+ */
+ auto result = InitializeAndCreateHandle();
+ if (!result) {
+ result.SetMessage("Couldn't start GATT server");
+ ReportError(result, &out);
+ return;
+ }
+ }
+
+ auto ret = bt_gatt_server_start();
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_server_start(): %d (%s)", ret, get_error_message(ret));
+ ReportError(BluetoothErrorToPlatformResult(ret, "Couldn't start GATT server"), &out);
+ return;
+ }
+ LoggerD("bt_gatt_server_start(): success");
+
+ running_ = true;
+ ReportSuccess(out);
+}
+
+void BluetoothGATTServer::Stop(picojson::object& out) {
+ ScopeLogger();
+
+ if (!running_) {
+ LoggerD("Server is not running");
+ ReportSuccess(out);
+ return;
+ }
+
+ // Unregistering all services should not fail.
+ // Even if it does we just let UnregisterAllSerivcesImpl() log the error
+ // and proceed with server destruction.
+ UnregisterAllServicesImpl();
+
+ // DestroyAllGATTObjects() should not fail
+ // If it does, it logs the error message.
+ DestroyAllGATTObjects();
+
+ // Deinitialize() is the function that actually stops the server,
+ // thus we return the result, it returns.
+ auto result = Deinitialize();
+ if (!result) {
+ result.SetMessage("Couldn't stop GATT server");
+ ReportError(result, &out);
+ } else {
+ ReportSuccess(out);
+ running_ = false;
+ }
+}
+
+PlatformResult BluetoothGATTServer::Initialize() {
+ ScopeLogger();
+
+ auto ret = bt_gatt_server_initialize();
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_server_initialize(): %d (%s)", ret, get_error_message(ret));
+ return BluetoothErrorToPlatformResult(ret);
+ }
+ LoggerD("bt_gatt_server_initialize(): success");
+ initialized_ = true;
+
+ return PlatformResult{};
+}
+
+PlatformResult BluetoothGATTServer::CreateHandle() {
+ ScopeLogger();
+
+ if (handle_) {
+ LoggerE("Server handle is already created");
+ return PlatformResult{ErrorCode::INVALID_STATE_ERR};
+ }
+
+ auto ret = bt_gatt_server_create(&handle_);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_server_create(): %d (%s)", ret, get_error_message(ret));
+ } else {
+ LoggerD("bt_gatt_server_create(): success");
+ }
+
+ return BluetoothErrorToPlatformResult(ret);
+}
+
+PlatformResult BluetoothGATTServer::Deinitialize() {
+ ScopeLogger();
+
+ if (!initialized_) {
+ LoggerE("Server is not initialized");
+ return PlatformResult{ErrorCode::INVALID_STATE_ERR};
+ }
+
+ auto ret = bt_gatt_server_deinitialize();
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_server_deinitialize(): %d (%s)", ret, get_error_message(ret));
+ return BluetoothErrorToPlatformResult(ret);
+ }
+
+ LoggerD("bt_gatt_server_deinitialize(): success");
+ initialized_ = false;
+
+ /*
+ * Undocumented behavior of native API: bt_gatt_server_deinitialize() calls
+ * bt_gatt_server_destroy() - after Deinitialize() bt_gatt_server_destroy()
+ * should not be called (a call results in a BT_INVALID_STATE_ERROR).
+ * handle_ is to be nullified, as it is no longer valid.
+ */
+ handle_ = nullptr;
+
+ return PlatformResult{};
+}
+
+PlatformResult BluetoothGATTServer::InitializeAndCreateHandle() {
+ ScopeLogger();
+
+ auto result = Initialize();
+ if (!result) {
+ return result;
+ }
+
+ result = CreateHandle();
+ if (!result) {
+ Deinitialize();
+ }
+ return result;
+}
+
+PlatformResult BluetoothGATTServer::UnregisterAllServicesImpl() {
+ ScopeLogger();
+
+ if (!handle_) {
+ LoggerE("Server handle is a nullptr");
+ return PlatformResult{ErrorCode::INVALID_STATE_ERR};
+ }
+
+ auto ret = bt_gatt_server_unregister_all_services(handle_);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_server_unregister_all_services(): %d (%s)", ret, get_error_message(ret));
+ return BluetoothErrorToPlatformResult(ret);
+ } else {
+ LoggerD("bt_gatt_server_unregister_all_services(): success");
+ return PlatformResult{};
+ }
+}
+
+PlatformResult BluetoothGATTServer::DestroyAllGATTObjects() {
+ ScopeLogger();
+
+ if (!handle_) {
+ LoggerE("Server handle is a nullptr");
+ return PlatformResult{ErrorCode::INVALID_STATE_ERR};
+ }
+
+ auto ret = bt_gatt_server_foreach_services(handle_, DestroyService, nullptr);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_server_unregister_all_services(): %d (%s)", ret, get_error_message(ret));
+ return BluetoothErrorToPlatformResult(ret);
+ } else {
+ LoggerD("bt_gatt_server_unregister_all_services(): success");
+ return PlatformResult{};
+ }
+
+ /*
+ * TODO: remove handles from service id -> service handle map
+ */
+}
+
+bool BluetoothGATTServer::DestroyService(int total, int index, bt_gatt_h handle, void* user_data) {
+ ScopeLogger("total: %d, index: %d, handle: %p", total, index, handle);
+
+ auto ret = bt_gatt_service_foreach_included_services(handle, DestroyService, nullptr);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_service_foreach_included_servics(): %d (%s)", ret, get_error_message(ret));
+ }
+ LoggerD("bt_gatt_service_foreach_included_servics(): success");
+
+ ret = bt_gatt_service_foreach_characteristics(handle, DestroyCharacteristic, nullptr);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_service_foreach_characteristics(): %d (%s)", ret, get_error_message(ret));
+ }
+ LoggerD("bt_gatt_service_foreach_characteristics(): success");
+
+ ret = bt_gatt_service_destroy(handle);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_service_destroy(): %d (%s)", ret, get_error_message(ret));
+ }
+
+ return true;
+}
+
+bool BluetoothGATTServer::DestroyCharacteristic(int total, int index, bt_gatt_h handle,
+ void* user_data) {
+ ScopeLogger("total: %d, index: %d, handle: %p", total, index, handle);
+
+ auto ret = bt_gatt_characteristic_foreach_descriptors(handle, DestroyDescriptor, nullptr);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_characteristic_foreach_descriptors(): %d (%s)", ret, get_error_message(ret));
+ }
+ LoggerD("bt_gatt_characteristic_foreach_descriptors(): success");
+
+ ret = bt_gatt_characteristic_destroy(handle);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_characteristic_destroy(): %d (%s)", ret, get_error_message(ret));
+ }
+
+ return true;
+}
+
+bool BluetoothGATTServer::DestroyDescriptor(int total, int index, bt_gatt_h handle,
+ void* user_data) {
+ ScopeLogger("total: %d, index: %d, handle: %p", total, index, handle);
+
+ auto ret = bt_gatt_descriptor_destroy(handle);
+ if (BT_ERROR_NONE != ret) {
+ LoggerE("bt_gatt_descriptor_destroy(): %d (%s)", ret, get_error_message(ret));
+ }
+ return true;
+}
+
+} // namespace bluetooth
+} // namespace extension
diff --git a/src/bluetooth/bluetooth_gatt_server.h b/src/bluetooth/bluetooth_gatt_server.h
new file mode 100644
index 0000000..6c5d83d
--- /dev/null
+++ b/src/bluetooth/bluetooth_gatt_server.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BLUETOOTH_BLUETOOTH_GATT_SERVER_H_
+#define BLUETOOTH_BLUETOOTH_GATT_SERVER_H_
+
+#include
+
+#include "common/picojson.h"
+#include "common/platform_result.h"
+
+using common::PlatformResult;
+
+namespace extension {
+namespace bluetooth {
+
+class BluetoothInstance;
+
+class BluetoothGATTServer {
+ public:
+ BluetoothGATTServer(const BluetoothInstance&);
+ ~BluetoothGATTServer();
+
+ void Start(picojson::object& out);
+ void Stop(picojson::object& out);
+
+ static bool DestroyService(int total, int index, bt_gatt_h handle, void* user_data);
+ static bool DestroyCharacteristic(int total, int index, bt_gatt_h handle, void* user_data);
+ static bool DestroyDescriptor(int total, int index, bt_gatt_h handle, void* user_data);
+
+ private:
+ const BluetoothInstance& instance_;
+ bool initialized_;
+ bool running_;
+ bt_gatt_server_h handle_;
+
+ PlatformResult UnregisterAllServicesImpl();
+ PlatformResult DestroyAllGATTObjects();
+ PlatformResult Initialize();
+ PlatformResult CreateHandle();
+ PlatformResult Deinitialize();
+ PlatformResult InitializeAndCreateHandle();
+};
+
+} // namespace bluetooth
+} // namespace extension
+
+#endif // BLUETOOTH_BLUETOOTH_GATT_SERVER_H_
diff --git a/src/bluetooth/bluetooth_instance.cc b/src/bluetooth/bluetooth_instance.cc
index 6b68e5f..2ff079e 100644
--- a/src/bluetooth/bluetooth_instance.cc
+++ b/src/bluetooth/bluetooth_instance.cc
@@ -36,7 +36,9 @@ BluetoothInstance::BluetoothInstance()
bluetooth_socket_(bluetooth_adapter_),
bluetooth_le_adapter_(*this),
bluetooth_gatt_service_(*this),
- bluetooth_le_device_(*this, bluetooth_gatt_service_) {
+ bluetooth_le_device_(*this, bluetooth_gatt_service_),
+ worker(),
+ bluetooth_gatt_server_(*this) {
ScopeLogger();
using std::placeholders::_1;
using std::placeholders::_2;
@@ -98,16 +100,21 @@ BluetoothInstance::BluetoothInstance()
REGISTER_METHOD(BluetoothGATTServiceAddValueChangeListener);
REGISTER_METHOD(BluetoothGATTServiceRemoveValueChangeListener);
+ REGISTER_METHOD(BluetoothGATTServerStart);
+ REGISTER_METHOD(BluetoothGATTServerStop);
+
#undef REGISTER_METHOD
}
BluetoothInstance::~BluetoothInstance() {
ScopeLogger();
+ worker.stop();
}
namespace {
const char* JSON_CALLBACK_ID = "callbackId";
const char* JSON_LISTENER_ID = "listenerId";
+const std::string kPrivilegeBluetooth = "http://tizen.org/privilege/bluetooth";
} // namespace
void BluetoothInstance::AsyncResponse(double callback_handle,
@@ -435,5 +442,43 @@ void BluetoothInstance::BluetoothGATTServiceRemoveValueChangeListener(const pico
bluetooth_gatt_service_.RemoveValueChangeListener(args, out);
}
+void BluetoothInstance::BluetoothGATTServerStart(const picojson::value& args,
+ picojson::object& out) {
+ ScopeLogger();
+
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out);
+
+ double callback_id = args.get(JSON_CALLBACK_ID).get();
+ worker.add_job([this, callback_id] {
+ ScopeLogger("Async call: BluetoothGATTServerStart");
+ picojson::value response = picojson::value(picojson::object());
+ picojson::object& async_out = response.get();
+ async_out[JSON_CALLBACK_ID] = picojson::value(callback_id);
+ this->bluetooth_gatt_server_.Start(async_out);
+ this->PostMessage(response.serialize().c_str());
+ });
+
+ ReportSuccess(out);
+}
+
+void BluetoothInstance::BluetoothGATTServerStop(const picojson::value& args,
+ picojson::object& out) {
+ ScopeLogger();
+
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeBluetooth, &out);
+
+ double callback_id = args.get(JSON_CALLBACK_ID).get();
+ worker.add_job([this, callback_id] {
+ ScopeLogger("Async call: BluetoothGATTServerStop");
+ picojson::value response = picojson::value(picojson::object());
+ picojson::object& async_out = response.get();
+ async_out[JSON_CALLBACK_ID] = picojson::value(callback_id);
+ this->bluetooth_gatt_server_.Stop(async_out);
+ this->PostMessage(response.serialize().c_str());
+ });
+
+ ReportSuccess(out);
+}
+
} // namespace bluetooth
} // namespace extension
diff --git a/src/bluetooth/bluetooth_instance.h b/src/bluetooth/bluetooth_instance.h
index 0ed4909..0ee235d 100644
--- a/src/bluetooth/bluetooth_instance.h
+++ b/src/bluetooth/bluetooth_instance.h
@@ -21,6 +21,7 @@
#include "bluetooth/bluetooth_adapter.h"
#include "bluetooth/bluetooth_device.h"
+#include "bluetooth/bluetooth_gatt_server.h"
#include "bluetooth/bluetooth_gatt_service.h"
#include "bluetooth/bluetooth_health_application.h"
#include "bluetooth/bluetooth_health_channel.h"
@@ -30,6 +31,7 @@
#include "bluetooth/bluetooth_service_handler.h"
#include "bluetooth/bluetooth_socket.h"
#include "bluetooth/bluetooth_util.h"
+#include "common/worker.h"
namespace extension {
namespace bluetooth {
@@ -106,6 +108,8 @@ class BluetoothInstance : public common::ParsedInstance {
picojson::object& out);
void BluetoothGATTServiceRemoveValueChangeListener(const picojson::value& args,
picojson::object& out);
+ void BluetoothGATTServerStart(const picojson::value& args, picojson::object& out);
+ void BluetoothGATTServerStop(const picojson::value& args, picojson::object& out);
BluetoothAdapter bluetooth_adapter_;
BluetoothDevice bluetooth_device_;
@@ -117,6 +121,14 @@ class BluetoothInstance : public common::ParsedInstance {
BluetoothLEAdapter bluetooth_le_adapter_;
BluetoothGATTService bluetooth_gatt_service_;
BluetoothLEDevice bluetooth_le_device_;
+ common::Worker worker;
+ // If all operations on bluetooth_gatt_server_ will be done by the worker,
+ // no mutex to prevent concurrent access of this object is needed
+ // - all operations will be done in a single worker thread.
+ // If any operation on the bluetooth_gatt_server_ object will be done
+ // synchronously, add a mutex and lock it before each call of server's
+ // method.
+ BluetoothGATTServer bluetooth_gatt_server_;
};
} // namespace bluetooth
diff --git a/src/bluetooth/bluetooth_util.cc b/src/bluetooth/bluetooth_util.cc
index 1b378a1..64a3c83 100644
--- a/src/bluetooth/bluetooth_util.cc
+++ b/src/bluetooth/bluetooth_util.cc
@@ -36,10 +36,13 @@ const picojson::object& GetArguments(const picojson::value& data) {
return data.get();
}
-PlatformResult GetBluetoothError(int error_code, const std::string& hint) {
+PlatformResult BluetoothErrorToPlatformResult(int error_code, const std::string& message) {
common::ErrorCode error = ErrorCode::UNKNOWN_ERR;
switch (error_code) {
+ case BT_ERROR_NONE:
+ error = ErrorCode::NO_ERROR;
+ break;
case BT_ERROR_RESOURCE_BUSY:
case BT_ERROR_NOW_IN_PROGRESS:
case BT_ERROR_NOT_ENABLED:
@@ -58,19 +61,31 @@ PlatformResult GetBluetoothError(int error_code, const std::string& hint) {
error = ErrorCode::QUOTA_EXCEEDED_ERR;
break;
+ case BT_ERROR_NOT_SUPPORTED:
+ error = ErrorCode::NOT_SUPPORTED_ERR;
+ break;
+
default:
error = ErrorCode::UNKNOWN_ERR;
break;
}
- std::string message = hint + " : " + GetBluetoothErrorMessage(error_code);
+ return PlatformResult{error, message};
+}
+
+PlatformResult GetBluetoothError(int error_code, const std::string& hint) {
+ auto message = hint + ": " + GetBluetoothErrorMessage(error_code);
+ auto result = BluetoothErrorToPlatformResult(error_code, message);
+
+ LoggerE("%s %d (%s)", message.c_str(), error_code, get_error_message(error_code));
- return LogAndCreateResult(error, message.c_str(), ("%s %d (%s)", message.c_str(), error_code,
- get_error_message(error_code)));
+ return result;
}
std::string GetBluetoothErrorMessage(int error_code) {
switch (error_code) {
+ case BT_ERROR_NONE:
+ return "Success";
case BT_ERROR_CANCELLED:
return "Operation cancelled";
case BT_ERROR_INVALID_PARAMETER:
diff --git a/src/bluetooth/bluetooth_util.h b/src/bluetooth/bluetooth_util.h
index 69f5d46..e182b13 100644
--- a/src/bluetooth/bluetooth_util.h
+++ b/src/bluetooth/bluetooth_util.h
@@ -31,6 +31,8 @@ double GetAsyncCallbackHandle(const picojson::value& data);
const picojson::object& GetArguments(const picojson::value& data);
+common::PlatformResult BluetoothErrorToPlatformResult(int error_code,
+ const std::string& message = "");
common::PlatformResult GetBluetoothError(int error_code, const std::string& hint);
std::string GetBluetoothErrorMessage(int error_code);
--
2.7.4