summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/host/layer23/include/osmocom/bb/common/settings.h62
-rw-r--r--src/host/layer23/src/common/settings.c3
-rw-r--r--src/host/layer23/src/mobile/mnccms.c128
-rw-r--r--src/host/layer23/src/mobile/vty_interface.c113
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);