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