SDR  - srsLTE Example - Pdsch_Ue                                           Home : www.sharetechnote.com

 

 

 

 

srsLTE - Example - Pdsch_Ue

 

This example is implemented by the source srsLTE\examples\Pdsch_ue.c. The functionality of this example is read OFDMA data (in the form of I/Q) from a file or RF Board and decode PDSCH. But you need to complete many of things before you decode PDSCH. So the source code would look much more complicated as you might think. But this would be a very good example of understanding the overall process of detect/decoding dowlink signal happening in UE.

 

By setting a simple flag, you can let this function to decode PDSCH from a file (meaning you don't need any RF hardware) or directly from a RF hardware (e.g, USRP).

 

Since my main purpose is to understand the details of the code, not building a working hardware. I chose to look into the details of the code that decode PDSCH from a file. I simplied the code which is directly related to this process and removing all error handling parts just leaving the parts that is directly related to the decoding process.

 

I hope this summary and additional comments help you to undertand the original source code in the project.

 

 

Case 1 : Decoding PDSCH from a file

 

/**

 *

 * \section COPYRIGHT

 *

 * Copyright 2013-2015 Software Radio Systems Limited

 *

 * \section LICENSE

 *

 * This file is part of the srsLTE library.

 *

 * srsLTE is free software: you can redistribute it and/or modify

 * it under the terms of the GNU Affero General Public License as

 * published by the Free Software Foundation, either version 3 of

 * the License, or (at your option) any later version.

 *

 * srsLTE is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 * GNU Affero General Public License for more details.

 *

 * A copy of the GNU Affero General Public License can be found in

 * the LICENSE file in the top-level directory of this distribution

 * and at http://www.gnu.org/licenses/.

 *

 */

 

 

int main(int argc, char **argv) {

    // Initialize all the resources that is required to perform Synchronization. When you decode PDSCH from file,

    // the main role of this function is to read data from pdsch file and store it into an internal array to be used in

    // other process.

    srslte_ue_sync_init_file(&ue_sync,

                                   prog_args.file_nof_prb,

                                   prog_args.input_file_name,

                                   prog_args.file_offset_time,

                                   prog_args.file_offset_freq)

     

    // Initialize all the resources that is required for decode MIB. Initialization of OFDM symbol array and Channel

    // Estimation resource are done in this function as well.

    srslte_ue_mib_init(&ue_mib, cell);

     

    // This function initialize all the resources (Arrays, Channels) to decode all the downlink channels (PCFICH,

    // PHICH, PDCCH, PDSCH). A lot of initialization routine for ofdm, channel estimation, and other physical channels

    // ( (PCFICH, PHICH, PDCCH, PDSCH) are called within this function

    srslte_ue_dl_init(&ue_dl, cell);

     

    // Configure downlink receiver for the RNTI specied by the option flag

    srslte_ue_dl_set_rnti(&ue_dl, prog_args.rnti);

     

    // Set initial CFO for ue_sync

    srslte_ue_sync_set_cfo(&ue_sync, cfo);

     

    // Decode channels for each subframe.

    while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {

        

        // Check if Sync signal is detected. It return 1 when sync detected, otherwise it return 0.

        ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer);

     

        /* srslte_ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */

        // if Sync is not detected (i.e, ret == 0) this part (Channel Decode) is skipped and go to next loop

        // try srslte_ue_sync_get_buffer() again.

        if (ret == 1) {

          switch (state) {

            case DECODE_MIB:

              if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) {

                srslte_pbch_decode_reset(&ue_mib.pbch);

     

                //Detect PBCH and decode MIB

                n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset)  

                  

                   // When PBCH is decoded, set state = DECODE_PDSCH, so that the routine decode PDSCH in next loop

                state = DECODE_PDSCH;   

              }

              break;

            case DECODE_PDSCH:

              if (decode_pdsch) {            

                INFO("Attempting DL decode SFN=%d\n", sfn);

                if (prog_args.rnti != SRSLTE_SIRNTI) {   

                  // if rnti option flag is not SI RNTI, perform regular dl decoding           

                  n = srslte_ue_dl_decode(&ue_dl,

                                                   &sf_buffer[prog_args.time_offset],

                                                   data, srslte_ue_sync_get_sfidx(&ue_sync));

                } else {

                  // if rnti option flag is set to be SI RNTI, perform regular dl decoding with the calculated rv

                  // RV for SIB1 is predefined

                  uint32_t k  = (sfn/2)%4;

                  uint32_t rv = ((uint32_t) ceilf((float)1.5*k))%4;

                  

                  n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data,

                                                  srslte_ue_sync_get_sfidx(&ue_sync),

                                                  SRSLTE_SIRNTI, rv);      

                }

                                        

                nof_trials++;

                

                rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.1);

                rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&ue_dl.chest), rsrp, 0.05);      

                noise = SRSLTE_VEC_EMA(srslte_chest_dl_get_noise_estimate(&ue_dl.chest), noise, 0.05);      

                nframes++;

              }

     

              break;

          }

          if (srslte_ue_sync_get_sfidx(&ue_sync) == 9) {

            // if subframe index == 9, increment SFN number by 1

            sfn++;

            if (sfn == 1024) {

              // if SFN == 1024, initialize SFN = 0

              sfn = 0;

              printf("\n");

              ue_dl.pkt_errors = 0;

              ue_dl.pkts_total = 0;

              ue_dl.nof_detected = 0;           

              nof_trials = 0;

            }

          }

          

     

        } else if (ret == 0) { // if Sync is not detected, do following

          printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r",

            srslte_sync_get_peak_value(&ue_sync.sfind),

            ue_sync.frame_total_cnt, ue_sync.state);      

        }

            

        sf_cnt++;                  

      } // end of while()

     

}

 

Result :-------------------------------------------------------------------------------------

 

Once you have built the code successful, you can run this code as shown in the following example. (If you are not familiar with how to build install srsLTE project and build it, refer to How to build srsLTE page).

 

Note 1: "pdsch.out" is the file that contains the I/Q data of LTE eNB downlink frame (I created this file using pdsch_enodeb example program.).

Note 2: Keep in mind that you have to specify C_RNTI using -r option as shown below. You have to use the RNTI value 1234 since it is hard coded in the example.

 

# ~/srsLTE/build/srslte/examples$ ./pdsch_ue -i "pdsch.out" -n 10 -r 1234

 

linux; GNU C++ version 5.3.1 20160413; Boost_105800; UHD_003.009.004-release

 

 - Cell ID:         0

 - Nof ports:       1

 - CP:              Normal  

 - PRB:             25

 - PHICH Length:    Normal

 - PHICH Resources: 1

 - SFN:             0

Decoded MIB. SFN: 0, offset: 0

CFO:  +0.00 kHz, SNR: 139.3 dB, PDCCH-Miss: 20.00%, PDSCH-BLER:  0.00%

Bye

 

This is it.  Now have fun !

 

If you want to get more detailed information about generation and decoding process, you can use -v option as follows.

 

#~/srsLTE/build/srslte/examples$ ./pdsch_enodeb -o "pdsch.out" -n 10 -m 9 -v

 

linux; GNU C++ version 5.3.1 20160413; Boost_105800; UHD_003.009.004-release

 

[INFO]:  Indexing 200 REGs. CellId: 0, 25 PRB, CP: Normal

[INFO]:  PCFICH allocating 4 regs. CellID: 0, PRB: 25

[INFO]:  Creating 4 PHICH mapping units. Normal length, Ng=1.00

[INFO]:  Init PDCCH REG space CFI 1. 27 useful REGs (3 CCEs)

[INFO]:  Init PDCCH REG space CFI 2. 108 useful REGs (12 CCEs)

[INFO]:  Init PDCCH REG space CFI 3. 180 useful REGs (20 CCEs)

[INFO]:  Init PDCCH: Max bits: 1440, 1 ports.

[INFO]:  Init PDSCH: 1 ports 25 PRBs, max_symbols: 4200

 - Resource Allocation Type:        Type 0

   + Resource Block Group Size:     2

   + RBG Bitmap:            0x1fff

 - Modulation and coding scheme index:  9

 - HARQ process:            0

 - New data indicator:          No

 - Redundancy version:          0

 - TPC command for PUCCH:       --

 - PRB Bitmap Assignment 0st slot:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

 - PRB Bitmap Assignment 1st slot:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

 - Number of PRBs:          25

 - Modulation type:         QPSK

 - Transport block size:        4008

Type new MCS index and press Enter: [INFO]:  SF: 0, Generating 0 random bits

[INFO]:  SF: 1, Generating 0 random bits

[INFO]:  Putting DCI to location: n=8, L=3

[INFO]:  CB Segmentation: TBS: 4008, C=1, C+=1 K+=4032, C-=0, K-=0, F=0, Bp=4032

[INFO]:  Encoding PDSCH SF: 1, Mod QPSK, NofBits: 4008, NofSymbols: 3150, NofBitsE: 6300, rv_idx: 0

[INFO]:  CB#0: cb_len: 4032, rlen: 4032, wp: 0, rp: 0, E: 6300

[INFO]:  Last CB, appending parity: 4008 from 0 and 24 to 4008

[INFO]:  END CB#1: wp: 6300, rp: 4032

[INFO]:  SF: 2, Generating 4008 random bits

....

 

 

In the same way, you can get more detailed information about the decoded result as shown below.

 

# ~/srsLTE/build/srslte/examples$ ./pdsch_ue -i "pdsch.out" -n 10 -r 1234 -v

 

linux; GNU C++ version 5.3.1 20160413; Boost_105800; UHD_003.009.004-release

 

[INFO]:  Offseting input file by 0 samples and 0.0 kHz

[INFO]:  Indexing 200 REGs. CellId: 0, 25 PRB, CP: Normal

[INFO]:  PCFICH allocating 4 regs. CellID: 0, PRB: 25

[INFO]:  Creating 4 PHICH mapping units. Normal length, Ng=1.00

[INFO]:  Init PDCCH REG space CFI 1. 27 useful REGs (3 CCEs)

[INFO]:  Init PDCCH REG space CFI 2. 108 useful REGs (12 CCEs)

[INFO]:  Init PDCCH REG space CFI 3. 180 useful REGs (20 CCEs)

[INFO]:  Init PDCCH: Max bits: 1440, 1 ports.

[INFO]:  Init PDSCH: 1 ports 25 PRBs, max_symbols: 4200

[INFO]:  

Entering main loop...

 

[INFO]:  Reading 5760 samples. sf_idx = 0

[INFO]:  Decoded PBCH: src=0, dst=0, nb=1, sfn_offset=0

[INFO]:  MIB decoded: 0

 - Cell ID:         0

 - Nof ports:       1

 - CP:              Normal  

 - PRB:             25

 - PHICH Length:    Normal

 - PHICH Resources: 1

 - SFN:             0

Decoded MIB. SFN: 0, offset: 0

[INFO]:  Reading 5760 samples. sf_idx = 1

[INFO]:  Attempting DL decode SFN=0

[INFO]:  Decoded CFI=3 with correlation 32.00, sf_idx=1

[INFO]:  Found DCI nCCE: 8, L: 3, n_bits=27

[INFO]:  Format1 PDSCH Scheduling

 - Resource Allocation Type:        Type 0

   + Resource Block Group Size:     2

   + RBG Bitmap:            0x1fff

 - Modulation and coding scheme index:  9

 - HARQ process:            0

 - New data indicator:          No

 - Redundancy version:          0

 - TPC command for PUCCH:       --

 - PRB Bitmap Assignment 0st slot:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

 - PRB Bitmap Assignment 1st slot:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

 - Number of PRBs:          25

 - Modulation type:         QPSK

 - Transport block size:        4008

[INFO]:  CB Segmentation: TBS: 4008, C=1, C+=1 K+=4032, C-=0, K-=0, F=0, Bp=4032

[INFO]:  Decoding PDSCH SF: 1, RNTI: 0x1234, Mod QPSK, TBS: 4008, NofSymbols: 3150, NofBitsE: 6300, rv_idx: 0, C_prb=25

[INFO]:  CB#0: cb_len: 4032, rlen: 4032, wp: 0, rp: 0, E: 6300, n_iters=1

[INFO]:  END CB#1: wp: 4032, rp: 6300

[INFO]:  

    CAUTION!! Received all-zero transport block

 

[INFO]:  TB decoded OK

[INFO]:  Reading 5760 samples. sf_idx = 2

[INFO]:  Attempting DL decode SFN=0

[INFO]:  Decoded CFI=3 with correlation 32.00, sf_idx=2

[INFO]:  Found DCI nCCE: 8, L: 3, n_bits=27

[INFO]:  Format1 PDSCH Scheduling

 - Resource Allocation Type:        Type 0

   + Resource Block Group Size:     2

   + RBG Bitmap:            0x1fff

 - Modulation and coding scheme index:  9

 - HARQ process:            0

 - New data indicator:          No

 - Redundancy version:          0

 - TPC command for PUCCH:       --

 - PRB Bitmap Assignment 0st slot:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

 - PRB Bitmap Assignment 1st slot:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

 - Number of PRBs:          25

 - Modulation type:         QPSK

 - Transport block size:        4008

[INFO]:  CB Segmentation: TBS: 4008, C=1, C+=1 K+=4032, C-=0, K-=0, F=0, Bp=4032

[INFO]:  Decoding PDSCH SF: 2, RNTI: 0x1234, Mod QPSK, TBS: 4008, NofSymbols: 3150, NofBitsE: 6300, rv_idx: 0, C_prb=25

[INFO]:  CB#0: cb_len: 4032, rlen: 4032, wp: 0, rp: 0, E: 6300, n_iters=1

[INFO]:  END CB#1: wp: 4032, rp: 6300

[INFO]:  TB decoded OK

[INFO]:  Reading 5760 samples. sf_idx = 3

[INFO]:  Attempting DL decode SFN=0

[INFO]:  Decoded CFI=3 with correlation 32.00, sf_idx=3

[INFO]:  Found DCI nCCE: 8, L: 3, n_bits=27

[INFO]:  Format1 PDSCH Scheduling

 - Resource Allocation Type:        Type 0

   + Resource Block Group Size:     2

   + RBG Bitmap:            0x1fff

 - Modulation and coding scheme index:  9

 - HARQ process:            0

 - New data indicator:          No

 - Redundancy version:          0

 - TPC command for PUCCH:       --

 - PRB Bitmap Assignment 0st slot:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

 - PRB Bitmap Assignment 1st slot:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

 - Number of PRBs:          25

 - Modulation type:         QPSK

 - Transport block size:        4008

 

....