1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.bluetooth.le; 18 19 import android.annotation.Nullable; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 23 import java.util.Objects; 24 25 /** 26 * PeriodicAdvertisingReport for Bluetooth LE synchronized advertising. 27 * 28 * @hide 29 */ 30 public final class PeriodicAdvertisingReport implements Parcelable { 31 32 /** The data returned is complete */ 33 public static final int DATA_COMPLETE = 0; 34 35 /** 36 * The data returned is incomplete. The controller was unsuccessful to receive all chained 37 * packets, returning only partial data. 38 */ 39 public static final int DATA_INCOMPLETE_TRUNCATED = 2; 40 41 private int mSyncHandle; 42 private int mTxPower; 43 private int mRssi; 44 private int mDataStatus; 45 46 // periodic advertising data. 47 @Nullable private ScanRecord mData; 48 49 // Device timestamp when the result was last seen. 50 private long mTimestampNanos; 51 52 /** Constructor of periodic advertising result. */ PeriodicAdvertisingReport( int syncHandle, int txPower, int rssi, int dataStatus, ScanRecord data)53 public PeriodicAdvertisingReport( 54 int syncHandle, int txPower, int rssi, int dataStatus, ScanRecord data) { 55 mSyncHandle = syncHandle; 56 mTxPower = txPower; 57 mRssi = rssi; 58 mDataStatus = dataStatus; 59 mData = data; 60 } 61 PeriodicAdvertisingReport(Parcel in)62 private PeriodicAdvertisingReport(Parcel in) { 63 readFromParcel(in); 64 } 65 66 @Override writeToParcel(Parcel dest, int flags)67 public void writeToParcel(Parcel dest, int flags) { 68 dest.writeInt(mSyncHandle); 69 dest.writeInt(mTxPower); 70 dest.writeInt(mRssi); 71 dest.writeInt(mDataStatus); 72 if (mData != null) { 73 dest.writeInt(1); 74 dest.writeByteArray(mData.getBytes()); 75 } else { 76 dest.writeInt(0); 77 } 78 } 79 readFromParcel(Parcel in)80 private void readFromParcel(Parcel in) { 81 mSyncHandle = in.readInt(); 82 mTxPower = in.readInt(); 83 mRssi = in.readInt(); 84 mDataStatus = in.readInt(); 85 if (in.readInt() == 1) { 86 mData = ScanRecord.parseFromBytes(in.createByteArray()); 87 } 88 } 89 90 @Override describeContents()91 public int describeContents() { 92 return 0; 93 } 94 95 /** Returns the synchronization handle. */ getSyncHandle()96 public int getSyncHandle() { 97 return mSyncHandle; 98 } 99 100 /** 101 * Returns the transmit power in dBm. The valid range is [-127, 126]. Value of 127 means 102 * information was not available. 103 */ getTxPower()104 public int getTxPower() { 105 return mTxPower; 106 } 107 108 /** Returns the received signal strength in dBm. The valid range is [-127, 20]. */ getRssi()109 public int getRssi() { 110 return mRssi; 111 } 112 113 /** 114 * Returns the data status. Can be one of {@link PeriodicAdvertisingReport#DATA_COMPLETE} or 115 * {@link PeriodicAdvertisingReport#DATA_INCOMPLETE_TRUNCATED}. 116 */ getDataStatus()117 public int getDataStatus() { 118 return mDataStatus; 119 } 120 121 /** Returns the data contained in this periodic advertising report. */ 122 @Nullable getData()123 public ScanRecord getData() { 124 return mData; 125 } 126 127 /** Returns timestamp since boot when the scan record was observed. */ getTimestampNanos()128 public long getTimestampNanos() { 129 return mTimestampNanos; 130 } 131 132 @Override hashCode()133 public int hashCode() { 134 return Objects.hash(mSyncHandle, mTxPower, mRssi, mDataStatus, mData, mTimestampNanos); 135 } 136 137 @Override equals(@ullable Object obj)138 public boolean equals(@Nullable Object obj) { 139 if (this == obj) { 140 return true; 141 } 142 if (obj == null || getClass() != obj.getClass()) { 143 return false; 144 } 145 PeriodicAdvertisingReport other = (PeriodicAdvertisingReport) obj; 146 return (mSyncHandle == other.mSyncHandle) 147 && (mTxPower == other.mTxPower) 148 && (mRssi == other.mRssi) 149 && (mDataStatus == other.mDataStatus) 150 && Objects.equals(mData, other.mData) 151 && (mTimestampNanos == other.mTimestampNanos); 152 } 153 154 @Override toString()155 public String toString() { 156 return "PeriodicAdvertisingReport{syncHandle=" 157 + mSyncHandle 158 + ", txPower=" 159 + mTxPower 160 + ", rssi=" 161 + mRssi 162 + ", dataStatus=" 163 + mDataStatus 164 + ", data=" 165 + Objects.toString(mData) 166 + ", timestampNanos=" 167 + mTimestampNanos 168 + '}'; 169 } 170 171 public static final @android.annotation.NonNull Parcelable.Creator<PeriodicAdvertisingReport> 172 CREATOR = 173 new Creator<PeriodicAdvertisingReport>() { 174 @Override 175 public PeriodicAdvertisingReport createFromParcel(Parcel source) { 176 return new PeriodicAdvertisingReport(source); 177 } 178 179 @Override 180 public PeriodicAdvertisingReport[] newArray(int size) { 181 return new PeriodicAdvertisingReport[size]; 182 } 183 }; 184 } 185