implement bearer cap support on CALL_PROCEEDING
This commit is contained in:
parent
477eb9f6d4
commit
c227fa7213
|
@ -129,6 +129,9 @@ struct mncc_call_leg {
|
||||||
struct osmo_timer_list cmd_timeout;
|
struct osmo_timer_list cmd_timeout;
|
||||||
int rsp_wanted;
|
int rsp_wanted;
|
||||||
|
|
||||||
|
int bearer_cap_valid;
|
||||||
|
struct gsm_mncc_bearer_cap bearer_cap;
|
||||||
|
|
||||||
struct mncc_connection *conn;
|
struct mncc_connection *conn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
48
src/mncc.c
48
src/mncc.c
|
@ -339,12 +339,26 @@ static void close_connection(struct mncc_connection *conn)
|
||||||
conn->on_disconnect(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)
|
static void continue_mo_call(struct mncc_call_leg *leg)
|
||||||
{
|
{
|
||||||
char *dest, *source;
|
char *dest, *source;
|
||||||
|
|
||||||
/* TODO.. continue call obviously only for MO call right now */
|
/* 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;
|
leg->state = MNCC_CC_PROCEEDING;
|
||||||
|
|
||||||
if (leg->called.type == GSM340_TYPE_INTERNATIONAL)
|
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;
|
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)
|
static void check_setup(struct mncc_connection *conn, char *buf, int rc)
|
||||||
{
|
{
|
||||||
struct gsm_mncc *data;
|
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);
|
return mncc_send(conn, MNCC_REJ_REQ, data->callref);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO.. bearer caps and better audio handling */
|
if ((data->fields & MNCC_F_BEARER_CAP) == 0) {
|
||||||
if ((data->fieds & MNCC_F_BEARER_CAP) == 0) {
|
|
||||||
LOGP(DMNCC, LOGL_ERROR,
|
LOGP(DMNCC, LOGL_ERROR,
|
||||||
"MNCC leg(%u) without bearrer cap fields(%u)\n",
|
"MNCC leg(%u) without bearrer cap\n", data->callref);
|
||||||
data->callref, data->fields);
|
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);
|
return mncc_send(conn, MNCC_REJ_REQ, data->callref);
|
||||||
}
|
}
|
||||||
/* parse bearer -> move to function */
|
|
||||||
|
|
||||||
if (!continue_setup(conn, data)) {
|
if (!continue_setup(conn, data)) {
|
||||||
LOGP(DMNCC, LOGL_ERROR,
|
LOGP(DMNCC, LOGL_ERROR,
|
||||||
|
@ -515,6 +548,9 @@ static void check_setup(struct mncc_connection *conn, char *buf, int rc)
|
||||||
leg->conn = conn;
|
leg->conn = conn;
|
||||||
leg->state = MNCC_CC_INITIAL;
|
leg->state = MNCC_CC_INITIAL;
|
||||||
leg->dir = MNCC_DIR_MO;
|
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->called, &data->called, sizeof(leg->called));
|
||||||
memcpy(&leg->calling, &data->calling, sizeof(leg->calling));
|
memcpy(&leg->calling, &data->calling, sizeof(leg->calling));
|
||||||
memcpy(&leg->imsi, data->imsi, sizeof(leg->imsi));
|
memcpy(&leg->imsi, data->imsi, sizeof(leg->imsi));
|
||||||
|
|
Loading…
Reference in New Issue