From 45014a0cadfd1f28d68d61b5160ee18fa391c4ba Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 14 Jan 2014 10:42:58 +0100 Subject: si: Fix range1024 encoding f0 is currently set to arfcns[0] in range_enc_determine_range(), while GSM 04.08 requires f0 to be ARFCN 0 in range1024 encoding. This patch modifies range_enc_determine_range() to force f0 to be 0 if this encoding is used. This way the case distinction in range_enc_filter_arfcns() is not longer necessary. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/arfcn_range_encode.h | 2 +- openbsc/src/libbsc/arfcn_range_encode.c | 44 ++++++++++++---------------- openbsc/src/libbsc/system_information.c | 2 +- openbsc/tests/gsm0408/gsm0408_test.c | 24 +++++++-------- 4 files changed, 33 insertions(+), 39 deletions(-) diff --git a/openbsc/include/openbsc/arfcn_range_encode.h b/openbsc/include/openbsc/arfcn_range_encode.h index 7a6fff000..bd85d6af4 100644 --- a/openbsc/include/openbsc/arfcn_range_encode.h +++ b/openbsc/include/openbsc/arfcn_range_encode.h @@ -16,7 +16,7 @@ enum { int range_enc_determine_range(const int *arfcns, int size, int *f0_out); int range_enc_arfcns(const int rng, const int *arfcns, int sze, int *out, int idx); int range_enc_find_index(const int rng, const int *arfcns, int size); -int range_enc_filter_arfcns(const int rng, int *arfcns, const int sze, const int f0, int *f0_included); +int range_enc_filter_arfcns(int *arfcns, const int sze, const int f0, int *f0_included); int range_enc_range128(uint8_t *chan_list, int f0, int *w); int range_enc_range256(uint8_t *chan_list, int f0, int *w); diff --git a/openbsc/src/libbsc/arfcn_range_encode.c b/openbsc/src/libbsc/arfcn_range_encode.c index 917754623..a047a06ea 100644 --- a/openbsc/src/libbsc/arfcn_range_encode.c +++ b/openbsc/src/libbsc/arfcn_range_encode.c @@ -144,7 +144,9 @@ int range_enc_arfcns(const int range, */ /** * This implements the range determination as described in GSM 04.08 J4. The - * result will be a base frequency f0 and the range to use. + * result will be a base frequency f0 and the range to use. Note that for range + * 1024 encoding f0 always refers to ARFCN 0 even if it is not an element of + * the arfcns list. * * \param[in] arfcns The input frequencies, they must be sorted, lowest number first * \param[in] size The length of the array @@ -166,8 +168,10 @@ int range_enc_determine_range(const int *arfcns, const int size, int *f0) return ARFCN_RANGE_256; if (max < 512 && size <= 18) return ARFCN_RANGE_512; - if (max < 1024 && size <= 17) + if (max < 1024 && size <= 17) { + *f0 = 0; return ARFCN_RANGE_1024; + } return ARFCN_RANGE_INVALID; } @@ -271,34 +275,24 @@ int range_enc_range1024(uint8_t *chan_list, int f0, int f0_included, int *w) return -1; } -int range_enc_filter_arfcns(const int range, int *arfcns, - const int size, const int f0, int *f0_included) +int range_enc_filter_arfcns(int *arfcns, + const int size, const int f0, int *f0_included) { int i, j = 0; *f0_included = 0; - if (range == ARFCN_RANGE_1024) { - for (i = 0; i < size; ++i) { - if (arfcns[i] == f0) { - *f0_included = 1; - continue; - } - - /* copy and subtract */ - arfcns[j++] = mod(arfcns[i] - 1, 1024); - } - } else { - for (i = 0; i < size; ++i) { - /* - * Appendix J.4 says the following: - * All frequencies except F(0), minus F(0) + 1. - * I assume we need to exclude it here. - */ - if (arfcns[i] == f0) - continue; - - arfcns[j++] = mod(arfcns[i] - (f0 + 1), 1024); + for (i = 0; i < size; ++i) { + /* + * Appendix J.4 says the following: + * All frequencies except F(0), minus F(0) + 1. + * I assume we need to exclude it here. + */ + if (arfcns[i] == f0) { + *f0_included = 1; + continue; } + + arfcns[j++] = mod(arfcns[i] - (f0 + 1), 1024); } return j; diff --git a/openbsc/src/libbsc/system_information.c b/openbsc/src/libbsc/system_information.c index aa1cb8d1b..a3deefc73 100644 --- a/openbsc/src/libbsc/system_information.c +++ b/openbsc/src/libbsc/system_information.c @@ -197,7 +197,7 @@ static int enc_freq_lst_range(uint8_t *chan_list, * Manipulate the ARFCN list according to the rules in J4 depending * on the selected range. */ - arfcns_used = range_enc_filter_arfcns(range, arfcns, arfcns_used, + arfcns_used = range_enc_filter_arfcns(arfcns, arfcns_used, f0, &f0_included); memset(w, 0, sizeof(w)); diff --git a/openbsc/tests/gsm0408/gsm0408_test.c b/openbsc/tests/gsm0408/gsm0408_test.c index 3a6bbddff..894eb0fb5 100644 --- a/openbsc/tests/gsm0408/gsm0408_test.c +++ b/openbsc/tests/gsm0408/gsm0408_test.c @@ -152,12 +152,12 @@ static int test_single_range_encoding(int range, const int *orig_arfcns, arfcns_used = arfcns_num; memmove(arfcns, orig_arfcns, sizeof(arfcns)); - f0 = arfcns[0]; + f0 = range == ARFCN_RANGE_1024 ? 0 : arfcns[0]; /* * Manipulate the ARFCN list according to the rules in J4 depending * on the selected range. */ - arfcns_used = range_enc_filter_arfcns(range, arfcns, arfcns_used, + arfcns_used = range_enc_filter_arfcns(arfcns, arfcns_used, f0, &f0_included); memset(w, 0, sizeof(w)); @@ -354,28 +354,28 @@ static void test_arfcn_filter() /* check that the arfcn is taken out. f0_included is only set for Range1024 */ f0_included = 24; - res = range_enc_filter_arfcns(ARFCN_RANGE_512, arfcns, ARRAY_SIZE(arfcns), + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), arfcns[0], &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); - VERIFY(f0_included, ==, 0); + VERIFY(f0_included, ==, 1); for (i = 0; i < res; ++i) VERIFY(arfcns[i], ==, ((i+2) * 2) - (2+1)); - /* check with range1024 */ + /* check with range1024, ARFCN 0 is included */ for (i = 0; i < ARRAY_SIZE(arfcns); ++i) - arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - arfcns[0], &f0_included); + arfcns[i] = i * 2; + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), + 0, &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns) - 1); VERIFY(f0_included, ==, 1); for (i = 0; i < res; ++i) - VERIFY(arfcns[i], ==, ((i + 2) * 2) - 1); + VERIFY(arfcns[i], ==, (i + 1) * 2 - 1); - /* check with range1024, not included */ + /* check with range1024, ARFCN 0 not included */ for (i = 0; i < ARRAY_SIZE(arfcns); ++i) arfcns[i] = (i + 1) * 2; - res = range_enc_filter_arfcns(ARFCN_RANGE_1024, arfcns, ARRAY_SIZE(arfcns), - 11, &f0_included); + res = range_enc_filter_arfcns(arfcns, ARRAY_SIZE(arfcns), + 0, &f0_included); VERIFY(res, ==, ARRAY_SIZE(arfcns)); VERIFY(f0_included, ==, 0); for (i = 0; i < res; ++i) -- cgit v1.2.3