summaryrefslogtreecommitdiff
path: root/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h
diff options
context:
space:
mode:
Diffstat (limited to 'gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h')
-rw-r--r--gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h537
1 files changed, 537 insertions, 0 deletions
diff --git a/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h b/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h
new file mode 100644
index 0000000..9dc1c95
--- /dev/null
+++ b/gsm-receiver/src/lib/decoder/openbtsstuff/GSMCommon.h
@@ -0,0 +1,537 @@
+/**@file Common-use GSM declarations, most from the GSM 04.xx and 05.xx series. */
+/*
+* Copyright 2008 Free Software Foundation, Inc.
+*
+* This software is distributed under the terms of the GNU Public License.
+* See the COPYING 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 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 General Public License for more details.
+
+ You should have received a copy of the GNU 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. */
+
+
+/* forward references */
+class L1FEC;
+class L2LAPDm;
+class L3Processor;
+class LogicalChannel;
+class L2Header;
+
+
+/** A base class for GSM exceptions. */
+class GSMError {};
+
+/** Duration ofa GSM frame, in microseconds. */
+const unsigned gFrameMicroseconds = 4615;
+
+
+/** Sleep for a given number of GSM frame periods. */
+inline void sleepFrames(unsigned frames)
+ { usleep(frames*gFrameMicroseconds); }
+
+/** Sleep for 1 GSM frame period. */
+inline void sleepFrame()
+ { usleep(gFrameMicroseconds); }
+
+
+
+/** 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 Support for GSM 7-bit alphabet, GSM 03.38 6.2.1. */
+//@{
+/** Indexed by GSM 7-bit, returns ASCII. */
+static const char gGSMAlphabet[] = "@\243$\245\350\351\371\354\362\347\n\330\370\r\305\345D_FGLOPCSTZ \306\346\337\311 !\"#\244%&\'()*+,-./0123456789:;<=>?\241ABCDEFGHIJKLMNOPQRSTUVWXYZ\304\326\321\334\247\277abcdefghijklmnopqrstuvwxyz\344\366\361\374\341";
+char encodeGSMChar(char ascii);
+inline char decodeGSMChar(char sms) { return gGSMAlphabet[(unsigned)sms]; }
+//@}
+
+
+/**@name BCD-ASCII mapping, GMS 04.08 Table 10.5.118. */
+//@{
+/** Indexed by BCD, returns ASCII. */
+static const char gBCDAlphabet[] = "0123456789.#abc";
+char encodeBCDChar(char ascii);
+inline char decodeBCDChar(char bcd) { return gBCDAlphabet[(unsigned)bcd]; }
+//@}
+
+
+/**@name Globally-fixed GSM timeout values (all in ms). */
+//@{
+/**@name GSM LAPDm timeouts, GSM 04.06 5.8, ITU-T Q.921 5.9 */
+//@{
+const unsigned T200ms = 900; ///< LAPDm ACK timeout, set for typical turnaround time
+//@}
+/**@name GSM timeouts for radio resource management, GSM 04.08 11.1. */
+//@{
+const unsigned T3101ms = 4000; ///< L1 timeout for SDCCH assignment
+const unsigned T3107ms = 3000; ///< L1 timeout for TCH/FACCH assignment
+const unsigned T3109ms = 10000; ///< L1 timeout for an existing channel
+const unsigned T3111ms = 2*T200ms; ///< L1 timeout for reassignment of a channel
+const unsigned T3113ms = 10000; ///< timeout for paging response
+const unsigned T3122ms = 2000; ///< RR access holdoff time (GSM 04.08 3.3.1.1.3.2)
+//@}
+/**@name GSM timeouts for mobility management, GSM 04.08 11.2. */
+//@{
+const unsigned T3212ms = 8*360000; ///< location updating period (in 6-min increments, 0-255)
+//const unsigned T3212ms = 0; ///< location updating period (in 6-min increments, 0-255), 0 disables
+//@}
+//@}
+
+
+
+
+/** GSM 04.08 Table 10.5.118 */
+enum TypeOfNumber {
+ UnknownTypeOfNumber = 0,
+ InternationalNumber = 1,
+ NationalNumber = 2,
+ NetworkSpecificNumber = 3,
+ ShortCodeNumber = 4
+};
+
+std::ostream& operator<<(std::ostream&, TypeOfNumber);
+
+
+/** GSM 04.08 Table 10.5.118 */
+enum NumberingPlan {
+ UnknownPlan = 0,
+ E164Plan = 1,
+ X121Plan = 3,
+ F69Plan = 4,
+ NationalPlan = 8,
+ PrivatePlan = 9
+};
+
+std::ostream& operator<<(std::ostream&, NumberingPlan);
+
+
+
+/** Codes for GSM band types, GSM 05.05 2. */
+enum GSMBand {
+ GSM850=0, ///< US cellular
+ EGSM900, ///< extended GSM
+ DCS1800, ///< worldwide DCS band
+ PCS1900 ///< US PCS band
+};
+
+
+/**@name Actual radio carrier frequencies, in kHz, GSM 05.05 2 */
+//@{
+unsigned uplinkFreqKHz(GSMBand wBand, unsigned wARFCN);
+unsigned downlinkFreqKHz(GSMBand wBand, unsigned wARFCN);
+//@}
+
+
+
+/**@name GSM Logical channel (LCH) types. */
+//@{
+/** Codes for logical channel types. */
+enum ChannelType {
+ ///@name Non-dedicated control channels.
+ //@{
+ SCHType, ///< sync
+ FCCHType, ///< frequency correction
+ BCCHType, ///< broadcast control
+ CCCHType, ///< common control, a combination of several sub-types
+ RACHType, ///< random access
+ SACCHType, ///< slow associated control (acutally dedicated, but...)
+ //@}
+ ///@name Dedicated control channels (DCCHs).
+ //@{
+ SDCCHType, ///< standalone dedicated control
+ FACCHType, ///< fast associated control
+ //@}
+ ///@name Traffic channels
+ //@{
+ TCHFType, ///< full-rate traffic
+ TCHHType, ///< half-rate traffic
+ AnyTCHType, ///< any TCH type
+ //@}
+ ///@name Special internal channel types.
+ //@{
+ LoopbackFullType, ///< loopback testing
+ LoopbackHalfType, ///< loopback testing
+ AnyDCCHType, ///< any dedicated control channel
+ UndefinedCHType, ///< undefined
+ //@}
+};
+
+
+/** Print channel type name to a stream. */
+std::ostream& operator<<(std::ostream& os, ChannelType val);
+
+
+//@}
+
+
+
+/** Mobile identity types, GSM 04.08 10.5.1.4 */
+enum MobileIDType {
+ NoIDType = 0,
+ IMSIType = 1,
+ IMEIType = 2,
+ IMEISVType = 3,
+ TMSIType = 4
+};
+
+std::ostream& operator<<(std::ostream& os, MobileIDType);
+
+
+/** Type and TDMA offset of a logical channel, from GSM 04.08 10.5.2.5 */
+enum TypeAndOffset {
+ TDMA_MISC=0,
+ TCHF_0=1,
+ TCHH_0=2, TCHH_1=3,
+ SDCCH_4_0=4, SDCCH_4_1=5, SDCCH_4_2=6, SDCCH_4_3=7,
+ SDCCH_8_0=8, SDCCH_8_1=9, SDCCH_8_2=10, SDCCH_8_3=11,
+ SDCCH_8_4=12, SDCCH_8_5=13, SDCCH_8_6=14, SDCCH_8_7=15,
+ /// An extra one for our internal use.
+ TDMA_BEACON=255
+};
+
+std::ostream& operator<<(std::ostream& os, TypeAndOffset);
+
+
+
+
+
+
+
+
+/**
+ L3 Protocol Discriminator, GSM 04.08 10.2, GSM 04.07 11.2.3.1.1.
+*/
+enum L3PD {
+ L3GroupCallControlPD=0x00,
+ L3BroadcastCallControlPD=0x01,
+ L3PDSS1PD=0x02,
+ L3CallControlPD=0x03,
+ L3PDSS2PD=0x04,
+ L3MobilityManagementPD=0x05,
+ L3RadioResourcePD=0x06,
+ L3MobilityManagementGPRSPD=0x08,
+ L3SMSPD=0x09,
+ L3GPRSSessionManagementPD=0x0a,
+ L3NonCallSSPD=0x0b,
+ L3LocationPD=0x0c,
+ L3ExtendedPD=0x0e,
+ L3TestProcedurePD=0x0f,
+ L3UndefinedPD=-1
+};
+
+
+
+std::ostream& operator<<(std::ostream& os, L3PD val);
+
+
+
+
+/**@name Modulus operations for frame numbers. */
+//@{
+/** The GSM hyperframe is largest time period in the GSM system, GSM 05.02 4.3.3. */
+const int32_t gHyperframe = 2048UL * 26UL * 51UL;
+
+/** Get a clock difference, within the modulus. */
+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.
+ No internal thread sync.
+*/
+class Time {
+
+ private:
+
+ int mFN; ///< frame number in the hyperframe
+ unsigned mTN; ///< timeslot number
+
+ public:
+
+ Time(int wFN=0, unsigned wTN=0)
+ :mFN(wFN),mTN(wTN)
+ { }
+
+
+ /** Move the time forward to a given position in a given modulus. */
+ void rollForward(unsigned wFN, unsigned modulus)
+ { while ((mFN % modulus) != wFN) mFN++; }
+
+ /**@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(int step=1)
+ {
+ if ((int)mTN<step) mFN = *this - Time(1,0);
+ if (mTN-step < 0) mTN = (mTN-step+8) % 8;
+ else mTN = (mTN-step) % 8;
+ return *this;
+ }
+
+ Time& incTN(int step=1)
+ {
+ mFN = mFN + (mTN + step)/8;
+ mTN = (mTN+step) % 8;
+ return *this;
+ }
+
+ Time& operator+=(int step)
+ {
+ mFN = (mFN+step) % gHyperframe;
+ return *this;
+ }
+
+ Time operator+(int step) const
+ {
+ Time newVal = *this;
+ newVal += step;
+ return newVal;
+ }
+
+ Time operator-(int step) const
+ {
+ return operator+(-step);
+ }
+
+ 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. */
+ //@{
+
+ unsigned SFN() const { return mFN / (26*51); }
+
+ unsigned T1() const { return SFN() % 2048; }
+
+ unsigned T2() const { return mFN % 26; }
+
+ 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);
+
+
+
+
+
+
+/**
+ A class for calculating the current GSM frame number.
+*/
+class Clock {
+
+ private:
+
+ mutable Mutex mLock;
+ int32_t mBaseFN;
+ Timeval mBaseTime;
+
+ public:
+
+ Clock(const Time& when = Time(0))
+ :mBaseFN(when.FN())
+ {}
+
+ /** Set the clock to a value. */
+ void set(const Time&);
+
+ /** Read the clock. */
+ int32_t FN() const;
+
+ /** Read the clock. */
+ Time get() const { return Time(FN()); }
+
+ /** Block until the clock passes a given time. */
+ void wait(const Time&) const;
+};
+
+
+
+
+
+
+
+
+/**
+ CCITT Z.100 activity timer, as described in GSM 04.06 5.1.
+ All times are in milliseconds.
+*/
+class Z100Timer {
+
+ private:
+
+ Timeval mEndTime; ///< the time at which this timer will expire
+ long mLimitTime; ///< timeout in milliseconds
+ bool mActive; ///< true if timer is active
+
+ public:
+
+ /** Create a timer with a given timeout in milliseconds. */
+ Z100Timer(long wLimitTime)
+ :mLimitTime(wLimitTime),
+ mActive(false)
+ {}
+
+ /** True if the timer is active and expired. */
+ bool expired() const;
+
+ /** Start or restart the timer. */
+ void set();
+
+ /** Stop the timer. */
+ void reset() { mActive = false; }
+
+ /** Returns true if the timer is active. */
+ bool active() const { return mActive; }
+
+ /**
+ Remaining time until expiration, in milliseconds.
+ Returns zero if the timer has expired.
+ */
+ long remaining() const;
+
+ /**
+ Block until the timer expires.
+ Returns immediately if the timer is not running.
+ */
+ void wait() const;
+};
+
+
+
+
+
+}; // namespace GSM
+
+
+#endif
+
+// vim: ts=4 sw=4
personal git repositories of Harald Welte. Your mileage may vary