9
0
Fork 0

msc: Move the MSC Connection into a new header file

This is in preparation of splitting the MSC part and the
nat logic for the upcoming config rewriting.
This commit is contained in:
Holger Hans Peter Freyther 2011-02-15 20:01:47 +01:00
parent f7ce2c6417
commit 84ec8714b2
15 changed files with 314 additions and 172 deletions

View File

@ -1,6 +1,6 @@
noinst_HEADERS = mtp_level3.h mtp_data.h ipaccess.h thread.h mtp_pcap.h \
mgcp_ss7.h bss_patch.h bssap_sccp.h bsc_data.h udp_input.h \
snmp_mtp.h cellmgr_debug.h bsc_sccp.h bsc_ussd.h sctp_m2ua.h \
isup_types.h counter.h
isup_types.h counter.h msc_connection.h
SUBDIRS = mgcp

View File

@ -39,53 +39,9 @@
struct bsc_data;
struct snmp_mtp_session;
struct msc_connection;
struct mtp_m2ua_transport;
/**
* 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;
@ -154,29 +110,22 @@ struct bsc_data {
struct bsc_fd inject_fd;
struct llist_head inject_list;
/* MSC related data... currently only one is supported */
struct bsc_msc_forward msc_forward;
/* m2ua code */
struct sctp_m2ua_transport *m2ua_trans;
/* MSCs */
struct llist_head mscs;
int num_mscs;
};
/* bsc related functions */
void release_bsc_resources(struct bsc_msc_forward *fw);
void release_bsc_resources(struct msc_connection *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_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 bsc_msc_forward *fw, int rc, struct sccp_parse_result *result, struct msgb *msg, int from_msc, int sls);
void update_con_state(struct msc_connection *msc, 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);
@ -186,9 +135,6 @@ int link_shutdown_all(struct mtp_link_set *);
int link_reset_all(struct mtp_link_set *);
int link_clear_all(struct mtp_link_set *);
/* MGCP */
void mgcp_forward(struct bsc_msc_forward *bsc, const uint8_t *data, unsigned int length);
/* pcap */
enum {
NET_IN,

View File

@ -30,7 +30,7 @@
#include <osmocom/sccp/sccp.h>
struct bsc_msc_forward;
struct msc_connection;
/*
* One SCCP connection.
@ -63,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 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 active_sccp_con *find_con_by_dest_ref(struct msc_connection *, struct sccp_source_reference *ref);
struct active_sccp_con *find_con_by_src_ref(struct msc_connection *,struct sccp_source_reference *src_ref);
struct active_sccp_con *find_con_by_src_dest_ref(struct msc_connection *, struct sccp_source_reference *src_ref,
struct sccp_source_reference *dst_ref);
unsigned int sls_for_src_ref(struct bsc_msc_forward *, struct sccp_source_reference *ref);
unsigned int sls_for_src_ref(struct msc_connection *, struct sccp_source_reference *ref);
#endif

View File

@ -21,10 +21,10 @@
#ifndef bsc_ussd_h
#define bsc_ussd_h
struct bsc_msc_forward;
struct msc_connection;
int bsc_ussd_handle_out_msg(struct bsc_msc_forward *, struct sccp_parse_result *result, struct msgb *msg);
int bsc_ussd_handle_out_msg(struct msc_connection *, 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);
int bsc_ussd_handle_in_msg(struct msc_connection *, struct sccp_parse_result *res, struct msgb *msg);
#endif

84
include/msc_connection.h Normal file
View File

@ -0,0 +1,84 @@
/*
* (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010-2011 by On-Waves
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MSC_CONNECTION_H
#define MSC_CONNECTION_H
#include <osmocore/linuxlist.h>
#include <osmocore/write_queue.h>
#include <osmocore/timer.h>
#include <osmocom/sccp/sccp.h>
struct bsc_data;
struct ss7_application;
struct msc_connection {
/* management */
struct llist_head entry;
int nr;
char *name;
/* ip management */
int dscp;
char *ip;
char *token;
/* connection management */
int msc_link_down;
struct write_queue msc_connection;
struct timer_list reconnect_timer;
int first_contact;
/* time to wait for first message from MSC */
struct timer_list msc_timeout;
int msc_time;
/* 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;
/* application pointer */
struct llist_head sccp_connections;
struct mtp_link_set *target_link;
int forward_only;
int reset_count;
};
/* msc related functions */
void msc_send_rlc(struct msc_connection *bsc, struct sccp_source_reference *src, struct sccp_source_reference *dest);
void msc_send_reset(struct msc_connection *bsc);
void msc_send_msg(struct msc_connection *bsc, int rc, struct sccp_parse_result *, struct msgb *msg);
void msc_send_direct(struct msc_connection *bsc, struct msgb *msg);
void msc_close_connection(struct msc_connection *data);
struct msc_connection *msc_connection_create(struct bsc_data *bsc, int mgcp);
struct msc_connection *msc_connection_num(struct bsc_data *bsc, int num);
int msc_connection_start(struct msc_connection *msc);
/* MGCP */
void mgcp_forward(struct msc_connection *msc, const uint8_t *data, unsigned int length);
#endif

View File

@ -25,7 +25,7 @@
#include <osmocore/utils.h>
struct bsc_data;
struct bsc_msc_forward;
struct msc_connection;
struct mtp_link;
struct mtp_level_3_mng *mng;
struct rate_ctr_group;
@ -76,7 +76,7 @@ struct mtp_link_set {
/* custom data */
struct bsc_data *bsc;
struct bsc_msc_forward *fw;
struct msc_connection *fw;
struct mtp_link_set *forward;
};

View File

@ -36,6 +36,8 @@ struct bsc_data *bsc_data_create()
}
INIT_LLIST_HEAD(&bsc->linksets);
INIT_LLIST_HEAD(&bsc->mscs);
bsc->dpc = 1;
bsc->opc = 0;
bsc->sccp_opc = -1;

View File

@ -1,7 +1,7 @@
/* routines to track connections */
/*
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010 by On-Waves
* (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010-2011 by On-Waves
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
@ -23,12 +23,13 @@
#include "bsc_data.h"
#include <cellmgr_debug.h>
#include <msc_connection.h>
#include <osmocore/talloc.h>
#include <string.h>
struct active_sccp_con *find_con_by_dest_ref(struct bsc_msc_forward *fw, struct sccp_source_reference *ref)
struct active_sccp_con *find_con_by_dest_ref(struct msc_connection *fw, struct sccp_source_reference *ref)
{
struct active_sccp_con *con;
@ -47,7 +48,7 @@ struct active_sccp_con *find_con_by_dest_ref(struct bsc_msc_forward *fw, struct
}
struct active_sccp_con *find_con_by_src_ref(struct bsc_msc_forward *fw, struct sccp_source_reference *src_ref)
struct active_sccp_con *find_con_by_src_ref(struct msc_connection *fw, struct sccp_source_reference *src_ref)
{
struct active_sccp_con *con;
@ -63,7 +64,7 @@ struct active_sccp_con *find_con_by_src_ref(struct bsc_msc_forward *fw, struct s
return NULL;
}
struct active_sccp_con *find_con_by_src_dest_ref(struct bsc_msc_forward *fw,
struct active_sccp_con *find_con_by_src_dest_ref(struct msc_connection *fw,
struct sccp_source_reference *src_ref,
struct sccp_source_reference *dst_ref)
{
@ -79,7 +80,7 @@ struct active_sccp_con *find_con_by_src_dest_ref(struct bsc_msc_forward *fw,
return NULL;
}
unsigned int sls_for_src_ref(struct bsc_msc_forward *fw, struct sccp_source_reference *ref)
unsigned int sls_for_src_ref(struct msc_connection *fw, struct sccp_source_reference *ref)
{
struct active_sccp_con *con;

View File

@ -25,7 +25,7 @@
* Check the msg and identify a Location Updating Request and see if the
* LAC is different to this one and then mark the CR message.
*/
int bsc_ussd_handle_out_msg(struct bsc_data *bsc, struct sccp_parse_result *result,
int bsc_ussd_handle_out_msg(struct msc_connection *msc, struct sccp_parse_result *result,
struct msgb *msg)
{
/* Only search for this in the CR message */
@ -40,7 +40,7 @@ int bsc_ussd_handle_out_msg(struct bsc_data *bsc, struct sccp_parse_result *resu
/*
* Check the message if it contains a location update request...
*/
int bsc_ussd_handle_in_msg(struct bsc_data *bsc, struct sccp_parse_result *res,
int bsc_ussd_handle_in_msg(struct msc_connection *msc, struct sccp_parse_result *res,
struct msgb *msg)
{
return 0;

View File

@ -22,6 +22,7 @@
#include <bsc_data.h>
#include <cellmgr_debug.h>
#include <msc_connection.h>
#include <mtp_data.h>
#include <mtp_pcap.h>
#include <snmp_mtp.h>
@ -87,11 +88,13 @@ void mtp_link_restart(struct mtp_link *link)
static void start_rest(void *_set)
{
struct msc_connection *msc;
struct mtp_link_set *set = _set;
struct mtp_link *data;
bsc->setup = 1;
if (msc_init(&bsc->msc_forward, 1) != 0) {
msc = msc_connection_num(bsc, 0);
if (msc && msc_connection_start(msc) != 0) {
fprintf(stderr, "Failed to init MSC part.\n");
exit(3);
}

View File

@ -20,6 +20,7 @@
*/
#include <mtp_data.h>
#include <msc_connection.h>
#include <mtp_level3.h>
#include <mtp_pcap.h>
#include <thread.h>
@ -97,8 +98,11 @@ out:
static void sigusr2()
{
struct msc_connection *msc;
printf("Closing the MSC connection on demand.\n");
msc_close_connection(&bsc->msc_forward);
llist_for_each_entry(msc, &bsc->mscs, entry)
msc_close_connection(msc);
}
static void print_help()
@ -157,13 +161,9 @@ static void handle_options(int argc, char **argv)
}
}
static void bsc_msc_forward_init(struct bsc_data *bsc,
struct bsc_msc_forward *msc)
static void bsc_msc_forward_init(struct msc_connection *msc)
{
INIT_LLIST_HEAD(&msc->sccp_connections);
msc->bsc_data = bsc;
msc->msc_address = "127.0.0.1";
msc->ip = talloc_strdup(msc, "127.0.0.1");
msc->ping_time = 20;
msc->pong_time = 5;
msc->msc_time = 20;
@ -172,9 +172,9 @@ static void bsc_msc_forward_init(struct bsc_data *bsc,
int main(int argc, char **argv)
{
int rc;
struct msc_connection *msc;
struct mtp_link_set *set;
thread_init();
log_init(&log_info);
@ -198,7 +198,12 @@ int main(int argc, char **argv)
bsc->app = APP_CELLMGR;
/* msc data */
bsc_msc_forward_init(bsc, &bsc->msc_forward);
msc = msc_connection_create(bsc, 1);
if (!msc) {
LOGP(DINP, LOGL_ERROR, "Failed to create the MSC connection.\n");
return -1;
}
bsc_msc_forward_init(msc);
handle_options(argc, argv);
@ -221,8 +226,8 @@ int main(int argc, char **argv)
if (!set)
return -1;
set->fw = &bsc->msc_forward;
bsc->msc_forward.bsc = set;
set->fw = msc;
msc->target_link = set;
while (1) {
bsc_select_main(0);

View File

@ -393,8 +393,12 @@ int main(int argc, char **argv)
}
/* dummy for links */
int msc_init(struct bsc_msc_forward *data, int dummy)
int msc_connection_start(struct msc_connection *conn)
{
return 0;
}
struct msc_connection *msc_connection_num(struct bsc_data *bsc, int num)
{
return NULL;
}

View File

@ -19,6 +19,7 @@
*
*/
#include <msc_connection.h>
#include <bsc_data.h>
#include <bsc_ussd.h>
#include <bss_patch.h>
@ -28,6 +29,7 @@
#include <mtp_data.h>
#include <cellmgr_debug.h>
#include <osmocore/talloc.h>
#include <osmocore/tlv.h>
#include <osmocore/utils.h>
@ -43,9 +45,9 @@
#define RECONNECT_TIME 10, 0
#define NAT_MUX 0xfc
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);
static void msc_send_id_response(struct msc_connection *bsc);
static void msc_send(struct msc_connection *bsc, struct msgb *msg, int proto);
static void msc_schedule_reconnect(struct msc_connection *bsc);
int send_or_queue_bsc_msg(struct mtp_link_set *link, int sls, struct msgb *msg)
{
@ -54,7 +56,7 @@ int send_or_queue_bsc_msg(struct mtp_link_set *link, int sls, struct msgb *msg)
return 0;
}
void msc_close_connection(struct bsc_msc_forward *fw)
void msc_close_connection(struct msc_connection *fw)
{
struct bsc_fd *bfd = &fw->msc_connection.bfd;
@ -71,7 +73,7 @@ void msc_close_connection(struct bsc_msc_forward *fw)
static void msc_connect_timeout(void *_fw_data)
{
struct bsc_msc_forward *fw = _fw_data;
struct msc_connection *fw = _fw_data;
LOGP(DMSC, LOGL_ERROR, "Timeout on the MSC connection.\n");
msc_close_connection(fw);
@ -79,12 +81,12 @@ static void msc_connect_timeout(void *_fw_data)
static void msc_pong_timeout(void *_fw_data)
{
struct bsc_msc_forward *fw = _fw_data;
struct msc_connection *fw = _fw_data;
LOGP(DMSC, LOGL_ERROR, "MSC didn't respond to ping. Closing.\n");
msc_close_connection(fw);
}
static void send_ping(struct bsc_msc_forward *fw)
static void send_ping(struct msc_connection *fw)
{
struct msgb *msg;
@ -102,7 +104,7 @@ static void send_ping(struct bsc_msc_forward *fw)
static void msc_ping_timeout(void *_fw_data)
{
struct bsc_msc_forward *fw = _fw_data;
struct msc_connection *fw = _fw_data;
if (fw->ping_time < 0)
return;
@ -123,7 +125,7 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
{
int error;
struct ipaccess_head *hh;
struct bsc_msc_forward *fw;
struct msc_connection *fw;
struct msgb *msg;
fw = bfd->data;
@ -165,7 +167,7 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
/* we can not forward it right now */
if (fw->forward_only) {
if (fw->bsc->sccp_up && send_or_queue_bsc_msg(fw->bsc, -1, msg) == 1)
if (fw->target_link->sccp_up && send_or_queue_bsc_msg(fw->target_link, -1, msg) == 1)
return 0;
msgb_free(msg);
@ -185,7 +187,7 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
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 (fw->bsc->sccp_up) {
} else if (fw->target_link->sccp_up) {
unsigned int sls;
update_con_state(fw, rc, &result, msg, 1, 0);
@ -195,10 +197,10 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
bsc_ussd_handle_in_msg(fw, &result, msg);
/* patch a possible PC */
bss_rewrite_header_to_bsc(msg, fw->bsc->opc, fw->bsc->dpc);
bss_rewrite_header_to_bsc(msg, fw->target_link->opc, fw->target_link->dpc);
/* we can not forward it right now */
if (send_or_queue_bsc_msg(fw->bsc, sls, msg) == 1)
if (send_or_queue_bsc_msg(fw->target_link, sls, msg) == 1)
return 0;
}
@ -230,7 +232,7 @@ static int msc_connection_connect(struct bsc_fd *fd, unsigned int what)
int rc;
int val;
socklen_t len = sizeof(val);
struct bsc_msc_forward *fw;
struct msc_connection *fw;
fw = fd->data;
@ -351,12 +353,12 @@ 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_msc_forward *fw = _data;
struct msc_connection *fw = _data;
bsc_del_timer(&fw->reconnect_timer);
fw->first_contact = 1;
rc = connect_to_msc(&fw->msc_connection.bfd, fw->msc_address, 5000, fw->msc_ip_dscp);
rc = connect_to_msc(&fw->msc_connection.bfd, fw->ip, 5000, fw->dscp);
if (rc < 0) {
fprintf(stderr, "Opening the MSC connection failed. Trying again\n");
bsc_schedule_timer(&fw->reconnect_timer, RECONNECT_TIME);
@ -368,7 +370,7 @@ static void msc_reconnect(void *_data)
bsc_schedule_timer(&fw->msc_timeout, fw->msc_time, 0);
}
static void msc_schedule_reconnect(struct bsc_msc_forward *fw)
static void msc_schedule_reconnect(struct msc_connection *fw)
{
bsc_schedule_timer(&fw->reconnect_timer, RECONNECT_TIME);
}
@ -416,7 +418,7 @@ static int mgcp_do_read(struct bsc_fd *fd)
return 0;
}
void mgcp_forward(struct bsc_msc_forward *fw, const uint8_t *data, unsigned int length)
void mgcp_forward(struct msc_connection *fw, const uint8_t *data, unsigned int length)
{
struct msgb *mgcp;
@ -439,7 +441,7 @@ void mgcp_forward(struct bsc_msc_forward *fw, const uint8_t *data, unsigned int
}
}
static int mgcp_create_port(struct bsc_msc_forward *fw)
static int mgcp_create_port(struct msc_connection *fw)
{
int on;
struct sockaddr_in addr;
@ -491,32 +493,7 @@ static int mgcp_create_port(struct bsc_msc_forward *fw)
return 0;
}
int msc_init(struct bsc_msc_forward *fw, int mgcp)
{
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 */
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(fw) != 0)
return -1;
/* now connect to the BSC */
msc_schedule_reconnect(fw);
return 0;
}
static void msc_send(struct bsc_msc_forward *fw, struct msgb *msg, int proto)
static void msc_send(struct msc_connection *fw, struct msgb *msg, int proto)
{
if (fw->msc_link_down) {
LOGP(DMSC, LOGL_NOTICE, "Dropping data due lack of MSC connection.\n");
@ -533,7 +510,7 @@ static void msc_send(struct bsc_msc_forward *fw, struct msgb *msg, int proto)
}
}
void msc_send_rlc(struct bsc_msc_forward *fw,
void msc_send_rlc(struct msc_connection *fw,
struct sccp_source_reference *src, struct sccp_source_reference *dst)
{
struct msgb *msg;
@ -550,7 +527,7 @@ void msc_send_rlc(struct bsc_msc_forward *fw,
msc_send(fw, msg, IPAC_PROTO_SCCP);
}
void msc_send_reset(struct bsc_msc_forward *fw)
void msc_send_reset(struct msc_connection *fw)
{
struct msgb *msg;
@ -567,7 +544,7 @@ void msc_send_reset(struct bsc_msc_forward *fw)
msc_ping_timeout(fw);
}
static void msc_send_id_response(struct bsc_msc_forward *fw)
static void msc_send_id_response(struct msc_connection *fw)
{
struct msgb *msg;
@ -579,12 +556,12 @@ static void msc_send_id_response(struct bsc_msc_forward *fw)
msc_send(fw, msg, IPAC_PROTO_IPACCESS);
}
void msc_send_direct(struct bsc_msc_forward *fw, struct msgb *msg)
void msc_send_direct(struct msc_connection *fw, struct msgb *msg)
{
return msc_send(fw, msg, IPAC_PROTO_SCCP);
}
void msc_send_msg(struct bsc_msc_forward *fw, int rc, struct sccp_parse_result *result, struct msgb *_msg)
void msc_send_msg(struct msc_connection *fw, int rc, struct sccp_parse_result *result, struct msgb *_msg)
{
struct msgb *msg;
@ -604,3 +581,63 @@ void msc_send_msg(struct bsc_msc_forward *fw, int rc, struct sccp_parse_result *
bss_rewrite_header_for_msc(rc, msg, _msg, result);
msc_send(fw, msg, IPAC_PROTO_SCCP);
}
struct msc_connection *msc_connection_create(struct bsc_data *bsc, int mgcp)
{
struct msc_connection *msc;
msc = talloc_zero(NULL, struct msc_connection);
if (!msc) {
LOGP(DMSC, LOGL_ERROR, "Failed to allocate the MSC Connection.\n");
return NULL;
}
write_queue_init(&msc->msc_connection, 100);
msc->reconnect_timer.cb = msc_reconnect;
msc->reconnect_timer.data = msc;
msc->msc_connection.read_cb = ipaccess_a_fd_cb;
msc->msc_connection.write_cb = ipaccess_write_cb;
msc->msc_connection.bfd.data = msc;
msc->msc_link_down = 1;
/* handle the timeout */
msc->ping_timeout.cb = msc_ping_timeout;
msc->ping_timeout.data = msc;
msc->pong_timeout.cb = msc_pong_timeout;
msc->pong_timeout.data = msc;
/* create MGCP port */
if (mgcp && mgcp_create_port(msc) != 0) {
LOGP(DMSC, LOGL_ERROR, "Failed to bind for the MGCP port.\n");
talloc_free(msc);
return NULL;
}
INIT_LLIST_HEAD(&msc->sccp_connections);
llist_add(&msc->entry, &bsc->mscs);
msc->nr = bsc->num_mscs++;
return msc;
}
struct msc_connection *msc_connection_num(struct bsc_data *bsc, int num)
{
struct msc_connection *msc;
llist_for_each_entry(msc, &bsc->mscs, entry)
if (msc->nr == num)
return msc;
return NULL;
}
int msc_connection_start(struct msc_connection *msc)
{
if (msc->msc_connection.bfd.fd > 0) {
LOGP(DMSC, LOGL_ERROR,
"Function should not be called with active connection.\n");
return -1;
}
msc_schedule_reconnect(msc);
return 0;
}

View File

@ -20,6 +20,7 @@
*/
#include <mtp_data.h>
#include <msc_connection.h>
#include <mtp_level3.h>
#include <bss_patch.h>
#include <bssap_sccp.h>
@ -44,13 +45,13 @@
#include <unistd.h>
static void send_reset_ack(struct mtp_link_set *link, int sls);
static void bsc_resources_released(struct bsc_msc_forward *bsc);
static void bsc_resources_released(struct msc_connection *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_msc_forward *bsc);
static void clear_connections(struct msc_connection *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_msc_forward *fw)
static void mgcp_reset(struct msc_connection *fw)
{
static const char mgcp_reset[] = {
"RSIP 1 13@mgw MGCP 1.0\r\n"
@ -66,7 +67,7 @@ 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;
struct msc_connection *fw = link->fw;
if (fw->forward_only) {
msc_send_direct(fw, _msg);
@ -177,7 +178,7 @@ static void handle_local_sccp(struct mtp_link_set *link, struct msgb *inpt, stru
return;
}
static void clear_connections(struct bsc_msc_forward *fw)
static void clear_connections(struct msc_connection *fw)
{
struct active_sccp_con *tmp, *con;
@ -185,10 +186,10 @@ static void clear_connections(struct bsc_msc_forward *fw)
free_con(con);
}
link_clear_all(fw->bsc);
link_clear_all(fw->target_link);
}
void bsc_resources_released(struct bsc_msc_forward *fw)
void bsc_resources_released(struct msc_connection *fw)
{
bsc_del_timer(&fw->reset_timeout);
}
@ -196,14 +197,14 @@ void bsc_resources_released(struct bsc_msc_forward *fw)
static void bsc_reset_timeout(void *_data)
{
struct msgb *msg;
struct bsc_msc_forward *fw = _data;
struct msc_connection *fw = _data;
/* no reset */
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(fw->bsc);
mtp_link_set_stop(fw->target_link);
clear_connections(fw);
link_reset_all(fw->bsc);
link_reset_all(fw->target_link);
bsc_resources_released(fw);
return;
}
@ -215,7 +216,7 @@ static void bsc_reset_timeout(void *_data)
}
++fw->reset_count;
mtp_link_set_submit_sccp_data(fw->bsc, -1, msg->l2h, msgb_l2len(msg));
mtp_link_set_submit_sccp_data(fw->target_link, -1, msg->l2h, msgb_l2len(msg));
msgb_free(msg);
bsc_schedule_timer(&fw->reset_timeout, 20, 0);
}
@ -238,7 +239,7 @@ 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_msc_forward *fw)
void release_bsc_resources(struct msc_connection *fw)
{
struct active_sccp_con *tmp;
struct active_sccp_con *con;
@ -260,7 +261,7 @@ void release_bsc_resources(struct bsc_msc_forward *fw)
continue;
/* wait for the clear commands */
mtp_link_set_submit_sccp_data(fw->bsc, con->sls, msg->l2h, msgb_l2len(msg));
mtp_link_set_submit_sccp_data(fw->target_link, con->sls, msg->l2h, msgb_l2len(msg));
msgb_free(msg);
}
@ -302,7 +303,7 @@ void mtp_linkset_up(struct mtp_link_set *set)
/**
* update the connection state and helpers below
*/
static void send_rlc_to_bsc(struct bsc_msc_forward *fw,
static void send_rlc_to_bsc(struct msc_connection *fw,
unsigned int sls, struct sccp_source_reference *src,
struct sccp_source_reference *dst)
{
@ -312,11 +313,11 @@ static void send_rlc_to_bsc(struct bsc_msc_forward *fw,
if (!msg)
return;
mtp_link_set_submit_sccp_data(fw->bsc, sls, msg->l2h, msgb_l2len(msg));
mtp_link_set_submit_sccp_data(fw->target_link, sls, msg->l2h, msgb_l2len(msg));
msgb_free(msg);
}
static void handle_rlsd(struct bsc_msc_forward *fw, struct sccp_connection_released *rlsd, int from_msc)
static void handle_rlsd(struct msc_connection *fw, struct sccp_connection_released *rlsd, int from_msc)
{
struct active_sccp_con *con;
@ -373,7 +374,7 @@ static void handle_rlsd(struct bsc_msc_forward *fw, struct sccp_connection_relea
* 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 bsc_msc_forward *fw, int rc, struct sccp_parse_result *res, struct msgb *msg, int from_msc, int sls)
void update_con_state(struct msc_connection *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;
@ -409,7 +410,7 @@ void update_con_state(struct bsc_msc_forward *fw, int rc, struct sccp_parse_resu
con->src_ref = cr->source_local_reference;
con->sls = sls;
con->link = fw->bsc;
con->link = fw->target_link;
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;

View File

@ -21,6 +21,7 @@
#include <bsc_data.h>
#include <mtp_pcap.h>
#include <msc_connection.h>
#include <osmocore/talloc.h>
#include <osmocore/gsm48.h>
@ -64,6 +65,8 @@ static struct cmd_node cell_node = {
static int config_write_cell(struct vty *vty)
{
struct msc_connection *msc = msc_connection_num(bsc, 0);
vty_out(vty, "cellmgr%s", VTY_NEWLINE);
vty_out(vty, " mtp dpc %d%s", bsc->dpc, VTY_NEWLINE);
vty_out(vty, " mtp opc %d%s", bsc->opc, VTY_NEWLINE);
@ -77,11 +80,15 @@ static int config_write_cell(struct vty *vty)
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_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);
if (msc) {
vty_out(vty, " msc ip %s%s", msc->ip, VTY_NEWLINE);
vty_out(vty, " msc ip-dscp %d%s", msc->dscp, VTY_NEWLINE);
vty_out(vty, " msc token %s%s", msc->token, VTY_NEWLINE);
}
return CMD_SUCCESS;
}
@ -197,6 +204,12 @@ DEFUN(cfg_msc_ip, cfg_msc_ip_cmd,
{
struct hostent *hosts;
struct in_addr *addr;
struct msc_connection *msc = msc_connection_num(bsc, 0);
if (!msc) {
vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
return CMD_WARNING;
}
hosts = gethostbyname(argv[0]);
if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) {
@ -206,7 +219,9 @@ DEFUN(cfg_msc_ip, cfg_msc_ip_cmd,
addr = (struct in_addr *) hosts->h_addr_list[0];
bsc->msc_forward.msc_address = talloc_strdup(NULL, inet_ntoa(*addr));
if (msc->ip)
talloc_free(msc->ip);
msc->ip = talloc_strdup(msc, inet_ntoa(*addr));
return CMD_SUCCESS;
}
@ -215,7 +230,14 @@ 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_forward.msc_ip_dscp = atoi(argv[0]);
struct msc_connection *msc = msc_connection_num(bsc, 0);
if (!msc) {
vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
return CMD_WARNING;
}
msc->dscp = atoi(argv[0]);
return CMD_SUCCESS;
}
@ -228,7 +250,16 @@ DEFUN(cfg_msc_token, cfg_msc_token_cmd,
"msc token TOKEN",
"Set the Token to be used for the MSC")
{
bsc->msc_forward.token = talloc_strdup(NULL, argv[0]);
struct msc_connection *msc = msc_connection_num(bsc, 0);
if (!msc) {
vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (msc->token)
talloc_free(msc->token);
msc->token = talloc_strdup(msc, argv[0]);
return CMD_SUCCESS;
}
@ -236,7 +267,14 @@ DEFUN(cfg_ping_time, cfg_ping_time_cmd,
"timeout ping NR",
"Set the PING interval. Negative to disable it")
{
bsc->msc_forward.ping_time = atoi(argv[0]);
struct msc_connection *msc = msc_connection_num(bsc, 0);
if (!msc) {
vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
return CMD_WARNING;
}
msc->ping_time = atoi(argv[0]);
return CMD_SUCCESS;
}
@ -244,7 +282,14 @@ DEFUN(cfg_pong_time, cfg_pong_time_cmd,
"timeout pong NR",
"Set the PING interval. Negative to disable it")
{
bsc->msc_forward.pong_time = atoi(argv[0]);
struct msc_connection *msc = msc_connection_num(bsc, 0);
if (!msc) {
vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
return CMD_WARNING;
}
msc->pong_time = atoi(argv[0]);
return CMD_SUCCESS;
}
@ -252,7 +297,14 @@ DEFUN(cfg_msc_time, cfg_msc_time_cmd,
"timeout msc NR",
"Set the MSC connect timeout")
{
bsc->msc_forward.msc_time = atoi(argv[0]);
struct msc_connection *msc = msc_connection_num(bsc, 0);
if (!msc) {
vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
return CMD_WARNING;
}
msc->msc_time = atoi(argv[0]);
return CMD_SUCCESS;
}
@ -339,9 +391,16 @@ DEFUN(show_msc, show_msc_cmd,
"show msc",
SHOW_STR "Display the status of the MSC\n")
{
struct msc_connection *msc = msc_connection_num(bsc, 0);
if (!msc) {
vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
return CMD_WARNING;
}
vty_out(vty, "MSC link is %s and had %s.%s",
bsc->msc_forward.msc_link_down == 0 ? "up" : "down",
bsc->msc_forward.first_contact == 1 ? "no contact" : "contact",
msc->msc_link_down == 0 ? "up" : "down",
msc->first_contact == 1 ? "no contact" : "contact",
VTY_NEWLINE);
return CMD_SUCCESS;
}