diff options
Diffstat (limited to 'src/msc_conn.c')
-rw-r--r-- | src/msc_conn.c | 137 |
1 files changed, 87 insertions, 50 deletions
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 <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; +} |