aboutsummaryrefslogtreecommitdiffstats
path: root/src/mncc.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-03-25 21:30:59 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-03-26 06:22:06 +0100
commitd3d8348c6233302a3655b28ad4afc276202d030a (patch)
tree51314d6b222747a83fc0b2b64ef63e78e846263f /src/mncc.c
parentad6eabd4b50cfe184b99578b91cf8aa5572b94b1 (diff)
mncc: Send RTP_CONNECT and verify connect result
The current code can not deal with two outstanding commands. Let's assume the user will hang up if the voice connection will fail and we will add a general RTP_CONNECT check to tearn down a call.
Diffstat (limited to 'src/mncc.c')
-rw-r--r--src/mncc.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/src/mncc.c b/src/mncc.c
index 4436a3f..a4ef191 100644
--- a/src/mncc.c
+++ b/src/mncc.c
@@ -127,14 +127,36 @@ 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 gsm_mncc_rtp mncc = { 0, };
struct mncc_call_leg *leg;
+ struct call_leg *other;
+ int rc;
OSMO_ASSERT(_leg->type == CALL_TYPE_MNCC);
leg = (struct mncc_call_leg *) _leg;
+ other = call_leg_other(_leg);
+
+ /*
+ * Send RTP CONNECT and we handle the general failure of it by
+ * tearing down the call.
+ */
+ mncc.msg_type = MNCC_RTP_CONNECT;
+ mncc.callref = leg->callref;
+ mncc.ip = other->ip;
+ mncc.port = other->port;
+ mncc.payload_type = other->payload_type;
/*
- * TODO.. connect rtp now..
+ * FIXME: mncc.payload_msg_type should already be compatible.. but
+ * payload_type should be different..
*/
+ rc = write(leg->conn->fd.fd, &mncc, sizeof(mncc));
+ if (rc != sizeof(mncc)) {
+ LOGP(DMNCC, LOGL_ERROR, "Failed to send message leg(%u)\n",
+ leg->callref);
+ close_connection(leg->conn);
+ return;
+ }
start_cmd_timer(leg, MNCC_SETUP_COMPL_IND);
mncc_send(leg->conn, MNCC_SETUP_RSP, leg->callref);
@@ -215,6 +237,37 @@ static void continue_call(struct mncc_call_leg *leg)
talloc_free(dest);
}
+static void check_rtp_connect(struct mncc_connection *conn, char *buf, int rc)
+{
+ struct gsm_mncc_rtp *rtp;
+ struct mncc_call_leg *leg;
+ struct call_leg *other_leg;
+
+ if (rc < sizeof(*rtp)) {
+ LOGP(DMNCC, LOGL_ERROR, "gsm_mncc_rtp of wrong size %d < %zu\n",
+ rc, sizeof(*rtp));
+ return close_connection(conn);
+ }
+
+ rtp = (struct gsm_mncc_rtp *) buf;
+ leg = mncc_find_leg(rtp->callref);
+ if (!leg) {
+ LOGP(DMNCC, LOGL_ERROR, "leg(%u) can not be found\n", rtp->callref);
+ return mncc_send(conn, MNCC_REJ_REQ, rtp->callref);
+ }
+
+ /* extract information about where the RTP is */
+ if (rtp->ip != 0 || rtp->port != 0 || rtp->payload_type != 0)
+ return;
+
+ LOGP(DMNCC, LOGL_ERROR, "leg(%u) rtp connect failed\n", rtp->callref);
+
+ other_leg = call_leg_other(&leg->base);
+ if (other_leg)
+ other_leg->release_call(other_leg);
+ leg->base.release_call(&leg->base);
+}
+
static void check_rtp_create(struct mncc_connection *conn, char *buf, int rc)
{
struct gsm_mncc_rtp *rtp;
@@ -479,6 +532,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_RTP_CONNECT:
+ check_rtp_connect(conn, buf, rc);
+ break;
case MNCC_DISC_IND:
check_disc_ind(conn, buf, rc);
break;