Example #1
0
int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) 
{
  srslte_dci_msg_t dci_msg;
  srslte_ra_dl_dci_t dci_unpacked;
  srslte_ra_dl_grant_t grant; 
  int ret = SRSLTE_ERROR; 
  
  if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &q->cfi)) < 0) {
    return ret; 
  }
  
  if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, 0, sf_idx, q->cfi)) {
    fprintf(stderr, "Error extracting LLRs\n");
    return SRSLTE_ERROR;
  }

  int found_dci = srslte_ue_dl_find_dl_dci(q, &dci_msg, q->cfi, sf_idx, rnti);   
  if (found_dci == 1) {
    
    if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, &dci_unpacked, &grant)) {
      fprintf(stderr, "Error unpacking DCI\n");
      return SRSLTE_ERROR;   
    }

    ret = srslte_ue_dl_decode_rnti_rv_packet(q, &grant, data, q->cfi, sf_idx, rnti, rvidx);    
  }
   
  if (found_dci == 1 && ret == SRSLTE_SUCCESS) { 
    return q->pdsch_cfg.grant.mcs.tbs;    
  } else {
    return 0;
  }
}
Example #2
0
int srslte_ue_dl_find_and_decode(srslte_ue_dl_t*     q,
                                 srslte_dl_sf_cfg_t* sf,
                                 srslte_ue_dl_cfg_t* cfg,
                                 srslte_pdsch_cfg_t* pdsch_cfg,
                                 uint8_t*            data[SRSLTE_MAX_CODEWORDS],
                                 bool                acks[SRSLTE_MAX_CODEWORDS])
{
  int ret = SRSLTE_ERROR;

  srslte_dci_dl_t    dci_dl;
  srslte_pmch_cfg_t  pmch_cfg;
  srslte_pdsch_res_t pdsch_res[SRSLTE_MAX_CODEWORDS];

  // Use default values for PDSCH decoder
  ZERO_OBJECT(pmch_cfg);

  uint32_t mi_set_len;
  if (q->cell.frame_type == SRSLTE_TDD && !sf->tdd_config.configured) {
    mi_set_len = 3;
  } else {
    mi_set_len = 1;
  }

  // Blind search PHICH mi value
  ZERO_OBJECT(dci_dl);
  ret = 0;
  for (uint32_t i = 0; i < mi_set_len && !ret; i++) {

    if (mi_set_len == 1) {
      srslte_ue_dl_set_mi_auto(q);
    } else {
      srslte_ue_dl_set_mi_manual(q, i);
    }

    if ((ret = srslte_ue_dl_decode_fft_estimate(q, sf, cfg)) < 0) {
      return ret;
    }

    ret = srslte_ue_dl_find_dl_dci(q, sf, cfg, pdsch_cfg->rnti, &dci_dl);
  }

  if (ret == 1) {
    // Logging
    char str[512];
    srslte_dci_dl_info(&dci_dl, str, 512);
    INFO("PDCCH: %s, snr=%.1f dB\n", str, q->chest_res.snr_db);

    // Force known MBSFN grant
    if (sf->sf_type == SRSLTE_SF_MBSFN) {
      dci_dl.rnti                    = SRSLTE_MRNTI;
      dci_dl.alloc_type              = SRSLTE_RA_ALLOC_TYPE0;
      dci_dl.type0_alloc.rbg_bitmask = 0xffffffff;
      dci_dl.tb[0].rv                = 0;
      dci_dl.tb[0].mcs_idx           = 2;
      dci_dl.format                  = SRSLTE_DCI_FORMAT1;
    }

    // Convert DCI message to DL grant
    if (srslte_ue_dl_dci_to_pdsch_grant(q, sf, cfg, &dci_dl, &pdsch_cfg->grant)) {
      ERROR("Error unpacking DCI\n");
      return SRSLTE_ERROR;
    }

    // Calculate RV if not provided in the grant and reset softbuffer
    for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
      if (pdsch_cfg->grant.tb[i].enabled) {
        if (pdsch_cfg->grant.tb[i].rv < 0) {
          uint32_t sfn              = sf->tti / 10;
          uint32_t k                = (sfn / 2) % 4;
          pdsch_cfg->grant.tb[i].rv = ((uint32_t)ceilf((float)1.5 * k)) % 4;
        }
        srslte_softbuffer_rx_reset_tbs(pdsch_cfg->softbuffers.rx[i], (uint32_t)pdsch_cfg->grant.tb[i].tbs);
      }
    }

    bool decode_enable = false;
    for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
      if (pdsch_cfg->grant.tb[tb].enabled) {
        decode_enable         = true;
        pdsch_res[tb].payload = data[tb];
        pdsch_res[tb].crc     = false;
      }
    }

    if (decode_enable) {
      if (sf->sf_type == SRSLTE_SF_NORM) {
        if (srslte_ue_dl_decode_pdsch(q, sf, pdsch_cfg, pdsch_res)) {
          ERROR("ERROR: Decoding PDSCH\n");
          ret = -1;
        }
      } else {
        pmch_cfg.pdsch_cfg = *pdsch_cfg;
        if (srslte_ue_dl_decode_pmch(q, sf, &pmch_cfg, pdsch_res)) {
          ERROR("Decoding PMCH\n");
          ret = -1;
        }
      }
    }

    for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
      if (pdsch_cfg->grant.tb[tb].enabled) {
        acks[tb] = pdsch_res[tb].crc;
      }
    }
  }
  return ret;
}
Example #3
0
int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q,
                             uint8_t *data[SRSLTE_MAX_CODEWORDS], uint32_t tm, uint32_t tti, uint16_t rnti,
                             bool acks[SRSLTE_MAX_CODEWORDS]) {
  srslte_mimo_type_t mimo_type;
  srslte_dci_msg_t dci_msg;
  srslte_ra_dl_dci_t dci_unpacked;
  srslte_ra_dl_grant_t grant; 
  int ret = SRSLTE_ERROR; 
  uint32_t cfi;
  uint32_t sf_idx = tti%10;
  
  if ((ret = srslte_ue_dl_decode_fft_estimate_mbsfn(q, sf_idx, &cfi, SRSLTE_SF_NORM)) < 0) {
    return ret; 
  }
  
  float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest);
  // Uncoment next line to do ZF by default in pdsch_ue example
  //float noise_estimate = 0; 

  if (srslte_pdcch_extract_llr_multi(&q->pdcch, q->sf_symbols_m, q->ce_m, noise_estimate, sf_idx, cfi)) {
    fprintf(stderr, "Error extracting LLRs\n");
    return SRSLTE_ERROR;
  }

  int found_dci = srslte_ue_dl_find_dl_dci(q, tm, cfi, sf_idx, rnti, &dci_msg);
  if (found_dci == 1) {
    
    if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, q->cell.nof_ports, &dci_unpacked, &grant)) {
      fprintf(stderr, "Error unpacking DCI\n");
      return SRSLTE_ERROR;   
    }
    
    /* ===== These lines of code are supposed to be MAC functionality === */


    int rvidx[SRSLTE_MAX_CODEWORDS] = {1};
    if (dci_unpacked.rv_idx < 0) {
      uint32_t sfn = tti / 10;
      uint32_t k = (sfn / 2) % 4;
      for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
        if (grant.tb_en[i]) {
          rvidx[i] = ((uint32_t) ceilf((float) 1.5 * k)) % 4;
          srslte_softbuffer_rx_reset_tbs(q->softbuffers[i], (uint32_t) grant.mcs[i].tbs);
        }
      }
    } else {
      for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
        if (grant.tb_en[i]) {
          switch (i) {
            case 0:
              rvidx[i] = (uint32_t) dci_unpacked.rv_idx;
              break;
            case 1:
              rvidx[i] = (uint32_t) dci_unpacked.rv_idx_1;
              break;
            default:
              ERROR("Wrong number of transport blocks");
              return SRSLTE_ERROR;
          }
          srslte_softbuffer_rx_reset_tbs(q->softbuffers[i], (uint32_t) grant.mcs[i].tbs);
        }
      }
    }

    switch(dci_msg.format) {
      case SRSLTE_DCI_FORMAT1:
      case SRSLTE_DCI_FORMAT1A:
      case SRSLTE_DCI_FORMAT1C:
        if (q->cell.nof_ports == 1) {
          mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
        } else {
          mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
        }
        break;
      case SRSLTE_DCI_FORMAT2:
        if (SRSLTE_RA_DL_GRANT_NOF_TB(&grant) == 1 && dci_unpacked.pinfo == 0) {
          mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
        } else {
          mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
        }
        break;
      case SRSLTE_DCI_FORMAT2A:
        if (SRSLTE_RA_DL_GRANT_NOF_TB(&grant) == 1 && dci_unpacked.pinfo == 0) {
          mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
        } else {
          mimo_type = SRSLTE_MIMO_TYPE_CDD;
        }
        break;

      /* Not implemented formats */
      case SRSLTE_DCI_FORMAT0:
      case SRSLTE_DCI_FORMAT1B:
      case SRSLTE_DCI_FORMAT1D:
      case SRSLTE_DCI_FORMAT2B:
      default:
        ERROR("Transmission mode not supported.");
        return SRSLTE_ERROR;
    }

    if (srslte_ue_dl_cfg_grant(q, &grant, cfi, sf_idx, rvidx, mimo_type)) {
      ERROR("Configuing PDSCH");
      return SRSLTE_ERROR; 
    }
    
    /* ===== End of MAC functionality ========== */

    q->nof_detected++;
  
    
    if (q->pdsch_cfg.grant.mcs[0].mod > 0 && q->pdsch_cfg.grant.mcs[0].tbs >= 0) {
      ret = srslte_pdsch_decode(&q->pdsch, &q->pdsch_cfg, q->softbuffers,
                                q->sf_symbols_m, q->ce_m,
                                noise_estimate,
                                rnti, data, acks);

      
      for (int tb = 0; tb < SRSLTE_MAX_TB; tb++) {
        if (grant.tb_en[tb]) {
          if (!acks[tb]) {
            q->pdsch_pkt_errors++;
          }
          q->pdsch_pkts_total++;
        }
      }

      if (ret == SRSLTE_ERROR) {
      } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) {
        fprintf(stderr, "Error calling srslte_pdsch_decode()\n");      
      }

      /* If we are in TM4 (Closed-Loop MIMO), compute condition number */

    }
  
  /*
    printf("Saving signal...\n");
    srslte_vec_save_file("input", input, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
    srslte_ue_dl_save_signal(q, &q->softbuffer, sf_idx, rvidx, rnti, cfi);
    //exit(-1);
  */
  
  }

  if (found_dci == 1 && ret == SRSLTE_SUCCESS) { 
    return q->pdsch_cfg.grant.mcs[0].tbs;
  } else {
    return 0;
  }
}