aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/bsc/gsm_data.h51
-rw-r--r--include/osmocom/bsc/osmo_bsc.h53
-rw-r--r--include/osmocom/bsc/osmo_bsc_mgcp.h5
-rw-r--r--include/osmocom/bsc/osmo_bsc_sigtran.h6
-rw-r--r--src/libbsc/bsc_api.c2
-rw-r--r--src/osmo-bsc/osmo_bsc_api.c51
-rw-r--r--src/osmo-bsc/osmo_bsc_audio.c24
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c60
-rw-r--r--src/osmo-bsc/osmo_bsc_ctrl.c5
-rw-r--r--src/osmo-bsc/osmo_bsc_filter.c18
-rw-r--r--src/osmo-bsc/osmo_bsc_mgcp.c49
-rw-r--r--src/osmo-bsc/osmo_bsc_sigtran.c144
-rw-r--r--tests/bsc/bsc_test.c5
-rw-r--r--tests/bssap/bssap_test.c15
14 files changed, 222 insertions, 266 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index c730d9641..04dc69673 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -25,6 +25,7 @@
#include <osmocom/gsm/protocol/gsm_12_21.h>
#include <osmocom/abis/e1_input.h>
#include <osmocom/bsc/meas_rep.h>
+#include <osmocom/bsc/bsc_msg_filter.h>
struct mgcp_client_conf;
struct mgcp_client;
@@ -80,6 +81,12 @@ struct gsm_classmark {
uint8_t classmark3[14]; /* if cm3 gets extended by spec, it will be truncated */
};
+enum subscr_sccp_state {
+ SUBSCR_SCCP_ST_NONE,
+ SUBSCR_SCCP_ST_WAIT_CONN_CONF,
+ SUBSCR_SCCP_ST_CONNECTED
+};
+
/* active radio connection of a mobile subscriber */
struct gsm_subscriber_connection {
/* global linked list of subscriber_connections */
@@ -88,9 +95,6 @@ struct gsm_subscriber_connection {
/* libbsc subscriber information (if available) */
struct bsc_subscr *bsub;
- /* SCCP connection associatd with this subscriber_connection */
- struct osmo_bsc_sccp_con *sccp_con;
-
/* back pointers */
struct gsm_network *network;
@@ -121,6 +125,47 @@ struct gsm_subscriber_connection {
* capabilities, which the MSC is required to translate into the codec list. */
struct gsm0808_speech_codec_list codec_list;
bool codec_list_present;
+
+ /* flag to prevent multiple simultaneous ciphering commands */
+ int ciphering_handled;
+
+ /* state related to welcome USSD */
+ uint8_t new_subscriber;
+
+ /* state related to osmo_bsc_filter.c */
+ struct bsc_filter_state filter_state;
+
+ /* SCCP connection associatd with this subscriber_connection */
+ struct {
+ /* for advanced ping/pong */
+ int send_ping;
+
+ /* SCCP connection realted */
+ struct bsc_msc_data *msc;
+
+ /* Sigtran connection ID */
+ int conn_id;
+ enum subscr_sccp_state state;
+ } sccp;
+
+ /* for audio handling */
+ struct {
+ uint16_t cic;
+ uint32_t rtp_ip;
+ int rtp_port;
+ /* RTP address of the remote end (assigned by MSC through assignment request) */
+ struct sockaddr_storage aoip_rtp_addr_remote;
+
+ /* Local RTP address (reported back to the MSC by us with the
+ * assignment complete message) */
+ struct sockaddr_storage aoip_rtp_addr_local;
+
+ /* storage to keep states of the MGCP connection handler, the
+ * handler is created when an assignment request is received
+ * and is terminated when the assignment complete message is
+ * sent */
+ struct mgcp_ctx *mgcp_ctx;
+ } user_plane;
};
diff --git a/include/osmocom/bsc/osmo_bsc.h b/include/osmocom/bsc/osmo_bsc.h
index 485c83648..678ac41d2 100644
--- a/include/osmocom/bsc/osmo_bsc.h
+++ b/include/osmocom/bsc/osmo_bsc.h
@@ -16,59 +16,14 @@ enum bsc_con {
};
struct bsc_msc_data;
-struct bsc_msc_connection;
-
-struct osmo_bsc_sccp_con {
- /* list_head anchoring us to gsm_network.subscr_conns */
- struct llist_head entry;
-
- /* flag to prevent multiple simultaneous ciphering commands */
- int ciphering_handled;
-
- /* for audio handling */
- struct {
- uint16_t cic;
- uint32_t rtp_ip;
- int rtp_port;
- /* RTP address of the remote end (assigned by MSC through assignment request) */
- struct sockaddr_storage aoip_rtp_addr_remote;
-
- /* Local RTP address (reported back to the MSC by us with the
- * assignment complete message) */
- struct sockaddr_storage aoip_rtp_addr_local;
-
- /* storage to keep states of the MGCP connection handler, the
- * handler is created when an assignment request is received
- * and is terminated when the assignment complete message is
- * sent */
- struct mgcp_ctx *mgcp_ctx;
- } user_plane;
-
- /* for advanced ping/pong */
- int send_ping;
-
- /* SCCP connection realted */
- struct bsc_msc_data *msc;
-
- /* back-pointer to subscriber connection */
- struct gsm_subscriber_connection *conn;
- /* state related to welcome USSD */
- uint8_t new_subscriber;
-
- /* state related to osmo_bsc_filter.c */
- struct bsc_filter_state filter_state;
-
- /* Sigtran connection ID */
- int conn_id;
-};
struct bsc_api *osmo_bsc_api();
-int bsc_queue_for_msc(struct osmo_bsc_sccp_con *conn, struct msgb *msg);
-int bsc_open_connection(struct osmo_bsc_sccp_con *sccp, struct msgb *msg);
+int bsc_queue_for_msc(struct gsm_subscriber_connection *conn, struct msgb *msg);
+int bsc_open_connection(struct gsm_subscriber_connection *sccp, struct msgb *msg);
enum bsc_con bsc_create_new_connection(struct gsm_subscriber_connection *conn,
struct bsc_msc_data *msc, int send_ping);
-int bsc_delete_connection(struct osmo_bsc_sccp_con *sccp);
+int bsc_delete_connection(struct gsm_subscriber_connection *sccp);
struct bsc_msc_data *bsc_find_msc(struct gsm_subscriber_connection *conn, struct msgb *);
int bsc_scan_bts_msg(struct gsm_subscriber_connection *conn, struct msgb *msg);
@@ -76,7 +31,7 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg);
int bsc_send_welcome_ussd(struct gsm_subscriber_connection *conn);
int bsc_handle_udt(struct bsc_msc_data *msc, struct msgb *msg, unsigned int length);
-int bsc_handle_dt(struct osmo_bsc_sccp_con *conn, struct msgb *msg, unsigned int len);
+int bsc_handle_dt(struct gsm_subscriber_connection *conn, struct msgb *msg, unsigned int len);
int bsc_ctrl_cmds_install();
diff --git a/include/osmocom/bsc/osmo_bsc_mgcp.h b/include/osmocom/bsc/osmo_bsc_mgcp.h
index dc2ba3475..15039f747 100644
--- a/include/osmocom/bsc/osmo_bsc_mgcp.h
+++ b/include/osmocom/bsc/osmo_bsc_mgcp.h
@@ -43,7 +43,7 @@ struct mgcp_ctx {
/* Copy of the pointer and the data with context information
* needed to process the AoIP and MGCP requests (system data) */
struct mgcp_client *mgcp;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
enum gsm48_chan_mode chan_mode;
bool full_rate;
struct gsm_lchan *lchan;
@@ -54,7 +54,8 @@ struct mgcp_ctx {
void mgcp_init(struct gsm_network *net);
-struct mgcp_ctx *mgcp_assignm_req(void *ctx, struct mgcp_client *mgcp, struct osmo_bsc_sccp_con *conn,
+struct mgcp_ctx *mgcp_assignm_req(void *ctx, struct mgcp_client *mgcp,
+ struct gsm_subscriber_connection *conn,
enum gsm48_chan_mode chan_mode, bool full_rate);
void mgcp_clear_complete(struct mgcp_ctx *mgcp_ctx, struct msgb *resp);
void mgcp_ass_complete(struct mgcp_ctx *mgcp_ctx, struct gsm_lchan *lchan);
diff --git a/include/osmocom/bsc/osmo_bsc_sigtran.h b/include/osmocom/bsc/osmo_bsc_sigtran.h
index 89649036e..5cb723066 100644
--- a/include/osmocom/bsc/osmo_bsc_sigtran.h
+++ b/include/osmocom/bsc/osmo_bsc_sigtran.h
@@ -28,15 +28,15 @@
enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, struct bsc_msc_data *msc);
/* Open a new connection oriented sigtran connection */
-int osmo_bsc_sigtran_open_conn(const struct osmo_bsc_sccp_con *conn, struct msgb *msg);
+int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg);
/* Send data to MSC */
-int osmo_bsc_sigtran_send(const struct osmo_bsc_sccp_con *conn, struct msgb *msg);
+int osmo_bsc_sigtran_send(struct gsm_subscriber_connection *conn, struct msgb *msg);
/* Delete a connection from the list with open connections
* (called by osmo_bsc_api.c on failing open connections and
* locally, when a connection is closed by the MSC */
-int osmo_bsc_sigtran_del_conn(struct osmo_bsc_sccp_con *sccp);
+int osmo_bsc_sigtran_del_conn(struct gsm_subscriber_connection *sccp);
/* Initalize osmo sigtran backhaul */
int osmo_bsc_sigtran_init(struct llist_head *mscs);
diff --git a/src/libbsc/bsc_api.c b/src/libbsc/bsc_api.c
index 2cb5b1032..908671935 100644
--- a/src/libbsc/bsc_api.c
+++ b/src/libbsc/bsc_api.c
@@ -32,6 +32,7 @@
#include <osmocom/bsc/gsm_04_08_utils.h>
#include <osmocom/bsc/bsc_subscriber.h>
#include <osmocom/bsc/penalty_timers.h>
+#include <osmocom/bsc/osmo_bsc_sigtran.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm48.h>
@@ -278,6 +279,7 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lcha
lchan->conn = conn;
INIT_LLIST_HEAD(&conn->ho_dtap_cache);
conn->ho_penalty_timers = penalty_timers_init(conn);
+ conn->sccp.conn_id = -1;
llist_add_tail(&conn->entry, &net->subscr_conns);
return conn;
}
diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c
index 1caaeee7c..465832c82 100644
--- a/src/osmo-bsc/osmo_bsc_api.c
+++ b/src/osmo-bsc/osmo_bsc_api.c
@@ -32,13 +32,13 @@
#include <osmocom/bsc/osmo_bsc_sigtran.h>
#define return_when_not_connected(conn) \
- if (!conn->sccp_con) {\
+ if (conn->sccp.state != SUBSCR_SCCP_ST_CONNECTED) {\
LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \
return; \
}
#define return_when_not_connected_val(conn, ret) \
- if (!conn->sccp_con) {\
+ if (conn->sccp.state != SUBSCR_SCCP_ST_CONNECTED) {\
LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \
return ret; \
}
@@ -48,7 +48,7 @@
LOGP(DMSC, LOGL_ERROR, "Failed to allocate response.\n"); \
return; \
} \
- osmo_bsc_sigtran_send(conn->sccp_con, resp);
+ osmo_bsc_sigtran_send(conn, resp);
static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
static int complete_layer3(struct gsm_subscriber_connection *conn,
@@ -135,12 +135,12 @@ static int bsc_filter_data(struct gsm_subscriber_connection *conn,
req.ctx = conn;
req.black_list = NULL;
req.access_lists = bsc_access_lists();
- req.local_lst_name = conn->sccp_con->msc->acc_lst_name;
+ req.local_lst_name = conn->sccp.msc->acc_lst_name;
req.global_lst_name = conn_get_bts(conn)->network->bsc_data->acc_lst_name;
req.bsc_nr = 0;
rc = bsc_msg_filter_data(gh, msgb_l3len(msg), &req,
- &conn->sccp_con->filter_state,
+ &conn->filter_state,
&cause);
*lu_cause = cause.lu_reject_cause;
return rc;
@@ -280,27 +280,27 @@ static int complete_layer3(struct gsm_subscriber_connection *conn,
}
if (imsi)
- conn->sccp_con->filter_state.imsi = talloc_steal(conn, imsi);
- conn->sccp_con->filter_state.con_type = con_type;
+ conn->filter_state.imsi = talloc_steal(conn, imsi);
+ conn->filter_state.con_type = con_type;
/* check return value, if failed check msg for and send USSD */
- network_code = get_network_code_for_msc(conn->sccp_con->msc);
- country_code = get_country_code_for_msc(conn->sccp_con->msc);
- lac = get_lac_for_msc(conn->sccp_con->msc, conn_get_bts(conn));
- ci = get_ci_for_msc(conn->sccp_con->msc, conn_get_bts(conn));
+ network_code = get_network_code_for_msc(conn->sccp.msc);
+ country_code = get_country_code_for_msc(conn->sccp.msc);
+ lac = get_lac_for_msc(conn->sccp.msc, conn_get_bts(conn));
+ ci = get_ci_for_msc(conn->sccp.msc, conn_get_bts(conn));
bsc_scan_bts_msg(conn, msg);
resp = gsm0808_create_layer3(msg, network_code, country_code, lac, ci);
if (!resp) {
LOGP(DMSC, LOGL_DEBUG, "Failed to create layer3 message.\n");
- osmo_bsc_sigtran_del_conn(conn->sccp_con);
+ osmo_bsc_sigtran_del_conn(conn);
return BSC_API_CONN_POL_REJECT;
}
- if (osmo_bsc_sigtran_open_conn(conn->sccp_con, resp) != 0) {
- osmo_bsc_sigtran_del_conn(conn->sccp_con);
+ if (osmo_bsc_sigtran_open_conn(conn, resp) != 0) {
+ osmo_bsc_sigtran_del_conn(conn);
msgb_free(resp);
return BSC_API_CONN_POL_REJECT;
}
@@ -314,14 +314,11 @@ static int complete_layer3(struct gsm_subscriber_connection *conn,
static int move_to_msc(struct gsm_subscriber_connection *_conn,
struct msgb *msg, struct bsc_msc_data *msc)
{
- struct osmo_bsc_sccp_con *old_con = _conn->sccp_con;
-
/*
* 1. Give up the old connection.
* This happens by sending a clear request to the MSC,
* it should end with the MSC releasing the connection.
*/
- old_con->conn = NULL;
bsc_clear_request(_conn, 0);
/*
@@ -329,7 +326,6 @@ static int move_to_msc(struct gsm_subscriber_connection *_conn,
* MSC. If it fails the caller will need to handle this
* properly.
*/
- _conn->sccp_con = NULL;
if (complete_layer3(_conn, msg, msc) != BSC_API_CONN_POL_ACCEPT) {
gsm0808_clear(_conn);
bsc_subscr_con_free(_conn);
@@ -416,7 +412,7 @@ static void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, st
/* Check the filter */
if (bsc_filter_data(conn, msg, &lu_cause) < 0) {
bsc_maybe_lu_reject(conn,
- conn->sccp_con->filter_state.con_type,
+ conn->filter_state.con_type,
lu_cause);
bsc_clear_request(conn, 0);
return;
@@ -435,7 +431,7 @@ static void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_
struct msgb *resp;
return_when_not_connected(conn);
- if (is_ipaccess_bts(conn_get_bts(conn)) && conn->sccp_con->user_plane.rtp_ip) {
+ if (is_ipaccess_bts(conn_get_bts(conn)) && conn->user_plane.rtp_ip) {
/* NOTE: In a network that makes use of an IPA base station
* and AoIP, we have to wait until the BTS reports its RTP
* IP/Port combination back to BSC via RSL. Unfortunately, the
@@ -473,27 +469,18 @@ static void bsc_assign_fail(struct gsm_subscriber_connection *conn,
static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
{
- struct osmo_bsc_sccp_con *sccp;
struct msgb *resp;
return_when_not_connected_val(conn, 1);
LOGP(DMSC, LOGL_INFO, "Tx MSC CLEAR REQUEST\n");
- /*
- * Remove the connection from BSC<->SCCP part, the SCCP part
- * will either be cleared by channel release or MSC disconnect
- */
- sccp = conn->sccp_con;
- sccp->conn = NULL;
- conn->sccp_con = NULL;
-
resp = gsm0808_create_clear_rqst(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE);
if (!resp) {
LOGP(DMSC, LOGL_ERROR, "Failed to allocate response.\n");
return 1;
}
- osmo_bsc_sigtran_send(sccp, resp);
+ osmo_bsc_sigtran_send(conn, resp);
return 1;
}
@@ -515,14 +502,14 @@ static void bsc_mr_config(struct gsm_subscriber_connection *conn,
struct bsc_msc_data *msc;
struct gsm48_multi_rate_conf *ms_conf, *bts_conf;
- if (!conn->sccp_con) {
+ if (!conn) {
LOGP(DMSC, LOGL_ERROR,
"No msc data available on conn %p. Audio will be broken.\n",
conn);
return;
}
- msc = conn->sccp_con->msc;
+ msc = conn->sccp.msc;
/* initialize the data structure */
lchan->mr_ms_lv[0] = sizeof(*ms_conf);
diff --git a/src/osmo-bsc/osmo_bsc_audio.c b/src/osmo-bsc/osmo_bsc_audio.c
index ceec469ca..295d8543a 100644
--- a/src/osmo-bsc/osmo_bsc_audio.c
+++ b/src/osmo-bsc/osmo_bsc_audio.c
@@ -45,24 +45,24 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
return 0;
con = lchan->conn;
- if (!con || !con->sccp_con)
+ if (!con)
return 0;
switch (signal) {
case S_ABISIP_CRCX_ACK:
/* we can ask it to connect now */
LOGP(DMSC, LOGL_DEBUG, "Connecting BTS to port: %d conn: %d\n",
- con->sccp_con->user_plane.rtp_port, lchan->abis_ip.conn_id);
+ con->user_plane.rtp_port, lchan->abis_ip.conn_id);
/* If AoIP is in use, the rtp_ip, which has been communicated
* via the A interface as connect_ip */
- if(con->sccp_con->user_plane.rtp_ip)
- rtp_ip = con->sccp_con->user_plane.rtp_ip;
+ if(con->user_plane.rtp_ip)
+ rtp_ip = con->user_plane.rtp_ip;
else
rtp_ip = ntohl(INADDR_ANY);
rc = rsl_ipacc_mdcx(lchan, rtp_ip,
- con->sccp_con->user_plane.rtp_port,
+ con->user_plane.rtp_port,
lchan->abis_ip.rtp_payload2);
if (rc < 0) {
LOGP(DMSC, LOGL_ERROR, "Failed to send MDCX: %d\n", rc);
@@ -77,12 +77,22 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
/* No need to do anything for handover here. As soon as a HANDOVER DETECT
* happens, osmo_bsc_mgcp.c will trigger the MGCP MDCX towards MGW by
* receiving an S_LCHAN_HANDOVER_DETECT signal. */
- } else if (is_ipaccess_bts(conn_get_bts(con)) && con->sccp_con->user_plane.rtp_ip) {
+#if 0
+ /* NOTE: When an ho_lchan exists, the MDCX is part of an
+ * handover operation (intra-bsc). This means we will not
+ * inform the MSC about the event, which means that no
+ * assignment complete message is transmitted, we just
+ * inform the logic that controls the MGW about the new
+ * connection info */
+ LOGP(DMSC, LOGL_INFO,"RTP connection handover initiated...\n");
+ mgcp_handover(con->user_plane.mgcp_ctx, con->ho_lchan);
+#endif
+ } else if (is_ipaccess_bts(conn_get_bts(con)) && con->user_plane.rtp_ip) {
/* NOTE: This is only relevant on AoIP networks with
* IPA based base stations. See also osmo_bsc_api.c,
* function bsc_assign_compl() */
LOGP(DMSC, LOGL_INFO, "Tx MSC ASSIGN COMPL (POSTPONED)\n");
- mgcp_ass_complete(con->sccp_con->user_plane.mgcp_ctx, lchan);
+ mgcp_ass_complete(con->user_plane.mgcp_ctx, lchan);
}
break;
}
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index 0adc001be..83c884c44 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -571,19 +571,15 @@ static int bssmap_handle_paging(struct bsc_msc_data *msc,
* GSM 08.08 § 3.1.9.1 and 3.2.1.21...
* release our gsm_subscriber_connection and send message
*/
-static int bssmap_handle_clear_command(struct osmo_bsc_sccp_con *conn,
+static int bssmap_handle_clear_command(struct gsm_subscriber_connection *conn,
struct msgb *msg, unsigned int payload_length)
{
struct msgb *resp;
/* TODO: handle the cause of this package */
- if (conn->conn) {
- LOGP(DMSC, LOGL_INFO, "Releasing all transactions on %p\n", conn);
- gsm0808_clear(conn->conn);
- bsc_subscr_con_free(conn->conn);
- conn->conn = NULL;
- }
+ LOGP(DMSC, LOGL_INFO, "Releasing all transactions on %p\n", conn);
+ gsm0808_clear(conn);
/* generate the clear complete message */
resp = gsm0808_create_clear_complete();
@@ -618,7 +614,7 @@ static int bssmap_handle_clear_command(struct osmo_bsc_sccp_con *conn,
* is supporting. Currently we are doing it in a rather static
* way by picking one encryption or no encryption.
*/
-static int bssmap_handle_cipher_mode(struct osmo_bsc_sccp_con *conn,
+static int bssmap_handle_cipher_mode(struct gsm_subscriber_connection *conn,
struct msgb *msg, unsigned int payload_length)
{
uint16_t len;
@@ -633,7 +629,7 @@ static int bssmap_handle_cipher_mode(struct osmo_bsc_sccp_con *conn,
uint8_t enc_bits_bsc;
uint8_t enc_bits_msc;
- if (!conn->conn) {
+ if (!conn) {
LOGP(DMSC, LOGL_ERROR, "No lchan/msc_data in cipher mode command.\n");
goto reject;
}
@@ -663,7 +659,7 @@ static int bssmap_handle_cipher_mode(struct osmo_bsc_sccp_con *conn,
goto reject;
}
- network = conn_get_bts(conn->conn)->network;
+ network = conn_get_bts(conn)->network;
data = TLVP_VAL(&tp, GSM0808_IE_ENCRYPTION_INFORMATION);
enc_bits_msc = data[0];
enc_key = &data[1];
@@ -692,7 +688,7 @@ static int bssmap_handle_cipher_mode(struct osmo_bsc_sccp_con *conn,
/* To complete the confusion, gsm0808_cipher_mode again expects the encryption as a number
* from 0 to 7. */
- if (gsm0808_cipher_mode(conn->conn, network->a5_encryption, enc_key, enc_key_len,
+ if (gsm0808_cipher_mode(conn, network->a5_encryption, enc_key, enc_key_len,
include_imeisv)) {
reject_cause = GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC;
goto reject;
@@ -728,7 +724,7 @@ static inline int mgcp_timeslot_to_port(int multiplex, int timeslot, int base)
*
* See §3.2.1.1 for the message type
*/
-static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
+static int bssmap_handle_assignm_req(struct gsm_subscriber_connection *conn,
struct msgb *msg, unsigned int length)
{
struct msgb *resp;
@@ -744,13 +740,13 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
struct gsm0808_speech_codec_list *scl_ptr = NULL;
int rc;
- if (!conn->conn) {
+ if (!conn) {
LOGP(DMSC, LOGL_ERROR,
"No lchan/msc_data in cipher mode command.\n");
return -1;
}
- msc = conn->msc;
+ msc = conn->sccp.msc;
tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l4h + 1, length - 1, 0, 0);
@@ -799,7 +795,7 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
}
/* Decode speech codec list (AoIP) */
- conn->conn->codec_list_present = false;
+ conn->codec_list_present = false;
if (aoip) {
/* Check for speech codec list element */
if (!TLVP_PRESENT(&tp, GSM0808_IE_SPEECH_CODEC_LIST)) {
@@ -809,7 +805,7 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
}
/* Decode Speech Codec list */
- rc = gsm0808_dec_speech_codec_list(&conn->conn->codec_list,
+ rc = gsm0808_dec_speech_codec_list(&conn->codec_list,
TLVP_VAL(&tp, GSM0808_IE_SPEECH_CODEC_LIST),
TLVP_LEN(&tp, GSM0808_IE_SPEECH_CODEC_LIST));
if (rc < 0) {
@@ -817,8 +813,8 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
"Unable to decode speech codec list\n");
goto reject;
}
- conn->conn->codec_list_present = true;
- scl_ptr = &conn->conn->codec_list;
+ conn->codec_list_present = true;
+ scl_ptr = &conn->codec_list;
}
/* Match codec information from the assignment command against the
@@ -856,7 +852,8 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
conn->user_plane.mgcp_ctx = mgcp_assignm_req(msc->network, msc->network->mgw.client,
conn, chan_mode, full_rate);
if (!conn->user_plane.mgcp_ctx) {
- LOGP(DMSC, LOGL_ERROR, "MGCP GW failure, rejecting assignment... (id=%i)\n", conn->conn_id);
+ LOGP(DMSC, LOGL_ERROR, "MGCP GW failure, rejecting assignment... (id=%i)\n",
+ conn->sccp.conn_id);
goto reject;
}
@@ -869,7 +866,7 @@ static int bssmap_handle_assignm_req(struct osmo_bsc_sccp_con *conn,
* to sccp-lite. */
conn->user_plane.rtp_port = mgcp_timeslot_to_port(multiplex, timeslot, msc->rtp_base);
conn->user_plane.rtp_ip = 0;
- return gsm0808_assign_req(conn->conn, chan_mode, full_rate);
+ return gsm0808_assign_req(conn, chan_mode, full_rate);
}
reject:
@@ -917,7 +914,7 @@ static int bssmap_rcvmsg_udt(struct bsc_msc_data *msc,
return ret;
}
-static int bssmap_rcvmsg_dt1(struct osmo_bsc_sccp_con *conn,
+static int bssmap_rcvmsg_dt1(struct gsm_subscriber_connection *conn,
struct msgb *msg, unsigned int length)
{
int ret = 0;
@@ -949,7 +946,7 @@ static int bssmap_rcvmsg_dt1(struct osmo_bsc_sccp_con *conn,
return ret;
}
-static int dtap_rcvmsg(struct osmo_bsc_sccp_con *conn,
+static int dtap_rcvmsg(struct gsm_subscriber_connection *conn,
struct msgb *msg, unsigned int length)
{
struct dtap_header *header;
@@ -960,7 +957,7 @@ static int dtap_rcvmsg(struct osmo_bsc_sccp_con *conn,
LOGP(DMSC, LOGL_DEBUG, "Rx MSC DTAP: %s\n",
osmo_hexdump(msg->l3h, length));
- if (!conn->conn) {
+ if (!conn) {
LOGP(DMSC, LOGL_ERROR, "No subscriber connection available\n");
return -1;
}
@@ -992,10 +989,10 @@ static int dtap_rcvmsg(struct osmo_bsc_sccp_con *conn,
memcpy(data, msg->l3h + sizeof(*header), length - sizeof(*header));
/* pass it to the filter for extra actions */
- rc = bsc_scan_msc_msg(conn->conn, gsm48);
- dtap_rc = gsm0808_submit_dtap(conn->conn, gsm48, header->link_id, 1);
+ rc = bsc_scan_msc_msg(conn, gsm48);
+ dtap_rc = gsm0808_submit_dtap(conn, gsm48, header->link_id, 1);
if (rc == BSS_SEND_USSD)
- bsc_send_welcome_ussd(conn->conn);
+ bsc_send_welcome_ussd(conn);
return dtap_rc;
}
@@ -1029,7 +1026,7 @@ int bsc_handle_udt(struct bsc_msc_data *msc,
return 0;
}
-int bsc_handle_dt(struct osmo_bsc_sccp_con *conn,
+int bsc_handle_dt(struct gsm_subscriber_connection *conn,
struct msgb *msg, unsigned int len)
{
if (len < sizeof(struct bssmap_header)) {
@@ -1063,9 +1060,8 @@ int bssmap_send_aoip_ass_compl(struct gsm_lchan *lchan)
OSMO_ASSERT(lchan->abis_ip.ass_compl.valid);
OSMO_ASSERT(conn);
- OSMO_ASSERT(conn->sccp_con);
- LOGP(DMSC, LOGL_DEBUG, "Sending assignment complete message... (id=%i)\n", conn->sccp_con->conn_id);
+ LOGP(DMSC, LOGL_DEBUG, "Sending assignment complete message... (id=%i)\n", conn->sccp.conn_id);
/* Extrapolate speech codec from speech mode */
gsm0808_speech_codec_from_chan_type(&sc, lchan->abis_ip.ass_compl.speech_mode);
@@ -1075,15 +1071,15 @@ int bssmap_send_aoip_ass_compl(struct gsm_lchan *lchan)
lchan->abis_ip.ass_compl.chosen_channel,
lchan->abis_ip.ass_compl.encr_alg_id,
lchan->abis_ip.ass_compl.speech_mode,
- &conn->sccp_con->user_plane.aoip_rtp_addr_local,
+ &conn->user_plane.aoip_rtp_addr_local,
&sc,
NULL);
if (!resp) {
LOGP(DMSC, LOGL_ERROR, "Failed to generate assignment completed message! (id=%i)\n",
- conn->sccp_con->conn_id);
+ conn->sccp.conn_id);
return -EINVAL;
}
- return osmo_bsc_sigtran_send(conn->sccp_con, resp);
+ return osmo_bsc_sigtran_send(conn, resp);
}
diff --git a/src/osmo-bsc/osmo_bsc_ctrl.c b/src/osmo-bsc/osmo_bsc_ctrl.c
index fc7908656..6092f2379 100644
--- a/src/osmo-bsc/osmo_bsc_ctrl.c
+++ b/src/osmo-bsc/osmo_bsc_ctrl.c
@@ -570,10 +570,7 @@ static int set_net_ussd_notify(struct ctrl_cmd *cmd, void *data)
net = cmd->node;
llist_for_each_entry(conn, &net->subscr_conns, entry) {
- if (!conn->sccp_con)
- continue;
-
- if (conn->sccp_con->user_plane.cic != cic)
+ if (conn->user_plane.cic != cic)
continue;
/*
diff --git a/src/osmo-bsc/osmo_bsc_filter.c b/src/osmo-bsc/osmo_bsc_filter.c
index 5399b7aee..c1f3e80a6 100644
--- a/src/osmo-bsc/osmo_bsc_filter.c
+++ b/src/osmo-bsc/osmo_bsc_filter.c
@@ -54,7 +54,7 @@ static void handle_lu_request(struct gsm_subscriber_connection *conn,
if (memcmp(&lai, &lu->lai, sizeof(lai)) != 0) {
LOGP(DMSC, LOGL_DEBUG, "Marking con for welcome USSD.\n");
- conn->sccp_con->new_subscriber = 1;
+ conn->new_subscriber = 1;
}
}
@@ -234,15 +234,7 @@ int bsc_scan_bts_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
static int send_welcome_ussd(struct gsm_subscriber_connection *conn)
{
- struct osmo_bsc_sccp_con *bsc_con;
-
- bsc_con = conn->sccp_con;
- if (!bsc_con) {
- LOGP(DMSC, LOGL_DEBUG, "No SCCP connection associated.\n");
- return 0;
- }
-
- if (!bsc_con->msc->ussd_welcome_txt) {
+ if (!conn->sccp.msc->ussd_welcome_txt) {
LOGP(DMSC, LOGL_DEBUG, "No USSD Welcome text defined.\n");
return 0;
}
@@ -252,7 +244,7 @@ static int send_welcome_ussd(struct gsm_subscriber_connection *conn)
int bsc_send_welcome_ussd(struct gsm_subscriber_connection *conn)
{
- bsc_send_ussd_notify(conn, 1, conn->sccp_con->msc->ussd_welcome_txt);
+ bsc_send_ussd_notify(conn, 1, conn->sccp.msc->ussd_welcome_txt);
bsc_send_ussd_release_complete(conn);
return 0;
@@ -362,7 +354,7 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
mtype = gsm48_hdr_msg_type(gh);
net = bts->network;
- msc = conn->sccp_con->msc;
+ msc = conn->sccp.msc;
if (mtype == GSM48_MT_MM_LOC_UPD_ACCEPT) {
if (has_core_identity(msc)) {
@@ -375,7 +367,7 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
}
}
- if (conn->sccp_con->new_subscriber)
+ if (conn->new_subscriber)
return send_welcome_ussd(conn);
return 0;
} else if (mtype == GSM48_MT_MM_INFO) {
diff --git a/src/osmo-bsc/osmo_bsc_mgcp.c b/src/osmo-bsc/osmo_bsc_mgcp.c
index bdf2dd283..4b6420e9b 100644
--- a/src/osmo-bsc/osmo_bsc_mgcp.c
+++ b/src/osmo-bsc/osmo_bsc_mgcp.c
@@ -151,7 +151,7 @@ static void crcx_for_bts_resp_cb(struct mgcp_response *r, void *priv);
static void fsm_crcx_bts_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct mgcp_ctx *mgcp_ctx = data;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
struct msgb *msg;
struct mgcp_msg mgcp_msg;
struct mgcp_client *mgcp;
@@ -174,7 +174,7 @@ static void fsm_crcx_bts_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data
mgcp_msg = (struct mgcp_msg) {
.verb = MGCP_VERB_CRCX,
.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | MGCP_MSG_PRESENCE_CONN_MODE),
- .call_id = conn->conn_id,
+ .call_id = conn->sccp.conn_id,
.conn_mode = MGCP_CONN_LOOPBACK
};
if (snprintf(mgcp_msg.endpoint, MGCP_ENDPOINT_MAXLEN, MGCP_ENDPOINT_FORMAT, rtp_endpoint) >=
@@ -201,7 +201,7 @@ static void crcx_for_bts_resp_cb(struct mgcp_response *r, void *priv)
{
struct mgcp_ctx *mgcp_ctx = priv;
int rc;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
uint32_t addr;
OSMO_ASSERT(mgcp_ctx);
@@ -256,7 +256,7 @@ static void crcx_for_bts_resp_cb(struct mgcp_response *r, void *priv)
static void fsm_proc_assignmnent_req_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct mgcp_ctx *mgcp_ctx = data;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
enum gsm48_chan_mode chan_mode;
bool full_rate;
int rc;
@@ -273,12 +273,12 @@ static void fsm_proc_assignmnent_req_cb(struct osmo_fsm_inst *fi, uint32_t event
return;
}
- OSMO_ASSERT(conn->conn);
+ OSMO_ASSERT(conn);
chan_mode = mgcp_ctx->chan_mode;
full_rate = mgcp_ctx->full_rate;
LOGPFSML(fi, LOGL_DEBUG, "MGW proceeding assignment request...\n");
- rc = gsm0808_assign_req(conn->conn, chan_mode, full_rate);
+ rc = gsm0808_assign_req(conn, chan_mode, full_rate);
if (rc < 0) {
handle_error(mgcp_ctx, MGCP_ERR_ASSGMNT_FAIL);
@@ -295,7 +295,7 @@ static void mdcx_for_bts_resp_cb(struct mgcp_response *r, void *priv);
static void fsm_mdcx_bts_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct mgcp_ctx *mgcp_ctx = data;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
struct gsm_lchan *lchan;
struct msgb *msg;
struct mgcp_msg mgcp_msg;
@@ -333,7 +333,7 @@ static void fsm_mdcx_bts_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data
.verb = MGCP_VERB_MDCX,
.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | MGCP_MSG_PRESENCE_CONN_ID |
MGCP_MSG_PRESENCE_CONN_MODE | MGCP_MSG_PRESENCE_AUDIO_IP | MGCP_MSG_PRESENCE_AUDIO_PORT),
- .call_id = conn->conn_id,
+ .call_id = conn->sccp.conn_id,
.conn_id = mgcp_ctx->conn_id_bts,
.conn_mode = MGCP_CONN_RECV_SEND,
.audio_ip = inet_ntoa(addr),
@@ -407,7 +407,7 @@ static void crcx_for_net_resp_cb(struct mgcp_response *r, void *priv);
static void fsm_crcx_net_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct mgcp_ctx *mgcp_ctx = data;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
struct msgb *msg;
struct mgcp_msg mgcp_msg;
struct mgcp_client *mgcp;
@@ -460,7 +460,7 @@ static void fsm_crcx_net_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data
.verb = MGCP_VERB_CRCX,
.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | MGCP_MSG_PRESENCE_CONN_MODE |
MGCP_MSG_PRESENCE_AUDIO_IP | MGCP_MSG_PRESENCE_AUDIO_PORT),
- .call_id = conn->conn_id,
+ .call_id = conn->sccp.conn_id,
.conn_mode = MGCP_CONN_RECV_SEND,
.audio_ip = addr,
.audio_port = port
@@ -489,7 +489,7 @@ static void crcx_for_net_resp_cb(struct mgcp_response *r, void *priv)
{
struct mgcp_ctx *mgcp_ctx = priv;
int rc;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
struct gsm_lchan *lchan;
struct sockaddr_in *sin;
uint32_t addr;
@@ -581,7 +581,7 @@ static void mdcx_for_bts_ho_resp_cb(struct mgcp_response *r, void *priv);
* change to ST_HALT when teardown is done. */
static void handle_teardown(struct mgcp_ctx *mgcp_ctx)
{
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
struct msgb *msg;
struct mgcp_msg mgcp_msg;
struct mgcp_client *mgcp;
@@ -607,7 +607,7 @@ static void handle_teardown(struct mgcp_ctx *mgcp_ctx)
mgcp_msg = (struct mgcp_msg) {
.verb = MGCP_VERB_DLCX,
.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID),
- .call_id = conn->conn_id
+ .call_id = conn->sccp.conn_id
};
if (snprintf(mgcp_msg.endpoint, sizeof(mgcp_msg.endpoint), MGCP_ENDPOINT_FORMAT, rtp_endpoint) >=
sizeof(mgcp_msg.endpoint)) {
@@ -633,7 +633,7 @@ static void handle_teardown(struct mgcp_ctx *mgcp_ctx)
* change to ST_CALL when teardown is done. */
static void handle_handover(struct mgcp_ctx *mgcp_ctx)
{
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
struct msgb *msg;
struct mgcp_msg mgcp_msg;
struct mgcp_client *mgcp;
@@ -663,7 +663,7 @@ static void handle_handover(struct mgcp_ctx *mgcp_ctx)
.presence = (MGCP_MSG_PRESENCE_ENDPOINT | MGCP_MSG_PRESENCE_CALL_ID | MGCP_MSG_PRESENCE_CONN_ID |
MGCP_MSG_PRESENCE_CONN_MODE | MGCP_MSG_PRESENCE_AUDIO_IP |
MGCP_MSG_PRESENCE_AUDIO_PORT),
- .call_id = conn->conn_id,
+ .call_id = conn->sccp.conn_id,
.conn_id = mgcp_ctx->conn_id_bts,
.conn_mode = MGCP_CONN_RECV_SEND,
.audio_ip = inet_ntoa(addr),
@@ -766,7 +766,7 @@ static void fsm_complete_handover(struct osmo_fsm_inst *fi, uint32_t event, void
static void dlcx_for_all_resp_cb(struct mgcp_response *r, void *priv)
{
struct mgcp_ctx *mgcp_ctx = priv;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
struct mgcp_client *mgcp;
OSMO_ASSERT(mgcp_ctx);
@@ -799,7 +799,7 @@ static void dlcx_for_all_resp_cb(struct mgcp_response *r, void *priv)
static void fsm_halt_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct mgcp_ctx *mgcp_ctx = (struct mgcp_ctx *)data;
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
OSMO_ASSERT(mgcp_ctx);
conn = mgcp_ctx->conn;
@@ -960,7 +960,8 @@ static struct osmo_fsm fsm_bsc_mgcp = {
* chan_mode: channel mode (system data, passed through)
* full_rate: full rate flag (system data, passed through)
* Returns an mgcp_context that contains system data and the OSMO-FSM */
-struct mgcp_ctx *mgcp_assignm_req(void *ctx, struct mgcp_client *mgcp, struct osmo_bsc_sccp_con *conn,
+struct mgcp_ctx *mgcp_assignm_req(void *ctx, struct mgcp_client *mgcp,
+ struct gsm_subscriber_connection *conn,
enum gsm48_chan_mode chan_mode, bool full_rate)
{
struct mgcp_ctx *mgcp_ctx;
@@ -969,7 +970,7 @@ struct mgcp_ctx *mgcp_assignm_req(void *ctx, struct mgcp_client *mgcp, struct os
OSMO_ASSERT(mgcp);
OSMO_ASSERT(conn);
- OSMO_ASSERT(snprintf(name, sizeof(name), "MGW_%i", conn->conn_id) < sizeof(name));
+ OSMO_ASSERT(snprintf(name, sizeof(name), "MGW_%i", conn->sccp.conn_id) < sizeof(name));
/* Allocate and configure a new fsm instance */
mgcp_ctx = talloc_zero(ctx, struct mgcp_ctx);
@@ -997,7 +998,7 @@ struct mgcp_ctx *mgcp_assignm_req(void *ctx, struct mgcp_client *mgcp, struct os
* respmgcp_ctx: pending clear complete message to send via A-Interface */
void mgcp_clear_complete(struct mgcp_ctx *mgcp_ctx, struct msgb *resp)
{
- struct osmo_bsc_sccp_con *conn;
+ struct gsm_subscriber_connection *conn;
OSMO_ASSERT(mgcp_ctx);
OSMO_ASSERT(resp);
@@ -1086,19 +1087,19 @@ static int mgcp_sig_ho_detect(struct gsm_lchan *new_lchan)
return -EINVAL;
}
- if (!conn->sccp_con) {
- LOGP(DHO, LOGL_ERROR, "%s HO Detect for conn without sccp_con\n",
+ if (!conn->sccp.conn_id) {
+ LOGP(DHO, LOGL_ERROR, "%s HO Detect for conn without sccp_conn_id\n",
gsm_lchan_name(new_lchan));
return -EINVAL;
}
- if (!conn->sccp_con->user_plane.mgcp_ctx) {
+ if (!conn->user_plane.mgcp_ctx) {
LOGP(DHO, LOGL_ERROR, "%s HO Detect for conn without MGCP ctx\n",
gsm_lchan_name(new_lchan));
return -EINVAL;
}
- mgcp_handover(conn->sccp_con->user_plane.mgcp_ctx, new_lchan);
+ mgcp_handover(conn->user_plane.mgcp_ctx, new_lchan);
return 0;
}
diff --git a/src/osmo-bsc/osmo_bsc_sigtran.c b/src/osmo-bsc/osmo_bsc_sigtran.c
index 5b065105f..0ffc14687 100644
--- a/src/osmo-bsc/osmo_bsc_sigtran.c
+++ b/src/osmo-bsc/osmo_bsc_sigtran.c
@@ -38,28 +38,26 @@
* (a copy of the pointer location submitted with osmo_bsc_sigtran_init() */
static struct llist_head *msc_list;
+extern struct gsm_network *bsc_gsmnet;
+
#define RESET_INTERVAL 1 /* sek */
#define SCCP_MSG_MAXSIZE 1024
#define CS7_POINTCODE_DEFAULT_OFFSET 2
-/* Internal list with connections we currently maintain. This
- * list is of type struct osmo_bsc_sccp_con */
-static LLIST_HEAD(active_connections);
-
/* The SCCP stack will not assign connection IDs to us automatically, we
* will do this ourselves using a counter variable, that counts one up
* for every new connection */
static uint32_t conn_id_counter;
/* Helper function to Check if the given connection id is already assigned */
-static struct osmo_bsc_sccp_con *get_bsc_conn_by_conn_id(int conn_id)
+static struct gsm_subscriber_connection *get_bsc_conn_by_conn_id(int conn_id)
{
conn_id &= 0xFFFFFF;
- struct osmo_bsc_sccp_con *bsc_con;
+ struct gsm_subscriber_connection *conn;
- llist_for_each_entry(bsc_con, &active_connections, entry) {
- if (bsc_con->conn_id == conn_id)
- return bsc_con;
+ llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) {
+ if (conn->sccp.conn_id == conn_id)
+ return conn;
}
return NULL;
@@ -131,12 +129,12 @@ static struct bsc_msc_data *get_msc_by_addr(const struct osmo_sccp_addr *msc_add
/* Send data to MSC, use the connection id which MSC it is */
static int handle_data_from_msc(int conn_id, struct msgb *msg)
{
- struct osmo_bsc_sccp_con *bsc_con = get_bsc_conn_by_conn_id(conn_id);
+ struct gsm_subscriber_connection *conn = get_bsc_conn_by_conn_id(conn_id);
int rc = -EINVAL;
- if (bsc_con) {
+ if (conn) {
msg->l3h = msgb_l2(msg);
- rc = bsc_handle_dt(bsc_con, msg, msgb_l2len(msg));
+ rc = bsc_handle_dt(conn, msg, msgb_l2len(msg));
} else
LOGP(DMSC, LOGL_NOTICE, "incoming data from unknown connection id: %i\n", conn_id);
@@ -168,7 +166,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
{
struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *)oph;
struct osmo_sccp_user *scu = _scu;
- struct osmo_bsc_sccp_con *bsc_con;
+ struct gsm_subscriber_connection *conn;
int rc = 0;
switch (OSMO_PRIM_HDR(&scu_prim->oph)) {
@@ -187,6 +185,9 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM):
/* Handle outbound connection confirmation */
+ conn = get_bsc_conn_by_conn_id(scu_prim->u.connect.conn_id);
+ if (conn)
+ conn->sccp.state = SUBSCR_SCCP_ST_CONNECTED;
if (msgb_l2len(oph->msg) > 0) {
DEBUGP(DMSC, "N-CONNECT.cnf(%u, %s)\n", scu_prim->u.connect.conn_id,
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
@@ -201,32 +202,28 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)));
/* Incoming data is a sign of a vital connection */
- bsc_con = get_bsc_conn_by_conn_id(scu_prim->u.disconnect.conn_id);
- if (bsc_con)
- a_reset_conn_success(bsc_con->msc->a.reset);
+ conn = get_bsc_conn_by_conn_id(scu_prim->u.disconnect.conn_id);
+ if (conn)
+ a_reset_conn_success(conn->sccp.msc->a.reset);
rc = handle_data_from_msc(scu_prim->u.data.conn_id, oph->msg);
break;
case OSMO_PRIM(OSMO_SCU_PRIM_N_DISCONNECT, PRIM_OP_INDICATION):
/* indication of disconnect */
+ conn = get_bsc_conn_by_conn_id(scu_prim->u.disconnect.conn_id);
+ if (conn)
+ conn->sccp.state = SUBSCR_SCCP_ST_NONE;
if (msgb_l2len(oph->msg) > 0) {
DEBUGP(DMSC, "N-DISCONNECT.ind(%u, %s, cause=%i)\n", scu_prim->u.disconnect.conn_id,
osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)), scu_prim->u.disconnect.cause);
handle_data_from_msc(scu_prim->u.disconnect.conn_id, oph->msg);
- } else
+ } else {
DEBUGP(DRANAP, "N-DISCONNECT.ind(%u, cause=%i)\n", scu_prim->u.disconnect.conn_id,
scu_prim->u.disconnect.cause);
-
- bsc_con = get_bsc_conn_by_conn_id(scu_prim->u.disconnect.conn_id);
- if (bsc_con) {
- /* We might have a connectivity problem. Maybe we need to go
- * through the reset procedure again? */
- if (scu_prim->u.disconnect.cause == 0)
- a_reset_conn_fail(bsc_con->msc->a.reset);
-
- rc = osmo_bsc_sigtran_del_conn(bsc_con);
}
+ if (conn)
+ rc = osmo_bsc_sigtran_del_conn(conn);
break;
default:
@@ -244,9 +241,7 @@ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu)
enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, struct bsc_msc_data *msc)
{
struct osmo_ss7_instance *ss7;
- struct osmo_bsc_sccp_con *bsc_con;
struct gsm_bts *bts = conn_get_bts(conn);
- int conn_id;
OSMO_ASSERT(conn);
OSMO_ASSERT(msc);
@@ -266,30 +261,13 @@ enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, s
return BSC_CON_REJECT_RF_GRACE;
}
- bsc_con = talloc_zero(bts, struct osmo_bsc_sccp_con);
- if (!bsc_con) {
- LOGP(DMSC, LOGL_ERROR, "Failed to allocate new SIGTRAN connection.\n");
- return BSC_CON_NO_MEM;
- }
-
- bsc_con->msc = msc;
- bsc_con->conn = conn;
- llist_add_tail(&bsc_con->entry, &active_connections);
- conn->sccp_con = bsc_con;
-
- /* Pick a free connection id */
- conn_id = pick_free_conn_id(msc);
- if (conn_id < 0)
- return BSC_CON_REJECT_NO_LINK;
- bsc_con->conn_id = conn_id;
-
- LOGP(DMSC, LOGL_NOTICE, "Allocated new connection id: %i\n", conn_id);
+ conn->sccp.msc = msc;
return BSC_CON_SUCCESS;
}
/* Open a new connection oriented sigtran connection */
-int osmo_bsc_sigtran_open_conn(const struct osmo_bsc_sccp_con *conn, struct msgb *msg)
+int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
struct osmo_ss7_instance *ss7;
struct bsc_msc_data *msc;
@@ -298,16 +276,22 @@ int osmo_bsc_sigtran_open_conn(const struct osmo_bsc_sccp_con *conn, struct msgb
OSMO_ASSERT(conn);
OSMO_ASSERT(msg);
- OSMO_ASSERT(conn->msc);
+ OSMO_ASSERT(conn->sccp.msc);
+ OSMO_ASSERT(conn->sccp.conn_id == -1);
- msc = conn->msc;
+ msc = conn->sccp.msc;
if (a_reset_conn_ready(msc->a.reset) == false) {
LOGP(DMSC, LOGL_ERROR, "MSC is not connected. Dropping.\n");
return -EINVAL;
}
- conn_id = conn->conn_id;
+ conn->sccp.conn_id = conn_id = pick_free_conn_id(msc);
+ if (conn->sccp.conn_id < 0) {
+ LOGP(DMSC, LOGL_ERROR, "Unable to allocate SCCP Connection ID\n");
+ return -1;
+ }
+ LOGP(DMSC, LOGL_DEBUG, "Allocated new connection id: %d\n", conn->sccp.conn_id);
ss7 = osmo_ss7_instance_find(msc->a.cs7_instance);
OSMO_ASSERT(ss7);
LOGP(DMSC, LOGL_NOTICE, "Opening new SIGTRAN connection (id=%i) to MSC: %s\n", conn_id,
@@ -315,12 +299,14 @@ int osmo_bsc_sigtran_open_conn(const struct osmo_bsc_sccp_con *conn, struct msgb
rc = osmo_sccp_tx_conn_req_msg(msc->a.sccp_user, conn_id, &msc->a.bsc_addr,
&msc->a.msc_addr, msg);
+ if (rc >= 0)
+ conn->sccp.state = SUBSCR_SCCP_ST_WAIT_CONN_CONF;
return rc;
}
/* Send data to MSC */
-int osmo_bsc_sigtran_send(const struct osmo_bsc_sccp_con *conn, struct msgb *msg)
+int osmo_bsc_sigtran_send(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
struct osmo_ss7_instance *ss7;
int conn_id;
@@ -329,9 +315,9 @@ int osmo_bsc_sigtran_send(const struct osmo_bsc_sccp_con *conn, struct msgb *msg
OSMO_ASSERT(conn);
OSMO_ASSERT(msg);
- OSMO_ASSERT(conn->msc);
+ OSMO_ASSERT(conn->sccp.msc);
- msc = conn->msc;
+ msc = conn->sccp.msc;
/* Log the type of the message we are sending. This is just
* informative, do not stop if detecting the type fails */
@@ -354,7 +340,7 @@ int osmo_bsc_sigtran_send(const struct osmo_bsc_sccp_con *conn, struct msgb *msg
return -EINVAL;
}
- conn_id = conn->conn_id;
+ conn_id = conn->sccp.conn_id;
ss7 = osmo_ss7_instance_find(msc->a.cs7_instance);
OSMO_ASSERT(ss7);
@@ -369,80 +355,66 @@ int osmo_bsc_sigtran_send(const struct osmo_bsc_sccp_con *conn, struct msgb *msg
/* Delete a connection from the list with open connections
* (called by osmo_bsc_api.c on failing open connections and
* locally, when a connection is closed by the MSC */
-int osmo_bsc_sigtran_del_conn(struct osmo_bsc_sccp_con *conn)
+int osmo_bsc_sigtran_del_conn(struct gsm_subscriber_connection *conn)
{
if (!conn)
return 0;
- if (conn->conn) {
- LOGP(DMSC, LOGL_ERROR,
- "sccp connection (id=%i) not cleared (gsm subscriber connection still active) -- forcefully clearing it now!\n",
- conn->conn_id);
- bsc_subscr_con_free(conn->conn);
- conn->conn = NULL;
+ LOGP(DMSC, LOGL_ERROR,
+ "sccp connection (id=%i) not cleared (gsm subscriber connection still active) -- forcefully clearing it now!\n", conn->sccp.conn_id);
- /* This bahaviour might be caused by a bad connection. Maybe we
- * will have to go through the reset procedure again */
- a_reset_conn_fail(conn->msc->a.reset);
- }
+ /* This bahaviour might be caused by a bad connection. Maybe we
+ * will have to go through the reset procedure again */
+ a_reset_conn_fail(conn->sccp.msc->a.reset);
/* Remove mgcp context if existant */
if (conn->user_plane.mgcp_ctx)
mgcp_free_ctx(conn->user_plane.mgcp_ctx);
- llist_del(&conn->entry);
- talloc_free(conn);
+ /* free the "conn" and make sure any pending lchans are also free'd */
+ bsc_subscr_con_free(conn);
return 0;
}
/* Send an USSD notification in case we loose the connection to the MSC */
-static void bsc_notify_msc_lost(const struct osmo_bsc_sccp_con *conn)
+static void bsc_notify_msc_lost(struct gsm_subscriber_connection *conn)
{
- struct gsm_subscriber_connection *subscr_conn;
-
/* Check if sccp conn is still present */
if (!conn)
return;
- subscr_conn = conn->conn;
-
- /* send USSD notification if string configured and conn->data is set */
- if (!subscr_conn)
- return;
/* check for config string */
- if (!conn->msc->ussd_msc_lost_txt)
+ if (!conn->sccp.msc->ussd_msc_lost_txt)
return;
- if (conn->msc->ussd_msc_lost_txt[0] == '\0')
+ if (conn->sccp.msc->ussd_msc_lost_txt[0] == '\0')
return;
/* send USSD notification */
- bsc_send_ussd_notify(subscr_conn, 1, subscr_conn->sccp_con->msc->ussd_msc_lost_txt);
- bsc_send_ussd_release_complete(subscr_conn);
+ bsc_send_ussd_notify(conn, 1, conn->sccp.msc->ussd_msc_lost_txt);
+ bsc_send_ussd_release_complete(conn);
}
/* Close all open sigtran connections and channels */
void osmo_bsc_sigtran_reset(const struct bsc_msc_data *msc)
{
- struct osmo_bsc_sccp_con *conn;
- struct osmo_bsc_sccp_con *conn_temp;
+ struct gsm_subscriber_connection *conn, *conn_temp;
OSMO_ASSERT(msc);
/* Close all open connections */
- llist_for_each_entry_safe(conn, conn_temp, &active_connections, entry) {
+ llist_for_each_entry_safe(conn, conn_temp, &bsc_gsmnet->subscr_conns, entry) {
/* We only may close connections which actually belong to this
* MSC. All other open connections are left untouched */
- if (conn->msc == msc) {
+ if (conn->sccp.msc == msc) {
/* Notify active connection users via USSD that the MSC is down */
bsc_notify_msc_lost(conn);
/* Take down all occopied RF channels */
- if (conn->conn)
- gsm0808_clear(conn->conn);
+ gsm0808_clear(conn);
/* Disconnect all Sigtran connections */
- osmo_sccp_tx_disconn(msc->a.sccp_user, conn->conn_id, &msc->a.bsc_addr, 0);
+ osmo_sccp_tx_disconn(msc->a.sccp_user, conn->sccp.conn_id, &msc->a.bsc_addr, 0);
/* Delete subscriber connection */
osmo_bsc_sigtran_del_conn(conn);
diff --git a/tests/bsc/bsc_test.c b/tests/bsc/bsc_test.c
index 19bb608e0..9c35d2f60 100644
--- a/tests/bsc/bsc_test.c
+++ b/tests/bsc/bsc_test.c
@@ -124,17 +124,14 @@ static void test_scan(void)
struct gsm_network *net = bsc_network_init(NULL, 1, 1);
struct gsm_bts *bts = gsm_bts_alloc(net, 0);
- struct osmo_bsc_sccp_con *sccp_con;
struct bsc_msc_data *msc;
struct gsm_subscriber_connection *conn;
- sccp_con = talloc_zero(net, struct osmo_bsc_sccp_con);
msc = talloc_zero(net, struct bsc_msc_data);
conn = talloc_zero(net, struct gsm_subscriber_connection);
bts->network = net;
- sccp_con->msc = msc;
- conn->sccp_con = sccp_con;
+ conn->sccp.msc = msc;
conn->lchan = &bts->c0->ts[1].lchan[0];
/* start testing with proper messages */
diff --git a/tests/bssap/bssap_test.c b/tests/bssap/bssap_test.c
index 861c98fa8..ad8974f73 100644
--- a/tests/bssap/bssap_test.c
+++ b/tests/bssap/bssap_test.c
@@ -80,22 +80,23 @@ struct {
},
};
+struct gsm_network *bsc_gsmnet;
+
void test_cell_identifier()
{
int i;
int rc;
- struct gsm_network *net;
struct bsc_msc_data *msc;
struct gsm_bts *bts;
- net = bsc_network_init(NULL, 1, 1);
- net->bsc_data->rf_ctrl = talloc_zero(NULL, struct osmo_bsc_rf);
- net->bsc_data->rf_ctrl->policy = S_RF_ON;
+ bsc_gsmnet = bsc_network_init(NULL, 1, 1);
+ bsc_gsmnet->bsc_data->rf_ctrl = talloc_zero(NULL, struct osmo_bsc_rf);
+ bsc_gsmnet->bsc_data->rf_ctrl->policy = S_RF_ON;
- msc = talloc_zero(net, struct bsc_msc_data);
- msc->network = net;
+ msc = talloc_zero(bsc_gsmnet, struct bsc_msc_data);
+ msc->network = bsc_gsmnet;
- bts = gsm_bts_alloc_register(net, GSM_BTS_TYPE_UNKNOWN, 0);
+ bts = gsm_bts_alloc_register(bsc_gsmnet, GSM_BTS_TYPE_UNKNOWN, 0);
if (bts == NULL) {
fprintf(stderr, "gsm_bts_alloc_register() returned NULL\n");
return;