Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63dea920 authored by Jack He's avatar Jack He Committed by Gerrit Code Review
Browse files

Merge "Check length of advertising data"

parents 407f75ba e5550443
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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);
@@ -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());
@@ -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);
@@ -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());
@@ -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(),
@@ -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");
        }
    }
}
+50 −9
Original line number Diff line number Diff line
@@ -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;
@@ -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));
@@ -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)
@@ -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) {
@@ -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) {
@@ -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) {
+27 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;