You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
5.3 KiB
255 lines
5.3 KiB
/**@file Common-use GSM declarations, most from the GSM 04.xx and 05.xx series. */ |
|
/* |
|
* Copyright 2008-2011 Free Software Foundation, Inc. |
|
* |
|
* SPDX-License-Identifier: AGPL-3.0+ |
|
* |
|
* This software is distributed under the terms of the GNU Affero Public License. |
|
* See the COPYING file in the main directory for details. |
|
* |
|
* This use of this software may be subject to additional restrictions. |
|
* See the LEGAL file in the main directory for details. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU Affero General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU Affero General Public License for more details. |
|
|
|
You should have received a copy of the GNU Affero General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
*/ |
|
|
|
|
|
|
|
#ifndef GSMCOMMON_H |
|
#define GSMCOMMON_H |
|
|
|
#include <stdlib.h> |
|
#include <sys/time.h> |
|
#include <ostream> |
|
#include <vector> |
|
|
|
#include <Threads.h> |
|
#include <Timeval.h> |
|
#include <BitVector.h> |
|
|
|
|
|
|
|
|
|
namespace GSM { |
|
|
|
/**@namespace GSM This namespace covers L1 FEC, L2 and L3 message translation. */ |
|
|
|
/** GSM Training sequences from GSM 05.02 5.2.3. */ |
|
extern const BitVector gTrainingSequence[]; |
|
extern const BitVector gEdgeTrainingSequence[]; |
|
|
|
/** C0T0 filler burst, GSM 05.02, 5.2.6 */ |
|
extern const BitVector gDummyBurst; |
|
|
|
/** Random access burst synch. sequence */ |
|
extern const BitVector gRACHSynchSequenceTS0; |
|
extern const BitVector gRACHSynchSequenceTS1; |
|
extern const BitVector gRACHSynchSequenceTS2; |
|
/** Random access burst synch. sequence, GSM 05.02 5.2.7 */ |
|
extern const BitVector gRACHBurst; |
|
|
|
|
|
/**@name Modulus operations for frame numbers. */ |
|
//@{ |
|
/** The GSM hyperframe is largest time period in the GSM system, GSM 05.02 4.3.3. */ |
|
const uint32_t gHyperframe = 2048UL * 26UL * 51UL; |
|
|
|
/** Get a clock difference, within the modulus, v1-v2. */ |
|
int32_t FNDelta(int32_t v1, int32_t v2); |
|
|
|
/** |
|
Compare two frame clock values. |
|
@return 1 if v1>v2, -1 if v1<v2, 0 if v1==v2 |
|
*/ |
|
int FNCompare(int32_t v1, int32_t v2); |
|
|
|
|
|
//@} |
|
|
|
|
|
/** |
|
GSM frame clock value. GSM 05.02 4.3 |
|
No internal thread sync. |
|
*/ |
|
class Time { |
|
|
|
private: |
|
|
|
int mFN; ///< frame number in the hyperframe |
|
int mTN; ///< timeslot number |
|
|
|
public: |
|
|
|
Time(int wFN=0, int wTN=0) |
|
:mFN(wFN),mTN(wTN) |
|
{ } |
|
|
|
|
|
/** Move the time forward to a given position in a given modulus. */ |
|
void rollForward(unsigned wFN, unsigned modulus) |
|
{ |
|
assert(modulus<gHyperframe); |
|
while ((mFN % modulus) != wFN) mFN=(mFN+1)%gHyperframe; |
|
} |
|
|
|
/**@name Accessors. */ |
|
//@{ |
|
int FN() const { return mFN; } |
|
void FN(unsigned wFN) { mFN = wFN; } |
|
unsigned TN() const { return mTN; } |
|
void TN(unsigned wTN) { mTN=wTN; } |
|
//@} |
|
|
|
/**@name Arithmetic. */ |
|
//@{ |
|
|
|
Time& operator++() |
|
{ |
|
mFN = (mFN+1) % gHyperframe; |
|
return *this; |
|
} |
|
|
|
Time& decTN(unsigned step=1) |
|
{ |
|
assert(step<=8); |
|
mTN -= step; |
|
if (mTN<0) { |
|
mTN+=8; |
|
mFN-=1; |
|
if (mFN<0) mFN+=gHyperframe; |
|
} |
|
return *this; |
|
} |
|
|
|
Time& incTN(unsigned step=1) |
|
{ |
|
assert(step<=8); |
|
mTN += step; |
|
if (mTN>7) { |
|
mTN-=8; |
|
mFN = (mFN+1) % gHyperframe; |
|
} |
|
return *this; |
|
} |
|
|
|
Time& operator+=(int step) |
|
{ |
|
// Remember the step might be negative. |
|
mFN += step; |
|
if (mFN<0) mFN+=gHyperframe; |
|
mFN = mFN % gHyperframe; |
|
return *this; |
|
} |
|
|
|
Time operator-(int step) const |
|
{ return operator+(-step); } |
|
|
|
Time operator+(int step) const |
|
{ |
|
Time newVal = *this; |
|
newVal += step; |
|
return newVal; |
|
} |
|
|
|
Time operator+(const Time& other) const |
|
{ |
|
unsigned newTN = (mTN + other.mTN) % 8; |
|
uint64_t newFN = (mFN+other.mFN + (mTN + other.mTN)/8) % gHyperframe; |
|
return Time(newFN,newTN); |
|
} |
|
|
|
int operator-(const Time& other) const |
|
{ |
|
return FNDelta(mFN,other.mFN); |
|
} |
|
|
|
//@} |
|
|
|
|
|
/**@name Comparisons. */ |
|
//@{ |
|
|
|
bool operator<(const Time& other) const |
|
{ |
|
if (mFN==other.mFN) return (mTN<other.mTN); |
|
return FNCompare(mFN,other.mFN)<0; |
|
} |
|
|
|
bool operator>(const Time& other) const |
|
{ |
|
if (mFN==other.mFN) return (mTN>other.mTN); |
|
return FNCompare(mFN,other.mFN)>0; |
|
} |
|
|
|
bool operator<=(const Time& other) const |
|
{ |
|
if (mFN==other.mFN) return (mTN<=other.mTN); |
|
return FNCompare(mFN,other.mFN)<=0; |
|
} |
|
|
|
bool operator>=(const Time& other) const |
|
{ |
|
if (mFN==other.mFN) return (mTN>=other.mTN); |
|
return FNCompare(mFN,other.mFN)>=0; |
|
} |
|
|
|
bool operator==(const Time& other) const |
|
{ |
|
return (mFN == other.mFN) && (mTN==other.mTN); |
|
} |
|
|
|
//@} |
|
|
|
|
|
|
|
/**@name Standard derivations. */ |
|
//@{ |
|
|
|
/** GSM 05.02 3.3.2.2.1 */ |
|
unsigned SFN() const { return mFN / (26*51); } |
|
|
|
/** GSM 05.02 3.3.2.2.1 */ |
|
unsigned T1() const { return SFN() % 2048; } |
|
|
|
/** GSM 05.02 3.3.2.2.1 */ |
|
unsigned T2() const { return mFN % 26; } |
|
|
|
/** GSM 05.02 3.3.2.2.1 */ |
|
unsigned T3() const { return mFN % 51; } |
|
|
|
/** GSM 05.02 3.3.2.2.1. */ |
|
unsigned T3p() const { return (T3()-1)/10; } |
|
|
|
/** GSM 05.02 6.3.1.3. */ |
|
unsigned TC() const { return (FN()/51) % 8; } |
|
|
|
/** GSM 04.08 10.5.2.30. */ |
|
unsigned T1p() const { return SFN() % 32; } |
|
|
|
/** GSM 05.02 6.2.3 */ |
|
unsigned T1R() const { return T1() % 64; } |
|
|
|
//@} |
|
}; |
|
|
|
|
|
std::ostream& operator<<(std::ostream& os, const Time& ts); |
|
|
|
}; // namespace GSM |
|
|
|
|
|
#endif |
|
|
|
// vim: ts=4 sw=4
|
|
|