call/mncc: Set proceeding and deal with release based on this state

Let's inform the MS that we have collected everything to move forward
with the call. A new way to release the call is required in this state.
This commit is contained in:
Holger Hans Peter Freyther 2016-03-24 18:26:24 +01:00
parent 292e2cddd0
commit f86979e1eb
2 changed files with 46 additions and 0 deletions

View File

@ -5,6 +5,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <stdbool.h>
struct sip_agent;
struct mncc_connection;
@ -34,6 +35,8 @@ struct call_leg {
int type;
struct call *call;
bool in_release;
/**
* RTP data
*/
@ -57,6 +60,7 @@ struct sip_call_leg {
enum mncc_cc_state {
MNCC_CC_INITIAL,
MNCC_CC_PROCEEDING,
};
struct mncc_call_leg {

View File

@ -146,6 +146,17 @@ static void mncc_call_leg_release(struct call_leg *_leg)
mncc_send(leg->conn, MNCC_REJ_REQ, leg->callref);
call_leg_release(_leg);
break;
case MNCC_CC_PROCEEDING:
LOGP(DMNCC, LOGL_DEBUG,
"Releasing call in proc-state leg(%u)\n", leg->callref);
leg->base.in_release = true;
start_cmd_timer(leg, MNCC_REL_IND);
mncc_send(leg->conn, MNCC_DISC_REQ, leg->callref);
break;
default:
LOGP(DMNCC, LOGL_ERROR, "Unknown state leg(%u) state(%d)\n",
leg->callref, leg->state);
break;
}
}
@ -163,6 +174,10 @@ static void continue_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);
leg->state = MNCC_CC_PROCEEDING;
if (leg->called.type == GSM340_TYPE_INTERNATIONAL)
dest = talloc_asprintf(tall_mncc_ctx, "+%.32s", leg->called.number);
else
@ -279,6 +294,30 @@ static void check_setup(struct mncc_connection *conn, char *buf, int rc)
mncc_rtp_send(conn, MNCC_RTP_CREATE, data->callref);
}
static void check_rel_ind(struct mncc_connection *conn, char *buf, int rc)
{
struct gsm_mncc *data;
struct mncc_call_leg *leg;
if (rc != sizeof(*data)) {
LOGP(DMNCC, LOGL_ERROR, "gsm_mncc of wrong size %d vs. %zu\n",
rc, sizeof(*data));
return close_connection(conn);
}
data = (struct gsm_mncc *) buf;
leg = mncc_find_leg(data->callref);
if (!leg) {
LOGP(DMNCC, LOGL_ERROR, "rel call(%u) can not be found\n", data->callref);
return;
}
if (leg->base.in_release)
stop_cmd_timer(leg, MNCC_REL_IND);
LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was released.\n", data->callref);
call_leg_release(leg);
}
static void check_hello(struct mncc_connection *conn, char *buf, int rc)
{
struct gsm_mncc_hello *hello;
@ -349,6 +388,9 @@ static int mncc_data(struct osmo_fd *fd, unsigned int what)
case MNCC_RTP_CREATE:
check_rtp_create(conn, buf, rc);
break;
case MNCC_REL_IND:
check_rel_ind(conn, buf, rc);
break;
default:
LOGP(DMNCC, LOGL_ERROR, "Unhandled message type %d/0x%x\n",
msg_type, msg_type);