1   /* Copyright 2022-2025 Thales Alenia Space
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.gnss.rflink.gps;
18  
19  import org.hipparchus.util.FastMath;
20  
21  /**
22   * Container for sub-frames 1.
23   * <p>
24   * Table 20-1, sheet 1 and table 40-1, sheet 1 in
25   * <a href="https://navcen.uscg.gov/sites/default/files/pdf/gps/IS-GPS-200N.pdf">NAVSTAR
26   * GPS Space Segment/Navigation User Segment Interface</a>, IS-GPS-200N, 22 Aug 2022
27   * </p>
28   * @author Luc Maisonobe
29   * @since 12.0
30   */
31  public class SubFrame1 extends SubFrame {
32  
33      /** Index of Week Number field. */
34      private static final int WEEK_NUMBER = 7;
35  
36      /** Index of C/A or P code field. */
37      private static final int CA_OR_P = 8;
38  
39      /** Index of URA_INDEX index field. */
40      private static final int URA_INDEX = 9;
41  
42      /** Index of SV Health field. */
43      private static final int SV_HEALTH = 10;
44  
45      /** Index of IODC field. */
46      private static final int IODC  = 11;
47  
48      /** Index of L2 P data flag field. */
49      private static final int L2_P_DATA = 12;
50  
51      /** Index of reserved field in word 4. */
52      private static final int RESERVED_4 = 13;
53  
54      /** Index of reserved field in word 5. */
55      private static final int RESERVED_5 = 14;
56  
57      /** Index of reserved field in word 6. */
58      private static final int RESERVED_6 = 15;
59  
60      /** Index of reserved field in word 7. */
61      private static final int RESERVED_7 = 16;
62  
63      /** Index of TGD field. */
64      private static final int TGD = 17;
65  
66      /** Index of TOC field. */
67      private static final int TOC  = 18;
68  
69      /** Index of AF2 field. */
70      private static final int AF2  = 19;
71  
72      /** Index of AF1 field. */
73      private static final int AF1  = 20;
74  
75      /** Index of AF0 field. */
76      private static final int AF0  = 21;
77  
78      /** */
79      /** Simple constructor.
80       * @param words raw words
81       */
82      SubFrame1(final int[] words) {
83  
84          // create raw container
85          super(words, AF0 + 1);
86  
87          // populate container
88          setField(WEEK_NUMBER,  3, 20, 10, words);
89          setField(CA_OR_P,      3, 18,  2, words);
90          setField(URA_INDEX,          3, 14,  4, words);
91          setField(SV_HEALTH,    3,  8,  6, words);
92          setField(IODC,         3,  6,  2, 8, 22, 8, words);
93          setField(L2_P_DATA,    4, 29,  1, words);
94          setField(RESERVED_4,   4,  6, 23, words);
95          setField(RESERVED_5,   5,  6, 24, words);
96          setField(RESERVED_6,   6,  6, 24, words);
97          setField(RESERVED_7,   7, 14, 16, words);
98          setField(TGD,          7,  6,  8, words);
99          setField(TOC,          8,  6, 16, words);
100         setField(AF2,          9, 22,  8, words);
101         setField(AF1,          9,  6, 16, words);
102         setField(AF0,         10,  8, 22, words);
103 
104     }
105 
106     /** Get Week Number.
107      * @return week number
108      */
109     public int getWeekNumber() {
110         return getField(WEEK_NUMBER);
111     }
112 
113     /** Get C/A or P flag.
114      * @return C/A or P flag
115      */
116     public int getCaOrPFlag() {
117         return getField(CA_OR_P);
118     }
119 
120     /** Get URA index.
121      * @return URA index
122      */
123     public int getUraIndex() {
124         return getField(URA_INDEX);
125     }
126 
127     /** Get SV health.
128      * @return SV health
129      */
130     public int getSvHealth() {
131         return getField(SV_HEALTH);
132     }
133 
134     /** Get IODC.
135      * @return IODC
136      */
137     public int getIODC() {
138         return getField(IODC);
139     }
140 
141     /** Get L2 P data flag.
142      * @return L2 P data flag
143      */
144     public int getL2PDataFlag() {
145         return getField(L2_P_DATA);
146     }
147 
148     /** Get the reserved field in word 4.
149      * @return reserved field in word 4
150      */
151     public int getReserved04() {
152         return getField(RESERVED_4);
153     }
154 
155     /** Get the reserved field in word 5.
156      * @return reserved field in word 5
157      */
158     public int getReserved05() {
159         return getField(RESERVED_5);
160     }
161 
162     /** Get the reserved field in word 6.
163      * @return reserved field in word 6
164      */
165     public int getReserved06() {
166         return getField(RESERVED_6);
167     }
168 
169     /** Get the reserved field in word 7.
170      * @return reserved field in word 7
171      */
172     public int getReserved07() {
173         return getField(RESERVED_7);
174     }
175 
176     /** Get the TGD.
177      * @return TGD
178      */
179     public int getTGD() {
180         return getField(TGD);
181     }
182 
183     /** Get the TOC.
184      * @return TOC
185      */
186     public int getTOC() {
187         return getField(TOC);
188     }
189 
190     /** Get af₂.
191      * @return af₂ (second/second²)
192      */
193     public double getAF2() {
194         return FastMath.scalb((double) getField(AF2), -55);
195     }
196 
197     /** Get af₁.
198      * @return af₁ (second/second)
199      */
200     public double getAF1() {
201         return FastMath.scalb((double) getField(AF1), -43);
202     }
203 
204     /** Get af₀.
205      * @return af₀
206      */
207     public double getAF0() {
208         return FastMath.scalb((double) getField(AF0), -31);
209     }
210 
211 }