コード例 #1
0
ファイル: pdsch.c プロジェクト: mfkiwl/srsLTE
static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg,
                                               srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data,
                                               uint32_t codeword_idx, uint32_t tb_idx, bool *ack) {
  srslte_ra_nbits_t *nbits = &cfg->nbits[tb_idx];
  srslte_ra_mcs_t *mcs = &cfg->grant.mcs[tb_idx];
  uint32_t rv = cfg->rv[tb_idx];
  int ret = SRSLTE_ERROR_INVALID_INPUTS;

  if (softbuffer && data && ack) {
    INFO("Decoding PDSCH SF: %d (CW%d -> TB%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
         cfg->sf_idx, codeword_idx, tb_idx, srslte_mod_string(mcs->mod), mcs->tbs,
         nbits->nof_re, nbits->nof_bits, rv);

    /* demodulate symbols
     * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
     * thus we don't need tot set it in the LLRs normalization
     */
    srslte_demod_soft_demodulate_s(mcs->mod, q->d[codeword_idx], q->e[codeword_idx], nbits->nof_re);

    /* Select scrambling sequence */
    srslte_sequence_t *seq = get_user_sequence(q, rnti, codeword_idx, cfg->sf_idx, nbits->nof_bits);

    /* Bit scrambling */
    srslte_scrambling_s_offset(seq, q->e[codeword_idx], 0, nbits->nof_bits);

    /* Return  */
    ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx);

    q->last_nof_iterations[codeword_idx] = srslte_sch_last_noi(&q->dl_sch);

    if (ret == SRSLTE_SUCCESS) {
      *ack = true;
    } else if (ret == SRSLTE_ERROR) {
      *ack = false;
      ret = SRSLTE_SUCCESS;
    } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) {
      *ack = false;
      ret = SRSLTE_ERROR;
    }
  } else {
    ERROR("Detected NULL pointer in TB%d &softbuffer=%p &data=%p &ack=%p", codeword_idx, softbuffer, (void*)data, ack);
  }

  return ret;
}
コード例 #2
0
ファイル: pdsch.c プロジェクト: mfkiwl/srsLTE
static int srslte_pdsch_codeword_encode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg,
                                               srslte_softbuffer_tx_t *softbuffer, uint16_t rnti, uint8_t *data,
                                               uint32_t codeword_idx, uint32_t tb_idx) {
  srslte_ra_nbits_t *nbits = &cfg->nbits[tb_idx];
  srslte_ra_mcs_t *mcs = &cfg->grant.mcs[tb_idx];
  uint32_t rv = cfg->rv[tb_idx];
  bool valid_inputs = true;

  if (!softbuffer) {
    ERROR("Error encoding (TB%d -> CW%d), softbuffer=NULL", tb_idx, codeword_idx);
    valid_inputs = false;
  }

  if (nbits->nof_bits && valid_inputs) {
    INFO("Encoding PDSCH SF: %d (TB%d -> CW%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
         cfg->sf_idx, tb_idx, codeword_idx, srslte_mod_string(mcs->mod), mcs->tbs,
         nbits->nof_re, nbits->nof_bits, rv);

    /* Channel coding */
    if (srslte_dlsch_encode2(&q->dl_sch, cfg, softbuffer, data, q->e[codeword_idx], tb_idx)) {
      ERROR("Error encoding (TB%d -> CW%d)", tb_idx, codeword_idx);
      return SRSLTE_ERROR;
    }

    /* Select scrambling sequence */
    srslte_sequence_t *seq = get_user_sequence(q, rnti, codeword_idx, cfg->sf_idx, nbits->nof_bits);

    /* Bit scrambling */
    srslte_scrambling_bytes(seq, (uint8_t *) q->e[codeword_idx], nbits->nof_bits);

    /* Bit mapping */
    srslte_mod_modulate_bytes(&q->mod[mcs->mod],
                              (uint8_t *) q->e[codeword_idx],
                              q->d[codeword_idx], nbits->nof_bits);

  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  return SRSLTE_SUCCESS;
}
コード例 #3
0
ファイル: pmch.c プロジェクト: mdasari823/srsLTE
int srslte_pmch_encode(srslte_pmch_t *q,
                       srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer,
                       uint8_t *data, uint16_t area_id, cf_t *sf_symbols[SRSLTE_MAX_PORTS])
{
  
  int i;
  /* Set pointers for layermapping & precoding */
  cf_t *x[SRSLTE_MAX_LAYERS];
  int ret = SRSLTE_ERROR_INVALID_INPUTS; 
   
  if (q != NULL && cfg != NULL)
  {
    for (i=0;i<q->cell.nof_ports;i++) {
      if (sf_symbols[i] == NULL) {
        return SRSLTE_ERROR_INVALID_INPUTS;
      }
    }
    
    if (cfg->grant.mcs[0].tbs == 0) {
      return SRSLTE_ERROR_INVALID_INPUTS;      
    }
    
    if (cfg->nbits[0].nof_re > q->max_re) {
      fprintf(stderr,
          "Error too many RE per subframe (%d). PMCH configured for %d RE (%d PRB)\n",
          cfg->nbits[0].nof_re, q->max_re, q->cell.nof_prb);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }

    INFO("Encoding PMCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
        cfg->sf_idx, srslte_mod_string(cfg->grant.mcs[0].mod), cfg->grant.mcs[0].tbs, 
         cfg->nbits[0].nof_re, cfg->nbits[0].nof_bits, 0);

    /* number of layers equals number of ports */
    for (i = 0; i < q->cell.nof_ports; i++) {
      x[i] = q->x[i];
    }
    memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));

    // TODO: use tb_encode directly
    if (srslte_dlsch_encode(&q->dl_sch, cfg, softbuffer, data, q->e)) {
      fprintf(stderr, "Error encoding TB\n");
      return SRSLTE_ERROR;
    }

    /* scramble */
    srslte_scrambling_bytes(&q->seqs[area_id]->seq[cfg->sf_idx], (uint8_t*) q->e, cfg->nbits[0].nof_bits);

    srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs[0].mod], (uint8_t*) q->e, q->d, cfg->nbits[0].nof_bits);
    
    /* No tx diversity in MBSFN */
    memcpy(q->symbols[0], q->d, cfg->nbits[0].nof_re * sizeof(cf_t));

    /* mapping to resource elements */
    for (i = 0; i < q->cell.nof_ports; i++) {
      srslte_pmch_put(q, q->symbols[i], sf_symbols[i], cfg->nbits[0].lstart);
    }
    
    ret = SRSLTE_SUCCESS;
  } 
  return ret; 
}
コード例 #4
0
ファイル: pmch.c プロジェクト: mdasari823/srsLTE
/** Decodes the pmch from the received symbols
 */
int srslte_pmch_decode_multi(srslte_pmch_t *q,
                             srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
                             cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate,
                             uint16_t area_id, uint8_t *data)
{

  /* Set pointers for layermapping & precoding */
  uint32_t i, n;
  cf_t *x[SRSLTE_MAX_LAYERS];
  
  if (q            != NULL &&
      sf_symbols   != NULL &&
      data         != NULL && 
      cfg          != NULL)
  {
    
    INFO("Decoding PMCH SF: %d, MBSFN area ID: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d, C_prb=%d, cfi=%d\n",
        cfg->sf_idx, area_id, srslte_mod_string(cfg->grant.mcs[0].mod), cfg->grant.mcs[0].tbs, cfg->nbits[0].nof_re,
         cfg->nbits[0].nof_bits, 0, cfg->grant.nof_prb, cfg->nbits[0].lstart-1);

    /* number of layers equals number of ports */
    for (i = 0; i < q->cell.nof_ports; i++) {
      x[i] = q->x[i];
    }
    memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));
     
    for (int j=0;j<q->nof_rx_antennas;j++) {
      /* extract symbols */
      n = srslte_pmch_get(q, sf_symbols[j], q->symbols[j], cfg->nbits[0].lstart);
      if (n != cfg->nbits[0].nof_re) {
        fprintf(stderr, "PMCH 1 extract symbols error expecting %d symbols but got %d, lstart %d\n", cfg->nbits[0].nof_re, n, cfg->nbits[0].lstart);
        return SRSLTE_ERROR;
      }
      
      /* extract channel estimates */
      for (i = 0; i < q->cell.nof_ports; i++) {
        n = srslte_pmch_get(q, ce[i][j], q->ce[i][j], cfg->nbits[0].lstart);
        if (n != cfg->nbits[0].nof_re) {
          fprintf(stderr, "PMCH 2 extract chest error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n);
          return SRSLTE_ERROR;
        }
      }      
    }
     
    // No tx diversity in MBSFN
    srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, NULL, q->nof_rx_antennas, cfg->nbits[0].nof_re, 1.0f, noise_estimate);
    
    if (SRSLTE_VERBOSE_ISDEBUG()) {
      DEBUG("SAVED FILE subframe.dat: received subframe symbols\n");
      srslte_vec_save_file("subframe.dat", sf_symbols, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t));
      DEBUG("SAVED FILE hest0.dat: channel estimates for port 4\n");
      srslte_vec_save_file("hest0.dat", ce[0], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t));
      DEBUG("SAVED FILE pmch_symbols.dat: symbols after equalization\n");
      srslte_vec_save_file("pmch_symbols.bin", q->d, cfg->nbits[0].nof_re*sizeof(cf_t));
    }
    
    /* demodulate symbols 
    * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, 
    * thus we don't need tot set it in thde LLRs normalization
    */
    srslte_demod_soft_demodulate_s(cfg->grant.mcs[0].mod, q->d, q->e, cfg->nbits[0].nof_re);
    
    /* descramble */
    srslte_scrambling_s_offset(&q->seqs[area_id]->seq[cfg->sf_idx], q->e, 0, cfg->nbits[0].nof_bits);
  
    if (SRSLTE_VERBOSE_ISDEBUG()) {
      DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n");
      srslte_vec_save_file("llr.dat", q->e, cfg->nbits[0].nof_bits*sizeof(int16_t));
    }
    return srslte_dlsch_decode(&q->dl_sch, cfg, softbuffer, q->e, data);
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
コード例 #5
0
ファイル: pdsch.c プロジェクト: sdnnfv/srsLTE
/** Converts the PDSCH data bits to symbols mapped to the slot ready for transmission
 */
int srslte_pdsch_encode_rnti(srslte_pdsch_t *q,
                             srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer,
                             uint8_t *data, uint16_t rnti, cf_t *sf_symbols[SRSLTE_MAX_PORTS])
{
    int i;
    /* Set pointers for layermapping & precoding */
    cf_t *x[SRSLTE_MAX_LAYERS];
    int ret = SRSLTE_ERROR_INVALID_INPUTS;

    if (q             != NULL &&
            data          != NULL &&
            cfg  != NULL)
    {

        for (i=0; i<q->cell.nof_ports; i++) {
            if (sf_symbols[i] == NULL) {
                return SRSLTE_ERROR_INVALID_INPUTS;
            }
        }

        if (cfg->grant.mcs.tbs == 0) {
            return SRSLTE_ERROR_INVALID_INPUTS;
        }

        if (cfg->nbits.nof_re > q->max_re) {
            fprintf(stderr,
                    "Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n",
                    cfg->nbits.nof_re, q->max_re, q->cell.nof_prb);
            return SRSLTE_ERROR_INVALID_INPUTS;
        }

        INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
             cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs,
             cfg->nbits.nof_re, cfg->nbits.nof_bits, cfg->rv);

        /* number of layers equals number of ports */
        for (i = 0; i < q->cell.nof_ports; i++) {
            x[i] = q->x[i];
        }
        memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));

        if (srslte_dlsch_encode(&q->dl_sch, cfg, softbuffer, data, q->e)) {
            fprintf(stderr, "Error encoding TB\n");
            return SRSLTE_ERROR;
        }

        if (rnti != q->rnti) {
            srslte_sequence_t seq;
            if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
                return SRSLTE_ERROR;
            }
            srslte_scrambling_bytes_offset(&seq, (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
            srslte_sequence_free(&seq);
        } else {
            srslte_scrambling_bytes_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->e, 0, cfg->nbits.nof_bits);
        }

        srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e, q->d, cfg->nbits.nof_bits);

        /* TODO: only diversity supported */
        if (q->cell.nof_ports > 1) {
            srslte_layermap_diversity(q->d, x, q->cell.nof_ports, cfg->nbits.nof_re);
            srslte_precoding_diversity(&q->precoding, x, q->symbols, q->cell.nof_ports,
                                       cfg->nbits.nof_re / q->cell.nof_ports);
        } else {
            memcpy(q->symbols[0], q->d, cfg->nbits.nof_re * sizeof(cf_t));
        }

        /* mapping to resource elements */
        for (i = 0; i < q->cell.nof_ports; i++) {
            srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
        }
        ret = SRSLTE_SUCCESS;
    }
    return ret;
}
コード例 #6
0
ファイル: pdsch.c プロジェクト: sdnnfv/srsLTE
/** Decodes the PDSCH from the received symbols
 */
int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
                             srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
                             cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate,
                             uint16_t rnti, uint8_t *data)
{

    /* Set pointers for layermapping & precoding */
    uint32_t i, n;
    cf_t *x[SRSLTE_MAX_LAYERS];

    if (q            != NULL &&
            sf_symbols   != NULL &&
            data         != NULL &&
            cfg          != NULL)
    {

        INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d, C_prb=%d\n",
             cfg->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->nbits.nof_re,
             cfg->nbits.nof_bits, cfg->rv, cfg->grant.nof_prb);

        /* number of layers equals number of ports */
        for (i = 0; i < q->cell.nof_ports; i++) {
            x[i] = q->x[i];
        }
        memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));

        /* extract symbols */
        n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
        if (n != cfg->nbits.nof_re) {
            fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
            return SRSLTE_ERROR;
        }

        /* extract channel estimates */
        for (i = 0; i < q->cell.nof_ports; i++) {
            n = srslte_pdsch_get(q, ce[i], q->ce[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
            if (n != cfg->nbits.nof_re) {
                fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
                return SRSLTE_ERROR;
            }
        }

        /* TODO: only diversity is supported */
        if (q->cell.nof_ports == 1) {
            /* no need for layer demapping */
            srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, cfg->nbits.nof_re, noise_estimate);
        } else {
            srslte_predecoding_diversity(&q->precoding, q->symbols[0], q->ce, x, q->cell.nof_ports,
                                         cfg->nbits.nof_re, noise_estimate);
            srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports,
                                        cfg->nbits.nof_re / q->cell.nof_ports);
        }

        if (SRSLTE_VERBOSE_ISDEBUG()) {
            DEBUG("SAVED FILE pdsch_symbols.dat: symbols after equalization\n",0);
            srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits.nof_re*sizeof(cf_t));
        }

        /* demodulate symbols
        * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
        * thus we don't need tot set it in the LLRs normalization
        */
        srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->e, cfg->nbits.nof_re);

        /* descramble */
        if (rnti != q->rnti) {
            srslte_sequence_t seq;
            if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
                return SRSLTE_ERROR;
            }
            srslte_scrambling_s_offset(&seq, q->e, 0, cfg->nbits.nof_bits);
            srslte_sequence_free(&seq);
        } else {
            srslte_scrambling_s_offset(&q->seq[cfg->sf_idx], q->e, 0, cfg->nbits.nof_bits);
        }

        if (SRSLTE_VERBOSE_ISDEBUG()) {
            DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n",0);
            srslte_vec_save_file("llr.dat", q->e, cfg->nbits.nof_bits*sizeof(int16_t));
        }

        return srslte_dlsch_decode(&q->dl_sch, cfg, softbuffer, q->e, data);

    } else {
        return SRSLTE_ERROR_INVALID_INPUTS;
    }
}
コード例 #7
0
ファイル: pmch_test.c プロジェクト: mfkiwl/srsLTE
int main(int argc, char **argv) {
  uint32_t i, j, k;
  int ret = -1;
  struct timeval t[3];
  srslte_softbuffer_tx_t *softbuffers_tx[SRSLTE_MAX_CODEWORDS];
  int M=1;
  
  parse_args(argc,argv);
  /* Initialise to zeros */
  bzero(&pmch_tx, sizeof(srslte_pmch_t));
  bzero(&pmch_rx, sizeof(srslte_pmch_t));
  bzero(&pmch_cfg, sizeof(srslte_pdsch_cfg_t));
  bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
  bzero(tx_slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
  bzero(rx_slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS);

  cell.nof_ports = 1;

  srslte_ra_dl_dci_t dci;
  bzero(&dci, sizeof(srslte_ra_dl_dci_t));
  dci.type0_alloc.rbg_bitmask = 0xffffffff;
  

  /* If transport block 0 is enabled */
    grant.tb_en[0] = true;
    grant.tb_en[1] = false;
    grant.mcs[0].idx = mcs_idx;

    grant.nof_prb = cell.nof_prb;
    grant.sf_type = SRSLTE_SF_MBSFN;

    srslte_dl_fill_ra_mcs(&grant.mcs[0], cell.nof_prb);
    grant.Qm[0] = srslte_mod_bits_x_symbol(grant.mcs[0].mod);
    for(int i = 0; i < 2; i++){
      for(int j = 0; j < grant.nof_prb; j++){
        grant.prb_idx[i][j] = true;
      }
    }

  /* init memory */
  for (i=0;i<SRSLTE_MAX_PORTS;i++) {
    for (j = 0; j < SRSLTE_MAX_PORTS; j++) {
      ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * NOF_CE_SYMBOLS);
      if (!ce[i][j]) {
        perror("srslte_vec_malloc");
        goto quit;
      }
      for (k = 0; k < NOF_CE_SYMBOLS; k++) {
        ce[i][j][k] = (i == j) ? 1.0f : 0.0f;
      }
    }
    rx_slot_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp));
    if (!rx_slot_symbols[i]) {
      perror("srslte_vec_malloc");
      goto quit;
    }
  }

  for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
    softbuffers_tx[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1);
    if (!softbuffers_tx[i]) {
      fprintf(stderr, "Error allocating TX soft buffer\n");
    }

    if (srslte_softbuffer_tx_init(softbuffers_tx[i], cell.nof_prb)) {
      fprintf(stderr, "Error initiating TX soft buffer\n");
      goto quit;
    }
  }

  for (i = 0; i < cell.nof_ports; i++) {
    tx_slot_symbols[i] = calloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), sizeof(cf_t));
    if (!tx_slot_symbols[i]) {
      perror("srslte_vec_malloc");
      goto quit;
    }
  }

  for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
    if (grant.tb_en[i]) {
      data_tx[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs);
      if (!data_tx[i]) {
        perror("srslte_vec_malloc");
        goto quit;
      }
      bzero(data_tx[i], sizeof(uint8_t) * grant.mcs[i].tbs);

      data_rx[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs);
      if (!data_rx[i]) {
        perror("srslte_vec_malloc");
        goto quit;
      }
      bzero(data_rx[i], sizeof(uint8_t) * grant.mcs[i].tbs);

    }
  }



  for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
    softbuffers_rx[i] = calloc(sizeof(srslte_softbuffer_rx_t), 1);
    if (!softbuffers_rx[i]) {
      fprintf(stderr, "Error allocating RX soft buffer\n");
      goto quit;
    }

    if (srslte_softbuffer_rx_init(softbuffers_rx[i], cell.nof_prb)) {
      fprintf(stderr, "Error initiating RX soft buffer\n");
      goto quit;
    }
  }

#ifdef DO_OFDM

  for (i = 0; i < cell.nof_ports; i++) {
    tx_sf_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));

    if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn[i], SRSLTE_CP_EXT, tx_slot_symbols[i], tx_sf_symbols[i], cell.nof_prb)) {
      fprintf(stderr, "Error creating iFFT object\n");
      exit(-1);
    }

    srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn[i], non_mbsfn_region);
    srslte_ofdm_set_normalize(&ifft_mbsfn[i], true);
  }

  for (i = 0; i < nof_rx_antennas; i++) {
    rx_sf_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));

    if (srslte_ofdm_rx_init_mbsfn(&fft_mbsfn[i], SRSLTE_CP_EXT, rx_sf_symbols[i], rx_slot_symbols[i], cell.nof_prb)) {
      fprintf(stderr, "Error creating iFFT object\n");
      exit(-1);
    }

    srslte_ofdm_set_non_mbsfn_region(&fft_mbsfn[i], non_mbsfn_region);
    srslte_ofdm_set_normalize(&fft_mbsfn[i], true);
  }




#endif /* DO_OFDM */

  /* Configure PDSCH */
  
  if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, subframe)) {
    fprintf(stderr, "Error configuring PMCH\n");
    exit(-1);
  }
  
  if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, subframe)) {
      fprintf(stderr, "Error configuring PMCH\n");
      exit(-1);
    }
    

  INFO(" Global:\n");
  INFO("         nof_prb=%d\n", cell.nof_prb);
  INFO("       nof_ports=%d\n", cell.nof_ports);
  INFO("              id=%d\n", cell.id);
  INFO("              cp=%s\n", srslte_cp_string(cell.cp));
  INFO("    phich_length=%d\n", (int) cell.phich_length);
  INFO(" phich_resources=%d\n", (int) cell.phich_resources);
  INFO("         nof_prb=%d\n", pmch_cfg.grant.nof_prb);
  INFO("          sf_idx=%d\n", pmch_cfg.sf_idx);
  INFO("       mimo_type=%s\n", srslte_mimotype2str(pmch_cfg.mimo_type));
  INFO("      nof_layers=%d\n", pmch_cfg.nof_layers);
  INFO("          nof_tb=%d\n", SRSLTE_RA_DL_GRANT_NOF_TB(&pmch_cfg.grant));  

  INFO("              Qm=%d\n", pmch_cfg.grant.Qm[0]);
  INFO("         mcs.idx=0x%X\n", pmch_cfg.grant.mcs[0].idx);
  INFO("         mcs.tbs=%d\n", pmch_cfg.grant.mcs[0].tbs);
  INFO("         mcs.mod=%s\n", srslte_mod_string(pmch_cfg.grant.mcs[0].mod));
  INFO("              rv=%d\n", pmch_cfg.rv[0]);
  INFO("          lstart=%d\n", pmch_cfg.nbits[0].lstart);
  INFO("        nof_bits=%d\n", pmch_cfg.nbits[0].nof_bits);
  INFO("          nof_re=%d\n", pmch_cfg.nbits[0].nof_re);
  INFO("        nof_symb=%d\n", pmch_cfg.nbits[0].nof_symb);



  if (srslte_pmch_init(&pmch_tx, cell.nof_prb)) {
    fprintf(stderr, "Error creating PMCH object\n");
  }
  srslte_pmch_set_area_id(&pmch_tx, mbsfn_area_id);

  if (srslte_pmch_init(&pmch_rx, cell.nof_prb)) {
    fprintf(stderr, "Error creating PMCH object\n");
  }
  srslte_pmch_set_area_id(&pmch_rx, mbsfn_area_id);




  for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
    if (grant.tb_en[tb]) {
      for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) {
        data_tx[tb][byte] = (uint8_t) (rand() % 256);
      }
    }
  }

  if (srslte_pmch_encode(&pmch_tx, &pmch_cfg, softbuffers_tx[0], data_tx[0], mbsfn_area_id, tx_slot_symbols)) {
    fprintf(stderr, "Error encoding PDSCH\n");
    exit(-1);
  }
  gettimeofday(&t[2], NULL);
  get_time_interval(t);
  printf("ENCODED in %.2f (PHY bitrate=%.2f Mbps. Processing bitrate=%.2f Mbps)\n",
         (float) t[0].tv_usec/M, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)/1000.0f,
         (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)*M/t[0].tv_usec);

#ifdef DO_OFDM
  for (i = 0; i < cell.nof_ports; i++) {
    /* For each Tx antenna modulate OFDM */
    srslte_ofdm_tx_sf(&ifft_mbsfn[i]);
  }


  /* combine outputs */
  for (j = 0; j < nof_rx_antennas; j++) {
    for (k = 0; k < NOF_CE_SYMBOLS; k++) {
      rx_sf_symbols[j][k] = 0.0f;
      for (i = 0; i < cell.nof_ports; i++) {
        rx_sf_symbols[j][k] += tx_sf_symbols[i][k] * ce[i][j][k];
      }
    }
  }
    
  #else
    /* combine outputs */
    for (j = 0; j < nof_rx_antennas; j++) {
      for (k = 0; k < SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); k++) {
        rx_slot_symbols[j][k] = 0.0f;
        for (i = 0; i < cell.nof_ports; i++) {
          rx_slot_symbols[j][k] += tx_slot_symbols[i][k] * ce[i][j][k];
        }
      }
    }
  #endif


  
  int r=0;
  gettimeofday(&t[1], NULL);

#ifdef DO_OFDM
    /* For each Rx antenna demodulate OFDM */
    for (i = 0; i < nof_rx_antennas; i++) {
      srslte_ofdm_rx_sf(&fft_mbsfn[i]);
    }
#endif
  for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
    if (grant.tb_en[i]) {
      srslte_softbuffer_rx_reset_tbs(softbuffers_rx[i], (uint32_t) grant.mcs[i].tbs);
    }
  }

  r = srslte_pmch_decode(&pmch_rx, &pmch_cfg, softbuffers_rx[0],rx_slot_symbols[0], ce[0],0,mbsfn_area_id, data_rx[0]);
  gettimeofday(&t[2], NULL);
  get_time_interval(t);
  printf("DECODED %s in %.2f (PHY bitrate=%.2f Mbps. Processing bitrate=%.2f Mbps)\n", r?"Error":"OK",
         (float) t[0].tv_usec/M, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)/1000.0f,
         (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)*M/t[0].tv_usec);

  /* If there is an error in PDSCH decode */
  if (r) {
    ret = -1;
    goto quit;
  }

  /* Check Tx and Rx bytes */
  for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
    if (grant.tb_en[tb]) {
      for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) {
        if (data_tx[tb][byte] != data_rx[tb][byte]) {
          ERROR("Found BYTE error in TB %d (%02X != %02X), quiting...", tb, data_tx[tb][byte], data_rx[tb][byte]);
          ret = SRSLTE_ERROR;
          goto quit;
        }
      }
    }
  }

  ret = SRSLTE_SUCCESS;

quit:
  srslte_pmch_free(&pmch_tx);
  srslte_pmch_free(&pmch_rx);
  for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
    srslte_softbuffer_tx_free(softbuffers_tx[i]);
    if (softbuffers_tx[i]) {
      free(softbuffers_tx[i]);
    }

    srslte_softbuffer_rx_free(softbuffers_rx[i]);
    if (softbuffers_rx[i]) {
      free(softbuffers_rx[i]);
    }

    if (data_tx[i]) {
      free(data_tx[i]);
    }

    if (data_rx[i]) {
      free(data_rx[i]);
    }
  }

  for (i=0;i<SRSLTE_MAX_PORTS;i++) {
    for (j = 0; j < SRSLTE_MAX_PORTS; j++) {
      if (ce[i][j]) {
        free(ce[i][j]);
      }
    }
    if (tx_slot_symbols[i]) {
      free(tx_slot_symbols[i]);
    }
    if (rx_slot_symbols[i]) {
      free(rx_slot_symbols[i]);
    }
  }
  if (ret) {
    printf("Error\n");
  } else {
    printf("Ok\n");
  }
  exit(ret);
}
コード例 #8
0
ファイル: pdsch.c プロジェクト: mfkiwl/srsLTE
/** Decodes the PDSCH from the received symbols
 */
int srslte_pdsch_decode(srslte_pdsch_t *q,
                        srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS],
                        cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
                        float noise_estimate, uint16_t rnti, uint8_t *data[SRSLTE_MAX_CODEWORDS],
                        bool acks[SRSLTE_MAX_CODEWORDS])
{

  /* Set pointers for layermapping & precoding */
  uint32_t i;
  cf_t *x[SRSLTE_MAX_LAYERS];

  if (q            != NULL &&
      sf_symbols   != NULL &&
      data         != NULL &&
      cfg          != NULL)
  {
    uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant);

    INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d, mimo_type=%s, nof_layers=%d, nof_tb=%d\n",
        cfg->sf_idx, rnti, cfg->nbits[0].nof_re, cfg->grant.nof_prb, srslte_mod_string(cfg->grant.mcs->mod), cfg->nof_layers, nof_tb);

    // Extract Symbols and Channel Estimates
    for (int j=0;j<q->nof_rx_antennas;j++) {
      int n = srslte_pdsch_get(q, sf_symbols[j], q->symbols[j], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx);
      if (n != cfg->nbits[0].nof_re) {
        fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n);
        return SRSLTE_ERROR;
      }

      for (i = 0; i < q->cell.nof_ports; i++) {
        n = srslte_pdsch_get(q, ce[i][j], q->ce[i][j], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx);
        if (n != cfg->nbits[0].nof_re) {
          fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n);
          return SRSLTE_ERROR;
        }
      }
    }

    // Prepare layers
    int nof_symbols [SRSLTE_MAX_CODEWORDS];
    nof_symbols[0] = cfg->nbits[0].nof_re * nof_tb / cfg->nof_layers;
    nof_symbols[1] = cfg->nbits[1].nof_re * nof_tb / cfg->nof_layers;

    if (cfg->nof_layers == nof_tb) {
      /* Skip layer demap */
      for (i = 0; i < cfg->nof_layers; i++) {
        x[i] = q->d[i];
      }
    } else {
      /* number of layers equals number of ports */
      for (i = 0; i < cfg->nof_layers; i++) {
        x[i] = q->x[i];
      }
      memset(&x[cfg->nof_layers], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - cfg->nof_layers));
    }

    float pdsch_scaling = 1.0f;
    if (q->rho_a != 0.0f) {
      pdsch_scaling = q->rho_a;
    }

    // Pre-decoder
    if (srslte_predecoding_type(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers,
                                      cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, pdsch_scaling, noise_estimate)<0) {
      DEBUG("Error predecoding\n");
      return SRSLTE_ERROR;
    }

    // Layer demapping only if necessary
    if (cfg->nof_layers != nof_tb) {
        srslte_layerdemap_type(x, q->d, cfg->nof_layers, nof_tb,
                             nof_symbols[0], nof_symbols, cfg->mimo_type);
    }

    /* Codeword decoding: Implementation of 3GPP 36.212 Table 5.3.3.1.5-1 and Table 5.3.3.1.5-2 */
    uint32_t cw_idx = (nof_tb == SRSLTE_MAX_TB && cfg->tb_cw_swap) ? 1 : 0;
    for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) {
      /* Decode only if transport block is enabled and the default ACK is not true */
      if (cfg->grant.tb_en[tb_idx]) {
        if (!acks[tb_idx]) {
          int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb_idx], rnti, data[tb_idx], cw_idx, tb_idx, &acks[tb_idx]);

          /* Check if there has been any execution error */
          if (ret) {
            return ret;
          }
        }

        cw_idx = (cw_idx + 1) % SRSLTE_MAX_CODEWORDS;
      }
    }

    pdsch_decode_debug(q, cfg, sf_symbols, ce);

    return SRSLTE_SUCCESS;
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
コード例 #9
0
ファイル: pdsch.c プロジェクト: mdasari823/srsLTE
static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg,
                                               srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data,
                                               uint32_t codeword_idx, uint32_t tb_idx, bool *ack) {
  srslte_ra_nbits_t *nbits = &cfg->nbits[tb_idx];
  srslte_ra_mcs_t *mcs = &cfg->grant.mcs[tb_idx];
  uint32_t rv = cfg->rv[tb_idx];
  int ret = SRSLTE_ERROR_INVALID_INPUTS;

  if (softbuffer && data && ack) {
    INFO("Decoding PDSCH SF: %d (CW%d -> TB%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
         cfg->sf_idx, codeword_idx, tb_idx, srslte_mod_string(mcs->mod), mcs->tbs,
         nbits->nof_re, nbits->nof_bits, rv);

    /* demodulate symbols
     * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
     * thus we don't need tot set it in the LLRs normalization
     */
    srslte_demod_soft_demodulate_s(mcs->mod, q->d[codeword_idx], q->e[codeword_idx], nbits->nof_re);

    /* Select scrambling sequence */
    srslte_sequence_t *seq = get_user_sequence(q, rnti, codeword_idx, cfg->sf_idx, nbits->nof_bits);

    /* Bit scrambling */
    srslte_scrambling_s_offset(seq, q->e[codeword_idx], 0, nbits->nof_bits);

    uint32_t qm = nbits->nof_bits/nbits->nof_re;
    switch(cfg->grant.mcs[tb_idx].mod) {

      case SRSLTE_MOD_BPSK:
        qm = 1;
        break;
      case SRSLTE_MOD_QPSK:
        qm = 2;
        break;
      case SRSLTE_MOD_16QAM:
        qm = 4;
        break;
      case SRSLTE_MOD_64QAM:
        qm = 6;
        break;
      default:
        ERROR("No modulation");
    }

    int16_t *e = q->e[codeword_idx];

    if (q->csi_enabled) {
      const uint32_t csi_max_idx = srslte_vec_max_fi(q->csi[codeword_idx], nbits->nof_bits / qm);
      float csi_max = 1.0f;
      if (csi_max_idx < nbits->nof_bits / qm) {
        csi_max = q->csi[codeword_idx][csi_max_idx];
      }
      for (int i = 0; i < nbits->nof_bits / qm; i++) {
        const float csi = q->csi[codeword_idx][i] / csi_max;
        for (int k = 0; k < qm; k++) {
          e[qm * i + k] = (int16_t) ((float) e[qm * i + k] * csi);
        }
      }
    }

    /* Return  */
    ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx);

    q->last_nof_iterations[codeword_idx] = srslte_sch_last_noi(&q->dl_sch);

    if (ret == SRSLTE_SUCCESS) {
      *ack = true;
    } else if (ret == SRSLTE_ERROR) {
      *ack = false;
      ret = SRSLTE_SUCCESS;
    } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) {
      *ack = false;
      ret = SRSLTE_ERROR;
    }
  } else {
    ERROR("Detected NULL pointer in TB%d &softbuffer=%p &data=%p &ack=%p", codeword_idx, softbuffer, (void*)data, ack);
  }

  return ret;
}