blob: d243214875dd80ee2293af687359d48d42064185 [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
25
26
27/*
28 Compilation switches
29 TRANSMIT_LOGGING write every burst on the given slot to a log
30*/
31
32#include "radioInterface.h"
33#include "Interthread.h"
34#include "GSMCommon.h"
35#include "Sockets.h"
36
37#include <sys/types.h>
38#include <sys/socket.h>
39
40/** Define this to be the slot number to be logged. */
41//#define TRANSMIT_LOGGING 1
42
43/** The Transceiver class, responsible for physical layer of basestation */
44class Transceiver {
45
46private:
47
48 GSM::Time mTransmitLatency; ///< latency between basestation clock and transmit deadline clock
49 GSM::Time mLatencyUpdateTime; ///< last time latency was updated
50
51 UDPSocket mDataSocket; ///< socket for writing to/reading from GSM core
52 UDPSocket mControlSocket; ///< socket for writing/reading control commands from GSM core
53 UDPSocket mClockSocket; ///< socket for writing clock updates to GSM core
54
55 VectorQueue mTransmitPriorityQueue; ///< priority queue of transmit bursts received from GSM core
56 VectorFIFO* mTransmitFIFO; ///< radioInterface FIFO of transmit bursts
57 VectorFIFO* mReceiveFIFO; ///< radioInterface FIFO of receive bursts
58
Thomas Tsou92c16df2013-09-28 18:04:19 -040059 Thread *mRxServiceLoopThread; ///< thread to pull bursts into receive FIFO
60 Thread *mTxServiceLoopThread; ///< thread to push bursts into transmit FIFO
dburgessb3a0ca42011-10-12 07:44:40 +000061 Thread *mControlServiceLoopThread; ///< thread to process control messages from GSM core
62 Thread *mTransmitPriorityQueueServiceLoopThread;///< thread to process transmit bursts from GSM core
63
64 GSM::Time mTransmitDeadlineClock; ///< deadline for pushing bursts into transmit FIFO
65 GSM::Time mLastClockUpdateTime; ///< last time clock update was sent up to core
66
67 RadioInterface *mRadioInterface; ///< associated radioInterface object
68 double txFullScale; ///< full scale input to radio
69 double rxFullScale; ///< full scale output to radio
70
71 /** Codes for burst types of received bursts*/
72 typedef enum {
73 OFF, ///< timeslot is off
74 TSC, ///< timeslot should contain a normal burst
75 RACH, ///< timeslot should contain an access burst
76 IDLE ///< timeslot is an idle (or dummy) burst
77 } CorrType;
78
79
80 /** Codes for channel combinations */
81 typedef enum {
82 FILL, ///< Channel is transmitted, but unused
83 I, ///< TCH/FS
84 II, ///< TCH/HS, idle every other slot
85 III, ///< TCH/HS
86 IV, ///< FCCH+SCH+CCCH+BCCH, uplink RACH
87 V, ///< FCCH+SCH+CCCH+BCCH+SDCCH/4+SACCH/4, uplink RACH+SDCCH/4
88 VI, ///< CCCH+BCCH, uplink RACH
89 VII, ///< SDCCH/8 + SACCH/8
ttsoufc40a842013-06-09 22:38:18 +000090 VIII, ///< TCH/F + FACCH/F + SACCH/M
91 IX, ///< TCH/F + SACCH/M
92 X, ///< TCH/FD + SACCH/MD
93 XI, ///< PBCCH+PCCCH+PDTCH+PACCH+PTCCH
94 XII, ///< PCCCH+PDTCH+PACCH+PTCCH
95 XIII, ///< PDTCH+PACCH+PTCCH
dburgessb3a0ca42011-10-12 07:44:40 +000096 NONE, ///< Channel is inactive, default
ttsoufc40a842013-06-09 22:38:18 +000097 LOOPBACK ///< similar go VII, used in loopback testing
dburgessb3a0ca42011-10-12 07:44:40 +000098 } ChannelCombination;
99
100
101 /** unmodulate a modulated burst */
102#ifdef TRANSMIT_LOGGING
103 void unModulateVector(signalVector wVector);
104#endif
105
106 /** modulate and add a burst to the transmit queue */
107 void addRadioVector(BitVector &burst,
108 int RSSI,
109 GSM::Time &wTime);
110
111 /** Push modulated burst into transmit FIFO corresponding to a particular timestamp */
112 void pushRadioVector(GSM::Time &nowTime);
113
114 /** Pull and demodulate a burst from the receive FIFO */
115 SoftVector *pullRadioVector(GSM::Time &wTime,
116 int &RSSI,
117 int &timingOffset);
118
119 /** Set modulus for specific timeslot */
120 void setModulus(int timeslot);
121
122 /** return the expected burst type for the specified timestamp */
123 CorrType expectedCorrType(GSM::Time currTime);
124
125 /** send messages over the clock socket */
126 void writeClockInterface(void);
127
Thomas Tsouc1f7c422013-10-11 13:49:55 -0400128 int mSPSTx; ///< number of samples per Tx symbol
129 int mSPSRx; ///< number of samples per Rx symbol
dburgessb3a0ca42011-10-12 07:44:40 +0000130
131 bool mOn; ///< flag to indicate that transceiver is powered on
132 ChannelCombination mChanType[8]; ///< channel types for all timeslots
133 double mTxFreq; ///< the transmit frequency
134 double mRxFreq; ///< the receive frequency
135 int mPower; ///< the transmit power in dB
136 unsigned mTSC; ///< the midamble sequence code
137 double mEnergyThreshold; ///< threshold to determine if received data is potentially a GSM burst
138 GSM::Time prevFalseDetectionTime; ///< last timestamp of a false energy detection
139 int fillerModulus[8]; ///< modulus values of all timeslots, in frames
140 signalVector *fillerTable[102][8]; ///< table of modulated filler waveforms for all timeslots
141 unsigned mMaxExpectedDelay; ///< maximum expected time-of-arrival offset in GSM symbols
142
143 GSM::Time channelEstimateTime[8]; ///< last timestamp of each timeslot's channel estimate
144 signalVector *channelResponse[8]; ///< most recent channel estimate of all timeslots
145 float SNRestimate[8]; ///< most recent SNR estimate of all timeslots
146 signalVector *DFEForward[8]; ///< most recent DFE feedforward filter of all timeslots
147 signalVector *DFEFeedback[8]; ///< most recent DFE feedback filter of all timeslots
148 float chanRespOffset[8]; ///< most recent timing offset, e.g. TOA, of all timeslots
149 complex chanRespAmplitude[8]; ///< most recent channel amplitude of all timeslots
150
151public:
152
153 /** Transceiver constructor
154 @param wBasePort base port number of UDP sockets
155 @param TRXAddress IP address of the TRX manager, as a string
Thomas Tsoud24cc2c2013-08-20 15:41:45 -0400156 @param wSPS number of samples per GSM symbol
dburgessb3a0ca42011-10-12 07:44:40 +0000157 @param wTransmitLatency initial setting of transmit latency
158 @param radioInterface associated radioInterface object
159 */
160 Transceiver(int wBasePort,
161 const char *TRXAddress,
Thomas Tsoud24cc2c2013-08-20 15:41:45 -0400162 int wSPS,
dburgessb3a0ca42011-10-12 07:44:40 +0000163 GSM::Time wTransmitLatency,
164 RadioInterface *wRadioInterface);
165
166 /** Destructor */
167 ~Transceiver();
168
169 /** start the Transceiver */
170 void start();
Thomas Tsou83e06892013-08-20 16:10:01 -0400171 bool init();
dburgessb3a0ca42011-10-12 07:44:40 +0000172
173 /** attach the radioInterface receive FIFO */
174 void receiveFIFO(VectorFIFO *wFIFO) { mReceiveFIFO = wFIFO;}
175
176 /** attach the radioInterface transmit FIFO */
177 void transmitFIFO(VectorFIFO *wFIFO) { mTransmitFIFO = wFIFO;}
178
dburgessb3a0ca42011-10-12 07:44:40 +0000179protected:
180
181 /** drive reception and demodulation of GSM bursts */
182 void driveReceiveFIFO();
183
184 /** drive transmission of GSM bursts */
185 void driveTransmitFIFO();
186
187 /** drive handling of control messages from GSM core */
188 void driveControl();
189
190 /**
191 drive modulation and sorting of GSM bursts from GSM core
192 @return true if a burst was transferred successfully
193 */
194 bool driveTransmitPriorityQueue();
195
Thomas Tsou92c16df2013-09-28 18:04:19 -0400196 friend void *RxServiceLoopAdapter(Transceiver *);
197
198 friend void *TxServiceLoopAdapter(Transceiver *);
dburgessb3a0ca42011-10-12 07:44:40 +0000199
200 friend void *ControlServiceLoopAdapter(Transceiver *);
201
202 friend void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
203
204 void reset();
kurtis.heimerl6b495a52011-11-26 03:17:21 +0000205
206 /** set priority on current thread */
207 void setPriority() { mRadioInterface->setPriority(); }
208
dburgessb3a0ca42011-10-12 07:44:40 +0000209};
210
Thomas Tsou92c16df2013-09-28 18:04:19 -0400211/** Main drive threads */
212void *RxServiceLoopAdapter(Transceiver *);
213void *TxServiceLoopAdapter(Transceiver *);
dburgessb3a0ca42011-10-12 07:44:40 +0000214
215/** control message handler thread loop */
216void *ControlServiceLoopAdapter(Transceiver *);
217
218/** transmit queueing thread loop */
219void *TransmitPriorityQueueServiceLoopAdapter(Transceiver *);
220