aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
Diffstat (limited to 'openbsc')
-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 029860300..545cdaada 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 258f125fa..eafc4e418 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 e0e4773ad..7162f5f12 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