From 07d31e324646e4ee044cd75569be8e9537d3bd9f Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Wed, 29 Jan 2020 15:38:38 +0100 Subject: [PATCH] [Bluetooth] Add or modify uuid fields of BLE GATT objects This commit adds uuid field to BluetoothGATTCharacteristic and BluetoothGATTDescriptor objects and serviceUuid to BluetoothGATTService. uuid values of BluetoothGATT{Characteristic, Descriptor} and BluetoothGATTService::serviceUuid default to null, if Web API implementation is unable to retrieve them from Native API. There are more UUID fields in Bluetooth API objects, but have not been made nullable. We expect values of BluetoothLEServiceData::uuid, BluetoothSocket::uuid, BluetoothServiceHandler::uuid fields to be valid, if the objects containing them are created successfully. Related ACR: TWDAPI-255 [Verification] tct-bluetooth-tizen-tests auto: 100%; manual Bluetooth04_BLE_wearable: 100% Change-Id: I4c7fe4e8b4507f07f58c0fb043081eb6d93c933c Signed-off-by: Pawel Wasowski --- src/bluetooth/bluetooth_api.js | 65 ++++++++++++++++++++------------- src/bluetooth/bluetooth_gatt_service.cc | 35 ++++++++++++++---- src/bluetooth/bluetooth_gatt_service.h | 2 +- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/bluetooth/bluetooth_api.js b/src/bluetooth/bluetooth_api.js index c1758a2..64428fc 100755 --- a/src/bluetooth/bluetooth_api.js +++ b/src/bluetooth/bluetooth_api.js @@ -1613,6 +1613,7 @@ BluetoothLEAdapter.prototype.stopAdvertise = function() { var BluetoothGATTService = function(data, address) { var handle_ = data.handle; var uuid_ = data.uuid; + var serviceUuid_ = data.serviceUuid; //address_ is needed to control if device is still connected var address_ = address || data.address; function servicesGetter() { @@ -1633,19 +1634,22 @@ var BluetoothGATTService = function(data, address) { var characteristics = []; var result = native.callSync('BluetoothGATTServiceGetCharacteristics', { handle: handle_, - uuid: uuid_, + uuid: serviceUuid_, address: address_ }); if (native.isSuccess(result)) { var resultObject = native.getResultObject(result); resultObject.forEach(function(c) { + if (!T.isNullOrUndefined(c)) { characteristics.push(new BluetoothGATTCharacteristic(c, address_)); + } }); } return characteristics; } Object.defineProperties(this, { uuid: { value: uuid_, writable: false, enumerable: true }, + serviceUuid: { value: serviceUuid_, writable: false, enumerable: true }, services: { enumerable: true, set: function() {}, get: servicesGetter }, characteristics: { enumerable: true, @@ -1666,32 +1670,23 @@ var toByteArray = function(array) { //class BluetoothGATTCharacteristic /////////////////////////// var BluetoothGATTCharacteristic = function(data, address) { - var handle_ = data.handle; - var descriptors_ = []; - var isBroadcast_ = false; - var hasExtendedProperties_ = false; - var isNotify_ = false; - var isIndication_ = false; - var isReadable_ = false; - var isSignedWrite_ = false; - var isWritable_ = false; - var isWriteNoResponse_ = false; - //address_ is needed to control if device is still connected - var address_ = address; - - if (T.isObject(data)) { - data.descriptors.forEach(function(dd) { - descriptors_.push(new BluetoothGATTDescriptor(dd, address_)); - }); - isBroadcast_ = data.isBroadcast; - hasExtendedProperties_ = data.hasExtendedProperties; - isNotify_ = data.isNotify; - isIndication_ = data.isIndication; - isReadable_ = data.isReadable; - isSignedWrite_ = data.isSignedWrite; - isWritable_ = data.isWritable; - isWriteNoResponse_ = data.isWriteNoResponse; + if (!T.isObject(data)) { + return null; } + var address_ = address; + var handle_ = data.handle; + var descriptors_ = data.descriptors.map(function(descriptor_data) { + return new BluetoothGATTDescriptor(descriptor_data, address_); + }); + var isBroadcast_ = data.isBroadcast; + var hasExtendedProperties_ = data.hasExtendedProperties; + var isNotify_ = data.isNotify; + var isIndication_ = data.isIndication; + var isReadable_ = data.isReadable; + var isSignedWrite_ = data.isSignedWrite; + var isWritable_ = data.isWritable; + var isWriteNoResponse_ = data.isWriteNoResponse; + var uuid_ = data.uuid; Object.defineProperties(this, { descriptors: { @@ -1756,6 +1751,13 @@ var BluetoothGATTCharacteristic = function(data, address) { return isWriteNoResponse_; }, set: function() {} + }, + uuid: { + enumerable: true, + get: function() { + return uuid_; + }, + set: function() {} } }); @@ -2004,6 +2006,7 @@ var BluetoothGATTDescriptor = function(data, address) { var handle_ = data.handle; //address_ is needed to control if device is still connected var address_ = address; + var uuid_ = data.uuid; this.readValue = function() { privUtils_.log('Entered BluetoothGATTDescriptor.readValue()'); @@ -2080,6 +2083,16 @@ var BluetoothGATTDescriptor = function(data, address) { throw native.getErrorObject(result); } }; + + Object.defineProperties(this, { + uuid: { + enumerable: true, + get: function() { + return uuid_; + }, + set: function() {}, + } + }); }; // class BluetoothAdapter /////////////////////////// diff --git a/src/bluetooth/bluetooth_gatt_service.cc b/src/bluetooth/bluetooth_gatt_service.cc index 07a7330..ca74a24 100644 --- a/src/bluetooth/bluetooth_gatt_service.cc +++ b/src/bluetooth/bluetooth_gatt_service.cc @@ -38,6 +38,7 @@ using namespace common::tools; namespace { const std::string kUuid = "uuid"; +const std::string kServiceUuid = "serviceUuid"; const std::string kHandle = "handle"; const std::string kAddress = "address"; @@ -156,6 +157,7 @@ PlatformResult BluetoothGATTService::GetSpecifiedGATTService(const std::string& * function. */ result->insert(std::make_pair(kUuid, picojson::value(uuid.uuid_in_source_format))); + result->insert(std::make_pair(kServiceUuid, picojson::value(uuid.uuid_in_source_format))); // handle is passed to upper layer because there is no need to delete it result->insert(std::make_pair(kHandle, picojson::value((double)(long)service))); // address is necessary to later check if device is still connected @@ -205,8 +207,10 @@ PlatformResult BluetoothGATTService::GetServicesHelper(bt_gatt_h handle, const s * UUID has always been set to source format in this function. */ result_obj.insert(std::make_pair(kUuid, picojson::value{uuid->uuid_in_source_format})); + result_obj.insert(std::make_pair(kServiceUuid, picojson::value{uuid->uuid_in_source_format})); } else { - result_obj.insert(std::make_pair(kUuid, picojson::value{})); + result_obj.insert(std::make_pair(kUuid, picojson::value{"0xFFFF"})); + result_obj.insert(std::make_pair(kServiceUuid, picojson::value{})); } // handle is passed to upper layer because there is no need of deletion @@ -227,11 +231,11 @@ void BluetoothGATTService::GetCharacteristics(const picojson::value& args, picoj ScopeLogger(); bt_gatt_h handle = (bt_gatt_h) static_cast(args.get("handle").get()); - const std::string& uuid = args.get("uuid").get(); + const std::string& address = args.get("address").get(); picojson::array array; - PlatformResult ret = GetCharacteristicsHelper(handle, address, uuid, &array); + PlatformResult ret = GetCharacteristicsHelper(handle, address, &array); if (ret.IsError()) { LogAndReportError(ret, &out, ("Error while getting characteristics")); } else { @@ -241,7 +245,6 @@ void BluetoothGATTService::GetCharacteristics(const picojson::value& args, picoj PlatformResult BluetoothGATTService::GetCharacteristicsHelper(bt_gatt_h handle, const std::string& address, - const std::string& uuid, picojson::array* array) { ScopeLogger(); @@ -262,8 +265,8 @@ PlatformResult BluetoothGATTService::GetCharacteristicsHelper(bt_gatt_h handle, handle, [](int total, int index, bt_gatt_h gatt_handle, void* data) { ScopeLogger( - "Entered into asynchronous function, bt_gatt_service_foreach_characteristics's " - "argument"); + "Entered into asynchronous function, bt_gatt_service_foreach_characteristics;" + " index: %d", index); Data* user_data = static_cast(data); picojson::array* array = user_data->array; PlatformResult* platform_result = user_data->platform_res; @@ -281,7 +284,9 @@ PlatformResult BluetoothGATTService::GetCharacteristicsHelper(bt_gatt_h handle, int ret = bt_gatt_characteristic_foreach_descriptors( gatt_handle, [](int total, int index, bt_gatt_h desc_handle, void* data) { - ScopeLogger(); + ScopeLogger( + "Entered into asynchronous function, bt_gatt_characteristic_foreach_descriptors;" + " index: %d", index); picojson::array& desc_array = *(static_cast(data)); picojson::value desc = picojson::value(picojson::object()); @@ -289,6 +294,14 @@ PlatformResult BluetoothGATTService::GetCharacteristicsHelper(bt_gatt_h handle, // handle is passed to upper layer because there is no need of deletion desc_obj.insert(std::make_pair(kHandle, picojson::value((double)(long)desc_handle))); + + auto uuid = UUID::createFromGatt(desc_handle); + if (uuid) { + desc_obj.insert(std::make_pair(kUuid, picojson::value{uuid->ShortestPossibleFormat()})); + } else { + desc_obj.insert(std::make_pair(kUuid, picojson::value{})); + } + desc_array.push_back(desc); return true; }, @@ -325,6 +338,14 @@ PlatformResult BluetoothGATTService::GetCharacteristicsHelper(bt_gatt_h handle, kExtendedProperties, picojson::value(IsProperty(property_bits, BT_GATT_PROPERTY_EXTENDED_PROPERTIES)))); + auto uuid = UUID::createFromGatt(gatt_handle); + if (uuid) { + result_obj.insert(std::make_pair(kUuid, picojson::value{uuid->ShortestPossibleFormat()})); + } else { + LoggerW("bt_gatt_get_uuid error: %d (%s)", err, get_error_message(err)); + result_obj.insert(std::make_pair(kUuid, picojson::value{})); + } + array->push_back(result); return true; }, diff --git a/src/bluetooth/bluetooth_gatt_service.h b/src/bluetooth/bluetooth_gatt_service.h index 40ca965..d4e5446 100644 --- a/src/bluetooth/bluetooth_gatt_service.h +++ b/src/bluetooth/bluetooth_gatt_service.h @@ -56,7 +56,7 @@ class BluetoothGATTService { common::PlatformResult GetServicesHelper(bt_gatt_h handle, const std::string& address, picojson::array* array); common::PlatformResult GetCharacteristicsHelper(bt_gatt_h handle, const std::string& address, - const std::string& uuid, picojson::array* array); + picojson::array* array); static void OnCharacteristicValueChanged(bt_gatt_h characteristic, char* value, int len, void* user_data); -- 2.7.4