[Bluetooth] Added method to obtain service UUIDs for BLE devices.
authorPawel Andruszkiewicz <p.andruszkie@samsung.com>
Fri, 7 Aug 2015 09:36:05 +0000 (11:36 +0200)
committerPawel Andruszkiewicz <p.andruszkie@samsung.com>
Fri, 7 Aug 2015 09:50:56 +0000 (18:50 +0900)
[Verification] Manually tested, proper 128bit UUIDs are obtained.

Change-Id: I85d4aaed23799f03b9ec0bf16d6c434dbab57bad
Signed-off-by: Pawel Andruszkiewicz <p.andruszkie@samsung.com>
src/bluetooth/bluetooth_api.js
src/bluetooth/bluetooth_gatt_service.cc
src/bluetooth/bluetooth_gatt_service.h
src/bluetooth/bluetooth_instance.cc
src/bluetooth/bluetooth_le_device.cc
src/bluetooth/bluetooth_le_device.h

index 08b6aa43119bbd594b15225fa1810423e845e213..f352afac06093833cffff54a1a7a669a8e81bf4b 100755 (executable)
@@ -585,7 +585,14 @@ var BluetoothLEDevice = function(data) {
         uuids : {
             enumerable: true,
             set : function(){},
-            get : function(){ return uuids ? uuids.slice() : null; }
+            get : function(){
+              var service_uuids = uuids ? uuids.slice() : null;
+              var result = native.callSync('BluetoothLEDevice_getServiceUuids', {address : address});
+              if (native.isSuccess(result)) {
+                service_uuids = native.getResultObject(result);
+              }
+              return service_uuids;
+            }
         },
         solicitationuuids : {
             enumerable: true,
index 738a87c6fc1c6ff9e95108a3cb7fcb7b0df8be1e..24cfdaacb87c40db13cd901ff66b3670904a6210 100755 (executable)
@@ -78,6 +78,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,23 +118,14 @@ 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");
@@ -491,6 +504,42 @@ void BluetoothGATTService::RemoveValueChangeListener(
   }
 }
 
+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 {
+      static_cast<picojson::array*>(user_data)->push_back(picojson::value(uuid));
+      free(uuid);
+    }
+
+    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);
index 9e59c8be6f9ff7c8b88a15dbdebed4d02251be08..7c493b0cf16eb0e3e801cb8f5acf07b2e8271a16 100755 (executable)
@@ -48,8 +48,14 @@ 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);
index f1b7a1db8ab2320e2743bec5aa673e5674e9158a..fef33bbcb015cc3b6802587be3754a6715c44382 100755 (executable)
@@ -141,6 +141,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",
index 4e0fa0af845137fd586c062a01e4cf59a75f7ac3..991cbfd159d4281c647ddf60c7ce52adba566ecb 100755 (executable)
@@ -407,6 +407,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) {
index fe5362ecd580cee791eb0ec5927dd965d454d218..f95cab041bf6e468baaf5e61a9fe23c60b05920b 100755 (executable)
@@ -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);