srsLTE/lib/src/phy/phch/ra_sl.c

210 lines
6.7 KiB
C

/**
* Copyright 2013-2022 Software Radio Systems Limited
*
* This file is part of srsRAN.
*
* srsRAN is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsRAN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <sys/time.h>
#include "srsran/phy/common/phy_common_sl.h"
#include "srsran/phy/phch/ra.h"
#include "srsran/phy/phch/ra_sl.h"
#include "srsran/phy/utils/random.h"
int srsran_sl_get_available_pool_prb(uint32_t prb_num, uint32_t prb_start, uint32_t prb_end)
{
if ((prb_num * 2) <= (prb_end - prb_start + 1)) {
return prb_num * 2;
} else {
return prb_num * 2 - 1;
}
}
int srsran_pscch_resources(uint32_t prb_num,
uint32_t prb_start,
uint32_t prb_end,
uint8_t* pscch_sf_bitmap,
uint32_t period_length,
uint32_t n_pscch,
uint32_t* m_a,
uint32_t* l_b)
{
uint8_t M = srsran_sl_get_available_pool_prb(prb_num, prb_start, prb_end);
uint32_t L = 0;
for (uint32_t i = 0; i < period_length; i++) {
if (pscch_sf_bitmap[i] == 1) {
L++;
}
}
if (L < 2) {
// ERROR("Invalid PSCCH subframe bitmap");
return SRSRAN_ERROR;
}
n_pscch = n_pscch % (L * M / 2);
uint32_t a1 = n_pscch / L; // RB index A
uint32_t b1 = n_pscch % L; // SF index A
uint32_t a2 = a1 + M / 2; // RB index B
uint32_t b2 = (n_pscch + 1 + (a1 % (L - 1))) % L; // SF index B
m_a[0] = a1 + prb_start; // PRB 1
m_a[1] = a2 + (prb_end + 1 - M); // PRB 2
uint32_t k = 0;
for (uint32_t i = 0; i < period_length; i++) {
if (pscch_sf_bitmap[i] == 1) {
k++;
if (k == (b1 + 1)) {
l_b[0] = i;
break;
}
}
}
k = 0;
for (uint32_t i = 0; i < period_length; i++) {
if (pscch_sf_bitmap[i] == 1) {
k++;
if (k == (b2 + 1)) {
l_b[1] = i;
break;
}
}
}
return SRSRAN_SUCCESS;
}
// 3GPP TS 36.213 Section 8.1.1. Uplink resource allocation type 0
uint32_t srsran_ra_sl_type0_to_riv(uint32_t nof_prb, uint32_t prb_start, uint32_t L_crb)
{
return srsran_ra_type2_to_riv(L_crb, prb_start, nof_prb);
}
// 3GPP TS 36.213 Section 8.1.1. Uplink resource allocation type 0
void srsran_ra_sl_type0_from_riv(uint32_t riv, uint32_t nof_prb, uint32_t* L_crb, uint32_t* prb_start)
{
srsran_ra_type2_from_riv(riv, L_crb, prb_start, nof_prb, nof_prb);
}
int srsran_ra_sl_pssch_allowed_sf(uint32_t pssch_sf_idx, uint32_t trp_idx, uint32_t duplex_mode, uint32_t tdd_config)
{
if (duplex_mode == SRSRAN_SL_DUPLEX_MODE_FDD) {
return srsran_sl_N_TRP_8[trp_idx][pssch_sf_idx % 8];
}
switch (tdd_config) {
// N_TRP = 6
case 3:
case 6:
return srsran_sl_N_TRP_6[trp_idx][pssch_sf_idx % 6];
// N_TRP = 7
case 0:
return srsran_sl_N_TRP_7[trp_idx][pssch_sf_idx % 7];
// N_TRP = 8
case 1:
case 2:
case 4:
case 5:
return srsran_sl_N_TRP_8[trp_idx][pssch_sf_idx % 8];
default:
return 0;
}
}
int srsran_sci_generate_trp_idx(uint32_t duplex_mode, uint32_t tdd_config, uint32_t k_TRP)
{
int retval = SRSRAN_ERROR;
struct timeval tv;
gettimeofday(&tv, NULL);
srsran_random_t random = srsran_random_init(tv.tv_usec);
// N_TRP = 8
if (duplex_mode == SRSRAN_SL_DUPLEX_MODE_FDD || tdd_config == 1 || tdd_config == 2 || tdd_config == 4 ||
tdd_config == 5) {
switch (k_TRP) {
case 1:
retval = srsran_sl_N_TRP_8_k_1[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_8_k_1) - 1)];
break;
case 2:
retval = srsran_sl_N_TRP_8_k_2[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_8_k_2) - 1)];
break;
case 4:
retval = srsran_sl_N_TRP_8_k_4[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_8_k_4) - 1)];
break;
case 8:
retval = srsran_sl_N_TRP_8_k_8[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_8_k_8) - 1)];
break;
}
// N_TRP = 7
} else if (tdd_config == 0) {
switch (k_TRP) {
case 1:
retval = srsran_sl_N_TRP_7_k_1[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_7_k_1) - 1)];
break;
case 2:
retval = srsran_sl_N_TRP_7_k_2[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_7_k_2) - 1)];
break;
case 3:
retval = srsran_sl_N_TRP_7_k_3[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_7_k_3) - 1)];
break;
case 4:
retval = srsran_sl_N_TRP_7_k_4[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_7_k_4) - 1)];
break;
case 5:
retval = srsran_sl_N_TRP_7_k_5[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_7_k_5) - 1)];
break;
case 6:
retval = srsran_sl_N_TRP_7_k_6[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_7_k_6) - 1)];
break;
case 7:
retval = srsran_sl_N_TRP_7_k_7[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_7_k_7) - 1)];
break;
}
// N_TRP = 6
} else if (tdd_config == 3 || tdd_config == 6) {
switch (k_TRP) {
case 1:
retval = srsran_sl_N_TRP_6_k_1[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_6_k_1) - 1)];
break;
case 2:
retval = srsran_sl_N_TRP_6_k_2[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_6_k_2) - 1)];
break;
case 3:
retval = srsran_sl_N_TRP_6_k_3[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_6_k_3) - 1)];
break;
case 4:
retval = srsran_sl_N_TRP_6_k_4[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_6_k_4) - 1)];
break;
case 5:
retval = srsran_sl_N_TRP_6_k_5[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_6_k_5) - 1)];
break;
case 6:
retval = srsran_sl_N_TRP_6_k_6[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_6_k_6) - 1)];
break;
}
} else {
retval = SRSRAN_SUCCESS;
}
srsran_random_free(random);
return retval;
}