aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-10-14 17:56:17 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-11-12 16:06:47 +0100
commitd9e229b08871c6be76e97e7d7281a824c1bdb231 (patch)
treecbde0e642256ed5f290e54ce647535ed2765be92
parent07415166b07602f2f2ab721e2b86bfd1c5eabcdd (diff)
mgcp: handle responses from the MGCP GW
-rw-r--r--openbsc/include/openbsc/mgcp_internal.h2
-rw-r--r--openbsc/include/openbsc/mgcpgw_client.h59
-rw-r--r--openbsc/src/libmgcp/mgcp_common.c21
-rw-r--r--openbsc/src/libmgcp/mgcp_protocol.c16
-rw-r--r--openbsc/src/libmgcp/mgcpgw_client.c207
-rw-r--r--openbsc/src/libmsc/msc_ifaces.c48
-rw-r--r--openbsc/src/osmo-cscn/cscn_main.c13
-rw-r--r--openbsc/tests/db/db_test.c12
8 files changed, 309 insertions, 69 deletions
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 6997b02e5..b58eb9b58 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -332,3 +332,5 @@ static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
return endp->cfg->bts_ports.bind_addr;
return endp->cfg->source_addr;
}
+
+int mgcp_msg_terminate_nul(struct msgb *msg);
diff --git a/openbsc/include/openbsc/mgcpgw_client.h b/openbsc/include/openbsc/mgcpgw_client.h
index c21011898..60e648d9b 100644
--- a/openbsc/include/openbsc/mgcpgw_client.h
+++ b/openbsc/include/openbsc/mgcpgw_client.h
@@ -1,6 +1,9 @@
#pragma once
#include <stdint.h>
+
+#include <osmocom/core/linuxlist.h>
+
enum mgcp_connection_mode;
struct msgb;
@@ -11,8 +14,6 @@ struct mgcpgw_client;
#define MGCPGW_CLIENT_REMOTE_ADDR_DEFAULT "127.0.0.1"
#define MGCPGW_CLIENT_REMOTE_PORT_DEFAULT 2427
-typedef void (* mgcp_rx_cb_t )(struct msgb *msg, void *priv);
-
struct mgcpgw_client_conf {
const char *local_addr;
int local_port;
@@ -20,11 +21,35 @@ struct mgcpgw_client_conf {
int remote_port;
};
+struct mgcp_response_head {
+ int response_code;
+ unsigned int trans_id;
+ const char *comment;
+};
+
+struct mgcp_response {
+ char *data;
+ struct mgcp_response_head head;
+ uint16_t audio_port;
+};
+
+/* Invoked when an MGCP response is received or sending failed. When the
+ * response is passed as NULL, this indicates failure during transmission. */
+typedef void (* mgcp_response_cb_t )(struct mgcp_response *response, void *priv);
+
+struct mgcp_response_pending {
+ struct llist_head entry;
+
+ unsigned int trans_id;
+ mgcp_response_cb_t response_cb;
+ void *priv;
+};
+
+
void mgcpgw_client_conf_init(struct mgcpgw_client_conf *conf);
struct mgcpgw_client *mgcpgw_client_init(void *ctx,
- struct mgcpgw_client_conf *conf,
- mgcp_rx_cb_t rx_cb, void *rx_cb_priv);
+ struct mgcpgw_client_conf *conf);
const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp);
uint16_t mgcpgw_client_remote_port(struct mgcpgw_client *mgcp);
@@ -32,16 +57,28 @@ uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp);
unsigned int mgcpgw_client_next_endpoint(struct mgcpgw_client *client);
-int mgcpgw_client_tx_crcx(struct mgcpgw_client *client,
+int mgcp_response_parse_params(struct mgcp_response *r);
+
+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);
-int mgcpgw_client_tx_mdcx(struct mgcpgw_client *client, uint16_t rtp_endpoint,
- const char *rtp_conn_addr, uint16_t rtp_port,
- enum mgcp_connection_mode 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);
-int mgcpgw_client_tx_str(struct mgcpgw_client *mgcp, const char *fmt, ...);
-int mgcpgw_client_tx_buf(struct mgcpgw_client *mgcp, const char *buf, int len);
-int mgcpgw_client_tx(struct mgcpgw_client *mgcp, struct msgb *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, ...);
+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);
+int mgcpgw_client_tx(struct mgcpgw_client *mgcp,
+ mgcp_response_cb_t response_cb, void *priv,
+ struct msgb *msg, unsigned int trans_id);
void mgcpgw_client_vty_init(int node, struct mgcpgw_client_conf *conf);
int mgcpgw_client_config_write(struct vty *vty, const char *indent);
diff --git a/openbsc/src/libmgcp/mgcp_common.c b/openbsc/src/libmgcp/mgcp_common.c
index 9f104739a..4d7d36ab8 100644
--- a/openbsc/src/libmgcp/mgcp_common.c
+++ b/openbsc/src/libmgcp/mgcp_common.c
@@ -20,6 +20,8 @@
*
*/
+#include <errno.h>
+
#include <osmocom/core/utils.h>
#include <openbsc/mgcp.h>
@@ -30,3 +32,22 @@ const struct value_string mgcp_connection_mode_strs[] = {
{ MGCP_CONN_RECV_ONLY, "recvonly" },
{ MGCP_CONN_LOOPBACK, "loopback" },
};
+
+/* Ensure that the msg->l2h is NUL terminated. */
+int mgcp_msg_terminate_nul(struct msgb *msg)
+{
+ unsigned char *tail = msg->l2h + msgb_l2len(msg); /* char after l2 data */
+ if (tail[-1] == '\0')
+ /* nothing to do */;
+ else if (msgb_tailroom(msg) > 0)
+ tail[0] = '\0';
+ else if (tail[-1] == '\r' || tail[-1] == '\n')
+ tail[-1] = '\0';
+ else {
+ LOGP(DMGCP, LOGL_ERROR, "Cannot NUL terminate MGCP message: "
+ "Length: %d, Buffer size: %d\n",
+ msgb_l2len(msg), msg->data_len);
+ return -ENOTSUP;
+ }
+ return 0;
+}
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index 2100f81a6..a34b42445 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -318,29 +318,17 @@ struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg)
int i, code, handled = 0;
struct msgb *resp = NULL;
char *data;
- unsigned char *tail = msg->l2h + msgb_l2len(msg); /* char after l2 data */
if (msgb_l2len(msg) < 4) {
LOGP(DMGCP, LOGL_ERROR, "msg too short: %d\n", msg->len);
return NULL;
}
- /* Ensure that the msg->l2h is NUL terminated. */
- if (tail[-1] == '\0')
- /* nothing to do */;
- else if (msgb_tailroom(msg) > 0)
- tail[0] = '\0';
- else if (tail[-1] == '\r' || tail[-1] == '\n')
- tail[-1] = '\0';
- else {
- LOGP(DMGCP, LOGL_ERROR, "Cannot NUL terminate MGCP message: "
- "Length: %d, Buffer size: %d\n",
- msgb_l2len(msg), msg->data_len);
+ if (mgcp_msg_terminate_nul(msg))
return NULL;
- }
/* attempt to treat it as a response */
- if (sscanf((const char *)&msg->l2h[0], "%3d %*s", &code) == 1) {
+ if (sscanf((const char *)&msg->l2h[0], "%3d %u*s", &code) == 1) {
LOGP(DMGCP, LOGL_DEBUG, "Response: Code: %d\n", code);
return NULL;
}
diff --git a/openbsc/src/libmgcp/mgcpgw_client.c b/openbsc/src/libmgcp/mgcpgw_client.c
index 025bed136..5c08843b0 100644
--- a/openbsc/src/libmgcp/mgcpgw_client.c
+++ b/openbsc/src/libmgcp/mgcpgw_client.c
@@ -25,6 +25,7 @@
#include <openbsc/mgcpgw_client.h>
#include <openbsc/mgcp.h>
+#include <openbsc/mgcp_internal.h>
#include <openbsc/debug.h>
#include <netinet/in.h>
@@ -38,10 +39,9 @@ struct mgcpgw_client {
struct mgcpgw_client_conf actual;
uint32_t remote_addr;
struct osmo_wqueue wq;
- mgcp_rx_cb_t rx_cb;
- void *rx_cb_priv;
unsigned int next_trans_id;
uint16_t next_endpoint;
+ struct llist_head responses_pending;
};
void mgcpgw_client_conf_init(struct mgcpgw_client_conf *conf)
@@ -60,6 +60,138 @@ unsigned int mgcpgw_client_next_endpoint(struct mgcpgw_client *client)
return client->next_endpoint ++;
}
+static void mgcpgw_client_handle_response(struct mgcpgw_client *mgcp,
+ struct mgcp_response_pending *pending,
+ struct mgcp_response *response)
+{
+ if (!pending)
+ return;
+ if (pending->response_cb)
+ pending->response_cb(response, pending->priv);
+ else
+ LOGP(DMGCP, LOGL_INFO, "MGCP response ignored (NULL cb)\n");
+ talloc_free(pending);
+}
+
+static int mgcp_response_parse_head(struct mgcp_response *r, struct msgb *msg)
+{
+ int comment_pos;
+
+ if (mgcp_msg_terminate_nul(msg))
+ goto response_parse_failure;
+
+ r->data = (char *)msg->data;
+
+ if (sscanf(r->data, "%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;
+ return 0;
+
+response_parse_failure:
+ LOGP(DMGCP, LOGL_ERROR,
+ "Failed to parse MGCP response header\n");
+ return -EINVAL;
+}
+
+/* TODO undup against mgcp_protocol.c:mgcp_check_param() */
+static bool mgcp_line_is_valid(const char *line)
+{
+ const size_t line_len = strlen(line);
+ if (line[0] == '\0')
+ return true;
+
+ if (line_len < 2
+ || line[1] != '=') {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Wrong MGCP option format: '%s'\n",
+ line);
+ return false;
+ }
+
+ return true;
+}
+
+/* Parse a line like "m=audio 16002 RTP/AVP 98" */
+static int mgcp_parse_audio(struct mgcp_response *r, const char *line)
+{
+ if (sscanf(line, "m=audio %hu",
+ &r->audio_port) != 1)
+ goto response_parse_failure;
+
+ return 0;
+
+response_parse_failure:
+ LOGP(DMGCP, LOGL_ERROR,
+ "Failed to parse MGCP response header\n");
+ return -EINVAL;
+}
+
+int mgcp_response_parse_params(struct mgcp_response *r)
+{
+ char *line;
+ char *data = r->data;
+ int rc;
+ for_each_line(line, data) {
+ if (!mgcp_line_is_valid(line))
+ return -EINVAL;
+
+ switch (line[0]) {
+ case 'm':
+ rc = mgcp_parse_audio(r, line);
+ if (rc)
+ return rc;
+ break;
+ default:
+ /* skip unhandled parameters */
+ break;
+ }
+ }
+ return 0;
+}
+
+static struct mgcp_response_pending *mgcpgw_client_response_pending_get(
+ struct mgcpgw_client *mgcp,
+ struct mgcp_response *r)
+{
+ struct mgcp_response_pending *pending;
+ if (!r)
+ return NULL;
+ llist_for_each_entry(pending, &mgcp->responses_pending, entry) {
+ if (pending->trans_id == r->head.trans_id) {
+ llist_del(&pending->entry);
+ return pending;
+ }
+ }
+ return NULL;
+}
+
+static int mgcpgw_client_read(struct mgcpgw_client *mgcp, struct msgb *msg)
+{
+ struct mgcp_response r;
+ struct mgcp_response_pending *pending;
+ int rc;
+
+ rc = mgcp_response_parse_head(&r, msg);
+ if (rc) {
+ LOGP(DMGCP, LOGL_ERROR, "Cannot parse MGCP response\n");
+ return -1;
+ }
+
+ pending = mgcpgw_client_response_pending_get(mgcp, &r);
+ if (!pending) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Cannot find matching MGCP transaction for trans_id %d\n",
+ r.head.trans_id);
+ return -1;
+ }
+
+ mgcpgw_client_handle_response(mgcp, pending, &r);
+ return 0;
+}
+
static int mgcp_do_read(struct osmo_fd *fd)
{
struct mgcpgw_client *mgcp = fd->data;
@@ -84,9 +216,9 @@ static int mgcp_do_read(struct osmo_fd *fd)
}
msg->l2h = msgb_put(msg, ret);
- if (mgcp->rx_cb)
- mgcp->rx_cb(msg, mgcp->rx_cb_priv);
- return 0;
+ ret = mgcpgw_client_read(mgcp, msg);
+ talloc_free(msg);
+ return ret;
}
static int mgcp_do_write(struct osmo_fd *fd, struct msgb *msg)
@@ -109,8 +241,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,
- mgcp_rx_cb_t rx_cb, void *rx_cb_priv)
+ struct mgcpgw_client_conf *conf)
{
int on;
struct sockaddr_in addr;
@@ -119,6 +250,8 @@ struct mgcpgw_client *mgcpgw_client_init(void *ctx,
mgcp = talloc_zero(ctx, struct mgcpgw_client);
+ INIT_LLIST_HEAD(&mgcp->responses_pending);
+
mgcp->next_trans_id = 1;
mgcp->next_endpoint = 1;
@@ -132,8 +265,6 @@ 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;
- mgcp->rx_cb = rx_cb;
- mgcp->rx_cb_priv = rx_cb_priv;
wq = &mgcp->wq;
wq->bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
@@ -214,30 +345,48 @@ uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp)
return mgcp->remote_addr;
}
-int mgcpgw_client_tx(struct mgcpgw_client *mgcp, struct msgb *msg)
+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 *pending;
int rc;
+ pending = talloc_zero(mgcp, struct mgcp_response_pending);
+ pending->trans_id = trans_id;
+ pending->response_cb = response_cb;
+ pending->priv = priv;
+ llist_add_tail(&pending->entry, &mgcp->responses_pending);
+
if (msgb_l2len(msg) > 4096) {
LOGP(DMGCP, LOGL_ERROR,
"Cannot send, MGCP message too large: %u\n",
msgb_l2len(msg));
msgb_free(msg);
- return -EINVAL;
+ rc = -EINVAL;
+ goto mgcp_tx_error;
}
rc = osmo_wqueue_enqueue(&mgcp->wq, msg);
if (rc) {
LOGP(DMGCP, LOGL_FATAL, "Could not queue message to MGCP GW\n");
msgb_free(msg);
- return rc;
+ goto mgcp_tx_error;
} else
LOGP(DMGCP, LOGL_INFO, "Queued %u bytes for MGCP GW\n",
msgb_l2len(msg));
return 0;
+
+mgcp_tx_error:
+ /* Pass NULL to response cb to indicate an error */
+ mgcpgw_client_handle_response(mgcp, pending, NULL);
+ return -1;
}
-int mgcpgw_client_tx_buf(struct mgcpgw_client *mgcp, const char *buf, int len)
+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)
{
struct msgb *msg;
@@ -254,10 +403,13 @@ int mgcpgw_client_tx_buf(struct mgcpgw_client *mgcp, const char *buf, int len)
memcpy(dst, buf, len);
msg->l2h = msg->data;
- return mgcpgw_client_tx(mgcp, msg);
+ return mgcpgw_client_tx(mgcp, response_cb, priv, msg, trans_id);
}
-int mgcpgw_client_tx_str(struct mgcpgw_client *mgcp, const char *fmt, ...)
+int mgcpgw_client_tx_str(struct mgcpgw_client *mgcp,
+ mgcp_response_cb_t response_cb, void *priv,
+ unsigned int trans_id,
+ const char *fmt, ...)
{
char compose[4096 - 128];
va_list ap;
@@ -271,37 +423,44 @@ int mgcpgw_client_tx_str(struct mgcpgw_client *mgcp, const char *fmt, ...)
return -EMSGSIZE;
if (len < 1)
return -EIO;
- return mgcpgw_client_tx_buf(mgcp, compose, len);
+ return mgcpgw_client_tx_buf(mgcp, response_cb, priv, compose, len, trans_id);
}
-int mgcpgw_client_tx_crcx(struct mgcpgw_client *client,
+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)
{
- return mgcpgw_client_tx_str(client,
+ unsigned int trans_id = mgcp->next_trans_id ++;
+ return mgcpgw_client_tx_str(mgcp,
+ response_cb, priv, trans_id,
"CRCX %u %x@mgw MGCP 1.0\r\n"
"C: %x\r\n"
"L: p:20, a:AMR, nt:IN\r\n"
"M: %s\r\n"
,
- client->next_trans_id ++,
+ trans_id,
rtp_endpoint,
call_id,
mgcp_cmode_name(mode));
}
-int mgcpgw_client_tx_mdcx(struct mgcpgw_client *client, uint16_t rtp_endpoint,
- const char *rtp_conn_addr, uint16_t rtp_port,
- enum mgcp_connection_mode 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)
+
{
- return mgcpgw_client_tx_str(client,
+ unsigned int trans_id = mgcp->next_trans_id ++;
+ return mgcpgw_client_tx_str(mgcp,
+ response_cb, priv, trans_id,
"MDCX %u %x@mgw MGCP 1.0\r\n"
"M: %s\r\n"
"\r\n"
"c=IN IP4 %s\r\n"
"m=audio %u RTP/AVP 255\r\n"
,
- client->next_trans_id ++,
+ trans_id,
rtp_endpoint,
mgcp_cmode_name(mode),
rtp_conn_addr,
diff --git a/openbsc/src/libmsc/msc_ifaces.c b/openbsc/src/libmsc/msc_ifaces.c
index 4b8f01f4c..49de9b9b9 100644
--- a/openbsc/src/libmsc/msc_ifaces.c
+++ b/openbsc/src/libmsc/msc_ifaces.c
@@ -128,6 +128,32 @@ static int iu_rab_act_cs(struct ue_conn_ctx *uectx, uint8_t rab_id,
return iu_rab_act(uectx, msg);
}
+static void mgcp_response_rab_act_cs_crcx(struct mgcp_response *r, void *priv)
+{
+ struct gsm_trans *trans = priv;
+ int rc;
+
+ if (r->head.response_code != 200) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "MGCPGW response yields error: %d %s\n",
+ r->head.response_code, r->head.comment);
+ goto rab_act_cs_error;
+ }
+
+ rc = mgcp_response_parse_params(r);
+ if (rc) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Cannot parse MGCP response, for %s\n",
+ subscr_name(trans->subscr));
+ goto rab_act_cs_error;
+ }
+
+
+rab_act_cs_error:
+ /* FIXME abort call, invalidate conn, ... */
+ return;
+}
+
static int conn_iu_rab_act_cs(struct gsm_trans *trans)
{
struct gsm_subscriber_connection *conn = trans->conn;
@@ -149,6 +175,7 @@ static int conn_iu_rab_act_cs(struct gsm_trans *trans)
* 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);
@@ -190,6 +217,11 @@ int msc_call_assignment(struct gsm_trans *trans)
}
}
+static void mgcp_response_bridge_mdcx(struct mgcp_response *r, void *priv)
+{
+ /* TODO */
+}
+
int msc_call_bridge(struct gsm_trans *trans1, struct gsm_trans *trans2)
{
struct gsm_subscriber_connection *conn1 = trans1->conn;
@@ -202,17 +234,25 @@ int msc_call_bridge(struct gsm_trans *trans1, struct gsm_trans *trans2)
/* First setup the counterparts' endpoints, so that when transmission
* starts the originating addresses are already known to be valid. */
- mgcpgw_client_tx_mdcx(mgcp, conn1->iu.mgcp_rtp_endpoint,
+ 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, conn2->iu.mgcp_rtp_endpoint,
+ 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, conn1->iu.mgcp_rtp_endpoint,
+ 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, conn2->iu.mgcp_rtp_endpoint,
+ 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);
diff --git a/openbsc/src/osmo-cscn/cscn_main.c b/openbsc/src/osmo-cscn/cscn_main.c
index 88393c909..3bdeffa6b 100644
--- a/openbsc/src/osmo-cscn/cscn_main.c
+++ b/openbsc/src/osmo-cscn/cscn_main.c
@@ -96,16 +96,6 @@ void *tall_map_ctx = NULL;
void *tall_upq_ctx = NULL;
/* end deps from libbsc legacy. */
-static void mgcp_rx_cb(struct msgb *msg, void *priv)
-{
- static char strbuf[4096];
- unsigned int l = msg->len < sizeof(strbuf)-1 ? msg->len : sizeof(strbuf)-1;
- strncpy(strbuf, (const char*)msg->data, l);
- strbuf[l] = '\0';
- DEBUGP(DMGCP, "Rx MGCP msg from MGCP GW: '%s'\n", strbuf);
- talloc_free(msg);
-}
-
static struct {
const char *database_name;
const char *config_file;
@@ -470,8 +460,7 @@ TODO: we probably want some of the _net_ ctrl commands from bsc_base_ctrl_cmds_i
* should try to use the nanoseconds part of the current time. */
cscn_network->mgcpgw.client = mgcpgw_client_init(
- cscn_network, &cscn_network->mgcpgw.conf,
- mgcp_rx_cb, NULL);
+ cscn_network, &cscn_network->mgcpgw.conf);
if (db_init(cscn_cmdline_config.database_name)) {
printf("DB: Failed to init database: %s\n",
diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c
index 2aa4ecf4d..4868be8df 100644
--- a/openbsc/tests/db/db_test.c
+++ b/openbsc/tests/db/db_test.c
@@ -257,18 +257,22 @@ int main()
void vty_out() {}
unsigned int mgcpgw_client_next_endpoint(struct mgcpgw_client *client)
{ return 0; }
-int mgcpgw_client_tx_crcx(struct mgcpgw_client *client,
+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)
{ return -ENOTSUP; }
-int mgcpgw_client_tx_mdcx(struct mgcpgw_client *client, uint16_t rtp_endpoint,
- const char *rtp_conn_addr, uint16_t rtp_port,
- enum mgcp_connection_mode 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)
{ return -ENOTSUP; }
const char *mgcpgw_client_remote_addr_str(struct mgcpgw_client *mgcp)
{ return "0.0.0.0"; }
uint32_t mgcpgw_client_remote_addr_n(struct mgcpgw_client *mgcp)
{ return 0; }
+int mgcp_response_parse_params(struct mgcp_response *r)
+{ return -EINVAL; }
struct RANAP_Cause;
int iu_tx_release(struct ue_conn_ctx *ctx, const struct RANAP_Cause *cause)
{ return 0; }