Beispiel #1
0
/* 36.211 v10.3.0 Section 6.3.4 */
int predecoding_type(cf_t *y, cf_t *ce[MAX_PORTS], cf_t *x[MAX_LAYERS],
    int nof_ports, int nof_layers, int nof_symbols, lte_mimo_type_t type) {

  if (nof_ports > MAX_PORTS) {
    fprintf(stderr, "Maximum number of ports is %d (nof_ports=%d)\n", MAX_PORTS,
        nof_ports);
    return -1;
  }
  if (nof_layers > MAX_LAYERS) {
    fprintf(stderr, "Maximum number of layers is %d (nof_layers=%d)\n",
        MAX_LAYERS, nof_layers);
    return -1;
  }

  switch (type) {
  case SINGLE_ANTENNA:
    if (nof_ports == 1 && nof_layers == 1) {
      return predecoding_single_zf(y, ce[0], x[0], nof_symbols);
    } else {
      fprintf(stderr,
          "Number of ports and layers must be 1 for transmission on single antenna ports\n");
      return -1;
    }
    break;
  case TX_DIVERSITY:
    if (nof_ports == nof_layers) {
      return predecoding_diversity_zf(y, ce, x, nof_ports, nof_symbols);
    } else {
      fprintf(stderr,
          "Error number of layers must equal number of ports in transmit diversity\n");
      return -1;
    }
    break;
  case SPATIAL_MULTIPLEX:
    fprintf(stderr, "Spatial multiplexing not supported\n");
    return -1;
  }
  return 0;
}
Beispiel #2
0
/* Decodes the PBCH channel
 *
 * The PBCH spans in 40 ms. This function is called every 10 ms. It tries to decode the MIB
 * given the symbols of a subframe (1 ms). Successive calls will use more subframes
 * to help the decoding process.
 *
 * Returns 1 if successfully decoded MIB, 0 if not and -1 on error
 */
int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS], pbch_mib_t *mib) {
  uint32_t src, dst, nb;
  uint32_t nant_[3] = { 1, 2, 4 };
  uint32_t na, nant;
  int i;
  int nof_bits;
  cf_t *x[MAX_LAYERS];
  
  int ret = LIBLTE_ERROR_INVALID_INPUTS;
  
  if (q                 != NULL &&
      slot1_symbols        != NULL && 
      mib               != NULL)
  {
    for (i=0;i<q->cell.nof_ports;i++) {
      if (ce_slot1[i] == NULL) {
        return LIBLTE_ERROR_INVALID_INPUTS;
      } 
    }

    /* Set pointers for layermapping & precoding */
    nof_bits = 2 * q->nof_symbols;

    /* number of layers equals number of ports */
    for (i = 0; i < MAX_PORTS; i++) {
      x[i] = q->pbch_x[i];
    }
    memset(&x[MAX_PORTS], 0, sizeof(cf_t*) * (MAX_LAYERS - MAX_PORTS));
    
    /* extract symbols */
    if (q->nof_symbols != pbch_get(slot1_symbols, q->pbch_symbols[0], q->cell)) {
      fprintf(stderr, "There was an error getting the PBCH symbols\n");
      return LIBLTE_ERROR;
    }

    /* extract channel estimates */
    for (i = 0; i < q->cell.nof_ports; i++) {
      if (q->nof_symbols != pbch_get(ce_slot1[i], q->ce[i], q->cell)) {
        fprintf(stderr, "There was an error getting the PBCH symbols\n");
        return LIBLTE_ERROR;
      }
    }

    q->frame_idx++;
    ret = 0;

    /* Try decoding for 1 to cell.nof_ports antennas */
    for (na = 0; na < q->cell.nof_ports && !ret; na++) {
      nant = nant_[na];

      DEBUG("Trying %d TX antennas with %d frames\n", nant, q->frame_idx);

      /* in conctrol channels, only diversity is supported */
      if (nant == 1) {
        /* no need for layer demapping */
        predecoding_single_zf(q->pbch_symbols[0], q->ce[0], q->pbch_d,
            q->nof_symbols);
      } else {
        predecoding_diversity_zf(q->pbch_symbols[0], q->ce, x, nant,
            q->nof_symbols);
        layerdemap_diversity(x, q->pbch_d, nant, q->nof_symbols / nant);
      }

      /* demodulate symbols */
      demod_soft_sigma_set(&q->demod, 1.0);
      demod_soft_demodulate(&q->demod, q->pbch_d,
          &q->pbch_llr[nof_bits * (q->frame_idx - 1)], q->nof_symbols);

      /* We don't know where the 40 ms begin, so we try all combinations. E.g. if we received
      * 4 frames, try 1,2,3,4 individually, 12, 23, 34 in pairs, 123, 234 and finally 1234.
      * We know they are ordered.
      *
      * FIXME: There are unnecessary checks because 2,3,4 have already been processed in the previous
      * calls.
      */
      for (nb = 0; nb < q->frame_idx && !ret; nb++) {
        for (dst = 0; (dst < 4 - nb) && !ret; dst++) {
          for (src = 0; src < q->frame_idx - nb && !ret; src++) {
            ret = pbch_decode_frame(q, mib, src, dst, nb + 1, nof_bits, nant);
            
          }
        }
      }
    }

    /* If not found, make room for the next packet of radio frame symbols */
    if (q->frame_idx == 4) {
      memmove(q->pbch_llr, &q->pbch_llr[nof_bits], nof_bits * 3 * sizeof(float));
      q->frame_idx = 3;
    }
  }
  return ret;
}