summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-03-27 17:02:39 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2016-03-27 17:02:39 +0200
commit916348b7dcbd3f5fb4b672c3e18f6dd092cea146 (patch)
treea714de91de06b97d3f4e32031442e9229b27b268 /src
parent80880d45b7091dfbf5c722e2b9e79b60e7a9aba7 (diff)
mncc: Begin to implement MT call handling for SIP->MNCC
Initiate the setup request that should result in the call getting all the way to the connected state at some point in time. The device I test with sadly rejects the call too soon.
Diffstat (limited to 'src')
-rw-r--r--src/app.c14
-rw-r--r--src/mncc.c57
-rw-r--r--src/mncc.h4
3 files changed, 70 insertions, 5 deletions
diff --git a/src/app.c b/src/app.c
index 36e7cb0..0fe149b 100644
--- a/src/app.c
+++ b/src/app.c
@@ -63,15 +63,19 @@ static void route_to_sip(struct call *call, const char *source, const char *dest
call->initial->release_call(call->initial);
}
+static void route_to_mncc(struct call *call, const char *source,
+ const char *dest)
+{
+ if (mncc_create_remote_leg(&g_app.mncc.conn, call, source, dest) != 0)
+ call->initial->release_call(call->initial);
+}
+
void app_route_call(struct call *call, const char *source, const char *dest)
{
if (call->initial->type == CALL_TYPE_MNCC)
route_to_sip(call, source, dest);
- else {
- LOGP(DAPP, LOGL_ERROR, "Can not route call(%u) to MNCC yet\n",
- call->id);
- call->initial->release_call(call->initial);
- }
+ else
+ route_to_mncc(call, source, dest);
}
const char *app_media_name(int ptmsg)
diff --git a/src/mncc.c b/src/mncc.c
index 2e0e01d..92ce189 100644
--- a/src/mncc.c
+++ b/src/mncc.c
@@ -489,6 +489,63 @@ static void check_hello(struct mncc_connection *conn, char *buf, int rc)
conn->state = MNCC_READY;
}
+int mncc_create_remote_leg(struct mncc_connection *conn, struct call *call,
+ const char *calling, const char *called)
+{
+ struct mncc_call_leg *leg;
+ struct gsm_mncc mncc = { 0, };
+ int rc;
+
+ leg = talloc_zero(call, struct mncc_call_leg);
+ if (!leg) {
+ LOGP(DMNCC, LOGL_ERROR, "Failed to allocate leg call(%u)\n",
+ call->id);
+ return -1;
+ }
+
+ leg->base.type = CALL_TYPE_MNCC;
+ 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->base.call = call;
+
+ leg->callref = call->id;
+
+ leg->conn = conn;
+ leg->state = MNCC_CC_INITIAL;
+
+ mncc.msg_type = MNCC_SETUP_REQ;
+ mncc.callref = leg->callref;
+
+ mncc.fields |= MNCC_F_CALLING;
+ mncc.calling.plan = 1;
+ mncc.calling.type = 0x0;
+ memcpy(&mncc.calling.number, calling, sizeof(mncc.calling.number));
+
+ mncc.fields |= MNCC_F_CALLED;
+ mncc.called.plan = 1;
+ mncc.called.type = 0x0;
+ memcpy(&mncc.called.number, called, sizeof(mncc.called.number));
+
+ /*
+ * TODO/FIXME:
+ * - Determine/request channel based on offered audio codecs
+ * - Screening, redirect?
+ * - Synth. the bearer caps based on codecs?
+ */
+ rc = write(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(conn);
+ talloc_free(leg);
+ return -1;
+ }
+
+ call->remote = &leg->base;
+ return 0;
+}
+
static void mncc_reconnect(void *data)
{
int rc;
diff --git a/src/mncc.h b/src/mncc.h
index 5944a1b..7078283 100644
--- a/src/mncc.h
+++ b/src/mncc.h
@@ -6,6 +6,7 @@
#include <stdint.h>
struct app_config;
+struct call;
enum {
MNCC_DISCONNECTED,
@@ -28,3 +29,6 @@ struct mncc_connection {
void mncc_connection_init(struct mncc_connection *conn, struct app_config *cfg);
void mncc_connection_start(struct mncc_connection *conn);
+
+int mncc_create_remote_leg(struct mncc_connection *conn, struct call *call,
+ const char *calling, const char *called);