Loading android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java +20 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ class AdvertiseHelper { type = COMPLETE_LOCAL_NAME; } check_length(type, nameLength + 1); ret.write(nameLength + 1); ret.write(type); ret.write(nameBytes, 0, nameLength); Loading @@ -92,6 +93,7 @@ class AdvertiseHelper { System.arraycopy(manufacturerData, 0, concated, 2, manufacturerData.length); } check_length(MANUFACTURER_SPECIFIC_DATA, concated.length + 1); ret.write(concated.length + 1); ret.write(MANUFACTURER_SPECIFIC_DATA); ret.write(concated, 0, concated.length); Loading Loading @@ -121,18 +123,21 @@ class AdvertiseHelper { } if (serviceUuids16.size() != 0) { check_length(COMPLETE_LIST_16_BIT_SERVICE_UUIDS, serviceUuids16.size() + 1); ret.write(serviceUuids16.size() + 1); ret.write(COMPLETE_LIST_16_BIT_SERVICE_UUIDS); ret.write(serviceUuids16.toByteArray(), 0, serviceUuids16.size()); } if (serviceUuids32.size() != 0) { check_length(COMPLETE_LIST_32_BIT_SERVICE_UUIDS, serviceUuids32.size() + 1); ret.write(serviceUuids32.size() + 1); ret.write(COMPLETE_LIST_32_BIT_SERVICE_UUIDS); ret.write(serviceUuids32.toByteArray(), 0, serviceUuids32.size()); } if (serviceUuids128.size() != 0) { check_length(COMPLETE_LIST_128_BIT_SERVICE_UUIDS, serviceUuids32.size() + 1); ret.write(serviceUuids128.size() + 1); ret.write(COMPLETE_LIST_128_BIT_SERVICE_UUIDS); ret.write(serviceUuids128.toByteArray(), 0, serviceUuids128.size()); Loading @@ -156,14 +161,17 @@ class AdvertiseHelper { } if (uuid.length == BluetoothUuid.UUID_BYTES_16_BIT) { check_length(SERVICE_DATA_16_BIT_UUID, concated.length + 1); ret.write(concated.length + 1); ret.write(SERVICE_DATA_16_BIT_UUID); ret.write(concated, 0, concated.length); } else if (uuid.length == BluetoothUuid.UUID_BYTES_32_BIT) { check_length(SERVICE_DATA_32_BIT_UUID, concated.length + 1); ret.write(concated.length + 1); ret.write(SERVICE_DATA_32_BIT_UUID); ret.write(concated, 0, concated.length); } else /*if (uuid.length == BluetoothUuid.UUID_BYTES_128_BIT)*/ { check_length(SERVICE_DATA_128_BIT_UUID, concated.length + 1); ret.write(concated.length + 1); ret.write(SERVICE_DATA_128_BIT_UUID); ret.write(concated, 0, concated.length); Loading @@ -190,18 +198,21 @@ class AdvertiseHelper { } if (serviceUuids16.size() != 0) { check_length(LIST_16_BIT_SERVICE_SOLICITATION_UUIDS, serviceUuids16.size() + 1); ret.write(serviceUuids16.size() + 1); ret.write(LIST_16_BIT_SERVICE_SOLICITATION_UUIDS); ret.write(serviceUuids16.toByteArray(), 0, serviceUuids16.size()); } if (serviceUuids32.size() != 0) { check_length(LIST_32_BIT_SERVICE_SOLICITATION_UUIDS, serviceUuids32.size() + 1); ret.write(serviceUuids32.size() + 1); ret.write(LIST_32_BIT_SERVICE_SOLICITATION_UUIDS); ret.write(serviceUuids32.toByteArray(), 0, serviceUuids32.size()); } if (serviceUuids128.size() != 0) { check_length(LIST_128_BIT_SERVICE_SOLICITATION_UUIDS, serviceUuids128.size() + 1); ret.write(serviceUuids128.size() + 1); ret.write(LIST_128_BIT_SERVICE_SOLICITATION_UUIDS); ret.write(serviceUuids128.toByteArray(), 0, serviceUuids128.size()); Loading @@ -209,6 +220,7 @@ class AdvertiseHelper { } for (TransportDiscoveryData transportDiscoveryData : data.getTransportDiscoveryData()) { check_length(TRANSPORT_DISCOVERY_DATA, transportDiscoveryData.totalBytes() + 1); ret.write(transportDiscoveryData.totalBytes() + 1); ret.write(TRANSPORT_DISCOVERY_DATA); ret.write(transportDiscoveryData.toByteArray(), Loading @@ -216,4 +228,12 @@ class AdvertiseHelper { } return ret.toByteArray(); } static void check_length(int type, int length) { if (length > 255) { Log.w(TAG, "Length of data with type " + Integer.toString(type, 16) + " is grater than 255"); throw new IllegalArgumentException("Length of data is grater than 255"); } } } android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java +50 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.bluetooth.gatt; import android.bluetooth.le.AdvertiseCallback; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertisingSetParameters; import android.bluetooth.le.IAdvertisingSetCallback; Loading Loading @@ -195,9 +196,12 @@ class AdvertiseManager { } String deviceName = AdapterService.getAdapterService().getName(); try { byte[] advDataBytes = AdvertiseHelper.advertiseDataToBytes(advertiseData, deviceName); byte[] scanResponseBytes = AdvertiseHelper.advertiseDataToBytes(scanResponse, deviceName); byte[] periodicDataBytes = AdvertiseHelper.advertiseDataToBytes(periodicData, deviceName); byte[] scanResponseBytes = AdvertiseHelper.advertiseDataToBytes(scanResponse, deviceName); byte[] periodicDataBytes = AdvertiseHelper.advertiseDataToBytes(periodicData, deviceName); int cbId = --sTempRegistrationId; mAdvertisers.put(binder, new AdvertiserInfo(cbId, deathRecipient, callback)); Loading @@ -207,6 +211,16 @@ class AdvertiseManager { } startAdvertisingSetNative(parameters, advDataBytes, scanResponseBytes, periodicParameters, periodicDataBytes, duration, maxExtAdvEvents, cbId); } catch (IllegalArgumentException e) { try { binder.unlinkToDeath(deathRecipient, 0); callback.onAdvertisingSetStarted(0x00, 0x00, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (RemoteException exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } } } void onOwnAddressRead(int advertiserId, int addressType, String address) Loading Loading @@ -280,8 +294,17 @@ class AdvertiseManager { return; } String deviceName = AdapterService.getAdapterService().getName(); try { setAdvertisingDataNative(advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); } catch (IllegalArgumentException e) { try { onAdvertisingDataSet(advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } } } void setScanResponseData(int advertiserId, AdvertiseData data) { Loading @@ -291,8 +314,17 @@ class AdvertiseManager { return; } String deviceName = AdapterService.getAdapterService().getName(); try { setScanResponseDataNative(advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); } catch (IllegalArgumentException e) { try { onScanResponseDataSet(advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } } } void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters) { Loading Loading @@ -321,8 +353,17 @@ class AdvertiseManager { return; } String deviceName = AdapterService.getAdapterService().getName(); try { setPeriodicAdvertisingDataNative(advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); } catch (IllegalArgumentException e) { try { onPeriodicAdvertisingDataSet(advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } } } void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) { Loading system/gd/hci/le_advertising_manager.cc +27 −0 Original line number Diff line number Diff line Loading @@ -351,6 +351,14 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb return; } // check extended advertising data is valid before start advertising if (!check_extended_advertising_data(config.advertisement) || !check_extended_advertising_data(config.scan_response)) { advertising_callbacks_->OnAdvertisingSetStarted( reg_id, id, le_physical_channel_tx_power_, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE); return; } if (!address_manager_registered) { le_address_manager_->Register(this); address_manager_registered = true; Loading Loading @@ -629,6 +637,25 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb } } bool check_extended_advertising_data(std::vector<GapData> data) { uint16_t data_len = 0; // check data size for (size_t i = 0; i < data.size(); i++) { if (data[i].size() > kLeMaximumFragmentLength) { LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength); return false; } data_len += data[i].size(); } if (data_len > le_maximum_advertising_data_length_) { LOG_WARN( "advertising data len exceeds le_maximum_advertising_data_length_ %d", le_maximum_advertising_data_length_); return false; } return true; }; void set_data(AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data) { if (!set_scan_rsp && advertising_sets_[advertiser_id].connectable) { GapData gap_data; Loading Loading
android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java +20 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ class AdvertiseHelper { type = COMPLETE_LOCAL_NAME; } check_length(type, nameLength + 1); ret.write(nameLength + 1); ret.write(type); ret.write(nameBytes, 0, nameLength); Loading @@ -92,6 +93,7 @@ class AdvertiseHelper { System.arraycopy(manufacturerData, 0, concated, 2, manufacturerData.length); } check_length(MANUFACTURER_SPECIFIC_DATA, concated.length + 1); ret.write(concated.length + 1); ret.write(MANUFACTURER_SPECIFIC_DATA); ret.write(concated, 0, concated.length); Loading Loading @@ -121,18 +123,21 @@ class AdvertiseHelper { } if (serviceUuids16.size() != 0) { check_length(COMPLETE_LIST_16_BIT_SERVICE_UUIDS, serviceUuids16.size() + 1); ret.write(serviceUuids16.size() + 1); ret.write(COMPLETE_LIST_16_BIT_SERVICE_UUIDS); ret.write(serviceUuids16.toByteArray(), 0, serviceUuids16.size()); } if (serviceUuids32.size() != 0) { check_length(COMPLETE_LIST_32_BIT_SERVICE_UUIDS, serviceUuids32.size() + 1); ret.write(serviceUuids32.size() + 1); ret.write(COMPLETE_LIST_32_BIT_SERVICE_UUIDS); ret.write(serviceUuids32.toByteArray(), 0, serviceUuids32.size()); } if (serviceUuids128.size() != 0) { check_length(COMPLETE_LIST_128_BIT_SERVICE_UUIDS, serviceUuids32.size() + 1); ret.write(serviceUuids128.size() + 1); ret.write(COMPLETE_LIST_128_BIT_SERVICE_UUIDS); ret.write(serviceUuids128.toByteArray(), 0, serviceUuids128.size()); Loading @@ -156,14 +161,17 @@ class AdvertiseHelper { } if (uuid.length == BluetoothUuid.UUID_BYTES_16_BIT) { check_length(SERVICE_DATA_16_BIT_UUID, concated.length + 1); ret.write(concated.length + 1); ret.write(SERVICE_DATA_16_BIT_UUID); ret.write(concated, 0, concated.length); } else if (uuid.length == BluetoothUuid.UUID_BYTES_32_BIT) { check_length(SERVICE_DATA_32_BIT_UUID, concated.length + 1); ret.write(concated.length + 1); ret.write(SERVICE_DATA_32_BIT_UUID); ret.write(concated, 0, concated.length); } else /*if (uuid.length == BluetoothUuid.UUID_BYTES_128_BIT)*/ { check_length(SERVICE_DATA_128_BIT_UUID, concated.length + 1); ret.write(concated.length + 1); ret.write(SERVICE_DATA_128_BIT_UUID); ret.write(concated, 0, concated.length); Loading @@ -190,18 +198,21 @@ class AdvertiseHelper { } if (serviceUuids16.size() != 0) { check_length(LIST_16_BIT_SERVICE_SOLICITATION_UUIDS, serviceUuids16.size() + 1); ret.write(serviceUuids16.size() + 1); ret.write(LIST_16_BIT_SERVICE_SOLICITATION_UUIDS); ret.write(serviceUuids16.toByteArray(), 0, serviceUuids16.size()); } if (serviceUuids32.size() != 0) { check_length(LIST_32_BIT_SERVICE_SOLICITATION_UUIDS, serviceUuids32.size() + 1); ret.write(serviceUuids32.size() + 1); ret.write(LIST_32_BIT_SERVICE_SOLICITATION_UUIDS); ret.write(serviceUuids32.toByteArray(), 0, serviceUuids32.size()); } if (serviceUuids128.size() != 0) { check_length(LIST_128_BIT_SERVICE_SOLICITATION_UUIDS, serviceUuids128.size() + 1); ret.write(serviceUuids128.size() + 1); ret.write(LIST_128_BIT_SERVICE_SOLICITATION_UUIDS); ret.write(serviceUuids128.toByteArray(), 0, serviceUuids128.size()); Loading @@ -209,6 +220,7 @@ class AdvertiseHelper { } for (TransportDiscoveryData transportDiscoveryData : data.getTransportDiscoveryData()) { check_length(TRANSPORT_DISCOVERY_DATA, transportDiscoveryData.totalBytes() + 1); ret.write(transportDiscoveryData.totalBytes() + 1); ret.write(TRANSPORT_DISCOVERY_DATA); ret.write(transportDiscoveryData.toByteArray(), Loading @@ -216,4 +228,12 @@ class AdvertiseHelper { } return ret.toByteArray(); } static void check_length(int type, int length) { if (length > 255) { Log.w(TAG, "Length of data with type " + Integer.toString(type, 16) + " is grater than 255"); throw new IllegalArgumentException("Length of data is grater than 255"); } } }
android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java +50 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.bluetooth.gatt; import android.bluetooth.le.AdvertiseCallback; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertisingSetParameters; import android.bluetooth.le.IAdvertisingSetCallback; Loading Loading @@ -195,9 +196,12 @@ class AdvertiseManager { } String deviceName = AdapterService.getAdapterService().getName(); try { byte[] advDataBytes = AdvertiseHelper.advertiseDataToBytes(advertiseData, deviceName); byte[] scanResponseBytes = AdvertiseHelper.advertiseDataToBytes(scanResponse, deviceName); byte[] periodicDataBytes = AdvertiseHelper.advertiseDataToBytes(periodicData, deviceName); byte[] scanResponseBytes = AdvertiseHelper.advertiseDataToBytes(scanResponse, deviceName); byte[] periodicDataBytes = AdvertiseHelper.advertiseDataToBytes(periodicData, deviceName); int cbId = --sTempRegistrationId; mAdvertisers.put(binder, new AdvertiserInfo(cbId, deathRecipient, callback)); Loading @@ -207,6 +211,16 @@ class AdvertiseManager { } startAdvertisingSetNative(parameters, advDataBytes, scanResponseBytes, periodicParameters, periodicDataBytes, duration, maxExtAdvEvents, cbId); } catch (IllegalArgumentException e) { try { binder.unlinkToDeath(deathRecipient, 0); callback.onAdvertisingSetStarted(0x00, 0x00, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (RemoteException exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } } } void onOwnAddressRead(int advertiserId, int addressType, String address) Loading Loading @@ -280,8 +294,17 @@ class AdvertiseManager { return; } String deviceName = AdapterService.getAdapterService().getName(); try { setAdvertisingDataNative(advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); } catch (IllegalArgumentException e) { try { onAdvertisingDataSet(advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } } } void setScanResponseData(int advertiserId, AdvertiseData data) { Loading @@ -291,8 +314,17 @@ class AdvertiseManager { return; } String deviceName = AdapterService.getAdapterService().getName(); try { setScanResponseDataNative(advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); } catch (IllegalArgumentException e) { try { onScanResponseDataSet(advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } } } void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters) { Loading Loading @@ -321,8 +353,17 @@ class AdvertiseManager { return; } String deviceName = AdapterService.getAdapterService().getName(); try { setPeriodicAdvertisingDataNative(advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName)); } catch (IllegalArgumentException e) { try { onPeriodicAdvertisingDataSet(advertiserId, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE); } catch (Exception exception) { Log.e(TAG, "Failed to callback:" + Log.getStackTraceString(exception)); } } } void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) { Loading
system/gd/hci/le_advertising_manager.cc +27 −0 Original line number Diff line number Diff line Loading @@ -351,6 +351,14 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb return; } // check extended advertising data is valid before start advertising if (!check_extended_advertising_data(config.advertisement) || !check_extended_advertising_data(config.scan_response)) { advertising_callbacks_->OnAdvertisingSetStarted( reg_id, id, le_physical_channel_tx_power_, AdvertisingCallback::AdvertisingStatus::DATA_TOO_LARGE); return; } if (!address_manager_registered) { le_address_manager_->Register(this); address_manager_registered = true; Loading Loading @@ -629,6 +637,25 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb } } bool check_extended_advertising_data(std::vector<GapData> data) { uint16_t data_len = 0; // check data size for (size_t i = 0; i < data.size(); i++) { if (data[i].size() > kLeMaximumFragmentLength) { LOG_WARN("AD data len shall not greater than %d", kLeMaximumFragmentLength); return false; } data_len += data[i].size(); } if (data_len > le_maximum_advertising_data_length_) { LOG_WARN( "advertising data len exceeds le_maximum_advertising_data_length_ %d", le_maximum_advertising_data_length_); return false; } return true; }; void set_data(AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data) { if (!set_scan_rsp && advertising_sets_[advertiser_id].connectable) { GapData gap_data; Loading