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.net.lowpan; 18 19 import android.os.Parcel; 20 import android.os.Parcelable; 21 import com.android.internal.util.HexDump; 22 import java.util.Arrays; 23 import java.util.Collection; 24 import java.util.Objects; 25 import java.util.TreeSet; 26 27 /** 28 * Describes a LoWPAN Beacon 29 * 30 * @hide 31 */ 32 // @SystemApi 33 public class LowpanBeaconInfo implements Parcelable { 34 public static final int UNKNOWN_RSSI = Integer.MAX_VALUE; 35 public static final int UNKNOWN_LQI = 0; 36 37 private LowpanIdentity mIdentity; 38 private int mRssi = UNKNOWN_RSSI; 39 private int mLqi = UNKNOWN_LQI; 40 private byte[] mBeaconAddress = null; 41 private final TreeSet<Integer> mFlags = new TreeSet<>(); 42 43 public static final int FLAG_CAN_ASSIST = 1; 44 45 /** @hide */ 46 public static class Builder { 47 final LowpanIdentity.Builder mIdentityBuilder = new LowpanIdentity.Builder(); 48 final LowpanBeaconInfo mBeaconInfo = new LowpanBeaconInfo(); 49 setLowpanIdentity(LowpanIdentity x)50 public Builder setLowpanIdentity(LowpanIdentity x) { 51 mIdentityBuilder.setLowpanIdentity(x); 52 return this; 53 } 54 setName(String x)55 public Builder setName(String x) { 56 mIdentityBuilder.setName(x); 57 return this; 58 } 59 setXpanid(byte x[])60 public Builder setXpanid(byte x[]) { 61 mIdentityBuilder.setXpanid(x); 62 return this; 63 } 64 setPanid(int x)65 public Builder setPanid(int x) { 66 mIdentityBuilder.setPanid(x); 67 return this; 68 } 69 setChannel(int x)70 public Builder setChannel(int x) { 71 mIdentityBuilder.setChannel(x); 72 return this; 73 } 74 setType(String x)75 public Builder setType(String x) { 76 mIdentityBuilder.setType(x); 77 return this; 78 } 79 setRssi(int x)80 public Builder setRssi(int x) { 81 mBeaconInfo.mRssi = x; 82 return this; 83 } 84 setLqi(int x)85 public Builder setLqi(int x) { 86 mBeaconInfo.mLqi = x; 87 return this; 88 } 89 setBeaconAddress(byte x[])90 public Builder setBeaconAddress(byte x[]) { 91 mBeaconInfo.mBeaconAddress = (x != null ? x.clone() : null); 92 return this; 93 } 94 setFlag(int x)95 public Builder setFlag(int x) { 96 mBeaconInfo.mFlags.add(x); 97 return this; 98 } 99 setFlags(Collection<Integer> x)100 public Builder setFlags(Collection<Integer> x) { 101 mBeaconInfo.mFlags.addAll(x); 102 return this; 103 } 104 build()105 public LowpanBeaconInfo build() { 106 mBeaconInfo.mIdentity = mIdentityBuilder.build(); 107 if (mBeaconInfo.mBeaconAddress == null) { 108 mBeaconInfo.mBeaconAddress = new byte[0]; 109 } 110 return mBeaconInfo; 111 } 112 } 113 LowpanBeaconInfo()114 private LowpanBeaconInfo() {} 115 getLowpanIdentity()116 public LowpanIdentity getLowpanIdentity() { 117 return mIdentity; 118 } 119 getRssi()120 public int getRssi() { 121 return mRssi; 122 } 123 getLqi()124 public int getLqi() { 125 return mLqi; 126 } 127 getBeaconAddress()128 public byte[] getBeaconAddress() { 129 return mBeaconAddress.clone(); 130 } 131 getFlags()132 public Collection<Integer> getFlags() { 133 return (Collection<Integer>) mFlags.clone(); 134 } 135 isFlagSet(int flag)136 public boolean isFlagSet(int flag) { 137 return mFlags.contains(flag); 138 } 139 140 @Override toString()141 public String toString() { 142 StringBuffer sb = new StringBuffer(); 143 144 sb.append(mIdentity.toString()); 145 146 if (mRssi != UNKNOWN_RSSI) { 147 sb.append(", RSSI:").append(mRssi).append("dBm"); 148 } 149 150 if (mLqi != UNKNOWN_LQI) { 151 sb.append(", LQI:").append(mLqi); 152 } 153 154 if (mBeaconAddress.length > 0) { 155 sb.append(", BeaconAddress:").append(HexDump.toHexString(mBeaconAddress)); 156 } 157 158 for (Integer flag : mFlags) { 159 switch (flag.intValue()) { 160 case FLAG_CAN_ASSIST: 161 sb.append(", CAN_ASSIST"); 162 break; 163 default: 164 sb.append(", FLAG_").append(Integer.toHexString(flag)); 165 break; 166 } 167 } 168 169 return sb.toString(); 170 } 171 172 @Override hashCode()173 public int hashCode() { 174 return Objects.hash(mIdentity, mRssi, mLqi, Arrays.hashCode(mBeaconAddress), mFlags); 175 } 176 177 @Override equals(Object obj)178 public boolean equals(Object obj) { 179 if (!(obj instanceof LowpanBeaconInfo)) { 180 return false; 181 } 182 LowpanBeaconInfo rhs = (LowpanBeaconInfo) obj; 183 return mIdentity.equals(rhs.mIdentity) 184 && Arrays.equals(mBeaconAddress, rhs.mBeaconAddress) 185 && mRssi == rhs.mRssi 186 && mLqi == rhs.mLqi 187 && mFlags.equals(rhs.mFlags); 188 } 189 190 /** Implement the Parcelable interface. */ 191 @Override describeContents()192 public int describeContents() { 193 return 0; 194 } 195 196 /** Implement the Parcelable interface. */ 197 @Override writeToParcel(Parcel dest, int flags)198 public void writeToParcel(Parcel dest, int flags) { 199 mIdentity.writeToParcel(dest, flags); 200 dest.writeInt(mRssi); 201 dest.writeInt(mLqi); 202 dest.writeByteArray(mBeaconAddress); 203 204 dest.writeInt(mFlags.size()); 205 for (Integer val : mFlags) { 206 dest.writeInt(val); 207 } 208 } 209 210 /** Implement the Parcelable interface. */ 211 public static final Creator<LowpanBeaconInfo> CREATOR = 212 new Creator<LowpanBeaconInfo>() { 213 public LowpanBeaconInfo createFromParcel(Parcel in) { 214 Builder builder = new Builder(); 215 216 builder.setLowpanIdentity(LowpanIdentity.CREATOR.createFromParcel(in)); 217 218 builder.setRssi(in.readInt()); 219 builder.setLqi(in.readInt()); 220 221 builder.setBeaconAddress(in.createByteArray()); 222 223 for (int i = in.readInt(); i > 0; i--) { 224 builder.setFlag(in.readInt()); 225 } 226 227 return builder.build(); 228 } 229 230 public LowpanBeaconInfo[] newArray(int size) { 231 return new LowpanBeaconInfo[size]; 232 } 233 }; 234 } 235