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