blob: 1f8bed2d1f4875bfa021f0489f6539e6427e6a9e [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];
79};
80
dburgessb3a0ca42011-10-12 07:44:40 +000081/** The Transceiver class, responsible for physical layer of basestation */
82class Transceiver {
dburgessb3a0ca42011-10-12 07:44:40 +000083private:
Thomas Tsoud647ec52013-10-29 15:17:34 -040084 int mBasePort;
85 std::string mAddr;
dburgessb3a0ca42011-10-12 07:44:40 +000086 GSM::Time mTransmitLatency; ///< latency between basestation clock and transmit deadline clock
87 GSM::Time mLatencyUpdateTime; ///< last time latency was updated
88
Thomas Tsoud647ec52013-10-29 15:17:34 -040089 UDPSocket *mDataSocket; ///< socket for writing to/reading from GSM core
90 UDPSocket *mCtrlSocket; ///< socket for writing/reading control commands from GSM core
91 UDPSocket *mClockSocket; ///< socket for writing clock updates to GSM core
dburgessb3a0ca42011-10-12 07:44:40 +000092
93 VectorQueue mTransmitPriorityQueue; ///< priority queue of transmit bursts received from GSM core
94 VectorFIFO* mTransmitFIFO; ///< radioInterface FIFO of transmit bursts
95 VectorFIFO* mReceiveFIFO; ///< radioInterface FIFO of receive bursts
96
Thomas Tsou92c16df2013-09-28 18:04:19 -040097 Thread *mRxServiceLoopThread; ///< thread to pull bursts into receive FIFO
98 Thread *mTxServiceLoopThread; ///< thread to push bursts into transmit FIFO
dburgessb3a0ca42011-10-12 07:44:40 +000099 Thread *mControlServiceLoopThread; ///< thread to process control messages from GSM core
100 Thread *mTransmitPriorityQueueServiceLoopThread;///< thread to process transmit bursts from GSM core
101
102 GSM::Time mTransmitDeadlineClock; ///< deadline for pushing bursts into transmit FIFO
103 GSM::Time mLastClockUpdateTime; ///< last time clock update was sent up to core
104
105 RadioInterface *mRadioInterface; ///< associated radioInterface object
106 double txFullScale; ///< full scale input to radio
107 double rxFullScale; ///< full scale output to radio
108
109 /** Codes for burst types of received bursts*/
110 typedef enum {
111 OFF, ///< timeslot is off
112 TSC, ///< timeslot should contain a normal burst
113 RACH, ///< timeslot should contain an access burst
114 IDLE ///< timeslot is an idle (or dummy) burst
115 } CorrType;
116
Thomas Tsoufa3a7872013-10-17 21:23:34 -0400117 float mNoiseLev; ///< Average noise level
118 noiseVector mNoises; ///< Vector holding running noise measurements
dburgessb3a0ca42011-10-12 07:44:40 +0000119
dburgessb3a0ca42011-10-12 07:44:40 +0000120 /** modulate and add a burst to the transmit queue */
121 void addRadioVector(BitVector &burst,
122 int RSSI,
123 GSM::Time &wTime);
124
125 /** Push modulated burst into transmit FIFO corresponding to a particular timestamp */
126 void pushRadioVector(GSM::Time &nowTime);
127
128 /** Pull and demodulate a burst from the receive FIFO */
129 SoftVector *pullRadioVector(GSM::Time &wTime,
130 int &RSSI,
131 int &timingOffset);
132
133 /** Set modulus for specific timeslot */
134 void setModulus(int timeslot);
135
136 /** return the expected burst type for the specified timestamp */
137 CorrType expectedCorrType(GSM::Time currTime);
138
139 /** send messages over the clock socket */
140 void writeClockInterface(void);
141
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400142 int mSPSTx; ///< number of samples per Tx symbol
143 int mSPSRx; ///< number of samples per Rx symbol
dburgessb3a0ca42011-10-12 07:44:40 +0000144
145 bool mOn; ///< flag to indicate that transceiver is powered on
dburgessb3a0ca42011-10-12 07:44:40 +0000146 double mTxFreq; ///< the transmit frequency
147 double mRxFreq; ///< the receive frequency
148 int mPower; ///< the transmit power in dB
149 unsigned mTSC; ///< the midamble sequence code
dburgessb3a0ca42011-10-12 07:44:40 +0000150 unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
151
Thomas Tsouf0782732013-10-29 15:55:47 -0400152 TransceiverState mState;
dburgessb3a0ca42011-10-12 07:44:40 +0000153
154public:
155
156 /** Transceiver constructor
157 @param wBasePort base port number of UDP sockets
158 @param TRXAddress IP address of the TRX manager, as a string
Thomas Tsoud24cc2c2013-08-20 15:41:45 -0400159 @param wSPS number of samples per GSM symbol
dburgessb3a0ca42011-10-12 07:44:40 +0000160 @param wTransmitLatency initial setting of transmit latency
161 @param radioInterface associated radioInterface object
162 */
163 Transceiver(int wBasePort,
164 const char *TRXAddress,
Thomas Tsoud24cc2c2013-08-20 15:41:45 -0400165 int wSPS,
dburgessb3a0ca42011-10-12 07:44:40 +0000166 GSM::Time wTransmitLatency,
167 RadioInterface *wRadioInterface);
168
169 /** Destructor */
170 ~Transceiver();
171
172 /** start the Transceiver */
173 void start();
Thomas Tsou83e06892013-08-20 16:10:01 -0400174 bool init();
dburgessb3a0ca42011-10-12 07:44:40 +0000175
176 /** attach the radioInterface receive FIFO */
177 void receiveFIFO(VectorFIFO *wFIFO) { mReceiveFIFO = wFIFO;}
178
179 /** attach the radioInterface transmit FIFO */
180 void transmitFIFO(VectorFIFO *wFIFO) { mTransmitFIFO = wFIFO;}
181
Thomas Tsouf0782732013-10-29 15:55:47 -0400182 /** Codes for channel combinations */
183 typedef enum {
184 FILL, ///< Channel is transmitted, but unused
185 I, ///< TCH/FS
186 II, ///< TCH/HS, idle every other slot
187 III, ///< TCH/HS
188 IV, ///< FCCH+SCH+CCCH+BCCH, uplink RACH
189 V, ///< FCCH+SCH+CCCH+BCCH+SDCCH/4+SACCH/4, uplink RACH+SDCCH/4
190 VI, ///< CCCH+BCCH, uplink RACH
191 VII, ///< SDCCH/8 + SACCH/8
192 VIII, ///< TCH/F + FACCH/F + SACCH/M
193 IX, ///< TCH/F + SACCH/M
194 X, ///< TCH/FD + SACCH/MD
195 XI, ///< PBCCH+PCCCH+PDTCH+PACCH+PTCCH
196 XII, ///< PCCCH+PDTCH+PACCH+PTCCH
197 XIII, ///< PDTCH+PACCH+PTCCH
198 NONE, ///< Channel is inactive, default
199 LOOPBACK ///< similar go VII, used in loopback testing
200 } ChannelCombination;
201
dburgessb3a0ca42011-10-12 07:44:40 +0000202protected:
203
204 /** drive reception and demodulation of GSM bursts */
205 void driveReceiveFIFO();
206
207 /** drive transmission of GSM bursts */
208 void driveTransmitFIFO();
209
210 /** drive handling of control messages from GSM core */
211 void driveControl();
212
213 /**
214 drive modulation and sorting of GSM bursts from GSM core
215 @return true if a burst was transferred successfully
216 */
217 bool driveTransmitPriorityQueue();
218
Thomas Tsou92c16df2013-09-28 18:04:19 -0400219 friend void *RxServiceLoopAdapter(Transceiver *);
220
221 friend void *TxServiceLoopAdapter(Transceiver *);
dburgessb3a0ca42011-10-12 07:44:40 +0000222
223 friend void *ControlServiceLoopAdapter(Transceiver *);
224
225 friend void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
226
227 void reset();
kurtis.heimerl6b495a52011-11-26 03:17:21 +0000228
229 /** set priority on current thread */
230 void setPriority() { mRadioInterface->setPriority(); }
231
dburgessb3a0ca42011-10-12 07:44:40 +0000232};
233
Thomas Tsou92c16df2013-09-28 18:04:19 -0400234/** Main drive threads */
235void *RxServiceLoopAdapter(Transceiver *);
236void *TxServiceLoopAdapter(Transceiver *);
dburgessb3a0ca42011-10-12 07:44:40 +0000237
238/** control message handler thread loop */
239void *ControlServiceLoopAdapter(Transceiver *);
240
241/** transmit queueing thread loop */
242void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
243