/* 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; }
/* 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; }