/** Converts the MIB message to symbols mapped to SLOT #1 ready for transmission */ void pbch_encode(pbch_t *q, pbch_mib_t *mib, cf_t *slot1_symbols[MAX_PORTS_CTRL], int nof_ports) { int i; int nof_bits = 2 * q->nof_symbols; assert(nof_ports <= MAX_PORTS_CTRL); /* Set pointers for layermapping & precoding */ cf_t *x[MAX_LAYERS]; /* number of layers equals number of ports */ for (i = 0; i < nof_ports; i++) { x[i] = q->pbch_x[i]; } memset(&x[nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - nof_ports)); if (q->frame_idx == 0) { /* pack MIB */ pbch_mib_pack(mib, q->data); /* encode & modulate */ crc_attach(&q->crc, q->data, 24); crc_set_mask(q->data, nof_ports); convcoder_encode(&q->encoder, q->data, q->data_enc, 40); rm_conv_tx(q->data_enc, 120, q->pbch_rm_b, 4 * nof_bits); } scrambling_b_offset(&q->seq_pbch, &q->pbch_rm_b[q->frame_idx * nof_bits], q->frame_idx * nof_bits, nof_bits); mod_modulate(&q->mod, &q->pbch_rm_b[q->frame_idx * nof_bits], q->pbch_d, nof_bits); /* layer mapping & precoding */ if (nof_ports > 1) { layermap_diversity(q->pbch_d, x, nof_ports, q->nof_symbols); precoding_diversity(x, q->pbch_symbols, nof_ports, q->nof_symbols / nof_ports); } else { memcpy(q->pbch_symbols[0], q->pbch_d, q->nof_symbols * sizeof(cf_t)); } /* mapping to resource elements */ for (i = 0; i < nof_ports; i++) { pbch_put(q->pbch_symbols[i], slot1_symbols[i], q->nof_prb, q->cp, q->cell_id); } q->frame_idx++; if (q->frame_idx == 4) { q->frame_idx = 0; } }
/* 36.211 v10.3.0 Section 6.3.4 */ int precoding_type(cf_t *x[MAX_LAYERS], cf_t *y[MAX_PORTS], int nof_layers, int nof_ports, 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 precoding_single(x[0], y[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 precoding_diversity(x, y, nof_ports, nof_symbols); } else { fprintf(stderr, "Error number of layers must equal number of ports in transmit diversity\n"); return -1; } case SPATIAL_MULTIPLEX: fprintf(stderr, "Spatial multiplexing not supported\n"); return -1; } return 0; }
/** Converts the MIB message to symbols mapped to SLOT #1 ready for transmission */ int pbch_encode(pbch_t *q, pbch_mib_t *mib, cf_t *slot1_symbols[MAX_PORTS]) { int i; int nof_bits; cf_t *x[MAX_LAYERS]; if (q != NULL && mib != NULL) { for (i=0;i<q->cell.nof_ports;i++) { if (slot1_symbols[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 < q->cell.nof_ports; i++) { x[i] = q->pbch_x[i]; } memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); if (q->frame_idx == 0) { /* pack MIB */ pbch_mib_pack(mib, q->data); /* encode & modulate */ crc_attach(&q->crc, q->data, 24); crc_set_mask(q->data, q->cell.nof_ports); convcoder_encode(&q->encoder, q->data, q->data_enc, 40); rm_conv_tx(q->data_enc, 120, q->pbch_rm_b, 4 * nof_bits); } scrambling_b_offset(&q->seq_pbch, &q->pbch_rm_b[q->frame_idx * nof_bits], q->frame_idx * nof_bits, nof_bits); mod_modulate(&q->mod, &q->pbch_rm_b[q->frame_idx * nof_bits], q->pbch_d, nof_bits); /* layer mapping & precoding */ if (q->cell.nof_ports > 1) { layermap_diversity(q->pbch_d, x, q->cell.nof_ports, q->nof_symbols); precoding_diversity(x, q->pbch_symbols, q->cell.nof_ports, q->nof_symbols / q->cell.nof_ports); } else { memcpy(q->pbch_symbols[0], q->pbch_d, q->nof_symbols * sizeof(cf_t)); } /* mapping to resource elements */ for (i = 0; i < q->cell.nof_ports; i++) { pbch_put(q->pbch_symbols[i], slot1_symbols[i], q->cell); } q->frame_idx++; if (q->frame_idx == 4) { q->frame_idx = 0; } return LIBLTE_SUCCESS; } else { return LIBLTE_ERROR_INVALID_INPUTS; } }