aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/libmgcp/mgcpgw_client.c185
-rw-r--r--openbsc/src/libmsc/msc_ifaces.c144
-rw-r--r--openbsc/src/osmo-msc/msc_main.c11
3 files changed, 236 insertions, 104 deletions
diff --git a/openbsc/src/libmgcp/mgcpgw_client.c b/openbsc/src/libmgcp/mgcpgw_client.c
index 7b50007d6..9f0c84de2 100644
--- a/openbsc/src/libmgcp/mgcpgw_client.c
+++ b/openbsc/src/libmgcp/mgcpgw_client.c
@@ -39,7 +39,7 @@ struct mgcpgw_client {
struct mgcpgw_client_conf actual;
uint32_t remote_addr;
struct osmo_wqueue wq;
- unsigned int next_trans_id;
+ mgcp_trans_id_t next_trans_id;
uint16_t next_endpoint;
struct llist_head responses_pending;
};
@@ -64,8 +64,11 @@ static void mgcpgw_client_handle_response(struct mgcpgw_client *mgcp,
struct mgcp_response_pending *pending,
struct mgcp_response *response)
{
- if (!pending)
+ if (!pending) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Cannot handle NULL response\n");
return;
+ }
if (pending->response_cb)
pending->response_cb(response, pending->priv);
else
@@ -76,18 +79,27 @@ static void mgcpgw_client_handle_response(struct mgcpgw_client *mgcp,
static int mgcp_response_parse_head(struct mgcp_response *r, struct msgb *msg)
{
int comment_pos;
+ char *end;
if (mgcp_msg_terminate_nul(msg))
goto response_parse_failure;
- r->data = (char *)msg->data;
+ r->body = (char *)msg->data;
- if (sscanf(r->data, "%3d %u %n",
+ if (sscanf(r->body, "%3d %u %n",
&r->head.response_code, &r->head.trans_id,
&comment_pos) != 2)
goto response_parse_failure;
- r->head.comment = r->data + comment_pos;
+ r->head.comment = r->body + comment_pos;
+ end = strchr(r->head.comment, '\r');
+ if (!end)
+ goto response_parse_failure;
+ /* Mark the end of the comment */
+ *end = '\0';
+ r->body = end + 1;
+ if (r->body[0] == '\n')
+ r->body ++;
return 0;
response_parse_failure:
@@ -132,8 +144,22 @@ response_parse_failure:
int mgcp_response_parse_params(struct mgcp_response *r)
{
char *line;
- char *data = r->data;
int rc;
+ OSMO_ASSERT(r->body);
+ char *data = strstr(r->body, "\n\n");
+
+ if (!data) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "MGCP response: cannot find start of parameters\n");
+ return -EINVAL;
+ }
+
+ /* Advance to after the \n\n, replace the second \n with \0. That's
+ * where the parameters start. */
+ data ++;
+ *data = '\0';
+ data ++;
+
for_each_line(line, data) {
if (!mgcp_line_is_valid(line))
return -EINVAL;
@@ -168,9 +194,15 @@ static struct mgcp_response_pending *mgcpgw_client_response_pending_get(
return NULL;
}
-static int mgcpgw_client_read(struct mgcpgw_client *mgcp, struct msgb *msg)
+/* Feed an MGCP message into the receive processing.
+ * Parse the head and call any callback registered for the transaction id found
+ * in the MGCP message. This is normally called directly from the internal
+ * mgcp_do_read that reads from the socket connected to the MGCP gateway. This
+ * function is published mainly to be able to feed data from the test suite.
+ */
+int mgcpgw_client_rx(struct mgcpgw_client *mgcp, struct msgb *msg)
{
- struct mgcp_response r;
+ struct mgcp_response r = { 0 };
struct mgcp_response_pending *pending;
int rc;
@@ -216,7 +248,7 @@ static int mgcp_do_read(struct osmo_fd *fd)
}
msg->l2h = msgb_put(msg, ret);
- ret = mgcpgw_client_read(mgcp, msg);
+ ret = mgcpgw_client_rx(mgcp, msg);
talloc_free(msg);
return ret;
}
@@ -243,10 +275,7 @@ static int mgcp_do_write(struct osmo_fd *fd, struct msgb *msg)
struct mgcpgw_client *mgcpgw_client_init(void *ctx,
struct mgcpgw_client_conf *conf)
{
- int on;
- struct sockaddr_in addr;
struct mgcpgw_client *mgcp;
- struct osmo_wqueue *wq;
mgcp = talloc_zero(ctx, struct mgcpgw_client);
@@ -265,12 +294,27 @@ struct mgcpgw_client *mgcpgw_client_init(void *ctx,
mgcp->actual.remote_port = conf->remote_port >= 0 ? (uint16_t)conf->remote_port :
MGCPGW_CLIENT_REMOTE_PORT_DEFAULT;
+ return mgcp;
+}
+
+int mgcpgw_client_connect(struct mgcpgw_client *mgcp)
+{
+ int on;
+ struct sockaddr_in addr;
+ struct osmo_wqueue *wq;
+ int rc;
+
+ if (!mgcp) {
+ LOGP(DMGCP, LOGL_FATAL, "MGCPGW client not initialized properly\n");
+ return -EINVAL;
+ }
+
wq = &mgcp->wq;
wq->bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
if (wq->bfd.fd < 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to create UDP socket errno: %d\n", errno);
- goto error_free;
+ return -errno;
}
on = 1;
@@ -278,6 +322,7 @@ struct mgcpgw_client *mgcpgw_client_init(void *ctx,
LOGP(DMGCP, LOGL_FATAL,
"Failed to initialize socket for MGCP GW: %s\n",
strerror(errno));
+ rc = -errno;
goto error_close_fd;
}
@@ -290,6 +335,7 @@ struct mgcpgw_client *mgcpgw_client_init(void *ctx,
LOGP(DMGCP, LOGL_FATAL,
"Failed to bind for MGCP GW to %s %u\n",
mgcp->actual.local_addr, mgcp->actual.local_port);
+ rc = -errno;
goto error_close_fd;
}
@@ -301,6 +347,7 @@ struct mgcpgw_client *mgcpgw_client_init(void *ctx,
"Failed to connect to MGCP GW at %s %u: %s\n",
mgcp->actual.remote_addr, mgcp->actual.remote_port,
strerror(errno));
+ rc = -errno;
goto error_close_fd;
}
@@ -314,19 +361,18 @@ struct mgcpgw_client *mgcpgw_client_init(void *ctx,
if (osmo_fd_register(&wq->bfd) != 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to register BFD\n");
+ rc = -EIO;
goto error_close_fd;
}
LOGP(DMGCP, LOGL_INFO, "MGCP GW connection: %s:%u -> %s:%u\n",
mgcp->actual.local_addr, mgcp->actual.local_port,
mgcp->actual.remote_addr, mgcp->actual.remote_port);
- return mgcp;
+ return 0;
error_close_fd:
close(wq->bfd.fd);
wq->bfd.fd = -1;
-error_free:
- talloc_free(mgcp);
- return NULL;
+ return rc;
}
const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp)
@@ -345,12 +391,13 @@ uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp)
return mgcp->remote_addr;
}
-int mgcpgw_client_tx(struct mgcpgw_client *mgcp,
- mgcp_response_cb_t response_cb, void *priv,
- struct msgb *msg, unsigned int trans_id)
+struct mgcp_response_pending * mgcpgw_client_pending_add(
+ struct mgcpgw_client *mgcp,
+ mgcp_trans_id_t trans_id,
+ mgcp_response_cb_t response_cb,
+ void *priv)
{
struct mgcp_response_pending *pending;
- int rc;
pending = talloc_zero(mgcp, struct mgcp_response_pending);
pending->trans_id = trans_id;
@@ -358,6 +405,31 @@ int mgcpgw_client_tx(struct mgcpgw_client *mgcp,
pending->priv = priv;
llist_add_tail(&pending->entry, &mgcp->responses_pending);
+ return pending;
+}
+
+/* Send the MGCP message in msg to the MGCP GW and handle a response with
+ * response_cb. NOTE: the response_cb still needs to call
+ * mgcp_response_parse_params(response) to get the parsed parameters -- to
+ * potentially save some CPU cycles, only the head line has been parsed when
+ * the response_cb is invoked. */
+int mgcpgw_client_tx(struct mgcpgw_client *mgcp, struct msgb *msg,
+ mgcp_response_cb_t response_cb, void *priv)
+{
+ struct mgcp_response_pending *pending;
+ mgcp_trans_id_t trans_id;
+ int rc;
+
+ trans_id = msg->cb[MSGB_CB_MGCP_TRANS_ID];
+ if (!trans_id) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Unset transaction id in mgcp send request\n");
+ talloc_free(msg);
+ return -EINVAL;
+ }
+
+ pending = mgcpgw_client_pending_add(mgcp, trans_id, response_cb, priv);
+
if (msgb_l2len(msg) > 4096) {
LOGP(DMGCP, LOGL_ERROR,
"Cannot send, MGCP message too large: %u\n",
@@ -383,35 +455,32 @@ mgcp_tx_error:
return -1;
}
-int mgcpgw_client_tx_buf(struct mgcpgw_client *mgcp,
- mgcp_response_cb_t response_cb, void *priv,
- const char *buf, int len,
- unsigned int trans_id)
+static struct msgb *mgcp_msg_from_buf(mgcp_trans_id_t trans_id,
+ const char *buf, int len)
{
struct msgb *msg;
if (len > (4096 - 128)) {
LOGP(DMGCP, LOGL_ERROR, "Cannot send to MGCP GW:"
" message too large: %d\n", len);
- return -ENOTSUP;
+ return NULL;
}
- msg = msgb_alloc_headroom(4096, 128, "MGCP Tx");
+ msg = msgb_alloc_headroom(4096, 128, "MGCP tx");
OSMO_ASSERT(msg);
char *dst = (char*)msgb_put(msg, len);
memcpy(dst, buf, len);
msg->l2h = msg->data;
+ msg->cb[MSGB_CB_MGCP_TRANS_ID] = trans_id;
- return mgcpgw_client_tx(mgcp, response_cb, priv, msg, trans_id);
+ return msg;
}
-int mgcpgw_client_tx_str(struct mgcpgw_client *mgcp,
- mgcp_response_cb_t response_cb, void *priv,
- unsigned int trans_id,
- const char *fmt, ...)
+static struct msgb *mgcp_msg_from_str(mgcp_trans_id_t trans_id,
+ const char *fmt, ...)
{
- char compose[4096 - 128];
+ static char compose[4096 - 128];
va_list ap;
int len;
OSMO_ASSERT(fmt);
@@ -419,21 +488,35 @@ int mgcpgw_client_tx_str(struct mgcpgw_client *mgcp,
va_start(ap, fmt);
len = vsnprintf(compose, sizeof(compose), fmt, ap);
va_end(ap);
- if (len >= sizeof(compose))
- return -EMSGSIZE;
- if (len < 1)
- return -EIO;
- return mgcpgw_client_tx_buf(mgcp, response_cb, priv, compose, len, trans_id);
+ if (len >= sizeof(compose)) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Message too large: trans_id=%u len=%d\n",
+ trans_id, len);
+ return NULL;
+ }
+ if (len < 1) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Failed to compose message: trans_id=%u len=%d\n",
+ trans_id, len);
+ return NULL;
+ }
+ return mgcp_msg_from_buf(trans_id, compose, len);
+}
+
+static mgcp_trans_id_t mgcpgw_client_next_trans_id(struct mgcpgw_client *mgcp)
+{
+ /* avoid zero trans_id to distinguish from unset trans_id */
+ if (!mgcp->next_trans_id)
+ mgcp->next_trans_id ++;
+ return mgcp->next_trans_id ++;
}
-int mgcpgw_client_tx_crcx(struct mgcpgw_client *mgcp,
- mgcp_response_cb_t response_cb, void *priv,
- uint16_t rtp_endpoint, unsigned int call_id,
- enum mgcp_connection_mode mode)
+struct msgb *mgcp_msg_crcx(struct mgcpgw_client *mgcp,
+ uint16_t rtp_endpoint, unsigned int call_id,
+ enum mgcp_connection_mode mode)
{
- unsigned int trans_id = mgcp->next_trans_id ++;
- return mgcpgw_client_tx_str(mgcp,
- response_cb, priv, trans_id,
+ mgcp_trans_id_t trans_id = mgcpgw_client_next_trans_id(mgcp);
+ return mgcp_msg_from_str(trans_id,
"CRCX %u %x@mgw MGCP 1.0\r\n"
"C: %x\r\n"
"L: p:20, a:AMR, nt:IN\r\n"
@@ -445,15 +528,13 @@ int mgcpgw_client_tx_crcx(struct mgcpgw_client *mgcp,
mgcp_cmode_name(mode));
}
-int mgcpgw_client_tx_mdcx(struct mgcpgw_client *mgcp,
- mgcp_response_cb_t response_cb, void *priv,
- uint16_t rtp_endpoint, const char *rtp_conn_addr,
- uint16_t rtp_port, enum mgcp_connection_mode mode)
+struct msgb *mgcp_msg_mdcx(struct mgcpgw_client *mgcp,
+ uint16_t rtp_endpoint, const char *rtp_conn_addr,
+ uint16_t rtp_port, enum mgcp_connection_mode mode)
{
- unsigned int trans_id = mgcp->next_trans_id ++;
- return mgcpgw_client_tx_str(mgcp,
- response_cb, priv, trans_id,
+ mgcp_trans_id_t trans_id = mgcpgw_client_next_trans_id(mgcp);
+ return mgcp_msg_from_str(trans_id,
"MDCX %u %x@mgw MGCP 1.0\r\n"
"M: %s\r\n"
"\r\n"
diff --git a/openbsc/src/libmsc/msc_ifaces.c b/openbsc/src/libmsc/msc_ifaces.c
index f75d425ca..d653e078a 100644
--- a/openbsc/src/libmsc/msc_ifaces.c
+++ b/openbsc/src/libmsc/msc_ifaces.c
@@ -110,27 +110,35 @@ int msc_tx_common_id(struct gsm_subscriber_connection *conn)
}
#ifdef BUILD_IU
-static int iu_rab_act_cs(struct ue_conn_ctx *uectx, uint8_t rab_id,
- uint32_t rtp_ip, uint16_t rtp_port)
+static void iu_rab_act_cs(struct ue_conn_ctx *uectx, uint8_t rab_id,
+ uint32_t rtp_ip, uint16_t rtp_port)
{
struct msgb *msg;
bool use_x213_nsap;
+ uint32_t conn_id = uectx->conn_id;
use_x213_nsap = (uectx->rab_assign_addr_enc == NSAP_ADDR_ENC_X213);
- LOGP(DIUCS, LOGL_DEBUG, "Assigning RAB: rab_id=%d, rtp=%x:%u,"
- " use_x213_nsap=%d\n", rab_id, rtp_ip, rtp_port, use_x213_nsap);
+ LOGP(DIUCS, LOGL_DEBUG, "Assigning RAB: conn_id=%u, rab_id=%d,"
+ " rtp=%x:%u, use_x213_nsap=%d\n", conn_id, rab_id, rtp_ip,
+ rtp_port, use_x213_nsap);
msg = ranap_new_msg_rab_assign_voice(rab_id, rtp_ip, rtp_port,
use_x213_nsap);
msg->l2h = msg->data;
- return iu_rab_act(uectx, msg);
+ if (iu_rab_act(uectx, msg))
+ LOGP(DIUCS, LOGL_ERROR, "Failed to send RAB Assignment:"
+ " conn_id=%d rab_id=%d rtp=%x:%u\n",
+ conn_id, rab_id, rtp_ip, rtp_port);
}
static void mgcp_response_rab_act_cs_crcx(struct mgcp_response *r, void *priv)
{
struct gsm_trans *trans = priv;
+ struct gsm_subscriber_connection *conn = trans->conn;
+ struct ue_conn_ctx *uectx = conn->iu.ue_ctx;
+ uint32_t rtp_ip;
int rc;
if (r->head.response_code != 200) {
@@ -148,6 +156,10 @@ static void mgcp_response_rab_act_cs_crcx(struct mgcp_response *r, void *priv)
goto rab_act_cs_error;
}
+ rtp_ip = mgcpgw_client_remote_addr_n(conn->network->mgcpgw.client);
+ iu_rab_act_cs(uectx, conn->iu.rab_id, rtp_ip,
+ conn->iu.mgcp_rtp_port_ue);
+ /* use_x213_nsap == 0 for ip.access nano3G */
rab_act_cs_error:
/* FIXME abort call, invalidate conn, ... */
@@ -157,7 +169,8 @@ rab_act_cs_error:
static int conn_iu_rab_act_cs(struct gsm_trans *trans)
{
struct gsm_subscriber_connection *conn = trans->conn;
- struct ue_conn_ctx *uectx = conn->iu.ue_ctx;
+ struct mgcpgw_client *mgcp = conn->network->mgcpgw.client;
+ struct msgb *msg;
/* HACK. where to scope the RAB Id? At the conn / subscriber /
* ue_conn_ctx? */
@@ -174,17 +187,9 @@ static int conn_iu_rab_act_cs(struct gsm_trans *trans)
/* Establish the RTP stream first as looping back to the originator.
* The MDCX will patch through to the counterpart. TODO: play a ring
* tone instead. */
- mgcpgw_client_tx_crcx(conn->network->mgcpgw.client,
- mgcp_response_rab_act_cs_crcx, trans,
- conn->iu.mgcp_rtp_endpoint, trans->callref,
- MGCP_CONN_LOOPBACK);
-
- uint32_t rtp_ip =
- mgcpgw_client_remote_addr_n(conn->network->mgcpgw.client);
-
- return iu_rab_act_cs(uectx, conn->iu.rab_id, rtp_ip,
- conn->iu.mgcp_rtp_port_ue);
- /* use_x213_nsap == 0 for ip.access nano3G */
+ msg = mgcp_msg_crcx(mgcp, conn->iu.mgcp_rtp_endpoint, trans->callref,
+ MGCP_CONN_LOOPBACK);
+ return mgcpgw_client_tx(mgcp, msg, mgcp_response_rab_act_cs_crcx, trans);
}
#endif
@@ -217,44 +222,85 @@ int msc_call_assignment(struct gsm_trans *trans)
}
}
-static void mgcp_response_bridge_mdcx(struct mgcp_response *r, void *priv)
+static void mgcp_response_bridge_mdcx(struct mgcp_response *r, void *priv);
+
+static void mgcp_bridge(struct gsm_trans *from, struct gsm_trans *to,
+ enum bridge_state state,
+ enum mgcp_connection_mode mode)
{
- /* TODO */
+ struct gsm_subscriber_connection *conn1 = from->conn;
+ struct gsm_subscriber_connection *conn2 = to->conn;
+ struct mgcpgw_client *mgcp = conn1->network->mgcpgw.client;
+ const char *ip;
+ struct msgb *msg;
+
+ OSMO_ASSERT(mgcp);
+
+ from->bridge.peer = to;
+ from->bridge.state = state;
+
+ /* Loop back to the same MGCP GW */
+ ip = mgcpgw_client_remote_addr_str(mgcp);
+
+ msg = mgcp_msg_mdcx(mgcp,
+ conn1->iu.mgcp_rtp_endpoint,
+ ip, conn2->iu.mgcp_rtp_port_cn,
+ mode);
+ if (mgcpgw_client_tx(mgcp, msg, mgcp_response_bridge_mdcx, from))
+ LOGP(DMGCP, LOGL_ERROR,
+ "Failed to send MDCX message for %s\n",
+ subscr_name(from->subscr));
}
-int msc_call_bridge(struct gsm_trans *trans1, struct gsm_trans *trans2)
+static void mgcp_response_bridge_mdcx(struct mgcp_response *r, void *priv)
{
- struct gsm_subscriber_connection *conn1 = trans1->conn;
- struct gsm_subscriber_connection *conn2 = trans2->conn;
+ struct gsm_trans *trans = priv;
+ struct gsm_trans *peer = trans->bridge.peer;
+
+ switch (trans->bridge.state) {
+ case BRIDGE_STATE_LOOPBACK_PENDING:
+ trans->bridge.state = BRIDGE_STATE_LOOPBACK_ESTABLISHED;
+
+ switch (peer->bridge.state) {
+ case BRIDGE_STATE_LOOPBACK_PENDING:
+ /* Wait until the other is done as well. */
+ return;
+ case BRIDGE_STATE_LOOPBACK_ESTABLISHED:
+ /* Now that both are in loopback, switch both to
+ * forwarding. */
+ mgcp_bridge(trans, peer, BRIDGE_STATE_BRIDGE_PENDING,
+ MGCP_CONN_RECV_SEND);
+ mgcp_bridge(peer, trans, BRIDGE_STATE_BRIDGE_PENDING,
+ MGCP_CONN_RECV_SEND);
+ break;
+ default:
+ LOGP(DMGCP, LOGL_ERROR,
+ "Unexpected bridge state: %d for %s\n",
+ trans->bridge.state, subscr_name(trans->subscr));
+ break;
+ }
+
+ case BRIDGE_STATE_BRIDGE_PENDING:
+ trans->bridge.state = BRIDGE_STATE_BRIDGE_ESTABLISHED;
+ break;
- struct mgcpgw_client *mgcp = conn1->network->mgcpgw.client;
- OSMO_ASSERT(mgcp);
+ default:
+ LOGP(DMGCP, LOGL_ERROR,
+ "Unexpected bridge state: %d for %s\n",
+ trans->bridge.state, subscr_name(trans->subscr));
+ break;
+ }
+}
- const char *ip = mgcpgw_client_remote_addr_str(mgcp);
-
- /* First setup the counterparts' endpoints, so that when transmission
- * starts the originating addresses are already known to be valid. */
- mgcpgw_client_tx_mdcx(mgcp,
- mgcp_response_bridge_mdcx, trans1,
- conn1->iu.mgcp_rtp_endpoint,
- ip, conn2->iu.mgcp_rtp_port_cn,
- MGCP_CONN_LOOPBACK);
- mgcpgw_client_tx_mdcx(mgcp,
- mgcp_response_bridge_mdcx, trans2,
- conn2->iu.mgcp_rtp_endpoint,
- ip, conn1->iu.mgcp_rtp_port_cn,
- MGCP_CONN_LOOPBACK);
- /* Now enable sending to and receiving from the peer. */
- mgcpgw_client_tx_mdcx(mgcp,
- mgcp_response_bridge_mdcx, trans1,
- conn1->iu.mgcp_rtp_endpoint,
- ip, conn2->iu.mgcp_rtp_port_cn,
- MGCP_CONN_RECV_SEND);
- mgcpgw_client_tx_mdcx(mgcp,
- mgcp_response_bridge_mdcx, trans2,
- conn2->iu.mgcp_rtp_endpoint,
- ip, conn1->iu.mgcp_rtp_port_cn,
- MGCP_CONN_RECV_SEND);
+int msc_call_bridge(struct gsm_trans *trans1, struct gsm_trans *trans2)
+{
+ /* First setup as loopback and configure the counterparts' endpoints,
+ * so that when transmission starts the originating addresses are
+ * already known to be valid. The callback will continue. */
+ mgcp_bridge(trans1, trans2, BRIDGE_STATE_LOOPBACK_PENDING,
+ MGCP_CONN_LOOPBACK);
+ mgcp_bridge(trans2, trans1, BRIDGE_STATE_LOOPBACK_PENDING,
+ MGCP_CONN_LOOPBACK);
return 0;
}
diff --git a/openbsc/src/osmo-msc/msc_main.c b/openbsc/src/osmo-msc/msc_main.c
index f1128988e..9d3efd702 100644
--- a/openbsc/src/osmo-msc/msc_main.c
+++ b/openbsc/src/osmo-msc/msc_main.c
@@ -459,9 +459,6 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
/* TODO: is this used for crypto?? Improve randomness, at least we
* should try to use the nanoseconds part of the current time. */
- msc_network->mgcpgw.client = mgcpgw_client_init(
- msc_network, &msc_network->mgcpgw.conf);
-
if (db_init(msc_cmdline_config.database_name)) {
printf("DB: Failed to init database: %s\n",
msc_cmdline_config.database_name);
@@ -506,6 +503,14 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
if (sms_queue_start(msc_network, 20) != 0)
return -1;
+ msc_network->mgcpgw.client = mgcpgw_client_init(
+ msc_network, &msc_network->mgcpgw.conf);
+
+ if (mgcpgw_client_connect(msc_network->mgcpgw.client)) {
+ printf("MGCPGW connect failed\n");
+ return 7;
+ }
+
/* Set up A-Interface */
/* TODO: implement A-Interface and remove above legacy stuff. */