Esempio n. 1
0
int dci_format1Cs_unpack(dci_msg_t *msg, ra_pdsch_t *data, int nof_prb) {
  uint16_t L_p, RB_p;

  /* pack bits */
  char *y = msg->data;

  if (msg->location.nof_bits != dci_format_sizeof(Format1C, nof_prb)) {
    fprintf(stderr, "Invalid message length for format 1C\n");
    return -1;
  }
  data->alloc_type = alloc_type2;
  data->type2_alloc.mode = t2_dist;
  if (nof_prb >= 50) {
    data->type2_alloc.n_gap = *y++;
  }
  int n_step = ra_type2_n_rb_step(nof_prb);
  int n_vrb_dl = ra_type2_n_vrb_dl(nof_prb, data->type2_alloc.n_gap == t2_ng1);

  uint32_t riv = bit_unpack(&y, riv_nbits((int) n_vrb_dl / n_step));
  int n_vrb_p = (int) n_vrb_dl / n_step;

  ra_type2_from_riv(riv, &L_p, &RB_p, n_vrb_p, n_vrb_p);
  data->type2_alloc.L_crb = L_p * n_step;
  data->type2_alloc.RB_start = RB_p * n_step;
  data->type2_alloc.riv = riv;

  data->mcs.mcs_idx = bit_unpack(&y, 5);
  data->mcs.tbs_idx = data->mcs.mcs_idx;
  data->mcs.tbs = ra_tbs_from_idx_format1c(data->mcs.tbs_idx);
  data->mcs.mod = QPSK;

  msg->location.nof_bits = (y - msg->data);

  return 0;
}
Esempio n. 2
0
int mod_modulate(modem_table_t* q, const uint8_t *bits, cf* symbols, int nbits) {
	int i,j,idx;
	uint8_t *b_ptr=(uint8_t*) bits;
	j=0;
	for (i=0;i<nbits;i+=q->nbits_x_symbol) {
		idx = bit_unpack(&b_ptr,q->nbits_x_symbol);
		symbols[j] = q->symbol_table[idx];
		j++;
	}
	return j;
}
Esempio n. 3
0
/** Unpacks MIB from PBCH message.
 * msg buffer must be 24 byte length at least
 */
void pbch_mib_unpack(char *msg, pbch_mib_t *mib) {
  int bw, phich_res;

  bw = bit_unpack(&msg, 3);
  switch (bw) {
  case 0:
    mib->nof_prb = 6;
    break;
  case 1:
    mib->nof_prb = 15;
    break;
  default:
    mib->nof_prb = (bw - 1) * 25;
    break;
  }
  if (*msg) {
    mib->phich_length = PHICH_EXT;
  } else {
    mib->phich_length = PHICH_NORM;
  }
  msg++;

  phich_res = bit_unpack(&msg, 2);
  switch (phich_res) {
  case 0:
    mib->phich_resources = R_1_6;
    break;
  case 1:
    mib->phich_resources = R_1_2;
    break;
  case 2:
    mib->phich_resources = R_1;
    break;
  case 3:
    mib->phich_resources = R_2;
    break;
  }
  mib->sfn = bit_unpack(&msg, 8) << 2;
}
Esempio n. 4
0
int dci_format1_unpack(dci_msg_t *msg, ra_pdsch_t *data, int nof_prb) {

  /* pack bits */
  char *y = msg->data;

  /* Make sure it's a Format1 message */
  if (msg->location.nof_bits != dci_format_sizeof(Format1, nof_prb)) {
    fprintf(stderr, "Invalid message length for format 1\n");
    return -1;
  }

  if (nof_prb > 10) {
    data->alloc_type = *y++;
  } else {
    data->alloc_type = alloc_type0;
  }

  /* Resource allocation: type0 or type 1 */
  int P = ra_type0_P(nof_prb);
  int alloc_size = (int) ceilf((float) nof_prb / P);
  switch (data->alloc_type) {
  case alloc_type0:
    data->type0_alloc.rbg_bitmask = bit_unpack(&y, alloc_size);
    break;
  case alloc_type1:
    data->type1_alloc.rbg_subset = bit_unpack(&y, (int) ceilf(log2f(P)));
    data->type1_alloc.shift = *y++ ? true : false;
    data->type1_alloc.vrb_bitmask = bit_unpack(&y,
        alloc_size - (int) ceilf(log2f(P)) - 1);
    break;
  default:
    fprintf(stderr,
        "Format 1 accepts type0 or type1 resource allocation only\n");
    return -1;

  }
  /* pack MCS according to 7.1.7 of 36.213 */
  uint32_t mcs = bit_unpack(&y, 5);
  data->mcs.mcs_idx = mcs;
  ra_mcs_from_idx_dl(mcs, &data->mcs);
  data->mcs.tbs = ra_tbs_from_idx(data->mcs.tbs_idx, ra_nprb_dl(data, nof_prb));

  /* harq process number */
  data->harq_process = bit_unpack(&y, 3);

  data->ndi = *y++ ? true : false;

  // rv version
  data->rv_idx = bit_unpack(&y, 2);

  // TPC not implemented

  return 0;
}
Esempio n. 5
0
/* Unpacks DCI format 1A for compact scheduling of PDSCH words according to 36.212 5.3.3.1.3
 *
 */
int dci_format1As_unpack(dci_msg_t *msg, ra_pdsch_t *data, int nof_prb,
    bool crc_is_crnti) {

  /* pack bits */
  char *y = msg->data;

  /* Make sure it's a Format0 message */
  if (msg->location.nof_bits != dci_format_sizeof(Format1A, nof_prb)) {
    fprintf(stderr, "Invalid message length for format 1A\n");
    return -1;
  }

  if (*y++ != 1) {
    fprintf(stderr,
        "Invalid format differentiation field value. This is Format0\n");
    return -1;
  }

  data->alloc_type = alloc_type2;
  data->type2_alloc.mode = *y++;

  // by default, set N_gap to 1
  data->type2_alloc.n_gap = t2_ng1;

  /* unpack RIV according to 7.1.6.3 of 36.213 */
  int nb_gap = 0;
  if (crc_is_crnti && data->type2_alloc.mode == t2_dist && nof_prb >= 50) {
    nb_gap = 1;
    data->type2_alloc.n_gap = *y++;
  }
  int nof_vrb;
  if (data->type2_alloc.mode == t2_loc) {
    nof_vrb = nof_prb;
  } else {
    nof_vrb = ra_type2_n_vrb_dl(nof_prb, data->type2_alloc.n_gap == t2_ng1);
  }
  uint32_t riv = bit_unpack(&y, riv_nbits(nof_prb) - nb_gap);
  ra_type2_from_riv(riv, &data->type2_alloc.L_crb, &data->type2_alloc.RB_start,
      nof_prb, nof_vrb);
  data->type2_alloc.riv = riv;

  // unpack MCS
  data->mcs.mcs_idx = bit_unpack(&y, 5);

  data->harq_process = bit_unpack(&y, 3);

  if (!crc_is_crnti && nof_prb >= 50 && data->type2_alloc.mode == t2_dist) {
    data->type2_alloc.n_gap = *y++;
  } else {
    y++; // bit reserved
  }

  // rv version
  bit_pack(data->rv_idx, &y, 2);

  if (crc_is_crnti) {
    // TPC not implemented
    y++;
    y++;
  } else {
    y++; // MSB of TPC is reserved
    data->type2_alloc.n_prb1a = *y++; // LSB indicates N_prb_1a for TBS
  }
  data->mcs.tbs_idx = data->mcs.mcs_idx;
  int n_prb;
  if (crc_is_crnti) {
    n_prb = ra_nprb_dl(data, nof_prb);
  } else {
    n_prb = data->type2_alloc.n_prb1a == nprb1a_2 ? 2 : 3;
  }
  data->mcs.tbs = ra_tbs_from_idx(data->mcs.tbs_idx, n_prb);
  data->mcs.mod = QPSK;

  return 0;
}
Esempio n. 6
0
/* Unpacks DCI format 0 data and store result in msg according
 * to 36.212 5.3.3.1.1
 *
 * TODO: TPC and cyclic shift for DM RS not implemented
 */
int dci_format0_unpack(dci_msg_t *msg, ra_pusch_t *data, int nof_prb) {

  /* pack bits */
  char *y = msg->data;
  int n_ul_hop;

  /* Make sure it's a Format0 message */
  if (msg->location.nof_bits != dci_format_sizeof(Format0, nof_prb)) {
    fprintf(stderr, "Invalid message length for format 0\n");
    return -1;
  }
  if (*y++ != 0) {
    fprintf(stderr,
        "Invalid format differentiation field value. This is Format1A\n");
    return -1;
  }
  if (*y++ == 0) {
    data->freq_hop_fl = hop_disabled;
    n_ul_hop = 0;
  } else {
    if (nof_prb < 50) {
      n_ul_hop = 1; // Table 8.4-1 of 36.213
      data->freq_hop_fl = *y++;
    } else {
      n_ul_hop = 2; // Table 8.4-1 of 36.213
      data->freq_hop_fl = y[0] << 1 | y[1];
      y += 2;
    }
  }
  /* unpack RIV according to 8.1 of 36.213 */
  uint32_t riv = bit_unpack(&y, riv_nbits(nof_prb) - n_ul_hop);
  ra_type2_from_riv(riv, &data->type2_alloc.L_crb, &data->type2_alloc.RB_start,
      nof_prb, nof_prb);
  bit_pack(riv, &y, riv_nbits(nof_prb) - n_ul_hop);
  data->type2_alloc.riv = riv;

  /* unpack MCS according to 8.6 of 36.213 */
  uint32_t mcs = bit_unpack(&y, 5);

  data->ndi = *y++ ? true : false;

  // TCP and DM RS commands not implemented
  y += 5;

  // CQI request
  data->cqi_request = *y++ ? true : false;

  // 8.6.2 First paragraph
  if (mcs <= 28) {
    ra_mcs_from_idx_ul(mcs, &data->mcs);
    data->mcs.tbs = ra_tbs_from_idx(data->mcs.tbs_idx,
        ra_nprb_ul(data, nof_prb));
  }

  // 8.6.1 and 8.6.2 36.213 second paragraph
  if (mcs == 29 && data->cqi_request && ra_nprb_ul(data, nof_prb) <= 4) {
    data->mcs.mod = QPSK;
  }
  if (mcs > 29) {
    // Else leave MOD_NULL and use the previously used PUSCH modulation
    data->mcs.mod = MOD_NULL;
    data->rv_idx = mcs - 28;
  }

  return 0;
}