diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/settings.h | 62 | ||||
-rw-r--r-- | src/host/layer23/src/common/settings.c | 3 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/mnccms.c | 128 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/vty_interface.c | 113 |
4 files changed, 197 insertions, 109 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/settings.h b/src/host/layer23/include/osmocom/bb/common/settings.h index a1c9b3ee..1d3e53df 100644 --- a/src/host/layer23/include/osmocom/bb/common/settings.h +++ b/src/host/layer23/include/osmocom/bb/common/settings.h @@ -117,24 +117,58 @@ struct test_sim_settings { } locigprs; }; -enum data_call_type { - DATA_CALL_TYPE_ISDN, - DATA_CALL_TYPE_ANALOG, -}; - -enum data_call_rate { - DATA_CALL_RATE_V110_300, - DATA_CALL_RATE_V110_1200, - DATA_CALL_RATE_V110_2400, - DATA_CALL_RATE_V110_4800, - DATA_CALL_RATE_V110_9600, - DATA_CALL_RATE_V110_14400, +/* Data (CSD) call type and rate, values like in the '<speed>' part of 'AT+CBST'. + * See 3GPP TS 27.007, section 6.7 "Select bearer service type +CBST". */ +enum data_call_type_rate { + DATA_CALL_TR_AUTO = 0, + DATA_CALL_TR_V21_300 = 1, + DATA_CALL_TR_V22_1200 = 2, + DATA_CALL_TR_V23_1200_75 = 3, + DATA_CALL_TR_V22bis_2400 = 4, + DATA_CALL_TR_V26ter_2400 = 5, + DATA_CALL_TR_V32_4800 = 6, + DATA_CALL_TR_V32_9600 = 7, + DATA_CALL_TR_V34_9600 = 12, + DATA_CALL_TR_V34_14400 = 14, + DATA_CALL_TR_V34_19200 = 15, + DATA_CALL_TR_V34_28800 = 16, + DATA_CALL_TR_V34_33600 = 17, + DATA_CALL_TR_V120_1200 = 34, + DATA_CALL_TR_V120_2400 = 36, + DATA_CALL_TR_V120_4800 = 38, + DATA_CALL_TR_V120_9600 = 39, + DATA_CALL_TR_V120_14400 = 43, + DATA_CALL_TR_V120_19200 = 47, + DATA_CALL_TR_V120_28800 = 48, + DATA_CALL_TR_V120_38400 = 49, + DATA_CALL_TR_V120_48000 = 50, + DATA_CALL_TR_V120_56000 = 51, + DATA_CALL_TR_V110_300 = 65, + DATA_CALL_TR_V110_1200 = 66, + DATA_CALL_TR_V110_2400 = 68, + DATA_CALL_TR_V110_4800 = 70, + DATA_CALL_TR_V110_9600 = 71, + DATA_CALL_TR_V110_14400 = 75, + DATA_CALL_TR_V110_19200 = 79, + DATA_CALL_TR_V110_28800 = 80, + DATA_CALL_TR_V110_38400 = 81, + DATA_CALL_TR_V110_48000 = 82, + DATA_CALL_TR_V110_56000 = 83, + DATA_CALL_TR_V110_64000 = 84, + DATA_CALL_TR_BTR_56000 = 115, + DATA_CALL_TR_BTR_64000 = 116, + DATA_CALL_TR_PIAFS32k_32000 = 120, + DATA_CALL_TR_PIAFS64k_64000 = 121, + DATA_CALL_TR_MMEDIA_28800 = 130, + DATA_CALL_TR_MMEDIA_32000 = 131, + DATA_CALL_TR_MMEDIA_33600 = 132, + DATA_CALL_TR_MMEDIA_56000 = 133, + DATA_CALL_TR_MMEDIA_64000 = 134, }; /* Data (CSD) call parameters */ struct data_call_params { - enum data_call_type type; - enum data_call_rate rate; + enum data_call_type_rate type_rate; enum gsm48_bcap_transp transp; /* async call parameters */ diff --git a/src/host/layer23/src/common/settings.c b/src/host/layer23/src/common/settings.c index bc5d115f..6bc56340 100644 --- a/src/host/layer23/src/common/settings.c +++ b/src/host/layer23/src/common/settings.c @@ -136,8 +136,7 @@ int gsm_settings_init(struct osmocom_ms *ms) set->uplink_release_local = true; set->call_params.data = (struct data_call_params) { - .type = DATA_CALL_TYPE_ISDN, - .rate = DATA_CALL_RATE_V110_9600, + .type_rate = DATA_CALL_TR_V110_9600, .transp = GSM48_BCAP_TR_TRANSP, /* async call parameters (8-N-1) */ diff --git a/src/host/layer23/src/mobile/mnccms.c b/src/host/layer23/src/mobile/mnccms.c index fa3b284e..95d7f0d6 100644 --- a/src/host/layer23/src/mobile/mnccms.c +++ b/src/host/layer23/src/mobile/mnccms.c @@ -199,12 +199,95 @@ static void mncc_set_bcap_speech(struct gsm_mncc *mncc, mncc->bearer_cap.mode = GSM48_BCAP_TMOD_CIRCUIT; } +static const struct bcap_data_set { + enum gsm48_bcap_ra ra; + enum gsm48_bcap_interm_rate ir; + enum gsm48_bcap_user_rate ur; + enum gsm48_bcap_modem_type mt; +} bcap_data_set_map[] = { + [DATA_CALL_TR_V21_300] = { + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_300, + .mt = GSM48_BCAP_MT_V21, + }, + [DATA_CALL_TR_V22_1200] = { + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_1200, + .mt = GSM48_BCAP_MT_V22, + }, + [DATA_CALL_TR_V23_1200_75] = { + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_1200_75, + .mt = GSM48_BCAP_MT_V23, + }, + [DATA_CALL_TR_V22bis_2400] = { + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_2400, + .mt = GSM48_BCAP_MT_V22bis, + }, + [DATA_CALL_TR_V26ter_2400] = { + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_2400, + .mt = GSM48_BCAP_MT_V26ter, + }, + [DATA_CALL_TR_V32_4800] = { + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_4800, + .mt = GSM48_BCAP_MT_V32, + }, + [DATA_CALL_TR_V32_9600] = { + .ir = GSM48_BCAP_IR_16k, + .ur = GSM48_BCAP_UR_9600, + .mt = GSM48_BCAP_MT_V32, + }, +#if 0 + [DATA_CALL_TR_V34_9600] = { + .ir = GSM48_BCAP_IR_16k, + .ur = GSM48_BCAP_UR_9600, + .mt = GSM48_BCAP_MT_V34, /* XXX */ + }, +#endif + [DATA_CALL_TR_V110_300] = { + .ra = GSM48_BCAP_RA_V110_X30, + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_300, + }, + [DATA_CALL_TR_V110_1200] = { + .ra = GSM48_BCAP_RA_V110_X30, + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_1200, + }, + [DATA_CALL_TR_V110_2400] = { + .ra = GSM48_BCAP_RA_V110_X30, + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_2400, + }, + [DATA_CALL_TR_V110_4800] = { + .ra = GSM48_BCAP_RA_V110_X30, + .ir = GSM48_BCAP_IR_8k, + .ur = GSM48_BCAP_UR_4800, + }, + [DATA_CALL_TR_V110_9600] = { + .ra = GSM48_BCAP_RA_V110_X30, + .ir = GSM48_BCAP_IR_16k, + .ur = GSM48_BCAP_UR_9600, + }, +}; + static void mncc_set_bcap_data(struct gsm_mncc *mncc, const struct gsm_settings *set, enum gsm_call_type call_type) { const struct data_call_params *cp = &set->call_params.data; struct gsm_mncc_bearer_cap *bcap = &mncc->bearer_cap; + const struct bcap_data_set *ds; + + OSMO_ASSERT(cp->type_rate < ARRAY_SIZE(bcap_data_set_map)); + ds = &bcap_data_set_map[cp->type_rate]; + if (ds->ir == 0 && ds->ur == 0) { + LOGP(DMNCC, LOGL_ERROR, "AT+CBST=%d is not supported\n", cp->type_rate); + return; + } mncc->fields |= MNCC_F_BEARER_CAP; @@ -214,16 +297,18 @@ static void mncc_set_bcap_data(struct gsm_mncc *mncc, .coding = GSM48_BCAP_CODING_GSM_STD, /* .radio is set below */ .data = { - /* TODO: make these fields configurable via *set */ - .rate_adaption = GSM48_BCAP_RA_V110_X30, .sig_access = GSM48_BCAP_SA_I440_I450, - .async = cp->is_async, + .rate_adaption = ds->ra, + .interm_rate = ds->ir, + .user_rate = ds->ur, + .modem_type = ds->mt, .transp = cp->transp, + + /* async call params */ + .async = cp->is_async, .nr_data_bits = cp->nr_data_bits, .nr_stop_bits = cp->nr_stop_bits, .parity = cp->parity, - /* .user_rate is set below */ - /* .interm_rate is set below */ }, }; @@ -242,9 +327,9 @@ static void mncc_set_bcap_data(struct gsm_mncc *mncc, /* Information transfer capability (octet 3) */ switch (call_type) { case GSM_CALL_T_DATA: - if (cp->type == DATA_CALL_TYPE_ISDN) + if (ds->mt == GSM48_BCAP_MT_NONE) bcap->transfer = GSM_MNCC_BCAP_UNR_DIG; - else /* == DATA_CALL_TYPE_ANALOG */ + else /* analog modem */ bcap->transfer = GSM_MNCC_BCAP_AUDIO; break; case GSM_CALL_T_DATA_FAX: @@ -255,35 +340,6 @@ static void mncc_set_bcap_data(struct gsm_mncc *mncc, OSMO_ASSERT(0); } - /* User rate (octet 6a) */ - switch (cp->rate) { - case DATA_CALL_RATE_V110_300: - bcap->data.user_rate = GSM48_BCAP_UR_300; - bcap->data.interm_rate = GSM48_BCAP_IR_8k; - break; - case DATA_CALL_RATE_V110_1200: - bcap->data.user_rate = GSM48_BCAP_UR_1200; - bcap->data.interm_rate = GSM48_BCAP_IR_8k; - break; - case DATA_CALL_RATE_V110_2400: - bcap->data.user_rate = GSM48_BCAP_UR_2400; - bcap->data.interm_rate = GSM48_BCAP_IR_8k; - break; - case DATA_CALL_RATE_V110_4800: - bcap->data.user_rate = GSM48_BCAP_UR_4800; - bcap->data.interm_rate = GSM48_BCAP_IR_8k; - break; - case DATA_CALL_RATE_V110_9600: - bcap->data.user_rate = GSM48_BCAP_UR_9600; - bcap->data.interm_rate = GSM48_BCAP_IR_16k; - break; - case DATA_CALL_RATE_V110_14400: /* TODO: the bcap encoder does not support 14400 bps */ - LOGP(DMNCC, LOGL_INFO, " support for 14400 bps is incomplete\n"); - bcap->data.user_rate = GSM48_BCAP_UR_9600; - bcap->data.interm_rate = GSM48_BCAP_IR_16k; - break; - } - /* FAX calls are special (see 3GPP TS 24.008, Annex D.3) */ if (call_type == GSM_CALL_T_DATA_FAX) { bcap->data.rate_adaption = GSM48_BCAP_RA_NONE; diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index 4c2263a2..edff5841 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -644,49 +644,57 @@ DEFUN(call_dtmf, call_dtmf_cmd, CALL_PARAMS_CMD_DESC \ "Parameters for data calls\n" -DEFUN(call_params_data_type, - call_params_data_type_cmd, - CALL_PARAMS_DATA_CMD " type (isdn|analog-modem)", - CALL_PARAMS_DATA_CMD_DESC - "Data call type (does not apply to FAX calls)\n" - "ISDN (Unrestricted Digital Information)\n" - "Analog modem (3.1 kHz audio, ex PLMN)\n") +/* only supported rate/type ('<speed>' in AT+CBST) values are listed here */ +static const struct value_string data_type_rate_descs[] = { +#if 0 + /* TODO: rates below 2400 bps are not supported */ + { DATA_CALL_TR_V21_300, "300 bps (V.21)" }, + { DATA_CALL_TR_V22_1200, "1200 bps (V.22)" }, + { DATA_CALL_TR_V23_1200_75, "1200/75 bps (V.23)" }, +#endif + { DATA_CALL_TR_V22bis_2400, "2400 bps (V.22bis)" }, + { DATA_CALL_TR_V26ter_2400, "2400 bps (V.26ter)" }, + { DATA_CALL_TR_V32_4800, "4800 bps (V.32)" }, + { DATA_CALL_TR_V32_9600, "9600 bps (V.32)" }, + { DATA_CALL_TR_V34_9600, "9600 bps (V.34)" }, +#if 0 + /* TODO: rates below 2400 bps are not supported */ + { DATA_CALL_TR_V110_300, "300 bps (V.110)" }, + { DATA_CALL_TR_V110_1200, "1200 bps (V.110)" }, +#endif + { DATA_CALL_TR_V110_2400, "2400 bps (V.110 or X.31 flag stuffing)" }, + { DATA_CALL_TR_V110_4800, "4800 bps (V.110 or X.31 flag stuffing)" }, + { DATA_CALL_TR_V110_9600, "9600 bps (V.110 or X.31 flag stuffing)" }, +#if 0 + /* TODO: 14400 bps is not supported */ + { DATA_CALL_TR_V110_14400, "14400 bps (V.110 or X.31 flag stuffing)" }, +#endif + { 0, NULL } +}; + +static char *call_params_data_type_rate_cmd_string(void *ctx) { - struct osmocom_ms *ms; - struct gsm_settings *set; - struct data_call_params *cp; - ms = l23_vty_get_ms(argv[0], vty); - if (!ms) - return CMD_WARNING; - set = &ms->settings; - cp = &set->call_params.data; + const struct value_string *vs; + char *string; - if (!strcmp(argv[1], "isdn")) - cp->type = DATA_CALL_TYPE_ISDN; - else if (!strcmp(argv[1], "analog-modem")) - cp->type = DATA_CALL_TYPE_ANALOG; - else /* should not happen */ - return CMD_WARNING; + string = talloc_asprintf(ctx, CALL_PARAMS_DATA_CMD " type-rate ("); + for (vs = &data_type_rate_descs[0]; vs->value || vs->str; vs++) + string = talloc_asprintf_append(string, "%u|", vs->value); + string[strlen(string) - 1] = ')'; - return CMD_SUCCESS; + return string; } -DEFUN(call_params_data_rate, - call_params_data_rate_cmd, - CALL_PARAMS_DATA_CMD " rate (65|66|68|70|71|75)", - CALL_PARAMS_DATA_CMD_DESC - "Data rate (values like in AT+CBST)\n" - "300 bps (V.110)\n" - "1200 bps (V.110)\n" - "2400 bps (V.110 or X.31 flag stuffing)\n" - "4800 bps (V.110 or X.31 flag stuffing)\n" - "9600 bps (V.110 or X.31 flag stuffing)\n" - "14400 bps (V.110 or X.31 flag stuffing)\n") +DEFUN(call_params_data_type_rate, + call_params_data_type_rate_cmd, + CALL_PARAMS_DATA_CMD /* generated */, + CALL_PARAMS_DATA_CMD_DESC /* generated */) { struct osmocom_ms *ms; struct gsm_settings *set; struct data_call_params *cp; + int val; ms = l23_vty_get_ms(argv[0], vty); if (!ms) @@ -694,28 +702,9 @@ DEFUN(call_params_data_rate, set = &ms->settings; cp = &set->call_params.data; - switch (atoi(argv[1])) { - case 65: - cp->rate = DATA_CALL_RATE_V110_300; - break; - case 66: - cp->rate = DATA_CALL_RATE_V110_1200; - break; - case 68: - cp->rate = DATA_CALL_RATE_V110_2400; - break; - case 70: - cp->rate = DATA_CALL_RATE_V110_4800; - break; - case 71: - cp->rate = DATA_CALL_RATE_V110_9600; - break; - case 75: - cp->rate = DATA_CALL_RATE_V110_14400; - break; - default: /* should not happen */ - return CMD_WARNING; - } + val = atoi(argv[1]); + OSMO_ASSERT(get_value_string_or_null(data_type_rate_descs, val) != NULL); + cp->type_rate = (enum data_call_type_rate)val; return CMD_SUCCESS; } @@ -2879,6 +2868,17 @@ int ms_vty_init(void) { int rc; + call_params_data_type_rate_cmd.string = + call_params_data_type_rate_cmd_string(NULL); + + call_params_data_type_rate_cmd.doc = + vty_cmd_string_from_valstr(NULL, + data_type_rate_descs, + CALL_PARAMS_DATA_CMD_DESC + "Type and rate (values like in AT+CBST; " + "see 3GPP TS 27.007, section 6.7)\n", + "\n", "", 0); + call_params_data_async_parity_cmd.string = vty_cmd_string_from_valstr(NULL, async_parity_names, @@ -2915,8 +2915,7 @@ int ms_vty_init(void) install_element(ENABLE_NODE, &call_cmd); install_element(ENABLE_NODE, &call_retr_cmd); install_element(ENABLE_NODE, &call_dtmf_cmd); - install_element(ENABLE_NODE, &call_params_data_type_cmd); - install_element(ENABLE_NODE, &call_params_data_rate_cmd); + install_element(ENABLE_NODE, &call_params_data_type_rate_cmd); install_element(ENABLE_NODE, &call_params_data_ce_cmd); install_element(ENABLE_NODE, &call_params_data_sync_async_cmd); install_element(ENABLE_NODE, &call_params_data_async_nr_stop_bits_cmd); |