blob: 1134e59f9b17ff1180f7c8a4b3c185715f9de831 [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>
25#include <mtp_data.h>
26#include <snmp_mtp.h>
27
Holger Hans Peter Freyther644aafb2011-01-03 23:51:07 +010028#include <osmocore/talloc.h>
29
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010030extern struct bsc_data bsc;
31
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010032int is_one_up(struct mtp_link_set *set)
33{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010034 struct mtp_link *entry;
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010035
36 llist_for_each_entry(entry, &set->links, entry)
37 if (entry->available)
38 return 1;
39 return 0;
40}
41
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010042void mtp_link_down(struct mtp_link *link)
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010043{
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010044 int one_up;
45 int was_up;
46
47 was_up = link->available;
48 link->available = 0;
49 one_up = is_one_up(link->the_link);
50
51 /* our linkset is now unsuable */
52 if (was_up && !one_up)
53 mtp_linkset_down(link->the_link);
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010054 link->clear_queue(link);
Holger Hans Peter Freyther069e6352011-01-04 13:01:23 +010055 mtp_link_set_init_slc(link->the_link);
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010056}
57
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010058void mtp_link_up(struct mtp_link *link)
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010059{
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010060 int one_up;
61
62 one_up = is_one_up(link->the_link);
63 link->available = 1;
64
Holger Hans Peter Freyther069e6352011-01-04 13:01:23 +010065 mtp_link_set_init_slc(link->the_link);
Holger Hans Peter Freyther0f833b02011-01-04 13:33:57 +010066 if (!one_up)
67 mtp_linkset_up(link->the_link);
Holger Hans Peter Freytherc8405692011-01-02 20:24:08 +010068}
69
Holger Hans Peter Freyther569f1e12011-01-02 18:47:49 +010070void mtp_link_set_sccp_down(struct mtp_link_set *link)
Holger Hans Peter Freyther016ba292010-12-20 16:21:18 +010071{
72}
73
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010074void mtp_link_set_submit(struct mtp_link *link, struct msgb *msg)
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010075{
Holger Hans Peter Freyther069e6352011-01-04 13:01:23 +010076 link->write(link, msg);
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010077}
78
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010079void mtp_link_restart(struct mtp_link *link)
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010080{
81 LOGP(DINP, LOGL_ERROR, "Need to restart the SS7 link.\n");
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +010082 link->reset(link);
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010083}
84
85static void start_rest(void *start)
86{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +010087 struct mtp_link *data;
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010088 bsc.setup = 1;
89
90 if (msc_init(&bsc, 1) != 0) {
91 fprintf(stderr, "Failed to init MSC part.\n");
92 exit(3);
93 }
94
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +010095 llist_for_each_entry(data, &bsc.link_set->links, entry)
96 data->start(data);
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +010097}
98
99int link_init(struct bsc_data *bsc)
100{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100101 struct mtp_udp_link *lnk;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100102
Holger Hans Peter Freyther644aafb2011-01-03 23:51:07 +0100103 bsc->link_set = mtp_link_set_alloc();
104 bsc->link_set->dpc = bsc->dpc;
105 bsc->link_set->opc = bsc->opc;
106 bsc->link_set->sccp_opc = bsc->sccp_opc > -1 ? bsc->sccp_opc : bsc->opc;
107 bsc->link_set->sltm_once = bsc->once;
108 bsc->link_set->ni = bsc->ni_ni;
109 bsc->link_set->spare = bsc->ni_spare;
110 bsc->link_set->bsc = bsc;
111
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100112 lnk = talloc_zero(bsc->link_set, struct mtp_udp_link);
113 lnk->base.pcap_fd = bsc->pcap_fd;
114 lnk->base.the_link = bsc->link_set;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100115 lnk->bsc = bsc;
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100116 lnk->link_index = 1;
117 lnk->reset_timeout = bsc->udp_reset_timeout;
118 mtp_link_set_add_link(bsc->link_set, (struct mtp_link *) lnk);
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100119
120 if (!bsc->src_port) {
121 LOGP(DINP, LOGL_ERROR, "You need to set a UDP address.\n");
122 return -1;
123 }
124
125 LOGP(DINP, LOGL_NOTICE, "Using UDP MTP mode.\n");
126
127 /* setup SNMP first, it is blocking */
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100128 lnk->session = snmp_mtp_session_create(bsc->udp_ip);
129 if (!lnk->session)
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100130 return -1;
131
132 /* now connect to the transport */
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100133 if (link_udp_init(lnk, bsc->src_port, bsc->udp_ip, bsc->udp_port) != 0)
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100134 return -1;
135
136 /*
137 * We will ask the MTP link to be taken down for two
138 * timeouts of the BSC to make sure we are missing the
139 * SLTM and it begins a reset. Then we will take it up
140 * again and do the usual business.
141 */
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100142 snmp_mtp_deactivate(lnk->session,
143 lnk->link_index);
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100144 bsc->start_timer.cb = start_rest;
145 bsc->start_timer.data = &bsc;
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100146 bsc_schedule_timer(&bsc->start_timer, lnk->reset_timeout, 0);
Holger Hans Peter Freythera99b04b2011-01-02 11:23:54 +0100147 LOGP(DMSC, LOGL_NOTICE, "Making sure SLTM will timeout.\n");
148
149 return 0;
150}
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100151
152int link_shutdown_all(struct mtp_link_set *set)
153{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100154 struct mtp_link *lnk;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100155
156 llist_for_each_entry(lnk, &set->links, entry)
157 lnk->shutdown(lnk);
158 return 0;
159}
160
161int link_reset_all(struct mtp_link_set *set)
162{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100163 struct mtp_link *lnk;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100164
165 llist_for_each_entry(lnk, &set->links, entry)
166 lnk->reset(lnk);
167 return 0;
168}
169
170int link_clear_all(struct mtp_link_set *set)
171{
Holger Hans Peter Freyther0e2f9112011-01-17 11:54:39 +0100172 struct mtp_link *lnk;
Holger Hans Peter Freytherfe72c162011-01-04 13:21:52 +0100173
174 llist_for_each_entry(lnk, &set->links, entry)
175 lnk->clear_queue(lnk);
176 return 0;
177}