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