GnssNavigationMessage.java revision 0f1ab04516d3e9a72eda22c998910f49f2bd40bb
1/* 2 * Copyright (C) 2014 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.location; 18 19import android.annotation.TestApi; 20import android.annotation.IntDef; 21import android.annotation.NonNull; 22import android.os.Parcel; 23import android.os.Parcelable; 24 25import java.lang.annotation.Retention; 26import java.lang.annotation.RetentionPolicy; 27import java.security.InvalidParameterException; 28 29/** 30 * A class containing a GNSS satellite Navigation Message. 31 */ 32public final class GnssNavigationMessage implements Parcelable { 33 34 private static final byte[] EMPTY_ARRAY = new byte[0]; 35 36 /** The type of the GPS Clock. */ 37 @Retention(RetentionPolicy.SOURCE) 38 @IntDef({TYPE_UNKNOWN, TYPE_GPS_L1CA, TYPE_GPS_L2CNAV, TYPE_GPS_L5CNAV, TYPE_GPS_CNAV2, 39 TYPE_GLO_L1CA, TYPE_BDS_D1, TYPE_BDS_D2, TYPE_GAL_I, TYPE_GAL_F}) 40 public @interface GnssNavigationMessageType {} 41 42 // The following enumerations must be in sync with the values declared in gps.h 43 44 /** Message type unknown */ 45 public static final int TYPE_UNKNOWN = 0; 46 /** GPS L1 C/A message contained in the structure. */ 47 public static final int TYPE_GPS_L1CA = 0x0101; 48 /** GPS L2-CNAV message contained in the structure. */ 49 public static final int TYPE_GPS_L2CNAV = 0x0102; 50 /** GPS L5-CNAV message contained in the structure. */ 51 public static final int TYPE_GPS_L5CNAV = 0x0103; 52 /** GPS CNAV-2 message contained in the structure. */ 53 public static final int TYPE_GPS_CNAV2 = 0x0104; 54 /** Glonass L1 CA message contained in the structure. */ 55 public static final int TYPE_GLO_L1CA = 0x0301; 56 /** Beidou D1 message contained in the structure. */ 57 public static final int TYPE_BDS_D1 = 0x0501; 58 /** Beidou D2 message contained in the structure. */ 59 public static final int TYPE_BDS_D2 = 0x0502; 60 /** Galileo I/NAV message contained in the structure. */ 61 public static final int TYPE_GAL_I = 0x0601; 62 /** Galileo F/NAV message contained in the structure. */ 63 public static final int TYPE_GAL_F = 0x0602; 64 65 /** 66 * The Navigation Message Status is 'unknown'. 67 */ 68 public static final int STATUS_UNKNOWN = 0; 69 70 /** 71 * The Navigation Message was received without any parity error in its navigation words. 72 */ 73 public static final int STATUS_PARITY_PASSED = (1<<0); 74 75 /** 76 * The Navigation Message was received with words that failed parity check, but the receiver was 77 * able to correct those words. 78 */ 79 public static final int STATUS_PARITY_REBUILT = (1<<1); 80 81 // End enumerations in sync with gps.h 82 83 private int mType; 84 private int mSvid; 85 private int mMessageId; 86 private int mSubmessageId; 87 private byte[] mData; 88 private int mStatus; 89 90 /** 91 * @hide 92 */ 93 @TestApi 94 public GnssNavigationMessage() { 95 initialize(); 96 } 97 98 /** 99 * Sets all contents to the values stored in the provided object. 100 * @hide 101 */ 102 @TestApi 103 public void set(GnssNavigationMessage navigationMessage) { 104 mType = navigationMessage.mType; 105 mSvid = navigationMessage.mSvid; 106 mMessageId = navigationMessage.mMessageId; 107 mSubmessageId = navigationMessage.mSubmessageId; 108 mData = navigationMessage.mData; 109 mStatus = navigationMessage.mStatus; 110 } 111 112 /** 113 * Resets all the contents to its original state. 114 * @hide 115 */ 116 @TestApi 117 public void reset() { 118 initialize(); 119 } 120 121 /** 122 * Gets the type of the navigation message contained in the object. 123 */ 124 @GnssNavigationMessageType 125 public int getType() { 126 return mType; 127 } 128 129 /** 130 * Sets the type of the navigation message. 131 * @hide 132 */ 133 @TestApi 134 public void setType(@GnssNavigationMessageType int value) { 135 mType = value; 136 } 137 138 /** 139 * Gets a string representation of the 'type'. 140 * For internal and logging use only. 141 */ 142 private String getTypeString() { 143 switch (mType) { 144 case TYPE_UNKNOWN: 145 return "Unknown"; 146 case TYPE_GPS_L1CA: 147 return "GPS L1 C/A"; 148 case TYPE_GPS_L2CNAV: 149 return "GPS L2-CNAV"; 150 case TYPE_GPS_L5CNAV: 151 return "GPS L5-CNAV"; 152 case TYPE_GPS_CNAV2: 153 return "GPS CNAV2"; 154 case TYPE_GLO_L1CA: 155 return "Glonass L1 C/A"; 156 case TYPE_BDS_D1: 157 return "Beidou D1"; 158 case TYPE_BDS_D2: 159 return "Beidou D2"; 160 case TYPE_GAL_I: 161 return "Galileo I"; 162 case TYPE_GAL_F: 163 return "Galileo F"; 164 default: 165 return "<Invalid:" + mType + ">"; 166 } 167 } 168 169 /** 170 * Gets the Pseudo-random number. 171 * Range: [1, 32]. 172 */ 173 public int getSvid() { 174 return mSvid; 175 } 176 177 /** 178 * Sets the Pseud-random number. 179 * @hide 180 */ 181 @TestApi 182 public void setSvid(int value) { 183 mSvid = value; 184 } 185 186 /** 187 * Gets the Message Identifier. 188 * It provides an index so the complete Navigation Message can be assembled. i.e. for L1 C/A 189 * subframe 4 and 5, this value corresponds to the 'frame id' of the navigation message. 190 * Subframe 1, 2, 3 does not contain a 'frame id' and this might be reported as -1. 191 */ 192 public int getMessageId() { 193 return mMessageId; 194 } 195 196 /** 197 * Sets the Message Identifier. 198 * @hide 199 */ 200 @TestApi 201 public void setMessageId(int value) { 202 mMessageId = value; 203 } 204 205 /** 206 * Gets the Sub-message Identifier. 207 * If required by {@link #getType()}, this value contains a sub-index within the current message 208 * (or frame) that is being transmitted. i.e. for L1 C/A the sub-message identifier corresponds 209 * to the sub-frame Id of the navigation message. 210 */ 211 public int getSubmessageId() { 212 return mSubmessageId; 213 } 214 215 /** 216 * Sets the Sub-message identifier. 217 * @hide 218 */ 219 @TestApi 220 public void setSubmessageId(int value) { 221 mSubmessageId = value; 222 } 223 224 /** 225 * Gets the data associated with the Navigation Message. 226 * The bytes (or words) specified using big endian format (MSB first). 227 */ 228 @NonNull 229 public byte[] getData() { 230 return mData; 231 } 232 233 /** 234 * Sets the data associated with the Navigation Message. 235 * @hide 236 */ 237 @TestApi 238 public void setData(byte[] value) { 239 if (value == null) { 240 throw new InvalidParameterException("Data must be a non-null array"); 241 } 242 243 mData = value; 244 } 245 246 /** 247 * Gets the Status of the navigation message contained in the object. 248 */ 249 public int getStatus() { 250 return mStatus; 251 } 252 253 /** 254 * Sets the status of the navigation message. 255 * @hide 256 */ 257 @TestApi 258 public void setStatus(int value) { 259 mStatus = value; 260 } 261 262 /** 263 * Gets a string representation of the 'status'. 264 * For internal and logging use only. 265 */ 266 private String getStatusString() { 267 switch (mStatus) { 268 case STATUS_UNKNOWN: 269 return "Unknown"; 270 case STATUS_PARITY_PASSED: 271 return "ParityPassed"; 272 case STATUS_PARITY_REBUILT: 273 return "ParityRebuilt"; 274 default: 275 return "<Invalid:" + mStatus + ">"; 276 } 277 } 278 279 public static final Creator<GnssNavigationMessage> CREATOR = 280 new Creator<GnssNavigationMessage>() { 281 @Override 282 public GnssNavigationMessage createFromParcel(Parcel parcel) { 283 GnssNavigationMessage navigationMessage = new GnssNavigationMessage(); 284 285 navigationMessage.setType(parcel.readInt()); 286 navigationMessage.setSvid(parcel.readInt()); 287 navigationMessage.setMessageId(parcel.readInt()); 288 navigationMessage.setSubmessageId(parcel.readInt()); 289 290 int dataLength = parcel.readInt(); 291 byte[] data = new byte[dataLength]; 292 parcel.readByteArray(data); 293 navigationMessage.setData(data); 294 295 if (parcel.dataAvail() >= Integer.SIZE) { 296 int status = parcel.readInt(); 297 navigationMessage.setStatus(status); 298 } else { 299 navigationMessage.setStatus(STATUS_UNKNOWN); 300 } 301 302 return navigationMessage; 303 } 304 305 @Override 306 public GnssNavigationMessage[] newArray(int size) { 307 return new GnssNavigationMessage[size]; 308 } 309 }; 310 311 @Override 312 public void writeToParcel(Parcel parcel, int flags) { 313 parcel.writeInt(mType); 314 parcel.writeInt(mSvid); 315 parcel.writeInt(mMessageId); 316 parcel.writeInt(mSubmessageId); 317 parcel.writeInt(mData.length); 318 parcel.writeByteArray(mData); 319 parcel.writeInt(mStatus); 320 } 321 322 @Override 323 public int describeContents() { 324 return 0; 325 } 326 327 @Override 328 public String toString() { 329 final String format = " %-15s = %s\n"; 330 StringBuilder builder = new StringBuilder("GnssNavigationMessage:\n"); 331 332 builder.append(String.format(format, "Type", getTypeString())); 333 builder.append(String.format(format, "Svid", mSvid)); 334 builder.append(String.format(format, "Status", getStatusString())); 335 builder.append(String.format(format, "MessageId", mMessageId)); 336 builder.append(String.format(format, "SubmessageId", mSubmessageId)); 337 338 builder.append(String.format(format, "Data", "{")); 339 String prefix = " "; 340 for(byte value : mData) { 341 builder.append(prefix); 342 builder.append(value); 343 prefix = ", "; 344 } 345 builder.append(" }"); 346 347 return builder.toString(); 348 } 349 350 private void initialize() { 351 mType = TYPE_UNKNOWN; 352 mSvid = 0; 353 mMessageId = -1; 354 mSubmessageId = -1; 355 mData = EMPTY_ARRAY; 356 mStatus = STATUS_UNKNOWN; 357 } 358} 359