diff options
Diffstat (limited to 'GSM/GSMCommon.h')
-rw-r--r-- | GSM/GSMCommon.h | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/GSM/GSMCommon.h b/GSM/GSMCommon.h new file mode 100644 index 0000000..80c5608 --- /dev/null +++ b/GSM/GSMCommon.h @@ -0,0 +1,248 @@ +/**@file Common-use GSM declarations, most from the GSM 04.xx and 05.xx series. */ +/* +* Copyright 2008-2011 Free Software Foundation, Inc. +* +* 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[]; + +/** C0T0 filler burst, GSM 05.02, 5.2.6 */ +extern const BitVector gDummyBurst; + +/** Random access burst synch. sequence */ +extern const BitVector gRACHSynchSequence; + + +/**@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 |