aboutsummaryrefslogtreecommitdiffstats
path: root/src/msc_conn.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-02-10 15:32:14 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-02-10 20:09:09 +0100
commite86c02e107d9bef11a69ecef85d923ae4f523ef3 (patch)
tree7797afa28ff03963e8f84f254b9b91b311b89ad0 /src/msc_conn.c
parentee63d7d15e14ca0b653086043e7a6d1d537a89a1 (diff)
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)
Diffstat (limited to 'src/msc_conn.c')
-rw-r--r--src/msc_conn.c235
1 files changed, 116 insertions, 119 deletions
diff --git a/src/msc_conn.c b/src/msc_conn.c
index 8f17eb4..31a71fd 100644
--- a/src/msc_conn.c
+++ b/src/msc_conn.c
@@ -22,6 +22,7 @@
#include <bsc_data.h>
#include <bsc_ussd.h>
#include <bss_patch.h>
+#include <bsc_sccp.h>
#include <bssap_sccp.h>
#include <ipaccess.h>
#include <mtp_data.h>
@@ -42,9 +43,9 @@
#define RECONNECT_TIME 10, 0
#define NAT_MUX 0xfc
-static void msc_send_id_response(struct bsc_data *bsc);
-static void msc_send(struct bsc_data *bsc, struct msgb *msg, int proto);
-static void msc_schedule_reconnect(struct bsc_data *bsc);
+static void msc_send_id_response(struct bsc_msc_forward *bsc);
+static void msc_send(struct bsc_msc_forward *bsc, struct msgb *msg, int proto);
+static void msc_schedule_reconnect(struct bsc_msc_forward *bsc);
int send_or_queue_bsc_msg(struct mtp_link_set *link, int sls, struct msgb *msg)
{
@@ -53,37 +54,37 @@ int send_or_queue_bsc_msg(struct mtp_link_set *link, int sls, struct msgb *msg)
return 0;
}
-void msc_close_connection(struct bsc_data *bsc)
+void msc_close_connection(struct bsc_msc_forward *fw)
{
- struct bsc_fd *bfd = &bsc->msc_connection.bfd;
+ struct bsc_fd *bfd = &fw->msc_connection.bfd;
close(bfd->fd);
bsc_unregister_fd(bfd);
bfd->fd = -1;
- bsc->msc_link_down = 1;
- release_bsc_resources(bsc);
- bsc_del_timer(&bsc->ping_timeout);
- bsc_del_timer(&bsc->pong_timeout);
- bsc_del_timer(&bsc->msc_timeout);
- msc_schedule_reconnect(bsc);
+ fw->msc_link_down = 1;
+ release_bsc_resources(fw);
+ bsc_del_timer(&fw->ping_timeout);
+ bsc_del_timer(&fw->pong_timeout);
+ bsc_del_timer(&fw->msc_timeout);
+ msc_schedule_reconnect(fw);
}
-static void msc_connect_timeout(void *_bsc_data)
+static void msc_connect_timeout(void *_fw_data)
{
- struct bsc_data *bsc_data = _bsc_data;
+ struct bsc_msc_forward *fw = _fw_data;
LOGP(DMSC, LOGL_ERROR, "Timeout on the MSC connection.\n");
- msc_close_connection(bsc_data);
+ msc_close_connection(fw);
}
-static void msc_pong_timeout(void *_bsc_data)
+static void msc_pong_timeout(void *_fw_data)
{
- struct bsc_data *bsc_data = _bsc_data;
+ struct bsc_msc_forward *fw = _fw_data;
LOGP(DMSC, LOGL_ERROR, "MSC didn't respond to ping. Closing.\n");
- msc_close_connection(bsc_data);
+ msc_close_connection(fw);
}
-static void send_ping(struct bsc_data *bsc)
+static void send_ping(struct bsc_msc_forward *fw)
{
struct msgb *msg;
@@ -96,23 +97,23 @@ static void send_ping(struct bsc_data *bsc)
msg->l2h = msgb_put(msg, 1);
msg->l2h[0] = IPAC_MSGT_PING;
- msc_send(bsc, msg, IPAC_PROTO_IPACCESS);
+ msc_send(fw, msg, IPAC_PROTO_IPACCESS);
}
-static void msc_ping_timeout(void *_bsc_data)
+static void msc_ping_timeout(void *_fw_data)
{
- struct bsc_data *bsc_data = _bsc_data;
+ struct bsc_msc_forward *fw = _fw_data;
- if (bsc_data->ping_time < 0)
+ if (fw->ping_time < 0)
return;
- send_ping(bsc_data);
+ send_ping(fw);
/* send another ping in 20 seconds */
- bsc_schedule_timer(&bsc_data->ping_timeout, bsc_data->ping_time, 0);
+ bsc_schedule_timer(&fw->ping_timeout, fw->ping_time, 0);
/* also start a pong timer */
- bsc_schedule_timer(&bsc_data->pong_timeout, bsc_data->pong_time, 0);
+ bsc_schedule_timer(&fw->pong_timeout, fw->pong_time, 0);
}
/*
@@ -122,21 +123,19 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
{
int error;
struct ipaccess_head *hh;
- struct mtp_link_set *link;
- struct bsc_data *bsc;
+ struct bsc_msc_forward *fw;
struct msgb *msg;
+ fw = bfd->data;
msg = ipaccess_read_msg(bfd, &error);
- bsc = (struct bsc_data *) bfd->data;
-
if (!msg) {
if (error == 0)
fprintf(stderr, "The connection to the MSC was lost, exiting\n");
else
fprintf(stderr, "Error in the IPA stream.\n");
- msc_close_connection(bsc);
+ msc_close_connection(fw);
return -1;
}
@@ -146,29 +145,27 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
hh = (struct ipaccess_head *) msg->data;
ipaccess_rcvmsg_base(msg, bfd);
- link = bsc->link_set;
-
/* initialize the networking. This includes sending a GSM08.08 message */
if (hh->proto == IPAC_PROTO_IPACCESS) {
- if (bsc->first_contact) {
+ if (fw->first_contact) {
LOGP(DMSC, LOGL_NOTICE, "Connected to MSC. Sending reset.\n");
- bsc_del_timer(&bsc->msc_timeout);
- bsc->first_contact = 0;
- bsc->msc_link_down = 0;
- msc_send_reset(bsc);
+ bsc_del_timer(&fw->msc_timeout);
+ fw->first_contact = 0;
+ fw->msc_link_down = 0;
+ msc_send_reset(fw);
}
- if (msg->l2h[0] == IPAC_MSGT_ID_GET && bsc->token) {
- msc_send_id_response(bsc);
+ if (msg->l2h[0] == IPAC_MSGT_ID_GET && fw->token) {
+ msc_send_id_response(fw);
} else if (msg->l2h[0] == IPAC_MSGT_PONG) {
- bsc_del_timer(&bsc->pong_timeout);
+ bsc_del_timer(&fw->pong_timeout);
}
} else if (hh->proto == IPAC_PROTO_SCCP) {
struct sccp_parse_result result;
int rc;
/* we can not forward it right now */
- if (bsc->forward_only && link->sccp_up) {
- if (send_or_queue_bsc_msg(link, -1, msg) != 1)
+ if (fw->forward_only && fw->bsc->sccp_up) {
+ if (send_or_queue_bsc_msg(fw->bsc, -1, msg) != 1)
msgb_free(msg);
return 0;
}
@@ -180,31 +177,31 @@ static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
LOGP(DMSC, LOGL_NOTICE, "Filtering reset ack from the MSC\n");
} else if (rc == BSS_FILTER_RLSD) {
LOGP(DMSC, LOGL_DEBUG, "Filtering RLSD from the MSC\n");
- update_con_state(NULL, rc, &result, msg, 1, 0);
+ update_con_state(fw, rc, &result, msg, 1, 0);
} else if (rc == BSS_FILTER_RLC) {
/* if we receive this we have forwarded a RLSD to the network */
LOGP(DMSC, LOGL_ERROR, "RLC from the network. BAD!\n");
} else if (rc == BSS_FILTER_CLEAR_COMPL) {
LOGP(DMSC, LOGL_ERROR, "Clear Complete from the network.\n");
- } else if (link->sccp_up) {
+ } else if (fw->bsc->sccp_up) {
unsigned int sls;
- update_con_state(NULL, rc, &result, msg, 1, 0);
- sls = sls_for_src_ref(result.destination_local_reference);
+ update_con_state(fw, rc, &result, msg, 1, 0);
+ sls = sls_for_src_ref(fw, result.destination_local_reference);
/* Check for Location Update Accept */
- bsc_ussd_handle_in_msg(bsc, &result, msg);
+ bsc_ussd_handle_in_msg(fw, &result, msg);
/* patch a possible PC */
- bss_rewrite_header_to_bsc(msg, link->opc, link->dpc);
+ bss_rewrite_header_to_bsc(msg, fw->bsc->opc, fw->bsc->dpc);
/* we can not forward it right now */
- if (send_or_queue_bsc_msg(link, sls, msg) == 1)
+ if (send_or_queue_bsc_msg(fw->bsc, sls, msg) == 1)
return 0;
}
} else if (hh->proto == NAT_MUX) {
- mgcp_forward(bsc, msg->l2h, msgb_l2len(msg));
+ mgcp_forward(fw, msg->l2h, msgb_l2len(msg));
} else {
LOGP(DMSC, LOGL_ERROR, "Unknown IPA proto 0x%x\n", hh->proto);
}
@@ -231,11 +228,11 @@ static int msc_connection_connect(struct bsc_fd *fd, unsigned int what)
int rc;
int val;
socklen_t len = sizeof(val);
- struct bsc_data *bsc;
+ struct bsc_msc_forward *fw;
- bsc = (struct bsc_data *) fd->data;
+ fw = fd->data;
- if (fd != &bsc->msc_connection.bfd) {
+ if (fd != &fw->msc_connection.bfd) {
LOGP(DMSC, LOGL_ERROR, "This is only working with the MSC connection.\n");
return -1;
}
@@ -258,12 +255,12 @@ static int msc_connection_connect(struct bsc_fd *fd, unsigned int what)
/* go to full operation */
fd->cb = write_queue_bfd_cb;
fd->when = BSC_FD_READ;
- if (!llist_empty(&bsc->msc_connection.msg_queue))
+ if (!llist_empty(&fw->msc_connection.msg_queue))
fd->when |= BSC_FD_WRITE;
return 0;
error:
- msc_close_connection(bsc);
+ msc_close_connection(fw);
return -1;
}
@@ -352,26 +349,26 @@ static int connect_to_msc(struct bsc_fd *fd, const char *ip, int port, int tos)
static void msc_reconnect(void *_data)
{
int rc;
- struct bsc_data *bsc = (struct bsc_data *) _data;
+ struct bsc_msc_forward *fw = _data;
- bsc_del_timer(&bsc->reconnect_timer);
- bsc->first_contact = 1;
+ bsc_del_timer(&fw->reconnect_timer);
+ fw->first_contact = 1;
- rc = connect_to_msc(&bsc->msc_connection.bfd, bsc->msc_address, 5000, bsc->msc_ip_dscp);
+ rc = connect_to_msc(&fw->msc_connection.bfd, fw->msc_address, 5000, fw->msc_ip_dscp);
if (rc < 0) {
fprintf(stderr, "Opening the MSC connection failed. Trying again\n");
- bsc_schedule_timer(&bsc->reconnect_timer, RECONNECT_TIME);
+ bsc_schedule_timer(&fw->reconnect_timer, RECONNECT_TIME);
return;
}
- bsc->msc_timeout.cb = msc_connect_timeout;
- bsc->msc_timeout.data = bsc;
- bsc_schedule_timer(&bsc->msc_timeout, bsc->msc_time, 0);
+ fw->msc_timeout.cb = msc_connect_timeout;
+ fw->msc_timeout.data = fw;
+ bsc_schedule_timer(&fw->msc_timeout, fw->msc_time, 0);
}
-static void msc_schedule_reconnect(struct bsc_data *bsc)
+static void msc_schedule_reconnect(struct bsc_msc_forward *fw)
{
- bsc_schedule_timer(&bsc->reconnect_timer, RECONNECT_TIME);
+ bsc_schedule_timer(&fw->reconnect_timer, RECONNECT_TIME);
}
/*
@@ -417,7 +414,7 @@ static int mgcp_do_read(struct bsc_fd *fd)
return 0;
}
-void mgcp_forward(struct bsc_data *bsc, const uint8_t *data, unsigned int length)
+void mgcp_forward(struct bsc_msc_forward *fw, const uint8_t *data, unsigned int length)
{
struct msgb *mgcp;
@@ -434,25 +431,25 @@ void mgcp_forward(struct bsc_data *bsc, const uint8_t *data, unsigned int length
msgb_put(mgcp, length);
memcpy(mgcp->data, data, mgcp->len);
- if (write_queue_enqueue(&bsc->mgcp_agent, mgcp) != 0) {
+ if (write_queue_enqueue(&fw->mgcp_agent, mgcp) != 0) {
LOGP(DMGCP, LOGL_FATAL, "Could not queue message to MGCP GW.\n");
msgb_free(mgcp);
}
}
-static int mgcp_create_port(struct bsc_data *bsc)
+static int mgcp_create_port(struct bsc_msc_forward *fw)
{
int on;
struct sockaddr_in addr;
- bsc->mgcp_agent.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (bsc->mgcp_agent.bfd.fd < 0) {
+ fw->mgcp_agent.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fw->mgcp_agent.bfd.fd < 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to create UDP socket errno: %d\n", errno);
return -1;
}
on = 1;
- setsockopt(bsc->mgcp_agent.bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ setsockopt(fw->mgcp_agent.bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
/* try to bind the socket */
memset(&addr, 0, sizeof(addr));
@@ -460,66 +457,66 @@ static int mgcp_create_port(struct bsc_data *bsc)
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = 0;
- if (bind(bsc->mgcp_agent.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ if (bind(fw->mgcp_agent.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to bind to any port.\n");
- close(bsc->mgcp_agent.bfd.fd);
- bsc->mgcp_agent.bfd.fd = -1;
+ close(fw->mgcp_agent.bfd.fd);
+ fw->mgcp_agent.bfd.fd = -1;
return -1;
}
/* connect to the remote */
addr.sin_port = htons(2427);
- if (connect(bsc->mgcp_agent.bfd.fd, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
+ if (connect(fw->mgcp_agent.bfd.fd, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to connect to local MGCP GW. %s\n", strerror(errno));
- close(bsc->mgcp_agent.bfd.fd);
- bsc->mgcp_agent.bfd.fd = -1;
+ close(fw->mgcp_agent.bfd.fd);
+ fw->mgcp_agent.bfd.fd = -1;
return -1;
}
- write_queue_init(&bsc->mgcp_agent, 10);
- bsc->mgcp_agent.bfd.data = bsc;
- bsc->mgcp_agent.bfd.when = BSC_FD_READ;
- bsc->mgcp_agent.read_cb = mgcp_do_read;
- bsc->mgcp_agent.write_cb = mgcp_do_write;
+ write_queue_init(&fw->mgcp_agent, 10);
+ fw->mgcp_agent.bfd.data = fw;
+ fw->mgcp_agent.bfd.when = BSC_FD_READ;
+ fw->mgcp_agent.read_cb = mgcp_do_read;
+ fw->mgcp_agent.write_cb = mgcp_do_write;
- if (bsc_register_fd(&bsc->mgcp_agent.bfd) != 0) {
+ if (bsc_register_fd(&fw->mgcp_agent.bfd) != 0) {
LOGP(DMGCP, LOGL_FATAL, "Failed to register BFD\n");
- close(bsc->mgcp_agent.bfd.fd);
- bsc->mgcp_agent.bfd.fd = -1;
+ close(fw->mgcp_agent.bfd.fd);
+ fw->mgcp_agent.bfd.fd = -1;
return -1;
}
return 0;
}
-int msc_init(struct bsc_data *bsc, int mgcp)
+int msc_init(struct bsc_msc_forward *fw, int mgcp)
{
- write_queue_init(&bsc->msc_connection, 100);
- bsc->reconnect_timer.cb = msc_reconnect;
- bsc->reconnect_timer.data = bsc;
- bsc->msc_connection.read_cb = ipaccess_a_fd_cb;
- bsc->msc_connection.write_cb = ipaccess_write_cb;
- bsc->msc_connection.bfd.data = bsc;
- bsc->msc_link_down = 1;
+ write_queue_init(&fw->msc_connection, 100);
+ fw->reconnect_timer.cb = msc_reconnect;
+ fw->reconnect_timer.data = fw;
+ fw->msc_connection.read_cb = ipaccess_a_fd_cb;
+ fw->msc_connection.write_cb = ipaccess_write_cb;
+ fw->msc_connection.bfd.data = fw;
+ fw->msc_link_down = 1;
/* handle the timeout */
- bsc->ping_timeout.cb = msc_ping_timeout;
- bsc->ping_timeout.data = bsc;
- bsc->pong_timeout.cb = msc_pong_timeout;
- bsc->pong_timeout.data = bsc;
+ fw->ping_timeout.cb = msc_ping_timeout;
+ fw->ping_timeout.data = fw;
+ fw->pong_timeout.cb = msc_pong_timeout;
+ fw->pong_timeout.data = fw;
/* create MGCP port */
- if (mgcp && mgcp_create_port(bsc) != 0)
+ if (mgcp && mgcp_create_port(fw) != 0)
return -1;
/* now connect to the BSC */
- msc_schedule_reconnect(bsc);
+ msc_schedule_reconnect(fw);
return 0;
}
-static void msc_send(struct bsc_data *bsc, struct msgb *msg, int proto)
+static void msc_send(struct bsc_msc_forward *fw, struct msgb *msg, int proto)
{
- if (bsc->msc_link_down) {
+ if (fw->msc_link_down) {
LOGP(DMSC, LOGL_NOTICE, "Dropping data due lack of MSC connection.\n");
msgb_free(msg);
return;
@@ -527,19 +524,19 @@ static void msc_send(struct bsc_data *bsc, struct msgb *msg, int proto)
ipaccess_prepend_header(msg, proto);
- if (write_queue_enqueue(&bsc->msc_connection, msg) != 0) {
+ if (write_queue_enqueue(&fw->msc_connection, msg) != 0) {
LOGP(DMSC, LOGL_FATAL, "Failed to queue MSG for the MSC.\n");
msgb_free(msg);
return;
}
}
-void msc_send_rlc(struct bsc_data *bsc,
+void msc_send_rlc(struct bsc_msc_forward *fw,
struct sccp_source_reference *src, struct sccp_source_reference *dst)
{
struct msgb *msg;
- if (bsc->msc_link_down) {
+ if (fw->msc_link_down) {
LOGP(DMSC, LOGL_NOTICE, "Not releasing connection due lack of connection.\n");
return;
}
@@ -548,14 +545,14 @@ void msc_send_rlc(struct bsc_data *bsc,
if (!msg)
return;
- msc_send(bsc, msg, IPAC_PROTO_SCCP);
+ msc_send(fw, msg, IPAC_PROTO_SCCP);
}
-void msc_send_reset(struct bsc_data *bsc)
+void msc_send_reset(struct bsc_msc_forward *fw)
{
struct msgb *msg;
- if (bsc->msc_link_down) {
+ if (fw->msc_link_down) {
LOGP(DMSC, LOGL_NOTICE, "Not sending reset due lack of connection.\n");
return;
}
@@ -564,37 +561,37 @@ void msc_send_reset(struct bsc_data *bsc)
if (!msg)
return;
- msc_send(bsc, msg, IPAC_PROTO_SCCP);
- msc_ping_timeout(bsc);
+ msc_send(fw, msg, IPAC_PROTO_SCCP);
+ msc_ping_timeout(fw);
}
-static void msc_send_id_response(struct bsc_data *bsc)
+static void msc_send_id_response(struct bsc_msc_forward *fw)
{
struct msgb *msg;
msg = msgb_alloc_headroom(4096, 128, "id resp");
msg->l2h = msgb_v_put(msg, IPAC_MSGT_ID_RESP);
- msgb_l16tv_put(msg, strlen(bsc->token) + 1,
- IPAC_IDTAG_UNITNAME, (uint8_t *) bsc->token);
+ msgb_l16tv_put(msg, strlen(fw->token) + 1,
+ IPAC_IDTAG_UNITNAME, (uint8_t *) fw->token);
- msc_send(bsc, msg, IPAC_PROTO_IPACCESS);
+ msc_send(fw, msg, IPAC_PROTO_IPACCESS);
}
-void msc_send_direct(struct bsc_data *bsc, struct msgb *msg)
+void msc_send_direct(struct bsc_msc_forward *fw, struct msgb *msg)
{
- return msc_send(bsc, msg, IPAC_PROTO_SCCP);
+ return msc_send(fw, msg, IPAC_PROTO_SCCP);
}
-void msc_send_msg(struct bsc_data *bsc, int rc, struct sccp_parse_result *result, struct msgb *_msg)
+void msc_send_msg(struct bsc_msc_forward *fw, int rc, struct sccp_parse_result *result, struct msgb *_msg)
{
struct msgb *msg;
- if (bsc->msc_connection.bfd.fd < 0) {
+ if (fw->msc_connection.bfd.fd < 0) {
LOGP(DMSC, LOGL_ERROR, "No connection to the MSC. dropping\n");
return;
}
- bsc_ussd_handle_out_msg(bsc, result, _msg);
+ bsc_ussd_handle_out_msg(fw, result, _msg);
msg = msgb_alloc_headroom(4096, 128, "SCCP to MSC");
if (!msg) {
@@ -603,5 +600,5 @@ void msc_send_msg(struct bsc_data *bsc, int rc, struct sccp_parse_result *result
}
bss_rewrite_header_for_msc(rc, msg, _msg, result);
- msc_send(bsc, msg, IPAC_PROTO_SCCP);
+ msc_send(fw, msg, IPAC_PROTO_SCCP);
}