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