summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-09-07 13:39:07 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2016-11-12 16:06:46 +0100
commitba46c4048c245507fa8d5529478db9ec67a60cef (patch)
tree3746440176ad3b5e9e5ce4e25e0e64684eb28300
parentea51bfd87535bd8f8a00db6d9777fff126ec2deb (diff)
IuCS: implement msc_call_assignment() for IuCS
Send IuCS RAB Activation upon MNCC_CALL_PROC_REQ. Implement function msc_call_assignment(): decide between sending A-iface BSSMAP Assignment Request or IuCS RAB Assignment Request. Implement iu_rab_act_cs() to send the IuCS RAB Assignment Request. The IP address and port of the MGCPGW sent in the RAB Assignment are still hardcoded. The A-interface extension is not implemented yet. Declare ranap_new_msg_rab_assign_voice() to avoid including ranap_msg_factory.h, which would require adding ASN1 CFLAGS to Makefile.am. The mgcpgw_client as well as some more osmo-iuh functions are now linked from libmsc, hence add some dummy stubs to libiudummy and db_test.c. Change-Id: Iaae51d1fbbfc28fad1c0b85e161d53d80a420a19
-rw-r--r--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/src/libmsc/msc_ifaces.c82
-rw-r--r--openbsc/tests/db/db_test.c11
-rw-r--r--openbsc/tests/libiudummy/iudummy.c15
4 files changed, 110 insertions, 1 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 9de8b8a..922a6c6 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -170,6 +170,9 @@ struct gsm_subscriber_connection {
struct {
struct ue_conn_ctx *ue_ctx;
int integrity_protection;
+ unsigned int mgcp_rtp_endpoint;
+ uint16_t mgcp_rtp_port_ue;
+ uint16_t mgcp_rtp_port_cn;
} iu;
};
diff --git a/openbsc/src/libmsc/msc_ifaces.c b/openbsc/src/libmsc/msc_ifaces.c
index f837ad9..2937b54 100644
--- a/openbsc/src/libmsc/msc_ifaces.c
+++ b/openbsc/src/libmsc/msc_ifaces.c
@@ -26,9 +26,16 @@
#include <openbsc/iu.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/transaction.h>
+#include <openbsc/mgcp.h>
+#include <openbsc/mgcpgw_client.h>
#include "../../bscconfig.h"
+extern struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id,
+ uint32_t rtp_ip,
+ uint16_t rtp_port,
+ bool use_x213_nsap);
+
static int msc_tx(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
switch (conn->via_iface) {
@@ -102,7 +109,80 @@ int msc_tx_common_id(struct gsm_subscriber_connection *conn)
#endif
}
+#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,
+ bool use_x213_nsap)
+{
+ struct msgb *msg;
+
+ 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);
+
+ 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);
+}
+
+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;
+
+ /* HACK. where to scope the RAB Id? At the conn / subscriber /
+ * ue_conn_ctx? */
+ static uint8_t next_rab_id = 1;
+
+ conn->iu.mgcp_rtp_endpoint =
+ mgcpgw_client_next_endpoint(conn->network->mgcpgw.client);
+ /* HACK: the addresses should be known from CRCX response
+ * and config. */
+ conn->iu.mgcp_rtp_port_ue = 4000 + 2 * conn->iu.mgcp_rtp_endpoint;
+ conn->iu.mgcp_rtp_port_cn = 16000 + 2 * conn->iu.mgcp_rtp_endpoint;
+
+ /* 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,
+ 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, next_rab_id++, rtp_ip, conn->iu.mgcp_rtp_port_ue, 1);
+ /* use_x213_nsap == 0 for ip.access nano3G */
+ /* TODO: store the RAB Id? At the conn / subscriber / ue_conn_ctx? */
+}
+#endif
+
int msc_call_assignment(struct gsm_trans *trans)
{
- return 0;
+ struct gsm_subscriber_connection *conn = trans->conn;
+
+ switch (conn->via_iface) {
+ case IFACE_A:
+ LOGP(DMSC, LOGL_ERROR,
+ "msc_call_assignment(): A-interface BSSMAP Assignment"
+ " Request not yet implemented\n");
+ return -ENOTSUP;
+
+ case IFACE_IU:
+#ifdef BUILD_IU
+ return conn_iu_rab_act_cs(trans);
+#else
+ LOGP(DMSC, LOGL_ERROR,
+ "msc_call_assignment(): IuCS RAB Activation not supported"
+ " in this build\n");
+ return -ENOTSUP;
+#endif
+
+ default:
+ LOGP(DMSC, LOGL_ERROR,
+ "msc_tx(): conn->via_iface invalid (%d)\n",
+ conn->via_iface);
+ return -EINVAL;
+ }
}
diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c
index 755a6e9..372806e 100644
--- a/openbsc/tests/db/db_test.c
+++ b/openbsc/tests/db/db_test.c
@@ -22,6 +22,7 @@
#include <openbsc/db.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/gsm_04_11.h>
+#include <openbsc/mgcp.h>
#include <osmocom/core/application.h>
@@ -254,3 +255,13 @@ int main()
/* stubs */
void vty_out() {}
+unsigned int mgcpgw_client_next_endpoint(struct mgcpgw_client *client)
+{ return 0; }
+int mgcpgw_client_tx_crcx(struct mgcpgw_client *client,
+ uint16_t rtp_endpoint, unsigned int call_id,
+ 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; }
diff --git a/openbsc/tests/libiudummy/iudummy.c b/openbsc/tests/libiudummy/iudummy.c
index 32ffaa1..d2d0d59 100644
--- a/openbsc/tests/libiudummy/iudummy.c
+++ b/openbsc/tests/libiudummy/iudummy.c
@@ -1,4 +1,5 @@
#include <stdint.h>
+#include <stdbool.h>
#include <osmocom/core/logging.h>
#include <osmocom/vty/logging.h>
@@ -34,6 +35,20 @@ int iu_page_ps(const char *imsi, const uint32_t *ptmsi, uint16_t lac, uint8_t ra
return 0;
}
+struct msgb *ranap_new_msg_rab_assign_voice(uint8_t rab_id, uint32_t rtp_ip,
+ uint16_t rtp_port,
+ bool use_x213_nsap)
+{
+ LOGP(DLGLOBAL, LOGL_INFO, "ranap_new_msg_rab_assign_voice() dummy called, NOT composing RAB Assignment\n");
+ return NULL;
+}
+
+int iu_rab_act(struct ue_conn_ctx *ue_ctx, struct msgb *msg)
+{
+ LOGP(DLGLOBAL, LOGL_INFO, "iu_rab_act() dummy called, NOT activating RAB\n");
+ return 0;
+}
+
int iu_tx_common_id(struct ue_conn_ctx *uectx, const char *imsi)
{
LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_common_id() dummy called, NOT sending CommonID\n");