This page is meant to describe the process of sending a GSM message on the transmit side to the BladeRF radio.
All the classes used by the ybts module to work with GSM messages are defined and implemented in the /mbts/GSM directory from YateBTS installation package, in the GSM namespace.
The GSMconfig class implements the GSM air interface and assures multithread access through MUTEX mechanisms. The GSM configuration is based on the contents from gConfig file which is used in the init() method; internal control loops are executed with the start() method.
For the physical layer L1, there are implemented a series of abstract encoders and decoders which are then wrapped by an instance of LogicalChannel in order to define the complete L3<->L1 handler.
The dataflow L1->L2, where L2 is the Data Link Layer, is described as follows:
The L2->L1 data flow is as follows:
While the L1FEC::sendLowSideRx method is used to send in an RxBurst for decoding, the L1FEC::writeHighSide method is used to send in an L2Frame for encoding and transmission.
The data link layer, L2 is represented by the class L2DL which is also implemented in the GSM namespace. This is a base class from which all the channels are derived. The interface with the L1 layer is implemented through the writeLowSide method mentioned above while the interface with the L3 layer, or Network Layer, is implemented through the method readHighSide which returns a L3Frame pointer. On the other hand, the interface L3->L2 is made through the method writeHighSide which accepts a reference to a L3Frameobject. All these pure virtual methods, meaning that they are overridden for each channel type.
For the Network Layer, L3, the LogicalChannel was implemented in the GSM namespace. This abstract representation of the GSM logical channel handles L3Frames and communicates with the second layer in terms of sending GSM message. It is a complete logical channel and it also includes processors for the other two layers (L2, L1). Above all, this is a virtual implementation which means that specific channel types are sublasses.
The transmission path
In case of a traffic channel, the flow of method calls in order to send a GSM message is as follows:
In case of a Common Control Channel (CCCH), the CCCHLogicalChannel class is used.It is derived from the LogicalChannel class. The main difference when sending a message is given by the fact that CCCH is written by multiple threads. Because of this, the abstract representation of the CCCH has a L3FrameFIFO member to manage the L3Frame frames. The flow of method calls in order to send a GSM message is as follows:
In both cases described above the ARFCNManager::writeHighSideTx call will pass a message through UDPSocket::write. Because the UDPSocket class is inherited from DatagramSocket the previous call will actually map to DatagramSocket::write which does an immediate sendto on the socket. The destination socket used by sendto is set in the UPDSocket class constructor, based on the destination port and IP . If the BladeRF device is connected to your machine, this is the point where the GSM message is actually sent to it by means of libusb.
The Transceiver class uses three UDPsockets to handle the communication with the GSM core. MDataSocket is the socket used for writing/reading, mControlSocket is the one writing/reading control commands while mClockSocket is the socket responsible for writing clock updates to the GSM core. The transmitted GSM message is handled through a thread , mTxServiceLoopThread, and the interface to the radio device is established through an RadioInterface object, mRadioInterface.
To send a burst with the transceiver, there must firstly be set some parameters which are specified through the class constructor:
The first step is to initialize the transceiver and then start it, which is achieved through the Transceiver::init() and Transceiver::start() methods.Also the transceiver’s receive FIFO must be filled with the radioInterface’s receive FIFO. The initialization process initializes the filler tables with dummy bursts while the start process starts a thread which processes the control messages from the GSM core. On the other hand, the process of starting the device actually involves starting a control service loop which is a thread aimed at processing the messages from the GSM core. This is done by using the UDPsocket::read.