9
0
Fork 0

bsc: Move the BSC<->MSC variables to a new struct.

Move the MSC related information out of the bsc_data and update
the code to use this BSC configuration. This is greatly cleaning
up the code and in theory there might now be two BSC and two MSCs
that one application can handle (minus the missing VTY config)
This commit is contained in:
Holger Hans Peter Freyther 2011-02-10 15:32:14 +01:00
parent ee63d7d15e
commit e86c02e107
11 changed files with 333 additions and 301 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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;
};
/**

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}