From: Pawel Andruszkiewicz Date: Fri, 7 Aug 2015 09:36:05 +0000 (+0200) Subject: [Bluetooth] Added method to obtain service UUIDs for BLE devices. X-Git-Tag: submit/tizen/20151026.073646^2^2~213 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=83bc37af12fef36d0d6106c736b0dd3270799853;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Bluetooth] Added method to obtain service UUIDs for BLE devices. [Verification] Manually tested, proper 128bit UUIDs are obtained. Change-Id: I85d4aaed23799f03b9ec0bf16d6c434dbab57bad Signed-off-by: Pawel Andruszkiewicz --- diff --git a/src/bluetooth/bluetooth_api.js b/src/bluetooth/bluetooth_api.js index 08b6aa43..f352afac 100755 --- a/src/bluetooth/bluetooth_api.js +++ b/src/bluetooth/bluetooth_api.js @@ -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, diff --git a/src/bluetooth/bluetooth_gatt_service.cc b/src/bluetooth/bluetooth_gatt_service.cc index 738a87c6..24cfdaac 100755 --- a/src/bluetooth/bluetooth_gatt_service.cc +++ b/src/bluetooth/bluetooth_gatt_service.cc @@ -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(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); diff --git a/src/bluetooth/bluetooth_gatt_service.h b/src/bluetooth/bluetooth_gatt_service.h index 9e59c8be..7c493b0c 100755 --- a/src/bluetooth/bluetooth_gatt_service.h +++ b/src/bluetooth/bluetooth_gatt_service.h @@ -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); diff --git a/src/bluetooth/bluetooth_instance.cc b/src/bluetooth/bluetooth_instance.cc index f1b7a1db..fef33bbc 100755 --- a/src/bluetooth/bluetooth_instance.cc +++ b/src/bluetooth/bluetooth_instance.cc @@ -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", diff --git a/src/bluetooth/bluetooth_le_device.cc b/src/bluetooth/bluetooth_le_device.cc index 4e0fa0af..991cbfd1 100755 --- a/src/bluetooth/bluetooth_le_device.cc +++ b/src/bluetooth/bluetooth_le_device.cc @@ -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(args, "address"); + + picojson::value response = picojson::value(picojson::array()); + picojson::array *data_obj = &response.get(); + + 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) { diff --git a/src/bluetooth/bluetooth_le_device.h b/src/bluetooth/bluetooth_le_device.h index fe5362ec..f95cab04 100755 --- a/src/bluetooth/bluetooth_le_device.h +++ b/src/bluetooth/bluetooth_le_device.h @@ -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);