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