Add VTY command to specify default speech codec
In order to have the MNCC application reliably decide on the codec type, it needs to know if we are running on a TCH/F or TCH/H. Thus, we pass lchan_mode as a new parameter to the 'struct gsm_mncc'
This commit is contained in:
parent
6b353778c4
commit
ab386e6120
|
@ -11,7 +11,7 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
|
|||
gprs_ns_frgre.h auth.h osmo_msc.h bsc_msc.h bsc_nat.h \
|
||||
osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h \
|
||||
osmo_msc_data.h osmo_bsc_grace.h sms_queue.h abis_om2000.h \
|
||||
bss.h gsm_data_shared.h control_cmd.h ipaccess.h
|
||||
bss.h gsm_data_shared.h control_cmd.h ipaccess.h mncc_int.h
|
||||
|
||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
|
||||
openbscdir = $(includedir)/openbsc
|
||||
|
|
|
@ -148,6 +148,7 @@ struct gsm_mncc {
|
|||
int emergency;
|
||||
char imsi[16];
|
||||
|
||||
unsigned char lchan_type;
|
||||
unsigned char lchan_mode;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef _MNCC_INT_H
|
||||
#define _MNCC_INT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct mncc_int {
|
||||
uint8_t def_codec[2];
|
||||
};
|
||||
|
||||
extern struct mncc_int mncc_int;
|
||||
|
||||
#endif
|
|
@ -35,6 +35,7 @@ enum bsc_vty_node {
|
|||
OM2K_NODE,
|
||||
TRUNK_NODE,
|
||||
PGROUP_NODE,
|
||||
MNCC_INT_NODE,
|
||||
};
|
||||
|
||||
extern int bsc_vty_is_config_node(struct vty *vty, int node);
|
||||
|
|
|
@ -86,12 +86,11 @@ enum node_type bsc_vty_go_parent(struct vty *vty)
|
|||
case PGROUP_NODE:
|
||||
vty->node = NAT_NODE;
|
||||
break;
|
||||
case MSC_NODE:
|
||||
vty->node = CONFIG_NODE;
|
||||
break;
|
||||
case TRUNK_NODE:
|
||||
vty->node = MGCP_NODE;
|
||||
break;
|
||||
case MSC_NODE:
|
||||
case MNCC_INT_NODE:
|
||||
default:
|
||||
vty->node = CONFIG_NODE;
|
||||
}
|
||||
|
@ -161,6 +160,7 @@ gDEFUN(ournode_exit,
|
|||
vty->index = NULL;
|
||||
break;
|
||||
case MSC_NODE:
|
||||
case MNCC_INT_NODE:
|
||||
vty->node = CONFIG_NODE;
|
||||
break;
|
||||
case TRUNK_NODE:
|
||||
|
@ -197,6 +197,7 @@ gDEFUN(ournode_end,
|
|||
case NAT_BSC_NODE:
|
||||
case PGROUP_NODE:
|
||||
case MSC_NODE:
|
||||
case MNCC_INT_NODE:
|
||||
vty_config_unlock(vty);
|
||||
vty->node = ENABLE_NODE;
|
||||
vty->index = NULL;
|
||||
|
|
|
@ -1839,6 +1839,8 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
|
|||
|
||||
memset(&setup, 0, sizeof(struct gsm_mncc));
|
||||
setup.callref = trans->callref;
|
||||
if (trans->conn && trans->conn->lchan)
|
||||
setup.lchan_type = trans->conn->lchan->type;
|
||||
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
|
||||
/* emergency setup is identified by msg_type */
|
||||
if (msg_type == GSM48_MT_CC_EMERG_SETUP)
|
||||
|
@ -1995,6 +1997,8 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
|
|||
|
||||
memset(&call_conf, 0, sizeof(struct gsm_mncc));
|
||||
call_conf.callref = trans->callref;
|
||||
if (trans->conn && trans->conn->lchan)
|
||||
call_conf.lchan_type = trans->conn->lchan->type;
|
||||
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
|
||||
#if 0
|
||||
/* repeat */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <openbsc/gsm_04_08.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/mncc.h>
|
||||
#include <openbsc/mncc_int.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/transaction.h>
|
||||
|
@ -41,6 +42,10 @@ static LLIST_HEAD(call_list);
|
|||
|
||||
static uint32_t new_callref = 0x00000001;
|
||||
|
||||
struct mncc_int mncc_int = {
|
||||
.def_codec = { GSM48_CMODE_SPEECH_EFR, GSM48_CMODE_SPEECH_V1 },
|
||||
};
|
||||
|
||||
static void free_call(struct gsm_call *call)
|
||||
{
|
||||
llist_del(&call->entry);
|
||||
|
@ -60,6 +65,15 @@ static struct gsm_call *get_call_ref(uint32_t callref)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static uint8_t determine_lchan_mode(struct gsm_mncc *setup)
|
||||
{
|
||||
/* FIXME: check codec capabilities of the phone */
|
||||
|
||||
if (setup->lchan_type == GSM_LCHAN_TCH_F)
|
||||
return mncc_int.def_codec[0];
|
||||
else
|
||||
return mncc_int.def_codec[1];
|
||||
}
|
||||
|
||||
/* on incoming call, look up database and send setup to remote subscr. */
|
||||
static int mncc_setup_ind(struct gsm_call *call, int msg_type,
|
||||
|
@ -112,7 +126,7 @@ static int mncc_setup_ind(struct gsm_call *call, int msg_type,
|
|||
/* modify mode */
|
||||
memset(&mncc, 0, sizeof(struct gsm_mncc));
|
||||
mncc.callref = call->callref;
|
||||
mncc.lchan_mode = GSM48_CMODE_SPEECH_EFR;
|
||||
mncc.lchan_mode = determine_lchan_mode(setup);
|
||||
DEBUGP(DMNCC, "(call %x) Modify channel mode.\n", call->callref);
|
||||
mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, &mncc);
|
||||
|
||||
|
@ -346,7 +360,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
|
|||
break;
|
||||
case MNCC_CALL_CONF_IND:
|
||||
/* we now need to MODIFY the channel */
|
||||
data->lchan_mode = GSM48_CMODE_SPEECH_EFR;
|
||||
data->lchan_mode = determine_lchan_mode(data);
|
||||
mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, data);
|
||||
break;
|
||||
case MNCC_ALERT_IND:
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <openbsc/gsm_04_80.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/sms_queue.h>
|
||||
#include <openbsc/mncc_int.h>
|
||||
|
||||
extern struct gsm_network *gsmnet_from_vty(struct vty *v);
|
||||
|
||||
|
@ -762,6 +763,69 @@ DEFUN(smsqueue_fail,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DEFUN(cfg_mncc_int, cfg_mncc_int_cmd,
|
||||
"mncc-int", "Configure internal MNCC handler")
|
||||
{
|
||||
vty->node = MNCC_INT_NODE;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static struct cmd_node mncc_int_node = {
|
||||
MNCC_INT_NODE,
|
||||
"%s(mncc-int)#",
|
||||
1,
|
||||
};
|
||||
|
||||
static const struct value_string tchf_codec_names[] = {
|
||||
{ GSM48_CMODE_SPEECH_V1, "fr" },
|
||||
{ GSM48_CMODE_SPEECH_EFR, "efr" },
|
||||
{ GSM48_CMODE_SPEECH_AMR, "amr" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const struct value_string tchh_codec_names[] = {
|
||||
{ GSM48_CMODE_SPEECH_V1, "hr" },
|
||||
{ GSM48_CMODE_SPEECH_AMR, "amr" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static int config_write_mncc_int(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, "mncc-int%s", VTY_NEWLINE);
|
||||
vty_out(vty, " default-codec tch-f %s%s",
|
||||
get_value_string(tchf_codec_names, mncc_int.def_codec[0]),
|
||||
VTY_NEWLINE);
|
||||
vty_out(vty, " default-codec tch-h %s%s",
|
||||
get_value_string(tchh_codec_names, mncc_int.def_codec[1]),
|
||||
VTY_NEWLINE);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(mnccint_def_codec_f,
|
||||
mnccint_def_codec_f_cmd,
|
||||
"default-codec tch-f (fr|efr|amr)",
|
||||
"Set default codec\n" "Codec for TCH/F\n"
|
||||
"Full-Rate\n" "Enhanced Full-Rate\n" "Adaptive Multi-Rate\n")
|
||||
{
|
||||
mncc_int.def_codec[0] = get_string_value(tchf_codec_names, argv[0]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(mnccint_def_codec_h,
|
||||
mnccint_def_codec_h_cmd,
|
||||
"default-codec tch-h (hr|amr)",
|
||||
"Set default codec\n" "Codec for TCH/H\n"
|
||||
"Half-Rate\n" "Adaptive Multi-Rate\n")
|
||||
{
|
||||
mncc_int.def_codec[1] = get_string_value(tchh_codec_names, argv[0]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int bsc_vty_init_extra(void)
|
||||
{
|
||||
osmo_signal_register_handler(SS_SCALL, scall_cbfn, NULL);
|
||||
|
@ -794,5 +858,11 @@ int bsc_vty_init_extra(void)
|
|||
install_element(ENABLE_NODE, &smsqueue_fail_cmd);
|
||||
install_element(ENABLE_NODE, &subscriber_send_pending_sms_cmd);
|
||||
|
||||
install_element(CONFIG_NODE, &cfg_mncc_int_cmd);
|
||||
install_node(&mncc_int_node, config_write_mncc_int);
|
||||
install_default(MNCC_INT_NODE);
|
||||
install_element(MNCC_INT_NODE, &mnccint_def_codec_f_cmd);
|
||||
install_element(MNCC_INT_NODE, &mnccint_def_codec_h_cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue