[bluetooth] sync tizen_2.4 branch latest bluetooth source code.
authorjk.pu <jk.pu@samsung.com>
Mon, 19 Oct 2015 04:46:09 +0000 (13:46 +0900)
committerjk.pu <jk.pu@samsung.com>
Mon, 19 Oct 2015 04:47:06 +0000 (13:47 +0900)
Change-Id: Ie8983af019c0d0d39685763399b2aac64e2ffb8a
Signed-off-by: jk.pu <jk.pu@samsung.com>
17 files changed:
src/bluetooth/bluetooth_adapter.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_api.js [changed mode: 0755->0644]
src/bluetooth/bluetooth_device.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_gatt_service.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_gatt_service.h [changed mode: 0755->0644]
src/bluetooth/bluetooth_health_application.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_health_channel.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_health_profile_handler.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_instance.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_le_adapter.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_le_device.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_le_device.h [changed mode: 0755->0644]
src/bluetooth/bluetooth_service_handler.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_socket.cc [changed mode: 0755->0644]
src/bluetooth/bluetooth_util.h [changed mode: 0755->0644]
src/common/tools.cc
src/common/tools.h

old mode 100755 (executable)
new mode 100644 (file)
index 0151b84..6ff5fe8
 #include "bluetooth_internal.h"
 
 #include "common/converter.h"
+#include "common/extension.h"
 #include "common/logger.h"
 #include "common/platform_result.h"
-#include "common/extension.h"
 #include "common/task-queue.h"
+#include "common/tools.h"
 
 #include "bluetooth/bluetooth_class.h"
 #include "bluetooth/bluetooth_device.h"
@@ -300,7 +301,6 @@ void BluetoothAdapter::DiscoveryStateChangedCB(
 
           data_obj->insert(std::make_pair(kData, picojson::value(adapter->discovered_devices_)));
 
-          //TODO Consider if all events during scanning shouldn't be called asynchronously
           adapter->user_request_list_[DISCOVER_DEVICES] = false;
           adapter->instance_.FireEvent(kAdapterDiscoverSuccessEvent, value);
         }
@@ -347,6 +347,9 @@ BluetoothAdapter::BluetoothAdapter(BluetoothInstance& instance) :
     is_powered_(false),
     is_initialized_(false),
     user_request_list_(),
+    user_request_callback_(),
+    requested_powered_(),
+    requested_visibility_(),
     instance_(instance)
 {
   LoggerD("Entered");
@@ -542,34 +545,41 @@ void BluetoothAdapter::SetPowered(const picojson::value& data, picojson::object&
     }
 
     if (ret.IsSuccess()) {
-      const void* t_param[] = { this, &ret, &new_powered, &callback_handle };
+      struct UserData {
+        BluetoothAdapter* adapter;
+        double callback_handle;
+      };
+
+      UserData* user_data = new UserData{ this, callback_handle };
 
       err = app_control_send_launch_request(service, [](
               app_control_h request, app_control_h reply,
               app_control_result_e r, void* user_data) {
+        LoggerD("app_control_send_launch_request() callback");
 
-        BluetoothAdapter* self = static_cast<BluetoothAdapter*>(((void**) user_data)[0]);
-        PlatformResult* p_ret = static_cast<PlatformResult*>(((void**) user_data)[1]);
-        bool* p_new_powered = static_cast<bool*>(((void**) user_data)[2]);
-        double* p_callback_handle = static_cast<double*>(((void**) user_data)[3]);
+        UserData* data = static_cast<UserData*>(user_data);
 
         char* result = nullptr;
         app_control_get_extra_data(reply, "result", &result);
-        LoggerD("bt onoff: %s", result);
 
-        if (strcmp(result, "success") == 0) {
-          self->requested_powered_ = *p_new_powered;
-          self->user_request_list_[SET_POWERED] = true;
-          self->user_request_callback_[SET_POWERED] = *p_callback_handle;
+        if (result && strcmp(result, "success") == 0) {
+          LoggerD("bt onoff: %s", result);
+          free(result);
         } else {
           LoggerE("app control setPowered failed");
-          *p_ret = PlatformResult(ErrorCode::UNKNOWN_ERR, "app control setPowered failed");
+          data->adapter->instance_.AsyncResponse(data->callback_handle, PlatformResult(ErrorCode::UNKNOWN_ERR, "app control setPowered failed"));
         }
-      }, t_param);
+
+        delete data;
+      }, user_data);
 
       if (err != APP_CONTROL_ERROR_NONE) {
         LoggerE("app control set launch request failed: %d", err);
         ret = PlatformResult(ErrorCode::UNKNOWN_ERR, "app control set launch request failed");
+      } else {
+        this->requested_powered_ = new_powered;
+        this->user_request_list_[SET_POWERED] = true;
+        this->user_request_callback_[SET_POWERED] = callback_handle;
       }
     }
 
@@ -578,6 +588,10 @@ void BluetoothAdapter::SetPowered(const picojson::value& data, picojson::object&
       LoggerE("app control destroy failed: %d", err);
       ret = PlatformResult(ErrorCode::UNKNOWN_ERR, "app control destroy failed");
     }
+
+    if (!ret) {
+      instance_.AsyncResponse(callback_handle, ret);
+    }
 #else
     this->requested_powered_ = new_powered;
     this->user_request_list_[SET_POWERED] = true;
@@ -588,11 +602,10 @@ void BluetoothAdapter::SetPowered(const picojson::value& data, picojson::object&
     } else {
       bt_adapter_disable();
     }
-    return;
 #endif
+  } else {
+    instance_.AsyncResponse(callback_handle, ret);
   }
-
-  instance_.AsyncResponse(callback_handle, ret);
 }
 
 void BluetoothAdapter::SetVisible(const picojson::value& data, picojson::object& out) {
@@ -847,10 +860,12 @@ void BluetoothAdapter::GetKnownDevices(const picojson::value& data, picojson::ob
     instance_.SyncResponse(callback_handle, response);
   };
 
+  auto queue_data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
   TaskQueue::GetInstance().Queue<picojson::value>(
       get_known_devices,
       get_known_devices_response,
-      std::shared_ptr<picojson::value>(new picojson::value(picojson::object())));
+      queue_data);
 
   ReportSuccess(out);
 }
@@ -914,10 +929,12 @@ void BluetoothAdapter::GetDevice(const picojson::value& data, picojson::object&
     instance_.SyncResponse(callback_handle, response);
   };
 
+  auto queue_data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
   TaskQueue::GetInstance().Queue<picojson::value>(
       get_device,
       get_device_response,
-      std::shared_ptr<picojson::value>(new picojson::value(picojson::object())));
+      queue_data);
 
   ReportSuccess(out);
 }
@@ -1254,10 +1271,12 @@ void BluetoothAdapter::RegisterRFCOMMServiceByUUID(const picojson::value& data,
     instance_.SyncResponse(callback_handle, response);
   };
 
+  auto queue_data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
   TaskQueue::GetInstance().Queue<picojson::value>(
       rfcomm,
       rfcomm_response,
-      std::shared_ptr<picojson::value>(new picojson::value(picojson::object())));
+      queue_data);
 
   ReportSuccess(out);
 }
@@ -1280,9 +1299,9 @@ void BluetoothAdapter::UnregisterUUID(const std::string& uuid, int callback_hand
       }
     }
 
-    if (registered_uuids_.size() == 0 &&
-        connection_requests_.size() == 0 &&
-        connected_sockets_.size() == 0) {
+    if (registered_uuids_.empty() &&
+        connection_requests_.empty() &&
+        connected_sockets_.empty()) {
       bt_socket_unset_connection_state_changed_cb();
     }
   } else if (result.IsSuccess()){
@@ -1466,13 +1485,13 @@ void BluetoothAdapter::OnSocketConnected(
     return;
   }
 
-  if (object->connected_sockets_.size() == 0) {
+  if (object->connected_sockets_.empty()) {
     bt_socket_unset_data_received_cb();
   }
 
-  if (object->registered_uuids_.size() == 0 &&
-      object->connection_requests_.size() == 0 &&
-      object->connected_sockets_.size() == 0) {
+  if (object->registered_uuids_.empty() &&
+      object->connection_requests_.empty() &&
+      object->connected_sockets_.empty()) {
     bt_socket_unset_connection_state_changed_cb();
   }
 }
old mode 100755 (executable)
new mode 100644 (file)
index 55b53d6..36e8fbe
@@ -262,14 +262,7 @@ tizen.BluetoothLEAdvertiseData = function(dict) {
         return serviceData_;
       },
       set: function(v) {
-        if (T.isNull(v)) {
-          serviceData_ = v;
-        } else if (T.isArray(v)) {
-          for (var i = 0; i < v.length; ++i) {
-            if (!(v[i] instanceof tizen.BluetoothLEServiceData)) {
-              return;
-            }
-          }
+        if (T.isNull(v) || (v instanceof tizen.BluetoothLEServiceData)) {
           serviceData_ = v;
         }
       }
@@ -340,14 +333,7 @@ tizen.BluetoothLEAdvertiseData = function(dict) {
     }
 
     // serviceData
-    if (T.isNull(dict.serviceData)) {
-      o.serviceData = dict.serviceData;
-    } else if (T.isArray(dict.serviceData)) {
-      for (var i = 0; i < dict.serviceData.length; ++i) {
-        if (!(dict.serviceData[i] instanceof tizen.BluetoothLEServiceData)) {
-          return;
-        }
-      }
+    if (T.isNull(dict.serviceData) || dict.serviceData instanceof tizen.BluetoothLEServiceData) {
       o.serviceData = dict.serviceData;
     } else if (!T.isUndefined(dict.serviceData)) {
       return;
@@ -571,42 +557,48 @@ BluetoothSocket.prototype.close = function() {
 
 //class BluetoothLEDevice ////////////////////////////////////////////////////
 var BluetoothLEDevice = function(data) {
-
-    var address = "", name = "", txpowerLevel = null, appearance = null, uuids = [],
-        solicitationuuids = [], serviceData = [], manufacturerData = null;
+    var address = "", name = null, txpowerlevel = null, appearance = null, uuids = null,
+        solicitationuuids = null, serviceData = null, manufacturerData = null;
 
     if (data) {
-        address = data.address;
-        name = data.name;
-        txpowerLevel = data.txpowerLevel;
-        appearance = data.appearance;
-        uuids = data.uuids;
-        solicitationuuids = data.solicitationuuids;
+      address = data.address;
+      name = data.name || null;
+      txpowerlevel = data.txpowerlevel || null;
+      appearance = data.appearance || null;
+      uuids = data.uuids || null;
+      solicitationuuids = data.solicitationuuids || null;
+      if (data.serviceData) {
         data.serviceData.forEach(function(d) {
             serviceData.push(new tizen.BluetoothLEServiceData(d));
         });
+      }
+      if (data.manufacturerData) {
         manufacturerData = new tizen.BluetoothLEManufacturerData(data.manufacturerData);
+      }
     }
 
     Object.defineProperties(this, {
         address : {value: address, writable: false, enumerable: true},
         name : {value: name, writable: false, enumerable: true},
-        txpowerLevel : {value: txpowerLevel, writable: false, enumerable: true},
+        txpowerlevel : {value: txpowerlevel, writable: false, enumerable: true},
         appearance : {value: appearance, writable: false, enumerable: true},
         uuids : {
             enumerable: true,
             set : function(){},
-            get : function(){ return uuids.slice(); }
+            get : function(){
+              var service_uuids = uuids ? uuids.slice() : null;
+              return service_uuids;
+            }
         },
         solicitationuuids : {
             enumerable: true,
             set : function(){},
-            get : function(){ return solicitationuuids.slice(); }
+            get : function(){ return solicitationuuids ? solicitationuuids.slice() : null; }
         },
         serviceData : {
             enumerable: true,
             set : function(){},
-            get : function(){ return serviceData.slice(); }
+            get : function(){ return serviceData ? serviceData.slice() : null; }
         },
         manufacturerData : {
             value: manufacturerData,
@@ -641,7 +633,7 @@ BluetoothLEDevice.prototype.connect = function() {
             native.callIfPossible(args.successCallback);
         }
     };
-
+    // Errors are handled by error callback
     native.call('BluetoothLEDevice_connect', {address : this.address}, callback);
 };
 
@@ -663,7 +655,7 @@ BluetoothLEDevice.prototype.disconnect = function() {
             nullable : true
         }
     ]);
-     var callback = function(result) {
+    var callback = function(result) {
         if (native.isFailure(result)) {
             native.callIfPossible(args.errorCallback, native.getErrorObject(result));
         } else {
@@ -671,7 +663,10 @@ BluetoothLEDevice.prototype.disconnect = function() {
         }
     };
 
-    native.call('BluetoothLEDevice_disconnect', {address : this.address}, callback);
+    var result = native.call('BluetoothLEDevice_disconnect', {address : this.address}, callback);
+    if (native.isFailure(result)) {
+        throw native.getErrorObject(result);
+    }
 };
 
 BluetoothLEDevice.prototype.getService = function() {
@@ -696,7 +691,7 @@ BluetoothLEDevice.prototype.getService = function() {
     if (native.isFailure(result)) {
         throw native.getErrorObject(result);
     } else {
-        return BluetoothGATTService(native.getResultObject(result));
+        return new BluetoothGATTService(native.getResultObject(result));
     }
 };
 
@@ -834,8 +829,8 @@ BluetoothDevice.prototype.connectToServiceByUUID = function() {
         }
     };
 
-    // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // The native function BluetoothDevice_connectToServiceByUUID always returns success
+    // Errors are handled by error callback
     native.call('BluetoothDevice_connectToServiceByUUID', callArgs, callback);
 };
 
@@ -935,7 +930,7 @@ BluetoothServiceHandler.prototype.unregister = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothServiceHandler_unregister', callArgs, callback);
 
     _bluetoothServiceListeners.removeListener(this.uuid);
@@ -1030,7 +1025,7 @@ BluetoothHealthApplication.prototype.unregister = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothHealthApplication_unregister', callArgs, callback);
 
     _bluetoothHealthApplicationListeners.removeListener(this._id);
@@ -1097,7 +1092,7 @@ BluetoothHealthProfileHandler.prototype.registerSinkApplication = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothHealthProfileHandler_registerSinkApp', callArgs, callback);
 };
 
@@ -1145,7 +1140,7 @@ BluetoothHealthProfileHandler.prototype.connectToSource = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothHealthProfileHandler_connectToSource', callArgs, callback);
 };
 
@@ -1482,12 +1477,10 @@ BluetoothLEAdapter.prototype.stopAdvertise = function() {
 
   xwalk.utils.checkPrivilegeAccess4Ver("2.4", Privilege.BLUETOOTH, Privilege.BLUETOOTH_ADMIN);
 
-  // TODO: when should we call _bleAdvertiseListener.removeListener()?
-
+  _bleAdvertiseListener.removeListener();
   var result = native.callSync('BluetoothLEAdapter_stopAdvertise', {});
 
   if (native.isFailure(result)) {
-    _bleAdvertiseListener.removeListener();
     throw native.getErrorObject(result);
   }
 };
@@ -1501,7 +1494,7 @@ var BluetoothGATTService = function(data, address) {
     function servicesGetter() {
         var services = [];
         var result = native.callSync('BluetoothGATTService_getServices',
-                {handle: handle_, uuid: uuid_, address : address_});
+                {handle: handle_, address : address_});
         if (native.isSuccess(result)) {
             var resultObject = native.getResultObject(result);
             resultObject.forEach(function(s) {
@@ -1529,6 +1522,15 @@ var BluetoothGATTService = function(data, address) {
     });
 };
 
+var toByteArray = function(array) {
+    var d = [];
+
+    array.forEach(function(b) {
+        d.push(Converter.toOctet(b));
+    });
+    return d;
+};
+
 //class BluetoothGATTCharacteristic ////////////////////////////////////////////////////
 var BluetoothGATTCharacteristic = function(data, address) {
   var handle_ = data.handle;
@@ -1633,16 +1635,7 @@ var BluetoothGATTCharacteristic = function(data, address) {
     }
   });
 
-  var toByteArray = function(array) {
-      var d = [];
-
-      array.forEach(function(b) {
-          d.push(Converter.toOctet(b));
-      });
-      return d;
-  };
-
-  BluetoothGATTCharacteristic.prototype.readValue = function() {
+  this.readValue = function() {
       console.log('Entered BluetoothGATTCharacteristic.readValue()');
 
       xwalk.utils.checkPrivilegeAccess4Ver("2.4", Privilege.BLUETOOTH, Privilege.BLUETOOTH_ADMIN);
@@ -1675,7 +1668,7 @@ var BluetoothGATTCharacteristic = function(data, address) {
       }
     };
 
-    BluetoothGATTCharacteristic.prototype.writeValue = function() {
+    this.writeValue = function() {
       console.log('Entered BluetoothGATTCharacteristic.writeValue()');
 
       xwalk.utils.checkPrivilegeAccess4Ver("2.4", Privilege.BLUETOOTH, Privilege.BLUETOOTH_ADMIN);
@@ -1713,7 +1706,7 @@ var BluetoothGATTCharacteristic = function(data, address) {
       }
     };
 
-  BluetoothGATTCharacteristic.prototype.addValueChangeListener = function() {
+  this.addValueChangeListener = function() {
     console.log('Entered BluetoothGATTCharacteristic.addValueChangeListener()');
 
     xwalk.utils.checkPrivilegeAccess4Ver("2.4", Privilege.BLUETOOTH, Privilege.BLUETOOTH_ADMIN);
@@ -1734,7 +1727,7 @@ var BluetoothGATTCharacteristic = function(data, address) {
     return _bluetoothGATTCharacteristicListener.addListener(callback, callArgs);
   };
 
-  BluetoothGATTCharacteristic.prototype.removeValueChangeListener = function() {
+  this.removeValueChangeListener = function() {
     console.log('Entered BluetoothGATTCharacteristic.removeValueChangeListener()');
 
     var args = AV.validateMethod(arguments, [{
@@ -1855,12 +1848,12 @@ var _bleConnectChangeListener = _multipleListenerBuilder(
 );
 
 //class BluetoothGATTDescriptor ////////////////////////////////////////////////////
-var BluetoothGATTDescriptor = function(address) {
+var BluetoothGATTDescriptor = function(data, address) {
   var handle_ = data.handle;
   //address_ is needed to control if device is still connected
   var address_ = address;
 
-  BluetoothGATTDescriptor.prototype.readValue = function() {
+  this.readValue = function() {
     console.log('Entered BluetoothGATTDescriptor.readValue()');
 
     xwalk.utils.checkPrivilegeAccess4Ver("2.4", Privilege.BLUETOOTH, Privilege.BLUETOOTH_ADMIN);
@@ -1893,7 +1886,7 @@ var BluetoothGATTDescriptor = function(address) {
     }
   };
 
-  BluetoothGATTDescriptor.prototype.writeValue = function() {
+  this.writeValue = function() {
     console.log('Entered BluetoothGATTDescriptor.writeValue()');
 
     xwalk.utils.checkPrivilegeAccess4Ver("2.4", Privilege.BLUETOOTH, Privilege.BLUETOOTH_ADMIN);
@@ -2036,7 +2029,7 @@ BluetoothAdapter.prototype.setName = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_setName', callArgs, callback);
 };
 
@@ -2076,7 +2069,7 @@ BluetoothAdapter.prototype.setPowered = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_setPowered', callArgs, callback);
 };
 
@@ -2132,7 +2125,7 @@ BluetoothAdapter.prototype.setVisible = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_setVisible', callArgs, callback);
 };
 
@@ -2305,7 +2298,7 @@ BluetoothAdapter.prototype.stopDiscovery = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_stopDiscovery', {}, callback);
 };
 
@@ -2340,7 +2333,7 @@ BluetoothAdapter.prototype.getKnownDevices = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_getKnownDevices', {}, callback);
 };
 
@@ -2374,7 +2367,7 @@ BluetoothAdapter.prototype.getDevice = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_getDevice', {address : args.address}, callback);
 };
 
@@ -2414,7 +2407,7 @@ BluetoothAdapter.prototype.createBonding = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_createBonding', callArgs, callback);
 };
 
@@ -2454,7 +2447,7 @@ BluetoothAdapter.prototype.destroyBonding = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_destroyBonding', callArgs, callback);
 };
 
@@ -2499,7 +2492,7 @@ BluetoothAdapter.prototype.registerRFCOMMServiceByUUID = function() {
     };
 
     // native.call does not inform if call results in failure
-    // TODO: what to do in this case?
+    // Errors are handled by error callback
     native.call('BluetoothAdapter_registerRFCOMMServiceByUUID', callArgs, callback);
 };
 
old mode 100755 (executable)
new mode 100644 (file)
index 9d9a809..5315d39
@@ -17,8 +17,9 @@
 #include "bluetooth_device.h"
 
 #include "common/converter.h"
-#include "common/logger.h"
 #include "common/extension.h"
+#include "common/logger.h"
+#include "common/tools.h"
 
 #include "bluetooth_adapter.h"
 #include "bluetooth_class.h"
old mode 100755 (executable)
new mode 100644 (file)
index d4c29e5..293c0f0
 
 #include <sstream>
 
+#include "common/extension.h"
 #include "common/logger.h"
 #include "common/platform_result.h"
-#include "common/extension.h"
 #include "common/task-queue.h"
+#include "common/tools.h"
 
 #include "bluetooth/bluetooth_instance.h"
 #include "bluetooth/bluetooth_util.h"
@@ -52,7 +53,7 @@ const std::string kWriteNoResponse = "isWriteNoResponse";
 const std::string kOnValueChanged = "BluetoothGATTCharacteristicValueChangeListener";
 
 bool IsProperty (int propertyBits, bt_gatt_property_e property) {
-  return (propertyBits & property) == 0;
+  return (propertyBits & property) != 0;
 }
 }
 
@@ -65,9 +66,12 @@ BluetoothGATTService::BluetoothGATTService(BluetoothInstance& instance) :
 BluetoothGATTService::~BluetoothGATTService() {
   LoggerD("Entered");
 
-  for (auto it : gatt_clients_) {
+  for (auto it : gatt_characteristic_) {
     // unregister callback, ignore errors
-    bt_gatt_client_unset_characteristic_value_changed_cb(it.second);
+    bt_gatt_client_unset_characteristic_value_changed_cb(it);
+  }
+
+  for (auto it : gatt_clients_) {
     LoggerD("destroying client for address: %s", it.first.c_str());
     bt_gatt_client_destroy(it.second);
   }
@@ -78,6 +82,28 @@ bool BluetoothGATTService::IsStillConnected(const std::string& address) {
   return gatt_clients_.end() != it;
 }
 
+bt_gatt_client_h BluetoothGATTService::GetGattClient(const std::string& address) {
+  LoggerD("Entered");
+
+  bt_gatt_client_h client = nullptr;
+
+  const auto it = gatt_clients_.find(address);
+
+  if (gatt_clients_.end() == it) {
+    int ret = bt_gatt_client_create(address.c_str(), &client);
+    if (BT_ERROR_NONE != ret) {
+      LoggerE("Failed to create GATT client, error: %d", ret);
+    } else {
+      gatt_clients_.insert(std::make_pair(address, client));
+    }
+  } else {
+    LoggerD("Client already created");
+    client = it->second;
+  }
+
+  return client;
+}
+
 // this method should be used to inform this object that some device was disconnected
 void BluetoothGATTService::TryDestroyClient(const std::string &address) {
   auto it = gatt_clients_.find(address);
@@ -96,26 +122,26 @@ PlatformResult BluetoothGATTService::GetSpecifiedGATTService(const std::string &
                                                              picojson::object* result) {
   LoggerD("Entered");
 
-  bt_gatt_client_h client = nullptr;
-  auto it = gatt_clients_.find(address);
-  int ret = BT_ERROR_NONE;
-  if (gatt_clients_.end() == it) {
-    ret = bt_gatt_client_create(address.c_str(), &client);
-    if (BT_ERROR_NONE != ret) {
-      LoggerE("%d", ret);
-      return util::GetBluetoothError(ret, "Failed to create the GATT client's handle");
-    }
-    gatt_clients_.insert(std::make_pair(address, client));
-  } else {
-    LoggerD("Client already created");
-    client = it->second;
+  bt_gatt_client_h client = GetGattClient(address);
+
+  if (nullptr == client) {
+    return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to create the GATT client's handle");
   }
 
   bt_gatt_h service = nullptr;
-  ret = bt_gatt_client_get_service(client, uuid.c_str(), &service);
+  int ret = bt_gatt_client_get_service(client, uuid.c_str(), &service);
   if (BT_ERROR_NONE != ret) {
-    LoggerE("%d", ret);
-    return util::GetBluetoothError(ret, "Failed to get a service's GATT handle");
+    LoggerE("bt_gatt_client_get_service() error: %d", ret);
+    switch (ret) {
+      case BT_ERROR_NO_DATA:
+        return PlatformResult(ErrorCode::NOT_FOUND_ERR, "Service not found");
+
+      case BT_ERROR_INVALID_PARAMETER:
+        return PlatformResult(ErrorCode::NOT_FOUND_ERR, "Service UUID is invalid");
+
+      default:
+        return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get a service's GATT handle");
+    }
   }
 
   //report BluetoothGattService
@@ -132,11 +158,10 @@ void BluetoothGATTService::GetServices(const picojson::value& args,
   LoggerD("Entered");
 
   bt_gatt_h handle = (bt_gatt_h) static_cast<long>(args.get("handle").get<double>());
-  const std::string& uuid = args.get("uuid").get<std::string>();
   const std::string& address = args.get("address").get<std::string>();
 
   picojson::array array;
-  PlatformResult ret = GetServicesHelper(handle, address, uuid, &array);
+  PlatformResult ret = GetServicesHelper(handle, address, &array);
   if (ret.IsError()) {
     LoggerE("Error while getting services");
     ReportError(ret, &out);
@@ -147,7 +172,6 @@ void BluetoothGATTService::GetServices(const picojson::value& args,
 
 PlatformResult BluetoothGATTService::GetServicesHelper(bt_gatt_h handle,
                                                        const std::string& address,
-                                                       const std::string& uuid,
                                                        picojson::array* array) {
   LoggerD("Entered");
 
@@ -157,27 +181,28 @@ PlatformResult BluetoothGATTService::GetServicesHelper(bt_gatt_h handle,
                           "Device is not connected");
   }
 
-  struct Data {
-    const std::string& uuid;
-    picojson::array* array;
-  };
-  Data user_data {uuid, array};
-
   int ret = bt_gatt_service_foreach_included_services(
       handle,
       [](int total, int index, bt_gatt_h gatt_handle, void *data) {
         LoggerD("Enter");
-        Data user_data = *(static_cast<Data*>(data));
 
         picojson::value result = picojson::value(picojson::object());
         picojson::object& result_obj = result.get<picojson::object>();
 
-        result_obj.insert(std::make_pair(kUuid, picojson::value(user_data.uuid)));
+        char* uuid = nullptr;
+
+        if (BT_ERROR_NONE == bt_gatt_get_uuid(gatt_handle, &uuid) && nullptr != uuid) {
+          result_obj.insert(std::make_pair(kUuid, picojson::value(uuid)));
+          free(uuid);
+        } else {
+          result_obj.insert(std::make_pair(kUuid, picojson::value("FFFF")));
+        }
+
         //handle is passed to upper layer because there is no need of deletion
         result_obj.insert(std::make_pair(kHandle, picojson::value((double)(long)gatt_handle)));
-        user_data.array->push_back(result);
+        static_cast<picojson::array*>(data)->push_back(result);
         return true;
-      }, static_cast<void*>(&user_data));
+      }, array);
   if (BT_ERROR_NONE != ret) {
     LoggerE("Failed bt_gatt_service_foreach_included_services() (%d)", ret);
     return util::GetBluetoothError(ret, "Failed to set a service's GATT callback");
@@ -322,7 +347,7 @@ void BluetoothGATTService::ReadValue(const picojson::value& args,
   bt_gatt_h handle = (bt_gatt_h) static_cast<long>(args.get("handle").get<double>());
 
   auto read_value = [](int result, bt_gatt_h handle, void *user_data) -> void {
-    Data* data = (Data*) user_data;
+    Data* data = static_cast<Data*>(user_data);
     double callback_handle = data->callback_handle;
     BluetoothGATTService* service = data->service;
     delete data;
@@ -464,6 +489,7 @@ void BluetoothGATTService::AddValueChangeListener(const picojson::value& args,
     LoggerE("bt_gatt_client_set_characteristic_value_changed_cb() failed with: %d", ret);
     ReportError(util::GetBluetoothError(ret, "Failed to register listener"), &out);
   } else {
+    gatt_characteristic_.push_back(handle);
     ReportSuccess(out);
   }
 }
@@ -487,10 +513,51 @@ void BluetoothGATTService::RemoveValueChangeListener(
     LoggerE("bt_gatt_client_unset_characteristic_value_changed_cb() failed with: %d", ret);
     ReportError(util::GetBluetoothError(ret, "Failed to unregister listener"), &out);
   } else {
+    gatt_characteristic_.erase(std::remove(gatt_characteristic_.begin(), gatt_characteristic_.end(), handle), gatt_characteristic_.end());
     ReportSuccess(out);
   }
 }
 
+common::PlatformResult BluetoothGATTService::GetServiceUuids(
+    const std::string& address, picojson::array* array) {
+  LoggerD("Entered");
+
+  bt_gatt_client_h client = GetGattClient(address);
+
+  if (nullptr == client) {
+    return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unable to create client");
+  }
+
+  auto foreach_callback = [](int total, int index, bt_gatt_h gatt_handle, void* user_data) -> bool {
+    LoggerD("Entered foreach_callback, total: %d, index: %d", total, index);
+
+    char* uuid = nullptr;
+    int ret = bt_gatt_get_uuid(gatt_handle, &uuid);
+
+    if (BT_ERROR_NONE != ret || nullptr == uuid) {
+      LoggerE("Failed to get UUID: %d", ret);
+    } else {
+      std::string u = std::string(uuid);
+      free(uuid);
+      if (u.length() > 4) {  // 128-bit UUID, needs to be converted to 16-bit
+        u = u.substr(4, 4);
+      }
+      static_cast<picojson::array*>(user_data)->push_back(picojson::value(u));
+    }
+
+    return true;
+  };
+
+  int ret = bt_gatt_client_foreach_services(client, foreach_callback, array);
+
+  if (BT_ERROR_NONE == ret) {
+    return PlatformResult(ErrorCode::NO_ERROR);
+  } else {
+    LoggerE("Failed to get UUIDS: %d", ret);
+    return util::GetBluetoothError(ret, "Failed to get UUIDS");
+  }
+}
+
 void BluetoothGATTService::OnCharacteristicValueChanged(
     bt_gatt_h characteristic, char* value, int length, void* user_data) {
   LoggerD("Entered, characteristic: [%p], len: [d], user_data: [%p]", characteristic, length, user_data);
old mode 100755 (executable)
new mode 100644 (file)
index 9e59c8b..7fc8f2d
@@ -48,10 +48,15 @@ class BluetoothGATTService {
   void RemoveValueChangeListener(const picojson::value& args,
                                  picojson::object& out);
 
+  common::PlatformResult GetServiceUuids(const std::string& address,
+                                         picojson::array* array);
+
  private:
   bool IsStillConnected(const std::string& address);
+
+  bt_gatt_client_h GetGattClient(const std::string& address);
+
   common::PlatformResult GetServicesHelper(bt_gatt_h handle, const std::string& address,
-                                                  const std::string& uuid,
                                                   picojson::array* array);
   common::PlatformResult GetCharacteristicsHelper(bt_gatt_h handle,
                                                   const std::string& address,
@@ -63,6 +68,7 @@ class BluetoothGATTService {
                                            void* user_data);
 
   std::map<std::string, bt_gatt_client_h> gatt_clients_;
+  std::vector<bt_gatt_h> gatt_characteristic_;
 
   BluetoothInstance& instance_;
 };
old mode 100755 (executable)
new mode 100644 (file)
index 4670815..457e5d5
@@ -17,8 +17,9 @@
 #include "bluetooth_health_application.h"
 
 #include "common/converter.h"
-#include "common/logger.h"
 #include "common/extension.h"
+#include "common/logger.h"
+#include "common/tools.h"
 
 #include "bluetooth_health_profile_handler.h"
 #include "bluetooth_util.h"
old mode 100755 (executable)
new mode 100644 (file)
index 3825d32..1209021
@@ -19,8 +19,9 @@
 #include <memory>
 
 #include "common/converter.h"
-#include "common/logger.h"
 #include "common/extension.h"
+#include "common/logger.h"
+#include "common/tools.h"
 
 #include "bluetooth_device.h"
 #include "bluetooth_util.h"
old mode 100755 (executable)
new mode 100644 (file)
index 6a788ba..1f0432d
 #include "bluetooth_health_profile_handler.h"
 
 #include "common/converter.h"
-#include "common/logger.h"
 #include "common/extension.h"
+#include "common/logger.h"
 #include "common/task-queue.h"
+#include "common/tools.h"
 
 #include "bluetooth/bluetooth_adapter.h"
 #include "bluetooth/bluetooth_instance.h"
@@ -275,10 +276,12 @@ void BluetoothHealthProfileHandler::RegisterSinkApp(const picojson::value& data,
     instance_.SyncResponse(callback_handle, response);
   };
 
+  auto queue_data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
   TaskQueue::GetInstance().Queue<picojson::value>(
       register_app,
       register_app_response,
-      std::shared_ptr<picojson::value>(new picojson::value(picojson::object())));
+      queue_data);
 
   ReportSuccess(out);
 }
@@ -374,10 +377,12 @@ void BluetoothHealthProfileHandler::UnregisterSinkAppAsync(const std::string& ap
     instance_.SyncResponse(callback_handle, response);
   };
 
+  auto data = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+
   TaskQueue::GetInstance().Queue<picojson::value>(
       unregister_app,
       unregister_app_response,
-      std::shared_ptr<picojson::value>(new picojson::value(picojson::object())));
+      data);
 }
 
 } // namespace bluetooth
old mode 100755 (executable)
new mode 100644 (file)
index f1b7a1d..c919693
@@ -19,6 +19,7 @@
 #include "common/converter.h"
 #include "common/logger.h"
 #include "common/task-queue.h"
+#include "common/tools.h"
 
 namespace extension {
 namespace bluetooth {
@@ -141,6 +142,10 @@ BluetoothInstance::BluetoothInstance() :
       "BluetoothLEDevice_removeConnectStateChangeListener",
       std::bind(&BluetoothLEDevice::RemoveConnectStateChangeListener,
                 &bluetooth_le_device_, _1, _2));
+  REGISTER_SYNC(
+        "BluetoothLEDevice_getServiceUuids",
+        std::bind(&BluetoothLEDevice::GetServiceUuids,
+                  &bluetooth_le_device_, _1, _2));
 
   // BluetoothGATTService
   REGISTER_SYNC("BluetoothGATTService_getServices",
@@ -201,14 +206,14 @@ void BluetoothInstance::SyncResponse(double callback_handle, const std::shared_p
   LoggerD("Entered");
   auto& obj = response->get<picojson::object>();
   obj[JSON_CALLBACK_ID] = picojson::value(callback_handle);
-  PostMessage(response->serialize().c_str());
+  Instance::PostMessage(this, response->serialize().c_str());
 }
 
 void BluetoothInstance::FireEvent(const std::string& event, picojson::value& value) {
   LoggerD("Entered");
   auto& obj = value.get<picojson::object>();
   obj[JSON_LISTENER_ID] = picojson::value(event);
-  PostMessage(value.serialize().c_str());
+  Instance::PostMessage(this, value.serialize().c_str());
 }
 
 void BluetoothInstance::FireEvent(const std::string& event, const picojson::value& value) {
old mode 100755 (executable)
new mode 100644 (file)
index 7b33332..f2c232d
@@ -16,6 +16,7 @@
 
 #include "bluetooth/bluetooth_le_adapter.h"
 
+#include "common/tools.h"
 #include "common/logger.h"
 
 #include "bluetooth/bluetooth_instance.h"
@@ -106,17 +107,23 @@ class BluetoothLEServiceData : public ParsedDataHolder {
 class BluetoothLEManufacturerData : public ParsedDataHolder {
  public:
   BluetoothLEManufacturerData()
-      : ParsedDataHolder() {
+      : ParsedDataHolder(),
+        data_(nullptr),
+        data_length_(0) {
   }
 
   const std::string& id() const {
     return id_;
   }
 
-  const std::string& data() const {
+  const unsigned char* const data() const {
     return data_;
   }
 
+  const int data_length() const {
+    return data_length_;
+  }
+
   static bool Construct(const picojson::value& obj,
                         BluetoothLEManufacturerData* out) {
     LoggerD("Entered");
@@ -131,6 +138,14 @@ class BluetoothLEManufacturerData : public ParsedDataHolder {
     return true;
   }
 
+  ~BluetoothLEManufacturerData() {
+    if (data_) {
+      delete [] data_;
+      data_ = nullptr;
+      data_length_ = 0;
+    }
+  }
+
  private:
   static bool ParseId(const picojson::value& obj,
                       BluetoothLEManufacturerData* out) {
@@ -148,18 +163,29 @@ class BluetoothLEManufacturerData : public ParsedDataHolder {
   static bool ParseData(const picojson::value& obj,
                         BluetoothLEManufacturerData* out) {
     LoggerD("Entered");
-    const auto& data = obj.get("data");
-    if (data.is<std::string>()) {
-      out->data_ = data.get<std::string>();
+
+    const auto& val_data = obj.get("data");
+
+    if (val_data.is<std::string>()) {
+      const std::string& str_data = val_data.get<std::string>();
+      const char* p_data = str_data.c_str();
+      int size = str_data.length();
+      if (size > 2 && (str_data.find("0x", 0) == 0 || str_data.find("0X", 0) == 0)) {
+        p_data += 2;
+        size -= 2;
+      }
+      out->data_length_ = size / 2;
+      out->data_ = new unsigned char[out->data_length_];
+      common::tools::HexToBin(p_data, size, out->data_, out->data_length_);
+      return true;
     } else {
       return false;
     }
-
-    return true;
   }
 
   std::string id_;
-  std::string data_;
+  unsigned char* data_;
+  int data_length_;
 };
 
 class BluetoothLEAdvertiseData : public ParsedDataHolder {
@@ -568,15 +594,15 @@ void BluetoothLEAdapter::StartAdvertise(const picojson::value& data, picojson::o
   }
 
   const auto& manufacturer_data = advertise_data.manufacturer_data();
-  if (manufacturer_data.id().empty() && manufacturer_data.data().empty()) {
+  if (manufacturer_data.id().empty() && manufacturer_data.data() == nullptr) {
     LoggerD("manufacturerData is empty");
   } else {
-      if (manufacturer_data.valid()) {
+    if (manufacturer_data.valid()) {
       ret = bt_adapter_le_add_advertising_manufacturer_data(advertiser,
                                                             packet_type,
                                                             atoi(manufacturer_data.id().c_str()),
-                                                            manufacturer_data.data().c_str(),
-                                                            manufacturer_data.data().length());
+                                                            (const char*)manufacturer_data.data(),
+                                                            manufacturer_data.data_length());
       if (BT_ERROR_NONE != ret) {
         LoggerE("bt_adapter_le_add_advertising_manufacturer_data() failed with: %d", ret);
         ReportError(util::GetBluetoothError(ret, "Failed to create advertiser"), &out);
@@ -678,7 +704,7 @@ void BluetoothLEAdapter::OnScanResult(
     ReportError(util::GetBluetoothError(result, "Error during scanning"), data_obj);
     data_obj->insert(std::make_pair(kAction, picojson::value(kOnScanError)));
   } else {
-    // TODO: this is probably capi-network-bluetooth error: when scan is stopped info has 0x1 value
+    // this is probably capi-network-bluetooth error: when scan is stopped info has 0x1 value
     if (nullptr != info && reinterpret_cast<void*>(0x1) != info) {
       // device found
       LoggerD("Device found");
old mode 100755 (executable)
new mode 100644 (file)
index 0551dcf..dcb429b
 
 #include "common/converter.h"
 #include "common/logger.h"
+#include "common/tools.h"
 
 using common::ErrorCode;
 using common::PlatformResult;
 using common::tools::ReportError;
 using common::tools::ReportSuccess;
+using common::tools::BinToHex;
 
 namespace extension {
 namespace bluetooth {
@@ -35,7 +37,7 @@ namespace {
 //le_device
 const std::string kDeviceName = "name";
 const std::string kDeviceAddress = "address";
-const std::string kTxPowerLevel = "txpowerLevel";
+const std::string kTxPowerLevel = "txpowerlevel";
 const std::string kAppearance = "appearance";
 const std::string kDeviceUuids = "uuids";
 const std::string kSolicitationUuids = "solicitationuuids";
@@ -107,7 +109,8 @@ static void ServiceDataToJson(bt_adapter_le_service_data_s *service_data_list,
   }
 }
 
-static void ManufacturerToJson(int manufacturer_id, char *manufacturer_data,
+static void ManufacturerToJson(int manufacturer_id,
+                               char *manufacturer_data,
                                int manufacturer_count,
                                picojson::object* le_device) {
   LoggerD("Entered");
@@ -115,8 +118,19 @@ static void ManufacturerToJson(int manufacturer_id, char *manufacturer_data,
   picojson::value response = picojson::value(picojson::object());
   picojson::object& response_obj = response.get<picojson::object>();
   response_obj[kId] = picojson::value(std::to_string(manufacturer_id));
-  response_obj[kData] = picojson::value(
-      std::string(manufacturer_data, manufacturer_count));
+
+  const int hex_count = manufacturer_count * 2;
+  char* manuf_data_hex = new char[hex_count + 1];
+  BinToHex((const unsigned char*) manufacturer_data,
+           manufacturer_count,
+           manuf_data_hex,
+           hex_count);
+  manuf_data_hex[hex_count] = '\0';
+  response_obj[kData] = picojson::value(std::string(manuf_data_hex));
+  delete [] manuf_data_hex;
+  manuf_data_hex = nullptr;
+
+  le_device->insert(std::make_pair(kManufacturerData, response));
 }
 
 PlatformResult BluetoothLEDevice::ToJson(
@@ -153,6 +167,7 @@ PlatformResult BluetoothLEDevice::ToJson(
 
     g_free(device_name);
   }
+
   int power_level = 0;
   found = false;
   for (size_t i = 0; i < types.size() && !found; ++i) {
@@ -167,9 +182,10 @@ PlatformResult BluetoothLEDevice::ToJson(
 
   if (found) {
     le_device->insert(
-      std::make_pair(kTxPowerLevel,
-                     picojson::value(static_cast<double>(power_level))));
+        std::make_pair(kTxPowerLevel,
+                       picojson::value(static_cast<double>(power_level))));
   }
+
   int appearance = 0;
   found = false;
   for (size_t i = 0; i < types.size() && !found; ++i) {
@@ -183,8 +199,8 @@ PlatformResult BluetoothLEDevice::ToJson(
 
   if (found) {
     le_device->insert(
-        std::make_pair(kAppearance,
-                       picojson::value(static_cast<double>(appearance))));
+          std::make_pair(kAppearance,
+                         picojson::value(static_cast<double>(appearance))));
   }
 
   char **uuids = nullptr;
@@ -251,7 +267,7 @@ PlatformResult BluetoothLEDevice::ToJson(
   if (found) {
     ServiceDataToJson(serviceDataList, service_data_list_count, le_device);
     ret = bt_adapter_le_free_service_data_list(serviceDataList,
-                                             service_data_list_count);
+                                               service_data_list_count);
     if (BT_ERROR_NONE != ret) {
       LoggerW("Failed to free service data list: %d", ret);
     }
@@ -279,6 +295,7 @@ PlatformResult BluetoothLEDevice::ToJson(
                        manufacturer_data_count, le_device);
     g_free(manufacturer_data);
   }
+
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
@@ -291,15 +308,27 @@ void BluetoothLEDevice::Connect(const picojson::value& data,
 
   const auto& address = common::FromJson<std::string>(args, "address");
 
-  int ret = bt_gatt_connect(address.c_str(), true);
+  bool connected = false;
+  int ret = bt_device_is_profile_connected(address.c_str(), BT_PROFILE_GATT, &connected);
   if (BT_ERROR_NONE != ret) {
-    instance_.AsyncResponse(
-        callback_handle,
-        PlatformResult(util::GetBluetoothError(ret, "Failed to connect.")));
+    instance_.AsyncResponse(callback_handle,
+                            PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to disconnect."));
     return;
   }
 
-  connecting_[address] = callback_handle;
+  if (connected) {
+      instance_.AsyncResponse(callback_handle,
+                              PlatformResult(ErrorCode::NO_ERROR));
+  } else {  // not connected yet
+    ret = bt_gatt_connect(address.c_str(), false);
+    if (BT_ERROR_NONE != ret) {
+      instance_.AsyncResponse(
+          callback_handle,
+          PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to connect."));
+      return;
+    }
+    connecting_[address] = callback_handle;
+  }
 
   ReportSuccess(out);
 }
@@ -310,14 +339,30 @@ void BluetoothLEDevice::Disconnect(const picojson::value& data,
 
   const auto callback_handle = util::GetAsyncCallbackHandle(data);
   const auto& args = util::GetArguments(data);
-
   const auto& address = common::FromJson<std::string>(args, "address");
 
-  int ret = bt_gatt_disconnect(address.c_str());
+  int ret = BT_ERROR_NONE;
+
+  bool connected = false;
+  ret = bt_device_is_profile_connected(address.c_str(), BT_PROFILE_GATT, &connected);
   if (BT_ERROR_NONE != ret) {
     instance_.AsyncResponse(
         callback_handle,
-        PlatformResult(util::GetBluetoothError(ret, "Failed to disconnect.")));
+        PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to disconnect."));
+    return;
+  }
+  if (!connected) {
+    ReportError(PlatformResult(ErrorCode::INVALID_STATE_ERR,
+                               "Bluetooth low energy device is not connected"),
+                &out);
+    return;
+  }
+
+  ret = bt_gatt_disconnect(address.c_str());
+  if (BT_ERROR_NONE != ret) {
+    instance_.AsyncResponse(
+        callback_handle,
+        PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to disconnect."));
     return;
   }
 
@@ -376,6 +421,25 @@ void BluetoothLEDevice::RemoveConnectStateChangeListener(
   ReportSuccess(out);
 }
 
+void BluetoothLEDevice::GetServiceUuids(const picojson::value& data,
+                                        picojson::object& out) {
+  LoggerD("Entered");
+
+  const auto& args = util::GetArguments(data);
+  const auto& address = common::FromJson<std::string>(args, "address");
+
+  picojson::value response = picojson::value(picojson::array());
+  picojson::array *data_obj = &response.get<picojson::array>();
+
+  PlatformResult result = service_.GetServiceUuids(address, data_obj);
+
+  if (result) {
+    ReportSuccess(response, out);
+  } else {
+    ReportError(result, &out);
+  }
+}
+
 void BluetoothLEDevice::GattConnectionState(int result, bool connected,
                                             const char* remote_address,
                                             void* user_data) {
old mode 100755 (executable)
new mode 100644 (file)
index fe5362e..f95cab0
@@ -47,6 +47,8 @@ class BluetoothLEDevice {
   void RemoveConnectStateChangeListener(const picojson::value& data,
                                         picojson::object& out);
 
+  void GetServiceUuids(const picojson::value& data, picojson::object& out);
+
   static common::PlatformResult ToJson(
       bt_adapter_le_device_scan_result_info_s* info,
       picojson::object* le_device);
old mode 100755 (executable)
new mode 100644 (file)
index f7b3040..d9b6e1e
@@ -17,8 +17,9 @@
 #include "bluetooth_service_handler.h"
 
 #include "common/converter.h"
-#include "common/logger.h"
 #include "common/extension.h"
+#include "common/logger.h"
+#include "common/tools.h"
 
 #include "bluetooth_adapter.h"
 #include "bluetooth_util.h"
old mode 100755 (executable)
new mode 100644 (file)
index 518223f..8f858bc
@@ -19,8 +19,9 @@
 #include <memory>
 
 #include "common/converter.h"
-#include "common/logger.h"
 #include "common/extension.h"
+#include "common/logger.h"
+#include "common/tools.h"
 
 #include "bluetooth_adapter.h"
 #include "bluetooth_device.h"
old mode 100755 (executable)
new mode 100644 (file)
index 2a48add..2673711
@@ -34,8 +34,8 @@ const picojson::object& GetArguments(const picojson::value& data);
 common::PlatformResult GetBluetoothError(int error_code, const std::string& hint);
 std::string GetBluetoothErrorMessage(int error_code);
 
-}  // namespace util
-}  // namespace bluetooth
-}  // namespace extension
+} // util
+} // bluetooth
+} // extension
 
 #endif // BLUETOOTH_BLUETOOTH_UTIL_H_
index 309c5818b69bec330694b21154a3daefe3ea6b76..24302f7caa02ec30596f5124a33ff2860f69161d 100644 (file)
@@ -285,5 +285,33 @@ std::string GetErrorString(int error_code) {
   return msg;
 }
 
+
+int HexToInt(char c) {
+  if (c >= '0' && c <= '9') {
+    return c - '0';
+  } else if (c >= 'A' && c <= 'Z') {
+    return c - 'A';
+  } else {
+    return c - 'a';
+  }
+}
+
+unsigned char* HexToBin(const char* hex, int size, unsigned char* bin, int bin_size) {
+  for (int i = 0; i < size - 1 && i / 2 < bin_size; i += 2) {
+    bin[i * 2] = HexToInt(hex[i]) << 4;
+    bin[i * 2] += HexToInt(hex[i + 1]);
+  }
+  return bin;
+}
+
+char* BinToHex(const unsigned char* bin, int size, char* hex, int hex_size) {
+  static const char * const digits = "0123456789ABCDEF";
+  for (int i = 0; i < size && i < hex_size / 2; i++) {
+    hex[i * 2] = digits[bin[i] >> 4];
+    hex[i * 2 + 1] = digits[bin[i] & 15];
+  }
+  return hex;
+}
+
 }  // namespace tools
 }  // namespace common
index 56b9a8af9ddb9bf0f9f90b723a227231713a4203..fcd986897abcce044d7b531192da2f52cad63783 100644 (file)
@@ -69,6 +69,10 @@ do { \
  */
 std::string GetErrorString(int error_code);
 
+int HexToInt(char c);
+unsigned char* HexToBin(const char* hex, int size, unsigned char* bin, int bin_size);
+char* BinToHex(const unsigned char* bin, int size, char* hex, int hex_size);
+
 }  // namespace tools
 }  // namespace common