[Bluetooth] BLEAdapter isScanning and BLEDevice new functions. 35/235535/19
authorArkadiusz Pietraszek <a.pietraszek@samsung.com>
Mon, 13 Jul 2020 12:20:35 +0000 (14:20 +0200)
committerPiotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/Samsung Electronics <p.kosko@samsung.com>
Tue, 15 Sep 2020 08:40:15 +0000 (10:40 +0200)
[ACR] TWDAPI-264

Bluetooth module can be upgraded with these functions provided by native layer:
BluetoothLEAdapter
bool isScanning ()

BluetoothLEDevice
bool isConnected ()
unsigned long getAttMtu ()
void requestAttMtuChange (unsigned long newAttMtu)
long addAttMtuChangeListener (ConnectionMTUCallback callback)
void removeAttMtuChangeListener (long watchId)

[Verification] New functionality has been tested on TW2 device in
developer console.

Change-Id: Id5f56ee4d67591b6d917552c6b7a09d2a5a06386
Signed-off-by: Arkadiusz Pietraszek <a.pietraszek@samsung.com>
src/bluetooth/bluetooth_adapter.cc
src/bluetooth/bluetooth_api.js
src/bluetooth/bluetooth_gatt_client_service.cc
src/bluetooth/bluetooth_gatt_client_service.h
src/bluetooth/bluetooth_instance.cc
src/bluetooth/bluetooth_instance.h
src/bluetooth/bluetooth_le_adapter.cc
src/bluetooth/bluetooth_le_adapter.h
src/bluetooth/bluetooth_le_device.cc
src/bluetooth/bluetooth_le_device.h

index 7bd1145..f4aaf96 100644 (file)
@@ -77,7 +77,7 @@ const unsigned short kTimeout = 180;
 
 static bool IsValidAddress(const std::string& address) {
   ScopeLogger();
-  const std::regex macAdressRegex {"([[:xdigit:]]{2}[:]){5}([[:xdigit:]]{2})"};
+  const std::regex macAdressRegex{"([[:xdigit:]]{2}[:]){5}([[:xdigit:]]{2})"};
 
   if (std::regex_match(address, macAdressRegex)) {
     return true;
@@ -88,7 +88,8 @@ static bool IsValidAddress(const std::string& address) {
 
 static bool IsValidUUID(const std::string& uuid) {
   ScopeLogger();
-  const std::regex uuidRegex {"[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}"};
+  const std::regex uuidRegex{
+      "[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}"};
 
   if (std::regex_match(uuid, uuidRegex)) {
     return true;
index 5fe9939..b241092 100755 (executable)
@@ -770,6 +770,20 @@ BluetoothLEDevice.prototype.getServiceAllUuids = function() {
     }
 };
 
+BluetoothLEDevice.prototype.isConnected = function() {
+    privUtils_.log('Entered BluetoothLEDevice.isConnected()');
+
+    var callArgs = {
+        address: this.address
+    };
+
+    var result = native.callSync('BluetoothLEDeviceIsConnected', callArgs);
+    if (native.isFailure(result)) {
+        throw native.getErrorObject(result);
+    }
+    return native.getResultObject(result);
+};
+
 BluetoothLEDevice.prototype.addConnectStateChangeListener = function() {
     privUtils_.log('Entered BluetoothLEDevice.addConnectStateChangeListener()');
     var args = AV.validateArgs(arguments, [
@@ -806,6 +820,78 @@ BluetoothLEDevice.prototype.removeConnectStateChangeListener = function() {
     _bleConnectChangeListener.removeListener(args.watchID);
 };
 
+BluetoothLEDevice.prototype.getAttMtu = function() {
+    privUtils_.log('Entered BluetoothLEDevice.getAttMtu()');
+
+    var callArgs = {
+        address: this.address
+    };
+
+    var result = native.callSync('BluetoothLEDeviceGetAttMtu', callArgs);
+    if (native.isFailure(result)) {
+        throw native.getErrorObject(result);
+    }
+    return native.getResultObject(result);
+}
+
+BluetoothLEDevice.prototype.requestAttMtuChange = function() {
+    privUtils_.log('Entered BluetoothLEDevice.requestAttMtuChange()');
+
+    var args = AV.validateArgs(arguments, [
+        {
+            name: 'mtu',
+            type: AV.Types.LONG
+        }
+    ]);
+
+    var callArgs = {
+        address: this.address,
+        mtu: args.mtu
+    };
+
+    var result = native.callSync('BluetoothLEDeviceRequestAttMtuChange', callArgs);
+    if (native.isFailure(result)) {
+        throw native.getErrorObject(result);
+    }
+    return native.getResultObject(result);
+}
+
+BluetoothLEDevice.prototype.addAttMtuChangeListener = function() {
+    privUtils_.log('Entered BluetoothLEDevice.addAttMtuChangeListener()');
+    var args = AV.validateArgs(arguments, [
+        {
+            name: 'callback',
+            type: AV.Types.FUNCTION
+        }
+    ]);
+
+    var callArgs = { address: this.address };
+
+    var callback = function(result) {
+        privUtils_.log('Entered BluetoothLEDevice.addAttMtuChangeListener() callback');
+        args.callback(result.attMtuValue);
+    };
+
+    var watchId = _bleAttMtuChangeListener.addListener(callback, callArgs);
+
+    return watchId;
+};
+
+BluetoothLEDevice.prototype.removeAttMtuChangeListener = function() {
+    privUtils_.log('Entered BluetoothLEDevice.removeAttMtuChangeListener()');
+
+    var args = AV.validateArgs(arguments, [
+        {
+            name: 'watchID',
+            type: AV.Types.LONG
+        }
+    ]);
+
+    var callArgs = { address: this.address };
+
+    _bleAttMtuChangeListener.removeListener(args.watchID, callArgs);
+};
+
 // class BluetoothDevice ///////////////////////////
 var BluetoothDevice = function(data) {
     var self = this;
@@ -1534,6 +1620,16 @@ BluetoothLEAdapter.prototype.stopScan = function() {
     }
 };
 
+BluetoothLEAdapter.prototype.isScanning = function() {
+    privUtils_.log('Entered BluetoothLEAdapter.isScanning()');
+
+    var result = native.callSync('BluetoothLEAdapterIsScanning', {});
+    if (native.isFailure(result)) {
+        throw native.getErrorObject(result);
+    }
+    return native.getResultObject(result);
+};
+
 var _BluetoothAdvertisePacketType = {
     ADVERTISE: 'ADVERTISE',
     SCAN_RESPONSE: 'SCAN_RESPONSE'
@@ -2496,6 +2592,15 @@ var _bleConnectChangeListener = _multipleListenerBuilder(
     'BluetoothLEDeviceRemoveConnectStateChangeListener'
 );
 
+var _bleAttMtuChangeListener = _multipleListenerBuilder(
+    'BluetoothLEAttMtuChangeCallback',
+    function(listener, event) {
+        listener(event);
+    },
+    'BluetoothLEDeviceAddAttMtuChangeListener',
+    'BluetoothLEDeviceRemoveAttMtuChangeListener'
+);
+
 //class BluetoothGATTDescriptor ///////////////////////////
 var BluetoothGATTDescriptor = function(data, address) {
     var handle_ = data.handle;
index 1be096c..1db6db3 100644 (file)
@@ -207,7 +207,8 @@ PlatformResult BluetoothGATTClientService::GetServicesHelper(bt_gatt_h handle, c
            * 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}));
+          result_obj.insert(
+              std::make_pair(kServiceUuid, picojson::value{uuid->uuid_in_source_format}));
         } else {
           result_obj.insert(std::make_pair(kUuid, picojson::value{"0xFFFF"}));
           result_obj.insert(std::make_pair(kServiceUuid, picojson::value{}));
@@ -266,7 +267,8 @@ PlatformResult BluetoothGATTClientService::GetCharacteristicsHelper(bt_gatt_h ha
       [](int total, int index, bt_gatt_h gatt_handle, void* data) {
         ScopeLogger(
             "Entered into asynchronous function, bt_gatt_service_foreach_characteristics;"
-            " index: %d", index);
+            " index: %d",
+            index);
         Data* user_data = static_cast<Data*>(data);
         picojson::array* array = user_data->array;
         PlatformResult* platform_result = user_data->platform_res;
@@ -285,8 +287,9 @@ PlatformResult BluetoothGATTClientService::GetCharacteristicsHelper(bt_gatt_h ha
             gatt_handle,
             [](int total, int index, bt_gatt_h desc_handle, void* data) {
               ScopeLogger(
-                "Entered into asynchronous function, bt_gatt_characteristic_foreach_descriptors;"
-                " index: %d", index);
+                  "Entered into asynchronous function, bt_gatt_characteristic_foreach_descriptors;"
+                  " index: %d",
+                  index);
               picojson::array& desc_array = *(static_cast<picojson::array*>(data));
 
               picojson::value desc = picojson::value(picojson::object());
@@ -297,7 +300,8 @@ PlatformResult BluetoothGATTClientService::GetCharacteristicsHelper(bt_gatt_h ha
 
               auto uuid = UUID::createFromGatt(desc_handle);
               if (uuid) {
-                desc_obj.insert(std::make_pair(kUuid, picojson::value{uuid->ShortestPossibleFormat()}));
+                desc_obj.insert(
+                    std::make_pair(kUuid, picojson::value{uuid->ShortestPossibleFormat()}));
               } else {
                 desc_obj.insert(std::make_pair(kUuid, picojson::value{}));
               }
index 7232868..2d727ea 100644 (file)
@@ -46,13 +46,13 @@ class BluetoothGATTClientService {
   void AddValueChangeListener(const picojson::value& args, picojson::object& out);
   void RemoveValueChangeListener(const picojson::value& args, picojson::object& out);
 
+  bt_gatt_client_h GetGattClient(const std::string& address);
+
   common::PlatformResult GetServiceAllUuids(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,
                                            picojson::array* array);
   common::PlatformResult GetCharacteristicsHelper(bt_gatt_h handle, const std::string& address,
index 70a70b7..2c3fc5a 100644 (file)
@@ -84,6 +84,7 @@ BluetoothInstance::BluetoothInstance()
 
   REGISTER_METHOD(BluetoothLEAdapterStartScan);
   REGISTER_METHOD(BluetoothLEAdapterStopScan);
+  REGISTER_METHOD(BluetoothLEAdapterIsScanning);
   REGISTER_METHOD(BluetoothLEAdapterStartAdvertise);
   REGISTER_METHOD(BluetoothLEAdapterStopAdvertise);
 
@@ -93,6 +94,11 @@ BluetoothInstance::BluetoothInstance()
   REGISTER_METHOD(BluetoothLEDeviceAddConnectStateChangeListener);
   REGISTER_METHOD(BluetoothLEDeviceRemoveConnectStateChangeListener);
   REGISTER_METHOD(BluetoothLEDeviceGetServiceAllUuids);
+  REGISTER_METHOD(BluetoothLEDeviceIsConnected);
+  REGISTER_METHOD(BluetoothLEDeviceGetAttMtu);
+  REGISTER_METHOD(BluetoothLEDeviceRequestAttMtuChange);
+  REGISTER_METHOD(BluetoothLEDeviceAddAttMtuChangeListener);
+  REGISTER_METHOD(BluetoothLEDeviceRemoveAttMtuChangeListener);
 
   REGISTER_METHOD(BluetoothGATTClientServiceGetServices);
   REGISTER_METHOD(BluetoothGATTClientServiceGetCharacteristics);
@@ -362,6 +368,12 @@ void BluetoothInstance::BluetoothLEAdapterStopScan(const picojson::value& args,
   bluetooth_le_adapter_.StopScan(args, out);
 }
 
+void BluetoothInstance::BluetoothLEAdapterIsScanning(const picojson::value& args,
+                                                     picojson::object& out) {
+  ScopeLogger();
+  bluetooth_le_adapter_.IsScanning(out);
+}
+
 void BluetoothInstance::BluetoothLEAdapterStartAdvertise(const picojson::value& args,
                                                          picojson::object& out) {
   ScopeLogger();
@@ -410,6 +422,36 @@ void BluetoothInstance::BluetoothLEDeviceGetServiceAllUuids(const picojson::valu
   bluetooth_le_device_.GetServiceAllUuids(args, out);
 }
 
+void BluetoothInstance::BluetoothLEDeviceIsConnected(const picojson::value& args,
+                                                     picojson::object& out) {
+  ScopeLogger();
+  bluetooth_le_device_.IsConnected(args, out);
+}
+
+void BluetoothInstance::BluetoothLEDeviceGetAttMtu(const picojson::value& args,
+                                                   picojson::object& out) {
+  ScopeLogger();
+  bluetooth_le_device_.GetAttMtu(args, out);
+}
+
+void BluetoothInstance::BluetoothLEDeviceRequestAttMtuChange(const picojson::value& args,
+                                                             picojson::object& out) {
+  ScopeLogger();
+  bluetooth_le_device_.RequestAttMtuChange(args, out);
+}
+
+void BluetoothInstance::BluetoothLEDeviceAddAttMtuChangeListener(const picojson::value& args,
+                                                                 picojson::object& out) {
+  ScopeLogger();
+  bluetooth_le_device_.AddAttMtuChangeListener(args, out);
+}
+
+void BluetoothInstance::BluetoothLEDeviceRemoveAttMtuChangeListener(const picojson::value& args,
+                                                                    picojson::object& out) {
+  ScopeLogger();
+  bluetooth_le_device_.RemoveAttMtuChangeListener(args, out);
+}
+
 void BluetoothInstance::BluetoothGATTClientServiceGetServices(const picojson::value& args,
                                                               picojson::object& out) {
   ScopeLogger();
index e3e31c2..0f5eeb0 100644 (file)
@@ -90,6 +90,7 @@ class BluetoothInstance : public common::ParsedInstance {
 
   void BluetoothLEAdapterStartScan(const picojson::value& args, picojson::object& out);
   void BluetoothLEAdapterStopScan(const picojson::value& args, picojson::object& out);
+  void BluetoothLEAdapterIsScanning(const picojson::value& args, picojson::object& out);
   void BluetoothLEAdapterStartAdvertise(const picojson::value& args, picojson::object& out);
   void BluetoothLEAdapterStopAdvertise(const picojson::value& args, picojson::object& out);
   void BluetoothLEDeviceConnect(const picojson::value& args, picojson::object& out);
@@ -100,6 +101,12 @@ class BluetoothInstance : public common::ParsedInstance {
   void BluetoothLEDeviceRemoveConnectStateChangeListener(const picojson::value& args,
                                                          picojson::object& out);
   void BluetoothLEDeviceGetServiceAllUuids(const picojson::value& args, picojson::object& out);
+  void BluetoothLEDeviceIsConnected(const picojson::value& args, picojson::object& out);
+  void BluetoothLEDeviceGetAttMtu(const picojson::value& args, picojson::object& out);
+  void BluetoothLEDeviceRequestAttMtuChange(const picojson::value& args, picojson::object& out);
+  void BluetoothLEDeviceAddAttMtuChangeListener(const picojson::value& args, picojson::object& out);
+  void BluetoothLEDeviceRemoveAttMtuChangeListener(const picojson::value& args,
+                                                   picojson::object& out);
 
   void BluetoothGATTClientServiceGetServices(const picojson::value& args, picojson::object& out);
   void BluetoothGATTClientServiceGetCharacteristics(const picojson::value& args,
index caad799..27fd38f 100644 (file)
@@ -465,6 +465,22 @@ void BluetoothLEAdapter::StopScan(const picojson::value& data, picojson::object&
   }
 }
 
+void BluetoothLEAdapter::IsScanning(picojson::object& out) {
+  ScopeLogger();
+
+  bool is_scanning;
+  int ret = bt_adapter_le_is_discovering(&is_scanning);
+
+  if (BT_ERROR_NONE != ret) {
+    LogAndReportError(
+        PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to check for scanning in progress"), &out,
+        ("Failed to check for scanning in progress: %d (%s)", ret, get_error_message(ret)));
+  } else {
+    scanning_ = is_scanning;
+    ReportSuccess(picojson::value(is_scanning), out);
+  }
+}
+
 void BluetoothLEAdapter::StartAdvertise(const picojson::value& data, picojson::object& out) {
   ScopeLogger();
   CHECK_BACKWARD_COMPABILITY_PRIVILEGE_ACCESS(Privilege::kBluetooth, Privilege::kBluetoothAdmin,
index b26fffd..48f0cef 100644 (file)
@@ -34,6 +34,7 @@ class BluetoothLEAdapter {
 
   void StartScan(const picojson::value& data, picojson::object& out);
   void StopScan(const picojson::value& data, picojson::object& out);
+  void IsScanning(picojson::object& out);
 
   void StartAdvertise(const picojson::value& data, picojson::object& out);
   void StopAdvertise(const picojson::value& data, picojson::object& out);
index bbcf715..fc2da2f 100644 (file)
@@ -49,10 +49,15 @@ const std::string kId = "id";
 const std::string kData = "data";
 const std::string kAction = "action";
 const std::string kRSSI = "rssi";
+const std::string kAttMtuValue = "attMtuValue";
 
 const std::string kOnConnected = "onconnected";
 const std::string kOnDisconnected = "ondisconnected";
 const std::string kConnectChangeEvent = "BluetoothLEConnectChangeCallback";
+const std::string kAttMtuChangeEvent = "BluetoothLEAttMtuChangeCallback";
+
+const char* kMtu = "mtu";
+const char* kAddress = "address";
 }
 
 BluetoothLEDevice::BluetoothLEDevice(BluetoothInstance& instance, BluetoothGATTClientService& service)
@@ -68,7 +73,25 @@ BluetoothLEDevice::~BluetoothLEDevice() {
   ScopeLogger();
   int ret = bt_gatt_unset_connection_state_changed_cb();
   if (ret != BT_ERROR_NONE) {
-    LoggerW("Failed to unset listener: %d", ret);
+    LoggerW("Failed to unset connection state change listener: %d", ret);
+  }
+
+  if(mac_address_.empty()) {
+    LoggerD("No att mtu change listener to unset: %d", ret);
+    return;
+  }
+
+  bt_gatt_client_h client = service_.GetGattClient(mac_address_);
+
+  if (nullptr == client) {
+    LoggerW("Failed to get client handle while unsetting att mtu change listener");
+    return;
+  }
+
+  ret = bt_gatt_client_unset_att_mtu_changed_cb(client);
+
+  if (BT_ERROR_NONE != ret) {
+    LoggerW("Failed to unset att mtu change listener: %d", ret);
   }
 }
 
@@ -434,6 +457,153 @@ void BluetoothLEDevice::GetServiceAllUuids(const picojson::value& data, picojson
   }
 }
 
+void BluetoothLEDevice::IsConnected(const picojson::value& data, picojson::object& out) {
+  ScopeLogger();
+
+  const auto& args = util::GetArguments(data);
+  const auto& address = common::FromJson<std::string>(args, kAddress);
+
+  bool connected = false;
+  int ret = bt_device_is_profile_connected(address.c_str(), BT_PROFILE_GATT, &connected);
+
+  if (BT_ERROR_NONE == ret) {
+    ReportSuccess(picojson::value(connected), out);
+  } else {
+    LogAndReportError(
+        PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to check if device is connected"), &out,
+        ("Failed to check if device is connected: %d (%s)", ret, get_error_message(ret)));
+  }
+}
+
+void BluetoothLEDevice::GetAttMtu(const picojson::value& data, picojson::object& out) {
+  ScopeLogger();
+
+  unsigned int mtu = 0;
+  const auto& args = util::GetArguments(data);
+  const auto& address = common::FromJson<std::string>(args, kAddress);
+
+  if(mac_address_.empty()) {
+    mac_address_ == address;
+  }
+
+  bt_gatt_client_h client = service_.GetGattClient(address);
+
+  int ret = bt_gatt_client_get_att_mtu(client, &mtu);
+  if (BT_ERROR_NONE != ret) {
+    if ( BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED == ret) {
+      LogAndReportError(PlatformResult(ErrorCode::INVALID_STATE_ERR, "Device is not connected"), &out,
+                       ("Failed to get ATT MTU: %d (%s)", ret, get_error_message(ret)));
+    } else {
+      LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get ATT MTU"), &out,
+                       ("Failed to get ATT MTU: %d (%s)", ret, get_error_message(ret)));
+    }
+    return;
+  }
+
+  ReportSuccess(picojson::value(static_cast<double>(mtu)), out);
+}
+
+void BluetoothLEDevice::RequestAttMtuChange(const picojson::value& data, picojson::object& out) {
+  ScopeLogger();
+
+  const auto& args = util::GetArguments(data);
+  const auto& mtu = (unsigned int)common::FromJson<double>(args, kMtu);
+  const auto& address = common::FromJson<std::string>(args, kAddress);
+
+  if(mac_address_.empty()) {
+    mac_address_ == address;
+  }
+
+  bt_gatt_client_h client = service_.GetGattClient(address);
+
+  int ret = bt_gatt_client_request_att_mtu_change(client, mtu);
+  if (BT_ERROR_NONE != ret) {
+    LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get ATT MTU"), &out,
+                      ("Failed to get ATT MTU: %d (%s)", ret, get_error_message(ret)));
+    return;
+  }
+
+  ReportSuccess(out);
+}
+
+void BluetoothLEDevice::AddAttMtuChangeListener(const picojson::value& data,
+                                                picojson::object& out) {
+  ScopeLogger();
+
+  const auto& args = util::GetArguments(data);
+  const auto& address = common::FromJson<std::string>(args, kAddress);
+
+  if(mac_address_.empty()) {
+    mac_address_ == address;
+  }
+
+  bt_gatt_client_h client = service_.GetGattClient(address);
+
+  int ret = bt_gatt_client_set_att_mtu_changed_cb(client, OnAttMtuValueChanged, this);
+
+  if (BT_ERROR_NONE != ret) {
+    LogAndReportError(util::GetBluetoothError(ret, "Failed to register listener"), &out,
+                      ("bt_gatt_client_set_att_mtu_changed_cb() failed with: %d (%s)", ret,
+                       get_error_message(ret)));
+  } else {
+    ReportSuccess(out);
+  }
+}
+
+void BluetoothLEDevice::RemoveAttMtuChangeListener(const picojson::value& data,
+                                                   picojson::object& out) {
+  ScopeLogger();
+
+  const auto& args = util::GetArguments(data);
+  const auto& address = common::FromJson<std::string>(args, kAddress);
+
+  bt_gatt_client_h client = service_.GetGattClient(address);
+
+  int ret = bt_gatt_client_unset_att_mtu_changed_cb(client);
+
+  if (BT_ERROR_NONE != ret) {
+    LogAndReportError(util::GetBluetoothError(ret, "Failed to register listener"), &out,
+                      ("bt_gatt_client_set_att_mtu_changed_cb() failed with: %d (%s)", ret,
+                       get_error_message(ret)));
+  } else {
+    if(!mac_address_.empty()) {
+      mac_address_.clear();
+    }
+    ReportSuccess(out);
+  }
+}
+
+void BluetoothLEDevice::OnAttMtuValueChanged(bt_gatt_client_h client,
+                                             const bt_gatt_client_att_mtu_info_s* mtu_info,
+                                             void* user_data) {
+  ScopeLogger();
+  if(!mtu_info) {
+    LoggerE("mtu_info is NULL");
+    return;
+  } else {
+    LoggerD("mtu_info->mtu: [%u]", mtu_info->mtu);
+  }
+
+  if (!user_data) {
+    LoggerE("user_data is NULL");
+    return;
+  }
+  BluetoothLEDevice* le_device = static_cast<BluetoothLEDevice*>(user_data);
+
+  le_device->TriggerAttMtuStateChangeListener(mtu_info->remote_address, mtu_info->mtu);
+}
+
+void BluetoothLEDevice::TriggerAttMtuStateChangeListener(char* remote_address, unsigned int mtu) {
+  ScopeLogger("adress: [%s], mtu: [%u]", remote_address, mtu);
+
+  picojson::value value = picojson::value(picojson::object());
+  picojson::object* data_obj = &value.get<picojson::object>();
+
+  data_obj->insert(std::make_pair(kAttMtuValue, picojson::value(static_cast<double>(mtu))));
+
+  instance_.FireEvent(kAttMtuChangeEvent, value);
+};
+
 void BluetoothLEDevice::GattConnectionState(int result, bool connected, const char* remote_address,
                                             void* user_data) {
   ScopeLogger("%s connected: %d", remote_address, connected);
index 99f42aa..5e0cd63 100644 (file)
@@ -48,6 +48,13 @@ class BluetoothLEDevice {
 
   void GetServiceAllUuids(const picojson::value& data, picojson::object& out);
 
+  void IsConnected(const picojson::value& data, picojson::object& out);
+
+  void GetAttMtu(const picojson::value& data, picojson::object& out);
+  void RequestAttMtuChange(const picojson::value& data, picojson::object& out);
+  void AddAttMtuChangeListener(const picojson::value& data, picojson::object& out);
+  void RemoveAttMtuChangeListener(const picojson::value& data, picojson::object& out);
+
   static common::PlatformResult ToJson(bt_adapter_le_device_scan_result_info_s* info,
                                        picojson::object* le_device);
 
@@ -57,13 +64,17 @@ class BluetoothLEDevice {
   bool IsInConnecting(const char* remote_address);
   static common::PlatformResult ValidateConnectionChange(int err_code);
   void TriggerConnectCallback(const char* remote_address, common::PlatformResult result);
+  void TriggerAttMtuStateChangeListener(char* remote_address, unsigned int mtu);
   void CleanClientInfo(const char* remote_address);
   void TriggerConnectStateChangeListener(const char* remote_address, bool connected);
+  static void OnAttMtuValueChanged(bt_gatt_client_h client,
+                                   const bt_gatt_client_att_mtu_info_s* mtu_info, void* user_data);
   BluetoothInstance& instance_;
   BluetoothGATTClientService& service_;
   std::unordered_map<std::string, double> connecting_;
   bool is_listener_set_;
   std::set<std::string> is_connected_;
+  std::string mac_address_;
 };
 
 }  // namespace bluetooth