blob: 5621e2835156f9671286fcf868c32ebd38cccbc2 [file] [log] [blame]
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +08001/* Use the UniPorte library to allocate endpoints */
2/*
Holger Hans Peter Freyther1cf3a832011-01-26 12:51:22 +01003 * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
4 * (C) 2010-2011 by On-Waves
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +08005 * All Rights Reserved
6 *
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +01007 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080010 * (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
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +010015 * GNU Affero General Public License for more details.
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080016 *
Holger Hans Peter Freytherde56c222011-01-16 17:45:14 +010017 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080019 *
20 */
21
22#include <mgcp_ss7.h>
23#include <mgcp/mgcp.h>
24#include <mgcp/mgcp_internal.h>
25
Holger Hans Peter Freythercbf7d182010-07-31 05:25:35 +080026#include <cellmgr_debug.h>
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080027
Holger Hans Peter Freythercbf7d182010-07-31 05:25:35 +080028#include <osmocore/select.h>
29#include <osmocore/talloc.h>
30#include <osmocore/timer.h>
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080031
Holger Hans Peter Freythercbf7d182010-07-31 05:25:35 +080032#include <osmocom/vty/vty.h>
Holger Hans Peter Freythercc1a9382010-08-04 06:24:04 +080033#include <osmocom/vty/telnet_interface.h>
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080034
35/* uniporte includes */
36#ifndef NO_UNIPORTE
37#include <UniPorte.h>
38#include <BusMastHostApi.h>
39#include <MtnSa.h>
40#include <SystemLayer.h>
41#include <PredefMobs.h>
42#endif
43
44#include <errno.h>
45#include <limits.h>
46#include <string.h>
47#include <unistd.h>
48#include <signal.h>
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080049
50#ifndef _GNU_SOURCE
51#define _GNU_SOURCE
52#endif
53#include <getopt.h>
54
Holger Hans Peter Freythercbf7d182010-07-31 05:25:35 +080055static struct log_target *stderr_target;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080056static char *config_file = "mgcp_mgw.cfg";
57static int exit_on_failure = 0;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080058
Holger Hans Peter Freyther1cf3a832011-01-26 12:51:22 +010059
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +010060extern struct mgcp_config *g_cfg;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080061
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +010062static void mgcp_ss7_endp_free(struct mgcp_endpoint *endp);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080063
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +010064
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +010065#ifndef NO_UNIPORTE
66static void mgcp_ss7_do_exec(struct mgcp_ss7 *mgcp, uint8_t type, struct mgcp_endpoint *, uint32_t param);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080067
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +010068/* Contains a mapping from UniPorte to the MGCP side of things */
69static struct mgcp_endpoint *s_endpoints[240];
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080070
Holger Hans Peter Freyther672f3212011-03-01 13:52:57 +010071static int select_voice_port(struct mgcp_endpoint *endp)
72{
73 int mgw_port;
74 int timeslot, multiplex;
75
76 mgcp_endpoint_to_timeslot(ENDPOINT_NUMBER(endp), &multiplex, &timeslot);
Holger Hans Peter Freyther3c8b0f82011-03-02 22:22:50 +010077 if (endp->blocked) {
78 LOGP(DMGCP, LOGL_ERROR, "Timeslot 0x%x is blocked.\n", timeslot);
Holger Hans Peter Freyther672f3212011-03-01 13:52:57 +010079 return -1;
80 }
81
82 mgw_port = endp->tcfg->voice_base + 30 * multiplex;
83
84 mgw_port = mgw_port + timeslot - endp->tcfg->endp_offset;
85 fprintf(stderr, "TEST: Going to use MGW: %d for MUL: %d TS: %d\n",
86 mgw_port, multiplex, timeslot);
87 return mgw_port;
88}
89
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080090static void check_exit(int status)
91{
92 if (exit_on_failure && status == 21) {
93 LOGP(DMGCP, LOGL_ERROR, "Failure detected with the MGW. Exiting.\n");
94 exit(-1);
95 }
96}
97
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +010098
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +080099static void Force_Poll( int milliseconds )
100{
101 int timeout = 0;
102 unsigned long startTime;
103
104 startTime = SysLyrGetTime();
105
106 /* Loop until the specified number of milliseconds
107 * have elapsed.
108 */
109 do {
110 MtnSaPoll();
111 SysLyrSleep( 20 );
112 } while ((SysLyrGetTime()-startTime)<(unsigned long)milliseconds);
113 return;
114}
115
116static char eventName[Event_TELEMETRY_DATA + 1][128] = {
117 { "Event_NOT_READY" },
118 { "Event_READY" },
119 { "Event_ANSWER" },
120 { "Event_OUTGOING_CALL" },
121 { "Event_ABORT" },
122 { "Event_CONNECT" },
123 { "Event_DISCONNECT" },
124 { "Event_MANAGED_OBJECT_GET_COMPLETE" },
125 { "Event_MANAGED_OBJECT_GET_AND_CLEAR_COMPLETE" },
126 { "Event_MANAGED_OBJECT_SET_COMPLETE" },
127 { "Event_MANAGED_OBJECT_TRAP" },
128 { "Event_PREDEF_MOB_SET_COMPLETE" },
129 { "Event_PREDEF_MOB_GET_COMPLETE" },
130 { "Event_USER_MOB_DEFINE_COMPLETE" },
131 { "Event_USER_MOB_SET_COMPLETE" },
132 { "Event_USER_MOB_GET_COMPLETE" },
133 { "Event_RECEIVE_DATA" },
134 { "Event_SEND_COMPLETE" },
135 { "Event_TDM_CONNECT_COMPLETE" },
136 { "Event_LOG" },
137 { "Event_DEVICE_IN_CONTACT" },
138 { "Event_DEVICE_MANAGED" },
139 { "Event_DEVICE_OUT_OF_CONTACT" },
140 { "Event_TELEMETRY_DATA" } };
141
142static char stateName[PortState_END_OF_ENUM][128] = {
143 { "PortState_IDLE" },
144 { "PortState_SIGNALING" },
145 { "PortState_INITIATING" },
146 { "PortState_LINK" },
147 { "PortState_TRAINING" },
148 { "PortState_EC_NEGOTIATING" },
149 { "PortState_DATA" },
150 { "PortState_RESYNCING" },
151 { "PortState_FAX" },
152 { "PortState_COMMAND_ESCAPE" },
153 { "PortState_TERMINATING" },
154 { "PortState_VOICE" },
155 { "PortState_PORT_RESET" },
156 { "PortState_DSP_RESET" },
157 { "PortState_ALLOCATED" },
158 { "PortState_OUT_OF_SERVICE" },
159 { "PortState_RECONFIGURE" },
160 { "PortState_ON_HOLD" } };
161static int uniporte_events(unsigned long port, EventTypeT event,
162 void *event_data, unsigned long event_data_length ) {
163 char text[128];
164 ManObjectInfoPtr info;
165 DataReceiveInfoPtr dataInfo;
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100166 struct mgcp_endpoint *endp;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800167 int i;
168 ToneDetectionPtr tones;
169
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800170 /* Don't print output when we receive data or complete
171 * sending data. That would be too verbose.
172 */
173 if (event==Event_DEVICE_MANAGED) {
174 MtnSaSetManObject(0, ChannelType_ETHERNET, ManObj_C_MOE_COMM_LOSS_RESET_DELAY ,
175 10, 0);
176 }
177 else if (event==Event_MANAGED_OBJECT_TRAP ) {
178 info = (ManObjectInfoPtr)event_data;
179 if (info->trapId == Trap_PORT_STATE_CHANGE) {
180 sprintf(text, "Port #%ld, Change to state %s", port, stateName[info->value]);
181 puts(text);
182
183 /* update the mgcp state */
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100184 if (port >= ARRAY_SIZE(s_endpoints)) {
185 fprintf(stderr, "The port is bigger than we can manage.\n");
186 return 0;
187 }
188
189 endp = s_endpoints[port];
190 if (!endp) {
191 fprintf(stderr, "Unexpected event on port %d\n", port);
192 return 0;
193 }
194
195 if (endp->block_processing != 1)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800196 fprintf(stderr, "State change on a non blocked port. ERROR.\n");
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100197 endp->block_processing = 0;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800198 }
199 }
200 else if ( event == Event_MANAGED_OBJECT_SET_COMPLETE ) {
201 info = (ManObjectInfoPtr)event_data;
202
203 sprintf(text, "Object %d value %d status %d", info->object, info->value,
204 info->status );
205 puts(text);
206 check_exit(info->status);
207 }
208 else if ( ( event == Event_USER_MOB_SET_COMPLETE ) ||
209 ( event == Event_USER_MOB_DEFINE_COMPLETE ) )
210 {
211 info = (ManObjectInfoPtr)event_data;
212
213 sprintf( text, "Mob ID %d status %d", info->MOBId, info->status );
214 puts(text);
215 check_exit(info->status);
216 }
217 else if ( event == Event_USER_MOB_GET_COMPLETE )
218 {
219 info = (ManObjectInfoPtr)event_data;
220
221 sprintf( text, "Mob ID %d status %d", info->MOBId, info->status );
222 puts(text);
223 check_exit(info->status);
224 }
225 else if (event == Event_CONNECT)
226 {
227 sprintf(text, "Port %d connected",port );
228 }
229 else if (event == Event_PREDEF_MOB_GET_COMPLETE)
230 {
231 info = (ManObjectInfoPtr)event_data;
232
233 sprintf(text, "Mob ID %d status %d", info->MOBId, info->status );
234 puts(text);
235 check_exit(info->status);
236 }
237
238 return( 0 );
239}
240
241static int initialize_uniporte(struct mgcp_ss7 *mgcp)
242{
243 ProfileT profile;
244 unsigned long mgw_address;
245 int rc;
246
247 LOGP(DMGCP, LOGL_NOTICE, "Initializing MGW on %s\n", mgcp->cfg->bts_ip);
248
249 MtnSaSetEthernetOnly();
250 rc = MtnSaStartup(uniporte_events);
251 if (rc != 0)
252 LOGP(DMGCP, LOGL_ERROR, "Failed to startup the MGW.\n");
253 SysEthGetHostAddress(mgcp->cfg->bts_ip, &mgw_address);
254 rc = MtnSaRegisterEthernetDevice(mgw_address, 0);
255 if (rc != 0)
256 LOGP(DMGCP, LOGL_ERROR, "Failed to register ethernet.\n");
257 Force_Poll(2000);
258 MtnSaTakeOverDevice(0);
259 Force_Poll(2000);
260 MtnSaSetReceiveTraps(1);
261 MtnSaSetTransparent();
262
263 /* change the voice profile to AMR */
264 MtnSaGetProfile(ProfileType_VOICE, 0, &profile);
265 profile.countryCode = CountryCode_INTERNAT_ALAW;
266 MtnSaSetProfile(ProfileType_VOICE, 0, &profile);
267
268 if (MtnSaGetPortCount() == 0)
269 return -1;
270
271 return 0;
272}
273
274
275static void* start_uniporte(void *_ss7) {
276 struct llist_head blocked;
277 struct mgcp_ss7_cmd *cmd, *tmp;
278 struct mgcp_ss7 *ss7 = _ss7;
279
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800280 if (initialize_uniporte(ss7) != 0) {
281 fprintf(stderr, "Failed to create Uniporte.\n");
282 exit(-1);
283 return 0;
284 }
285
286 fprintf(stderr, "Created the MGCP processing thread.\n");
287 INIT_LLIST_HEAD(&blocked);
288 for (;;) {
289 thread_swap(ss7->cmd_queue);
290start_over:
291 /* handle items that are currently blocked */
292 llist_for_each_entry_safe(cmd, tmp, &blocked, entry) {
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100293 if (cmd->endp->block_processing)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800294 continue;
295
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100296 mgcp_ss7_do_exec(ss7, cmd->type, cmd->endp, cmd->param);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800297 llist_del(&cmd->entry);
298 free(cmd);
299
300 /* We might have unblocked something, make sure we operate in order */
301 MtnSaPoll();
302 goto start_over;
303 }
304
305 llist_for_each_entry_safe(cmd, tmp, ss7->cmd_queue->main_head, entry) {
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100306 if (cmd->endp->block_processing) {
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800307 llist_del(&cmd->entry);
308 llist_add_tail(&cmd->entry, &blocked);
309 continue;
310 }
311
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100312 mgcp_ss7_do_exec(ss7, cmd->type, cmd->endp, cmd->param);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800313 llist_del(&cmd->entry);
314 free(cmd);
315
316 /* We might have unblocked something, make sure we operate in order */
317 MtnSaPoll();
318 goto start_over;
319 }
320
321 Force_Poll(20);
322 }
323
324 return 0;
325}
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800326
327static void update_mute_status(int mgw_port, int conn_mode)
328{
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800329 if (conn_mode == MGCP_CONN_NONE) {
330 MtnSaSetManObject(mgw_port, ChannelType_PORT, ManObj_C_VOICE_UPSTREAM_MUTE, 1, 0);
331 MtnSaSetManObject(mgw_port, ChannelType_PORT, ManObj_C_VOICE_DOWNSTREAM_MUTE, 1, 0);
332 } else if (conn_mode == MGCP_CONN_RECV_ONLY) {
333 MtnSaSetManObject(mgw_port, ChannelType_PORT, ManObj_C_VOICE_UPSTREAM_MUTE, 1, 0);
334 MtnSaSetManObject(mgw_port, ChannelType_PORT, ManObj_C_VOICE_DOWNSTREAM_MUTE, 0, 0);
335 } else if (conn_mode == MGCP_CONN_SEND_ONLY) {
336 MtnSaSetManObject(mgw_port, ChannelType_PORT, ManObj_C_VOICE_UPSTREAM_MUTE, 0, 0);
337 MtnSaSetManObject(mgw_port, ChannelType_PORT, ManObj_C_VOICE_DOWNSTREAM_MUTE, 1, 0);
338 } else if (conn_mode == MGCP_CONN_RECV_SEND) {
339 MtnSaSetManObject(mgw_port, ChannelType_PORT, ManObj_C_VOICE_UPSTREAM_MUTE, 0, 0);
340 MtnSaSetManObject(mgw_port, ChannelType_PORT, ManObj_C_VOICE_DOWNSTREAM_MUTE, 0, 0);
341 } else {
342 LOGP(DMGCP, LOGL_ERROR, "Unhandled conn mode: %d\n", conn_mode);
343 }
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800344}
345
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100346static void allocate_endp(struct mgcp_ss7 *ss7, struct mgcp_endpoint *endp)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800347{
Holger Hans Peter Freyther672f3212011-03-01 13:52:57 +0100348 int mgw_port;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800349 unsigned long mgw_address, loc_address;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800350
Holger Hans Peter Freyther672f3212011-03-01 13:52:57 +0100351 /* now find the voice processor we want to use */
352 mgw_port = select_voice_port(endp);
353 if (mgw_port < 0)
354 return;
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100355
356 endp->audio_port = MtnSaAllocate(mgw_port);
357 if (endp->audio_port == UINT_MAX) {
358 fprintf(stderr, "Failed to allocate the port: %d\n", ENDPOINT_NUMBER(endp));
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800359 return;
360 }
361
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100362 if (mgw_port != endp->audio_port) {
363 fprintf(stderr, "Oh... a lot of assumptions are now broken %d %d %s:%d\n",
364 mgw_port, endp->audio_port, __func__, __LINE__);
365 }
366
367 s_endpoints[endp->audio_port] = endp;
368
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100369 /* Gain settings, apply before switching the port to voice */
370 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100371 ManObj_C_VOICE_INPUT_DIGITAL_GAIN, endp->tcfg->digital_inp_gain, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100372 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100373 ManObj_C_VOICE_OUTPUT_DIGITAL_GAIN, endp->tcfg->digital_out_gain, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100374 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100375 ManObj_G_US_AGC_ENABLE, endp->tcfg->upstr_agc_enbl, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100376 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100377 ManObj_G_DS_AGC_ENABLE, endp->tcfg->dwnstr_agc_enbl, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100378 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100379 ManObj_G_US_ADAPTATION_RATE, endp->tcfg->upstr_adp_rate, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100380 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100381 ManObj_G_DS_ADAPTATION_RATE, endp->tcfg->dwnstr_adp_rate, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100382 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100383 ManObj_G_US_MAX_APPLIED_GAIN, endp->tcfg->upstr_max_gain, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100384 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100385 ManObj_G_DS_MAX_APPLIED_GAIN, endp->tcfg->dwnstr_max_gain, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100386 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100387 ManObj_C_US_TARGET_LEVEL, endp->tcfg->upstr_target_lvl, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100388 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100389 ManObj_C_US_TARGET_LEVEL, endp->tcfg->dwnstr_target_lvl, 0);
Holger Hans Peter Freyther8fa8e582010-12-01 23:14:57 +0100390
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800391 /* Select AMR 5.9, Payload 98, no CRC, hardcoded */
392 MtnSaApplyProfile(mgw_port, ProfileType_VOICE, 0);
393 MtnSaSetManObject(mgw_port, ChannelType_PORT,
394 ManObj_G_DATA_PATH, DataPathT_ETHERNET, 0 );
395 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100396 ManObj_C_VOICE_RTP_TELEPHONE_EVENT_PT_TX,
397 endp->tcfg->audio_payload, 0);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800398 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100399 ManObj_G_RTP_AMR_PAYLOAD_TYPE,
400 endp->tcfg->audio_payload, 0);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800401 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100402 ManObj_G_RTP_AMR_PAYLOAD_FORMAT,
403 RtpAmrPayloadFormat_OCTET_ALIGNED, 0);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800404 MtnSaSetManObject(mgw_port, ChannelType_PORT,
405 ManObj_G_VOICE_ENCODING, Voice_Encoding_AMR_5_90, 0);
Holger Hans Peter Freytherd5918ff2010-08-06 16:03:27 +0000406 MtnSaSetManObject(mgw_port, ChannelType_PORT,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100407 ManObj_C_VOICE_VAD_CNG, endp->tcfg->vad_enabled, 0);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800408
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100409 update_mute_status(mgw_port, endp->conn_mode);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800410
411 /* set the addresses */
412 SysEthGetHostAddress(ss7->cfg->bts_ip, &mgw_address);
413 SysEthGetHostAddress(ss7->cfg->local_ip, &loc_address);
414 MtnSaSetVoIpAddresses(mgw_port,
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100415 mgw_address, endp->bts_end.local_port,
416 loc_address, endp->bts_end.local_port);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800417 MtnSaConnect(mgw_port, mgw_port);
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100418 endp->block_processing = 1;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800419}
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800420
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100421static void mgcp_ss7_do_exec(struct mgcp_ss7 *mgcp, uint8_t type,
422 struct mgcp_endpoint *mgw_endp, uint32_t param)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800423{
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800424 int rc;
425
426 switch (type) {
427 case MGCP_SS7_MUTE_STATUS:
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100428 if (mgw_endp->audio_port != UINT_MAX)
429 update_mute_status(mgw_endp->audio_port, param);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800430 break;
431 case MGCP_SS7_DELETE:
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100432 if (mgw_endp->audio_port != UINT_MAX) {
433 rc = MtnSaDisconnect(mgw_endp->audio_port);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800434 if (rc != 0)
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100435 fprintf(stderr, "Failed to disconnect port: %u\n", mgw_endp->audio_port);
436 rc = MtnSaDeallocate(mgw_endp->audio_port);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800437 if (rc != 0)
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100438 fprintf(stderr, "Failed to deallocate port: %u\n", mgw_endp->audio_port);
439
440 mgw_endp->audio_port = UINT_MAX;
441 mgw_endp->block_processing = 1;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800442 }
443 break;
444 case MGCP_SS7_ALLOCATE:
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100445 allocate_endp(mgcp, mgw_endp);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800446 break;
447 }
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800448}
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100449#endif
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800450
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100451void mgcp_ss7_exec(struct mgcp_endpoint *endp, int type, uint32_t param)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800452{
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100453 struct mgcp_ss7 *mgcp;
454
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800455 struct mgcp_ss7_cmd *cmd = malloc(sizeof(*cmd));
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100456 if (!cmd) {
457 LOGP(DMGCP, LOGL_ERROR, "Failed to send a command.\n");
458 return;
459 }
460
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800461 memset(cmd, 0, sizeof(*cmd));
462 cmd->type = type;
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100463 cmd->endp = endp;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800464 cmd->param = param;
465
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100466 mgcp = endp->tcfg->cfg->data;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800467 thread_safe_add(mgcp->cmd_queue, &cmd->entry);
468}
469
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100470static int ss7_allocate_endpoint(struct mgcp_ss7 *ss7, struct mgcp_endpoint *mg_endp)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800471{
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100472 mg_endp->bts_end.rtp_port = htons(mg_endp->bts_end.local_port);
473 mg_endp->bts_end.rtcp_port = htons(mg_endp->bts_end.local_port + 1);
474 mg_endp->bts_end.addr = ss7->cfg->bts_in;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800475
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100476 mgcp_ss7_exec(mg_endp, MGCP_SS7_ALLOCATE, 0);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800477 return MGCP_POLICY_CONT;
478}
479
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100480static int ss7_modify_endpoint(struct mgcp_ss7 *ss7, struct mgcp_endpoint *mg_endp)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800481{
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100482 mgcp_ss7_exec(mg_endp, MGCP_SS7_MUTE_STATUS, mg_endp->conn_mode);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800483
484 /*
Holger Hans Peter Freythere3abeb12010-10-18 19:36:50 +0200485 * Just assume that we have the data now.
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800486 */
Holger Hans Peter Freythere3abeb12010-10-18 19:36:50 +0200487 mgcp_send_dummy(mg_endp);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800488
489 /* update the remote end */
490 return MGCP_POLICY_CONT;
491}
492
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100493static int ss7_delete_endpoint(struct mgcp_ss7 *ss7, struct mgcp_endpoint *endp)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800494{
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100495 mgcp_ss7_endp_free(endp);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800496 return MGCP_POLICY_CONT;
497}
498
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100499static int mgcp_ss7_policy(struct mgcp_trunk_config *tcfg, int endp_no, int state, const char *trans)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800500{
501 int rc;
502 struct mgcp_ss7 *ss7;
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100503 struct mgcp_endpoint *endp;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800504
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100505
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100506
507 endp = &tcfg->endpoints[endp_no];
508 ss7 = (struct mgcp_ss7 *) tcfg->cfg->data;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800509
Holger Hans Peter Freyther8e6d4c32011-03-21 15:14:04 +0100510 /* these endpoints are blocked */
511 if (endp->blocked) {
512 LOGP(DMGCP, LOGL_NOTICE, "Rejecting non voice timeslots 0x%x\n", endp_no);
513 return MGCP_POLICY_REJECT;
514 }
515
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800516 /* TODO: Make it async and wait for the port to be connected */
517 rc = MGCP_POLICY_REJECT;
518 switch (state) {
519 case MGCP_ENDP_CRCX:
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100520 rc = ss7_allocate_endpoint(ss7, endp);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800521 break;
522 case MGCP_ENDP_MDCX:
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100523 rc = ss7_modify_endpoint(ss7, endp);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800524 break;
525 case MGCP_ENDP_DLCX:
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100526 rc = ss7_delete_endpoint(ss7, endp);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800527 break;
528 }
529
530 return rc;
531}
532
533static void enqueue_msg(struct write_queue *queue, struct sockaddr_in *addr, struct msgb *msg)
534{
535 struct sockaddr_in *data;
536
537 data = (struct sockaddr_in *) msgb_push(msg, sizeof(*data));
538 *data = *addr;
539 if (write_queue_enqueue(queue, msg) != 0) {
540 LOGP(DMGCP, LOGL_ERROR, "Failed to queue the message.\n");
541 msgb_free(msg);
542 }
543}
544
545static int write_call_agent(struct bsc_fd *bfd, struct msgb *msg)
546{
547 int rc;
548 struct sockaddr_in *addr;
549
550 addr = (struct sockaddr_in *) msg->data;
551 rc = sendto(bfd->fd, msg->l2h, msgb_l2len(msg), 0,
552 (struct sockaddr *) addr, sizeof(*addr));
553
554 if (rc != msgb_l2len(msg))
555 LOGP(DMGCP, LOGL_ERROR, "Failed to write MGCP message: rc: %d errno: %d\n", rc, errno);
556
557 return rc;
558}
559
560
561static int read_call_agent(struct bsc_fd *fd)
562{
563 struct sockaddr_in addr;
564 socklen_t slen = sizeof(addr);
565 struct msgb *resp;
566 struct mgcp_ss7 *cfg;
567 struct write_queue *queue;
568
569 cfg = (struct mgcp_ss7 *) fd->data;
570 queue = container_of(fd, struct write_queue, bfd);
571
572 /* read one less so we can use it as a \0 */
573 int rc = recvfrom(fd->fd, cfg->mgcp_msg->data, cfg->mgcp_msg->data_len - 1, 0,
574 (struct sockaddr *) &addr, &slen);
575
576 if (rc < 0) {
577 perror("Gateway failed to read");
578 return -1;
579 } else if (slen > sizeof(addr)) {
580 fprintf(stderr, "Gateway received message from outerspace: %d %d\n",
581 slen, sizeof(addr));
582 return -1;
583 }
584
585 /* handle message now */
586 cfg->mgcp_msg->l2h = msgb_put(cfg->mgcp_msg, rc);
587 resp = mgcp_handle_message(cfg->cfg, cfg->mgcp_msg);
588 msgb_reset(cfg->mgcp_msg);
589
590 if (resp)
591 enqueue_msg(queue, &addr, resp);
592 return 0;
593}
594
595static int create_socket(struct mgcp_ss7 *cfg)
596{
597 int on;
598 struct sockaddr_in addr;
599 struct bsc_fd *bfd;
600
601 bfd = &cfg->mgcp_fd.bfd;
602
603 cfg->mgcp_fd.read_cb = read_call_agent;
604 cfg->mgcp_fd.write_cb = write_call_agent;
605 bfd->when = BSC_FD_READ;
606 bfd->fd = socket(AF_INET, SOCK_DGRAM, 0);
607 if (bfd->fd < 0) {
608 perror("Gateway failed to listen");
609 return -1;
610 }
611
612 on = 1;
613 setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
614
615 memset(&addr, 0, sizeof(addr));
616 addr.sin_family = AF_INET;
617 addr.sin_port = htons(cfg->cfg->source_port);
618 addr.sin_addr.s_addr = INADDR_ANY;
619
620 if (bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
621 perror("Gateway failed to bind");
622 close(bfd->fd);
623 return -1;
624 }
625
626 bfd->data = cfg;
627 cfg->mgcp_msg = msgb_alloc(4096, "mgcp-msg");
628 if (!cfg->mgcp_msg) {
629 fprintf(stderr, "Gateway memory error.\n");
630 close(bfd->fd);
631 return -1;
632 }
633 talloc_steal(cfg, cfg->mgcp_msg);
634
635
636 if (bsc_register_fd(bfd) != 0) {
637 DEBUGP(DMGCP, "Failed to register the fd\n");
638 close(bfd->fd);
639 return -1;
640 }
641
642 return 0;
643}
644
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100645static void mgcp_ss7_endp_free(struct mgcp_endpoint *endp)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800646{
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100647 mgcp_ss7_exec(endp, MGCP_SS7_DELETE, 0);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800648}
649
650static int reset_cb(struct mgcp_config *cfg)
651{
652 mgcp_ss7_reset((struct mgcp_ss7 *) cfg->data);
653 return 0;
654}
655
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100656static int realloc_cb(struct mgcp_trunk_config *tcfg, int endp_no)
Holger Hans Peter Freyther95cac742010-09-18 03:16:52 +0800657{
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100658 struct mgcp_endpoint *endp = &tcfg->endpoints[endp_no];
659 mgcp_ss7_endp_free(endp);
Holger Hans Peter Freyther95cac742010-09-18 03:16:52 +0800660 return 0;
661}
662
Holger Hans Peter Freytherf9e99772010-08-04 07:10:55 +0800663static struct mgcp_ss7 *mgcp_ss7_init(struct mgcp_config *cfg)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800664{
Holger Hans Peter Freytherd3849122011-03-01 14:38:47 +0100665 struct mgcp_trunk_config *trunk;
666 int dsp_resource, i;
667
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800668 struct mgcp_ss7 *conf = talloc_zero(NULL, struct mgcp_ss7);
669 if (!conf)
670 return NULL;
671
672 write_queue_init(&conf->mgcp_fd, 30);
Holger Hans Peter Freytherf9e99772010-08-04 07:10:55 +0800673 conf->cfg = cfg;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800674
675 /* take over the ownership */
676 talloc_steal(conf, conf->cfg);
Holger Hans Peter Freytherf9e99772010-08-04 07:10:55 +0800677
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800678 conf->cfg->policy_cb = mgcp_ss7_policy;
679 conf->cfg->reset_cb = reset_cb;
Holger Hans Peter Freyther95cac742010-09-18 03:16:52 +0800680 conf->cfg->realloc_cb = realloc_cb;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800681 conf->cfg->data = conf;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800682
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800683 if (create_socket(conf) != 0) {
684 LOGP(DMGCP, LOGL_ERROR, "Failed to create socket.\n");
685 talloc_free(conf);
686 return NULL;
687 }
688
Holger Hans Peter Freytherb7299a82011-03-01 15:48:05 +0100689 if (cfg->configure_trunks && mgcp_snmp_init() != 0) {
690 LOGP(DMGCP, LOGL_ERROR, "Failed to initialize SNMP.\n");
691 talloc_free(conf);
692 return NULL;
693 }
694
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100695 /* Now do the init of the trunks */
Holger Hans Peter Freytherd3849122011-03-01 14:38:47 +0100696 dsp_resource = 0;
697 for (i = 1; i < cfg->trunk.number_endpoints; ++i) {
698 int multiplex, timeslot;
699 mgcp_endpoint_to_timeslot(i, &multiplex, &timeslot);
Holger Hans Peter Freyther0d20e0d2011-03-02 21:44:01 +0100700 if (timeslot == 0x0 || timeslot == 0x1F) {
701 cfg->trunk.endpoints[i].blocked = 1;
Holger Hans Peter Freytherd3849122011-03-01 14:38:47 +0100702 continue;
Holger Hans Peter Freyther0d20e0d2011-03-02 21:44:01 +0100703 }
Holger Hans Peter Freytherd3849122011-03-01 14:38:47 +0100704
705 dsp_resource += 1;
Holger Hans Peter Freytherb7299a82011-03-01 15:48:05 +0100706
707 if (cfg->configure_trunks) {
708 int res;
709
710 res = mgcp_snmp_connect(dsp_resource,
711 cfg->trunk.target_trunk_start + multiplex,
712 timeslot);
713
714 if (res != 0) {
715 LOGP(DMGCP, LOGL_ERROR, "Failed to configure virtual trunk.\n");
716 talloc_free(conf);
717 return NULL;
718 }
719 }
Holger Hans Peter Freytherd3849122011-03-01 14:38:47 +0100720 }
721
722 llist_for_each_entry(trunk, &cfg->trunks, entry) {
723 trunk->voice_base = dsp_resource;
724
725 for (i = 1; i < trunk->number_endpoints; ++i) {
726 int multiplex, timeslot;
727 mgcp_endpoint_to_timeslot(i, &multiplex, &timeslot);
Holger Hans Peter Freyther0d20e0d2011-03-02 21:44:01 +0100728 if (timeslot == 0x0 || timeslot == 0x1) {
729 trunk->endpoints[i].blocked = 1;
Holger Hans Peter Freytherd3849122011-03-01 14:38:47 +0100730 continue;
Holger Hans Peter Freyther0d20e0d2011-03-02 21:44:01 +0100731 }
Holger Hans Peter Freytherd3849122011-03-01 14:38:47 +0100732
733 dsp_resource += 1;
Holger Hans Peter Freytherb7299a82011-03-01 15:48:05 +0100734
735 if (cfg->configure_trunks) {
736 int res;
737
738 res = mgcp_snmp_connect(dsp_resource,
739 trunk->trunk_nr + multiplex,
740 timeslot);
741
742 if (res != 0) {
743 LOGP(DMGCP, LOGL_ERROR,
744 "Failed to configure virtual trunk.\n");
745 talloc_free(conf);
746 return NULL;
747 }
748 }
Holger Hans Peter Freytherd3849122011-03-01 14:38:47 +0100749 }
750 }
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800751
752 conf->cmd_queue = thread_notifier_alloc();
753 if (!conf->cmd_queue) {
754 LOGP(DMGCP, LOGL_ERROR, "Failed to allocate the command queue.\n");
755 talloc_free(conf);
756 return NULL;
757 }
758
759#ifndef NO_UNIPORTE
760 conf->cmd_queue->no_write = 1;
761 pthread_create(&conf->thread, NULL, start_uniporte, conf);
762#endif
763
764 return conf;
765}
766
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100767static void free_trunk(struct mgcp_trunk_config *trunk)
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800768{
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100769 int i;
770 for (i = 1; i < trunk->number_endpoints; ++i) {
771 struct mgcp_endpoint *endp = &trunk->endpoints[i];
772 mgcp_ss7_endp_free(endp);
773 mgcp_free_endp(endp);
774 }
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800775}
776
777void mgcp_ss7_reset(struct mgcp_ss7 *mgcp)
778{
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100779 struct mgcp_trunk_config *trunk;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800780
781 if (!mgcp)
782 return;
783
784 LOGP(DMGCP, LOGL_INFO, "Resetting all endpoints.\n");
785
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100786 /* free UniPorte and MGCP data */
787 free_trunk(&mgcp->cfg->trunk);
788
789 llist_for_each_entry(trunk, &mgcp->cfg->trunks, entry)
790 free_trunk(trunk);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800791}
792
793static void print_help()
794{
795 printf(" Some useful help...\n");
796 printf(" -h This help text.\n");
797 printf(" -c --config=CFG. The configuration file.\n");
798 printf(" -e --exit-on-failure. Exit the app on MGW failure.\n");
799}
800
801static void print_usage()
802{
803 printf("Usage: mgcp_mgw\n");
804}
805
806
807static void handle_options(int argc, char **argv)
808{
809 while (1) {
810 int option_index = 0, c;
811 static struct option long_options[] = {
812 {"help", 0, 0, 'h'},
813 {"config", 1, 0, 'c'},
814 {"exit", 0, 0, 'e'},
815 {0, 0, 0, 0},
816 };
817
818 c = getopt_long(argc, argv, "hc:e",
819 long_options, &option_index);
820 if (c == -1)
821 break;
822
823 switch (c) {
824 case 'h':
825 print_usage();
826 print_help();
827 exit(0);
828 case 'c':
829 config_file = optarg;
830 break;
831 case 'e':
832 exit_on_failure = 1;
833 break;
834 default:
835 fprintf(stderr, "Unknown option.\n");
836 break;
837 }
838 }
839}
840
841
842int main(int argc, char **argv)
843{
844 struct mgcp_ss7 *mgcp;
Holger Hans Peter Freythercc1a9382010-08-04 06:24:04 +0800845 int rc;
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800846
Holger Hans Peter Freythercbf7d182010-07-31 05:25:35 +0800847 log_init(&log_info);
848 stderr_target = log_target_create_stderr();
849 log_add_target(stderr_target);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800850
851 /* enable filters */
Holger Hans Peter Freythercbf7d182010-07-31 05:25:35 +0800852 log_set_all_filter(stderr_target, 1);
853 log_set_category_filter(stderr_target, DINP, 1, LOGL_INFO);
854 log_set_category_filter(stderr_target, DSCCP, 1, LOGL_INFO);
855 log_set_category_filter(stderr_target, DMSC, 1, LOGL_INFO);
856 log_set_category_filter(stderr_target, DMGCP, 1, LOGL_INFO);
857 log_set_print_timestamp(stderr_target, 1);
858 log_set_use_color(stderr_target, 0);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800859
860 handle_options(argc, argv);
861
862 signal(SIGPIPE, SIG_IGN);
863
864 mgcp_mgw_vty_init();
Holger Hans Peter Freytherf41617b2010-08-04 07:08:33 +0800865
Holger Hans Peter Freyther757f1742010-09-17 22:03:08 +0800866 g_cfg = mgcp_config_alloc();
867 if (!g_cfg) {
Holger Hans Peter Freytherf41617b2010-08-04 07:08:33 +0800868 LOGP(DMGCP, LOGL_ERROR, "Failed to allocate mgcp config.\n");
869 return -1;
870 }
871
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100872 if (mgcp_parse_config(config_file, g_cfg) != 0) {
873 LOGP(DMGCP, LOGL_ERROR,
874 "Failed to parse the config file: '%s'\n", config_file);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800875 return -1;
876 }
877
Holger Hans Peter Freythercc1a9382010-08-04 06:24:04 +0800878 rc = telnet_init(NULL, NULL, 4243);
879 if (rc < 0)
880 return rc;
881
Holger Hans Peter Freytherdcc33122011-03-01 01:24:10 +0100882 printf("Creating MGCP MGW ip: %s mgw: %s\n",
883 g_cfg->local_ip, g_cfg->bts_ip);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800884
Holger Hans Peter Freyther757f1742010-09-17 22:03:08 +0800885 mgcp = mgcp_ss7_init(g_cfg);
Holger Hans Peter Freyther97f66e22010-07-28 03:32:52 +0800886 if (!mgcp) {
887 fprintf(stderr, "Failed to create MGCP\n");
888 exit(-1);
889 }
890 while (1) {
891 bsc_select_main(0);
892 }
893 return 0;
894}
895