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

Commit 6934f9c5 authored by Wei Wang's avatar Wei Wang
Browse files

Add protection for controller timeout/failure, maximum number of

advertisers, filters etc.

Change-Id: I94b719ddc0d9943c1a3c304285969d4c80e50a69
parent 5582e3c6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -88,6 +88,9 @@ public class GattService extends ProfileService {
    static final int SCAN_FILTER_ENABLED = 1;
    static final int SCAN_FILTER_MODIFIED = 2;

    // TODO: query the number from hardware instead of hard-coded here.
    private static final int MAX_FILTER_SIZE = 1;

    /**
     * Search queue to serialize remote onbject inspection.
     */
@@ -1318,6 +1321,11 @@ public class GattService extends ProfileService {
            }
            filters.addAll(client.filters);
        }
        // TODO: find a better way to handle too many filters.
        if (filters.size() > MAX_FILTER_SIZE) {
            if (DBG) Log.d(TAG, "filters size > " + MAX_FILTER_SIZE + ", clearing filters");
            filters = new HashSet<ScanFilter>();
        }
        return filters;
    }

+27 −2
Original line number Diff line number Diff line
@@ -54,6 +54,13 @@ final class GattServiceStateMachine extends StateMachine {
    static final int ADD_SCAN_FILTER = 16;
    static final int ENABLE_SCAN_FILTER = 17;

    // TODO: This should be queried from hardware.
    private final int MAX_ADVERTISERS = 4;

    // TODO: Remove this once stack callback is stable.
    private static final int OPERATION_TIMEOUT = 101;
    private static final int TIMEOUT_MILLIS = 3000;

    private static final String TAG = "GattServiceStateMachine";
    private static final boolean DBG = true;

@@ -159,14 +166,13 @@ final class GattServiceStateMachine extends StateMachine {
                    break;
                case STOP_BLE_SCAN:
                    // Note this should only happen no client is doing scans any more.
                    gattClientScanFilterClearNative();
                    gattClientScanNative(false);
                    break;
                case START_ADVERTISING:
                    AdvertiseClient client = (AdvertiseClient) message.obj;
                    if (mAdvertiseClients.containsKey(client.clientIf)) {
                        // do something.
                        log("advertising already started for client : " + client.clientIf);
                        loge("advertising already started for client : " + client.clientIf);
                        try {
                            mService.onMultipleAdvertiseCallback(client.clientIf,
                                    AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
@@ -176,6 +182,17 @@ final class GattServiceStateMachine extends StateMachine {
                        transitionTo(mIdle);
                        break;
                    }
                    if (mAdvertiseClients.size() >= MAX_ADVERTISERS) {
                        loge("too many advertisier, current size : " + mAdvertiseClients.size());
                        try {
                            mService.onMultipleAdvertiseCallback(client.clientIf,
                                    AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS);
                        } catch (RemoteException e) {
                            loge("failed to start advertising", e);
                        }
                        transitionTo(mIdle);
                        break;
                    }
                    newMessage = obtainMessage(ENABLE_ADVERTISING);
                    newMessage.obj = message.obj;
                    sendMessage(newMessage);
@@ -239,6 +256,7 @@ final class GattServiceStateMachine extends StateMachine {
                        hasFilter = true;
                    }
                    gattClientScanFilterClearNative();
                    sendMessageDelayed(OPERATION_TIMEOUT, TIMEOUT_MILLIS);
                    break;
                case ADD_SCAN_FILTER:
                    if (mScanFilterQueue.isEmpty()) {
@@ -261,6 +279,10 @@ final class GattServiceStateMachine extends StateMachine {
                    break;
                case ENABLE_BLE_SCAN:
                    gattClientScanNative(true);
                    removeMessages(OPERATION_TIMEOUT);
                    transitionTo(mIdle);
                    break;
                case OPERATION_TIMEOUT:
                    transitionTo(mIdle);
                    break;
                default:
@@ -339,6 +361,7 @@ final class GattServiceStateMachine extends StateMachine {
                    AdvertiseClient client = (AdvertiseClient) message.obj;
                    mAdvertiseClients.put(client.clientIf, client);
                    enableAdvertising(client);
                    sendMessageDelayed(OPERATION_TIMEOUT, client.clientIf, TIMEOUT_MILLIS);
                    break;
                case SET_ADVERTISING_DATA:
                    int clientIf = message.arg1;
@@ -348,9 +371,11 @@ final class GattServiceStateMachine extends StateMachine {
                    if (client.scanResponse != null) {
                        setAdvertisingData(clientIf, client.scanResponse, true);
                    }
                    removeMessages(OPERATION_TIMEOUT);
                    transitionTo(mIdle);
                    break;
                case CANCEL_ADVERTISING:
                case OPERATION_TIMEOUT:
                    clientIf = message.arg1;
                    try {
                        mService.onMultipleAdvertiseCallback(clientIf,
+3 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.bluetooth.gatt;

import android.bluetooth.le.ScanFilter;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
@@ -130,7 +131,8 @@ import java.util.UUID;
        entry.company = company;
        entry.company_mask = 0xFFFF;
        entry.data = data;
        entry.data_mask = new byte[0];
        entry.data_mask = new byte[data.length];
        Arrays.fill(entry.data_mask, (byte) 0xFF);
        mEntries.add(entry);
    }