File: ScanResult.java

package info (click to toggle)
android-platform-frameworks-base 1%3A10.0.0%2Br36-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 321,788 kB
  • sloc: java: 962,234; cpp: 274,314; xml: 242,770; python: 5,060; sh: 1,432; ansic: 494; makefile: 47; sed: 19
file content (353 lines) | stat: -rw-r--r-- 11,381 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth.le;

import android.annotation.Nullable;
import android.bluetooth.BluetoothDevice;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Objects;

/**
 * ScanResult for Bluetooth LE scan.
 */
public final class ScanResult implements Parcelable {

    /**
     * For chained advertisements, inidcates tha the data contained in this
     * scan result is complete.
     */
    public static final int DATA_COMPLETE = 0x00;

    /**
     * For chained advertisements, indicates that the controller was
     * unable to receive all chained packets and the scan result contains
     * incomplete truncated data.
     */
    public static final int DATA_TRUNCATED = 0x02;

    /**
     * Indicates that the secondary physical layer was not used.
     */
    public static final int PHY_UNUSED = 0x00;

    /**
     * Advertising Set ID is not present in the packet.
     */
    public static final int SID_NOT_PRESENT = 0xFF;

    /**
     * TX power is not present in the packet.
     */
    public static final int TX_POWER_NOT_PRESENT = 0x7F;

    /**
     * Periodic advertising interval is not present in the packet.
     */
    public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0x00;

    /**
     * Mask for checking whether event type represents legacy advertisement.
     */
    private static final int ET_LEGACY_MASK = 0x10;

    /**
     * Mask for checking whether event type represents connectable advertisement.
     */
    private static final int ET_CONNECTABLE_MASK = 0x01;

    // Remote Bluetooth device.
    private BluetoothDevice mDevice;

    // Scan record, including advertising data and scan response data.
    @Nullable
    private ScanRecord mScanRecord;

    // Received signal strength.
    private int mRssi;

    // Device timestamp when the result was last seen.
    private long mTimestampNanos;

    private int mEventType;
    private int mPrimaryPhy;
    private int mSecondaryPhy;
    private int mAdvertisingSid;
    private int mTxPower;
    private int mPeriodicAdvertisingInterval;

    /**
     * Constructs a new ScanResult.
     *
     * @param device Remote Bluetooth device found.
     * @param scanRecord Scan record including both advertising data and scan response data.
     * @param rssi Received signal strength.
     * @param timestampNanos Timestamp at which the scan result was observed.
     * @deprecated use {@link #ScanResult(BluetoothDevice, int, int, int, int, int, int, int,
     * ScanRecord, long)}
     */
    @Deprecated
    public ScanResult(BluetoothDevice device, ScanRecord scanRecord, int rssi,
            long timestampNanos) {
        mDevice = device;
        mScanRecord = scanRecord;
        mRssi = rssi;
        mTimestampNanos = timestampNanos;
        mEventType = (DATA_COMPLETE << 5) | ET_LEGACY_MASK | ET_CONNECTABLE_MASK;
        mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
        mSecondaryPhy = PHY_UNUSED;
        mAdvertisingSid = SID_NOT_PRESENT;
        mTxPower = 127;
        mPeriodicAdvertisingInterval = 0;
    }

    /**
     * Constructs a new ScanResult.
     *
     * @param device Remote Bluetooth device found.
     * @param eventType Event type.
     * @param primaryPhy Primary advertising phy.
     * @param secondaryPhy Secondary advertising phy.
     * @param advertisingSid Advertising set ID.
     * @param txPower Transmit power.
     * @param rssi Received signal strength.
     * @param periodicAdvertisingInterval Periodic advertising interval.
     * @param scanRecord Scan record including both advertising data and scan response data.
     * @param timestampNanos Timestamp at which the scan result was observed.
     */
    public ScanResult(BluetoothDevice device, int eventType, int primaryPhy, int secondaryPhy,
            int advertisingSid, int txPower, int rssi, int periodicAdvertisingInterval,
            ScanRecord scanRecord, long timestampNanos) {
        mDevice = device;
        mEventType = eventType;
        mPrimaryPhy = primaryPhy;
        mSecondaryPhy = secondaryPhy;
        mAdvertisingSid = advertisingSid;
        mTxPower = txPower;
        mRssi = rssi;
        mPeriodicAdvertisingInterval = periodicAdvertisingInterval;
        mScanRecord = scanRecord;
        mTimestampNanos = timestampNanos;
    }

    private ScanResult(Parcel in) {
        readFromParcel(in);
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        if (mDevice != null) {
            dest.writeInt(1);
            mDevice.writeToParcel(dest, flags);
        } else {
            dest.writeInt(0);
        }
        if (mScanRecord != null) {
            dest.writeInt(1);
            dest.writeByteArray(mScanRecord.getBytes());
        } else {
            dest.writeInt(0);
        }
        dest.writeInt(mRssi);
        dest.writeLong(mTimestampNanos);
        dest.writeInt(mEventType);
        dest.writeInt(mPrimaryPhy);
        dest.writeInt(mSecondaryPhy);
        dest.writeInt(mAdvertisingSid);
        dest.writeInt(mTxPower);
        dest.writeInt(mPeriodicAdvertisingInterval);
    }

    private void readFromParcel(Parcel in) {
        if (in.readInt() == 1) {
            mDevice = BluetoothDevice.CREATOR.createFromParcel(in);
        }
        if (in.readInt() == 1) {
            mScanRecord = ScanRecord.parseFromBytes(in.createByteArray());
        }
        mRssi = in.readInt();
        mTimestampNanos = in.readLong();
        mEventType = in.readInt();
        mPrimaryPhy = in.readInt();
        mSecondaryPhy = in.readInt();
        mAdvertisingSid = in.readInt();
        mTxPower = in.readInt();
        mPeriodicAdvertisingInterval = in.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Returns the remote Bluetooth device identified by the Bluetooth device address.
     */
    public BluetoothDevice getDevice() {
        return mDevice;
    }

    /**
     * Returns the scan record, which is a combination of advertisement and scan response.
     */
    @Nullable
    public ScanRecord getScanRecord() {
        return mScanRecord;
    }

    /**
     * Returns the received signal strength in dBm. The valid range is [-127, 126].
     */
    public int getRssi() {
        return mRssi;
    }

    /**
     * Returns timestamp since boot when the scan record was observed.
     */
    public long getTimestampNanos() {
        return mTimestampNanos;
    }

    /**
     * Returns true if this object represents legacy scan result.
     * Legacy scan results do not contain advanced advertising information
     * as specified in the Bluetooth Core Specification v5.
     */
    public boolean isLegacy() {
        return (mEventType & ET_LEGACY_MASK) != 0;
    }

    /**
     * Returns true if this object represents connectable scan result.
     */
    public boolean isConnectable() {
        return (mEventType & ET_CONNECTABLE_MASK) != 0;
    }

    /**
     * Returns the data status.
     * Can be one of {@link ScanResult#DATA_COMPLETE} or
     * {@link ScanResult#DATA_TRUNCATED}.
     */
    public int getDataStatus() {
        // return bit 5 and 6
        return (mEventType >> 5) & 0x03;
    }

    /**
     * Returns the primary Physical Layer
     * on which this advertisment was received.
     * Can be one of {@link BluetoothDevice#PHY_LE_1M} or
     * {@link BluetoothDevice#PHY_LE_CODED}.
     */
    public int getPrimaryPhy() {
        return mPrimaryPhy;
    }

    /**
     * Returns the secondary Physical Layer
     * on which this advertisment was received.
     * Can be one of {@link BluetoothDevice#PHY_LE_1M},
     * {@link BluetoothDevice#PHY_LE_2M}, {@link BluetoothDevice#PHY_LE_CODED}
     * or {@link ScanResult#PHY_UNUSED} - if the advertisement
     * was not received on a secondary physical channel.
     */
    public int getSecondaryPhy() {
        return mSecondaryPhy;
    }

    /**
     * Returns the advertising set id.
     * May return {@link ScanResult#SID_NOT_PRESENT} if
     * no set id was is present.
     */
    public int getAdvertisingSid() {
        return mAdvertisingSid;
    }

    /**
     * Returns the transmit power in dBm.
     * Valid range is [-127, 126]. A value of {@link ScanResult#TX_POWER_NOT_PRESENT}
     * indicates that the TX power is not present.
     */
    public int getTxPower() {
        return mTxPower;
    }

    /**
     * Returns the periodic advertising interval in units of 1.25ms.
     * Valid range is 6 (7.5ms) to 65536 (81918.75ms). A value of
     * {@link ScanResult#PERIODIC_INTERVAL_NOT_PRESENT} means periodic
     * advertising interval is not present.
     */
    public int getPeriodicAdvertisingInterval() {
        return mPeriodicAdvertisingInterval;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mDevice, mRssi, mScanRecord, mTimestampNanos,
                mEventType, mPrimaryPhy, mSecondaryPhy,
                mAdvertisingSid, mTxPower,
                mPeriodicAdvertisingInterval);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        ScanResult other = (ScanResult) obj;
        return Objects.equals(mDevice, other.mDevice) && (mRssi == other.mRssi)
                && Objects.equals(mScanRecord, other.mScanRecord)
                && (mTimestampNanos == other.mTimestampNanos)
                && mEventType == other.mEventType
                && mPrimaryPhy == other.mPrimaryPhy
                && mSecondaryPhy == other.mSecondaryPhy
                && mAdvertisingSid == other.mAdvertisingSid
                && mTxPower == other.mTxPower
                && mPeriodicAdvertisingInterval == other.mPeriodicAdvertisingInterval;
    }

    @Override
    public String toString() {
        return "ScanResult{" + "device=" + mDevice + ", scanRecord="
                + Objects.toString(mScanRecord) + ", rssi=" + mRssi
                + ", timestampNanos=" + mTimestampNanos + ", eventType=" + mEventType
                + ", primaryPhy=" + mPrimaryPhy + ", secondaryPhy=" + mSecondaryPhy
                + ", advertisingSid=" + mAdvertisingSid + ", txPower=" + mTxPower
                + ", periodicAdvertisingInterval=" + mPeriodicAdvertisingInterval + '}';
    }

    public static final @android.annotation.NonNull Parcelable.Creator<ScanResult> CREATOR = new Creator<ScanResult>() {
        @Override
        public ScanResult createFromParcel(Parcel source) {
            return new ScanResult(source);
        }

        @Override
        public ScanResult[] newArray(int size) {
            return new ScanResult[size];
        }
    };

}