From c227fa7213c6edcc8faad8a6fbed79f158762340 Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Tue, 26 Dec 2017 21:37:36 +0100 Subject: implement bearer cap support on CALL_PROCEEDING --- src/call.h | 3 +++ src/mncc.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/call.h b/src/call.h index 5a11f6c..97c7db1 100644 --- a/src/call.h +++ b/src/call.h @@ -129,6 +129,9 @@ struct mncc_call_leg { struct osmo_timer_list cmd_timeout; int rsp_wanted; + int bearer_cap_valid; + struct gsm_mncc_bearer_cap bearer_cap; + struct mncc_connection *conn; }; diff --git a/src/mncc.c b/src/mncc.c index ffc6223..75f2c31 100644 --- a/src/mncc.c +++ b/src/mncc.c @@ -339,12 +339,26 @@ static void close_connection(struct mncc_connection *conn) conn->on_disconnect(conn); } +static void send_mncc_call_proc_req(struct mncc_call_leg *leg) +{ + struct gsm_mncc out_mncc = { 0, }; + + mncc_fill_header(&out_mncc, MNCC_CALL_PROC_REQ, leg->callref); + if (leg->bearer_cap_valid) { + out_mncc.fields |= MNCC_F_BEARER_CAP; + out_mncc.bearer_cap = leg->bearer_cap; + } else + LOGP(DMNCC, LOGL_ERROR, "Sending call (ref(%u) state(%d)) proceed without bearer caps!\n", + leg->callref, leg->state); + mncc_write(leg->conn, &out_mncc, leg->callref); +} + static void continue_mo_call(struct mncc_call_leg *leg) { char *dest, *source; /* TODO.. continue call obviously only for MO call right now */ - mncc_send(leg->conn, MNCC_CALL_PROC_REQ, leg->callref); + send_mncc_call_proc_req(leg); leg->state = MNCC_CC_PROCEEDING; if (leg->called.type == GSM340_TYPE_INTERNATIONAL) @@ -456,6 +470,22 @@ static int continue_setup(struct mncc_connection *conn, struct gsm_mncc *mncc) return 1; } +static int check_codec_overlap(struct gsm_mncc_bearer_cap *cap) { + /* TODO: validate that the available codecs matches with our allowed codecs */ + return 1; +} + +static int select_codec(struct gsm_mncc_bearer_cap *ms_caps, + struct gsm_mncc_bearer_cap *output_caps) +{ + memcpy(output_caps, ms_caps, sizeof(struct gsm_mncc_bearer_cap)); + /* FR version 1 */ + output_caps->speech_ver[0] = 0; + output_caps->speech_ver[1] = -1; + + return 0; +} + static void check_setup(struct mncc_connection *conn, char *buf, int rc) { struct gsm_mncc *data; @@ -484,14 +514,17 @@ static void check_setup(struct mncc_connection *conn, char *buf, int rc) return mncc_send(conn, MNCC_REJ_REQ, data->callref); } - /* TODO.. bearer caps and better audio handling */ - if ((data->fieds & MNCC_F_BEARER_CAP) == 0) { + if ((data->fields & MNCC_F_BEARER_CAP) == 0) { LOGP(DMNCC, LOGL_ERROR, - "MNCC leg(%u) without bearrer cap fields(%u)\n", - data->callref, data->fields); + "MNCC leg(%u) without bearrer cap\n", data->callref); + return mncc_send(conn, MNCC_REJ_REQ, data->callref); + } + if (!check_codec_overlap(&data->bearer_cap)) { + /* TODO: more detailed codec view */ + LOGP(DMNCC, LOGL_ERROR, + "MNCC leg(%u) has wrong codecs\n", data->callref); return mncc_send(conn, MNCC_REJ_REQ, data->callref); } - /* parse bearer -> move to function */ if (!continue_setup(conn, data)) { LOGP(DMNCC, LOGL_ERROR, @@ -515,6 +548,9 @@ static void check_setup(struct mncc_connection *conn, char *buf, int rc) leg->conn = conn; leg->state = MNCC_CC_INITIAL; leg->dir = MNCC_DIR_MO; + /* bcaps are ensured to be present */ + select_codec(&data->bearer_cap, &leg->bearer_cap); + leg->bearer_cap_valid = 1; memcpy(&leg->called, &data->called, sizeof(leg->called)); memcpy(&leg->calling, &data->calling, sizeof(leg->calling)); memcpy(&leg->imsi, data->imsi, sizeof(leg->imsi)); -- cgit v1.2.3