OSDN Git Service

service: add SetMtu and OnMtuChanged
authorJakub Pawlowski <jpawlowski@google.com>
Tue, 26 Jan 2016 20:58:47 +0000 (12:58 -0800)
committerJakub Pawlowski <jpawlowski@google.com>
Wed, 27 Jan 2016 14:18:18 +0000 (14:18 +0000)
Change-Id: I7a6c6cb46f4710b5d2c57b9d0e9cfac166d7cd62

13 files changed:
service/client/main.cpp
service/common/bluetooth/binder/IBluetoothLowEnergy.cpp
service/common/bluetooth/binder/IBluetoothLowEnergy.h
service/common/bluetooth/binder/IBluetoothLowEnergyCallback.cpp
service/common/bluetooth/binder/IBluetoothLowEnergyCallback.h
service/doc/IBluetoothLowEnergy.txt
service/doc/IBluetoothLowEnergyCallback.txt
service/example/heart_rate/heart_rate_server.cpp
service/ipc/binder/bluetooth_low_energy_binder_server.cpp
service/ipc/binder/bluetooth_low_energy_binder_server.h
service/low_energy_client.cpp
service/low_energy_client.h
service/test/low_energy_client_unittest.cpp

index 6d0381a..7184531 100644 (file)
@@ -175,6 +175,21 @@ class CLIBluetoothLowEnergyCallback
       PrintPrompt();
   }
 
+  void OnMtuChanged(int status, const char *address, int mtu) override {
+    if (showing_prompt.load())
+      cout << endl;
+
+    cout << COLOR_BOLDWHITE "MTU changed: "
+         << COLOR_BOLDYELLOW "[" << address << " ] "
+         << COLOR_BOLDWHITE " - status: " << status
+         << COLOR_BOLDWHITE " - mtu: " << mtu << COLOR_OFF;
+
+    cout  << endl << endl;
+
+    if (showing_prompt.load())
+      PrintPrompt();
+  }
+
   void OnScanResult(const bluetooth::ScanResult& scan_result) override {
     if (showing_prompt.load())
       cout << endl;
index 48d9956..ae2237b 100644 (file)
@@ -84,6 +84,16 @@ status_t BnBluetoothLowEnergy::onTransact(
 
     return android::NO_ERROR;
   }
+  case SET_MTU_TRANSACTION: {
+    int client_id = data.readInt32();
+    const char* address = data.readCString();
+    int mtu = data.readInt32();
+
+    bool result = SetMtu(client_id, address, mtu);
+    reply->writeInt32(result);
+
+    return android::NO_ERROR;
+  }
   case START_SCAN_TRANSACTION: {
     int client_id = data.readInt32();
     auto settings = CreateScanSettingsFromParcel(data);
@@ -209,6 +219,18 @@ bool BpBluetoothLowEnergy::Disconnect(int client_id, const char* address) {
   return reply.readInt32();
 }
 
+bool BpBluetoothLowEnergy::SetMtu(int client_id, const char* address, int mtu) {
+  Parcel data, reply;
+
+  data.writeInterfaceToken(IBluetoothLowEnergy::getInterfaceDescriptor());
+  data.writeInt32(client_id);
+  data.writeCString(address);
+  data.writeInt32(mtu);
+
+  remote()->transact(IBluetoothLowEnergy::SET_MTU_TRANSACTION, data, &reply);
+  return reply.readInt32();
+}
+
 bool BpBluetoothLowEnergy::StartScan(
     int client_id,
     const bluetooth::ScanSettings& settings,
index 78d7213..56f8c51 100644 (file)
@@ -59,6 +59,7 @@ class IBluetoothLowEnergy : public android::IInterface {
 
     CONNECT_TRANSACTION,
     DISCONNECT_TRANSACTION,
+    SET_MTU_TRANSACTION,
     READ_REMOTE_RSSI_TRANSACTION,
     CONFIGURE_ATT_MTU_TRANSACTION,
     CONNECTION_PARAMETER_UPDATE_TRANSACTION,
@@ -75,6 +76,8 @@ class IBluetoothLowEnergy : public android::IInterface {
   virtual bool Connect(int client_id, const char* address, bool is_direct) = 0;
   virtual bool Disconnect(int client_id, const char* address) = 0;
 
+  virtual bool SetMtu(int client_id, const char* address, int mtu) = 0;
+
   virtual bool StartScan(
       int client_id,
       const bluetooth::ScanSettings& settings,
@@ -126,6 +129,8 @@ class BpBluetoothLowEnergy : public android::BpInterface<IBluetoothLowEnergy> {
   bool Connect(int client_id, const char* address, bool is_direct) override;
   bool Disconnect(int client_id, const char* address) override;
 
+  bool SetMtu(int client_id, const char* address, int mtu) override;
+
   bool StartScan(
       int client_id,
       const bluetooth::ScanSettings& settings,
index e2b7292..c887e5f 100644 (file)
@@ -64,6 +64,14 @@ status_t BnBluetoothLowEnergyCallback::onTransact(
     OnConnectionState(status, client_id, address, connected);
     return android::NO_ERROR;
   }
+  case ON_MTU_CHANGED_TRANSACTION: {
+    int status = data.readInt32();
+    const char *address = data.readCString();
+    int mtu = data.readInt32();
+
+    OnMtuChanged(status, address, mtu);
+    return android::NO_ERROR;
+  }
   case ON_SCAN_RESULT_TRANSACTION: {
     auto scan_result = CreateScanResultFromParcel(data);
     CHECK(scan_result.get());
@@ -124,6 +132,22 @@ void BpBluetoothLowEnergyCallback::OnConnectionState(
       IBinder::FLAG_ONEWAY);
 }
 
+void BpBluetoothLowEnergyCallback::OnMtuChanged(
+    int status, const char* address, int mtu) {
+  Parcel data;
+
+  data.writeInterfaceToken(
+      IBluetoothLowEnergyCallback::getInterfaceDescriptor());
+  data.writeInt32(status);
+  data.writeCString(address);
+  data.writeInt32(mtu);
+
+  remote()->transact(
+      IBluetoothLowEnergyCallback::ON_MTU_CHANGED_TRANSACTION,
+      data, NULL,
+      IBinder::FLAG_ONEWAY);
+}
+
 void BpBluetoothLowEnergyCallback::OnScanResult(
     const bluetooth::ScanResult& scan_result) {
   Parcel data, reply;
index 908e78b..6c52726 100644 (file)
@@ -44,6 +44,7 @@ namespace binder {
   enum {
     ON_CLIENT_REGISTERED_TRANSACTION = android::IBinder::FIRST_CALL_TRANSACTION,
     ON_CONNECTION_STATE_TRANSACTION,
+    ON_MTU_CHANGED_TRANSACTION,
     ON_SCAN_RESULT_TRANSACTION,
     ON_BATCH_SCAN_RESULTS_TRANSACTION,
     ON_READ_REMOTE_RSSI_TRANSACTION,
@@ -57,6 +58,7 @@ namespace binder {
   virtual void OnClientRegistered(int status, int client_if) = 0;
   virtual void OnConnectionState(int status, int client_id, const char* address,
                                  bool connected) = 0;
+  virtual void OnMtuChanged(int status, const char* address, int mtu) = 0;
   virtual void OnScanResult(const bluetooth::ScanResult& scan_result) = 0;
   virtual void OnMultiAdvertiseCallback(
       int status, bool is_start,
@@ -97,6 +99,7 @@ class BpBluetoothLowEnergyCallback
   void OnClientRegistered(int status, int client_if) override;
   void OnConnectionState(int status, int client_id, const char* address,
                          bool connected) override;
+  void OnMtuChanged(int status, const char* address, int mtu) override;
   void OnScanResult(const bluetooth::ScanResult& scan_result) override;
   void OnMultiAdvertiseCallback(
       int status, bool is_start,
index c05620e..b7218cb 100644 (file)
@@ -45,11 +45,18 @@ interface IBluetoothLowEnergy {
                   in boolean is_direct);
 
   /* Disconnect from previously connected BLE device with address |address|.
-   * Return true on success, false otherwise.
+   * Returns true on success, false otherwise.
    */
   boolean Disconnect(in int client_id, in const char* address);
 
   /**
+   * Sends request to set MTU to |mtu| for the device with address |address|.
+   * OnMtuChanged callback will be triggered as a result of this call. Returns
+   * true when the command was sent, false otherwise.
+   */
+   boolean setMtu(in int client_id, in char* address, int mtu);
+
+  /**
    * Initiates a BLE device scan for the scan client with ID |client_id|, using
    * the parameters defined in |settings|. Scan results that are reported to the
    * application with the associated IBluetoothLowEnergyCallback event will be
index 4fa60bf..1ced0aa 100644 (file)
@@ -33,6 +33,11 @@ oneway interface IBluetoothLowEnergyCallback {
   void OnConnectionState(in int status, in int client_id, in const char* address,
                          in bool connected);
 
+  /* Called to report current MTU value. Can be a result of calling
+   * IBluetoothLowEnergy.setMtu or remote device trying to change MTU.
+   */
+  void OnMtuChanged(in int status, in const char* address, in int mtu);
+
   /**
    * Called to report BLE device scan results once a scan session is started for
    * this client using IBluetoothLowEnergy.startScan. |scan_result| contains all
index f111362..724ef29 100644 (file)
@@ -36,6 +36,8 @@ class CLIBluetoothLowEnergyCallback
   // IBluetoothLowEnergyCallback overrides:
   void OnConnectionState(int status, int client_id, const char* address,
                          bool connected) override {}
+  void OnMtuChanged(int status, const char *address, int mtu) override {}
+
   void OnScanResult(const bluetooth::ScanResult& scan_result) override {}
 
   void OnClientRegistered(int status, int client_id){
index f49d909..0e5d6ff 100644 (file)
@@ -86,6 +86,23 @@ bool BluetoothLowEnergyBinderServer::Disconnect(int client_id,
   return client->Disconnect(std::string(address));
 }
 
+bool BluetoothLowEnergyBinderServer::SetMtu(int client_id,
+                                            const char* address,
+                                            int mtu) {
+  VLOG(2) << __func__ << " client_id: " << client_id
+          << " address: " << address
+          << " mtu: " << mtu;
+  std::lock_guard<std::mutex> lock(*maps_lock());
+
+  auto client = GetLEClient(client_id);
+  if (!client) {
+    LOG(ERROR) << "Unknown client_id: " << client_id;
+    return false;
+  }
+
+  return client->SetMtu(address, mtu);
+}
+
 bool BluetoothLowEnergyBinderServer::StartScan(
     int client_id,
     const bluetooth::ScanSettings& settings,
@@ -215,6 +232,22 @@ void BluetoothLowEnergyBinderServer::OnConnectionState(
   cb->OnConnectionState(status, client_id, address, connected);
 }
 
+void BluetoothLowEnergyBinderServer::OnMtuChanged(
+      bluetooth::LowEnergyClient* client, int status, const char* address, int mtu) {
+  VLOG(2) << __func__ << " address: " << address
+          << " status: " << status
+          << " mtu: " << mtu;
+
+  int client_id = client->GetInstanceId();
+  auto cb = GetLECallback(client_id);
+  if (!cb.get()) {
+    VLOG(2) << "Client was unregistered - client_id: " << client_id;
+    return;
+  }
+
+  cb->OnMtuChanged(status, address, mtu);
+}
+
 void BluetoothLowEnergyBinderServer::OnScanResult(
     bluetooth::LowEnergyClient* client,
     const bluetooth::ScanResult& result) {
index 48a4f71..c060ef8 100644 (file)
@@ -49,6 +49,7 @@ class BluetoothLowEnergyBinderServer
   void UnregisterAll() override;
   bool Connect(int client_id, const char* address, bool is_direct) override;
   bool Disconnect(int client_id, const char* address) override;
+  bool SetMtu(int client_id, const char* address, int mtu) override;
   bool StartScan(
       int client_id,
       const bluetooth::ScanSettings& settings,
@@ -64,6 +65,8 @@ class BluetoothLowEnergyBinderServer
   // bluetooth::LowEnergyClient::Delegate overrides:
   void OnConnectionState(bluetooth::LowEnergyClient* client, int status,
                          const char* address, bool connected) override;
+  void OnMtuChanged(bluetooth::LowEnergyClient* client, int status,
+                    const char* address, int mtu) override;
   void OnScanResult(bluetooth::LowEnergyClient* client,
                     const bluetooth::ScanResult& result) override;
 
index 4ec116e..a6653b7 100644 (file)
@@ -378,6 +378,33 @@ bool LowEnergyClient::Disconnect(std::string address) {
   return true;
 }
 
+bool LowEnergyClient::SetMtu(std::string address, int mtu) {
+  VLOG(2) << __func__ << "Address: " << address
+          << " MTU: " << mtu;
+
+  bt_bdaddr_t bda;
+  util::BdAddrFromString(address, &bda);
+
+  std::map<const bt_bdaddr_t, int>::iterator conn_id;
+  {
+    lock_guard<mutex> lock(connection_fields_lock_);
+    conn_id = connection_ids_.find(bda);
+    if (conn_id == connection_ids_.end()) {
+      LOG(WARNING) << "Can't set MTU, no existing connection to " << address;
+      return false;
+    }
+  }
+
+  bt_status_t status = hal::BluetoothGattInterface::Get()->
+      GetClientHALInterface()->configure_mtu(conn_id->second, mtu);
+  if (status != BT_STATUS_SUCCESS) {
+    LOG(ERROR) << "HAL call to set MTU failed";
+    return false;
+  }
+
+  return true;
+}
+
 void LowEnergyClient::SetDelegate(Delegate* delegate) {
   lock_guard<mutex> lock(delegate_mutex_);
   delegate_ = delegate;
@@ -597,6 +624,31 @@ void LowEnergyClient::DisconnectCallback(
                                  false);
 }
 
+void LowEnergyClient::MtuChangedCallback(
+      hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
+      int mtu) {
+  VLOG(1) << __func__ << " conn_id: " << conn_id << " status: " << status
+          << " mtu: " << mtu;
+
+  const bt_bdaddr_t *bda = nullptr;
+  {
+    lock_guard<mutex> lock(connection_fields_lock_);
+    for (auto& connection: connection_ids_) {
+      if (connection.second == conn_id) {
+        bda = &connection.first;
+        break;
+      }
+    }
+  }
+
+  if (!bda)
+    return;
+
+  const char *addr = BtAddrString(bda).c_str();
+  if (delegate_)
+    delegate_->OnMtuChanged(this, status, addr, mtu);
+}
+
 void LowEnergyClient::MultiAdvEnableCallback(
     hal::BluetoothGattInterface* gatt_iface,
     int client_id, int status) {
index 700ad9c..45ff662 100644 (file)
@@ -65,6 +65,10 @@ class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
     virtual void OnConnectionState(LowEnergyClient* client, int status,
                                    const char* address, bool connected) = 0;
 
+    // Called asynchronously to notify the delegate of mtu change
+    virtual void OnMtuChanged(LowEnergyClient* client, int status, const char* address,
+                              int mtu) = 0;
+
    private:
     DISALLOW_COPY_AND_ASSIGN(Delegate);
   };
@@ -89,6 +93,10 @@ class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
   // Return true on success, false otherwise.
   bool Disconnect(std::string address);
 
+  // Sends request to set MTU to |mtu| for device with address |address|.
+  // Return true on success, false otherwise.
+  bool SetMtu(std::string address, int mtu);
+
   // Initiates a BLE device scan for this client using the given |settings| and
   // |filters|. See the documentation for ScanSettings and ScanFilter for how
   // these parameters can be configured. Return true on success, false
@@ -149,6 +157,9 @@ class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
   void DisconnectCallback(
       hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
       int client_id, const bt_bdaddr_t& bda) override;
+  void MtuChangedCallback(
+      hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
+      int mtu) override;
   void MultiAdvEnableCallback(
       hal::BluetoothGattInterface* gatt_iface,
       int client_id, int status) override;
@@ -220,6 +231,7 @@ class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
   std::mutex connection_fields_lock_;
 
   // Maps bluetooth address to connection id
+  //TODO(jpawlowski): change type to bimap
   std::map<const bt_bdaddr_t, int, ConnComparator> connection_ids_;
 
   DISALLOW_COPY_AND_ASSIGN(LowEnergyClient);
index 70bbd2a..cecdc8e 100644 (file)
@@ -77,7 +77,8 @@ class MockGattHandler
 
 class TestDelegate : public LowEnergyClient::Delegate {
  public:
-  TestDelegate() : scan_result_count_(0), connection_state_count_(0) {
+  TestDelegate() : scan_result_count_(0), connection_state_count_(0),
+                   last_mtu_(0) {
   }
 
   ~TestDelegate() override = default;
@@ -93,6 +94,12 @@ class TestDelegate : public LowEnergyClient::Delegate {
     connection_state_count_++;
   }
 
+  void OnMtuChanged(LowEnergyClient* client, int status, const char* address,
+                    int mtu) {
+    ASSERT_TRUE(client);
+    last_mtu_ = mtu;
+  }
+
   void OnScanResult(LowEnergyClient* client, const ScanResult& scan_result) {
     ASSERT_TRUE(client);
     scan_result_count_++;
@@ -105,6 +112,8 @@ class TestDelegate : public LowEnergyClient::Delegate {
 
   int connection_state_count_;
 
+  int last_mtu_;
+
   DISALLOW_COPY_AND_ASSIGN(TestDelegate);
 };