Beispiel #1
0
static int int_2_bits(uint32_t* src, uint8_t* dst, int nbits) {
  int n;
  n=nbits/32;
  for (int i=0;i<n;i++) {
    srslte_bit_unpack(src[i],&dst,32);
  }
  srslte_bit_unpack(src[n],&dst,nbits-n*32);
  return n;
}
Beispiel #2
0
/* Decode UCI CQI/PMI over PUCCH 
 */
int16_t srslte_uci_decode_cqi_pucch(srslte_uci_cqi_pucch_t* q,
                                    int16_t                 b_bits[SRSLTE_CQI_MAX_BITS],
                                    uint8_t*                cqi_data,
                                    uint32_t                cqi_len)
{
  if (cqi_len           < SRSLTE_UCI_MAX_CQI_LEN_PUCCH     &&
      b_bits            != NULL  &&
      cqi_data          != NULL) 
  {
    uint32_t max_w = 0;
    int32_t max_corr = INT32_MIN;
    uint32_t nwords      = 1 << SRSLTE_UCI_MAX_CQI_LEN_PUCCH;
    for (uint32_t w=0;w<nwords;w += 1<<(SRSLTE_UCI_MAX_CQI_LEN_PUCCH - cqi_len)) {
          
      // Calculate correlation with pregenerated word and select maximum
      int32_t corr = srslte_vec_dot_prod_sss(q->cqi_table_s[w], b_bits, SRSLTE_UCI_CQI_CODED_PUCCH_B);
      if (corr > max_corr) {
        max_corr = corr;
        max_w    = w;
      }
    }
    // Convert word to bits again
    uint8_t *ptr = cqi_data; 
    srslte_bit_unpack(max_w, &ptr, SRSLTE_UCI_MAX_CQI_LEN_PUCCH);
    
    INFO("Decoded CQI: w=%d, corr=%d\n", max_w, max_corr);
    return max_corr;
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
Beispiel #3
0
int srslte_mod_modulate(srslte_modem_table_t* q, uint8_t *bits, cf_t* symbols, uint32_t nbits) {
  uint32_t i,j,idx;
  uint8_t *b_ptr=(uint8_t*) bits;
  j=0;
  for (i=0;i<nbits;i+=q->nbits_x_symbol) {
    idx = srslte_bit_unpack(&b_ptr,q->nbits_x_symbol);
    if (idx < q->nsymbols) {
      symbols[j] = q->symbol_table[idx];      
    } else {
      return SRSLTE_ERROR;
    }
    j++;
  }
  return j;
}
Beispiel #4
0
void cqi_pusch_pregen(srslte_uci_cqi_pusch_t *q) {
  uint8_t word[11]; 
    
  for (int i=0;i<11;i++) {
    uint32_t nwords   = (1<<(i+1));
    q->cqi_table[i]   = srslte_vec_malloc(sizeof(uint8_t)*nwords*32);
    q->cqi_table_s[i] = srslte_vec_malloc(sizeof(int16_t) * nwords * 32);
    for (uint32_t w=0;w<nwords;w++) {
      uint8_t *ptr = word; 
      srslte_bit_unpack(w, &ptr, i+1);
      encode_cqi_pusch_block(word, i + 1, &q->cqi_table[i][32 * w]);
      for (int j=0;j<32;j++) {
        q->cqi_table_s[i][32*w+j] = 2*q->cqi_table[i][32*w+j]-1;
      }
    }
  }
}
Beispiel #5
0
void srslte_uci_cqi_pucch_init(srslte_uci_cqi_pucch_t *q) {
  uint8_t word[16];

  uint32_t nwords = 1 << SRSLTE_UCI_MAX_CQI_LEN_PUCCH;
  q->cqi_table = srslte_vec_malloc(nwords * sizeof(int8_t *));
  q->cqi_table_s = srslte_vec_malloc(nwords * sizeof(int16_t *));

  for (uint32_t w = 0; w < nwords; w++) {
    q->cqi_table[w] = srslte_vec_malloc(SRSLTE_UCI_CQI_CODED_PUCCH_B * sizeof(int8_t));
    q->cqi_table_s[w] = srslte_vec_malloc(SRSLTE_UCI_CQI_CODED_PUCCH_B * sizeof(int16_t));
    uint8_t *ptr = word;
    srslte_bit_unpack(w, &ptr, SRSLTE_UCI_MAX_CQI_LEN_PUCCH);
    srslte_uci_encode_cqi_pucch(word, SRSLTE_UCI_MAX_CQI_LEN_PUCCH, q->cqi_table[w]);
    for (int j = 0; j < SRSLTE_UCI_CQI_CODED_PUCCH_B; j++) {
      q->cqi_table_s[w][j] = (int16_t)(2 * q->cqi_table[w][j] - 1);
    }
  }
}
Beispiel #6
0
// For decoding the block-encoded CQI we use ML decoding
int decode_cqi_short(srslte_uci_cqi_pusch_t *q, int16_t *q_bits, uint32_t Q, uint8_t *data, uint32_t nof_bits)
{
  if (nof_bits          <= 11    &&
      nof_bits          > 0      && 
      q                 != NULL  &&
      data              != NULL  &&
      q_bits            != NULL) 
  {
    // Accumulate all copies of the 32-length sequence 
    if (Q>32) {
      int i=1; 
      for (;i<Q/32;i++) {
        srslte_vec_sum_sss(&q_bits[i*32], q_bits, q_bits, 32);
      }
      srslte_vec_sum_sss(&q_bits[i*32], q_bits, q_bits, Q%32);
    }
    
    uint32_t max_w = 0;
    int32_t max_corr = INT32_MIN;   
    for (uint32_t w=0;w<(1<<nof_bits);w++) {
          
      // Calculate correlation with pregenerated word and select maximum
      int32_t corr = srslte_vec_dot_prod_sss(&q->cqi_table_s[nof_bits-1][w*32], q_bits, SRSLTE_MIN(32, Q));
      if (corr > max_corr) {
        max_corr = corr; 
        max_w = w; 
      }
    }
    // Convert word to bits again
    uint8_t *ptr = data; 
    srslte_bit_unpack(max_w, &ptr, nof_bits);
    
    INFO("Decoded CQI: w=%d, corr=%d\n", max_w, max_corr);
    return SRSLTE_SUCCESS;
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }  
}
Beispiel #7
0
int main(int argc, char **argv) {
  srslte_dci_msg_t msg;
  srslte_ra_dl_dci_t ra_dl;
  int len, rlen;
  int nof_prb;
  int nwords;
  int i;
  uint8_t *y;

  if (argc < 3) {
    usage(argv[0]);
    exit(-1);
  }

  nof_prb = atoi(argv[1]);
  len = atoi(argv[2]);

  nwords = (len - 1) / 32 + 1;

  if (argc < 3 + nwords) {
    usage(argv[0]);
    exit(-1);
  }

  y = msg.data;
  rlen = 0;
  uint32_t x;
  for (i = 0; i < nwords; i++) {
    x = strtoul(argv[i + 3], NULL, 16);
    if (len - rlen < 32) {
      srslte_bit_unpack(x, &y, len - rlen);
    } else {
      srslte_bit_unpack(x, &y, 32);
    }

  }

  printf("DCI message len %d:\n", len);
  for (i = 0; i < len; i++) {
    printf("%d, ", msg.data[i]);
  }
  printf("\n");

  srslte_dci_msg_type_t dci_type;
  msg.nof_bits = len;
  if (srslte_dci_msg_get_type(&msg, &dci_type, nof_prb, SRSLTE_SIRNTI)) {
    fprintf(stderr, "Can't obtain DCI message type\n");
    exit(-1);
  }
  printf("\n");
  printf("Message type:");
  srslte_dci_msg_type_fprint(stdout, dci_type);
  switch (dci_type.type) {
  case SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED:
    bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t));
    srslte_dci_msg_unpack_pdsch(&msg, &ra_dl, nof_prb, false);
    srslte_ra_pdsch_fprint(stdout, &ra_dl, nof_prb);
    break;
  default:
    printf("Error expected PDSCH\n");
    exit(-1);
  }
  printf("\n");
}
Beispiel #8
0
/* Decode a transport block according to 36.212 5.3.2
 *
 */
static int decode_tb(srslte_sch_t *q, 
                     srslte_softbuffer_rx_t *softbuffer, srslte_cbsegm_t *cb_segm, 
                     uint32_t Qm, uint32_t rv, uint32_t nof_e_bits, 
                     float *e_bits, uint8_t *data) 
{
  uint8_t parity[24];
  uint8_t *p_parity = parity;
  uint32_t par_rx, par_tx;
  uint32_t i;
  uint32_t cb_len, rp, wp, rlen, F, n_e;
  
  if (q            != NULL && 
      data         != NULL &&       
      softbuffer   != NULL &&
      e_bits       != NULL &&
      cb_segm      != NULL)
  {

    if (cb_segm->tbs == 0 || cb_segm->C == 0) {
      return SRSLTE_SUCCESS;
    }
    
    rp = 0;
    rp = 0;
    wp = 0;
    uint32_t Gp = nof_e_bits / Qm;
    uint32_t gamma=Gp;

    if (cb_segm->C>0) {
      gamma = Gp%cb_segm->C;
    }
    
    bool early_stop = true;
    for (i = 0; i < cb_segm->C && early_stop; i++) {

      /* Get read/write lengths */
      if (i < cb_segm->C2) {
        cb_len = cb_segm->K2;
      } else {
        cb_len = cb_segm->K1;
      }
      if (cb_segm->C == 1) {
        rlen = cb_len;
      } else {
        rlen = cb_len - 24;
      }
      if (i == 0) {
        F = cb_segm->F;
      } else {
        F = 0;
      }

      if (i <= cb_segm->C - gamma - 1) {
        n_e = Qm * (Gp/cb_segm->C);
      } else {
        n_e = Qm * ((uint32_t) ceilf((float) Gp/cb_segm->C));
      }

      INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i,
          cb_len, rlen - F, wp, rp, F, n_e);
      
      /* Rate Unmatching */
      if (srslte_rm_turbo_rx(softbuffer->buffer_f[i], softbuffer->buff_size,  
                  &e_bits[rp], n_e, 
                  (float*) q->cb_out, 3 * cb_len + 12, rv, F)) {
        fprintf(stderr, "Error in rate matching\n");
        return SRSLTE_ERROR;
      }

      if (SRSLTE_VERBOSE_ISDEBUG()) {
        DEBUG("CB#%d RMOUT: ", i);
        srslte_vec_fprint_f(stdout, q->cb_out, 3*cb_len+12);
      }

      /* Turbo Decoding with CRC-based early stopping */
      q->nof_iterations = 0; 
      uint32_t len_crc; 
      uint8_t *cb_in_ptr; 
      srslte_crc_t *crc_ptr; 
      early_stop = false; 

      srslte_tdec_reset(&q->decoder, cb_len);
            
      do {
        srslte_tdec_iteration(&q->decoder, (float*) q->cb_out, cb_len); 
        q->nof_iterations++;
        
        if (cb_segm->C > 1) {
          len_crc = cb_len; 
          cb_in_ptr = q->cb_in; 
          crc_ptr = &q->crc_cb; 
        } else {
          len_crc = cb_segm->tbs+24; 
          cb_in_ptr = &q->cb_in[F];
          crc_ptr = &q->crc_tb; 
        }

        srslte_tdec_decision(&q->decoder, q->cb_in, cb_len);
  
        /* Check Codeblock CRC and stop early if incorrect */
        if (!srslte_crc_checksum(crc_ptr, cb_in_ptr, len_crc)) {
          early_stop = true;           
        }
        
      } while (q->nof_iterations < SRSLTE_PDSCH_MAX_TDEC_ITERS && !early_stop);
      q->average_nof_iterations = SRSLTE_VEC_EMA((float) q->nof_iterations, q->average_nof_iterations, 0.2);

      if (SRSLTE_VERBOSE_ISDEBUG()) {
        DEBUG("CB#%d IN: ", i);
        srslte_vec_fprint_b(stdout, q->cb_in, cb_len);
      }
            
      // If CB CRC is not correct, early_stop will be false and wont continue with rest of CBs

      /* Copy data to another buffer, removing the Codeblock CRC */
      if (i < cb_segm->C - 1) {
        memcpy(&data[wp], &q->cb_in[F], (rlen - F) * sizeof(uint8_t));
      } else {
        DEBUG("Last CB, appending parity: %d to %d from %d and 24 from %d\n",
            rlen - F - 24, wp, F, rlen - 24);
        
        /* Append Transport Block parity bits to the last CB */
        memcpy(&data[wp], &q->cb_in[F], (rlen - F - 24) * sizeof(uint8_t));
        memcpy(parity, &q->cb_in[rlen - 24], 24 * sizeof(uint8_t));
      }

      /* Set read/write pointers */
      wp += (rlen - F);
      rp += n_e;
    }

    if (!early_stop) {
      INFO("CB %d failed. TB is erroneous.\n",i-1);
      return SRSLTE_ERROR; 
    } else {
      INFO("END CB#%d: wp: %d, rp: %d\n", i, wp, rp);

      // Compute transport block CRC
      par_rx = srslte_crc_checksum(&q->crc_tb, data, cb_segm->tbs);

      // check parity bits
      par_tx = srslte_bit_unpack(&p_parity, 24);

      if (!par_rx) {
        INFO("\n\tCAUTION!! Received all-zero transport block\n\n", 0);
      }

      if (par_rx == par_tx) {
        INFO("TB decoded OK\n",i);
        return SRSLTE_SUCCESS;
      } else {
        INFO("Error in TB parity\n",i);
        return SRSLTE_ERROR;
      }
      
    }
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}