mirror of https://github.com/pvnis/srsRAN_4G.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
4.9 KiB
C
204 lines
4.9 KiB
C
/*
|
|
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
|
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
|
*
|
|
* OSLD-lib is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* OSLD-lib 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 Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "lte/base.h"
|
|
|
|
const int lte_symbol_sz(int nof_prb) {
|
|
if (nof_prb<=0) {
|
|
return -1;
|
|
}
|
|
if (nof_prb<=6) {
|
|
return 128;
|
|
} else if (nof_prb<=15) {
|
|
return 256;
|
|
} else if (nof_prb<=25) {
|
|
return 512;
|
|
} else if (nof_prb<=50) {
|
|
return 1024;
|
|
} else if (nof_prb<=75) {
|
|
return 1536;
|
|
} else if (nof_prb<=100) {
|
|
return 2048;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int lte_voffset(int symbol_id, int cell_id, int nof_ports) {
|
|
if (nof_ports == 1 && symbol_id==0) {
|
|
return (cell_id+3) % 6;
|
|
} else {
|
|
return cell_id % 6;
|
|
}
|
|
}
|
|
|
|
/* Returns the number of available RE per PRB */
|
|
int lte_re_x_prb(int ns, int symbol, int nof_ports, int nof_symbols) {
|
|
if (symbol == 0) {
|
|
if (((ns % 2) == 0) || (ns == 1)) {
|
|
return RE_X_RB - 4;
|
|
} else {
|
|
if (nof_ports == 1) {
|
|
return RE_X_RB - 2;
|
|
} else {
|
|
return RE_X_RB - 4;
|
|
}
|
|
}
|
|
} else if (symbol == 1) {
|
|
if (ns == 1) {
|
|
return RE_X_RB - 4;
|
|
} else if (nof_ports == 4) {
|
|
return RE_X_RB - 4;
|
|
} else {
|
|
return RE_X_RB;
|
|
}
|
|
} else if (symbol == nof_symbols - 3) {
|
|
if (nof_ports == 1) {
|
|
return RE_X_RB - 2;
|
|
} else {
|
|
return RE_X_RB - 4;
|
|
}
|
|
} else {
|
|
return RE_X_RB;
|
|
}
|
|
}
|
|
|
|
|
|
struct lte_band {
|
|
int band;
|
|
float fd_low_mhz;
|
|
int earfcn_offset;
|
|
int earfcn_max;
|
|
enum band_geographical_area area;
|
|
};
|
|
|
|
struct lte_band lte_bands[NOF_LTE_BANDS] = {
|
|
{1, 2110, 0, 599, ALL},
|
|
{2, 1930, 600, 1199, NAR},
|
|
{3, 1805, 1200, 1949, ALL},
|
|
{4, 2110, 1950, 2399, NAR},
|
|
{5, 869, 2400, 2649, NAR},
|
|
{6, 875, 2650, 2749, APAC},
|
|
{7, 2620, 2750, 3449, EMEA},
|
|
{8, 925, 3450, 3799, ALL},
|
|
{9, 1844.9, 3800, 4149, APAC},
|
|
{10, 2110, 4150, 4749, NAR},
|
|
{11, 1475.9, 4750, 4949, JAPAN},
|
|
{12, 729, 5010, 5179, NAR},
|
|
{13, 746, 5180, 5279, NAR},
|
|
{14, 758, 5280, 5379, NAR},
|
|
{17, 734, 5730, 5849, NAR},
|
|
{18, 860, 5850, 5999, JAPAN},
|
|
{19, 875, 6000, 6149, JAPAN},
|
|
{20, 791, 6150, 6449, EMEA},
|
|
{21, 1495.9, 6450, 6599, JAPAN},
|
|
{22, 3500, 6600, 7399, NA},
|
|
{23, 2180, 7500, 7699, NAR},
|
|
{24, 1525, 7700, 8039, NAR},
|
|
{25, 1930, 8040, 8689, NAR},
|
|
{26, 859, 8690, 9039, NAR},
|
|
{27, 852, 9040, 9209, NAR},
|
|
{28, 758, 9210, 9659, APAC},
|
|
{29, 717, 9660, 9769, NAR},
|
|
{30, 2350, 9770, 9869, NAR},
|
|
{31, 462.5, 9870, 9919, CALA}
|
|
};
|
|
#define EOF_BAND 9919
|
|
|
|
float get_fd(struct lte_band *band, int earfcn) {
|
|
return band->fd_low_mhz + 0.1*(earfcn - band->earfcn_offset);
|
|
}
|
|
|
|
float lte_band_fd(int earfcn) {
|
|
int i;
|
|
i=0;
|
|
while(i < NOF_LTE_BANDS && lte_bands[i].earfcn_offset<earfcn) {
|
|
i++;
|
|
}
|
|
if (i == NOF_LTE_BANDS) {
|
|
fprintf(stderr, "Error: EARFCN %d not found\n", earfcn);
|
|
return -1.0;
|
|
}
|
|
return get_fd(<e_bands[i], earfcn);
|
|
}
|
|
|
|
int lte_band_get_fd_band_all(int band, lte_earfcn_t *earfcn, int max_elems) {
|
|
return lte_band_get_fd_band(band, earfcn, -1, -1, max_elems);
|
|
}
|
|
|
|
int lte_band_get_fd_band(int band, lte_earfcn_t *earfcn, int start_earfcn, int end_earfcn, int max_elems) {
|
|
int i, j;
|
|
int nof_earfcn;
|
|
i=0;
|
|
while(i < NOF_LTE_BANDS && lte_bands[i].band != band) {
|
|
i++;
|
|
}
|
|
if (i == NOF_LTE_BANDS) {
|
|
fprintf(stderr, "Error: Invalid band %d\n", band);
|
|
return -1;
|
|
}
|
|
if (end_earfcn == -1) {
|
|
end_earfcn = lte_bands[i].earfcn_max;
|
|
} else {
|
|
if (end_earfcn > lte_bands[i].earfcn_max) {
|
|
fprintf(stderr, "Error: Invalid end earfcn %d. Max is %d\n", end_earfcn, lte_bands[i].earfcn_max);
|
|
return -1;
|
|
}
|
|
}
|
|
if (start_earfcn == -1) {
|
|
start_earfcn = lte_bands[i].earfcn_offset;
|
|
} else {
|
|
if (start_earfcn < lte_bands[i].earfcn_offset) {
|
|
fprintf(stderr, "Error: Invalid start earfcn %d. Min is %d\n", start_earfcn, lte_bands[i].earfcn_offset);
|
|
return -1;
|
|
}
|
|
}
|
|
nof_earfcn = end_earfcn - start_earfcn;
|
|
|
|
if (nof_earfcn > max_elems) {
|
|
nof_earfcn = max_elems;
|
|
}
|
|
for (j=0;j<nof_earfcn;j++) {
|
|
earfcn[j].id = j + start_earfcn;
|
|
earfcn[j].fd = get_fd(<e_bands[i], earfcn[j].id);
|
|
}
|
|
return j;
|
|
}
|
|
|
|
int lte_band_get_fd_region(enum band_geographical_area region, lte_earfcn_t *earfcn, int max_elems) {
|
|
int i;
|
|
int n;
|
|
int nof_fd = 0;
|
|
for (i=0;i<NOF_LTE_BANDS && max_elems > 0;i++) {
|
|
if (lte_bands[i].area == region) {
|
|
n = lte_band_get_fd_band(i, &earfcn[nof_fd], -1, -1, max_elems);
|
|
if (n != -1) {
|
|
nof_fd += n;
|
|
max_elems -= n;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
return nof_fd;
|
|
}
|
|
|