[BluetoothLE] Add default values for missing LEDevice attributes.
authorPawel Andruszkiewicz <p.andruszkie@samsung.com>
Thu, 30 Jul 2015 14:23:40 +0000 (16:23 +0200)
committerAndrzej Popowski <a.popowski@samsung.com>
Mon, 3 Aug 2015 07:40:44 +0000 (09:40 +0200)
[Verification] Code compiles.

Change-Id: Ifb9acf4e7a054df7bb27e5c7c690c4afbd3e5d44
Signed-off-by: Pawel Andruszkiewicz <p.andruszkie@samsung.com>
src/bluetooth/bluetooth_api.js
src/bluetooth/bluetooth_le_adapter.cc
src/bluetooth/bluetooth_le_device.cc
src/common/tools.cc
src/common/tools.h

index 55b53d6..fac24d6 100755 (executable)
@@ -571,42 +571,45 @@ 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(){ return uuids ? uuids.slice() : null; }
         },
         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,
index 7b33332..ef4fb6a 100755 (executable)
@@ -16,6 +16,7 @@
 
 #include "bluetooth/bluetooth_le_adapter.h"
 
+#include "common/tools.h"
 #include "common/logger.h"
 
 #include "bluetooth/bluetooth_instance.h"
@@ -106,15 +107,21 @@ 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 {
-    return data_;
+  const char* const data() const {
+    return (const char*) data_;
+  }
+
+  const int data_length() const {
+    return data_length_;
   }
 
   static bool Construct(const picojson::value& obj,
@@ -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());
+                                                            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);
index 0551dcf..bcc22c4 100755 (executable)
 
 #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,16 @@ 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));
+
+  char manuf_data_hex[manufacturer_count * 2 + 1];
+  BinToHex((const unsigned char*) manufacturer_data,
+           manufacturer_count,
+           manuf_data_hex,
+           sizeof(manuf_data_hex) - 1);
+  manuf_data_hex[manufacturer_count * 2] = 0;
+  response_obj[kData] = picojson::value(std::string(manuf_data_hex));
+
+  le_device->insert(std::make_pair(kManufacturerData, response));
 }
 
 PlatformResult BluetoothLEDevice::ToJson(
@@ -147,12 +158,11 @@ PlatformResult BluetoothLEDevice::ToJson(
     }
   }
 
-  if (found) {
-    le_device->insert(
-        std::make_pair(kDeviceName, picojson::value(std::string(device_name))));
+  le_device->insert(
+      std::make_pair(kDeviceName, picojson::value(std::string(device_name))));
+
+  g_free(device_name);
 
-    g_free(device_name);
-  }
   int power_level = 0;
   found = false;
   for (size_t i = 0; i < types.size() && !found; ++i) {
@@ -165,11 +175,10 @@ PlatformResult BluetoothLEDevice::ToJson(
     }
   }
 
-  if (found) {
-    le_device->insert(
+  le_device->insert(
       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) {
@@ -181,11 +190,9 @@ PlatformResult BluetoothLEDevice::ToJson(
     }
   }
 
-  if (found) {
-    le_device->insert(
+  le_device->insert(
         std::make_pair(kAppearance,
                        picojson::value(static_cast<double>(appearance))));
-  }
 
   char **uuids = nullptr;
   int count = 0;
@@ -200,13 +207,11 @@ PlatformResult BluetoothLEDevice::ToJson(
     }
   }
 
-  if (found) {
-    UUIDsToJson(uuids, count, kDeviceUuids, le_device);
-    for (int i = 0; i < count; ++i) {
-      g_free(uuids[i]);
-    }
-    g_free(uuids);
+  UUIDsToJson(uuids, count, kDeviceUuids, le_device);
+  for (int i = 0; i < count; ++i) {
+    g_free(uuids[i]);
   }
+  g_free(uuids);
 
   char** service_solicitation_uuids = nullptr;
   int service_solicitation_uuids_count = 0;
@@ -224,14 +229,12 @@ PlatformResult BluetoothLEDevice::ToJson(
     }
   }
 
-  if (found) {
-    UUIDsToJson(service_solicitation_uuids, service_solicitation_uuids_count,
-                kSolicitationUuids, le_device);
-    for (int i = 0; i < service_solicitation_uuids_count; ++i) {
-      g_free(service_solicitation_uuids[i]);
-    }
-    g_free(service_solicitation_uuids);
+  UUIDsToJson(service_solicitation_uuids, service_solicitation_uuids_count,
+              kSolicitationUuids, le_device);
+  for (int i = 0; i < service_solicitation_uuids_count; ++i) {
+    g_free(service_solicitation_uuids[i]);
   }
+  g_free(service_solicitation_uuids);
 
   bt_adapter_le_service_data_s *serviceDataList = nullptr;
   int service_data_list_count = 0;
@@ -248,13 +251,11 @@ PlatformResult BluetoothLEDevice::ToJson(
     }
   }
 
-  if (found) {
-    ServiceDataToJson(serviceDataList, service_data_list_count, le_device);
-    ret = bt_adapter_le_free_service_data_list(serviceDataList,
+  ServiceDataToJson(serviceDataList, service_data_list_count, le_device);
+  ret = bt_adapter_le_free_service_data_list(serviceDataList,
                                              service_data_list_count);
-    if (BT_ERROR_NONE != ret) {
-      LoggerW("Failed to free service data list: %d", ret);
-    }
+  if (BT_ERROR_NONE != ret) {
+    LoggerW("Failed to free service data list: %d", ret);
   }
 
   int manufacturer_id = 0;
@@ -278,6 +279,8 @@ PlatformResult BluetoothLEDevice::ToJson(
     ManufacturerToJson(manufacturer_id, manufacturer_data,
                        manufacturer_data_count, le_device);
     g_free(manufacturer_data);
+  } else {
+    ManufacturerToJson(-1, "XX", 2, le_device);
   }
   return PlatformResult(ErrorCode::NO_ERROR);
 }
index cc06772..1271b7c 100644 (file)
@@ -282,5 +282,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 56b9a8a..fcd9868 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