blob: 1eb7ec986ac98172997037635c9e92581d1b6695 [file] [log] [blame]
Holger Hans Peter Freythera7bc3aa2011-02-16 16:12:07 +01001/*
2 * The SS7 Application part for forwarding or nat...
3 *
4 * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
5 * (C) 2010-2011 by On-Waves
6 * All Rights Reserved
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#include <ss7_application.h>
24#include <bsc_data.h>
25#include <cellmgr_debug.h>
26#include <msc_connection.h>
27#include <sctp_m2ua.h>
28
29#include <osmocore/talloc.h>
30
31struct ss7_application *ss7_application_alloc(struct bsc_data *bsc)
32{
33 struct ss7_application *app;
34
35 app = talloc_zero(bsc, struct ss7_application);
36 if (!app) {
37 LOGP(DINP, LOGL_ERROR, "Failed to create SS7 Application.\n");
38 return NULL;
39 }
40
41 INIT_LLIST_HEAD(&app->sccp_connections);
42 llist_add(&app->entry, &bsc->apps);
43 app->nr = bsc->num_apps++;
44 app->bsc = bsc;
45
46 return app;
47}
48
49struct ss7_application *ss7_application_num(struct bsc_data *bsc, int num)
50{
51 struct ss7_application *ss7;
52
53 llist_for_each_entry(ss7, &bsc->apps, entry)
54 if (ss7->nr == num)
55 return ss7;
56
57 return NULL;
58}
59
60static int ss7_app_setup_stp(struct ss7_application *app,
61 int src_type, int src_num,
62 int dst_type, int dst_num)
63{
64 struct mtp_link_set *src, *dst;
65
66 if (src_type != SS7_SET_LINKSET) {
67 LOGP(DINP, LOGL_ERROR,
68 "SS7 %d/%s source needs to be a linkset.\n",
69 app->nr, app->name);
70 return -1;
71 }
72
73 if (dst_type != SS7_SET_LINKSET) {
74 LOGP(DINP, LOGL_ERROR,
75 "SS7 %d/%s destination needs to be a linkset.\n",
76 app->nr, app->name);
77 return -1;
78 }
79
80 /* veryify the MTP Linkset */
81 src = mtp_link_set_num(app->bsc, src_num);
82 if (!src) {
83 LOGP(DINP, LOGL_ERROR,
84 "SS7 %d/%s source linkset not found with nr: %d.\n",
85 app->nr, app->name, src_num);
86 return -2;
87 }
88
89 if (src->app) {
90 LOGP(DINP, LOGL_ERROR,
91 "SS7 %d/%s is using linkset %d/%s\n",
92 src->app->nr, src->app->name,
93 src->no, src->name);
94 return -3;
95 }
96
97 /* veryify the MTP Linkset */
98 dst = mtp_link_set_num(app->bsc, dst_num);
99 if (!dst) {
100 LOGP(DINP, LOGL_ERROR,
101 "SS7 %d/%s destionation linkset not found with nr: %d.\n",
102 app->nr, app->name, dst_num);
103 return -2;
104 }
105
106 if (dst->app) {
107 LOGP(DINP, LOGL_ERROR,
108 "SS7 %d/%s is using linkset %d/%s\n",
109 dst->app->nr, dst->app->name,
110 dst->no, dst->name);
111 return -3;
112 }
113
114 /* now connect it */
115 src->app = app;
116 app->route_src.type = src_type;
117 app->route_src.nr = src_num;
118 app->route_src.set = src;
119 app->route_src.msc = NULL;
120
121 dst->app = app;
122 app->route_dst.type = dst_type;
123 app->route_dst.nr = dst_num;
124 app->route_dst.set = dst;
125 app->route_dst.msc = NULL;
126
127 app->type = APP_STP;
128 app->bsc->m2ua_trans->started = 1;
129
Holger Hans Peter Freythera7bc3aa2011-02-16 16:12:07 +0100130 return 0;
131}
132
133static int ss7_app_setup_relay(struct ss7_application *app, int type,
134 int src_type, int src_num, int dst_type, int dst_num)
135{
136 struct mtp_link_set *mtp;
137 struct msc_connection *msc;
138
139 /* verify the types */
140 if (src_type != SS7_SET_LINKSET) {
141 LOGP(DINP, LOGL_ERROR,
142 "SS7 %d/%s source needs to be a linkset.\n",
143 app->nr, app->name);
144 return -1;
145 }
146
147 if (dst_type != SS7_SET_MSC) {
148 LOGP(DINP, LOGL_ERROR,
149 "SS7 %d/%s dest needs to be a MSC.\n",
150 app->nr, app->name);
151 return -1;
152 }
153
154 /* veryify the MTP Linkset */
155 mtp = mtp_link_set_num(app->bsc, src_num);
156 if (!mtp) {
157 LOGP(DINP, LOGL_ERROR,
158 "SS7 %d/%s source linkset not found with nr: %d.\n",
159 app->nr, app->name, src_num);
160 return -2;
161 }
162
163 if (mtp->app) {
164 LOGP(DINP, LOGL_ERROR,
165 "SS7 %d/%s is using linkset %d/%s\n",
166 mtp->app->nr, mtp->app->name,
167 mtp->no, mtp->name);
168 return -3;
169 }
170
171 /* verify the MSC connection */
172 msc = msc_connection_num(app->bsc, dst_num);
173 if (!msc) {
174 LOGP(DINP, LOGL_ERROR,
175 "SS7 %d/%s dest MSC not found with nr: %d.\n",
176 app->nr, app->name, dst_num);
177 return -4;
178 }
179
180 if (msc->app) {
181 LOGP(DINP, LOGL_ERROR,
182 "SS7 %d/%s is using MSC connection %d/%s\n",
183 msc->app->nr, msc->app->name,
184 msc->nr, msc->name);
185 return -5;
186 }
187
188
189 /* now connect it and run the app */
190 mtp->app = app;
191 app->route_src.type = src_type;
192 app->route_src.nr = src_num;
193 app->route_src.set = mtp;
194 app->route_src.msc = NULL;
195
196 msc->app = app;
197 app->route_dst.type = dst_type;
198 app->route_dst.nr = dst_num;
199 app->route_dst.set = NULL;
200 app->route_dst.msc = msc;
201
202 app->type = type;
203
Holger Hans Peter Freythera7bc3aa2011-02-16 16:12:07 +0100204 return 0;
205}
206
207int ss7_application_setup(struct ss7_application *ss7, int type,
208 int src_type, int src_num,
209 int dst_type, int dst_num)
210{
211 switch (type) {
212 case APP_CELLMGR:
213 case APP_RELAY:
214 return ss7_app_setup_relay(ss7, type, src_type, src_num,
215 dst_type, dst_num);
216 break;
217 case APP_STP:
218 return ss7_app_setup_stp(ss7, src_type, src_num,
219 dst_type, dst_num);
220 default:
221 LOGP(DINP, LOGL_ERROR,
222 "SS7 Application %d is not supported.\n", type);
223 return -1;
224 }
225}
Holger Hans Peter Freytherab7c6012011-02-16 22:23:52 +0100226
227
228static void start_mtp(struct mtp_link_set *set)
229{
230 struct mtp_link *link;
231
232 llist_for_each_entry(link, &set->links, entry)
233 link->reset(link);
234}
235
236static void start_msc(struct msc_connection *msc)
237{
238 msc_connection_start(msc);
239}
240
241int ss7_application_start(struct ss7_application *app)
242{
243 if (app->route_src.set)
244 start_mtp(app->route_src.set);
245 if (app->route_dst.set)
246 start_mtp(app->route_dst.set);
247
248 if (app->route_src.msc)
249 start_msc(app->route_src.msc);
250 if (app->route_dst.msc)
251 start_msc(app->route_dst.msc);
252
253 LOGP(DINP, LOGL_NOTICE, "SS7 Application %d/%s is now running.\n",
254 app->nr, app->name);
255 return 0;
256}