aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/call.h13
-rw-r--r--src/mncc.c56
2 files changed, 67 insertions, 2 deletions
diff --git a/src/call.h b/src/call.h
index 102c366..a7f03ee 100644
--- a/src/call.h
+++ b/src/call.h
@@ -45,6 +45,16 @@ struct call_leg {
uint32_t payload_type;
uint32_t payload_msg_type;
+ /**
+ * Remote started to ring/alert
+ */
+ void (*ring_call)(struct call_leg *);
+
+ /**
+ * Remote picked up
+ */
+ void (*connect_call)(struct call_leg *);
+
/**
* Set by the call_leg implementation and will be called
* by the application to release the call.
@@ -60,7 +70,8 @@ struct sip_call_leg {
enum mncc_cc_state {
MNCC_CC_INITIAL,
- MNCC_CC_PROCEEDING,
+ MNCC_CC_PROCEEDING, /* skip delivered state */
+ MNCC_CC_CONNECTED,
};
struct mncc_call_leg {
diff --git a/src/mncc.c b/src/mncc.c
index 8ce90fe..eaf6add 100644
--- a/src/mncc.c
+++ b/src/mncc.c
@@ -125,6 +125,30 @@ static void mncc_rtp_send(struct mncc_connection *conn, uint32_t msg_type, uint3
}
}
+static void mncc_call_leg_connect(struct call_leg *_leg)
+{
+ struct mncc_call_leg *leg;
+
+ OSMO_ASSERT(_leg->type == CALL_TYPE_MNCC);
+ leg = (struct mncc_call_leg *) _leg;
+
+ /*
+ * TODO.. connect rtp now..
+ */
+
+ start_cmd_timer(leg, MNCC_SETUP_COMPL_IND);
+ mncc_send(leg->conn, MNCC_SETUP_RSP, leg->callref);
+}
+
+static void mncc_call_leg_ring(struct call_leg *_leg)
+{
+ struct mncc_call_leg *leg;
+
+ OSMO_ASSERT(_leg->type == CALL_TYPE_MNCC);
+ leg = (struct mncc_call_leg *) _leg;
+
+ mncc_send(leg->conn, MNCC_ALERT_REQ, leg->callref);
+}
static void mncc_call_leg_release(struct call_leg *_leg)
{
@@ -148,8 +172,9 @@ static void mncc_call_leg_release(struct call_leg *_leg)
call_leg_release(_leg);
break;
case MNCC_CC_PROCEEDING:
+ case MNCC_CC_CONNECTED:
LOGP(DMNCC, LOGL_DEBUG,
- "Releasing call in proc-state leg(%u)\n", leg->callref);
+ "Releasing call in non-initial 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);
@@ -279,6 +304,8 @@ static void check_setup(struct mncc_connection *conn, char *buf, int rc)
}
leg = (struct mncc_call_leg *) call->initial;
+ leg->base.connect_call = mncc_call_leg_connect;
+ leg->base.ring_call = mncc_call_leg_ring;
leg->base.release_call = mncc_call_leg_release;
leg->callref = data->callref;
leg->conn = conn;
@@ -374,6 +401,30 @@ static void check_rel_cnf(struct mncc_connection *conn, char *buf, int rc)
call_leg_release(&leg->base);
}
+static void check_stp_cmpl_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, "stp.cmpl call(%u) can not be found\n",
+ data->callref);
+ return;
+ }
+
+ LOGP(DMNCC, LOGL_NOTICE, "leg(%u) is now connected.\n", leg->callref);
+ stop_cmd_timer(leg, MNCC_SETUP_COMPL_IND);
+ leg->state = MNCC_CC_CONNECTED;
+}
+
static void check_hello(struct mncc_connection *conn, char *buf, int rc)
{
struct gsm_mncc_hello *hello;
@@ -453,6 +504,9 @@ static int mncc_data(struct osmo_fd *fd, unsigned int what)
case MNCC_REL_CNF:
check_rel_cnf(conn, buf, rc);
break;
+ case MNCC_SETUP_COMPL_IND:
+ check_stp_cmpl_ind(conn, buf, rc);
+ break;
default:
LOGP(DMNCC, LOGL_ERROR, "Unhandled message type %d/0x%x\n",
msg_type, msg_type);