11a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang/*
21a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * Copyright (C) 2013 The Android Open Source Project
31a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang *
41a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * Licensed under the Apache License, Version 2.0 (the "License");
51a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * you may not use this file except in compliance with the License.
61a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * You may obtain a copy of the License at
71a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang *
81a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang *      http://www.apache.org/licenses/LICENSE-2.0
91a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang *
101a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * Unless required by applicable law or agreed to in writing, software
111a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * distributed under the License is distributed on an "AS IS" BASIS,
121a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * See the License for the specific language governing permissions and
141a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * limitations under the License.
151a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang */
161a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
171a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wangpackage com.android.bluetooth.gatt;
181a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
19466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wangimport android.bluetooth.BluetoothUuid;
2080e7d011fdb511a6583258458e97821176866baaWei Wangimport android.bluetooth.le.ScanFilter;
21466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wangimport android.os.ParcelUuid;
221a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
2380780da923f52a6b5a80f8619cf3e735970eaad9Wei Wangimport java.util.Arrays;
241a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wangimport java.util.HashSet;
251a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wangimport java.util.Iterator;
261a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wangimport java.util.Objects;
271a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wangimport java.util.Set;
281a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wangimport java.util.UUID;
291a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
301a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang/**
311a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * Helper class used to manage advertisement package filters.
321a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang *
331a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang * @hide
341a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang */
351a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang/* package */class ScanFilterQueue {
361a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    public static final int TYPE_DEVICE_ADDRESS = 0;
37466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang    public static final int TYPE_SERVICE_DATA_CHANGED = 1;
381a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    public static final int TYPE_SERVICE_UUID = 2;
391a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    public static final int TYPE_SOLICIT_UUID = 3;
401a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    public static final int TYPE_LOCAL_NAME = 4;
411a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    public static final int TYPE_MANUFACTURER_DATA = 5;
42466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang    public static final int TYPE_SERVICE_DATA = 6;
43466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang
44466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang    // Max length is 31 - 3(flags) - 2 (one byte for length and one byte for type).
45466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang    private static final int MAX_LEN_PER_FIELD = 26;
461a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
471a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    // Values defined in bluedroid.
4814929a82d56b94b9b75e2aefeb9c6ef29482eed0Wei Wang    private static final byte DEVICE_TYPE_ALL = 2;
491a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
501a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    class Entry {
511a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public String address;
521a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public byte addr_type;
531a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public byte type;
541a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public UUID uuid;
551a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public UUID uuid_mask;
561a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public String name;
571a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public int company;
581a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public int company_mask;
591a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public byte[] data;
601a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public byte[] data_mask;
611a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
621a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        @Override
631a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public int hashCode() {
641a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            return Objects.hash(address, addr_type, type, uuid, uuid_mask, name, company,
651a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                    company_mask, data, data_mask);
661a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        }
671a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
681a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        @Override
691a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        public boolean equals(Object obj) {
701a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            if (this == obj) {
711a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                return true;
721a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            }
731a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            if (obj == null || getClass() != obj.getClass()) {
741a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                return false;
751a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            }
762b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang            Entry other = (Entry) obj;
771a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            return Objects.equals(address, other.address) &&
781a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                    addr_type == other.addr_type && type == other.type &&
791a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                    Objects.equals(uuid, other.uuid) &&
801a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                    Objects.equals(uuid_mask, other.uuid_mask) &&
811a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                    Objects.equals(name, other.name) &&
822b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang                            company == other.company && company_mask == other.company_mask &&
831a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                    Objects.deepEquals(data, other.data) &&
841a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                    Objects.deepEquals(data_mask, other.data_mask);
851a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        }
861a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
871a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
881a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    private Set<Entry> mEntries = new HashSet<Entry>();
891a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
901a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void addDeviceAddress(String address, byte type) {
911a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = new Entry();
921a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.type = TYPE_DEVICE_ADDRESS;
931a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.address = address;
941a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.addr_type = type;
951a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.add(entry);
961a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
971a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
981a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void addServiceChanged() {
991a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = new Entry();
100466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        entry.type = TYPE_SERVICE_DATA_CHANGED;
1011a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.add(entry);
1021a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1031a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1041a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void addUuid(UUID uuid) {
1051a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = new Entry();
1061a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.type = TYPE_SERVICE_UUID;
1071a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.uuid = uuid;
1081a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.uuid_mask = new UUID(0, 0);
1091a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.add(entry);
1101a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1111a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1121a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void addUuid(UUID uuid, UUID uuid_mask) {
1131a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = new Entry();
1141a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.type = TYPE_SERVICE_UUID;
1151a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.uuid = uuid;
1161a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.uuid_mask = uuid_mask;
1171a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.add(entry);
1181a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1191a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1201a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void addSolicitUuid(UUID uuid) {
1211a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = new Entry();
1221a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.type = TYPE_SOLICIT_UUID;
1231a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.uuid = uuid;
1241a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.add(entry);
1251a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1261a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1271a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void addName(String name) {
1281a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = new Entry();
1291a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.type = TYPE_LOCAL_NAME;
1301a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.name = name;
1311a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.add(entry);
1321a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1331a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1341a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void addManufacturerData(int company, byte[] data) {
1351a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = new Entry();
1361a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.type = TYPE_MANUFACTURER_DATA;
1371a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.company = company;
1381a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.company_mask = 0xFFFF;
1391a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.data = data;
14080780da923f52a6b5a80f8619cf3e735970eaad9Wei Wang        entry.data_mask = new byte[data.length];
14180780da923f52a6b5a80f8619cf3e735970eaad9Wei Wang        Arrays.fill(entry.data_mask, (byte) 0xFF);
1421a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.add(entry);
1431a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1441a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1451a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void addManufacturerData(int company, int company_mask, byte[] data, byte[] data_mask) {
1461a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = new Entry();
1471a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.type = TYPE_MANUFACTURER_DATA;
1481a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.company = company;
1491a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.company_mask = company_mask;
1501a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.data = data;
1511a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        entry.data_mask = data_mask;
1521a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.add(entry);
1531a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1541a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
155466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang    void addServiceData(byte[] data, byte[] dataMask) {
156466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        Entry entry = new Entry();
157466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        entry.type = TYPE_SERVICE_DATA;
158466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        entry.data = data;
159466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        entry.data_mask = dataMask;
160466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        mEntries.add(entry);
161466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang    }
162466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang
1631a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    Entry pop() {
1641a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        if (isEmpty()) {
1651a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            return null;
1661a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        }
1671a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Iterator<Entry> iterator = mEntries.iterator();
1681a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        Entry entry = iterator.next();
1691a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        iterator.remove();
1701a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        return entry;
1711a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1721a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1731a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    boolean isEmpty() {
1741a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        return mEntries.isEmpty();
1751a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1761a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1771a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void clearUuids() {
1781a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        for (Iterator<Entry> it = mEntries.iterator(); it.hasNext();) {
1791a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            Entry entry = it.next();
1801a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            if (entry.type == TYPE_SERVICE_UUID)
1811a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang                it.remove();
1821a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        }
1831a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1841a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1851a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    void clear() {
1861a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        mEntries.clear();
1871a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
1881a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang
1892b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang    /**
1902b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang     * Compute feature selection based on the filters presented.
1912b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang     */
1922b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang    int getFeatureSelection() {
1932b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        int selc = 0;
1942b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        for (Entry entry : mEntries) {
1952b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang            selc |= (1 << entry.type);
1962b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        }
1972b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        return selc;
1982b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang    }
1992b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang
2002b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang    /**
2012b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang     * Add ScanFilter to scan filter queue.
2022b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang     */
2032b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang    void addScanFilter(ScanFilter filter) {
2042b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        if (filter == null)
2051a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            return;
206361e580eb6c07759cdd775ed57902839ff4bfe90Andre Eisenbach        if (filter.getDeviceName() != null) {
207361e580eb6c07759cdd775ed57902839ff4bfe90Andre Eisenbach            addName(filter.getDeviceName());
2082b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        }
2092b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        if (filter.getDeviceAddress() != null) {
2102b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang            addDeviceAddress(filter.getDeviceAddress(), DEVICE_TYPE_ALL);
2112b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        }
2122b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        if (filter.getServiceUuid() != null) {
2132b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang            if (filter.getServiceUuidMask() == null) {
2142b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang                addUuid(filter.getServiceUuid().getUuid());
2152b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang            } else {
2162b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang                addUuid(filter.getServiceUuid().getUuid(),
2172b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang                        filter.getServiceUuidMask().getUuid());
2181a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            }
2192b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        }
2202b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang        if (filter.getManufacturerData() != null) {
2212b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang            if (filter.getManufacturerDataMask() == null) {
2222b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang                addManufacturerData(filter.getManufacturerId(), filter.getManufacturerData());
2232b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang            } else {
2242b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang                addManufacturerData(filter.getManufacturerId(), 0xFFFF,
2252b670d217c743a7a8082f1d72baf532ef66ba21cWei Wang                        filter.getManufacturerData(), filter.getManufacturerDataMask());
2261a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang            }
2271a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang        }
228466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        if (filter.getServiceDataUuid() != null && filter.getServiceData() != null) {
229466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            ParcelUuid serviceDataUuid = filter.getServiceDataUuid();
230466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            byte[] serviceData = filter.getServiceData();
231466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            byte[] serviceDataMask = filter.getServiceDataMask();
232466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            if (serviceDataMask == null) {
233466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang                serviceDataMask = new byte[serviceData.length];
234466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang                Arrays.fill(serviceDataMask, (byte) 0xFF);
235466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            }
236466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            serviceData = concate(serviceDataUuid, serviceData);
237466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            serviceDataMask = concate(serviceDataUuid, serviceDataMask);
238466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            if (serviceData != null && serviceDataMask != null) {
239466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang                addServiceData(serviceData, serviceDataMask);
240466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            }
241466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        }
242466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang    }
243466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang
244466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang    private byte[] concate(ParcelUuid serviceDataUuid, byte[] serviceData) {
245466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        int dataLen = 2 + (serviceData == null ? 0 : serviceData.length);
246466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        // If data is too long, don't add it to hardware scan filter.
247466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        if (dataLen > MAX_LEN_PER_FIELD) {
248466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            return null;
249466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        }
250466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        byte[] concated = new byte[dataLen];
251466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        // Extract 16 bit UUID value.
252466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        int uuidValue = BluetoothUuid.getServiceIdentifierFromParcelUuid(
253466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang                serviceDataUuid);
254466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        // First two bytes are service data UUID in little-endian.
255466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        concated[0] = (byte) (uuidValue & 0xFF);
256466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        concated[1] = (byte) ((uuidValue >> 8) & 0xFF);
257466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        if (serviceData != null) {
258466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang            System.arraycopy(serviceData, 0, concated, 2, serviceData.length);
259466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        }
260466e67f34a72bbb43fa03aae7ad96cb41f02451dWei Wang        return concated;
2611a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang    }
2621a2f87a202a4d634f0b6b5b6e9a8545796207288Wei Wang}
263