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;
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);
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,
CONNECT_TRANSACTION,
DISCONNECT_TRANSACTION,
+ SET_MTU_TRANSACTION,
READ_REMOTE_RSSI_TRANSACTION,
CONFIGURE_ATT_MTU_TRANSACTION,
CONNECTION_PARAMETER_UPDATE_TRANSACTION,
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,
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,
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());
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;
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,
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,
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,
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
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
// 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){
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,
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) {
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,
// 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;
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;
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) {
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);
};
// 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
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;
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);
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;
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_++;
int connection_state_count_;
+ int last_mtu_;
+
DISALLOW_COPY_AND_ASSIGN(TestDelegate);
};