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 17package android.bluetooth.le; 18 19import android.annotation.Nullable; 20import android.os.Parcel; 21import android.os.Parcelable; 22 23import java.util.Objects; 24 25/** 26 * PeriodicAdvertisingReport for Bluetooth LE synchronized advertising. 27 * 28 * @hide 29 */ 30public final class PeriodicAdvertisingReport implements Parcelable { 31 32 /** 33 * The data returned is complete 34 */ 35 public static final int DATA_COMPLETE = 0; 36 37 /** 38 * The data returned is incomplete. The controller was unsuccessfull to 39 * receive all chained packets, returning only partial data. 40 */ 41 public static final int DATA_INCOMPLETE_TRUNCATED = 2; 42 43 private int mSyncHandle; 44 private int mTxPower; 45 private int mRssi; 46 private int mDataStatus; 47 48 // periodic advertising data. 49 @Nullable 50 private ScanRecord mData; 51 52 // Device timestamp when the result was last seen. 53 private long mTimestampNanos; 54 55 /** 56 * Constructor of periodic advertising result. 57 */ 58 public PeriodicAdvertisingReport(int syncHandle, int txPower, int rssi, 59 int dataStatus, ScanRecord data) { 60 mSyncHandle = syncHandle; 61 mTxPower = txPower; 62 mRssi = rssi; 63 mDataStatus = dataStatus; 64 mData = data; 65 } 66 67 private PeriodicAdvertisingReport(Parcel in) { 68 readFromParcel(in); 69 } 70 71 @Override 72 public void writeToParcel(Parcel dest, int flags) { 73 dest.writeInt(mSyncHandle); 74 dest.writeInt(mTxPower); 75 dest.writeInt(mRssi); 76 dest.writeInt(mDataStatus); 77 if (mData != null) { 78 dest.writeInt(1); 79 dest.writeByteArray(mData.getBytes()); 80 } else { 81 dest.writeInt(0); 82 } 83 } 84 85 private void readFromParcel(Parcel in) { 86 mSyncHandle = in.readInt(); 87 mTxPower = in.readInt(); 88 mRssi = in.readInt(); 89 mDataStatus = in.readInt(); 90 if (in.readInt() == 1) { 91 mData = ScanRecord.parseFromBytes(in.createByteArray()); 92 } 93 } 94 95 @Override 96 public int describeContents() { 97 return 0; 98 } 99 100 /** 101 * Returns the synchronization handle. 102 */ 103 public int getSyncHandle() { 104 return mSyncHandle; 105 } 106 107 /** 108 * Returns the transmit power in dBm. The valid range is [-127, 126]. Value 109 * of 127 means information was not available. 110 */ 111 public int getTxPower() { 112 return mTxPower; 113 } 114 115 /** 116 * Returns the received signal strength in dBm. The valid range is [-127, 20]. 117 */ 118 public int getRssi() { 119 return mRssi; 120 } 121 122 /** 123 * Returns the data status. Can be one of {@link PeriodicAdvertisingReport#DATA_COMPLETE} 124 * or {@link PeriodicAdvertisingReport#DATA_INCOMPLETE_TRUNCATED}. 125 */ 126 public int getDataStatus() { 127 return mDataStatus; 128 } 129 130 /** 131 * Returns the data contained in this periodic advertising report. 132 */ 133 @Nullable 134 public ScanRecord getData() { 135 return mData; 136 } 137 138 /** 139 * Returns timestamp since boot when the scan record was observed. 140 */ 141 public long getTimestampNanos() { 142 return mTimestampNanos; 143 } 144 145 @Override 146 public int hashCode() { 147 return Objects.hash(mSyncHandle, mTxPower, mRssi, mDataStatus, mData, mTimestampNanos); 148 } 149 150 @Override 151 public boolean equals(Object obj) { 152 if (this == obj) { 153 return true; 154 } 155 if (obj == null || getClass() != obj.getClass()) { 156 return false; 157 } 158 PeriodicAdvertisingReport other = (PeriodicAdvertisingReport) obj; 159 return (mSyncHandle == other.mSyncHandle) 160 && (mTxPower == other.mTxPower) 161 && (mRssi == other.mRssi) 162 && (mDataStatus == other.mDataStatus) 163 && Objects.equals(mData, other.mData) 164 && (mTimestampNanos == other.mTimestampNanos); 165 } 166 167 @Override 168 public String toString() { 169 return "PeriodicAdvertisingReport{syncHandle=" + mSyncHandle 170 + ", txPower=" + mTxPower + ", rssi=" + mRssi + ", dataStatus=" + mDataStatus 171 + ", data=" + Objects.toString(mData) + ", timestampNanos=" + mTimestampNanos + '}'; 172 } 173 174 public static final Parcelable.Creator<PeriodicAdvertisingReport> CREATOR = 175 new Creator<PeriodicAdvertisingReport>() { 176 @Override 177 public PeriodicAdvertisingReport createFromParcel(Parcel source) { 178 return new PeriodicAdvertisingReport(source); 179 } 180 181 @Override 182 public PeriodicAdvertisingReport[] newArray(int size) { 183 return new PeriodicAdvertisingReport[size]; 184 } 185 }; 186} 187