From 84ec8714b21a766471129282b98a8bcbfef799f0 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 15 Feb 2011 20:01:47 +0100 Subject: 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. --- include/Makefile.am | 2 +- include/bsc_data.h | 68 +++-------------------- include/bsc_sccp.h | 10 ++-- include/bsc_ussd.h | 6 +-- include/msc_connection.h | 84 +++++++++++++++++++++++++++++ include/mtp_data.h | 4 +- src/bsc.c | 2 + src/bsc_sccp.c | 13 ++--- src/bsc_ussd.c | 4 +- src/links.c | 5 +- src/main.c | 27 ++++++---- src/main_stp.c | 6 ++- src/msc_conn.c | 137 ++++++++++++++++++++++++++++++----------------- src/sccp_state.c | 37 ++++++------- src/vty_interface.c | 81 ++++++++++++++++++++++++---- 15 files changed, 314 insertions(+), 172 deletions(-) create mode 100644 include/msc_connection.h diff --git a/include/Makefile.am b/include/Makefile.am index 1dbaef7..ce617e7 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -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 diff --git a/include/bsc_data.h b/include/bsc_data.h index 6fb5b26..ac799f1 100644 --- a/include/bsc_data.h +++ b/include/bsc_data.h @@ -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, diff --git a/include/bsc_sccp.h b/include/bsc_sccp.h index 833257d..9c3bb11 100644 --- a/include/bsc_sccp.h +++ b/include/bsc_sccp.h @@ -30,7 +30,7 @@ #include -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 diff --git a/include/bsc_ussd.h b/include/bsc_ussd.h index 988b7ab..23ec40f 100644 --- a/include/bsc_ussd.h +++ b/include/bsc_ussd.h @@ -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 diff --git a/include/msc_connection.h b/include/msc_connection.h new file mode 100644 index 0000000..3770452 --- /dev/null +++ b/include/msc_connection.h @@ -0,0 +1,84 @@ +/* + * (C) 2010-2011 by Holger Hans Peter Freyther + * (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 . + */ + +#ifndef MSC_CONNECTION_H +#define MSC_CONNECTION_H + +#include +#include +#include + +#include + +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 diff --git a/include/mtp_data.h b/include/mtp_data.h index d054de8..6ed31c3 100644 --- a/include/mtp_data.h +++ b/include/mtp_data.h @@ -25,7 +25,7 @@ #include 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; }; diff --git a/src/bsc.c b/src/bsc.c index 081774d..af2c1c7 100644 --- a/src/bsc.c +++ b/src/bsc.c @@ -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; diff --git a/src/bsc_sccp.c b/src/bsc_sccp.c index f0bd600..b8276d2 100644 --- a/src/bsc_sccp.c +++ b/src/bsc_sccp.c @@ -1,7 +1,7 @@ /* routines to track connections */ /* - * (C) 2010 by Holger Hans Peter Freyther - * (C) 2010 by On-Waves + * (C) 2010-2011 by Holger Hans Peter Freyther + * (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 +#include #include #include -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; diff --git a/src/bsc_ussd.c b/src/bsc_ussd.c index 7cdce1a..ca16759 100644 --- a/src/bsc_ussd.c +++ b/src/bsc_ussd.c @@ -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; diff --git a/src/links.c b/src/links.c index b74d843..2a72b46 100644 --- a/src/links.c +++ b/src/links.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -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); } diff --git a/src/main.c b/src/main.c index 93e9ee3..2962d94 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -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); diff --git a/src/main_stp.c b/src/main_stp.c index 203ce12..95007f6 100644 --- a/src/main_stp.c +++ b/src/main_stp.c @@ -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; +} diff --git a/src/msc_conn.c b/src/msc_conn.c index e43a304..7eb18aa 100644 --- a/src/msc_conn.c +++ b/src/msc_conn.c @@ -19,6 +19,7 @@ * */ +#include #include #include #include @@ -28,6 +29,7 @@ #include #include +#include #include #include @@ -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; +} diff --git a/src/sccp_state.c b/src/sccp_state.c index 2c79bd4..3457756 100644 --- a/src/sccp_state.c +++ b/src/sccp_state.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -44,13 +45,13 @@ #include 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; diff --git a/src/vty_interface.c b/src/vty_interface.c index fbf0200..e7193f4 100644 --- a/src/vty_interface.c +++ b/src/vty_interface.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -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; } -- cgit v1.2.3