blob: aa059c28131114bf9b95ae439f8c3fc3738eb036 [file] [log] [blame]
Alexander Chemeris040b3052013-06-16 14:29:54 +04001/**@file Common-use GSM declarations, most from the GSM 04.xx and 05.xx series. */
2/*
3* Copyright 2008-2011 Free Software Foundation, Inc.
4*
Pau Espin Pedrol21d03d32019-07-22 12:05:52 +02005* SPDX-License-Identifier: AGPL-3.0+
6*
Alexander Chemeris040b3052013-06-16 14:29:54 +04007* This software is distributed under the terms of the GNU Affero Public License.
8* See the COPYING file in the main directory for details.
9*
10* This use of this software may be subject to additional restrictions.
11* See the LEGAL file in the main directory for details.
12
13 This program is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Affero General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU Affero General Public License for more details.
22
23 You should have received a copy of the GNU Affero General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
25
26*/
27
28
29
30#ifndef GSMCOMMON_H
31#define GSMCOMMON_H
32
33#include <stdlib.h>
34#include <sys/time.h>
35#include <ostream>
36#include <vector>
37
38#include <Threads.h>
39#include <Timeval.h>
40#include <BitVector.h>
41
42
43
44
45namespace GSM {
46
47/**@namespace GSM This namespace covers L1 FEC, L2 and L3 message translation. */
48
49/** GSM Training sequences from GSM 05.02 5.2.3. */
50extern const BitVector gTrainingSequence[];
Tom Tsoud3253432016-03-06 03:08:01 -080051extern const BitVector gEdgeTrainingSequence[];
Alexander Chemeris040b3052013-06-16 14:29:54 +040052
53/** C0T0 filler burst, GSM 05.02, 5.2.6 */
54extern const BitVector gDummyBurst;
Eric Wildd8a1dee2024-02-21 19:33:09 +010055extern const BitVector gDummyBurstTSC;
Alexander Chemeris040b3052013-06-16 14:29:54 +040056
57/** Random access burst synch. sequence */
Vadim Yanitskiya79bc702018-10-17 11:01:58 +020058extern const BitVector gRACHSynchSequenceTS0;
59extern const BitVector gRACHSynchSequenceTS1;
60extern const BitVector gRACHSynchSequenceTS2;
Eric Wildd8a1dee2024-02-21 19:33:09 +010061
62/** Synchronization burst sync sequence */
63extern const BitVector gSCHSynchSequence;
64
Alexander Chemeris5efe0502016-03-23 17:06:32 +030065/** Random access burst synch. sequence, GSM 05.02 5.2.7 */
66extern const BitVector gRACHBurst;
Alexander Chemeris040b3052013-06-16 14:29:54 +040067
68
69/**@name Modulus operations for frame numbers. */
70//@{
71/** The GSM hyperframe is largest time period in the GSM system, GSM 05.02 4.3.3. */
72const uint32_t gHyperframe = 2048UL * 26UL * 51UL;
73
74/** Get a clock difference, within the modulus, v1-v2. */
75int32_t FNDelta(int32_t v1, int32_t v2);
76
77/**
78 Compare two frame clock values.
79 @return 1 if v1>v2, -1 if v1<v2, 0 if v1==v2
80*/
81int FNCompare(int32_t v1, int32_t v2);
82
83
84//@}
85
86
87/**
88 GSM frame clock value. GSM 05.02 4.3
89 No internal thread sync.
90*/
91class Time {
92
93 private:
94
95 int mFN; ///< frame number in the hyperframe
96 int mTN; ///< timeslot number
97
98 public:
99
100 Time(int wFN=0, int wTN=0)
101 :mFN(wFN),mTN(wTN)
102 { }
103
104
105 /** Move the time forward to a given position in a given modulus. */
106 void rollForward(unsigned wFN, unsigned modulus)
107 {
108 assert(modulus<gHyperframe);
109 while ((mFN % modulus) != wFN) mFN=(mFN+1)%gHyperframe;
110 }
111
112 /**@name Accessors. */
113 //@{
114 int FN() const { return mFN; }
115 void FN(unsigned wFN) { mFN = wFN; }
116 unsigned TN() const { return mTN; }
117 void TN(unsigned wTN) { mTN=wTN; }
118 //@}
119
120 /**@name Arithmetic. */
121 //@{
122
123 Time& operator++()
124 {
125 mFN = (mFN+1) % gHyperframe;
126 return *this;
127 }
128
129 Time& decTN(unsigned step=1)
130 {
131 assert(step<=8);
132 mTN -= step;
133 if (mTN<0) {
134 mTN+=8;
135 mFN-=1;
136 if (mFN<0) mFN+=gHyperframe;
137 }
138 return *this;
139 }
140
141 Time& incTN(unsigned step=1)
142 {
143 assert(step<=8);
144 mTN += step;
145 if (mTN>7) {
146 mTN-=8;
147 mFN = (mFN+1) % gHyperframe;
148 }
149 return *this;
150 }
151
152 Time& operator+=(int step)
153 {
154 // Remember the step might be negative.
155 mFN += step;
156 if (mFN<0) mFN+=gHyperframe;
157 mFN = mFN % gHyperframe;
158 return *this;
159 }
160
161 Time operator-(int step) const
162 { return operator+(-step); }
163
164 Time operator+(int step) const
165 {
166 Time newVal = *this;
167 newVal += step;
168 return newVal;
169 }
170
171 Time operator+(const Time& other) const
172 {
173 unsigned newTN = (mTN + other.mTN) % 8;
174 uint64_t newFN = (mFN+other.mFN + (mTN + other.mTN)/8) % gHyperframe;
175 return Time(newFN,newTN);
Pau Espin Pedrolbdb970e2019-07-22 12:03:39 +0200176 }
Alexander Chemeris040b3052013-06-16 14:29:54 +0400177
178 int operator-(const Time& other) const
179 {
180 return FNDelta(mFN,other.mFN);
181 }
182
183 //@}
184
185
186 /**@name Comparisons. */
187 //@{
188
189 bool operator<(const Time& other) const
190 {
191 if (mFN==other.mFN) return (mTN<other.mTN);
192 return FNCompare(mFN,other.mFN)<0;
193 }
194
195 bool operator>(const Time& other) const
196 {
197 if (mFN==other.mFN) return (mTN>other.mTN);
198 return FNCompare(mFN,other.mFN)>0;
199 }
200
201 bool operator<=(const Time& other) const
202 {
203 if (mFN==other.mFN) return (mTN<=other.mTN);
204 return FNCompare(mFN,other.mFN)<=0;
205 }
206
207 bool operator>=(const Time& other) const
208 {
209 if (mFN==other.mFN) return (mTN>=other.mTN);
210 return FNCompare(mFN,other.mFN)>=0;
211 }
212
213 bool operator==(const Time& other) const
214 {
215 return (mFN == other.mFN) && (mTN==other.mTN);
216 }
217
218 //@}
219
220
221
222 /**@name Standard derivations. */
223 //@{
224
225 /** GSM 05.02 3.3.2.2.1 */
226 unsigned SFN() const { return mFN / (26*51); }
227
228 /** GSM 05.02 3.3.2.2.1 */
229 unsigned T1() const { return SFN() % 2048; }
230
231 /** GSM 05.02 3.3.2.2.1 */
232 unsigned T2() const { return mFN % 26; }
233
234 /** GSM 05.02 3.3.2.2.1 */
235 unsigned T3() const { return mFN % 51; }
236
237 /** GSM 05.02 3.3.2.2.1. */
238 unsigned T3p() const { return (T3()-1)/10; }
239
240 /** GSM 05.02 6.3.1.3. */
241 unsigned TC() const { return (FN()/51) % 8; }
242
243 /** GSM 04.08 10.5.2.30. */
244 unsigned T1p() const { return SFN() % 32; }
245
246 /** GSM 05.02 6.2.3 */
247 unsigned T1R() const { return T1() % 64; }
248
249 //@}
250};
251
252
253std::ostream& operator<<(std::ostream& os, const Time& ts);
254
255}; // namespace GSM
256
257
258#endif
259
260// vim: ts=4 sw=4