blob: 4b549ef5a0d868c1cde1941a73c69555ba89f58f [file] [log] [blame]
dburgessb3a0ca42011-10-12 07:44:40 +00001/*
2* Copyright 2008 Free Software Foundation, Inc.
3*
4* This software is distributed under the terms of the GNU Public License.
5* See the COPYING file in the main directory for details.
6*
7* This use of this software may be subject to additional restrictions.
8* See the LEGAL file in the main directory for details.
9
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23*/
24
dburgessb3a0ca42011-10-12 07:44:40 +000025#include "radioInterface.h"
26#include "Interthread.h"
27#include "GSMCommon.h"
28#include "Sockets.h"
29
30#include <sys/types.h>
31#include <sys/socket.h>
32
dburgessb3a0ca42011-10-12 07:44:40 +000033/** The Transceiver class, responsible for physical layer of basestation */
34class Transceiver {
dburgessb3a0ca42011-10-12 07:44:40 +000035private:
Thomas Tsoud647ec52013-10-29 15:17:34 -040036 int mBasePort;
37 std::string mAddr;
dburgessb3a0ca42011-10-12 07:44:40 +000038 GSM::Time mTransmitLatency; ///< latency between basestation clock and transmit deadline clock
39 GSM::Time mLatencyUpdateTime; ///< last time latency was updated
40
Thomas Tsoud647ec52013-10-29 15:17:34 -040041 UDPSocket *mDataSocket; ///< socket for writing to/reading from GSM core
42 UDPSocket *mCtrlSocket; ///< socket for writing/reading control commands from GSM core
43 UDPSocket *mClockSocket; ///< socket for writing clock updates to GSM core
dburgessb3a0ca42011-10-12 07:44:40 +000044
45 VectorQueue mTransmitPriorityQueue; ///< priority queue of transmit bursts received from GSM core
46 VectorFIFO* mTransmitFIFO; ///< radioInterface FIFO of transmit bursts
47 VectorFIFO* mReceiveFIFO; ///< radioInterface FIFO of receive bursts
48
Thomas Tsou92c16df2013-09-28 18:04:19 -040049 Thread *mRxServiceLoopThread; ///< thread to pull bursts into receive FIFO
50 Thread *mTxServiceLoopThread; ///< thread to push bursts into transmit FIFO
dburgessb3a0ca42011-10-12 07:44:40 +000051 Thread *mControlServiceLoopThread; ///< thread to process control messages from GSM core
52 Thread *mTransmitPriorityQueueServiceLoopThread;///< thread to process transmit bursts from GSM core
53
54 GSM::Time mTransmitDeadlineClock; ///< deadline for pushing bursts into transmit FIFO
55 GSM::Time mLastClockUpdateTime; ///< last time clock update was sent up to core
56
57 RadioInterface *mRadioInterface; ///< associated radioInterface object
58 double txFullScale; ///< full scale input to radio
59 double rxFullScale; ///< full scale output to radio
60
61 /** Codes for burst types of received bursts*/
62 typedef enum {
63 OFF, ///< timeslot is off
64 TSC, ///< timeslot should contain a normal burst
65 RACH, ///< timeslot should contain an access burst
66 IDLE ///< timeslot is an idle (or dummy) burst
67 } CorrType;
68
69
70 /** Codes for channel combinations */
71 typedef enum {
72 FILL, ///< Channel is transmitted, but unused
73 I, ///< TCH/FS
74 II, ///< TCH/HS, idle every other slot
75 III, ///< TCH/HS
76 IV, ///< FCCH+SCH+CCCH+BCCH, uplink RACH
77 V, ///< FCCH+SCH+CCCH+BCCH+SDCCH/4+SACCH/4, uplink RACH+SDCCH/4
78 VI, ///< CCCH+BCCH, uplink RACH
79 VII, ///< SDCCH/8 + SACCH/8
ttsoufc40a842013-06-09 22:38:18 +000080 VIII, ///< TCH/F + FACCH/F + SACCH/M
81 IX, ///< TCH/F + SACCH/M
82 X, ///< TCH/FD + SACCH/MD
83 XI, ///< PBCCH+PCCCH+PDTCH+PACCH+PTCCH
84 XII, ///< PCCCH+PDTCH+PACCH+PTCCH
85 XIII, ///< PDTCH+PACCH+PTCCH
dburgessb3a0ca42011-10-12 07:44:40 +000086 NONE, ///< Channel is inactive, default
ttsoufc40a842013-06-09 22:38:18 +000087 LOOPBACK ///< similar go VII, used in loopback testing
dburgessb3a0ca42011-10-12 07:44:40 +000088 } ChannelCombination;
89
Thomas Tsoufa3a7872013-10-17 21:23:34 -040090 float mNoiseLev; ///< Average noise level
91 noiseVector mNoises; ///< Vector holding running noise measurements
dburgessb3a0ca42011-10-12 07:44:40 +000092
dburgessb3a0ca42011-10-12 07:44:40 +000093 /** modulate and add a burst to the transmit queue */
94 void addRadioVector(BitVector &burst,
95 int RSSI,
96 GSM::Time &wTime);
97
98 /** Push modulated burst into transmit FIFO corresponding to a particular timestamp */
99 void pushRadioVector(GSM::Time &nowTime);
100
101 /** Pull and demodulate a burst from the receive FIFO */
102 SoftVector *pullRadioVector(GSM::Time &wTime,
103 int &RSSI,
104 int &timingOffset);
105
106 /** Set modulus for specific timeslot */
107 void setModulus(int timeslot);
108
109 /** return the expected burst type for the specified timestamp */
110 CorrType expectedCorrType(GSM::Time currTime);
111
112 /** send messages over the clock socket */
113 void writeClockInterface(void);
114
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400115 int mSPSTx; ///< number of samples per Tx symbol
116 int mSPSRx; ///< number of samples per Rx symbol
dburgessb3a0ca42011-10-12 07:44:40 +0000117
118 bool mOn; ///< flag to indicate that transceiver is powered on
119 ChannelCombination mChanType[8]; ///< channel types for all timeslots
120 double mTxFreq; ///< the transmit frequency
121 double mRxFreq; ///< the receive frequency
122 int mPower; ///< the transmit power in dB
123 unsigned mTSC; ///< the midamble sequence code
dburgessb3a0ca42011-10-12 07:44:40 +0000124 int fillerModulus[8]; ///< modulus values of all timeslots, in frames
125 signalVector *fillerTable[102][8]; ///< table of modulated filler waveforms for all timeslots
126 unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
127
128 GSM::Time channelEstimateTime[8]; ///< last timestamp of each timeslot's channel estimate
129 signalVector *channelResponse[8]; ///< most recent channel estimate of all timeslots
130 float SNRestimate[8]; ///< most recent SNR estimate of all timeslots
131 signalVector *DFEForward[8]; ///< most recent DFE feedforward filter of all timeslots
132 signalVector *DFEFeedback[8]; ///< most recent DFE feedback filter of all timeslots
133 float chanRespOffset[8]; ///< most recent timing offset, e.g. TOA, of all timeslots
134 complex chanRespAmplitude[8]; ///< most recent channel amplitude of all timeslots
135
136public:
137
138 /** Transceiver constructor
139 @param wBasePort base port number of UDP sockets
140 @param TRXAddress IP address of the TRX manager, as a string
Thomas Tsoud24cc2c2013-08-20 15:41:45 -0400141 @param wSPS number of samples per GSM symbol
dburgessb3a0ca42011-10-12 07:44:40 +0000142 @param wTransmitLatency initial setting of transmit latency
143 @param radioInterface associated radioInterface object
144 */
145 Transceiver(int wBasePort,
146 const char *TRXAddress,
Thomas Tsoud24cc2c2013-08-20 15:41:45 -0400147 int wSPS,
dburgessb3a0ca42011-10-12 07:44:40 +0000148 GSM::Time wTransmitLatency,
149 RadioInterface *wRadioInterface);
150
151 /** Destructor */
152 ~Transceiver();
153
154 /** start the Transceiver */
155 void start();
Thomas Tsou83e06892013-08-20 16:10:01 -0400156 bool init();
dburgessb3a0ca42011-10-12 07:44:40 +0000157
158 /** attach the radioInterface receive FIFO */
159 void receiveFIFO(VectorFIFO *wFIFO) { mReceiveFIFO = wFIFO;}
160
161 /** attach the radioInterface transmit FIFO */
162 void transmitFIFO(VectorFIFO *wFIFO) { mTransmitFIFO = wFIFO;}
163
dburgessb3a0ca42011-10-12 07:44:40 +0000164protected:
165
166 /** drive reception and demodulation of GSM bursts */
167 void driveReceiveFIFO();
168
169 /** drive transmission of GSM bursts */
170 void driveTransmitFIFO();
171
172 /** drive handling of control messages from GSM core */
173 void driveControl();
174
175 /**
176 drive modulation and sorting of GSM bursts from GSM core
177 @return true if a burst was transferred successfully
178 */
179 bool driveTransmitPriorityQueue();
180
Thomas Tsou92c16df2013-09-28 18:04:19 -0400181 friend void *RxServiceLoopAdapter(Transceiver *);
182
183 friend void *TxServiceLoopAdapter(Transceiver *);
dburgessb3a0ca42011-10-12 07:44:40 +0000184
185 friend void *ControlServiceLoopAdapter(Transceiver *);
186
187 friend void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
188
189 void reset();
kurtis.heimerl6b495a52011-11-26 03:17:21 +0000190
191 /** set priority on current thread */
192 void setPriority() { mRadioInterface->setPriority(); }
193
dburgessb3a0ca42011-10-12 07:44:40 +0000194};
195
Thomas Tsou92c16df2013-09-28 18:04:19 -0400196/** Main drive threads */
197void *RxServiceLoopAdapter(Transceiver *);
198void *TxServiceLoopAdapter(Transceiver *);
dburgessb3a0ca42011-10-12 07:44:40 +0000199
200/** control message handler thread loop */
201void *ControlServiceLoopAdapter(Transceiver *);
202
203/** transmit queueing thread loop */
204void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
205