From 69e00ccd6ff3a19b771070b78ed3d85dd219799f Mon Sep 17 00:00:00 2001 From: Philipp Maier Date: Wed, 9 Oct 2019 13:38:38 +0200 Subject: gsm0508: add functions to calculate beginning of a block The calculation of the beginning of a block for TCH/F, TCH/H and FACCH can be challenging since those channels are affected by the diagonal interleaving of the TCH channels. However, GSM 05.02 Section 7 Table 1 of 5 specifies how the blocks are distributed over the TDMA frame interval. Lets add a mapping function that is based on that table Related: OS#3803 Change-Id: I3d71c66f8c401f5afbad9b1c86c24580dab9e0ce --- src/gsm/gsm0502.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++ src/gsm/libosmogsm.map | 1 + 2 files changed, 158 insertions(+) (limited to 'src') diff --git a/src/gsm/gsm0502.c b/src/gsm/gsm0502.c index 53259a42..1a71e617 100644 --- a/src/gsm/gsm0502.c +++ b/src/gsm/gsm0502.c @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include unsigned int gsm0502_calc_paging_group(struct gsm48_control_channel_descr *chan_desc, uint64_t imsi) @@ -44,3 +47,157 @@ gsm0502_calc_paging_group(struct gsm48_control_channel_descr *chan_desc, uint64_ return group; } + +/* Clause 7 Table 1 of 5 Mapping of logical channels onto physical channels */ +#define TCH_REPEAT_LENGTH 13 +#define FACCH_F_REPEAT_LENGTH 13 +#define FACCH_H_REPEAT_LENGTH 26 + +static const uint8_t gsm0502_tch_f_traffic_block_map[3][8] = { + {0, 1, 2, 3, 4, 5, 6, 7}, + {4, 5, 6, 7, 8, 9, 10, 11}, + {8, 9, 10, 11, 0, 1, 2, 3} +}; + +static const uint8_t gsm0502_tch_h0_traffic_block_map[3][4] = { + {0, 2, 4, 6}, + {4, 6, 8, 10}, + {8, 10, 0, 2} +}; + +static const uint8_t gsm0502_tch_h1_traffic_block_map[3][4] = { + {1, 3, 5, 7}, + {5, 7, 9, 11}, + {9, 11, 1, 3} +}; + +static const uint8_t gsm0502_tch_f_facch_block_map[3][8] = { + {0, 1, 2, 3, 4, 5, 6, 7}, + {4, 5, 6, 7, 8, 9, 10, 11}, + {8, 9, 10, 11, 0, 1, 2, 3} +}; + +static const uint8_t gsm0502_tch_h0_facch_block_map[3][6] = { + {0, 2, 4, 6, 8, 10}, + {8, 10, 13, 15, 17, 19}, + {17, 19, 21, 23, 0, 2} +}; + +static const uint8_t gsm0502_tch_h1_facch_block_map[3][6] = { + {1, 3, 5, 7, 9, 11}, + {9, 11, 14, 16, 18, 20}, + {18, 20, 22, 24, 1, 3} +}; + +/* Struct to describe a remapping function for block frame nbumbers. The member + * blockend describes the ending of a block for which we want to determine the + * beginning frame number. The member distance describes the value we need to + * subtract from the blockend frame number in order to get the beginning of the + * the block. The member cycle describes the Repeat length in TDMA frames we + * are dealing with. For traffic channels this is always 13, for control + * channels it is different. The member len simply defines amount of + * blockendings and distances we store in the remap table */ +struct fn_remap_table { + unsigned int cycle; + unsigned int len; + uint8_t blockend[8]; + uint8_t distance[8]; +}; + +/* Memory to hold the remap tables we will automatically generate on startup */ +static struct fn_remap_table tch_f_remap_table; +static struct fn_remap_table tch_h0_remap_table; +static struct fn_remap_table tch_h1_remap_table; +static struct fn_remap_table facch_f_remap_table; +static struct fn_remap_table facch_h0_remap_table; +static struct fn_remap_table facch_h1_remap_table; +static struct fn_remap_table *fn_remap_table_ptr[FN_REMAP_MAX]; + +/* Generate a remap table from a given block map. A block map lists the block + * layout as defined in GSM 05.02, Clause 7 Table 1 of 5, one block per row. + * Parameters: + * table: name of the remap table to output + * map: traffic block map input + * rows: length of the traffic block map + * cols: witdh of the traffic block map + * repeat: repeat length in TDMA frames (cycle) */ +#define fn_remap_table_from_traffic_block_map(table, map, rows, cols, repeat) \ + for(i=0;icycle; + + for (i = 0; i < table->len; i++) { + if (table->blockend[i] == fn_cycle) { + sub = table->distance[i]; + break; + } + } + + if (sub == -1) { + LOGP(DLGLOBAL, LOGL_ERROR, "could not remap frame number!, fn=%"PRIu32"\n", fn); + return fn; + } + + fn_map = (fn + GSM_MAX_FN - sub) % GSM_MAX_FN; + + return fn_map; +} diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map index ea1f759d..724fe5b1 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -107,6 +107,7 @@ gsm0480_gen_return_error; gsm0480_gen_reject; gsm0502_calc_paging_group; +gsm0502_fn_remap; gsm0503_xcch; gsm0503_rach; -- cgit v1.2.3