blob: 51b6e2466fcb544fa4bd9cf1f362fbf45fbdffe7 [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
Thomas Tsouf0782732013-10-29 15:55:47 -040033class Transceiver;
34
35/** Channel descriptor for transceiver object and channel number pair */
36struct TransceiverChannel {
37 TransceiverChannel(Transceiver *trx, int num)
38 {
39 this->trx = trx;
40 this->num = num;
41 }
42
43 ~TransceiverChannel()
44 {
45 }
46
47 Transceiver *trx;
48 size_t num;
49};
50
51/** Internal transceiver state variables */
52struct TransceiverState {
53 TransceiverState();
54 ~TransceiverState();
55
56 /* Initialize a multiframe slot in the filler table */
57 void init(size_t slot, signalVector *burst);
58
59 int chanType[8];
60
61 /* Last timestamp of each timeslot's channel estimate */
62 GSM::Time chanEstimateTime[8];
63
64 /* The filler table */
65 signalVector *fillerTable[102][8];
66 int fillerModulus[8];
67
68 /* Most recent channel estimate of all timeslots */
69 signalVector *chanResponse[8];
70
71 /* Most recent DFE feedback filter of all timeslots */
72 signalVector *DFEForward[8];
73 signalVector *DFEFeedback[8];
74
75 /* Most recent SNR, timing, and channel amplitude estimates */
76 float SNRestimate[8];
77 float chanRespOffset[8];
78 complex chanRespAmplitude[8];
Thomas Tsoua0179e32013-11-14 15:52:04 -050079
80 /* Received noise energy levels */
81 float mNoiseLev;
82 noiseVector mNoises;
Thomas Tsouf0782732013-10-29 15:55:47 -040083};
84
dburgessb3a0ca42011-10-12 07:44:40 +000085/** The Transceiver class, responsible for physical layer of basestation */
86class Transceiver {
dburgessb3a0ca42011-10-12 07:44:40 +000087private:
Thomas Tsoud647ec52013-10-29 15:17:34 -040088 int mBasePort;
89 std::string mAddr;
dburgessb3a0ca42011-10-12 07:44:40 +000090 GSM::Time mTransmitLatency; ///< latency between basestation clock and transmit deadline clock
91 GSM::Time mLatencyUpdateTime; ///< last time latency was updated
92
Thomas Tsou204a9f12013-10-29 18:34:16 -040093 std::vector<UDPSocket *> mDataSockets; ///< socket for writing to/reading from GSM core
94 std::vector<UDPSocket *> mCtrlSockets; ///< socket for writing/reading control commands from GSM core
95 UDPSocket *mClockSocket; ///< socket for writing clock updates to GSM core
dburgessb3a0ca42011-10-12 07:44:40 +000096
Thomas Tsou204a9f12013-10-29 18:34:16 -040097 std::vector<VectorQueue> mTxPriorityQueues; ///< priority queue of transmit bursts received from GSM core
98 std::vector<VectorFIFO *> mReceiveFIFO; ///< radioInterface FIFO of receive bursts
dburgessb3a0ca42011-10-12 07:44:40 +000099
Thomas Tsou204a9f12013-10-29 18:34:16 -0400100 std::vector<Thread *> mRxServiceLoopThreads; ///< thread to pull bursts into receive FIFO
101 Thread *mRxLowerLoopThread; ///< thread to pull bursts into receive FIFO
102 Thread *mTxLowerLoopThread; ///< thread to push bursts into transmit FIFO
103 std::vector<Thread *> mControlServiceLoopThreads; ///< thread to process control messages from GSM core
104 std::vector<Thread *> mTxPriorityQueueServiceLoopThreads; ///< thread to process transmit bursts from GSM core
dburgessb3a0ca42011-10-12 07:44:40 +0000105
106 GSM::Time mTransmitDeadlineClock; ///< deadline for pushing bursts into transmit FIFO
107 GSM::Time mLastClockUpdateTime; ///< last time clock update was sent up to core
108
109 RadioInterface *mRadioInterface; ///< associated radioInterface object
110 double txFullScale; ///< full scale input to radio
111 double rxFullScale; ///< full scale output to radio
112
113 /** Codes for burst types of received bursts*/
114 typedef enum {
115 OFF, ///< timeslot is off
116 TSC, ///< timeslot should contain a normal burst
117 RACH, ///< timeslot should contain an access burst
118 IDLE ///< timeslot is an idle (or dummy) burst
119 } CorrType;
120
dburgessb3a0ca42011-10-12 07:44:40 +0000121 /** modulate and add a burst to the transmit queue */
Thomas Tsoua2fe91a2013-11-13 22:48:11 -0500122 void addRadioVector(size_t chan, BitVector &bits,
Thomas Tsou204a9f12013-10-29 18:34:16 -0400123 int RSSI, GSM::Time &wTime);
dburgessb3a0ca42011-10-12 07:44:40 +0000124
125 /** Push modulated burst into transmit FIFO corresponding to a particular timestamp */
126 void pushRadioVector(GSM::Time &nowTime);
127
Thomas Tsou204a9f12013-10-29 18:34:16 -0400128 /** Pull and demodulate a burst from the receive FIFO */
129 SoftVector *pullRadioVector(GSM::Time &wTime, int &RSSI,
130 int &timingOffset, size_t chan = 0);
131
dburgessb3a0ca42011-10-12 07:44:40 +0000132 /** Set modulus for specific timeslot */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400133 void setModulus(size_t timeslot, size_t chan);
dburgessb3a0ca42011-10-12 07:44:40 +0000134
135 /** return the expected burst type for the specified timestamp */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400136 CorrType expectedCorrType(GSM::Time currTime, size_t chan);
dburgessb3a0ca42011-10-12 07:44:40 +0000137
138 /** send messages over the clock socket */
139 void writeClockInterface(void);
140
Thomas Tsou30421a72013-11-13 23:14:48 -0500141 /** Detect RACH bursts */
142 bool detectRACH(TransceiverState *state,
143 signalVector &burst,
144 complex &amp, float &toa);
145
146 /** Detect normal bursts */
147 bool detectTSC(TransceiverState *state,
148 signalVector &burst,
149 complex &amp, float &toa, GSM::Time &time);
150
151 /** Demodulat burst and output soft bits */
152 SoftVector *demodulate(TransceiverState *state,
153 signalVector &burst, complex amp,
154 float toa, size_t tn, bool equalize);
155
156
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400157 int mSPSTx; ///< number of samples per Tx symbol
158 int mSPSRx; ///< number of samples per Rx symbol
Thomas Tsou204a9f12013-10-29 18:34:16 -0400159 size_t mChans;
dburgessb3a0ca42011-10-12 07:44:40 +0000160
161 bool mOn; ///< flag to indicate that transceiver is powered on
dburgessb3a0ca42011-10-12 07:44:40 +0000162 double mTxFreq; ///< the transmit frequency
163 double mRxFreq; ///< the receive frequency
164 int mPower; ///< the transmit power in dB
165 unsigned mTSC; ///< the midamble sequence code
dburgessb3a0ca42011-10-12 07:44:40 +0000166 unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
167
Thomas Tsou204a9f12013-10-29 18:34:16 -0400168 std::vector<TransceiverState> mStates;
dburgessb3a0ca42011-10-12 07:44:40 +0000169
170public:
171
172 /** Transceiver constructor
173 @param wBasePort base port number of UDP sockets
174 @param TRXAddress IP address of the TRX manager, as a string
Thomas Tsoud24cc2c2013-08-20 15:41:45 -0400175 @param wSPS number of samples per GSM symbol
dburgessb3a0ca42011-10-12 07:44:40 +0000176 @param wTransmitLatency initial setting of transmit latency
177 @param radioInterface associated radioInterface object
178 */
179 Transceiver(int wBasePort,
180 const char *TRXAddress,
Thomas Tsou204a9f12013-10-29 18:34:16 -0400181 size_t wSPS, size_t chans,
dburgessb3a0ca42011-10-12 07:44:40 +0000182 GSM::Time wTransmitLatency,
183 RadioInterface *wRadioInterface);
Thomas Tsou204a9f12013-10-29 18:34:16 -0400184
dburgessb3a0ca42011-10-12 07:44:40 +0000185 /** Destructor */
186 ~Transceiver();
187
188 /** start the Transceiver */
189 void start();
Thomas Tsou83e06892013-08-20 16:10:01 -0400190 bool init();
dburgessb3a0ca42011-10-12 07:44:40 +0000191
192 /** attach the radioInterface receive FIFO */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400193 bool receiveFIFO(VectorFIFO *wFIFO, size_t chan)
194 {
195 if (chan >= mReceiveFIFO.size())
196 return false;
dburgessb3a0ca42011-10-12 07:44:40 +0000197
Thomas Tsou204a9f12013-10-29 18:34:16 -0400198 mReceiveFIFO[chan] = wFIFO;
199 return true;
200 }
dburgessb3a0ca42011-10-12 07:44:40 +0000201
Thomas Tsouf0782732013-10-29 15:55:47 -0400202 /** Codes for channel combinations */
203 typedef enum {
204 FILL, ///< Channel is transmitted, but unused
205 I, ///< TCH/FS
206 II, ///< TCH/HS, idle every other slot
207 III, ///< TCH/HS
208 IV, ///< FCCH+SCH+CCCH+BCCH, uplink RACH
209 V, ///< FCCH+SCH+CCCH+BCCH+SDCCH/4+SACCH/4, uplink RACH+SDCCH/4
210 VI, ///< CCCH+BCCH, uplink RACH
211 VII, ///< SDCCH/8 + SACCH/8
212 VIII, ///< TCH/F + FACCH/F + SACCH/M
213 IX, ///< TCH/F + SACCH/M
214 X, ///< TCH/FD + SACCH/MD
215 XI, ///< PBCCH+PCCCH+PDTCH+PACCH+PTCCH
216 XII, ///< PCCCH+PDTCH+PACCH+PTCCH
217 XIII, ///< PDTCH+PACCH+PTCCH
218 NONE, ///< Channel is inactive, default
219 LOOPBACK ///< similar go VII, used in loopback testing
220 } ChannelCombination;
221
dburgessb3a0ca42011-10-12 07:44:40 +0000222protected:
Thomas Tsou204a9f12013-10-29 18:34:16 -0400223 /** drive lower receive I/O and burst generation */
224 void driveReceiveRadio();
dburgessb3a0ca42011-10-12 07:44:40 +0000225
Thomas Tsou204a9f12013-10-29 18:34:16 -0400226 /** drive demodulation of GSM bursts */
227 void driveReceiveFIFO(size_t chan);
dburgessb3a0ca42011-10-12 07:44:40 +0000228
229 /** drive transmission of GSM bursts */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400230 void driveTxFIFO();
dburgessb3a0ca42011-10-12 07:44:40 +0000231
232 /** drive handling of control messages from GSM core */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400233 void driveControl(size_t chan);
dburgessb3a0ca42011-10-12 07:44:40 +0000234
235 /**
236 drive modulation and sorting of GSM bursts from GSM core
237 @return true if a burst was transferred successfully
238 */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400239 bool driveTxPriorityQueue(size_t chan);
dburgessb3a0ca42011-10-12 07:44:40 +0000240
Thomas Tsou204a9f12013-10-29 18:34:16 -0400241 friend void *RxUpperLoopAdapter(TransceiverChannel *);
Thomas Tsou92c16df2013-09-28 18:04:19 -0400242
Thomas Tsou204a9f12013-10-29 18:34:16 -0400243 friend void *TxUpperLoopAdapter(TransceiverChannel *);
dburgessb3a0ca42011-10-12 07:44:40 +0000244
Thomas Tsou204a9f12013-10-29 18:34:16 -0400245 friend void *RxLowerLoopAdapter(Transceiver *);
dburgessb3a0ca42011-10-12 07:44:40 +0000246
Thomas Tsou204a9f12013-10-29 18:34:16 -0400247 friend void *TxLowerLoopAdapter(Transceiver *);
248
249 friend void *ControlServiceLoopAdapter(TransceiverChannel *);
250
dburgessb3a0ca42011-10-12 07:44:40 +0000251
252 void reset();
kurtis.heimerl6b495a52011-11-26 03:17:21 +0000253
254 /** set priority on current thread */
Thomas Tsou7553aa92013-11-08 12:50:03 -0500255 void setPriority(float prio = 0.5) { mRadioInterface->setPriority(prio); }
kurtis.heimerl6b495a52011-11-26 03:17:21 +0000256
dburgessb3a0ca42011-10-12 07:44:40 +0000257};
258
Thomas Tsou204a9f12013-10-29 18:34:16 -0400259void *RxUpperLoopAdapter(TransceiverChannel *);
260
Thomas Tsou92c16df2013-09-28 18:04:19 -0400261/** Main drive threads */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400262void *RxLowerLoopAdapter(Transceiver *);
263void *TxLowerLoopAdapter(Transceiver *);
dburgessb3a0ca42011-10-12 07:44:40 +0000264
265/** control message handler thread loop */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400266void *ControlServiceLoopAdapter(TransceiverChannel *);
dburgessb3a0ca42011-10-12 07:44:40 +0000267
268/** transmit queueing thread loop */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400269void *TxUpperLoopAdapter(TransceiverChannel *);
dburgessb3a0ca42011-10-12 07:44:40 +0000270