blob: 236d190818f0ae7ae27558acf986408d58cd0deb [file] [log] [blame]
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +01001/* link management code */
2/*
3 * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
4 * (C) 2010-2011 by On-Waves
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23#include <bsc_data.h>
24#include <cellmgr_debug.h>
Holger Hans Peter Freyther84ec8712011-02-15 20:01:47 +010025#include <msc_connection.h>
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010026#include <mtp_data.h>
Holger Hans Peter Freytherddf8eae2011-01-22 17:36:01 +010027#include <mtp_pcap.h>
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010028#include <snmp_mtp.h>
29
Holger Hans Peter Freyther644aafb2011-01-03 23:51:07 +010030#include <osmocore/talloc.h>
31
Holger Hans Peter Freyther2ff47b82011-02-15 20:25:10 +010032extern struct bsc_data *bsc;
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010033
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010034int is_one_up(struct mtp_link_set *set)
35{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010036 struct mtp_link *entry;
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010037
38 llist_for_each_entry(entry, &set->links, entry)
39 if (entry->available)
40 return 1;
41 return 0;
42}
43
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010044void mtp_link_down(struct mtp_link *link)
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010045{
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010046 int one_up;
47 int was_up;
48
49 was_up = link->available;
50 link->available = 0;
Holger Hans Peter Freythera8ce0612011-01-20 16:30:24 +010051 link->was_up = 0;
Holger Hans Peter Freyther2d845fc2011-01-20 15:42:13 +010052 one_up = is_one_up(link->set);
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010053
54 /* our linkset is now unsuable */
55 if (was_up && !one_up)
Holger Hans Peter Freyther2d845fc2011-01-20 15:42:13 +010056 mtp_linkset_down(link->set);
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010057 link->clear_queue(link);
Holger Hans Peter Freythera8ce0612011-01-20 16:30:24 +010058 mtp_link_stop_link_test(link);
Holger Hans Peter Freyther2d845fc2011-01-20 15:42:13 +010059 mtp_link_set_init_slc(link->set);
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010060}
61
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010062void mtp_link_up(struct mtp_link *link)
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010063{
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010064 int one_up;
65
Holger Hans Peter Freyther309d79f2011-01-28 18:26:20 +010066 if (link->blocked) {
Holger Hans Peter Freyther5a34c7f2011-02-17 03:23:42 +010067 LOGP(DINP, LOGL_ERROR,
68 "Ignoring link up on blocked link %d/%s of linkset %d/%s.\n",
69 link->nr, link->name, link->set->nr, link->set->name);
Holger Hans Peter Freyther309d79f2011-01-28 18:26:20 +010070 return;
71 }
72
Holger Hans Peter Freyther2d845fc2011-01-20 15:42:13 +010073 one_up = is_one_up(link->set);
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010074 link->available = 1;
Holger Hans Peter Freythera8ce0612011-01-20 16:30:24 +010075 link->was_up = 0;
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010076
Holger Hans Peter Freyther2d845fc2011-01-20 15:42:13 +010077 mtp_link_set_init_slc(link->set);
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010078 if (!one_up)
Holger Hans Peter Freyther2d845fc2011-01-20 15:42:13 +010079 mtp_linkset_up(link->set);
Holger Hans Peter Freythera8ce0612011-01-20 16:30:24 +010080 else
81 mtp_link_start_link_test(link);
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010082}
83
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010084void mtp_link_restart(struct mtp_link *link)
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010085{
86 LOGP(DINP, LOGL_ERROR, "Need to restart the SS7 link.\n");
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +010087 link->reset(link);
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010088}
89
Holger Hans Peter Freyther89fa11a2011-02-10 18:26:07 +010090struct mtp_link_set *link_init(struct bsc_data *bsc)
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010091{
Holger Hans Peter Freytherc6bfa272011-01-22 17:06:34 +010092 int i;
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010093 struct mtp_udp_link *lnk;
Holger Hans Peter Freyther6c0b2e52011-02-17 02:18:38 +010094 struct mtp_link *blnk;
Holger Hans Peter Freyther89fa11a2011-02-10 18:26:07 +010095 struct mtp_link_set *set;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +010096
Holger Hans Peter Freyther599c9a42011-02-15 11:18:38 +010097 set = mtp_link_set_alloc(bsc);
Holger Hans Peter Freyther89fa11a2011-02-10 18:26:07 +010098 set->name = talloc_strdup(set, "MTP");
99 set->dpc = bsc->dpc;
100 set->opc = bsc->opc;
101 set->sccp_opc = bsc->sccp_opc > -1 ? bsc->sccp_opc : bsc->opc;
102 set->isup_opc = bsc->isup_opc > -1 ? bsc->isup_opc : bsc->opc;
103 set->sltm_once = bsc->once;
104 set->ni = bsc->ni_ni;
105 set->spare = bsc->ni_spare;
Holger Hans Peter Freyther89fa11a2011-02-10 18:26:07 +0100106 set->pcap_fd = bsc->pcap_fd;
Holger Hans Peter Freyther644aafb2011-01-03 23:51:07 +0100107
Holger Hans Peter Freyther1b5d8462011-02-17 01:48:42 +0100108 set->supported_ssn[1] = 1;
109 set->supported_ssn[7] = 1;
110 set->supported_ssn[8] = 1;
111 set->supported_ssn[146] = 1;
112 set->supported_ssn[254] = 1;
113
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100114 if (!bsc->src_port) {
115 LOGP(DINP, LOGL_ERROR, "You need to set a UDP address.\n");
Holger Hans Peter Freyther89fa11a2011-02-10 18:26:07 +0100116 return NULL;
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100117 }
118
119 LOGP(DINP, LOGL_NOTICE, "Using UDP MTP mode.\n");
120
Holger Hans Peter Freyther3a1c0af2011-01-24 20:21:11 +0100121 if (link_global_init(&bsc->udp_data, bsc->src_port) != 0)
Holger Hans Peter Freyther89fa11a2011-02-10 18:26:07 +0100122 return NULL;
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100123
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100124
Holger Hans Peter Freytherc6bfa272011-01-22 17:06:34 +0100125 for (i = 1; i <= bsc->udp_nr_links; ++i) {
Holger Hans Peter Freyther6c0b2e52011-02-17 02:18:38 +0100126 blnk = mtp_link_alloc(set);
127 lnk = talloc_zero(blnk, struct mtp_udp_link);
128 lnk->base = blnk;
129 lnk->base->data = lnk;
130 lnk->base->type = SS7_LTYPE_UDP;
Holger Hans Peter Freytherc6bfa272011-01-22 17:06:34 +0100131 lnk->bsc = bsc;
132 lnk->data = &bsc->udp_data;
133 lnk->link_index = i;
134 lnk->reset_timeout = bsc->udp_reset_timeout;
Holger Hans Peter Freytherc6bfa272011-01-22 17:06:34 +0100135
136 /* now connect to the transport */
137 if (link_udp_init(lnk, bsc->udp_ip, bsc->udp_port) != 0)
Holger Hans Peter Freyther89fa11a2011-02-10 18:26:07 +0100138 return NULL;
Holger Hans Peter Freytherc6bfa272011-01-22 17:06:34 +0100139 }
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100140
Holger Hans Peter Freyther89fa11a2011-02-10 18:26:07 +0100141 return set;
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100142}
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100143
144int link_shutdown_all(struct mtp_link_set *set)
145{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100146 struct mtp_link *lnk;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100147
148 llist_for_each_entry(lnk, &set->links, entry)
149 lnk->shutdown(lnk);
150 return 0;
151}
152
153int link_reset_all(struct mtp_link_set *set)
154{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100155 struct mtp_link *lnk;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100156
157 llist_for_each_entry(lnk, &set->links, entry)
158 lnk->reset(lnk);
159 return 0;
160}
161
162int link_clear_all(struct mtp_link_set *set)
163{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100164 struct mtp_link *lnk;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100165
166 llist_for_each_entry(lnk, &set->links, entry)
167 lnk->clear_queue(lnk);
168 return 0;
169}
Holger Hans Peter Freytherddf8eae2011-01-22 17:36:01 +0100170
Holger Hans Peter Freyther36260e92011-01-22 17:37:56 +0100171int mtp_handle_pcap(struct mtp_link *link, int dir, const uint8_t *data, int len)
Holger Hans Peter Freytherddf8eae2011-01-22 17:36:01 +0100172{
Holger Hans Peter Freyther8ade9b72011-01-23 16:18:18 +0100173 if (link->pcap_fd >= 0)
Holger Hans Peter Freytherf6375b42011-01-22 21:01:23 +0100174 mtp_pcap_write_msu(link->pcap_fd, data, len);
Holger Hans Peter Freyther8ade9b72011-01-23 16:18:18 +0100175 if (link->set->pcap_fd >= 0)
Holger Hans Peter Freytherf6375b42011-01-22 21:01:23 +0100176 mtp_pcap_write_msu(link->set->pcap_fd, data, len);
Holger Hans Peter Freyther16b07c62011-01-22 23:19:27 +0100177
178 /* This might be too expensive? */
179 LOGP(DPCAP, LOGL_NOTICE, "Packet: %s\n", hexdump(data, len));
Holger Hans Peter Freytherddf8eae2011-01-22 17:36:01 +0100180 return 0;
181}