blob: bb5468a4c5fa945ed8bfb128906a128759324674 [file] [log] [blame]
Philipp Maier844876f2018-07-13 09:17:07 +02001/*
2 * (C) 2018 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
3 * All Rights Reserved
4 *
5 * Author: Philipp Maier
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Neels Hofmeyrb5ce49f2018-07-24 17:42:14 +020022#include <osmocom/bsc/gsm_data.h>
Philipp Maier844876f2018-07-13 09:17:07 +020023#include <osmocom/bsc/osmo_bsc.h>
24#include <osmocom/bsc/bsc_msc_data.h>
25#include <osmocom/bsc/gsm_04_80.h>
26#include <osmocom/core/application.h>
27#include <osmocom/bsc/codec_pref.h>
28
29#include <stdio.h>
30
31void *ctx = NULL;
32
33#define MSC_AUDIO_SUPPORT_MAX 5
34#define N_CONFIG_VARIANTS 9
35
36/* Make sure that there is some memory to put our test configuration. */
37static void init_msc_config(struct bsc_msc_data *msc)
38{
39 unsigned int i;
40
41 msc->audio_support = talloc_zero_array(ctx, struct gsm_audio_support *, MSC_AUDIO_SUPPORT_MAX);
42 msc->audio_length = MSC_AUDIO_SUPPORT_MAX;
43 for (i = 0; i < MSC_AUDIO_SUPPORT_MAX; i++) {
44 msc->audio_support[i] = talloc_zero(msc->audio_support, struct gsm_audio_support);
45 }
46}
47
48/* Free memory that we have used for the test configuration. */
49static void free_msc_config(struct bsc_msc_data *msc)
50{
51 talloc_free(msc->audio_support);
52}
53
54/* The speech codec list is sent by the MS and lists the voice codec settings
55 * that the MS is able to support. The BSC must select one of this codecs
56 * depending on what the MSC is able to support. The following function
57 * generates some realistically made up speech codec lists. */
58static void make_scl_config(struct gsm0808_speech_codec_list *scl, uint8_t config_no)
59{
60 OSMO_ASSERT(config_no < N_CONFIG_VARIANTS);
61
62 switch (config_no) {
63 case 0:
64 /* FR1 only */
65 scl->codec[0].type = GSM0808_SCT_FR1;
66 scl->len = 1;
67 break;
68 case 1:
69 /* HR1 only */
70 scl->codec[0].type = GSM0808_SCT_HR1;
71 scl->len = 1;
72 break;
73 case 2:
74 /* FR2 only */
75 scl->codec[0].type = GSM0808_SCT_FR2;
76 scl->len = 1;
77 break;
78 case 3:
79 /* FR3 only */
80 scl->codec[0].type = GSM0808_SCT_FR3;
Philipp Maierf96c04a2018-09-14 16:58:55 +020081 scl->codec[0].cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR;
Philipp Maier844876f2018-07-13 09:17:07 +020082 scl->len = 1;
83 break;
84 case 4:
85 /* HR3 only */
86 scl->codec[0].type = GSM0808_SCT_HR3;
Philipp Maierf96c04a2018-09-14 16:58:55 +020087 scl->codec[0].cfg = GSM0808_SC_CFG_DEFAULT_HR_AMR;
Philipp Maier844876f2018-07-13 09:17:07 +020088 scl->len = 1;
89 break;
90 case 5:
91 /* FR1 and HR1 */
92 scl->codec[0].type = GSM0808_SCT_FR1;
93 scl->codec[1].type = GSM0808_SCT_HR1;
94 scl->len = 2;
95 break;
96 case 6:
97 /* FR1, FR2 and HR1 */
98 scl->codec[0].type = GSM0808_SCT_FR1;
99 scl->codec[1].type = GSM0808_SCT_FR2;
100 scl->codec[2].type = GSM0808_SCT_HR1;
101 scl->len = 3;
102 break;
103 case 7:
104 /* FR1, FR3 and HR3 */
105 scl->codec[0].type = GSM0808_SCT_FR1;
106 scl->codec[1].type = GSM0808_SCT_FR3;
Philipp Maierf96c04a2018-09-14 16:58:55 +0200107 scl->codec[1].cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR;
Philipp Maier844876f2018-07-13 09:17:07 +0200108 scl->codec[2].type = GSM0808_SCT_HR3;
Philipp Maierf96c04a2018-09-14 16:58:55 +0200109 scl->codec[2].cfg = GSM0808_SC_CFG_DEFAULT_HR_AMR;
Philipp Maier844876f2018-07-13 09:17:07 +0200110 scl->len = 3;
111 break;
112 case 8:
113 /* FR1, FR2, FR3, HR1 and HR3 */
114 scl->codec[0].type = GSM0808_SCT_FR1;
115 scl->codec[1].type = GSM0808_SCT_FR2;
116 scl->codec[2].type = GSM0808_SCT_FR3;
Philipp Maierf96c04a2018-09-14 16:58:55 +0200117 scl->codec[2].cfg = GSM0808_SC_CFG_DEFAULT_FR_AMR;
Philipp Maier844876f2018-07-13 09:17:07 +0200118 scl->codec[3].type = GSM0808_SCT_HR1;
119 scl->codec[4].type = GSM0808_SCT_HR3;
Philipp Maierf96c04a2018-09-14 16:58:55 +0200120 scl->codec[4].cfg = GSM0808_SC_CFG_DEFAULT_HR_AMR;
Philipp Maier844876f2018-07-13 09:17:07 +0200121 scl->len = 5;
122 break;
123 }
124}
125
126/* The channel type element which is sent to the BSC by the MSC lists all the
127 * codecs that the MSC is able to support. The following function generates
128 * a realistic permitted speech settings */
129static void make_ct_config(struct gsm0808_channel_type *ct, uint8_t config_no)
130{
131 OSMO_ASSERT(config_no < N_CONFIG_VARIANTS);
132
133 switch (config_no) {
134 case 0:
135 /* FR1 only */
136 ct->perm_spch[0] = GSM0808_PERM_FR1;
137 ct->perm_spch_len = 1;
138 break;
139 case 1:
140 /* HR1 only */
141 ct->perm_spch[0] = GSM0808_PERM_HR1;
142 ct->perm_spch_len = 1;
143 break;
144 case 2:
145 /* FR2 only */
146 ct->perm_spch[0] = GSM0808_PERM_FR2;
147 ct->perm_spch_len = 1;
148 break;
149 case 3:
150 /* FR3 only */
151 ct->perm_spch[0] = GSM0808_PERM_FR3;
152 ct->perm_spch_len = 1;
153 break;
154 case 4:
155 /* HR3 only */
156 ct->perm_spch[0] = GSM0808_PERM_HR3;
157 ct->perm_spch_len = 1;
158 break;
159 case 5:
160 /* FR1 and HR1 */
161 ct->perm_spch[0] = GSM0808_PERM_FR1;
162 ct->perm_spch[1] = GSM0808_PERM_HR1;
163 ct->perm_spch_len = 2;
164 break;
165 case 6:
166 /* FR1, FR2 and HR1 */
167 ct->perm_spch[0] = GSM0808_PERM_FR1;
168 ct->perm_spch[1] = GSM0808_PERM_FR2;
169 ct->perm_spch[2] = GSM0808_PERM_HR1;
170 ct->perm_spch_len = 3;
171 break;
172 case 7:
173 /* FR1, FR3 and HR3 */
174 ct->perm_spch[0] = GSM0808_PERM_FR1;
175 ct->perm_spch[1] = GSM0808_PERM_FR3;
176 ct->perm_spch[2] = GSM0808_PERM_HR3;
177 ct->perm_spch_len = 3;
178 break;
179 case 8:
180 /* FR1, FR2, FR3, HR1 and HR3 */
181 ct->perm_spch[0] = GSM0808_PERM_FR1;
182 ct->perm_spch[1] = GSM0808_PERM_FR2;
183 ct->perm_spch[2] = GSM0808_PERM_FR3;
184 ct->perm_spch[3] = GSM0808_PERM_HR1;
185 ct->perm_spch[4] = GSM0808_PERM_HR3;
186 ct->perm_spch_len = 5;
187 break;
188 }
189}
190
191/* Generate some realistic MSC configuration which one also could find in the
192 * real world. This configuration acts as a filter. While the MSC could in
193 * theory advertise codecs more codecs as we are able to support we have to
194 * make sure that only the codecs we have support for are considered. */
195static void make_msc_config(struct bsc_msc_data *msc, uint8_t config_no)
196{
197 /* 1 = FR1/HR1
198 * 2 = FR2/HR2
199 * 3 = FR2/HR3
200 * Note: HR2 is deprecated */
201
202 OSMO_ASSERT(config_no < N_CONFIG_VARIANTS);
203
Philipp Maier67e47c62018-09-13 12:05:51 +0200204 /* Setup an AMR configuration, this configuration is separate and does
205 * not influence other codecs than AMR */
206 msc->amr_conf.m4_75 = 1;
207 msc->amr_conf.m5_15 = 1;
208 msc->amr_conf.m5_90 = 1;
209 msc->amr_conf.m6_70 = 1;
210 msc->amr_conf.m7_40 = 1;
211 msc->amr_conf.m7_95 = 1;
212 msc->amr_conf.m10_2 = 1;
213 msc->amr_conf.m12_2 = 1;
214
Philipp Maier844876f2018-07-13 09:17:07 +0200215 switch (config_no) {
216 case 0:
217 /* FR1 only */
218 msc->audio_support[0]->ver = 1;
219 msc->audio_support[0]->hr = 0;
220 msc->audio_length = 1;
221 break;
222 case 1:
223 /* HR1 only */
224 msc->audio_support[0]->ver = 1;
225 msc->audio_support[0]->hr = 1;
226 msc->audio_length = 1;
227 break;
228 case 2:
229 /* FR2 only */
230 msc->audio_support[0]->ver = 2;
231 msc->audio_support[0]->hr = 0;
232 msc->audio_length = 1;
233 break;
234 case 3:
235 /* FR3 only */
236 msc->audio_support[0]->ver = 3;
237 msc->audio_support[0]->hr = 0;
238 msc->audio_length = 1;
239 break;
240 case 4:
241 /* HR3 only */
242 msc->audio_support[0]->ver = 3;
243 msc->audio_support[0]->hr = 1;
244 msc->audio_length = 1;
245 break;
246 case 5:
247 /* FR1 and HR1 */
248 msc->audio_support[0]->ver = 1;
249 msc->audio_support[0]->hr = 0;
250 msc->audio_support[1]->ver = 1;
251 msc->audio_support[1]->hr = 1;
252 msc->audio_length = 2;
253 break;
254 case 6:
255 /* FR1, FR2 and HR1 */
256 msc->audio_support[0]->ver = 1;
257 msc->audio_support[0]->hr = 0;
258 msc->audio_support[1]->ver = 2;
259 msc->audio_support[1]->hr = 0;
260 msc->audio_support[2]->ver = 1;
261 msc->audio_support[2]->hr = 1;
262 msc->audio_length = 3;
263 break;
264 case 7:
265 /* FR1, FR3 and HR3 */
266 msc->audio_support[0]->ver = 1;
267 msc->audio_support[0]->hr = 0;
268 msc->audio_support[1]->ver = 3;
269 msc->audio_support[1]->hr = 0;
270 msc->audio_support[2]->ver = 3;
271 msc->audio_support[2]->hr = 1;
272 msc->audio_length = 3;
273 break;
274 case 8:
275 /* FR1, FR2, FR3, HR1 and HR3 */
276 msc->audio_support[0]->ver = 1;
277 msc->audio_support[0]->hr = 0;
278 msc->audio_support[1]->ver = 2;
279 msc->audio_support[1]->hr = 0;
280 msc->audio_support[2]->ver = 3;
281 msc->audio_support[2]->hr = 0;
282 msc->audio_support[3]->ver = 1;
283 msc->audio_support[3]->hr = 1;
284 msc->audio_support[4]->ver = 3;
285 msc->audio_support[4]->hr = 1;
286 msc->audio_length = 5;
287 break;
288 }
289}
290
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200291/* Generate a realitically looking bts codec configuration */
292static void make_bts_config(struct gsm_bts *bts, uint8_t config_no)
293{
294 /* Note: FR is supported by all BTSs, so there is no flag for it */
295
Philipp Maier67e47c62018-09-13 12:05:51 +0200296 struct gsm48_multi_rate_conf *cfg;
Philipp Maierb15af632018-10-10 11:58:02 +0200297 static struct gsm_bts_trx trx;
Philipp Maier67e47c62018-09-13 12:05:51 +0200298
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200299 OSMO_ASSERT(config_no < N_CONFIG_VARIANTS);
300
301 bts->codec.hr = 0;
302 bts->codec.efr = 0;
303 bts->codec.amr = 0;
Philipp Maier67e47c62018-09-13 12:05:51 +0200304 memset(&bts->mr_full.gsm48_ie, 0, sizeof(bts->mr_full.gsm48_ie));
305 memset(&bts->mr_full.gsm48_ie, 0, sizeof(bts->mr_half.gsm48_ie));
306
307 /* Setup an AMR configuration, this configuration is separate and does
308 * not influence other codecs than AMR */
309 cfg = (struct gsm48_multi_rate_conf*) &bts->mr_full.gsm48_ie;
310 cfg->m4_75 = 1;
311 cfg->m5_15 = 1;
312 cfg->m5_90 = 1;
313 cfg->m6_70 = 1;
314 cfg->m7_40 = 1;
315 cfg->m7_95 = 1;
316 cfg->m10_2 = 1;
317 cfg->m12_2 = 1;
318 cfg = (struct gsm48_multi_rate_conf*) &bts->mr_half.gsm48_ie;
319 cfg->m4_75 = 1;
320 cfg->m5_15 = 1;
321 cfg->m5_90 = 1;
322 cfg->m6_70 = 1;
323 cfg->m7_40 = 1;
324 cfg->m7_95 = 1;
325 cfg->m10_2 = 0;
326 cfg->m12_2 = 0;
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200327
Philipp Maierb15af632018-10-10 11:58:02 +0200328 /* Initalize TRX with a TCH/F and a TCH/H channel */
329 memset(&trx, 0, sizeof(trx));
330 INIT_LLIST_HEAD(&bts->trx_list);
331 llist_add(&trx.list, &bts->trx_list);
332 trx.ts[0].pchan_from_config = GSM_PCHAN_TCH_F;
333 trx.ts[1].pchan_from_config = GSM_PCHAN_TCH_H;
334
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200335 switch (config_no) {
336 case 0:
337 /* FR1 (implicit) only */
338 break;
339 case 1:
340 /* HR1 only (+FR implicit) */
341 bts->codec.hr = 1;
342 break;
343 case 2:
344 /* FR2 only (+FR implicit) */
345 bts->codec.efr = 1;
346 break;
347 case 3:
348 /* FR3 only (+FR implicit) */
349 bts->codec.amr = 1;
350 break;
351 case 4:
352 /* HR3 only (+FR implicit) */
353 bts->codec.amr = 1;
354 break;
355 case 5:
356 /* FR1 (implicit) and HR1 */
357 bts->codec.hr = 1;
358 break;
359 case 6:
360 /* FR1 (implicit), FR2 and HR1 */
361 bts->codec.efr = 1;
362 bts->codec.hr = 1;
363 break;
364 case 7:
365 /* FR1 (implicit), FR3 and HR3 */
366 bts->codec.amr = 1;
367 break;
368 case 8:
369 /* FR1 (implicit), FR2, FR3, HR1 and HR3 */
370 bts->codec.hr = 1;
371 bts->codec.efr = 1;
372 bts->codec.amr = 1;
373 break;
374 }
375}
376
Philipp Maier844876f2018-07-13 09:17:07 +0200377/* Try execute match_codec_pref(), display input and output parameters */
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200378static int test_match_codec_pref(const struct gsm0808_channel_type *ct, const struct gsm0808_speech_codec_list *scl,
379 const struct bsc_msc_data *msc, struct gsm_bts *bts)
Philipp Maier844876f2018-07-13 09:17:07 +0200380{
381 int rc;
382 unsigned int i;
Philipp Maierbb66d102019-01-22 11:29:06 +0100383 struct channel_mode_and_rate ch_mode_rate = { };
Philipp Maier844876f2018-07-13 09:17:07 +0200384
385 printf("Determining channel mode and rate:\n");
386
387 printf(" * MS: speech codec list (%u items):\n", scl->len);
388 for (i = 0; i < scl->len; i++)
389 printf(" codec[%u]->type=%s\n", i, gsm0808_speech_codec_type_name(scl->codec[i].type));
390
391 printf(" * MSC: channel type permitted speech (%u items):\n", ct->perm_spch_len);
392 for (i = 0; i < ct->perm_spch_len; i++)
393 printf(" perm_spch[%u]=%s\n", i, gsm0808_permitted_speech_name(ct->perm_spch[i]));
394
395 printf(" * BSS: audio support settings (%u items):\n", msc->audio_length);
396 for (i = 0; i < msc->audio_length; i++)
397 if (msc->audio_support[i]->hr)
398 printf(" audio_support[%u]=HR%u\n", i, msc->audio_support[i]->ver);
399 else
400 printf(" audio_support[%u]=FR%u\n", i, msc->audio_support[i]->ver);
401
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200402 printf(" * BTS: audio support settings:\n");
403 printf(" (GSM-FR implicitly supported)\n");
404 printf(" codec->hr=%u\n", bts->codec.hr);
405 printf(" codec->efr=%u\n", bts->codec.efr);
406 printf(" codec->amr=%u\n", bts->codec.amr);
407
Philipp Maierbb66d102019-01-22 11:29:06 +0100408 rc = match_codec_pref(&ch_mode_rate, ct, scl, msc, bts, RATE_PREF_NONE);
Philipp Maierc9a4f692018-09-21 14:21:50 +0200409 printf(" * result: rc=%i, full_rate=%i, s15_s0=%04x, chan_mode=%s\n",
Neels Hofmeyr0848ff82019-03-14 22:11:45 +0000410 rc, ch_mode_rate.full_rate, ch_mode_rate.s15_s0, gsm48_chan_mode_name(ch_mode_rate.chan_mode));
Philipp Maier844876f2018-07-13 09:17:07 +0200411
412 printf("\n");
413
414 return rc;
415}
416
417/* MS, MSC and local MSC settings are the same */
418static void test_one_to_one(void)
419{
420 unsigned int i;
421 struct gsm0808_channel_type ct_msc;
422 struct gsm0808_speech_codec_list scl_ms;
423 struct bsc_msc_data msc_local;
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200424 struct gsm_bts bts_local;
Philipp Maier844876f2018-07-13 09:17:07 +0200425 int rc;
426
427 printf("============== test_one_to_one ==============\n\n");
428
429 init_msc_config(&msc_local);
430
431 for (i = 0; i < N_CONFIG_VARIANTS; i++) {
432 make_msc_config(&msc_local, i);
433 make_scl_config(&scl_ms, i);
434 make_ct_config(&ct_msc, i);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200435 make_bts_config(&bts_local, i);
436 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200437 OSMO_ASSERT(rc == 0);
438 }
439
440 free_msc_config(&msc_local);
441}
442
443/* Network supports all combinations, MS varies */
444static void test_ms(void)
445{
446 unsigned int i;
447 struct gsm0808_channel_type ct_msc;
448 struct gsm0808_speech_codec_list scl_ms;
449 struct bsc_msc_data msc_local;
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200450 struct gsm_bts bts_local;
Philipp Maier844876f2018-07-13 09:17:07 +0200451 int rc;
452
453 printf("============== test_ms ==============\n\n");
454
455 init_msc_config(&msc_local);
456
457 make_msc_config(&msc_local, 8);
458 make_ct_config(&ct_msc, 8);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200459 make_bts_config(&bts_local, 8);
Philipp Maier844876f2018-07-13 09:17:07 +0200460 for (i = 0; i < N_CONFIG_VARIANTS; i++) {
461 make_scl_config(&scl_ms, i);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200462 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200463 OSMO_ASSERT(rc == 0);
464 }
465
466 free_msc_config(&msc_local);
467}
468
469/* BSS and MS support all combinations, MSC varies */
470static void test_ct(void)
471{
472 unsigned int i;
473 struct gsm0808_channel_type ct_msc;
474 struct gsm0808_speech_codec_list scl_ms;
475 struct bsc_msc_data msc_local;
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200476 struct gsm_bts bts_local;
Philipp Maier844876f2018-07-13 09:17:07 +0200477 int rc;
478
479 printf("============== test_ct ==============\n\n");
480
481 init_msc_config(&msc_local);
482
483 make_msc_config(&msc_local, 8);
484 make_scl_config(&scl_ms, 8);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200485 make_bts_config(&bts_local, 8);
Philipp Maier844876f2018-07-13 09:17:07 +0200486 for (i = 0; i < N_CONFIG_VARIANTS; i++) {
487 make_ct_config(&ct_msc, i);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200488 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200489 OSMO_ASSERT(rc == 0);
490 }
491
492 free_msc_config(&msc_local);
493}
494
495/* MSC and MS support all combinations, BSS varies */
496static void test_msc(void)
497{
498 unsigned int i;
499 struct gsm0808_channel_type ct_msc;
500 struct gsm0808_speech_codec_list scl_ms;
501 struct bsc_msc_data msc_local;
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200502 struct gsm_bts bts_local;
Philipp Maier844876f2018-07-13 09:17:07 +0200503 int rc;
504
505 printf("============== test_msc ==============\n\n");
506
507 init_msc_config(&msc_local);
508
509 make_ct_config(&ct_msc, 8);
510 make_scl_config(&scl_ms, 8);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200511 make_bts_config(&bts_local, 8);
Philipp Maier844876f2018-07-13 09:17:07 +0200512 for (i = 0; i < N_CONFIG_VARIANTS; i++) {
513 make_msc_config(&msc_local, 8);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200514 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200515 OSMO_ASSERT(rc == 0);
516 }
517
518 free_msc_config(&msc_local);
519}
520
521/* Some mixed configurations that are supposed to work */
522static void test_selected_working(void)
523{
524 struct gsm0808_channel_type ct_msc;
525 struct gsm0808_speech_codec_list scl_ms;
526 struct bsc_msc_data msc_local;
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200527 struct gsm_bts bts_local;
Philipp Maier844876f2018-07-13 09:17:07 +0200528 int rc;
529
530 printf("============== test_selected_working ==============\n\n");
531
532 init_msc_config(&msc_local);
533
534 make_scl_config(&scl_ms, 6);
535 make_ct_config(&ct_msc, 5);
536 make_msc_config(&msc_local, 7);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200537 make_bts_config(&bts_local, 8);
538 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200539 OSMO_ASSERT(rc == 0);
540
541 make_scl_config(&scl_ms, 0);
542 make_ct_config(&ct_msc, 5);
543 make_msc_config(&msc_local, 7);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200544 make_bts_config(&bts_local, 8);
545 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200546 OSMO_ASSERT(rc == 0);
547
548 make_scl_config(&scl_ms, 1);
549 make_ct_config(&ct_msc, 5);
550 make_msc_config(&msc_local, 6);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200551 make_bts_config(&bts_local, 8);
552 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
553 OSMO_ASSERT(rc == 0);
554
555 make_scl_config(&scl_ms, 6);
556 make_ct_config(&ct_msc, 5);
557 make_msc_config(&msc_local, 7);
558 make_bts_config(&bts_local, 4);
559 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
560 OSMO_ASSERT(rc == 0);
561
562 make_scl_config(&scl_ms, 0);
563 make_ct_config(&ct_msc, 5);
564 make_msc_config(&msc_local, 7);
565 make_bts_config(&bts_local, 2);
566 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
567 OSMO_ASSERT(rc == 0);
568
569 make_scl_config(&scl_ms, 1);
570 make_ct_config(&ct_msc, 5);
571 make_msc_config(&msc_local, 6);
572 make_bts_config(&bts_local, 1);
573 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200574 OSMO_ASSERT(rc == 0);
575
576 free_msc_config(&msc_local);
577}
578
579/* Some mixed configurations that can not work */
580static void test_selected_non_working(void)
581{
582 struct gsm0808_channel_type ct_msc;
583 struct gsm0808_speech_codec_list scl_ms;
584 struct bsc_msc_data msc_local;
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200585 struct gsm_bts bts_local;
Philipp Maier844876f2018-07-13 09:17:07 +0200586 int rc;
587
588 printf("============== test_selected_non_working ==============\n\n");
589
590 init_msc_config(&msc_local);
591
592 make_scl_config(&scl_ms, 1);
593 make_ct_config(&ct_msc, 5);
594 make_msc_config(&msc_local, 7);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200595 make_bts_config(&bts_local, 8);
596 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200597 OSMO_ASSERT(rc == -1);
598
599 make_scl_config(&scl_ms, 1);
600 make_ct_config(&ct_msc, 5);
601 make_msc_config(&msc_local, 7);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200602 make_bts_config(&bts_local, 8);
603 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200604 OSMO_ASSERT(rc == -1);
605
606 make_scl_config(&scl_ms, 1);
607 make_ct_config(&ct_msc, 4);
608 make_msc_config(&msc_local, 6);
Philipp Maier5bc43cd2018-07-13 16:14:18 +0200609 make_bts_config(&bts_local, 8);
610 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
611 OSMO_ASSERT(rc == -1);
612
613 make_scl_config(&scl_ms, 1);
614 make_ct_config(&ct_msc, 2);
615 make_msc_config(&msc_local, 7);
616 make_bts_config(&bts_local, 8);
617 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
618 OSMO_ASSERT(rc == -1);
619
620 make_scl_config(&scl_ms, 1);
621 make_ct_config(&ct_msc, 5);
622 make_msc_config(&msc_local, 4);
623 make_bts_config(&bts_local, 8);
624 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
625 OSMO_ASSERT(rc == -1);
626
627 make_scl_config(&scl_ms, 8);
628 make_ct_config(&ct_msc, 4);
629 make_msc_config(&msc_local, 6);
630 make_bts_config(&bts_local, 7);
631 rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local);
Philipp Maier844876f2018-07-13 09:17:07 +0200632 OSMO_ASSERT(rc == -1);
633
634 free_msc_config(&msc_local);
635}
636
Philipp Maier67e47c62018-09-13 12:05:51 +0200637/* Try execute bss_supp_codec_list(), display input and output parameters */
638static void test_gen_bss_supported_codec_list(const struct bsc_msc_data *msc, struct gsm_bts *bts)
639{
640 unsigned int i;
641 struct gsm0808_speech_codec_list scl;
642
643 printf("Determining Codec List (BSS Supported):\n");
644
645 printf(" * BSS: audio support settings (%u items):\n", msc->audio_length);
646 for (i = 0; i < msc->audio_length; i++)
647 if (msc->audio_support[i]->hr)
648 printf(" audio_support[%u]=HR%u\n", i, msc->audio_support[i]->ver);
649 else
650 printf(" audio_support[%u]=FR%u\n", i, msc->audio_support[i]->ver);
651
652 printf(" * BTS: audio support settings:\n");
653 printf(" (GSM-FR implicitly supported)\n");
654 printf(" codec->hr=%u\n", bts->codec.hr);
655 printf(" codec->efr=%u\n", bts->codec.efr);
656 printf(" codec->amr=%u\n", bts->codec.amr);
657
658 gen_bss_supported_codec_list(&scl, msc, bts);
659
660 printf(" * result: speech codec list (%u items):\n", scl.len);
661 for (i = 0; i < scl.len; i++) {
662 printf(" codec[%u]->type=%s", i, gsm0808_speech_codec_type_name(scl.codec[i].type));
663 if (msc->audio_support[i]->ver == 3)
664 printf(" S15-S0=%04x", scl.codec[i].cfg);
665 printf("\n");
666 }
667 printf("\n");
668}
669
670/* Test gen_bss_supported_codec_list() with some mixed configurations */
671static void test_gen_bss_supported_codec_list_cfgs(void)
672{
673 struct bsc_msc_data msc_local;
674 struct gsm_bts bts_local;
675 uint8_t i;
676 uint8_t k;
677
678 printf("============== test_gen_bss_supp_codec_list_cfgs ==============\n\n");
679 init_msc_config(&msc_local);
680
681 for (i = 0; i < N_CONFIG_VARIANTS; i++) {
682 for (k = 0; k < N_CONFIG_VARIANTS; k++) {
683 make_msc_config(&msc_local, i);
684 make_bts_config(&bts_local, k);
685 printf("MSC config: %u, BTS config: %u\n", i, k);
686 test_gen_bss_supported_codec_list(&msc_local, &bts_local);
687 }
688 }
689
690 free_msc_config(&msc_local);
691}
692
Philipp Maier844876f2018-07-13 09:17:07 +0200693static const struct log_info_cat log_categories[] = {
694 [DMSC] = {
695 .name = "DMSC",
696 .description = "Mobile Switching Center",
697 .enabled = 1,.loglevel = LOGL_NOTICE,
698 },
699};
700
701static const struct log_info log_info = {
702 .cat = log_categories,
703 .num_cat = ARRAY_SIZE(log_categories),
704};
705
706int main(int argc, char **argv)
707{
708 ctx = talloc_named_const(NULL, 0, "codec_pref_test");
709 msgb_talloc_ctx_init(ctx, 0);
710 osmo_init_logging2(ctx, &log_info);
711
712 test_one_to_one();
713 test_ms();
714 test_ct();
715 test_msc();
716 test_selected_working();
717 test_selected_non_working();
Philipp Maier67e47c62018-09-13 12:05:51 +0200718 test_gen_bss_supported_codec_list_cfgs();
Philipp Maier844876f2018-07-13 09:17:07 +0200719
720 printf("Testing execution completed.\n");
721 talloc_free(ctx);
722 return 0;
723}