aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/bsc_data.h100
-rw-r--r--include/bsc_sccp.h10
-rw-r--r--include/bsc_ussd.h6
-rw-r--r--include/mtp_data.h2
-rw-r--r--src/bsc_sccp.c19
-rw-r--r--src/links.c2
-rw-r--r--src/main.c158
-rw-r--r--src/main_stp.c15
-rw-r--r--src/main_udt.c43
-rw-r--r--src/msc_conn.c235
-rw-r--r--src/vty_interface.c44
11 files changed, 333 insertions, 301 deletions
diff --git a/include/bsc_data.h b/include/bsc_data.h
index b0dc6f8..a72ea6a 100644
--- a/include/bsc_data.h
+++ b/include/bsc_data.h
@@ -40,6 +40,51 @@
struct bsc_data;
struct snmp_mtp_session;
+/**
+ * Struct holding the BSC to MSC forwarding state.
+ */
+struct bsc_msc_forward {
+ /* back pointer */
+ struct bsc_data *bsc_data;
+
+ /* the linkset we are using here */
+ struct mtp_link_set *bsc;
+
+ /* MSC */
+ char *msc_address;
+ struct write_queue msc_connection;
+ struct timer_list reconnect_timer;
+ int first_contact;
+ int msc_time;
+ struct timer_list msc_timeout;
+ int msc_ip_dscp;
+
+ int msc_link_down;
+ struct llist_head sccp_connections;
+ int reset_count;
+
+ /* LAC of the cell */
+ struct gsm48_loc_area_id lai;
+ uint16_t mcc;
+ uint16_t mnc;
+ uint16_t lac;
+
+ const char *token;
+
+ /* timeouts for the msc connection */
+ int ping_time;
+ int pong_time;
+ struct timer_list ping_timeout;
+ struct timer_list pong_timeout;
+ struct timer_list reset_timeout;
+
+ /* mgcp messgaes */
+ struct write_queue mgcp_agent;
+
+ /* do nothing with the data coming from the MSC */
+ int forward_only;
+};
+
struct mtp_udp_data {
struct write_queue write_queue;
struct timer_list snmp_poll;
@@ -74,39 +119,13 @@ enum {
struct bsc_data {
int app;
- /* MSC */
- char *msc_address;
- struct write_queue msc_connection;
- struct timer_list reconnect_timer;
- int first_contact;
- int msc_time;
- struct timer_list msc_timeout;
- int msc_ip_dscp;
-
- int ping_time;
- int pong_time;
- struct timer_list ping_timeout;
- struct timer_list pong_timeout;
-
- int msc_link_down;
- struct llist_head sccp_connections;
- struct timer_list reset_timeout;
- int reset_count;
-
struct timer_list start_timer;
-
int setup;
-
int pcap_fd;
int udp_reset_timeout;
struct mtp_link_set *link_set;
struct mtp_link_set *m2ua_set;
- const char *token;
-
- /* mgcp messgaes */
- struct write_queue mgcp_agent;
-
/* udp code */
struct mtp_udp_data udp_data;
@@ -127,37 +146,32 @@ struct bsc_data {
/* isup handling */
int isup_pass;
- /* LAC of the cell */
- struct gsm48_loc_area_id lai;
- uint16_t mcc;
- uint16_t mnc;
- uint16_t lac;
-
- int forward_only;
/* inject */
int allow_inject;
struct bsc_fd inject_fd;
struct llist_head inject_list;
+
+ /* MSC related data... currently only one is supported */
+ struct bsc_msc_forward msc_forward;
};
/* bsc related functions */
-void release_bsc_resources(struct bsc_data *bsc);
+void release_bsc_resources(struct bsc_msc_forward *fw);
void mtp_linkset_down(struct mtp_link_set *);
void mtp_linkset_up(struct mtp_link_set *);
/* msc related functions */
-int msc_init(struct bsc_data *bsc, int mgcp);
-void msc_send_rlc(struct bsc_data *bsc, struct sccp_source_reference *src, struct sccp_source_reference *dest);
-void msc_send_reset(struct bsc_data *bsc);
-void msc_send_msg(struct bsc_data *bsc, int rc, struct sccp_parse_result *, struct msgb *msg);
-void msc_send_direct(struct bsc_data *bsc, struct msgb *msg);
-void msc_close_connection(struct bsc_data *data);
+int msc_init(struct bsc_msc_forward *bsc, int mgcp);
+void msc_send_rlc(struct bsc_msc_forward *bsc, struct sccp_source_reference *src, struct sccp_source_reference *dest);
+void msc_send_reset(struct bsc_msc_forward *bsc);
+void msc_send_msg(struct bsc_msc_forward *bsc, int rc, struct sccp_parse_result *, struct msgb *msg);
+void msc_send_direct(struct bsc_msc_forward *bsc, struct msgb *msg);
+void msc_close_connection(struct bsc_msc_forward *data);
/* connection tracking and action */
-void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_result *result, struct msgb *msg, int from_msc, int sls);
-unsigned int sls_for_src_ref(struct sccp_source_reference *ref);
+void update_con_state(struct bsc_msc_forward *fw, int rc, struct sccp_parse_result *result, struct msgb *msg, int from_msc, int sls);
/* udp init */
int link_global_init(struct mtp_udp_data *data, int src_port);
@@ -168,7 +182,7 @@ int link_reset_all(struct mtp_link_set *);
int link_clear_all(struct mtp_link_set *);
/* MGCP */
-void mgcp_forward(struct bsc_data *bsc, const uint8_t *data, unsigned int length);
+void mgcp_forward(struct bsc_msc_forward *bsc, const uint8_t *data, unsigned int length);
/* pcap */
enum {
diff --git a/include/bsc_sccp.h b/include/bsc_sccp.h
index 8811a2b..833257d 100644
--- a/include/bsc_sccp.h
+++ b/include/bsc_sccp.h
@@ -30,6 +30,8 @@
#include <osmocom/sccp/sccp.h>
+struct bsc_msc_forward;
+
/*
* One SCCP connection.
* Use for connection tracking and fixups...
@@ -61,10 +63,10 @@ struct active_sccp_con {
};
void free_con(struct active_sccp_con *con);
-struct active_sccp_con *find_con_by_dest_ref(struct sccp_source_reference *ref);
-struct active_sccp_con *find_con_by_src_ref(struct sccp_source_reference *src_ref);
-struct active_sccp_con *find_con_by_src_dest_ref(struct sccp_source_reference *src_ref,
+struct active_sccp_con *find_con_by_dest_ref(struct bsc_msc_forward *, struct sccp_source_reference *ref);
+struct active_sccp_con *find_con_by_src_ref(struct bsc_msc_forward *,struct sccp_source_reference *src_ref);
+struct active_sccp_con *find_con_by_src_dest_ref(struct bsc_msc_forward *, struct sccp_source_reference *src_ref,
struct sccp_source_reference *dst_ref);
-unsigned int sls_for_src_ref(struct sccp_source_reference *ref);
+unsigned int sls_for_src_ref(struct bsc_msc_forward *, struct sccp_source_reference *ref);
#endif
diff --git a/include/bsc_ussd.h b/include/bsc_ussd.h
index ed61b65..988b7ab 100644
--- a/include/bsc_ussd.h
+++ b/include/bsc_ussd.h
@@ -21,8 +21,10 @@
#ifndef bsc_ussd_h
#define bsc_ussd_h
-int bsc_ussd_handle_out_msg(struct bsc_data *bsc, struct sccp_parse_result *result, struct msgb *msg);
+struct bsc_msc_forward;
-int bsc_ussd_handle_in_msg(struct bsc_data *bsc, struct sccp_parse_result *res, struct msgb *msg);
+int bsc_ussd_handle_out_msg(struct bsc_msc_forward *, struct sccp_parse_result *result, struct msgb *msg);
+
+int bsc_ussd_handle_in_msg(struct bsc_msc_forward *, struct sccp_parse_result *res, struct msgb *msg);
#endif
diff --git a/include/mtp_data.h b/include/mtp_data.h
index 9314962..1fa9277 100644
--- a/include/mtp_data.h
+++ b/include/mtp_data.h
@@ -25,6 +25,7 @@
#include <osmocore/utils.h>
struct bsc_data;
+struct bsc_msc_forward;
struct mtp_link;
struct mtp_level_3_mng *mng;
struct rate_ctr_group;
@@ -71,6 +72,7 @@ struct mtp_link_set {
/* custom data */
struct bsc_data *bsc;
+ struct bsc_msc_forward *fw;
};
/**
diff --git a/src/bsc_sccp.c b/src/bsc_sccp.c
index ea13c43..f0bd600 100644
--- a/src/bsc_sccp.c
+++ b/src/bsc_sccp.c
@@ -28,9 +28,7 @@
#include <string.h>
-extern struct bsc_data bsc;
-
-struct active_sccp_con *find_con_by_dest_ref(struct sccp_source_reference *ref)
+struct active_sccp_con *find_con_by_dest_ref(struct bsc_msc_forward *fw, struct sccp_source_reference *ref)
{
struct active_sccp_con *con;
@@ -39,7 +37,7 @@ struct active_sccp_con *find_con_by_dest_ref(struct sccp_source_reference *ref)
return NULL;
}
- llist_for_each_entry(con, &bsc.sccp_connections, entry) {
+ llist_for_each_entry(con, &fw->sccp_connections, entry) {
if (memcmp(&con->dst_ref, ref, sizeof(*ref)) == 0)
return con;
}
@@ -49,7 +47,7 @@ struct active_sccp_con *find_con_by_dest_ref(struct sccp_source_reference *ref)
}
-struct active_sccp_con *find_con_by_src_ref(struct sccp_source_reference *src_ref)
+struct active_sccp_con *find_con_by_src_ref(struct bsc_msc_forward *fw, struct sccp_source_reference *src_ref)
{
struct active_sccp_con *con;
@@ -57,7 +55,7 @@ struct active_sccp_con *find_con_by_src_ref(struct sccp_source_reference *src_re
if (!src_ref)
return NULL;
- llist_for_each_entry(con, &bsc.sccp_connections, entry) {
+ llist_for_each_entry(con, &fw->sccp_connections, entry) {
if (memcmp(&con->src_ref, src_ref, sizeof(*src_ref)) == 0)
return con;
}
@@ -65,12 +63,13 @@ struct active_sccp_con *find_con_by_src_ref(struct sccp_source_reference *src_re
return NULL;
}
-struct active_sccp_con *find_con_by_src_dest_ref(struct sccp_source_reference *src_ref,
+struct active_sccp_con *find_con_by_src_dest_ref(struct bsc_msc_forward *fw,
+ struct sccp_source_reference *src_ref,
struct sccp_source_reference *dst_ref)
{
struct active_sccp_con *con;
- llist_for_each_entry(con, &bsc.sccp_connections, entry) {
+ llist_for_each_entry(con, &fw->sccp_connections, entry) {
if (memcmp(src_ref, &con->src_ref, sizeof(*src_ref)) == 0 &&
memcmp(dst_ref, &con->dst_ref, sizeof(*dst_ref)) == 0) {
return con;
@@ -80,11 +79,11 @@ struct active_sccp_con *find_con_by_src_dest_ref(struct sccp_source_reference *s
return NULL;
}
-unsigned int sls_for_src_ref(struct sccp_source_reference *ref)
+unsigned int sls_for_src_ref(struct bsc_msc_forward *fw, struct sccp_source_reference *ref)
{
struct active_sccp_con *con;
- con = find_con_by_src_ref(ref);
+ con = find_con_by_src_ref(fw, ref);
if (!con)
return -1;
return con->sls;
diff --git a/src/links.c b/src/links.c
index af8f9d0..c5ac5da 100644
--- a/src/links.c
+++ b/src/links.c
@@ -90,7 +90,7 @@ static void start_rest(void *start)
struct mtp_link *data;
bsc.setup = 1;
- if (msc_init(&bsc, 1) != 0) {
+ if (msc_init(&bsc.msc_forward, 1) != 0) {
fprintf(stderr, "Failed to init MSC part.\n");
exit(3);
}
diff --git a/src/main.c b/src/main.c
index 3ae4f72..d38e9b9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -65,19 +65,19 @@ struct bsc_data bsc;
extern void cell_vty_init(void);
static void send_reset_ack(struct mtp_link_set *link, int sls);
-static void bsc_resources_released(struct bsc_data *bsc);
+static void bsc_resources_released(struct bsc_msc_forward *bsc);
static void handle_local_sccp(struct mtp_link_set *link, struct msgb *inp, struct sccp_parse_result *res, int sls);
-static void clear_connections(struct bsc_data *bsc);
+static void clear_connections(struct bsc_msc_forward *bsc);
static void send_local_rlsd(struct mtp_link_set *link, struct sccp_parse_result *res);
/* send a RSIP to the MGCP GW */
-static void mgcp_reset(struct bsc_data *bsc)
+static void mgcp_reset(struct bsc_msc_forward *fw)
{
static const char mgcp_reset[] = {
"RSIP 1 13@mgw MGCP 1.0\r\n"
};
- mgcp_forward(bsc, (const uint8_t *) mgcp_reset, strlen(mgcp_reset));
+ mgcp_forward(fw, (const uint8_t *) mgcp_reset, strlen(mgcp_reset));
}
/*
@@ -87,21 +87,22 @@ void mtp_link_set_forward_sccp(struct mtp_link_set *link, struct msgb *_msg, int
{
int rc;
struct sccp_parse_result result;
+ struct bsc_msc_forward *fw = link->fw;
rc = bss_patch_filter_msg(_msg, &result);
if (rc == BSS_FILTER_RESET) {
LOGP(DMSC, LOGL_NOTICE, "Filtering BSS Reset from the BSC\n");
- mgcp_reset(&bsc);
+ mgcp_reset(fw);
send_reset_ack(link, sls);
return;
}
/* special responder */
- if (bsc.msc_link_down) {
- if (rc == BSS_FILTER_RESET_ACK && bsc.reset_count > 0) {
+ if (fw->msc_link_down) {
+ if (rc == BSS_FILTER_RESET_ACK && fw->reset_count > 0) {
LOGP(DMSC, LOGL_ERROR, "Received reset ack for closing.\n");
- clear_connections(&bsc);
- bsc_resources_released(&bsc);
+ clear_connections(fw);
+ bsc_resources_released(fw);
return;
}
@@ -114,7 +115,7 @@ void mtp_link_set_forward_sccp(struct mtp_link_set *link, struct msgb *_msg, int
}
/* update the connection state */
- update_con_state(link, rc, &result, _msg, 0, sls);
+ update_con_state(link->fw, rc, &result, _msg, 0, sls);
if (rc == BSS_FILTER_CLEAR_COMPL) {
send_local_rlsd(link, &result);
@@ -124,7 +125,7 @@ void mtp_link_set_forward_sccp(struct mtp_link_set *link, struct msgb *_msg, int
}
- msc_send_msg(&bsc, rc, &result, _msg);
+ msc_send_msg(fw, rc, &result, _msg);
}
void mtp_link_set_forward_isup(struct mtp_link_set *set, struct msgb *msg, int sls)
@@ -160,7 +161,7 @@ static void handle_local_sccp(struct mtp_link_set *link, struct msgb *inpt, stru
form1 = (struct sccp_data_form1 *) inpt->l2h;
- llist_for_each_entry(con, &bsc.sccp_connections, entry) {
+ llist_for_each_entry(con, &link->fw->sccp_connections, entry) {
if (memcmp(&form1->destination_local_reference,
&con->dst_ref, sizeof(con->dst_ref)) == 0) {
LOGP(DINP, LOGL_DEBUG, "Sending a release request now.\n");
@@ -178,60 +179,60 @@ static void handle_local_sccp(struct mtp_link_set *link, struct msgb *inpt, stru
} else if (inpt->l2h[0] == SCCP_MSG_TYPE_UDT && result->data_len >= 3) {
if (inpt->l3h[0] == 0 && inpt->l3h[2] == BSS_MAP_MSG_RESET_ACKNOWLEDGE) {
LOGP(DINP, LOGL_NOTICE, "Reset ACK. Connecting to the MSC again.\n");
- bsc_resources_released(&bsc);
+ bsc_resources_released(link->fw);
return;
}
}
/* Update the state, maybe the connection was released? */
- update_con_state(link, 0, result, inpt, 0, sls);
- if (llist_empty(&bsc.sccp_connections))
- bsc_resources_released(&bsc);
+ update_con_state(link->fw, 0, result, inpt, 0, sls);
+ if (llist_empty(&link->fw->sccp_connections))
+ bsc_resources_released(link->fw);
return;
}
-static void clear_connections(struct bsc_data *bsc)
+static void clear_connections(struct bsc_msc_forward *fw)
{
struct active_sccp_con *tmp, *con;
- llist_for_each_entry_safe(con, tmp, &bsc->sccp_connections, entry) {
+ llist_for_each_entry_safe(con, tmp, &fw->sccp_connections, entry) {
free_con(con);
}
- link_clear_all(bsc->link_set);
+ link_clear_all(fw->bsc);
}
-void bsc_resources_released(struct bsc_data *bsc)
+void bsc_resources_released(struct bsc_msc_forward *fw)
{
- bsc_del_timer(&bsc->reset_timeout);
+ bsc_del_timer(&fw->reset_timeout);
}
static void bsc_reset_timeout(void *_data)
{
struct msgb *msg;
- struct bsc_data *bsc = (struct bsc_data *) _data;
+ struct bsc_msc_forward *fw = _data;
/* no reset */
- if (bsc->reset_count > 0) {
+ if (fw->reset_count > 0) {
LOGP(DINP, LOGL_ERROR, "The BSC did not answer the GSM08.08 reset. Restart MTP\n");
- mtp_link_set_stop(bsc->link_set);
- clear_connections(bsc);
- link_reset_all(bsc->link_set);
- bsc_resources_released(bsc);
+ mtp_link_set_stop(fw->bsc);
+ clear_connections(fw);
+ link_reset_all(fw->bsc);
+ bsc_resources_released(fw);
return;
}
msg = create_reset();
if (!msg) {
- bsc_schedule_timer(&bsc->reset_timeout, 10, 0);
+ bsc_schedule_timer(&fw->reset_timeout, 10, 0);
return;
}
- ++bsc->reset_count;
- mtp_link_set_submit_sccp_data(bsc->link_set, -1, msg->l2h, msgb_l2len(msg));
+ ++fw->reset_count;
+ mtp_link_set_submit_sccp_data(fw->bsc, -1, msg->l2h, msgb_l2len(msg));
msgb_free(msg);
- bsc_schedule_timer(&bsc->reset_timeout, 20, 0);
+ bsc_schedule_timer(&fw->reset_timeout, 20, 0);
}
/*
@@ -252,18 +253,18 @@ static void bsc_reset_timeout(void *_data)
* MTP link is going down while we are sending. We will simply
* reconnect to the MSC.
*/
-void release_bsc_resources(struct bsc_data *bsc)
+void release_bsc_resources(struct bsc_msc_forward *fw)
{
struct active_sccp_con *tmp;
struct active_sccp_con *con;
- bsc_del_timer(&bsc->reset_timeout);
+ bsc_del_timer(&fw->reset_timeout);
/* 2. clear the MGCP endpoints */
- mgcp_reset(bsc);
+ mgcp_reset(fw);
/* 1. send BSSMAP Cleanup.. if we have any connection */
- llist_for_each_entry_safe(con, tmp, &bsc->sccp_connections, entry) {
+ llist_for_each_entry_safe(con, tmp, &fw->sccp_connections, entry) {
if (!con->has_dst_ref) {
free_con(con);
continue;
@@ -274,18 +275,18 @@ void release_bsc_resources(struct bsc_data *bsc)
continue;
/* wait for the clear commands */
- mtp_link_set_submit_sccp_data(bsc->link_set, con->sls, msg->l2h, msgb_l2len(msg));
+ mtp_link_set_submit_sccp_data(fw->bsc, con->sls, msg->l2h, msgb_l2len(msg));
msgb_free(msg);
}
- if (llist_empty(&bsc->sccp_connections)) {
- bsc_resources_released(bsc);
+ if (llist_empty(&fw->sccp_connections)) {
+ bsc_resources_released(fw);
} else {
/* Send a reset in 20 seconds if we fail to bring everything down */
- bsc->reset_timeout.cb = bsc_reset_timeout;
- bsc->reset_timeout.data = bsc;
- bsc->reset_count = 0;
- bsc_schedule_timer(&bsc->reset_timeout, 10, 0);
+ fw->reset_timeout.cb = bsc_reset_timeout;
+ fw->reset_timeout.data = fw;
+ fw->reset_count = 0;
+ bsc_schedule_timer(&fw->reset_timeout, 10, 0);
}
}
@@ -293,11 +294,11 @@ void mtp_linkset_down(struct mtp_link_set *set)
{
set->available = 0;
mtp_link_set_stop(set);
- clear_connections(set->bsc);
- mgcp_reset(set->bsc);
+ clear_connections(set->fw);
+ mgcp_reset(set->fw);
/* If we have an A link send a reset to the MSC */
- msc_send_reset(set->bsc);
+ msc_send_reset(set->fw);
}
void mtp_linkset_up(struct mtp_link_set *set)
@@ -305,9 +306,9 @@ void mtp_linkset_up(struct mtp_link_set *set)
set->available = 1;
/* we have not gone through link down */
- if (set->bsc->msc_link_down) {
- clear_connections(set->bsc);
- bsc_resources_released(set->bsc);
+ if (set->fw->msc_link_down) {
+ clear_connections(set->fw);
+ bsc_resources_released(set->fw);
}
mtp_link_set_reset(set);
@@ -328,13 +329,13 @@ static void send_rlc_to_bsc(unsigned int sls, struct sccp_source_reference *src,
msgb_free(msg);
}
-static void handle_rlsd(struct sccp_connection_released *rlsd, int from_msc)
+static void handle_rlsd(struct bsc_msc_forward *fw, struct sccp_connection_released *rlsd, int from_msc)
{
struct active_sccp_con *con;
if (from_msc) {
/* search for a connection, reverse src/dest for MSC */
- con = find_con_by_src_dest_ref(&rlsd->destination_local_reference,
+ con = find_con_by_src_dest_ref(fw, &rlsd->destination_local_reference,
&rlsd->source_local_reference);
if (con) {
LOGP(DINP, LOGL_DEBUG, "RLSD conn still alive: local: 0x%x remote: 0x%x\n",
@@ -346,19 +347,19 @@ static void handle_rlsd(struct sccp_connection_released *rlsd, int from_msc)
LOGP(DINP, LOGL_DEBUG, "Sending RLC for MSC: src: 0x%x dst: 0x%x\n",
sccp_src_ref_to_int(&rlsd->destination_local_reference),
sccp_src_ref_to_int(&rlsd->source_local_reference));
- msc_send_rlc(&bsc, &rlsd->destination_local_reference,
+ msc_send_rlc(fw, &rlsd->destination_local_reference,
&rlsd->source_local_reference);
}
} else {
unsigned int sls = -1;
- con = find_con_by_src_dest_ref(&rlsd->source_local_reference,
+ con = find_con_by_src_dest_ref(fw, &rlsd->source_local_reference,
&rlsd->destination_local_reference);
if (con) {
LOGP(DINP, LOGL_DEBUG, "Timeout on BSC. Sending RLC. src: 0x%x\n",
sccp_src_ref_to_int(&rlsd->source_local_reference));
if (con->released_from_msc)
- msc_send_rlc(&bsc, &con->src_ref, &con->dst_ref);
+ msc_send_rlc(fw, &con->src_ref, &con->dst_ref);
sls = con->sls;
free_con(con);
} else {
@@ -385,7 +386,7 @@ static void handle_rlsd(struct sccp_connection_released *rlsd, int from_msc)
* 1.) We are destroying the connection, we might send a RLC to
* the MSC if we are waiting for one.
*/
-void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_result *res, struct msgb *msg, int from_msc, int sls)
+void update_con_state(struct bsc_msc_forward *fw, int rc, struct sccp_parse_result *res, struct msgb *msg, int from_msc, int sls)
{
struct active_sccp_con *con;
struct sccp_connection_request *cr;
@@ -406,7 +407,7 @@ void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_resul
}
cr = (struct sccp_connection_request *) msg->l2h;
- con = find_con_by_src_ref(&cr->source_local_reference);
+ con = find_con_by_src_ref(fw, &cr->source_local_reference);
if (con) {
LOGP(DINP, LOGL_ERROR, "Duplicate SRC reference for: 0x%x. Reusing\n",
sccp_src_ref_to_int(&con->src_ref));
@@ -421,8 +422,8 @@ void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_resul
con->src_ref = cr->source_local_reference;
con->sls = sls;
- con->link = link;
- llist_add_tail(&con->entry, &bsc.sccp_connections);
+ con->link = fw->bsc;
+ llist_add_tail(&con->entry, &fw->sccp_connections);
LOGP(DINP, LOGL_DEBUG, "Adding CR: local ref: 0x%x\n", sccp_src_ref_to_int(&con->src_ref));
break;
case SCCP_MSG_TYPE_CC:
@@ -432,7 +433,7 @@ void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_resul
}
cc = (struct sccp_connection_confirm *) msg->l2h;
- con = find_con_by_src_ref(&cc->destination_local_reference);
+ con = find_con_by_src_ref(fw, &cc->destination_local_reference);
if (con) {
con->dst_ref = cc->source_local_reference;
con->has_dst_ref = 1;
@@ -451,7 +452,7 @@ void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_resul
}
cref = (struct sccp_connection_refused *) msg->l2h;
- con = find_con_by_src_ref(&cref->destination_local_reference);
+ con = find_con_by_src_ref(fw, &cref->destination_local_reference);
if (con) {
LOGP(DINP, LOGL_DEBUG, "Releasing local: 0x%x\n", sccp_src_ref_to_int(&con->src_ref));
free_con(con);
@@ -461,7 +462,7 @@ void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_resul
LOGP(DINP, LOGL_ERROR, "CREF from BSC is not handled.\n");
break;
case SCCP_MSG_TYPE_RLSD:
- handle_rlsd((struct sccp_connection_released *) msg->l2h, from_msc);
+ handle_rlsd(fw, (struct sccp_connection_released *) msg->l2h, from_msc);
break;
case SCCP_MSG_TYPE_RLC:
if (from_msc) {
@@ -470,12 +471,12 @@ void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_resul
}
rlc = (struct sccp_connection_release_complete *) msg->l2h;
- con = find_con_by_src_dest_ref(&rlc->source_local_reference,
+ con = find_con_by_src_dest_ref(fw, &rlc->source_local_reference,
&rlc->destination_local_reference);
if (con) {
LOGP(DINP, LOGL_DEBUG, "Releasing local: 0x%x\n", sccp_src_ref_to_int(&con->src_ref));
if (con->released_from_msc)
- msc_send_rlc(&bsc, &con->src_ref, &con->dst_ref);
+ msc_send_rlc(fw, &con->src_ref, &con->dst_ref);
free_con(con);
return;
}
@@ -505,7 +506,7 @@ static void send_local_rlsd_for_con(void *data)
++con->rls_tries;
LOGP(DINP, LOGL_DEBUG, "Sending RLSD for 0x%x the %d time.\n",
sccp_src_ref_to_int(&con->src_ref), con->rls_tries);
- mtp_link_set_submit_sccp_data(bsc.link_set, con->sls, rlsd->l2h, msgb_l2len(rlsd));
+ mtp_link_set_submit_sccp_data(con->link, con->sls, rlsd->l2h, msgb_l2len(rlsd));
msgb_free(rlsd);
}
@@ -515,7 +516,7 @@ static void send_local_rlsd(struct mtp_link_set *link, struct sccp_parse_result
LOGP(DINP, LOGL_DEBUG, "Received GSM Clear Complete. Sending RLSD locally.\n");
- con = find_con_by_dest_ref(res->destination_local_reference);
+ con = find_con_by_dest_ref(link->fw, res->destination_local_reference);
if (!con)
return;
con->rls_tries = 0;
@@ -562,7 +563,7 @@ out:
static void sigusr2()
{
printf("Closing the MSC connection on demand.\n");
- msc_close_connection(&bsc);
+ msc_close_connection(&bsc.msc_forward);
}
static void print_help()
@@ -621,10 +622,21 @@ static void handle_options(int argc, char **argv)
}
}
+static void bsc_msc_forward_init(struct bsc_data *bsc,
+ struct bsc_msc_forward *msc)
+{
+ INIT_LLIST_HEAD(&msc->sccp_connections);
+
+ msc->bsc_data = bsc;
+ msc->msc_address = "127.0.0.1";
+ msc->ping_time = 20;
+ msc->pong_time = 5;
+ msc->msc_time = 20;
+}
+
int main(int argc, char **argv)
{
int rc;
- INIT_LLIST_HEAD(&bsc.sccp_connections);
bsc.app = APP_CELLMGR;
bsc.dpc = 1;
@@ -637,6 +649,9 @@ int main(int argc, char **argv)
bsc.src_port = 1313;
bsc.ni_ni = MTP_NI_NATION_NET;
bsc.ni_spare = 0;
+ bsc.setup = 0;
+ bsc.pcap_fd = -1;
+ bsc.udp_reset_timeout = 180;
mtp_link_set_init();
thread_init();
@@ -656,13 +671,8 @@ int main(int argc, char **argv)
sccp_set_log_area(DSCCP);
- bsc.setup = 0;
- bsc.msc_address = "127.0.0.1";
- bsc.pcap_fd = -1;
- bsc.udp_reset_timeout = 180;
- bsc.ping_time = 20;
- bsc.pong_time = 5;
- bsc.msc_time = 20;
+ /* msc data */
+ bsc_msc_forward_init(&bsc, &bsc.msc_forward);
handle_options(argc, argv);
@@ -683,6 +693,8 @@ int main(int argc, char **argv)
if (link_init(&bsc) != 0)
return -1;
+ bsc.link_set->fw = &bsc.msc_forward;
+ bsc.msc_forward.bsc = bsc.link_set;
while (1) {
bsc_select_main(0);
diff --git a/src/main_stp.c b/src/main_stp.c
index 6e8752e..5ddc10e 100644
--- a/src/main_stp.c
+++ b/src/main_stp.c
@@ -305,7 +305,6 @@ int main(int argc, char **argv)
int rc;
struct mtp_link *data;
struct mtp_m2ua_link *lnk;
- INIT_LLIST_HEAD(&bsc.sccp_connections);
bsc.app = APP_STP;
bsc.dpc = 1;
@@ -318,6 +317,9 @@ int main(int argc, char **argv)
bsc.ni_ni = MTP_NI_NATION_NET;
bsc.ni_spare = 0;
bsc.udp_nr_links = 1;
+ bsc.setup = 0;
+ bsc.pcap_fd = -1;
+ bsc.udp_reset_timeout = 180;
mtp_link_set_init();
thread_init();
@@ -338,15 +340,6 @@ int main(int argc, char **argv)
sccp_set_log_area(DSCCP);
m2ua_set_log_area(DM2UA);
- bsc.setup = 0;
- bsc.msc_address = "127.0.0.1";
- bsc.pcap_fd = -1;
- bsc.udp_reset_timeout = 180;
- bsc.ping_time = 20;
- bsc.pong_time = 5;
- bsc.msc_time = 20;
- bsc.forward_only = 1;
-
handle_options(argc, argv);
signal(SIGPIPE, SIG_IGN);
@@ -403,7 +396,7 @@ int main(int argc, char **argv)
}
/* dummy for links */
-int msc_init(struct bsc_data *data, int dummy)
+int msc_init(struct bsc_msc_forward *data, int dummy)
{
return 0;
}
diff --git a/src/main_udt.c b/src/main_udt.c
index 7f2f045..e8eb06b 100644
--- a/src/main_udt.c
+++ b/src/main_udt.c
@@ -69,7 +69,7 @@ extern void cell_vty_init(void);
*/
void mtp_link_set_forward_sccp(struct mtp_link_set *link, struct msgb *_msg, int sls)
{
- msc_send_direct(&bsc, _msg);
+ msc_send_direct(link->fw, _msg);
}
void mtp_link_set_forward_isup(struct mtp_link_set *set, struct msgb *msg, int sls)
@@ -83,7 +83,7 @@ void mtp_linkset_down(struct mtp_link_set *set)
mtp_link_set_stop(set);
/* If we have an A link send a reset to the MSC */
- msc_send_reset(set->bsc);
+ msc_send_reset(set->fw);
}
void mtp_linkset_up(struct mtp_link_set *set)
@@ -121,7 +121,7 @@ out:
static void sigusr2()
{
printf("Closing the MSC connection on demand.\n");
- msc_close_connection(&bsc);
+ msc_close_connection(&bsc.msc_forward);
}
static void print_help()
@@ -180,10 +180,21 @@ static void handle_options(int argc, char **argv)
}
}
+static void bsc_msc_forward_init(struct bsc_data *bsc,
+ struct bsc_msc_forward *msc)
+{
+ INIT_LLIST_HEAD(&msc->sccp_connections);
+
+ msc->bsc_data = bsc;
+ msc->msc_address = "127.0.0.1";
+ msc->ping_time = 20;
+ msc->pong_time = 5;
+ msc->msc_time = 20;
+}
+
int main(int argc, char **argv)
{
int rc;
- INIT_LLIST_HEAD(&bsc.sccp_connections);
bsc.app = APP_RELAY;
bsc.dpc = 1;
@@ -196,6 +207,9 @@ int main(int argc, char **argv)
bsc.ni_ni = MTP_NI_NATION_NET;
bsc.ni_spare = 0;
bsc.udp_nr_links = 1;
+ bsc.setup = 0;
+ bsc.pcap_fd = -1;
+ bsc.udp_reset_timeout = 180;
mtp_link_set_init();
thread_init();
@@ -216,14 +230,8 @@ int main(int argc, char **argv)
sccp_set_log_area(DSCCP);
m2ua_set_log_area(DM2UA);
- bsc.setup = 0;
- bsc.msc_address = "127.0.0.1";
- bsc.pcap_fd = -1;
- bsc.udp_reset_timeout = 180;
- bsc.ping_time = 20;
- bsc.pong_time = 5;
- bsc.msc_time = 20;
- bsc.forward_only = 1;
+ /* msc data */
+ bsc_msc_forward_init(&bsc, &bsc.msc_forward);
handle_options(argc, argv);
@@ -244,6 +252,8 @@ int main(int argc, char **argv)
if (link_init(&bsc) != 0)
return -1;
+ bsc.link_set->fw = &bsc.msc_forward;
+ bsc.msc_forward.bsc = bsc.link_set;
while (1) {
bsc_select_main(0);
@@ -252,11 +262,12 @@ int main(int argc, char **argv)
return 0;
}
-void release_bsc_resources(struct bsc_data *bsc)
+void release_bsc_resources(struct bsc_msc_forward *fw)
{
}
-struct msgb *create_sccp_rlc(struct sccp_source_reference *src_ref,
+struct msgb *create_sccp_rlc(struct bsc_msc_forward *fw,
+ struct sccp_source_reference *src_ref,
struct sccp_source_reference *dst)
{
LOGP(DMSC, LOGL_NOTICE, "Refusing to create connection handling.\n");
@@ -269,13 +280,13 @@ struct msgb *create_reset()
return NULL;
}
-void update_con_state(struct mtp_link_set *link, int rc, struct sccp_parse_result *res, struct msgb *msg, int from_msc, int sls)
+void update_con_state(struct bsc_msc_forward *fw, int rc, struct sccp_parse_result *res, struct msgb *msg, int from_msc, int sls)
{
LOGP(DMSC, LOGL_ERROR, "Should not be called.\n");
return;
}
-unsigned int sls_for_src_ref(struct sccp_source_reference *ref)
+unsigned int sls_for_src_ref(struct bsc_msc_forward *fw, struct sccp_source_reference *ref)
{
return 13;
}
diff --git a/src/msc_conn.c b/src/msc_conn.c
index 8f17eb4..31a71fd 100644
--- a/src/msc_conn.c
+++ b/src/msc_conn.c
@@ -22,6 +22,7 @@
#include <bsc_data.h>
#include <bsc_ussd.h>
#include <bss_patch.h>
+#include <bsc_sccp.h>
#include <bssap_sccp.h>
#include <ipaccess.h>
#include <mtp_data.h>
@@ -42,9 +43,9 @@
#define RECONNECT_TIME 10, 0
#define NAT_MUX 0xfc
-static void msc_send_id_response(struct bsc_data *bsc);
-static void msc_send(struct bsc_data *bsc, struct msgb *msg, int proto);
-static void msc_schedule_reconnect(struct bsc_data *bsc);
+static void msc_send_id_response(struct bsc_msc_forward *bsc);
+static void msc_send(struct bsc_msc_forward *bsc, struct msgb *msg, int proto);
+static void msc_schedule_reconnect(struct bsc_msc_forward *bsc);
int send_or_queue_bsc_msg(struct mtp_link_set *link, int sls, struct msgb *msg)
{
@@ -53,37 +54,37 @@ int send_or_queue_bsc_msg(struct mtp_link_set *link, int sls, struct msgb *msg)
return 0;
}
-void msc_close_connection(struct bsc_data *bsc)
+void msc_close_connection(struct bsc_msc_forward *fw)
{
- struct bsc_fd *bfd = &bsc->msc_connection.bfd;
+ struct bsc_fd *bfd = &fw->msc_connection.bfd;
close(bfd->fd);
bsc_unregister_fd(bfd);
bfd->fd = -1;
- bsc->msc_link_down = 1;
- release_bsc_resources(bsc);
- bsc_del_timer(&bsc->ping_timeout);
- bsc_del_timer(&bsc->pong_timeout);
- bsc_del_timer(&bsc->msc_timeout);
- msc_schedule_reconnect(bsc);
+ fw->msc_link_down = 1;
+ release_bsc_resources(fw);
+ bsc_del_timer(&fw->ping_timeout);
+ bsc_del_timer(&fw->pong_timeout);
+ bsc_del_timer(&fw->msc_timeout);
+ msc_schedule_reconnect(fw);
}
-static void msc_connect_timeout(void *_bsc_data)
+static void msc_connect_timeout(void *_fw_data)
{
- struct bsc_data *bsc_data = _bsc_data;
+ struct bsc_msc_forward *fw = _fw_data;
LOGP(DMSC, LOGL_ERROR, "Timeout on the MSC connection.\n");
- msc_close_connection(bsc_data);
+ msc_close_connection(fw);
}
-static void msc_pong_timeout(void *_bsc_data)
+static void msc_pong_timeout(void *_fw_data)
{
- struct bsc_data *bsc_data = _bsc_data;
+ struct bsc_msc_forward *fw = _fw_data;
LOGP(DMSC, LOGL_ERROR, "MSC didn't respond to ping. Closing.\n");
- msc_close_connection(bsc_data);
+ msc_close_connection(fw);
}
-static void send_ping(struct bsc_data *bsc)
+static void send_ping(struct bsc_msc_forward *fw)
{
struct msgb *msg;
@@ -96,23 +97,23 @@ static void send_ping(struct bsc_data *bsc)
msg->l2h = msgb_put(msg, 1);
msg->l2h[0] = IPAC_MSGT_PING;
- msc_send(bsc, msg, IPAC_PROTO_IPACCESS);
+ msc_send(fw, msg, IPAC_PROTO_IPACCESS);
}
-static void msc_ping_timeout(void *_bsc_data)
+static void msc_ping_timeout(void *_fw_data)
{
- struct bsc_data *bsc_data = _bsc_data;
+ struct bsc_msc_forward *fw = _fw_data;
- if (bsc_data->ping_time < 0)
+ if (fw->ping_time < 0)
return;
- send_ping(bsc_data);
+ send_ping(fw);
/* send another ping in 20 seconds */
- bsc_schedule_timer(&bsc_data->ping_timeout, bsc_data->ping_time, 0);
+ bsc_schedule_timer(&fw->ping_timeout, fw->ping_time, 0);
/* also start a pong timer */
- bsc_schedule_timer(&bsc_data->pong_timeout, bsc_data->pong_time, 0);
+ bsc_schedule_timer(&fw->pong_timeout, fw->pong_time, 0);
}
/*
@@ -122,21 +123,19 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
{
int error;
struct ipaccess_head *hh;
- struct mtp_link_set *link;
- struct bsc_data *bsc;
+ struct bsc_msc_forward *fw;
struct msgb *msg;
+ fw = bfd->data;
msg = ipaccess_read_msg(bfd, &error);
- bsc = (struct bsc_data *) bfd->data;
-
if (!msg) {
if (error == 0)
fprintf(stderr, "The connection to the MSC was lost, exiting\n");
else
fprintf(stderr, "Error in the IPA stream.\n");
- msc_close_connection(bsc);
+ msc_close_connection(fw);
return -1;
}
@@ -146,29 +145,27 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
hh = (struct ipaccess_head *) msg->data;
ipaccess_rcvmsg_base(msg, bfd);
- link = bsc->link_set;
-
/* initialize the networking. This includes sending a GSM08.08 message */
if (hh->proto == IPAC_PROTO_IPACCESS) {
- if (bsc->first_contact) {
+ if (fw->first_contact) {
LOGP(DMSC, LOGL_NOTICE, "Connected to MSC. Sending reset.\n");
- bsc_del_timer(&bsc->msc_timeout);
- bsc->first_contact = 0;
- bsc->msc_link_down = 0;
- msc_send_reset(bsc);
+ bsc_del_timer(&fw->msc_timeout);
+ fw->first_contact = 0;
+ fw->msc_link_down = 0;
+ msc_send_reset(fw);
}
- if (msg->l2h[0] == IPAC_MSGT_ID_GET && bsc->token) {
- msc_send_id_response(bsc);
+ if (msg->l2h[0] == IPAC_MSGT_ID_GET && fw->token) {
+ msc_send_id_response(fw);
} else if (msg->l2h[0] == IPAC_MSGT_PONG) {
- bsc_del_timer(&bsc->pong_timeout);
+ bsc_del_timer(&fw->pong_timeout);
}
} else if (hh->proto == IPAC_PROTO_SCCP) {
struct sccp_parse_result result;
int rc;
/* we can not forward it right now */
- if (bsc->forward_only && link->sccp_up) {
- if (send_or_queue_bsc_msg(link, -1, msg) != 1)
+ if (fw->forward_only && fw->bsc->sccp_up) {
+ if (send_or_queue_bsc_msg(fw->bsc, -1, msg) != 1)
msgb_free(msg);
return 0;
}
@@ -180,31 +177,31 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
LOGP(DMSC, LOGL_NOTICE, "Filtering reset ack from the MSC\n");
} else if (rc == BSS_FILTER_RLSD) {
LOGP(DMSC, LOGL_DEBUG, "Filtering RLSD from the MSC\n");
- update_con_state(NULL, rc, &result, msg, 1, 0);
+ update_con_state(fw, rc, &result, msg, 1, 0);
} else if (rc == BSS_FILTER_RLC) {
/* if we receive this we have forwarded a RLSD to the network */
LOGP(DMSC, LOGL_ERROR, "RLC from the network. BAD!\n");
} else if (rc == BSS_FILTER_CLEAR_COMPL) {
LOGP(DMSC, LOGL_ERROR, "Clear Complete from the network.\n");
- } else if (link->sccp_up) {
+ } else if (fw->bsc->sccp_up) {
unsigned int sls;
- update_con_state(NULL, rc, &result, msg, 1, 0);
- sls = sls_for_src_ref(result.destination_local_reference);
+ update_con_state(fw, rc, &result, msg, 1, 0);
+ sls = sls_for_src_ref(fw, result.destination_local_reference);
/* Check for Location Update Accept */
- bsc_ussd_handle_in_msg(bsc, &result, msg);
+ bsc_ussd_handle_in_msg(fw, &result, msg);
/* patch a possible PC */
- bss_rewrite_header_to_bsc(msg, link->opc, link->dpc);
+ bss_rewrite_header_to_bsc(msg, fw->bsc->opc, fw->bsc->dpc);
/* we can not forward it right now */
- if (send_or_queue_bsc_msg(link, sls, msg) == 1)
+ if (send_or_queue_bsc_msg(fw->bsc, sls, msg) == 1)
return 0;
}
} else if (hh->proto == NAT_MUX) {
- mgcp_forward(bsc, msg->l2h, msgb_l2len(msg));
+ mgcp_forward(fw, msg->l2h, msgb_l2len(msg));
} else {
LOGP(DMSC, LOGL_ERROR, "Unknown IPA proto 0x%x\n", hh->proto);
}
@@ -231,11 +228,11 @@ static int msc_connection_connect(struct bsc_fd *fd, unsigned int what)
int rc;
int val;
socklen_t len = sizeof(val);
- struct bsc_data *bsc;
+ struct bsc_msc_forward *fw;
- bsc = (struct bsc_data *) fd->data;
+ fw = fd->data;
- if (fd != &bsc->msc_connection.bfd) {
+ if (fd != &fw->msc_connection.bfd) {
LOGP(DMSC, LOGL_ERROR, "This is only working with the MSC connection.\n");
return -1;
}
@@ -258,12 +255,12 @@ static int msc_connection_connect(struct bsc_fd *fd, unsigned int what)
/* go to full operation */
fd->cb = write_queue_bfd_cb;
fd->when = BSC_FD_READ;
- if (!llist_empty(&bsc->msc_connection.msg_queue))
+ if (!llist_empty(&fw->msc_connection.msg_queue))
fd->when |= BSC_FD_WRITE;
return 0;
error:
- msc_close_connection(bsc);
+ msc_close_connection(fw);
return -1;
}
@@ -352,26 +349,26 @@ static int connect_to_msc(struct bsc_fd *fd, const char *ip, int port, int tos)
static void msc_reconnect(void *_data)
{
int rc;
- struct bsc_data *bsc = (struct bsc_data *) _data;
+ struct bsc_msc_forward *fw = _data;
- bsc_del_timer(&bsc->reconnect_timer);
- bsc->first_contact = 1;
+ bsc_del_timer(&fw->reconnect_timer);
+ fw->first_contact = 1;
- rc = connect_to_msc(&bsc->msc_connection.bfd, bsc->msc_address, 5000, bsc->msc_ip_dscp);
+ rc = connect_to_msc(&fw->msc_connection.bfd, fw->msc_address, 5000, fw->msc_ip_dscp);
if (rc < 0) {
fprintf(stderr, "Opening the MSC connection failed. Trying again\n");
- bsc_schedule_timer(&bsc->reconnect_timer, RECONNECT_TIME);
+ bsc_schedule_timer(&fw->reconnect_timer, RECONNECT_TIME);
return;
}
- bsc->msc_timeout.cb = msc_connect_timeout;
- bsc->msc_timeout.data = bsc;
- bsc_schedule_timer(&bsc->msc_timeout, bsc->msc_time, 0);
+ fw->msc_timeout.cb = msc_connect_timeout;
+ fw->msc_timeout.data = fw;
+ bsc_schedule_timer(&fw->msc_timeout, fw->msc_time, 0);
}
-static void msc_schedule_reconnect(struct bsc_data *bsc)
+static void msc_schedule_reconnect(struct bsc_msc_forward *fw)
{
- bsc_schedule_timer(&bsc->reconnect_timer, RECONNECT_TIME);
+ bsc_schedule_timer(&fw->reconnect_timer, RECONNECT_TIME);
}
/*
@@ -417,7 +414,7 @@ static int mgcp_do_read(struct bsc_fd *fd)
return 0;
}
-void mgcp_forward(struct bsc_data *bsc, const uint8_t *data, unsigned int length)
+void mgcp_forward(struct bsc_msc_forward *fw, const uint8_t *data, unsigned int length)
{
struct msgb *mgcp;
@@ -434,25 +431,25 @@ void mgcp_forward(struct bsc_data *bsc, const uint8_t *data, unsigned int length
msgb_put(mgcp, length);
memcpy(mgcp->data, data, mgcp->len);
- if (write_queue_enqueue(&bsc->mgcp_agent, mgcp) != 0) {
+ if (write_queue_enqueue(&fw->mgcp_agent, mgcp) != 0) {
LOGP(DMGCP, LOGL_FATAL, "Could not queue message to MGCP GW.\n");
msgb_free(mgcp);
}
}
-static int mgcp_create_port(struct bsc_data *bsc)
+static int mgcp_create_port(struct bsc_msc_forward *fw)
{
int on;
struct sockaddr_in addr;
- bsc->mgcp_agent.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (bsc->mgcp_agent.bfd.fd < 0) {
+ fw->mgcp_agent.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fw->mgcp_agent.bfd.fd < 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to create UDP socket errno: %d\n", errno);
return -1;
}
on = 1;
- setsockopt(bsc->mgcp_agent.bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ setsockopt(fw->mgcp_agent.bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
/* try to bind the socket */
memset(&addr, 0, sizeof(addr));
@@ -460,66 +457,66 @@ static int mgcp_create_port(struct bsc_data *bsc)
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = 0;
- if (bind(bsc->mgcp_agent.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ if (bind(fw->mgcp_agent.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to bind to any port.\n");
- close(bsc->mgcp_agent.bfd.fd);
- bsc->mgcp_agent.bfd.fd = -1;
+ close(fw->mgcp_agent.bfd.fd);
+ fw->mgcp_agent.bfd.fd = -1;
return -1;
}
/* connect to the remote */
addr.sin_port = htons(2427);
- if (connect(bsc->mgcp_agent.bfd.fd, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
+ if (connect(fw->mgcp_agent.bfd.fd, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to connect to local MGCP GW. %s\n", strerror(errno));
- close(bsc->mgcp_agent.bfd.fd);
- bsc->mgcp_agent.bfd.fd = -1;
+ close(fw->mgcp_agent.bfd.fd);
+ fw->mgcp_agent.bfd.fd = -1;
return -1;
}
- write_queue_init(&bsc->mgcp_agent, 10);
- bsc->mgcp_agent.bfd.data = bsc;
- bsc->mgcp_agent.bfd.when = BSC_FD_READ;
- bsc->mgcp_agent.read_cb = mgcp_do_read;
- bsc->mgcp_agent.write_cb = mgcp_do_write;
+ write_queue_init(&fw->mgcp_agent, 10);
+ fw->mgcp_agent.bfd.data = fw;
+ fw->mgcp_agent.bfd.when = BSC_FD_READ;
+ fw->mgcp_agent.read_cb = mgcp_do_read;
+ fw->mgcp_agent.write_cb = mgcp_do_write;
- if (bsc_register_fd(&bsc->mgcp_agent.bfd) != 0) {
+ if (bsc_register_fd(&fw->mgcp_agent.bfd) != 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to register BFD\n");
- close(bsc->mgcp_agent.bfd.fd);
- bsc->mgcp_agent.bfd.fd = -1;
+ close(fw->mgcp_agent.bfd.fd);
+ fw->mgcp_agent.bfd.fd = -1;
return -1;
}
return 0;
}
-int msc_init(struct bsc_data *bsc, int mgcp)
+int msc_init(struct bsc_msc_forward *fw, int mgcp)
{
- write_queue_init(&bsc->msc_connection, 100);
- bsc->reconnect_timer.cb = msc_reconnect;
- bsc->reconnect_timer.data = bsc;
- bsc->msc_connection.read_cb = ipaccess_a_fd_cb;
- bsc->msc_connection.write_cb = ipaccess_write_cb;
- bsc->msc_connection.bfd.data = bsc;
- bsc->msc_link_down = 1;
+ write_queue_init(&fw->msc_connection, 100);
+ fw->reconnect_timer.cb = msc_reconnect;
+ fw->reconnect_timer.data = fw;
+ fw->msc_connection.read_cb = ipaccess_a_fd_cb;
+ fw->msc_connection.write_cb = ipaccess_write_cb;
+ fw->msc_connection.bfd.data = fw;
+ fw->msc_link_down = 1;
/* handle the timeout */
- bsc->ping_timeout.cb = msc_ping_timeout;
- bsc->ping_timeout.data = bsc;
- bsc->pong_timeout.cb = msc_pong_timeout;
- bsc->pong_timeout.data = bsc;
+ fw->ping_timeout.cb = msc_ping_timeout;
+ fw->ping_timeout.data = fw;
+ fw->pong_timeout.cb = msc_pong_timeout;
+ fw->pong_timeout.data = fw;
/* create MGCP port */
- if (mgcp && mgcp_create_port(bsc) != 0)
+ if (mgcp && mgcp_create_port(fw) != 0)
return -1;
/* now connect to the BSC */
- msc_schedule_reconnect(bsc);
+ msc_schedule_reconnect(fw);
return 0;
}
-static void msc_send(struct bsc_data *bsc, struct msgb *msg, int proto)
+static void msc_send(struct bsc_msc_forward *fw, struct msgb *msg, int proto)
{
- if (bsc->msc_link_down) {
+ if (fw->msc_link_down) {
LOGP(DMSC, LOGL_NOTICE, "Dropping data due lack of MSC connection.\n");
msgb_free(msg);
return;
@@ -527,19 +524,19 @@ static void msc_send(struct bsc_data *bsc, struct msgb *msg, int proto)
ipaccess_prepend_header(msg, proto);
- if (write_queue_enqueue(&bsc->msc_connection, msg) != 0) {
+ if (write_queue_enqueue(&fw->msc_connection, msg) != 0) {
LOGP(DMSC, LOGL_FATAL, "Failed to queue MSG for the MSC.\n");
msgb_free(msg);
return;
}
}
-void msc_send_rlc(struct bsc_data *bsc,
+void msc_send_rlc(struct bsc_msc_forward *fw,
struct sccp_source_reference *src, struct sccp_source_reference *dst)
{
struct msgb *msg;
- if (bsc->msc_link_down) {
+ if (fw->msc_link_down) {
LOGP(DMSC, LOGL_NOTICE, "Not releasing connection due lack of connection.\n");
return;
}
@@ -548,14 +545,14 @@ void msc_send_rlc(struct bsc_data *bsc,
if (!msg)
return;
- msc_send(bsc, msg, IPAC_PROTO_SCCP);
+ msc_send(fw, msg, IPAC_PROTO_SCCP);
}
-void msc_send_reset(struct bsc_data *bsc)
+void msc_send_reset(struct bsc_msc_forward *fw)
{
struct msgb *msg;
- if (bsc->msc_link_down) {
+ if (fw->msc_link_down) {
LOGP(DMSC, LOGL_NOTICE, "Not sending reset due lack of connection.\n");
return;
}
@@ -564,37 +561,37 @@ void msc_send_reset(struct bsc_data *bsc)
if (!msg)
return;
- msc_send(bsc, msg, IPAC_PROTO_SCCP);
- msc_ping_timeout(bsc);
+ msc_send(fw, msg, IPAC_PROTO_SCCP);
+ msc_ping_timeout(fw);
}
-static void msc_send_id_response(struct bsc_data *bsc)
+static void msc_send_id_response(struct bsc_msc_forward *fw)
{
struct msgb *msg;
msg = msgb_alloc_headroom(4096, 128, "id resp");
msg->l2h = msgb_v_put(msg, IPAC_MSGT_ID_RESP);
- msgb_l16tv_put(msg, strlen(bsc->token) + 1,
- IPAC_IDTAG_UNITNAME, (uint8_t *) bsc->token);
+ msgb_l16tv_put(msg, strlen(fw->token) + 1,
+ IPAC_IDTAG_UNITNAME, (uint8_t *) fw->token);
- msc_send(bsc, msg, IPAC_PROTO_IPACCESS);
+ msc_send(fw, msg, IPAC_PROTO_IPACCESS);
}
-void msc_send_direct(struct bsc_data *bsc, struct msgb *msg)
+void msc_send_direct(struct bsc_msc_forward *fw, struct msgb *msg)
{
- return msc_send(bsc, msg, IPAC_PROTO_SCCP);
+ return msc_send(fw, msg, IPAC_PROTO_SCCP);
}
-void msc_send_msg(struct bsc_data *bsc, int rc, struct sccp_parse_result *result, struct msgb *_msg)
+void msc_send_msg(struct bsc_msc_forward *fw, int rc, struct sccp_parse_result *result, struct msgb *_msg)
{
struct msgb *msg;
- if (bsc->msc_connection.bfd.fd < 0) {
+ if (fw->msc_connection.bfd.fd < 0) {
LOGP(DMSC, LOGL_ERROR, "No connection to the MSC. dropping\n");
return;
}
- bsc_ussd_handle_out_msg(bsc, result, _msg);
+ bsc_ussd_handle_out_msg(fw, result, _msg);
msg = msgb_alloc_headroom(4096, 128, "SCCP to MSC");
if (!msg) {
@@ -603,5 +600,5 @@ void msc_send_msg(struct bsc_data *bsc, int rc, struct sccp_parse_result *result
}
bss_rewrite_header_for_msc(rc, msg, _msg, result);
- msc_send(bsc, msg, IPAC_PROTO_SCCP);
+ msc_send(fw, msg, IPAC_PROTO_SCCP);
}
diff --git a/src/vty_interface.c b/src/vty_interface.c
index f90780d..6d0c7b6 100644
--- a/src/vty_interface.c
+++ b/src/vty_interface.c
@@ -71,18 +71,18 @@ static int config_write_cell(struct vty *vty)
vty_out(vty, " mtp ni %d%s", bsc.ni_ni, VTY_NEWLINE);
vty_out(vty, " mtp spare %d%s", bsc.ni_spare, VTY_NEWLINE);
vty_out(vty, " mtp sltm once %d%s", bsc.once, VTY_NEWLINE);
- vty_out(vty, " country-code %d%s", bsc.mcc, VTY_NEWLINE);
- vty_out(vty, " network-code %d%s", bsc.mnc, VTY_NEWLINE);
- vty_out(vty, " location-area-code %d%s", bsc.lac, VTY_NEWLINE);
+ vty_out(vty, " country-code %d%s", bsc.msc_forward.mcc, VTY_NEWLINE);
+ vty_out(vty, " network-code %d%s", bsc.msc_forward.mnc, VTY_NEWLINE);
+ vty_out(vty, " location-area-code %d%s", bsc.msc_forward.lac, VTY_NEWLINE);
if (bsc.udp_ip)
vty_out(vty, " udp dest ip %s%s", bsc.udp_ip, VTY_NEWLINE);
vty_out(vty, " udp dest port %d%s", bsc.udp_port, VTY_NEWLINE);
vty_out(vty, " udp src port %d%s", bsc.src_port, VTY_NEWLINE);
vty_out(vty, " udp reset %d%s", bsc.udp_reset_timeout, VTY_NEWLINE);
vty_out(vty, " udp number-links %d%s", bsc.udp_nr_links, VTY_NEWLINE);
- vty_out(vty, " msc ip %s%s", bsc.msc_address, VTY_NEWLINE);
- vty_out(vty, " msc ip-dscp %d%s", bsc.msc_ip_dscp, VTY_NEWLINE);
- vty_out(vty, " msc token %s%s", bsc.token, VTY_NEWLINE);
+ vty_out(vty, " msc ip %s%s", bsc.msc_forward.msc_address, VTY_NEWLINE);
+ vty_out(vty, " msc ip-dscp %d%s", bsc.msc_forward.msc_ip_dscp, VTY_NEWLINE);
+ vty_out(vty, " msc token %s%s", bsc.msc_forward.token, VTY_NEWLINE);
vty_out(vty, " isup pass-through %d%s", bsc.isup_pass, VTY_NEWLINE);
return CMD_SUCCESS;
@@ -209,7 +209,7 @@ DEFUN(cfg_msc_ip, cfg_msc_ip_cmd,
addr = (struct in_addr *) hosts->h_addr_list[0];
- bsc.msc_address = talloc_strdup(NULL, inet_ntoa(*addr));
+ bsc.msc_forward.msc_address = talloc_strdup(NULL, inet_ntoa(*addr));
return CMD_SUCCESS;
}
@@ -218,7 +218,7 @@ DEFUN(cfg_msc_ip_dscp, cfg_msc_ip_dscp_cmd,
"Set the IP DSCP on the A-link\n"
"Set the DSCP in IP packets to the MSC")
{
- bsc.msc_ip_dscp = atoi(argv[0]);
+ bsc.msc_forward.msc_ip_dscp = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -231,7 +231,7 @@ DEFUN(cfg_msc_token, cfg_msc_token_cmd,
"msc token TOKEN",
"Set the Token to be used for the MSC")
{
- bsc.token = talloc_strdup(NULL, argv[0]);
+ bsc.msc_forward.token = talloc_strdup(NULL, argv[0]);
return CMD_SUCCESS;
}
@@ -239,7 +239,7 @@ DEFUN(cfg_ping_time, cfg_ping_time_cmd,
"timeout ping NR",
"Set the PING interval. Negative to disable it")
{
- bsc.ping_time = atoi(argv[0]);
+ bsc.msc_forward.ping_time = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -247,7 +247,7 @@ DEFUN(cfg_pong_time, cfg_pong_time_cmd,
"timeout pong NR",
"Set the PING interval. Negative to disable it")
{
- bsc.pong_time = atoi(argv[0]);
+ bsc.msc_forward.pong_time = atoi(argv[0]);
return CMD_SUCCESS;
}
@@ -255,21 +255,21 @@ DEFUN(cfg_msc_time, cfg_msc_time_cmd,
"timeout msc NR",
"Set the MSC connect timeout")
{
- bsc.msc_time = atoi(argv[0]);
+ bsc.msc_forward.msc_time = atoi(argv[0]);
return CMD_SUCCESS;
}
-static void update_lai(struct bsc_data *bsc)
+static void update_lai(struct bsc_msc_forward *fw)
{
- gsm48_generate_lai(&bsc->lai, bsc->mcc, bsc->mnc, bsc->lac);
+ gsm48_generate_lai(&fw->lai, fw->mcc, fw->mnc, fw->lac);
}
DEFUN(cfg_mnc, cfg_mnc_cmd,
"network-code NR",
"Set the Mobile Network Code\n" "Number\n")
{
- bsc.mnc = atoi(argv[0]);
- update_lai(&bsc);
+ bsc.msc_forward.mnc = atoi(argv[0]);
+ update_lai(&bsc.msc_forward);
return CMD_SUCCESS;
}
@@ -277,8 +277,8 @@ DEFUN(cfg_mcc, cfg_mcc_cmd,
"country-code NR",
"Set the Mobile Country Code\n" "Number\n")
{
- bsc.mcc = atoi(argv[0]);
- update_lai(&bsc);
+ bsc.msc_forward.mcc = atoi(argv[0]);
+ update_lai(&bsc.msc_forward);
return CMD_SUCCESS;
}
@@ -286,8 +286,8 @@ DEFUN(cfg_lac, cfg_lac_cmd,
"location-area-code NR",
"Set the Location Area Code\n" "Number\n")
{
- bsc.lac = atoi(argv[0]);
- update_lai(&bsc);
+ bsc.msc_forward.lac = atoi(argv[0]);
+ update_lai(&bsc.msc_forward);
return CMD_SUCCESS;
}
@@ -372,8 +372,8 @@ DEFUN(show_msc, show_msc_cmd,
SHOW_STR "Display the status of the MSC\n")
{
vty_out(vty, "MSC link is %s and had %s.%s",
- bsc.msc_link_down == 0 ? "up" : "down",
- bsc.first_contact == 1 ? "no contact" : "contact",
+ bsc.msc_forward.msc_link_down == 0 ? "up" : "down",
+ bsc.msc_forward.first_contact == 1 ? "no contact" : "contact",
VTY_NEWLINE);
return CMD_SUCCESS;
}