summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2017-05-29 13:18:44 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-06-18 17:50:08 +0200
commitdfe085d979ba8b7266a6c66ecb13bf5a11a8d86f (patch)
tree20a343521ce9e91024471c7b4e9728f2ddcf26d5
parente818b91729de56db7643c0961f810c1652f65701 (diff)
osmo-msc: Integrate A interface into existing call control
The MSC already has some basic call control handling mechanism, that was primarily used with 3G before. However, the already existing code that handles the 3G calls is also perfectly fine for handling 2G calls. This commit integrates the A interface without breaking it for 3G.
-rw-r--r--openbsc/src/libmsc/a_iface.c22
-rw-r--r--openbsc/src/libmsc/a_iface_bssap.c43
-rw-r--r--openbsc/src/libmsc/msc_ifaces.c20
3 files changed, 72 insertions, 13 deletions
diff --git a/openbsc/src/libmsc/a_iface.c b/openbsc/src/libmsc/a_iface.c
index 0298603..545cdaa 100644
--- a/openbsc/src/libmsc/a_iface.c
+++ b/openbsc/src/libmsc/a_iface.c
@@ -29,6 +29,8 @@
#include <openbsc/a_iface.h>
#include <openbsc/a_iface_bssap.h>
#include <openbsc/transaction.h>
+#include <openbsc/mgcpgw_client.h>
+#include <osmocom/core/byteswap.h>
/* A pointer to the GSM network we work with. By the current paradigm,
* there can only be one gsm_network per MSC. The pointer is set once
@@ -128,15 +130,14 @@ int a_assign(struct gsm_trans *trans)
{
struct gsm_subscriber_connection *conn;
struct gsm0808_channel_type ct;
- uint16_t cic;
- uint16_t *cic_ptr = NULL;
- struct sockaddr_storage *ss = NULL;
struct gsm0808_speech_codec_list *scl = NULL;
uint32_t *ci_ptr = NULL;
+ struct msgb *msg;
+ struct sockaddr_storage rtp_addr;
+ struct sockaddr_in rtp_addr_in;
conn = trans->conn;
OSMO_ASSERT(conn);
- struct msgb *msg;
/* FIXME: This is still work in progress */
/* Some fake parameters for testing */
@@ -145,14 +146,19 @@ int a_assign(struct gsm_trans *trans)
ct.perm_spch[0] = GSM0808_PERM_FR1;
ct.perm_spch_len = 1;
- cic = 0x0023;
- cic_ptr = &cic;
+ /* Package RTP-Address data */
+ memset(&rtp_addr_in, 0, sizeof(rtp_addr_in));
+ rtp_addr_in.sin_family = AF_INET;
+ rtp_addr_in.sin_port = osmo_htons(conn->iu.mgcp_rtp_port_ue);
+ rtp_addr_in.sin_addr.s_addr = osmo_htonl(mgcpgw_client_remote_addr_n(gsm_network->mgcpgw.client));
- msg = gsm0808_create_ass(&ct, cic_ptr, ss, scl, ci_ptr);
+ memset(&rtp_addr, 0, sizeof(rtp_addr));
+ memcpy(&rtp_addr, &rtp_addr_in, sizeof(rtp_addr_in));
+
+ msg = gsm0808_create_ass(&ct, NULL, &rtp_addr, scl, ci_ptr);
LOGP(DMSC, LOGL_DEBUG, "N-DATA.req(%u, %s)\n", conn->a.conn_id, osmo_hexdump(msg->data, msg->len));
return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg);
-
}
/* Callback function, called by the SSCP stack when data arrives */
diff --git a/openbsc/src/libmsc/a_iface_bssap.c b/openbsc/src/libmsc/a_iface_bssap.c
index 258f125..eafc4e4 100644
--- a/openbsc/src/libmsc/a_iface_bssap.c
+++ b/openbsc/src/libmsc/a_iface_bssap.c
@@ -30,6 +30,9 @@
#include <openbsc/a_iface_bssap.h>
#include <openbsc/iu.h>
#include <openbsc/osmo_msc.h>
+#include <osmocom/core/byteswap.h>
+
+#define IP_V4_ADDR_LEN 4
/* Addresses of all BSCs which have been registered to this MSC */
static LLIST_HEAD(bsc_addr_list);
@@ -526,14 +529,52 @@ static int bssmap_ass_compl(struct osmo_sccp_user *scu, struct a_conn_info *a_co
{
struct gsm_network *network = a_conn_info->network;
struct gsm_subscriber_connection *conn;
+ struct mgcpgw_client *mgcp;
+ struct tlv_parsed tp;
+ struct sockaddr_storage rtp_addr;
+ struct sockaddr_in *rtp_addr_in;
+ int rc;
conn = subscr_conn_lookup_a(network, a_conn_info->conn_id);
if (!conn)
goto fail;
+ mgcp = conn->network->mgcpgw.client;
+ OSMO_ASSERT(mgcp);
+
LOGP(DMSC, LOGL_NOTICE, "BSC sends assignment complete message (conn_id=%i)\n", conn->a.conn_id);
- /* Inform the MSC about the assignment completion event */
+ tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0);
+
+ if (!TLVP_PRESENT(&tp, GSM0808_IE_AOIP_TRASP_ADDR)) {
+ LOGP(DMSC, LOGL_ERROR, "AoIP transport identifier missing -- discarding message!\n");
+ goto fail;
+ }
+
+ /* Decode AoIP transport address element */
+ rc = gsm0808_dec_aoip_trasp_addr(&rtp_addr, TLVP_VAL(&tp, GSM0808_IE_AOIP_TRASP_ADDR), TLVP_LEN(&tp, GSM0808_IE_AOIP_TRASP_ADDR));
+ if (rc < 0) {
+ LOGP(DMSC, LOGL_ERROR, "Unable to decode aoip transport address.\n");
+ goto fail;
+ }
+
+ /* use address / port supplied with the AoIP
+ * transport address element */
+ if(rtp_addr.ss_family == AF_INET)
+ {
+ rtp_addr_in = (struct sockaddr_in *)&rtp_addr;
+ conn->iu.mgcp_rtp_port_ue = osmo_ntohs(rtp_addr_in->sin_port);
+ /* FIXME: We also get the IP-Address of the remote (e.g. BTS)
+ * end with the response. Currently we just ignore that address.
+ * Instead we expect that our local MGCP gateway and the code
+ * controlling it, magically knows the IP of the remote end. */
+ } else {
+ LOGP(DMSC, LOGL_ERROR, "Unsopported addressing scheme. (supports only IPV4)\n");
+ goto fail;
+ }
+
+ /* FIXME: Seems to be related to authentication or,
+ encryption. Is this really in the right place? */
msc_rx_sec_mode_compl(conn);
msgb_free(msg);
diff --git a/openbsc/src/libmsc/msc_ifaces.c b/openbsc/src/libmsc/msc_ifaces.c
index e0e4773..7162f5f 100644
--- a/openbsc/src/libmsc/msc_ifaces.c
+++ b/openbsc/src/libmsc/msc_ifaces.c
@@ -172,9 +172,17 @@ static void mgcp_response_rab_act_cs_crcx(struct mgcp_response *r, void *priv)
conn->iu.mgcp_rtp_port_cn = r->audio_port;
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 */
+
+ if (trans->conn->via_ran == RAN_UTRAN_IU) {
+ /* Assign a voice channel via RANAP on 3G */
+ 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 */
+ } else if (trans->conn->via_ran == RAN_GERAN_A) {
+ /* Assign a voice channel via A on 2G */
+ return a_assign(trans);
+ } else
+ goto rab_act_cs_error;
rab_act_cs_error:
/* FIXME abort call, invalidate conn, ... */
@@ -213,7 +221,11 @@ int msc_call_assignment(struct gsm_trans *trans)
switch (conn->via_ran) {
case RAN_GERAN_A:
- return a_assign(trans);
+ /* FIXME We first go for conn_iu_rab_act_cs(), this function
+ * will create a loopback rtp connection first and then call
+ * a_assign(). Probably we need to find another name for
+ * conn_iu_rab_act_cs? */
+ return conn_iu_rab_act_cs(trans);
case RAN_UTRAN_IU:
#ifdef BUILD_IU