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