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