1 /*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005/2012, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * This module (mod_gsmopen) has been contributed by:
25 *
26 * Giovanni Maruzzelli (gmaruzz@gmail.com)
27 *
28 *
29 * Further Contributors:
30 *
31 *
32 *
33 * mod_gsmopen.c -- GSM compatible Endpoint Module
34 *
35 */
36
37 #include "gsmopen.h"
38
39 #if 0
40 #ifdef WIN32
41 /***************/
42 // from http://www.openasthra.com/c-tidbits/gettimeofday-function-for-windows/
43
44 #include <time.h>
45
46 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
47 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
48 #else /* */
49 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
50 #endif /* */
51 struct sk_timezone {
52 int tz_minuteswest; /* minutes W of Greenwich */
53 int tz_dsttime; /* type of dst correction */
54 };
55 int gettimeofday(struct timeval *tv, struct sk_timezone *tz)
56 {
57 FILETIME ft;
58 unsigned __int64 tmpres = 0;
59 static int tzflag;
60 if (NULL != tv) {
61 GetSystemTimeAsFileTime(&ft);
62 tmpres |= ft.dwHighDateTime;
63 tmpres <<= 32;
64 tmpres |= ft.dwLowDateTime;
65
66 /*converting file time to unix epoch */
67 tmpres /= 10; /*convert into microseconds */
68 tmpres -= DELTA_EPOCH_IN_MICROSECS;
69 tv->tv_sec = (long) (tmpres / 1000000UL);
70 tv->tv_usec = (long) (tmpres % 1000000UL);
71 }
72 if (NULL != tz) {
73 if (!tzflag) {
74 _tzset();
75 tzflag++;
76 }
77 tz->tz_minuteswest = _timezone / 60;
78 tz->tz_dsttime = _daylight;
79 }
80 return 0;
81 }
82
83 /***************/
84 #endif /* WIN32 */
85 #endif //0
86 SWITCH_BEGIN_EXTERN_C
87 SWITCH_MODULE_LOAD_FUNCTION(mod_gsmopen_load);
88 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_gsmopen_shutdown);
89 SWITCH_MODULE_DEFINITION(mod_gsmopen, mod_gsmopen_load, mod_gsmopen_shutdown, NULL);
90 SWITCH_END_EXTERN_C
91 #define GSMOPEN_CHAT_PROTO "sms"
92 #if 1
93 SWITCH_STANDARD_API(gsm_function);
94 /* BEGIN: Changes here */
95 #define GSM_SYNTAX "list [full] || console || AT_command || remove < interface_name | interface_id > || reload"
96 /* END: Changes heres */
97 SWITCH_STANDARD_API(gsmopen_function);
98 #define GSMOPEN_SYNTAX "interface_name AT_command"
99 #endif //0
100
101 SWITCH_STANDARD_API(gsmopen_boost_audio_function);
102 #define GSMOPEN_BOOST_AUDIO_SYNTAX "interface_name [<play|capt> <in decibels: -40 ... 0 ... +40>]"
103 SWITCH_STANDARD_API(sendsms_function);
104 #define SENDSMS_SYNTAX "gsmopen_sendsms interface_name destination_number SMS_text"
105 SWITCH_STANDARD_API(gsmopen_dump_function);
106 #define GSMOPEN_DUMP_SYNTAX "gsmopen_dump <interface_name|list>"
107 /* BEGIN: Changes here */
108 #define FULL_RELOAD 0
109 #define SOFT_RELOAD 1
110 /* END: Changes heres */
111
112 const char *interface_status[] = { /* should match GSMOPEN_STATE_xxx in gsmopen.h */
113 "IDLE",
114 "DOWN",
115 "RING",
116 "DIALING",
117 "BUSY",
118 "UP",
119 "RINGING",
120 "PRERING",
121 "DOUBLE",
122 "SELECTD",
123 "HANG_RQ",
124 "PREANSW"
125 };
126 const char *phone_callflow[] = { /* should match CALLFLOW_XXX in gsmopen.h */
127 "CALL_IDLE",
128 "CALL_DOWN",
129 "INCOMING_RNG",
130 "CALL_DIALING",
131 "CALL_LINEBUSY",
132 "CALL_ACTIVE",
133 "INCOMING_HNG",
134 "CALL_RLEASD",
135 "CALL_NOCARR",
136 "CALL_INFLUX",
137 "CALL_INCOMING",
138 "CALL_FAILED",
139 "CALL_NOSRVC",
140 "CALL_OUTRESTR",
141 "CALL_SECFAIL",
142 "CALL_NOANSWER",
143 "STATUS_FNSHED",
144 "STATUS_CANCLED",
145 "STATUS_FAILED",
146 "STATUS_REFUSED",
147 "STATUS_RINGING",
148 "STATUS_INPROGRS",
149 "STATUS_UNPLACD",
150 "STATUS_ROUTING",
151 "STATUS_EARLYMD",
152 "INCOMING_CLID",
153 "STATUS_RMTEHOLD"
154 };
155
156
157 static struct {
158 int debug;
159 char *ip;
160 int port;
161 char *dialplan;
162 char *destination;
163 char *context;
164 char *codec_string;
165 char *codec_order[SWITCH_MAX_CODECS];
166 int codec_order_last;
167 char *codec_rates_string;
168 char *codec_rates[SWITCH_MAX_CODECS];
169 int codec_rates_last;
170 unsigned int flags;
171 int fd;
172 int calls;
173 int real_interfaces;
174 int next_interface;
175 char hold_music[256];
176 private_t GSMOPEN_INTERFACES[GSMOPEN_MAX_INTERFACES];
177 switch_mutex_t *mutex;
178 private_t *gsm_console;
179 } globals;
180
181 switch_endpoint_interface_t *gsmopen_endpoint_interface;
182 switch_memory_pool_t *gsmopen_module_pool = NULL;
183 int running = 0;
184
185 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan);
186 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, globals.context);
187 SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_destination, globals.destination);
188 //SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string);
189 //SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string);
190
191 /* BEGIN: Changes here */
192 static switch_status_t interface_exists(char *the_interface);
193 #if 1
194 static switch_status_t remove_interface(char *the_interface);
195 #endif //0
196 /* END: Changes here */
197
198 static switch_status_t channel_on_init(switch_core_session_t *session);
199 static switch_status_t channel_on_hangup(switch_core_session_t *session);
200 static switch_status_t channel_on_destroy(switch_core_session_t *session);
201 static switch_status_t channel_on_routing(switch_core_session_t *session);
202 static switch_status_t channel_on_exchange_media(switch_core_session_t *session);
203 static switch_status_t channel_on_consume_media(switch_core_session_t *session);
204 static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
205 static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
206 switch_event_t *var_event,
207 switch_caller_profile_t *outbound_profile,
208 switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
209 switch_call_cause_t *cancel_cause);
210 static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
211 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
212 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
213 static switch_status_t gsmopen_tech_init(private_t * tech_pvt, switch_core_session_t *session);
214
gsmopen_codec(private_t * tech_pvt,int sample_rate,int codec_ms)215 static switch_status_t gsmopen_codec(private_t * tech_pvt, int sample_rate, int codec_ms)
216 {
217 switch_core_session_t *session = NULL;
218
219 if (switch_core_codec_init
220 (&tech_pvt->read_codec, "L16", NULL, NULL, sample_rate, codec_ms, 1,
221 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
222 ERRORA("Can't load codec?\n", GSMOPEN_P_LOG);
223 return SWITCH_STATUS_FALSE;
224 }
225
226 if (switch_core_codec_init
227 (&tech_pvt->write_codec, "L16", NULL, NULL, sample_rate, codec_ms, 1,
228 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
229 ERRORA("Can't load codec?\n", GSMOPEN_P_LOG);
230 switch_core_codec_destroy(&tech_pvt->read_codec);
231 return SWITCH_STATUS_FALSE;
232 }
233
234 tech_pvt->read_frame.rate = sample_rate;
235 tech_pvt->read_frame.codec = &tech_pvt->read_codec;
236
237 session = switch_core_session_locate(tech_pvt->session_uuid_str);
238
239 if (session) {
240 switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
241 switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
242 switch_core_session_rwunlock(session);
243 } else {
244 ERRORA("no session\n", GSMOPEN_P_LOG);
245 return SWITCH_STATUS_FALSE;
246 }
247
248 return SWITCH_STATUS_SUCCESS;
249
250 }
251
gsmopen_tech_init(private_t * tech_pvt,switch_core_session_t * session)252 switch_status_t gsmopen_tech_init(private_t * tech_pvt, switch_core_session_t *session)
253 {
254
255 #ifdef WANT_SPEEX
256 int ciapa;
257 long level;
258 int tmp;
259 #endif// WANT_SPEEX
260 switch_assert(tech_pvt != NULL);
261 switch_assert(session != NULL);
262 tech_pvt->read_frame.data = tech_pvt->databuf;
263 tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
264 switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
265 switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
266 switch_core_session_set_private(session, tech_pvt);
267 switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(session), sizeof(tech_pvt->session_uuid_str));
268 if (!strlen(tech_pvt->session_uuid_str)) {
269 ERRORA("no tech_pvt->session_uuid_str\n", GSMOPEN_P_LOG);
270 return SWITCH_STATUS_FALSE;
271 }
272 if (gsmopen_codec(tech_pvt, SAMPLERATE_GSMOPEN, 20) != SWITCH_STATUS_SUCCESS) {
273 ERRORA("gsmopen_codec FAILED\n", GSMOPEN_P_LOG);
274 return SWITCH_STATUS_FALSE;
275 }
276 //teletone_dtmf_detect_init(&tech_pvt->dtmf_detect, tech_pvt->read_codec.implementation->actual_samples_per_second);
277 //teletone_dtmf_detect_init(&tech_pvt->dtmf_detect, 8000);
278 dtmf_rx_init(&tech_pvt->dtmf_state, NULL, NULL);
279 dtmf_rx_parms(&tech_pvt->dtmf_state, 0, 10, 10, -99);
280
281 #ifdef GSMOPEN_ALSA
282 if(tech_pvt->no_sound==0){
283 if (alsa_init(tech_pvt)) {
284 ERRORA("alsa_init failed\n", GSMOPEN_P_LOG);
285 return SWITCH_STATUS_FALSE;
286
287 }
288 }
289 #endif// GSMOPEN_ALSA
290 #ifdef GSMOPEN_PORTAUDIO
291 if(tech_pvt->no_sound==0){
292 if (gsmopen_portaudio_init(tech_pvt)) {
293 ERRORA("gsmopen_portaudio_init failed\n", GSMOPEN_P_LOG);
294 return SWITCH_STATUS_FALSE;
295
296 }
297 }
298 #endif// GSMOPEN_PORTAUDIO
299
300 if (switch_core_timer_init(&tech_pvt->timer_read, "soft", 20, tech_pvt->read_codec.implementation->samples_per_packet, gsmopen_module_pool) !=
301 SWITCH_STATUS_SUCCESS) {
302 ERRORA("setup timer failed\n", GSMOPEN_P_LOG);
303 return SWITCH_STATUS_FALSE;
304 }
305
306 switch_core_timer_sync(&tech_pvt->timer_read);
307
308 if (switch_core_timer_init(&tech_pvt->timer_write, "soft", 20, tech_pvt->write_codec.implementation->samples_per_packet, gsmopen_module_pool) !=
309 SWITCH_STATUS_SUCCESS) {
310 ERRORA("setup timer failed\n", GSMOPEN_P_LOG);
311 return SWITCH_STATUS_FALSE;
312 }
313
314 switch_core_timer_sync(&tech_pvt->timer_write);
315
316 #ifdef WANT_SPEEX
317 /* Echo canceller with 100 ms tail length */
318 #ifndef GIOVA48
319 tech_pvt->echo_state = speex_echo_state_init(160, 1024);
320 ciapa = 8000;
321 #else// GIOVA48
322 tech_pvt->echo_state = speex_echo_state_init(960, 4800);
323 ciapa = 48000;
324 #endif // GIOVA48
325 speex_echo_ctl(tech_pvt->echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &ciapa);
326
327 #if 1 //NO MORE
328 /* Setup preprocessor and associate with echo canceller for residual echo suppression */
329 #ifndef GIOVA48
330 tech_pvt->preprocess = speex_preprocess_state_init(160, 8000);
331 #else// GIOVA48
332 tech_pvt->preprocess = speex_preprocess_state_init(960, 48000);
333 #endif // GIOVA48
334 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE,
335 tech_pvt->echo_state);
336
337 #if 0
338 /* Setup preprocessor various other goodies */
339 tmp = 0;
340 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_AGC, &tmp);
341 //level=8000.1;
342 //speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_AGC_LEVEL, &level);
343
344 // Let's turn off all of the 'denoisers' (eg denoise and dereverb, and vad too) because they start automatic gain on mic input on cm108 usb, also if it (the agc on usb) disbled through mixer
345 tmp = 0;
346 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_DENOISE, &tmp);
347 tmp = 0;
348 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_DEREVERB, &tmp);
349 tmp = 0;
350 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_VAD, &tmp);
351 #endif
352
353 tmp = 0;
354 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_SET_DENOISE, &tmp);
355 tmp = 1;
356 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC, &tmp);
357 fprintf(stderr, "AGC is: %d\n", tmp);
358 level = 1.0;
359 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_LEVEL, &level);
360 fprintf(stderr, "AGC_LEVEL is: %f\n", level);
361 //tmp=1;
362 //speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_TARGET, &tmp);
363 //fprintf( stderr, "AGC_TARGET is: %d\n", tmp );
364 tmp = 1;
365 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_DENOISE, &tmp);
366 fprintf(stderr, "DENOISE is: %d\n", tmp);
367 tmp = 1;
368 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_DEREVERB, &tmp);
369 fprintf(stderr, "DEREVERB is: %d\n", tmp);
370 tmp = 1;
371 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_VAD, &tmp);
372 fprintf(stderr, "VAD is: %d\n", tmp);
373
374 #if 0
375 tmp = 1;
376 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_NOISE_SUPPRESS, &tmp);
377 fprintf(stderr, "SPEEX_PREPROCESS_GET_NOISE_SUPPRESS is: %d\n", tmp);
378 tmp = 1;
379 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS, &tmp);
380 fprintf(stderr, "SPEEX_PREPROCESS_GET_ECHO_SUPPRESS is: %d\n", tmp);
381 tmp = 1;
382 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE,
383 &tmp);
384 fprintf(stderr, "SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE is: %d\n", tmp);
385 tmp = 1;
386 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_MAX_GAIN, &tmp);
387 fprintf(stderr, "SPEEX_PREPROCESS_GET_AGC_MAX_GAIN is: %d\n", tmp);
388 tmp = 1;
389 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_INCREMENT, &tmp);
390 fprintf(stderr, "SPEEX_PREPROCESS_GET_AGC_INCREMENT is: %d\n", tmp);
391 tmp = 1;
392 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_AGC_DECREMENT, &tmp);
393 fprintf(stderr, "SPEEX_PREPROCESS_GET_AGC_DECREMENT is: %d\n", tmp);
394 tmp = 1;
395 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_PROB_START, &tmp);
396 fprintf(stderr, "SPEEX_PREPROCESS_GET_PROB_START is: %d\n", tmp);
397 tmp = 1;
398 speex_preprocess_ctl(tech_pvt->preprocess, SPEEX_PREPROCESS_GET_PROB_CONTINUE, &tmp);
399 fprintf(stderr, "SPEEX_PREPROCESS_GET_PROB_CONTINUE is: %d\n", tmp);
400 #endif //0
401 #endif// 0 //NO MORE
402
403 #endif // WANT_SPEEX
404
405
406
407 switch_clear_flag(tech_pvt, TFLAG_HANGUP);
408 DEBUGA_GSMOPEN("gsmopen_codec SUCCESS\n", GSMOPEN_P_LOG);
409 return SWITCH_STATUS_SUCCESS;
410 }
411
412 /* BEGIN: Changes here */
interface_exists(char * the_interface)413 static switch_status_t interface_exists(char *the_interface)
414 {
415 int i;
416 int interface_id;
417
418 if (*the_interface == '#') { /* look by interface id or interface name */
419 the_interface++;
420 switch_assert(the_interface);
421 interface_id = atoi(the_interface);
422
423 /* take a number as interface id */
424 if (interface_id > 0 || (interface_id == 0 && strcmp(the_interface, "0") == 0)) {
425 if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) {
426 return SWITCH_STATUS_SUCCESS;
427 }
428 } else {
429 /* interface name */
430 for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) {
431 if (strcmp(globals.GSMOPEN_INTERFACES[interface_id].name, the_interface) == 0) {
432 return SWITCH_STATUS_SUCCESS;
433 break;
434 }
435 }
436 }
437 } else { /* look by gsmopen_user */
438
439
440 for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) {
441 if (strlen(globals.GSMOPEN_INTERFACES[i].gsmopen_user)) {
442 if (strcmp(globals.GSMOPEN_INTERFACES[i].gsmopen_user, the_interface) == 0) {
443 return SWITCH_STATUS_SUCCESS;
444 }
445 }
446 }
447 }
448 return SWITCH_STATUS_FALSE;
449 }
450
451 #if 1
remove_interface(char * the_interface)452 static switch_status_t remove_interface(char *the_interface)
453 {
454 int x = 10;
455 unsigned int howmany = 8;
456 int interface_id = -1;
457 private_t *tech_pvt = NULL;
458 switch_status_t status;
459
460 //running = 0;
461
462
463 //XXX if (*the_interface == '#') { /* remove by interface id or interface name */
464 //XXX the_interface++;
465 switch_assert(the_interface);
466 interface_id = atoi(the_interface);
467
468 if (interface_id > 0 || (interface_id == 0 && strcmp(the_interface, "0") == 0)) {
469 /* take a number as interface id */
470 tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id];
471 } else {
472
473 for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) {
474 if (strcmp(globals.GSMOPEN_INTERFACES[interface_id].name, the_interface) == 0) {
475 tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id];
476 break;
477 }
478 }
479 }
480 //XXX } //else { /* remove by gsmopen_user */
481 //for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) {
482 //if (strcmp(globals.GSMOPEN_INTERFACES[interface_id].gsmopen_user, the_interface) == 0) {
483 //tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id];
484 //break;
485 //}
486 //}
487 //}
488
489 if (!tech_pvt) {
490 DEBUGA_GSMOPEN("interface '%s' does not exist\n", GSMOPEN_P_LOG, the_interface);
491 goto end;
492 }
493
494 if (strlen(globals.GSMOPEN_INTERFACES[interface_id].session_uuid_str)) {
495 DEBUGA_GSMOPEN("interface '%s' is busy\n", GSMOPEN_P_LOG, the_interface);
496 goto end;
497 }
498
499 globals.GSMOPEN_INTERFACES[interface_id].running = 0;
500
501 if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) {
502 #if 1
503 #ifdef WIN32
504 switch_file_write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die
505 #else /* WIN32 */
506 howmany = write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", howmany);
507 #endif /* WIN32 */
508 #endif //0
509 DEBUGA_GSMOPEN("HERE will shutdown gsmopen_signaling_thread of '%s'\n", GSMOPEN_P_LOG, the_interface);
510 }
511
512 if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) {
513 #if 0
514 #ifdef WIN32
515 if (SendMessage(tech_pvt->GSMopenHandles.win32_hInit_MainWindowHandle, WM_DESTROY, 0, 0) == FALSE) { // let's the gsmopen_api_thread_func die
516 DEBUGA_GSMOPEN("got FALSE here, thread probably was already dead. GetLastError returned: %d\n", GSMOPEN_P_LOG, GetLastError());
517 globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread = NULL;
518 }
519 #else
520 XEvent e;
521 Atom atom1 = XInternAtom(tech_pvt->GSMopenHandles.disp, "GSMOPENCONTROLAPI_MESSAGE_BEGIN", False);
522 memset(&e, 0, sizeof(e));
523 e.xclient.type = ClientMessage;
524 e.xclient.message_type = atom1; /* leading message */
525 e.xclient.display = tech_pvt->GSMopenHandles.disp;
526 e.xclient.window = tech_pvt->GSMopenHandles.gsmopen_win;
527 e.xclient.format = 8;
528
529 XSendEvent(tech_pvt->GSMopenHandles.disp, tech_pvt->GSMopenHandles.win, False, 0, &e);
530 XSync(tech_pvt->GSMopenHandles.disp, False);
531 #endif //WIN32
532 #endif //0
533
534 DEBUGA_GSMOPEN("HERE will shutdown gsmopen_api_thread of '%s'\n", GSMOPEN_P_LOG, the_interface);
535 }
536
537 while (x) {
538 x--;
539 switch_yield(50000);
540 }
541
542 if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) {
543 switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread);
544 }
545
546 if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) {
547 switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread);
548 }
549
550 switch_mutex_lock(globals.mutex);
551 if (globals.gsm_console == &globals.GSMOPEN_INTERFACES[interface_id]) {
552 DEBUGA_GSMOPEN("interface '%s' no more console\n", GSMOPEN_P_LOG, the_interface);
553 globals.gsm_console = NULL;
554 } else {
555 DEBUGA_GSMOPEN("interface '%s' STILL console\n", GSMOPEN_P_LOG, the_interface);
556 }
557 memset(&globals.GSMOPEN_INTERFACES[interface_id], '\0', sizeof(private_t));
558 globals.real_interfaces--;
559 switch_mutex_unlock(globals.mutex);
560
561 DEBUGA_GSMOPEN("interface '%s' deleted successfully\n", GSMOPEN_P_LOG, the_interface);
562 globals.GSMOPEN_INTERFACES[interface_id].running = 1;
563 end:
564 //running = 1;
565 return SWITCH_STATUS_SUCCESS;
566 }
567 #endif //0
568
569 /* END: Changes here */
570
571 /*
572 State methods they get called when the state changes to the specific state
573 returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
574 so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
575 */
channel_on_init(switch_core_session_t * session)576 static switch_status_t channel_on_init(switch_core_session_t *session)
577 {
578 switch_channel_t *channel;
579 private_t *tech_pvt = NULL;
580
581 tech_pvt = (private_t *) switch_core_session_get_private(session);
582 switch_assert(tech_pvt != NULL);
583
584 channel = switch_core_session_get_channel(session);
585 switch_assert(channel != NULL);
586 //ERRORA("%s CHANNEL INIT\n", GSMOPEN_P_LOG, tech_pvt->name);
587 switch_set_flag(tech_pvt, TFLAG_IO);
588
589 switch_mutex_lock(globals.mutex);
590 globals.calls++;
591
592 switch_mutex_unlock(globals.mutex);
593 DEBUGA_GSMOPEN("%s CHANNEL INIT %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session));
594
595 return SWITCH_STATUS_SUCCESS;
596 }
597
channel_on_destroy(switch_core_session_t * session)598 static switch_status_t channel_on_destroy(switch_core_session_t *session)
599 {
600 private_t *tech_pvt = NULL;
601
602 tech_pvt = (private_t *) switch_core_session_get_private(session);
603
604
605 if (tech_pvt) {
606 DEBUGA_GSMOPEN("%s CHANNEL DESTROY %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session));
607
608 if (switch_core_codec_ready(&tech_pvt->read_codec)) {
609 switch_core_codec_destroy(&tech_pvt->read_codec);
610 }
611
612 if (switch_core_codec_ready(&tech_pvt->write_codec)) {
613 switch_core_codec_destroy(&tech_pvt->write_codec);
614 }
615
616 switch_core_timer_destroy(&tech_pvt->timer_read);
617 switch_core_timer_destroy(&tech_pvt->timer_write);
618
619 #ifdef GSMOPEN_ALSA
620 if(tech_pvt->no_sound==0){
621 alsa_shutdown(tech_pvt);
622 }
623 #endif// GSMOPEN_ALSA
624 #ifdef GSMOPEN_PORTAUDIO
625 if(tech_pvt->no_sound==0){
626 if (gsmopen_portaudio_shutdown(tech_pvt)) {
627 ERRORA("gsmopen_portaudio_shutdown failed\n", GSMOPEN_P_LOG);
628
629 }
630 }
631 #endif// GSMOPEN_PORTAUDIO
632
633
634 *tech_pvt->session_uuid_str = '\0';
635 tech_pvt->interface_state = GSMOPEN_STATE_IDLE;
636 if (tech_pvt->phone_callflow == CALLFLOW_STATUS_FINISHED) {
637 tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE;
638 }
639 switch_core_session_set_private(session, NULL);
640 } else {
641 DEBUGA_GSMOPEN("!!!!!!NO tech_pvt!!!! CHANNEL DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(session));
642 }
643
644 return SWITCH_STATUS_SUCCESS;
645 }
646
channel_on_hangup(switch_core_session_t * session)647 static switch_status_t channel_on_hangup(switch_core_session_t *session)
648 {
649 switch_channel_t *channel = NULL;
650 private_t *tech_pvt = NULL;
651
652
653 channel = switch_core_session_get_channel(session);
654 switch_assert(channel != NULL);
655
656 tech_pvt = (private_t *) switch_core_session_get_private(session);
657 switch_assert(tech_pvt != NULL);
658
659 tech_pvt->phone_callflow = CALLFLOW_CALL_HANGUP_REQUESTED;
660
661 if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
662 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
663 tech_pvt->ob_failed_calls++;
664 } else {
665 tech_pvt->ib_failed_calls++;
666 }
667 }
668
669
670 DEBUGA_GSMOPEN("%s CHANNEL HANGUP\n", GSMOPEN_P_LOG, tech_pvt->name);
671 switch_clear_flag(tech_pvt, TFLAG_IO);
672 switch_clear_flag(tech_pvt, TFLAG_VOICE);
673 switch_set_flag(tech_pvt, TFLAG_HANGUP);
674
675 gsmopen_hangup(tech_pvt);
676
677 //memset(tech_pvt->session_uuid_str, '\0', sizeof(tech_pvt->session_uuid_str));
678 //*tech_pvt->session_uuid_str = '\0';
679 DEBUGA_GSMOPEN("%s CHANNEL HANGUP\n", GSMOPEN_P_LOG, tech_pvt->name);
680 switch_mutex_lock(globals.mutex);
681 globals.calls--;
682 if (globals.calls < 0) {
683 globals.calls = 0;
684 }
685
686 tech_pvt->interface_state = GSMOPEN_STATE_IDLE;
687 //FIXME if (tech_pvt->phone_callflow == CALLFLOW_STATUS_FINISHED) {
688 tech_pvt->phone_callflow = CALLFLOW_CALL_IDLE;
689 //FIXME }
690 switch_mutex_unlock(globals.mutex);
691
692 return SWITCH_STATUS_SUCCESS;
693 }
694
channel_on_routing(switch_core_session_t * session)695 static switch_status_t channel_on_routing(switch_core_session_t *session)
696 {
697 switch_channel_t *channel = NULL;
698 private_t *tech_pvt = NULL;
699
700 channel = switch_core_session_get_channel(session);
701 switch_assert(channel != NULL);
702
703 tech_pvt = (private_t *) switch_core_session_get_private(session);
704 switch_assert(tech_pvt != NULL);
705
706 DEBUGA_GSMOPEN("%s CHANNEL ROUTING\n", GSMOPEN_P_LOG, tech_pvt->name);
707
708 return SWITCH_STATUS_SUCCESS;
709 }
710
channel_on_execute(switch_core_session_t * session)711 static switch_status_t channel_on_execute(switch_core_session_t *session)
712 {
713
714 switch_channel_t *channel = NULL;
715 private_t *tech_pvt = NULL;
716
717 channel = switch_core_session_get_channel(session);
718 switch_assert(channel != NULL);
719
720 tech_pvt = (private_t *) switch_core_session_get_private(session);
721 switch_assert(tech_pvt != NULL);
722
723 DEBUGA_GSMOPEN("%s CHANNEL EXECUTE\n", GSMOPEN_P_LOG, tech_pvt->name);
724
725 return SWITCH_STATUS_SUCCESS;
726 }
727
channel_kill_channel(switch_core_session_t * session,int sig)728 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig)
729 {
730 switch_channel_t *channel = NULL;
731 private_t *tech_pvt = NULL;
732
733 channel = switch_core_session_get_channel(session);
734 switch_assert(channel != NULL);
735
736 tech_pvt = (private_t *) switch_core_session_get_private(session);
737 switch_assert(tech_pvt != NULL);
738
739 DEBUGA_GSMOPEN("%s CHANNEL KILL_CHANNEL\n", GSMOPEN_P_LOG, tech_pvt->name);
740 switch (sig) {
741 case SWITCH_SIG_KILL:
742 DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_SIG_KILL\n", GSMOPEN_P_LOG, switch_channel_get_name(channel));
743 //switch_mutex_lock(tech_pvt->flag_mutex);
744 switch_clear_flag(tech_pvt, TFLAG_IO);
745 switch_clear_flag(tech_pvt, TFLAG_VOICE);
746 switch_set_flag(tech_pvt, TFLAG_HANGUP);
747 //switch_mutex_unlock(tech_pvt->flag_mutex);
748 break;
749 case SWITCH_SIG_BREAK:
750 DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_SIG_BREAK\n", GSMOPEN_P_LOG, switch_channel_get_name(channel));
751 //switch_set_flag(tech_pvt, TFLAG_BREAK);
752 //switch_mutex_lock(tech_pvt->flag_mutex);
753 switch_set_flag(tech_pvt, TFLAG_BREAK);
754 //switch_mutex_unlock(tech_pvt->flag_mutex);
755 break;
756 default:
757 break;
758 }
759
760 return SWITCH_STATUS_SUCCESS;
761 }
channel_on_consume_media(switch_core_session_t * session)762 static switch_status_t channel_on_consume_media(switch_core_session_t *session)
763 {
764 private_t *tech_pvt = NULL;
765
766 tech_pvt = (private_t *) switch_core_session_get_private(session);
767
768 DEBUGA_GSMOPEN("%s CHANNEL CONSUME_MEDIA\n", GSMOPEN_P_LOG, tech_pvt->name);
769 return SWITCH_STATUS_SUCCESS;
770 }
771
772
channel_on_exchange_media(switch_core_session_t * session)773 static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
774 {
775 private_t *tech_pvt = NULL;
776 tech_pvt = (private_t *) switch_core_session_get_private(session);
777 DEBUGA_GSMOPEN("%s CHANNEL EXCHANGE_MEDIA\n", GSMOPEN_P_LOG, tech_pvt->name);
778 return SWITCH_STATUS_SUCCESS;
779 }
780
channel_on_soft_execute(switch_core_session_t * session)781 static switch_status_t channel_on_soft_execute(switch_core_session_t *session)
782 {
783 private_t *tech_pvt = NULL;
784 tech_pvt = (private_t *) switch_core_session_get_private(session);
785 DEBUGA_GSMOPEN("%s CHANNEL SOFT_EXECUTE\n", GSMOPEN_P_LOG, tech_pvt->name);
786 return SWITCH_STATUS_SUCCESS;
787 }
788
channel_send_dtmf(switch_core_session_t * session,const switch_dtmf_t * dtmf)789 static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
790 {
791 private_t *tech_pvt = (private_t *) switch_core_session_get_private(session);
792 switch_assert(tech_pvt != NULL);
793
794 DEBUGA_GSMOPEN("%s CHANNEL SEND_DTMF\n", GSMOPEN_P_LOG, tech_pvt->name);
795 DEBUGA_GSMOPEN("DTMF: %c\n", GSMOPEN_P_LOG, dtmf->digit);
796
797 gsmopen_senddigit(tech_pvt, dtmf->digit);
798
799 return SWITCH_STATUS_SUCCESS;
800 }
801
channel_read_frame(switch_core_session_t * session,switch_frame_t ** frame,switch_io_flag_t flags,int stream_id)802 static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
803 {
804 switch_channel_t *channel = NULL;
805 private_t *tech_pvt = NULL;
806 switch_byte_t *data;
807 #if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
808 int samples;
809 char digit_str[256];
810 #endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
811 #ifdef GSMOPEN_PORTAUDIO
812 #ifdef WANT_SPEEX
813 spx_int16_t *speexptr;
814 spx_int16_t pcm2[160];
815 int i;
816 #endif// GSMOPEN_ALSA
817 #endif// WANT_SPEEX
818
819
820 channel = switch_core_session_get_channel(session);
821 switch_assert(channel != NULL);
822
823 tech_pvt = (private_t *) switch_core_session_get_private(session);
824 switch_assert(tech_pvt != NULL);
825
826 if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
827 ERRORA("channel not ready \n", GSMOPEN_P_LOG);
828 //TODO: kill the bastard
829 return SWITCH_STATUS_FALSE;
830 }
831
832
833 tech_pvt->read_frame.flags = SFF_NONE;
834 *frame = NULL;
835
836 if (switch_test_flag(tech_pvt, TFLAG_HANGUP)) {
837 return SWITCH_STATUS_FALSE;
838 }
839
840 #ifndef GSMOPEN_PORTAUDIO
841 switch_core_timer_next(&tech_pvt->timer_read);
842 #endif// GSMOPEN_PORTAUDIO
843
844 if(tech_pvt->no_sound==1){
845 goto cng;
846 }
847 #if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
848 #ifdef GSMOPEN_ALSA
849 //if ((samples = snd_pcm_readi(tech_pvt->alsac, tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_packet)) > 0)
850 if ((samples = alsa_read(tech_pvt, (short *) tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_packet)) > 0)
851 #endif// GSMOPEN_ALSA
852 #ifdef GSMOPEN_PORTAUDIO
853 if ((samples = gsmopen_portaudio_read(tech_pvt, (short *) tech_pvt->read_frame.data, tech_pvt->read_codec.implementation->samples_per_packet)) > 0)
854 #endif// GSMOPEN_PORTAUDIO
855 {
856
857 #ifdef GSMOPEN_PORTAUDIO
858 #ifdef WANT_SPEEX
859
860 if (tech_pvt->speexecho) {
861 speexptr = ((spx_int16_t *) tech_pvt->read_frame.data);
862 /* Perform echo cancellation */
863 speex_echo_capture(tech_pvt->echo_state, speexptr, pcm2);
864 #ifndef GIOVA48
865 for (i = 0; i < 160; i++)
866 #else //GIOVA48
867 for (i = 0; i < 960; i++)
868 #endif //GIOVA48
869 speexptr[i] = pcm2[i];
870 }
871 /* Apply noise/echo residual suppression */
872 if (tech_pvt->speexpreprocess) {
873 speex_preprocess_run(tech_pvt->preprocess, speexptr);
874 }
875
876 DEBUGA_GSMOPEN("read\n", GSMOPEN_P_LOG);
877 #endif //WANT_SPEEX
878 #endif // GSMOPEN_PORTAUDIO
879
880
881
882
883
884 tech_pvt->read_frame.datalen = samples * 2;
885 tech_pvt->read_frame.samples = samples;
886
887 #ifndef GSMOPEN_PORTAUDIO
888 tech_pvt->read_frame.timestamp = tech_pvt->timer_read.samplecount;
889 #endif// GSMOPEN_PORTAUDIO
890
891 *frame = &tech_pvt->read_frame;
892
893 //status = SWITCH_STATUS_SUCCESS;
894 switch_set_flag(tech_pvt, TFLAG_VOICE);
895 }
896
897 //WARNINGA("samples=%d\n", GSMOPEN_P_LOG, samples);
898 if (samples != 160) {
899 ERRORA("samples=%d\n", GSMOPEN_P_LOG, samples);
900 goto cng;
901 }
902 //DEBUGA_GSMOPEN("samples=%d tech_pvt->read_frame.timestamp=%d\n", GSMOPEN_P_LOG, samples, tech_pvt->read_frame.timestamp);
903
904 //usleep(17000);
905 //usleep(17000);
906
907
908
909
910
911 memset(digit_str, 0, sizeof(digit_str));
912 //teletone_dtmf_detect(&tech_pvt->dtmf_detect, (int16_t *) tech_pvt->read_frame.data, tech_pvt->read_frame.samples);
913 //teletone_dtmf_get(&tech_pvt->dtmf_detect, digit_str, sizeof(digit_str));
914 dtmf_rx(&tech_pvt->dtmf_state, (int16_t *) tech_pvt->read_frame.data, tech_pvt->read_frame.samples);
915 dtmf_rx_get(&tech_pvt->dtmf_state, digit_str, sizeof(digit_str));
916
917 gsmopen_sound_boost(tech_pvt->read_frame.data, tech_pvt->read_frame.samples, tech_pvt->capture_boost);
918
919 if (digit_str[0]) {
920 switch_time_t new_dtmf_timestamp = switch_time_now();
921 if ((new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp) > 350000) { //FIXME: make it configurable
922 char *p = digit_str;
923 switch_channel_t *channel = switch_core_session_get_channel(session);
924
925 while (p && *p) {
926 switch_dtmf_t dtmf = {0};
927 dtmf.digit = *p;
928 dtmf.duration = SWITCH_DEFAULT_DTMF_DURATION;
929 switch_channel_queue_dtmf(channel, &dtmf);
930 p++;
931 }
932 NOTICA("DTMF DETECTED: [%s] new_dtmf_timestamp: %u, delta_t: %u\n", GSMOPEN_P_LOG, digit_str, (unsigned int) new_dtmf_timestamp,
933 (unsigned int) (new_dtmf_timestamp - tech_pvt->old_dtmf_timestamp));
934 tech_pvt->old_dtmf_timestamp = new_dtmf_timestamp;
935 }
936 }
937 while (switch_test_flag(tech_pvt, TFLAG_IO)) {
938 if (switch_test_flag(tech_pvt, TFLAG_BREAK)) {
939 switch_clear_flag(tech_pvt, TFLAG_BREAK);
940 DEBUGA_GSMOPEN("CHANNEL READ FRAME goto CNG\n", GSMOPEN_P_LOG);
941 goto cng;
942 }
943
944 if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
945 DEBUGA_GSMOPEN("CHANNEL READ FRAME not IO\n", GSMOPEN_P_LOG);
946 return SWITCH_STATUS_FALSE;
947 }
948
949 if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) {
950 switch_clear_flag(tech_pvt, TFLAG_VOICE);
951 if (!tech_pvt->read_frame.datalen) {
952 DEBUGA_GSMOPEN("CHANNEL READ CONTINUE\n", GSMOPEN_P_LOG);
953 continue;
954 }
955 *frame = &tech_pvt->read_frame;
956 #ifdef BIGENDIAN
957 if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
958 switch_swap_linear((*frame)->data, (int) (*frame)->datalen / 2);
959 }
960 #endif
961 //WARNINGA("HERE\n", GSMOPEN_P_LOG);
962 return SWITCH_STATUS_SUCCESS;
963 }
964
965 WARNINGA("HERE\n", GSMOPEN_P_LOG);
966 DEBUGA_GSMOPEN("CHANNEL READ no TFLAG_VOICE\n", GSMOPEN_P_LOG);
967 return SWITCH_STATUS_FALSE;
968
969 }
970
971 DEBUGA_GSMOPEN("CHANNEL READ FALSE\n", GSMOPEN_P_LOG);
972 return SWITCH_STATUS_FALSE;
973 #endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
974 cng:
975 data = (switch_byte_t *) tech_pvt->read_frame.data;
976 data[0] = 65;
977 data[1] = 0;
978 tech_pvt->read_frame.datalen = 2;
979 tech_pvt->read_frame.flags = SFF_CNG;
980 *frame = &tech_pvt->read_frame;
981 #ifdef GSMOPEN_PORTAUDIO
982 //speex_echo_state_reset(tech_pvt->stream->echo_state);
983 #endif // GSMOPEN_PORTAUDIO
984 return SWITCH_STATUS_SUCCESS;
985
986 }
987
channel_write_frame(switch_core_session_t * session,switch_frame_t * frame,switch_io_flag_t flags,int stream_id)988 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
989 {
990 switch_channel_t *channel = NULL;
991 private_t *tech_pvt = NULL;
992 #if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
993 unsigned int sent;
994 #endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
995 #ifdef GSMOPEN_PORTAUDIO
996 #ifdef WANT_SPEEX
997 spx_int16_t *speexptr;
998 #endif// GSMOPEN_ALSA
999 #endif// WANT_SPEEX
1000
1001 channel = switch_core_session_get_channel(session);
1002 switch_assert(channel != NULL);
1003
1004 tech_pvt = (private_t *) switch_core_session_get_private(session);
1005 switch_assert(tech_pvt != NULL);
1006
1007 if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
1008 ERRORA("channel not ready \n", GSMOPEN_P_LOG);
1009 //TODO: kill the bastard
1010 return SWITCH_STATUS_FALSE;
1011 }
1012 #ifdef BIGENDIAN
1013 if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) {
1014 #ifdef WIN32
1015 switch_swap_linear((int16_t *)frame->data, (int) frame->datalen / 2);
1016 #else
1017 switch_swap_linear(frame->data, (int) frame->datalen / 2);
1018 #endif //WIN32
1019 }
1020 #endif
1021
1022 //switch_core_timer_next(&tech_pvt->timer_write);
1023 //sent = frame->datalen;
1024
1025 //ERRORA("PLAY \n", GSMOPEN_P_LOG);
1026 //snd_pcm_writei(tech_pvt->alsap, (short *) frame->data, (int) (frame->datalen / 2));
1027
1028 gsmopen_sound_boost(frame->data, frame->samples, tech_pvt->playback_boost);
1029 #ifdef GSMOPEN_ALSA
1030
1031 switch_core_timer_next(&tech_pvt->timer_write);
1032 sent = alsa_write(tech_pvt, (short *) frame->data, (int) (frame->datalen));
1033 //DEBUGA_GSMOPEN("sent=%d \n", GSMOPEN_P_LOG, sent);
1034
1035 if (sent && sent != frame->datalen / 2 && sent != -1) {
1036 DEBUGA_GSMOPEN("sent %d\n", GSMOPEN_P_LOG, sent);
1037 }
1038 #endif// GSMOPEN_ALSA
1039 #ifdef GSMOPEN_PORTAUDIO
1040 sent = gsmopen_portaudio_write(tech_pvt, (short *) frame->data, (int) (frame->datalen));
1041 //DEBUGA_GSMOPEN("sent=%d \n", GSMOPEN_P_LOG, sent);
1042
1043 if (sent && sent != frame->datalen / 2 && sent != -1) {
1044 DEBUGA_GSMOPEN("sent %d\n", GSMOPEN_P_LOG, sent);
1045 }
1046
1047 #ifdef WANT_SPEEX
1048 if (tech_pvt->speexecho) {
1049 speexptr = (spx_int16_t *) frame->data;
1050 /* Put frame into playback buffer */
1051 speex_echo_playback(tech_pvt->echo_state, speexptr);
1052 DEBUGA_GSMOPEN("write\n", GSMOPEN_P_LOG);
1053 }
1054 #endif //WANT_SPEEX
1055 #endif // GSMOPEN_PORTAUDIO
1056 //NOTICA("sent=%d\n", GSMOPEN_P_LOG, sent);
1057 return SWITCH_STATUS_SUCCESS;
1058 }
1059
channel_answer_channel(switch_core_session_t * session)1060 static switch_status_t channel_answer_channel(switch_core_session_t *session)
1061 {
1062 private_t *tech_pvt;
1063 switch_channel_t *channel = NULL;
1064
1065 channel = switch_core_session_get_channel(session);
1066 switch_assert(channel != NULL);
1067
1068 tech_pvt = (private_t *) switch_core_session_get_private(session);
1069 switch_assert(tech_pvt != NULL);
1070
1071 //ERRORA("%s CHANNEL INIT\n", GSMOPEN_P_LOG, tech_pvt->name);
1072 switch_set_flag(tech_pvt, TFLAG_IO);
1073 gsmopen_serial_answer(tech_pvt);
1074
1075 /* Move channel's state machine to ROUTING. This means the call is trying
1076 to get from the initial start where the call because, to the point
1077 where a destination has been identified. If the channel is simply
1078 left in the initial state, nothing will happen. */
1079 switch_channel_set_state(channel, CS_ROUTING);
1080 switch_mutex_lock(globals.mutex);
1081 globals.calls++;
1082
1083 switch_mutex_unlock(globals.mutex);
1084 DEBUGA_GSMOPEN("%s CHANNEL ANSWER %s\n", GSMOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session));
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101 DEBUGA_GSMOPEN("ANSWERED! \n", GSMOPEN_P_LOG);
1102
1103 return SWITCH_STATUS_SUCCESS;
1104 }
1105
channel_receive_message(switch_core_session_t * session,switch_core_session_message_t * msg)1106 static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
1107 {
1108 switch_channel_t *channel;
1109 private_t *tech_pvt;
1110 #if defined(GSMOPEN_ALSA)
1111 int samples;
1112 short tmp_buffer[1280];
1113 #endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
1114
1115 channel = switch_core_session_get_channel(session);
1116 switch_assert(channel != NULL);
1117
1118 tech_pvt = (private_t *) switch_core_session_get_private(session);
1119 switch_assert(tech_pvt != NULL);
1120
1121 switch (msg->message_id) {
1122 case SWITCH_MESSAGE_INDICATE_ANSWER:
1123 {
1124 DEBUGA_GSMOPEN("MSG_ID=%d, TO BE ANSWERED!\n", GSMOPEN_P_LOG, msg->message_id);
1125 channel_answer_channel(session);
1126 }
1127 break;
1128 case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC:
1129
1130 DEBUGA_GSMOPEN("%s CHANNEL got SWITCH_MESSAGE_INDICATE_AUDIO_SYNC\n", GSMOPEN_P_LOG, switch_channel_get_name(channel));
1131 switch_core_timer_sync(&tech_pvt->timer_read);
1132 switch_core_timer_sync(&tech_pvt->timer_write);
1133
1134 #ifdef GSMOPEN_ALSA
1135 while ((samples = alsa_read(tech_pvt, tmp_buffer, tech_pvt->read_codec.implementation->samples_per_packet * 4)) > 160) {
1136 //WARNINGA("read %d samples\n", GSMOPEN_P_LOG, samples);
1137 }
1138 #endif// GSMOPEN_ALSA
1139 #ifdef GSMOPEN_PORTAUDIO
1140 //while ((samples = gsmopen_portaudio_read(tech_pvt, tmp_buffer, tech_pvt->read_codec.implementation->samples_per_packet * 2)) > 160) {
1141 //WARNINGA("read %d samples\n", GSMOPEN_P_LOG, samples);
1142 //}
1143 #ifdef WANT_SPEEX
1144 speex_echo_state_reset(tech_pvt->echo_state);
1145 #endif// WANT_SPEEX
1146 #endif// GSMOPEN_PORTAUDIO
1147 break;
1148
1149
1150 default:
1151 {
1152 DEBUGA_GSMOPEN("MSG_ID=%d\n", GSMOPEN_P_LOG, msg->message_id);
1153 }
1154 break;
1155 }
1156
1157 return SWITCH_STATUS_SUCCESS;
1158 }
1159
channel_receive_event(switch_core_session_t * session,switch_event_t * event)1160 static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
1161 {
1162 struct private_object *tech_pvt = (struct private_object *) switch_core_session_get_private(session);
1163 char *body = switch_event_get_body(event);
1164 switch_assert(tech_pvt != NULL);
1165
1166 if (!body) {
1167 body = (char *) "";
1168 }
1169
1170 WARNINGA("event: |||%s|||\n", GSMOPEN_P_LOG, body);
1171
1172 return SWITCH_STATUS_SUCCESS;
1173 }
1174
1175 switch_state_handler_table_t gsmopen_state_handlers = {
1176 /*.on_init */ channel_on_init,
1177 /*.on_routing */ channel_on_routing,
1178 /*.on_execute */ channel_on_execute,
1179 /*.on_hangup */ channel_on_hangup,
1180 /*.on_exchange_media */ channel_on_exchange_media,
1181 /*.on_soft_execute */ channel_on_soft_execute,
1182 /*.on_consume_media */ channel_on_consume_media,
1183 /*.on_hibernate */ NULL,
1184 /*.on_reset */ NULL,
1185 /*.on_park */ NULL,
1186 /*.on_reporting */ NULL,
1187 /*.on_destroy */ channel_on_destroy
1188 };
1189
1190 switch_io_routines_t gsmopen_io_routines = {
1191 /*.outgoing_channel */ channel_outgoing_channel,
1192 /*.read_frame */ channel_read_frame,
1193 /*.write_frame */ channel_write_frame,
1194 /*.kill_channel */ channel_kill_channel,
1195 /*.send_dtmf */ channel_send_dtmf,
1196 /*.receive_message */ channel_receive_message,
1197 /*.receive_event */ channel_receive_event
1198 };
1199
channel_outgoing_channel(switch_core_session_t * session,switch_event_t * var_event,switch_caller_profile_t * outbound_profile,switch_core_session_t ** new_session,switch_memory_pool_t ** pool,switch_originate_flag_t flags,switch_call_cause_t * cancel_cause)1200 static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
1201 switch_event_t *var_event,
1202 switch_caller_profile_t *outbound_profile,
1203 switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
1204 switch_call_cause_t *cancel_cause)
1205 {
1206 private_t *tech_pvt = NULL;
1207 if ((*new_session = switch_core_session_request(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) {
1208 switch_channel_t *channel = NULL;
1209 switch_caller_profile_t *caller_profile;
1210 char *rdest;
1211 int found = 0;
1212 char interface_name[256];
1213
1214 DEBUGA_GSMOPEN("1 SESSION_REQUEST %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session));
1215 switch_core_session_add_stream(*new_session, NULL);
1216
1217
1218 if (!zstr(outbound_profile->destination_number)) {
1219 int i;
1220 char *slash;
1221
1222 switch_copy_string(interface_name, outbound_profile->destination_number, 255);
1223 slash = strrchr(interface_name, '/');
1224 *slash = '\0';
1225
1226 switch_mutex_lock(globals.mutex);
1227 if (strncmp("ANY", interface_name, strlen(interface_name)) == 0 || strncmp("RR", interface_name, strlen(interface_name)) == 0) {
1228 /* we've been asked for the "ANY" interface, let's find the first idle interface */
1229 //DEBUGA_GSMOPEN("Finding one available gsmopen interface\n", GSMOPEN_P_LOG);
1230 //tech_pvt = find_available_gsmopen_interface(NULL);
1231 //if (tech_pvt)
1232 //found = 1;
1233 //} else if (strncmp("RR", interface_name, strlen(interface_name)) == 0) {
1234 /* Find the first idle interface using Round Robin */
1235 DEBUGA_GSMOPEN("Finding one available gsmopen interface RR\n", GSMOPEN_P_LOG);
1236 tech_pvt = find_available_gsmopen_interface_rr(NULL);
1237 if (tech_pvt) {
1238 found = 1;
1239 DEBUGA_GSMOPEN("FOUND one available gsmopen interface RR\n", GSMOPEN_P_LOG);
1240 }
1241 }
1242
1243 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
1244 /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */
1245 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
1246 && (strncmp(globals.GSMOPEN_INTERFACES[i].name, interface_name, strlen(interface_name)) == 0)) {
1247 if (strlen(globals.GSMOPEN_INTERFACES[i].session_uuid_str)) {
1248 DEBUGA_GSMOPEN
1249 ("globals.GSMOPEN_INTERFACES[%d].name=|||%s||| session_uuid_str=|||%s||| is BUSY\n",
1250 GSMOPEN_P_LOG, i, globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].session_uuid_str);
1251 DEBUGA_GSMOPEN("1 SESSION_DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session));
1252 switch_core_session_destroy(new_session);
1253 switch_mutex_unlock(globals.mutex);
1254 return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
1255 }
1256
1257 DEBUGA_GSMOPEN("globals.GSMOPEN_INTERFACES[%d].name=|||%s|||?\n", GSMOPEN_P_LOG, i, globals.GSMOPEN_INTERFACES[i].name);
1258 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
1259 found = 1;
1260 break;
1261 }
1262
1263 }
1264
1265 } else {
1266 ERRORA("Doh! no destination number?\n", GSMOPEN_P_LOG);
1267 switch_core_session_destroy(new_session);
1268 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1269 }
1270
1271 if (!found) {
1272 DEBUGA_GSMOPEN("Doh! no available interface for |||%s|||?\n", GSMOPEN_P_LOG, interface_name);
1273 DEBUGA_GSMOPEN("2 SESSION_DESTROY %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(*new_session));
1274 switch_core_session_destroy(new_session);
1275 switch_mutex_unlock(globals.mutex);
1276 //return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1277 return SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
1278 }
1279
1280 channel = switch_core_session_get_channel(*new_session);
1281 if (!channel) {
1282 ERRORA("Doh! no channel?\n", GSMOPEN_P_LOG);
1283 switch_core_session_destroy(new_session);
1284 switch_mutex_unlock(globals.mutex);
1285 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1286 }
1287 if (gsmopen_tech_init(tech_pvt, *new_session) != SWITCH_STATUS_SUCCESS) {
1288 ERRORA("Doh! no tech_init?\n", GSMOPEN_P_LOG);
1289 switch_core_session_destroy(new_session);
1290 switch_mutex_unlock(globals.mutex);
1291 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1292 }
1293
1294
1295 if (outbound_profile) {
1296 char name[128];
1297
1298 snprintf(name, sizeof(name), "gsmopen/%s", outbound_profile->destination_number);
1299 //snprintf(name, sizeof(name), "gsmopen/%s", tech_pvt->name);
1300 switch_channel_set_name(channel, name);
1301 caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
1302 switch_channel_set_caller_profile(channel, caller_profile);
1303 tech_pvt->caller_profile = caller_profile;
1304 } else {
1305 ERRORA("Doh! no caller profile\n", GSMOPEN_P_LOG);
1306 switch_core_session_destroy(new_session);
1307 switch_mutex_unlock(globals.mutex);
1308 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1309 }
1310
1311 tech_pvt->ob_calls++;
1312
1313 rdest = strchr(caller_profile->destination_number, '/');
1314 *rdest++ = '\0';
1315
1316 //gsmopen_call(tech_pvt, rdest, 30);
1317
1318 switch_copy_string(tech_pvt->session_uuid_str, switch_core_session_get_uuid(*new_session), sizeof(tech_pvt->session_uuid_str));
1319 caller_profile = tech_pvt->caller_profile;
1320 caller_profile->destination_number = rdest;
1321
1322 switch_set_flag(tech_pvt, TFLAG_OUTBOUND);
1323 switch_channel_set_state(channel, CS_INIT);
1324 gsmopen_call(tech_pvt, rdest, 30);
1325 switch_mutex_unlock(globals.mutex);
1326 return SWITCH_CAUSE_SUCCESS;
1327 }
1328
1329 ERRORA("Doh! no new_session\n", GSMOPEN_P_LOG);
1330 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1331 }
1332
1333 /*!
1334 * \brief This thread runs during a call, and monitor the interface for signaling, like hangup, caller id, etc most of signaling is handled inside the gsmopen_signaling_read function
1335 *
1336 */
1337
load_config(int reload_type)1338 static switch_status_t load_config(int reload_type)
1339 {
1340 const char *cf = "gsmopen.conf";
1341 switch_xml_t cfg, xml, global_settings, param, interfaces, myinterface;
1342 private_t *tech_pvt = NULL;
1343
1344 switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, gsmopen_module_pool);
1345 if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
1346 ERRORA("open of %s failed\n", GSMOPEN_P_LOG, cf);
1347 running = 0;
1348 switch_xml_free(xml);
1349 return SWITCH_STATUS_TERM;
1350 }
1351
1352 switch_mutex_lock(globals.mutex);
1353 if ((global_settings = switch_xml_child(cfg, "global_settings"))) {
1354 for (param = switch_xml_child(global_settings, "param"); param; param = param->next) {
1355 char *var = (char *) switch_xml_attr_soft(param, "name");
1356 char *val = (char *) switch_xml_attr_soft(param, "value");
1357
1358 if (!strcasecmp(var, "debug")) {
1359 DEBUGA_GSMOPEN("globals.debug=%d\n", GSMOPEN_P_LOG, globals.debug);
1360 globals.debug = atoi(val);
1361 DEBUGA_GSMOPEN("globals.debug=%d\n", GSMOPEN_P_LOG, globals.debug);
1362 } else if (!strcasecmp(var, "hold-music")) {
1363 switch_set_string(globals.hold_music, val);
1364 DEBUGA_GSMOPEN("globals.hold_music=%s\n", GSMOPEN_P_LOG, globals.hold_music);
1365 } else if (!strcmp(var, "dialplan")) {
1366 set_global_dialplan(val);
1367 DEBUGA_GSMOPEN("globals.dialplan=%s\n", GSMOPEN_P_LOG, globals.dialplan);
1368 } else if (!strcmp(var, "destination")) {
1369 set_global_destination(val);
1370 DEBUGA_GSMOPEN("globals.destination=%s\n", GSMOPEN_P_LOG, globals.destination);
1371 } else if (!strcmp(var, "context")) {
1372 set_global_context(val);
1373 DEBUGA_GSMOPEN("globals.context=%s\n", GSMOPEN_P_LOG, globals.context);
1374
1375 }
1376
1377 }
1378 }
1379
1380 if ((interfaces = switch_xml_child(cfg, "per_interface_settings"))) {
1381 int i = 0;
1382
1383 for (myinterface = switch_xml_child(interfaces, "interface"); myinterface; myinterface = myinterface->next) {
1384 char *id = (char *) switch_xml_attr(myinterface, "id");
1385 char *name = (char *) switch_xml_attr(myinterface, "name");
1386 const char *context = "default";
1387 const char *dialplan = "XML";
1388 const char *destination = "5000";
1389 const char *controldevice_name = "/dev/ttyACM0";
1390 //char *digit_timeout;
1391 //char *max_digits;
1392 //char *hotline;
1393 char *dial_regex = NULL;
1394 char *hold_music = NULL;
1395 char *fail_dial_regex = NULL;
1396 //const char *enable_callerid ;
1397
1398
1399 const char *at_dial_pre_number = "ATD";
1400 const char *at_dial_post_number = ";";
1401 const char *at_dial_expect = "OK";
1402 const char *at_hangup = "ATH";
1403 const char *at_hangup_expect = "OK";
1404 const char *at_answer = "ATA";
1405 const char *at_answer_expect = "OK";
1406 const char *at_send_dtmf = "AT+VTS";
1407 const char *at_preinit_1 = "";
1408 const char *at_preinit_1_expect = "";
1409 const char *at_preinit_2 = "";
1410 const char *at_preinit_2_expect = "";
1411 const char *at_preinit_3 = "";
1412 const char *at_preinit_3_expect = "";
1413 const char *at_preinit_4 = "";
1414 const char *at_preinit_4_expect = "";
1415 const char *at_preinit_5 = "";
1416 const char *at_preinit_5_expect = "";
1417 const char *at_postinit_1 = "at+cmic=0,9";
1418 const char *at_postinit_1_expect = "OK";
1419 const char *at_postinit_2 = "AT+CKPD=\"EEE\"";
1420 const char *at_postinit_2_expect = "OK";
1421 const char *at_postinit_3 = "AT+CSSN=1,0";
1422 const char *at_postinit_3_expect = "OK";
1423 const char *at_postinit_4 = "at+sidet=0";
1424 const char *at_postinit_4_expect = "OK";
1425 const char *at_postinit_5 = "at+clvl=99";
1426 const char *at_postinit_5_expect = "OK";
1427 const char *at_query_battchg = "AT+CBC";
1428 const char *at_query_battchg_expect = "OK";
1429 const char *at_query_signal = "AT+CSQ";
1430 const char *at_query_signal_expect = "OK";
1431 const char *at_call_idle = "+MCST: 1";
1432 const char *at_call_incoming = "+MCST: 2";
1433 const char *at_call_active = "+CSSI: 7";
1434 const char *at_call_failed = "+MCST: 65";
1435 const char *at_call_calling = "+CSSI: 1";
1436 const char *at_indicator_noservice_string = "CIEV: 2;0";
1437 const char *at_indicator_nosignal_string = "CIEV: 5;0";
1438 const char *at_indicator_lowsignal_string = "CIEV: 5;1";
1439 const char *at_indicator_lowbattchg_string = "CIEV: 0;1";
1440 const char *at_indicator_nobattchg_string = "CIEV: 0;0";
1441 const char *at_indicator_callactive_string = "CIEV: 3;1";
1442 const char *at_indicator_nocallactive_string = "CIEV: 3;0";
1443 const char *at_indicator_nocallsetup_string = "CIEV: 6;0";
1444 const char *at_indicator_callsetupincoming_string = "CIEV: 6;1";
1445 const char *at_indicator_callsetupoutgoing_string = "CIEV: 6;2";
1446 const char *at_indicator_callsetupremoteringing_string = "CIEV: 6;3";
1447 //const char *sms_receiving_program = "/usr/local/bin/ciapalo";
1448 const char *alsacname = "plughw:1";
1449 const char *alsapname = "plughw:1";
1450 const char *at_early_audio = "0";
1451 const char *at_after_preinit_pause = "500000";
1452 const char *at_initial_pause = "500000";
1453 const char *at_has_clcc = "0";
1454 const char *at_has_ecam = "0";
1455 const char *alsa_period_size = "160";
1456 const char *alsa_periods_in_buffer = "4";
1457 const char *gsmopen_sound_rate = "8000";
1458 const char *alsa_play_is_mono = "1";
1459 const char *alsa_capture_is_mono = "1";
1460 const char *capture_boost = "5";
1461 const char *playback_boost = "10";
1462 #if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
1463 const char *no_sound = "0";
1464 #else
1465 const char *no_sound = "1";
1466 #endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
1467 #ifdef GSMOPEN_PORTAUDIO
1468 const char *portaudiocindex;
1469 const char *portaudiopindex;
1470 const char *speexecho;
1471 const char *speexpreprocess;
1472 #endif// GSMOPEN_PORTAUDIO
1473
1474 uint32_t interface_id = 0;
1475 #ifdef WIN32
1476 int controldevice_speed = 115200; //FIXME TODO
1477 #else
1478 uint32_t controldevice_speed = B115200; //FIXME TODO
1479 #endif //WIN32
1480 uint32_t controldevprotocol = PROTOCOL_AT; //FIXME TODO
1481 uint32_t running = 1; //FIXME TODO
1482 const char *gsmopen_serial_sync_period = "300"; //FIXME TODO
1483
1484
1485
1486 tech_pvt = NULL;
1487
1488 for (param = switch_xml_child(myinterface, "param"); param; param = param->next) {
1489 char *var = (char *) switch_xml_attr_soft(param, "name");
1490 char *val = (char *) switch_xml_attr_soft(param, "value");
1491
1492 if (!strcasecmp(var, "id")) {
1493 id = val;
1494 } else if (!strcasecmp(var, "name")) {
1495 name = val;
1496 } else if (!strcasecmp(var, "context")) {
1497 context = val;
1498 } else if (!strcasecmp(var, "dialplan")) {
1499 dialplan = val;
1500 } else if (!strcasecmp(var, "destination")) {
1501 destination = val;
1502 } else if (!strcasecmp(var, "controldevice_name")) {
1503 controldevice_name = val;
1504 //} else if (!strcasecmp(var, "digit_timeout")) {
1505 //digit_timeout = val;
1506 //} else if (!strcasecmp(var, "max_digits")) {
1507 //max_digits = val;
1508 //} else if (!strcasecmp(var, "hotline")) {
1509 //hotline = val;
1510 } else if (!strcasecmp(var, "dial_regex")) {
1511 dial_regex = val;
1512 } else if (!strcasecmp(var, SWITCH_HOLD_MUSIC_VARIABLE)) {
1513 hold_music = val;
1514 } else if (!strcasecmp(var, "fail_dial_regex")) {
1515 fail_dial_regex = val;
1516 //} else if (!strcasecmp(var, "enable_callerid")) {
1517 //enable_callerid = val;
1518 } else if (!strcasecmp(var, "at_dial_pre_number")) {
1519 at_dial_pre_number = val;
1520 } else if (!strcasecmp(var, "at_dial_post_number")) {
1521 at_dial_post_number = val;
1522 } else if (!strcasecmp(var, "at_dial_expect")) {
1523 at_dial_expect = val;
1524 } else if (!strcasecmp(var, "at_hangup")) {
1525 at_hangup = val;
1526 } else if (!strcasecmp(var, "at_hangup_expect")) {
1527 at_hangup_expect = val;
1528 } else if (!strcasecmp(var, "at_answer")) {
1529 at_answer = val;
1530 } else if (!strcasecmp(var, "at_answer_expect")) {
1531 at_answer_expect = val;
1532 } else if (!strcasecmp(var, "at_send_dtmf")) {
1533 at_send_dtmf = val;
1534 } else if (!strcasecmp(var, "at_preinit_1")) {
1535 at_preinit_1 = val;
1536 } else if (!strcasecmp(var, "at_preinit_1_expect")) {
1537 at_preinit_1_expect = val;
1538 } else if (!strcasecmp(var, "at_preinit_2")) {
1539 at_preinit_2 = val;
1540 } else if (!strcasecmp(var, "at_preinit_2_expect")) {
1541 at_preinit_2_expect = val;
1542 } else if (!strcasecmp(var, "at_preinit_3")) {
1543 at_preinit_3 = val;
1544 } else if (!strcasecmp(var, "at_preinit_3_expect")) {
1545 at_preinit_3_expect = val;
1546 } else if (!strcasecmp(var, "at_preinit_4")) {
1547 at_preinit_4 = val;
1548 } else if (!strcasecmp(var, "at_preinit_4_expect")) {
1549 at_preinit_4_expect = val;
1550 } else if (!strcasecmp(var, "at_preinit_5")) {
1551 at_preinit_5 = val;
1552 } else if (!strcasecmp(var, "at_preinit_5_expect")) {
1553 at_preinit_5_expect = val;
1554 } else if (!strcasecmp(var, "at_postinit_1")) {
1555 at_postinit_1 = val;
1556 } else if (!strcasecmp(var, "at_postinit_1_expect")) {
1557 at_postinit_1_expect = val;
1558 } else if (!strcasecmp(var, "at_postinit_2")) {
1559 at_postinit_2 = val;
1560 } else if (!strcasecmp(var, "at_postinit_2_expect")) {
1561 at_postinit_2_expect = val;
1562 } else if (!strcasecmp(var, "at_postinit_3")) {
1563 at_postinit_3 = val;
1564 } else if (!strcasecmp(var, "at_postinit_3_expect")) {
1565 at_postinit_3_expect = val;
1566 } else if (!strcasecmp(var, "at_postinit_4")) {
1567 at_postinit_4 = val;
1568 } else if (!strcasecmp(var, "at_postinit_4_expect")) {
1569 at_postinit_4_expect = val;
1570 } else if (!strcasecmp(var, "at_postinit_5")) {
1571 at_postinit_5 = val;
1572 } else if (!strcasecmp(var, "at_postinit_5_expect")) {
1573 at_postinit_5_expect = val;
1574 } else if (!strcasecmp(var, "at_query_battchg")) {
1575 at_query_battchg = val;
1576 } else if (!strcasecmp(var, "at_query_battchg_expect")) {
1577 at_query_battchg_expect = val;
1578 } else if (!strcasecmp(var, "at_query_signal")) {
1579 at_query_signal = val;
1580 } else if (!strcasecmp(var, "at_query_signal_expect")) {
1581 at_query_signal_expect = val;
1582 } else if (!strcasecmp(var, "at_call_idle")) {
1583 at_call_idle = val;
1584 } else if (!strcasecmp(var, "at_call_incoming")) {
1585 at_call_incoming = val;
1586 } else if (!strcasecmp(var, "at_call_active")) {
1587 at_call_active = val;
1588 } else if (!strcasecmp(var, "at_call_failed")) {
1589 at_call_failed = val;
1590 } else if (!strcasecmp(var, "at_call_calling")) {
1591 at_call_calling = val;
1592 } else if (!strcasecmp(var, "at_indicator_noservice_string")) {
1593 at_indicator_noservice_string = val;
1594 } else if (!strcasecmp(var, "at_indicator_nosignal_string")) {
1595 at_indicator_nosignal_string = val;
1596 } else if (!strcasecmp(var, "at_indicator_lowsignal_string")) {
1597 at_indicator_lowsignal_string = val;
1598 } else if (!strcasecmp(var, "at_indicator_lowbattchg_string")) {
1599 at_indicator_lowbattchg_string = val;
1600 } else if (!strcasecmp(var, "at_indicator_nobattchg_string")) {
1601 at_indicator_nobattchg_string = val;
1602 } else if (!strcasecmp(var, "at_indicator_callactive_string")) {
1603 at_indicator_callactive_string = val;
1604 } else if (!strcasecmp(var, "at_indicator_nocallactive_string")) {
1605 at_indicator_nocallactive_string = val;
1606 } else if (!strcasecmp(var, "at_indicator_nocallsetup_string")) {
1607 at_indicator_nocallsetup_string = val;
1608 } else if (!strcasecmp(var, "at_indicator_callsetupincoming_string")) {
1609 at_indicator_callsetupincoming_string = val;
1610 } else if (!strcasecmp(var, "at_indicator_callsetupoutgoing_string")) {
1611 at_indicator_callsetupoutgoing_string = val;
1612 } else if (!strcasecmp(var, "at_indicator_callsetupremoteringing_string")) {
1613 at_indicator_callsetupremoteringing_string = val;
1614 //} else if (!strcasecmp(var, "sms_receiving_program")) {
1615 //sms_receiving_program = val;
1616 } else if (!strcasecmp(var, "alsacname")) {
1617 alsacname = val;
1618 } else if (!strcasecmp(var, "alsapname")) {
1619 alsapname = val;
1620 #ifdef GSMOPEN_PORTAUDIO
1621 } else if (!strcasecmp(var, "portaudiocindex")) {
1622 portaudiocindex = val;
1623 } else if (!strcasecmp(var, "portaudiopindex")) {
1624 portaudiopindex = val;
1625 } else if (!strcasecmp(var, "speexecho")) {
1626 speexecho = val;
1627 } else if (!strcasecmp(var, "speexpreprocess")) {
1628 speexpreprocess = val;
1629 #endif// GSMOPEN_PORTAUDIO
1630 } else if (!strcasecmp(var, "at_early_audio")) {
1631 at_early_audio = val;
1632 } else if (!strcasecmp(var, "at_after_preinit_pause")) {
1633 at_after_preinit_pause = val;
1634 } else if (!strcasecmp(var, "at_initial_pause")) {
1635 at_initial_pause = val;
1636 } else if (!strcasecmp(var, "at_has_clcc")) {
1637 at_has_clcc = val;
1638 } else if (!strcasecmp(var, "at_has_ecam")) {
1639 at_has_ecam = val;
1640 } else if (!strcasecmp(var, "alsa_period_size")) {
1641 alsa_period_size = val;
1642 } else if (!strcasecmp(var, "alsa_periods_in_buffer")) {
1643 alsa_periods_in_buffer = val;
1644 } else if (!strcasecmp(var, "gsmopen_sound_rate")) {
1645 gsmopen_sound_rate = val;
1646 } else if (!strcasecmp(var, "alsa_play_is_mono")) {
1647 alsa_play_is_mono = val;
1648 } else if (!strcasecmp(var, "alsa_capture_is_mono")) {
1649 alsa_capture_is_mono = val;
1650 } else if (!strcasecmp(var, "capture_boost")) {
1651 capture_boost = val;
1652 } else if (!strcasecmp(var, "playback_boost")) {
1653 playback_boost = val;
1654 } else if (!strcasecmp(var, "no_sound")) {
1655 no_sound = val;
1656 } else if (!strcasecmp(var, "gsmopen_serial_sync_period")) {
1657 gsmopen_serial_sync_period = val;
1658 }
1659
1660
1661 }
1662
1663 /* BEGIN: Changes here */
1664 if (reload_type == SOFT_RELOAD) {
1665 char the_interface[256];
1666 sprintf(the_interface, "#%s", name);
1667
1668 if (interface_exists(the_interface) == SWITCH_STATUS_SUCCESS) {
1669 continue;
1670 }
1671 }
1672 /* END: Changes here */
1673
1674 if (!id) {
1675 ERRORA("interface missing REQUIRED param 'id'\n", GSMOPEN_P_LOG);
1676 continue;
1677 }
1678
1679 if (switch_is_number(id)) {
1680 interface_id = atoi(id);
1681 } else {
1682 ERRORA("interface param 'id' MUST be a number, now id='%s'\n", GSMOPEN_P_LOG, id);
1683 continue;
1684 }
1685
1686 if (!switch_is_number(at_early_audio)) {
1687 ERRORA("interface param 'at_early_audio' MUST be a number, now at_early_audio='%s'\n", GSMOPEN_P_LOG, at_early_audio);
1688 continue;
1689 }
1690 if (!switch_is_number(at_after_preinit_pause)) {
1691 ERRORA("interface param 'at_after_preinit_pause' MUST be a number, now at_after_preinit_pause='%s'\n", GSMOPEN_P_LOG,
1692 at_after_preinit_pause);
1693 continue;
1694 }
1695 if (!switch_is_number(at_initial_pause)) {
1696 ERRORA("interface param 'at_initial_pause' MUST be a number, now at_initial_pause='%s'\n", GSMOPEN_P_LOG, at_initial_pause);
1697 continue;
1698 }
1699 if (!switch_is_number(at_has_clcc)) {
1700 ERRORA("interface param 'at_has_clcc' MUST be a number, now at_has_clcc='%s'\n", GSMOPEN_P_LOG, at_has_clcc);
1701 continue;
1702 }
1703 if (!switch_is_number(at_has_ecam)) {
1704 ERRORA("interface param 'at_has_ecam' MUST be a number, now at_has_ecam='%s'\n", GSMOPEN_P_LOG, at_has_ecam);
1705 continue;
1706 }
1707 if (!switch_is_number(alsa_period_size)) {
1708 ERRORA("interface param 'alsa_period_size' MUST be a number, now alsa_period_size='%s'\n", GSMOPEN_P_LOG, alsa_period_size);
1709 continue;
1710 }
1711 if (!switch_is_number(alsa_periods_in_buffer)) {
1712 ERRORA("interface param 'alsa_periods_in_buffer' MUST be a number, now alsa_periods_in_buffer='%s'\n", GSMOPEN_P_LOG,
1713 alsa_periods_in_buffer);
1714 continue;
1715 }
1716 if (!switch_is_number(gsmopen_sound_rate)) {
1717 ERRORA("interface param 'gsmopen_sound_rate' MUST be a number, now gsmopen_sound_rate='%s'\n", GSMOPEN_P_LOG, gsmopen_sound_rate);
1718 continue;
1719 }
1720 if (!switch_is_number(alsa_play_is_mono)) {
1721 ERRORA("interface param 'alsa_play_is_mono' MUST be a number, now alsa_play_is_mono='%s'\n", GSMOPEN_P_LOG, alsa_play_is_mono);
1722 continue;
1723 }
1724 if (!switch_is_number(alsa_capture_is_mono)) {
1725 ERRORA("interface param 'alsa_capture_is_mono' MUST be a number, now alsa_capture_is_mono='%s'\n", GSMOPEN_P_LOG, alsa_capture_is_mono);
1726 continue;
1727 }
1728 if (!switch_is_number(capture_boost)) {
1729 ERRORA("interface param 'capture_boost' MUST be a number, now capture_boost='%s'\n", GSMOPEN_P_LOG, capture_boost);
1730 continue;
1731 }
1732 if (!switch_is_number(playback_boost)) {
1733 ERRORA("interface param 'playback_boost' MUST be a number, now playback_boost='%s'\n", GSMOPEN_P_LOG, playback_boost);
1734 continue;
1735 }
1736 if (!switch_is_number(no_sound)) {
1737 ERRORA("interface param 'no_sound' MUST be a number, now no_sound='%s'\n", GSMOPEN_P_LOG, no_sound);
1738 continue;
1739 }
1740 if (!switch_is_number(gsmopen_serial_sync_period)) {
1741 ERRORA("interface param 'gsmopen_serial_sync_period' MUST be a number, now gsmopen_serial_sync_period='%s'\n", GSMOPEN_P_LOG, gsmopen_serial_sync_period);
1742 continue;
1743 }
1744
1745
1746 if (interface_id && interface_id < GSMOPEN_MAX_INTERFACES) {
1747 private_t newconf;
1748 switch_threadattr_t *gsmopen_api_thread_attr = NULL;
1749 int res = 0;
1750
1751 memset(&newconf, '\0', sizeof(newconf));
1752 globals.GSMOPEN_INTERFACES[interface_id] = newconf;
1753
1754
1755 tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id];
1756
1757 switch_mutex_init(&globals.GSMOPEN_INTERFACES[interface_id].controldev_lock, SWITCH_MUTEX_NESTED, gsmopen_module_pool);
1758
1759
1760 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].id, id);
1761 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].name, name);
1762 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].context, context);
1763 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].dialplan, dialplan);
1764 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].destination, destination);
1765 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].controldevice_name, controldevice_name);
1766 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].dial_regex, dial_regex);
1767 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].hold_music, hold_music);
1768 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].fail_dial_regex, fail_dial_regex);
1769 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_pre_number, at_dial_pre_number);
1770 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_post_number, at_dial_post_number);
1771 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_dial_expect, at_dial_expect);
1772 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_hangup, at_hangup);
1773 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_hangup_expect, at_hangup_expect);
1774 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_answer, at_answer);
1775 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_answer_expect, at_answer_expect);
1776 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_send_dtmf, at_send_dtmf);
1777 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_1, at_preinit_1);
1778 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_1_expect, at_preinit_1_expect);
1779 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_2, at_preinit_2);
1780 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_2_expect, at_preinit_2_expect);
1781 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_3, at_preinit_3);
1782 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_3_expect, at_preinit_3_expect);
1783 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_4, at_preinit_4);
1784 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_4_expect, at_preinit_4_expect);
1785 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_5, at_preinit_5);
1786 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_preinit_5_expect, at_preinit_5_expect);
1787 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_1, at_postinit_1);
1788 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_1_expect, at_postinit_1_expect);
1789 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_2, at_postinit_2);
1790 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_2_expect, at_postinit_2_expect);
1791 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_3, at_postinit_3);
1792 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_3_expect, at_postinit_3_expect);
1793 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_4, at_postinit_4);
1794 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_4_expect, at_postinit_4_expect);
1795 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_5, at_postinit_5);
1796 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_postinit_5_expect, at_postinit_5_expect);
1797 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_battchg, at_query_battchg);
1798 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_battchg_expect, at_query_battchg_expect);
1799 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_signal, at_query_signal);
1800 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_query_signal_expect, at_query_signal_expect);
1801 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_idle, at_call_idle);
1802 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_incoming, at_call_incoming);
1803 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_active, at_call_active);
1804 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_failed, at_call_failed);
1805 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_call_calling, at_call_calling);
1806 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_noservice_string, at_indicator_noservice_string);
1807 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nosignal_string, at_indicator_nosignal_string);
1808 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_lowsignal_string, at_indicator_lowsignal_string);
1809 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_lowbattchg_string, at_indicator_lowbattchg_string);
1810 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nobattchg_string, at_indicator_nobattchg_string);
1811 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callactive_string, at_indicator_callactive_string);
1812 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nocallactive_string, at_indicator_nocallactive_string);
1813 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_nocallsetup_string, at_indicator_nocallsetup_string);
1814 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupincoming_string, at_indicator_callsetupincoming_string);
1815 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupoutgoing_string, at_indicator_callsetupoutgoing_string);
1816 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].at_indicator_callsetupremoteringing_string,
1817 at_indicator_callsetupremoteringing_string);
1818 //switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].sms_receiving_program, sms_receiving_program);
1819 #ifdef GSMOPEN_ALSA
1820 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].alsacname, alsacname);
1821 switch_set_string(globals.GSMOPEN_INTERFACES[interface_id].alsapname, alsapname);
1822 #endif// GSMOPEN_ALSA
1823
1824 #ifdef GSMOPEN_PORTAUDIO
1825 globals.GSMOPEN_INTERFACES[interface_id].portaudiocindex = atoi(portaudiocindex);
1826 globals.GSMOPEN_INTERFACES[interface_id].portaudiopindex = atoi(portaudiopindex);
1827 globals.GSMOPEN_INTERFACES[interface_id].speexecho = atoi(speexecho);
1828 globals.GSMOPEN_INTERFACES[interface_id].speexpreprocess = atoi(speexpreprocess);
1829 #endif// GSMOPEN_PORTAUDIO
1830 globals.GSMOPEN_INTERFACES[interface_id].at_early_audio = atoi(at_early_audio);
1831 globals.GSMOPEN_INTERFACES[interface_id].at_after_preinit_pause = atoi(at_after_preinit_pause);
1832 globals.GSMOPEN_INTERFACES[interface_id].at_initial_pause = atoi(at_initial_pause);
1833 globals.GSMOPEN_INTERFACES[interface_id].at_has_clcc = atoi(at_has_clcc);
1834 globals.GSMOPEN_INTERFACES[interface_id].at_has_ecam = atoi(at_has_ecam);
1835 #ifdef GSMOPEN_ALSA
1836 globals.GSMOPEN_INTERFACES[interface_id].alsa_period_size = atoi(alsa_period_size);
1837 globals.GSMOPEN_INTERFACES[interface_id].alsa_periods_in_buffer = atoi(alsa_periods_in_buffer);
1838 globals.GSMOPEN_INTERFACES[interface_id].gsmopen_sound_rate = atoi(gsmopen_sound_rate);
1839 globals.GSMOPEN_INTERFACES[interface_id].alsa_play_is_mono = atoi(alsa_play_is_mono);
1840 globals.GSMOPEN_INTERFACES[interface_id].alsa_capture_is_mono = atoi(alsa_capture_is_mono);
1841 #endif// GSMOPEN_ALSA
1842 globals.GSMOPEN_INTERFACES[interface_id].capture_boost = atoi(capture_boost);
1843 globals.GSMOPEN_INTERFACES[interface_id].playback_boost = atoi(playback_boost);
1844 #if defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
1845 globals.GSMOPEN_INTERFACES[interface_id].no_sound = atoi(no_sound);
1846 #else
1847 globals.GSMOPEN_INTERFACES[interface_id].no_sound = 1;
1848 #endif // defined(GSMOPEN_ALSA) || defined(GSMOPEN_PORTAUDIO)
1849 globals.GSMOPEN_INTERFACES[interface_id].gsmopen_serial_sync_period = atoi(gsmopen_serial_sync_period);
1850
1851
1852
1853 globals.GSMOPEN_INTERFACES[interface_id].controldevice_speed = controldevice_speed; //FIXME
1854 globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol = controldevprotocol; //FIXME
1855 globals.GSMOPEN_INTERFACES[interface_id].running = running; //FIXME
1856
1857
1858
1859 WARNINGA("STARTING interface_id=%d\n", GSMOPEN_P_LOG, interface_id);
1860 DEBUGA_GSMOPEN("id=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].id);
1861 DEBUGA_GSMOPEN("name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].name);
1862 DEBUGA_GSMOPEN("hold-music=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].hold_music);
1863 DEBUGA_GSMOPEN("context=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].context);
1864 DEBUGA_GSMOPEN("dialplan=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].dialplan);
1865 DEBUGA_GSMOPEN("destination=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].destination);
1866 DEBUGA_GSMOPEN("controldevice_name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].controldevice_name);
1867 #ifdef GSMOPEN_ALSA
1868 DEBUGA_GSMOPEN("alsacname=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].alsacname);
1869 DEBUGA_GSMOPEN("alsapname=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].alsapname);
1870 #endif// GSMOPEN_ALSA
1871
1872
1873 #ifdef GSMOPEN_PORTAUDIO
1874 //FIXME
1875 //globals.GSMOPEN_INTERFACES[interface_id].portaudiocindex = 1;
1876 //globals.GSMOPEN_INTERFACES[interface_id].portaudiopindex = 1;
1877 //globals.GSMOPEN_INTERFACES[interface_id].speexecho = 1;
1878 //globals.GSMOPEN_INTERFACES[interface_id].speexpreprocess = 1;
1879 DEBUGA_GSMOPEN("portaudiocindex=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].portaudiocindex);
1880 DEBUGA_GSMOPEN("portaudiocindex=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].portaudiocindex);
1881 DEBUGA_GSMOPEN("speexecho=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].speexecho);
1882 DEBUGA_GSMOPEN("speexpreprocess=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[interface_id].speexpreprocess);
1883 #endif// GSMOPEN_PORTAUDIO
1884 DEBUGA_GSMOPEN("gsmopen_serial_sync_period=%d\n", GSMOPEN_P_LOG, (int)globals.GSMOPEN_INTERFACES[interface_id].gsmopen_serial_sync_period);
1885 /* init the serial port */
1886 if (globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol != PROTOCOL_NO_SERIAL) {
1887 globals.GSMOPEN_INTERFACES[interface_id].controldevfd =
1888 gsmopen_serial_init(&globals.GSMOPEN_INTERFACES[interface_id], globals.GSMOPEN_INTERFACES[interface_id].controldevice_speed);
1889 if (globals.GSMOPEN_INTERFACES[interface_id].controldevfd == -1) {
1890 ERRORA("gsmopen_serial_init failed\n", GSMOPEN_P_LOG);
1891 ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id);
1892 //return SWITCH_STATUS_FALSE;
1893 globals.GSMOPEN_INTERFACES[interface_id].running=0;
1894 alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_serial_init failed");
1895 globals.GSMOPEN_INTERFACES[interface_id].active=0;
1896 globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0';
1897 continue;
1898 }
1899 }
1900
1901 /* config the phone/modem on the serial port */
1902 if (globals.GSMOPEN_INTERFACES[interface_id].controldevprotocol != PROTOCOL_NO_SERIAL) {
1903 res = gsmopen_serial_config(&globals.GSMOPEN_INTERFACES[interface_id]);
1904 if (res) {
1905 int count = 0;
1906 ERRORA("gsmopen_serial_config failed, let's try again\n", GSMOPEN_P_LOG);
1907 while(res && count < 5){
1908 switch_sleep(100000); //0.1 seconds
1909 res = gsmopen_serial_config(&globals.GSMOPEN_INTERFACES[interface_id]);
1910 count++;
1911 if (res) {
1912 ERRORA("%d: gsmopen_serial_config failed, let's try again\n", GSMOPEN_P_LOG, count);
1913 }
1914 }
1915 if (res) {
1916 ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id);
1917 //return SWITCH_STATUS_FALSE;
1918 globals.GSMOPEN_INTERFACES[interface_id].running=0;
1919 alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_serial_config failed");
1920 globals.GSMOPEN_INTERFACES[interface_id].active=0;
1921 globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0';
1922 continue;
1923 }
1924 }
1925 }
1926
1927 if(globals.GSMOPEN_INTERFACES[interface_id].no_sound==0){
1928 #ifdef GSMOPEN_ALSA
1929 if (alsa_init(&globals.GSMOPEN_INTERFACES[interface_id])) {
1930 ERRORA("alsa_init failed\n", GSMOPEN_P_LOG);
1931 ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id);
1932 //return SWITCH_STATUS_FALSE;
1933 globals.GSMOPEN_INTERFACES[interface_id].running=0;
1934 alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "alsa_init failed");
1935 globals.GSMOPEN_INTERFACES[interface_id].active=0;
1936 globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0';
1937 continue;
1938
1939 }
1940
1941 if (alsa_shutdown(&globals.GSMOPEN_INTERFACES[interface_id])) {
1942 ERRORA("alsa_shutdown failed\n", GSMOPEN_P_LOG);
1943 ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id);
1944 //return SWITCH_STATUS_FALSE;
1945 globals.GSMOPEN_INTERFACES[interface_id].running=0;
1946 alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "alsa_shutdown failed");
1947 globals.GSMOPEN_INTERFACES[interface_id].active=0;
1948 globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0';
1949 continue;
1950
1951 }
1952 #endif// GSMOPEN_ALSA
1953 #ifdef GSMOPEN_PORTAUDIO
1954 if (gsmopen_portaudio_init(&globals.GSMOPEN_INTERFACES[interface_id])) {
1955 ERRORA("gsmopen_portaudio_init failed\n", GSMOPEN_P_LOG);
1956 ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id);
1957 //return SWITCH_STATUS_FALSE;
1958 globals.GSMOPEN_INTERFACES[interface_id].running=0;
1959 alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_portaudio_init failed");
1960 globals.GSMOPEN_INTERFACES[interface_id].active=0;
1961 globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0';
1962 continue;
1963
1964 }
1965
1966 if (gsmopen_portaudio_shutdown(&globals.GSMOPEN_INTERFACES[interface_id])) {
1967 ERRORA("gsmopen_portaudio_shutdown failed\n", GSMOPEN_P_LOG);
1968 ERRORA("STARTING interface_id=%d FAILED\n", GSMOPEN_P_LOG, interface_id);
1969 //return SWITCH_STATUS_FALSE;
1970 globals.GSMOPEN_INTERFACES[interface_id].running=0;
1971 alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "gsmopen_portaudio_shutdown failed");
1972 globals.GSMOPEN_INTERFACES[interface_id].active=0;
1973 globals.GSMOPEN_INTERFACES[interface_id].name[0]='\0';
1974 continue;
1975
1976 }
1977 #endif// GSMOPEN_PORTAUDIO
1978 }
1979
1980 globals.GSMOPEN_INTERFACES[interface_id].active=1;
1981
1982 //gsmopen_store_boost((char *)"5", &globals.GSMOPEN_INTERFACES[interface_id].capture_boost); //FIXME
1983 //gsmopen_store_boost((char *)"10", &globals.GSMOPEN_INTERFACES[interface_id].playback_boost); //FIXME
1984 gsmopen_store_boost((char *) capture_boost, &globals.GSMOPEN_INTERFACES[interface_id].capture_boost); //FIXME
1985 gsmopen_store_boost((char *) playback_boost, &globals.GSMOPEN_INTERFACES[interface_id].playback_boost); //FIXME
1986
1987 switch_sleep(100000);
1988 switch_threadattr_create(&gsmopen_api_thread_attr, gsmopen_module_pool);
1989 switch_threadattr_stacksize_set(gsmopen_api_thread_attr, SWITCH_THREAD_STACKSIZE);
1990 switch_thread_create(&globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread, gsmopen_api_thread_attr, gsmopen_do_gsmopenapi_thread,
1991 &globals.GSMOPEN_INTERFACES[interface_id], gsmopen_module_pool);
1992
1993 switch_sleep(100000);
1994 WARNINGA("STARTED interface_id=%d\n", GSMOPEN_P_LOG, interface_id);
1995
1996 } else {
1997 ERRORA("interface id %d is higher than GSMOPEN_MAX_INTERFACES (%d)\n", GSMOPEN_P_LOG, interface_id, GSMOPEN_MAX_INTERFACES);
1998 alarm_event(&globals.GSMOPEN_INTERFACES[interface_id], ALARM_FAILED_INTERFACE, "interface id is higher than GSMOPEN_MAX_INTERFACES");
1999 continue;
2000 }
2001
2002 }
2003
2004 for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) {
2005 if (strlen(globals.GSMOPEN_INTERFACES[i].name)) {
2006 /* How many real intterfaces */
2007 globals.real_interfaces = i + 1;
2008
2009 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
2010
2011 DEBUGA_GSMOPEN("id=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].id);
2012 DEBUGA_GSMOPEN("name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].name);
2013 DEBUGA_GSMOPEN("context=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].context);
2014 DEBUGA_GSMOPEN("hold-music=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].hold_music);
2015 DEBUGA_GSMOPEN("dialplan=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].dialplan);
2016 DEBUGA_GSMOPEN("destination=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].destination);
2017 DEBUGA_GSMOPEN("controldevice_name=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].controldevice_name);
2018 #ifdef GSMOPEN_ALSA
2019 DEBUGA_GSMOPEN("alsacname=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].alsacname);
2020 DEBUGA_GSMOPEN("alsapname=%s\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].alsapname);
2021 #endif// GSMOPEN_ALSA
2022 #ifdef GSMOPEN_PORTAUDIO
2023 DEBUGA_GSMOPEN("portaudiocindex=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].portaudiocindex);
2024 DEBUGA_GSMOPEN("portaudiopindex=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].portaudiopindex);
2025 DEBUGA_GSMOPEN("speexecho=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].speexecho);
2026 DEBUGA_GSMOPEN("speexpreprocess=%d\n", GSMOPEN_P_LOG, globals.GSMOPEN_INTERFACES[i].speexpreprocess);
2027 #endif// GSMOPEN_PORTAUDIO
2028 DEBUGA_GSMOPEN("gsmopen_serial_sync_period=%d\n", GSMOPEN_P_LOG, (int)globals.GSMOPEN_INTERFACES[i].gsmopen_serial_sync_period);
2029
2030 }
2031 }
2032 }
2033
2034 switch_mutex_unlock(globals.mutex);
2035 switch_xml_free(xml);
2036
2037 return SWITCH_STATUS_SUCCESS;
2038 }
2039
2040 //static switch_status_t chat_send(const char *proto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint)
chat_send(switch_event_t * message_event)2041 static switch_status_t chat_send(switch_event_t *message_event)
2042 {
2043 char *user, *host, *f_user = NULL, *f_host = NULL, *f_resource = NULL;
2044 private_t *tech_pvt = NULL;
2045 int i = 0, found = 0;
2046
2047 const char *proto;
2048 const char *from;
2049 const char *to;
2050 const char *subject;
2051 const char *body;
2052 //const char *type;
2053 const char *hint;
2054
2055 proto = switch_event_get_header(message_event, "proto");
2056 from = switch_event_get_header(message_event, "from");
2057 to = switch_event_get_header(message_event, "to");
2058 subject = switch_event_get_header(message_event, "subject");
2059 body = switch_event_get_body(message_event);
2060 //type = switch_event_get_header(message_event, "type");
2061 hint = switch_event_get_header(message_event, "hint");
2062
2063 switch_assert(proto != NULL);
2064
2065 DEBUGA_GSMOPEN("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", GSMOPEN_P_LOG, proto, from, to, subject, body,
2066 hint ? hint : "NULL");
2067
2068 if (!to || !strlen(to)) {
2069 ERRORA("Missing To: header.\n", GSMOPEN_P_LOG);
2070 return SWITCH_STATUS_SUCCESS;
2071 }
2072
2073 if ((!from && !hint) || (!strlen(from) && !strlen(hint))) {
2074 ERRORA("Missing From: AND Hint: headers.\n", GSMOPEN_P_LOG);
2075 return SWITCH_STATUS_SUCCESS;
2076 }
2077
2078 if (from && (f_user = strdup(from))) {
2079 if ((f_host = strchr(f_user, '@'))) {
2080 *f_host++ = '\0';
2081 if ((f_resource = strchr(f_host, '/'))) {
2082 *f_resource++ = '\0';
2083 }
2084 }
2085 }
2086
2087 if (!strlen(hint)) { //FIXME FIXME FIXME
2088 hint = from;
2089 }
2090 if (to && (user = strdup(to))) {
2091 if ((host = strchr(user, '@'))) {
2092 *host++ = '\0';
2093 }
2094
2095 DEBUGA_GSMOPEN("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, hint=%s)\n", GSMOPEN_P_LOG, proto, from, to, subject, body,
2096 hint ? hint : "NULL");
2097 if (hint && strlen(hint)) {
2098 //in hint we receive the interface name to use
2099 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
2100 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
2101 && (strncmp(globals.GSMOPEN_INTERFACES[i].name, hint, strlen(hint)) == 0)) {
2102 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
2103 DEBUGA_GSMOPEN("Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", GSMOPEN_P_LOG, i,
2104 globals.GSMOPEN_INTERFACES[i].name);
2105 found = 1;
2106 break;
2107 }
2108 }
2109 } /* FIXME add a tech_pvt member for the SIM telephone number //else {
2110 //we have no a predefined interface name to use (hint is NULL), so let's choose an interface from the username (from)
2111 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
2112 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
2113 && (strncmp(globals.GSMOPEN_INTERFACES[i].skype_user, from, strlen(from)) == 0)) {
2114 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
2115 DEBUGA_GSMOPEN("Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", GSMOPEN_P_LOG, i, globals.GSMOPEN_INTERFACES[i].name);
2116 found = 1;
2117 break;
2118 }
2119 }
2120 }
2121 */
2122 if (!found) {
2123 ERRORA("ERROR: A GSMopen interface with name='%s' or one with SIM_number='%s' was not found\n", GSMOPEN_P_LOG, hint ? hint : "NULL",
2124 from ? from : "NULL");
2125 goto end;
2126 } else {
2127 gsmopen_sendsms(tech_pvt, (char *) to, (char *) body);
2128 }
2129 }
2130 end:
2131 switch_safe_free(user);
2132 switch_safe_free(f_user);
2133 return SWITCH_STATUS_SUCCESS;
2134 }
2135
compat_chat_send(const char * proto,const char * from,const char * to,const char * subject,const char * body,const char * type,const char * hint)2136 static switch_status_t compat_chat_send(const char *proto, const char *from, const char *to,
2137 const char *subject, const char *body, const char *type, const char *hint)
2138 {
2139 switch_event_t *message_event;
2140 switch_status_t status;
2141
2142 if (switch_event_create(&message_event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
2143 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "proto", proto);
2144 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "from", from);
2145 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "to", to);
2146 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "subject", subject);
2147 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "type", type);
2148 switch_event_add_header_string(message_event, SWITCH_STACK_BOTTOM, "hint", hint);
2149
2150 if (body) {
2151 switch_event_add_body(message_event, "%s", body);
2152 }
2153 } else {
2154 abort();
2155 }
2156
2157 status = chat_send(message_event);
2158 switch_event_destroy(&message_event);
2159
2160 return status;
2161
2162 }
2163
SWITCH_MODULE_LOAD_FUNCTION(mod_gsmopen_load)2164 SWITCH_MODULE_LOAD_FUNCTION(mod_gsmopen_load)
2165 {
2166 switch_api_interface_t *commands_api_interface;
2167 switch_chat_interface_t *chat_interface;
2168
2169 gsmopen_module_pool = pool;
2170 memset(&globals, '\0', sizeof(globals));
2171
2172 running = 1;
2173
2174 if (load_config(FULL_RELOAD) != SWITCH_STATUS_SUCCESS) {
2175 running = 0;
2176 return SWITCH_STATUS_FALSE;
2177 }
2178
2179 if (switch_event_reserve_subclass(MY_EVENT_INCOMING_SMS) != SWITCH_STATUS_SUCCESS) {
2180 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
2181 return SWITCH_STATUS_GENERR;
2182 }
2183
2184 *module_interface = switch_loadable_module_create_module_interface(pool, modname);
2185 gsmopen_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
2186 gsmopen_endpoint_interface->interface_name = "gsmopen";
2187 gsmopen_endpoint_interface->io_routines = &gsmopen_io_routines;
2188 gsmopen_endpoint_interface->state_handler = &gsmopen_state_handlers;
2189
2190 if (running) {
2191
2192 #if 1
2193 SWITCH_ADD_API(commands_api_interface, "gsm", "gsm console AT_command", gsm_function, GSM_SYNTAX);
2194 SWITCH_ADD_API(commands_api_interface, "gsmopen", "gsmopen interface AT_command", gsmopen_function, GSMOPEN_SYNTAX);
2195 #endif //0
2196 SWITCH_ADD_API(commands_api_interface, "gsmopen_boost_audio", "gsmopen_boost_audio interface AT_command", gsmopen_boost_audio_function, GSMOPEN_BOOST_AUDIO_SYNTAX);
2197 SWITCH_ADD_API(commands_api_interface, "gsmopen_dump", "gsmopen_dump interface", gsmopen_dump_function, GSMOPEN_DUMP_SYNTAX);
2198 SWITCH_ADD_API(commands_api_interface, "gsmopen_sendsms", "gsmopen_sendsms interface destination_number SMS_text", sendsms_function,
2199 SENDSMS_SYNTAX);
2200 SWITCH_ADD_CHAT(chat_interface, GSMOPEN_CHAT_PROTO, chat_send);
2201
2202 /* indicate that the module should continue to be loaded */
2203 return SWITCH_STATUS_SUCCESS;
2204 } else
2205 return SWITCH_STATUS_FALSE;
2206 }
2207
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_gsmopen_shutdown)2208 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_gsmopen_shutdown)
2209 {
2210 int x;
2211 private_t *tech_pvt = NULL;
2212 switch_status_t status;
2213 unsigned int howmany = 8;
2214 int interface_id;
2215 int fd;
2216
2217 running = 0;
2218
2219 for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) {
2220 tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id];
2221
2222 if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) {
2223 WARNINGA("SHUTDOWN interface_id=%d\n", GSMOPEN_P_LOG, interface_id);
2224 globals.GSMOPEN_INTERFACES[interface_id].running = 0;
2225 if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) {
2226 #ifdef WIN32
2227 switch_file_write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", &howmany); // let's the controldev_thread die
2228 #else /* WIN32 */
2229 howmany = write(tech_pvt->GSMopenHandles.fdesc[1], "sciutati", howmany);
2230 #endif /* WIN32 */
2231 }
2232 x = 10;
2233 while (x) { //FIXME 0.5 seconds?
2234 x--;
2235 switch_yield(50000);
2236 }
2237 if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread) {
2238 switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_signaling_thread);
2239 }
2240 if (globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread) {
2241 switch_thread_join(&status, globals.GSMOPEN_INTERFACES[interface_id].gsmopen_api_thread);
2242 }
2243
2244 x = 10;
2245 while (x) { //FIXME 0.5 seconds?
2246 x--;
2247 switch_yield(50000);
2248 }
2249 fd = tech_pvt->controldevfd;
2250 //DEBUGA_GSMOPEN("SHUTDOWN tech_pvt->controldevfd=%d\n", GSMOPEN_P_LOG, tech_pvt->controldevfd);
2251 if (fd) {
2252 //close(fd);
2253 //tech_pvt->controldevfd = -1;
2254 DEBUGA_GSMOPEN("SHUTDOWN tech_pvt->controldevfd=%d\n", GSMOPEN_P_LOG, tech_pvt->controldevfd);
2255 }
2256 #ifndef WIN32
2257 shutdown(tech_pvt->audiogsmopenpipe[0], 2);
2258 close(tech_pvt->audiogsmopenpipe[0]);
2259 shutdown(tech_pvt->audiogsmopenpipe[1], 2);
2260 close(tech_pvt->audiogsmopenpipe[1]);
2261 shutdown(tech_pvt->audiopipe[0], 2);
2262 close(tech_pvt->audiopipe[0]);
2263 shutdown(tech_pvt->audiopipe[1], 2);
2264 close(tech_pvt->audiopipe[1]);
2265 shutdown(tech_pvt->GSMopenHandles.fdesc[0], 2);
2266 close(tech_pvt->GSMopenHandles.fdesc[0]);
2267 shutdown(tech_pvt->GSMopenHandles.fdesc[1], 2);
2268 close(tech_pvt->GSMopenHandles.fdesc[1]);
2269 #endif /* WIN32 */
2270 }
2271
2272 }
2273
2274 switch_event_free_subclass(MY_EVENT_INCOMING_SMS);
2275
2276 switch_safe_free(globals.dialplan);
2277 switch_safe_free(globals.context);
2278 switch_safe_free(globals.destination);
2279 switch_safe_free(globals.codec_string);
2280 switch_safe_free(globals.codec_rates_string);
2281
2282 return SWITCH_STATUS_SUCCESS;
2283 }
2284
2285
gsmopen_do_gsmopenapi_thread(switch_thread_t * thread,void * obj)2286 void *SWITCH_THREAD_FUNC gsmopen_do_gsmopenapi_thread(switch_thread_t * thread, void *obj)
2287 {
2288 return gsmopen_do_gsmopenapi_thread_func(obj);
2289 }
2290
dtmf_received(private_t * tech_pvt,char * value)2291 int dtmf_received(private_t * tech_pvt, char *value)
2292 {
2293 switch_core_session_t *session = NULL;
2294 switch_channel_t *channel = NULL;
2295
2296 session = switch_core_session_locate(tech_pvt->session_uuid_str);
2297 channel = switch_core_session_get_channel(session);
2298
2299 if (channel) {
2300
2301 if (!switch_channel_test_flag(channel, CF_BRIDGED)) {
2302
2303 switch_dtmf_t dtmf = { (char) value[0], switch_core_default_dtmf_duration(0) };
2304 DEBUGA_GSMOPEN("received DTMF %c on channel %s\n", GSMOPEN_P_LOG, dtmf.digit, switch_channel_get_name(channel));
2305 switch_mutex_lock(tech_pvt->flag_mutex);
2306 //FIXME: why sometimes DTMFs from here do not seems to be get by FS?
2307 switch_channel_queue_dtmf(channel, &dtmf);
2308 switch_set_flag(tech_pvt, TFLAG_DTMF);
2309 switch_mutex_unlock(tech_pvt->flag_mutex);
2310 } else {
2311 DEBUGA_GSMOPEN
2312 ("received a DTMF on channel %s, but we're BRIDGED, so let's NOT relay it out of band\n", GSMOPEN_P_LOG, switch_channel_get_name(channel));
2313 }
2314 } else {
2315 WARNINGA("received %c DTMF, but no channel?\n", GSMOPEN_P_LOG, value[0]);
2316 }
2317 switch_core_session_rwunlock(session);
2318
2319 return 0;
2320 }
2321
new_inbound_channel(private_t * tech_pvt)2322 int new_inbound_channel(private_t * tech_pvt)
2323 {
2324 switch_core_session_t *session = NULL;
2325 switch_channel_t *channel = NULL;
2326
2327 switch_assert(tech_pvt != NULL);
2328 tech_pvt->ib_calls++;
2329 if ((session = switch_core_session_request(gsmopen_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL)) != 0) {
2330 DEBUGA_GSMOPEN("2 SESSION_REQUEST %s\n", GSMOPEN_P_LOG, switch_core_session_get_uuid(session));
2331 switch_core_session_add_stream(session, NULL);
2332 channel = switch_core_session_get_channel(session);
2333 if (!channel) {
2334 ERRORA("Doh! no channel?\n", GSMOPEN_P_LOG);
2335 switch_core_session_destroy(&session);
2336 return 0;
2337 }
2338 if (gsmopen_tech_init(tech_pvt, session) != SWITCH_STATUS_SUCCESS) {
2339 ERRORA("Doh! no tech_init?\n", GSMOPEN_P_LOG);
2340 switch_core_session_destroy(&session);
2341 return 0;
2342 }
2343
2344 if ((tech_pvt->caller_profile =
2345 switch_caller_profile_new(switch_core_session_get_pool(session), "gsmopen",
2346 tech_pvt->dialplan, tech_pvt->callid_name,
2347 tech_pvt->callid_number, NULL, NULL, NULL, NULL, "mod_gsmopen", tech_pvt->context, tech_pvt->destination)) != 0) {
2348 char name[128];
2349 //switch_snprintf(name, sizeof(name), "gsmopen/%s/%s", tech_pvt->name, tech_pvt->caller_profile->destination_number);
2350 switch_snprintf(name, sizeof(name), "gsmopen/%s", tech_pvt->name);
2351 switch_channel_set_name(channel, name);
2352 switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
2353 }
2354 switch_channel_set_state(channel, CS_INIT);
2355 if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
2356 ERRORA("Error spawning thread\n", GSMOPEN_P_LOG);
2357 switch_core_session_destroy(&session);
2358 return 0;
2359 }
2360 }
2361 if (channel) {
2362 //switch_channel_mark_answered(channel);
2363 }
2364
2365 DEBUGA_GSMOPEN("new_inbound_channel\n", GSMOPEN_P_LOG);
2366
2367 return 0;
2368 }
2369
remote_party_is_ringing(private_t * tech_pvt)2370 int remote_party_is_ringing(private_t * tech_pvt)
2371 {
2372 switch_core_session_t *session = NULL;
2373 switch_channel_t *channel = NULL;
2374
2375 if (!zstr(tech_pvt->session_uuid_str)) {
2376 session = switch_core_session_locate(tech_pvt->session_uuid_str);
2377 } else {
2378 ERRORA("No session???\n", GSMOPEN_P_LOG);
2379 goto done;
2380 }
2381 if (session) {
2382 channel = switch_core_session_get_channel(session);
2383 } else {
2384 ERRORA("No session???\n", GSMOPEN_P_LOG);
2385 goto done;
2386 }
2387 if (channel) {
2388 switch_channel_mark_ring_ready(channel);
2389 DEBUGA_GSMOPEN("gsmopen_call: REMOTE PARTY RINGING\n", GSMOPEN_P_LOG);
2390 } else {
2391 ERRORA("No channel???\n", GSMOPEN_P_LOG);
2392 }
2393
2394 switch_core_session_rwunlock(session);
2395
2396 done:
2397 return 0;
2398 }
2399
remote_party_is_early_media(private_t * tech_pvt)2400 int remote_party_is_early_media(private_t * tech_pvt)
2401 {
2402 switch_core_session_t *session = NULL;
2403 switch_channel_t *channel = NULL;
2404
2405 if (!zstr(tech_pvt->session_uuid_str)) {
2406 session = switch_core_session_locate(tech_pvt->session_uuid_str);
2407 } else {
2408 ERRORA("No session???\n\n\n", GSMOPEN_P_LOG);
2409 //TODO: kill the bastard
2410 goto done;
2411 }
2412 if (session) {
2413 channel = switch_core_session_get_channel(session);
2414 switch_core_session_add_stream(session, NULL);
2415 } else {
2416 ERRORA("No session???\n", GSMOPEN_P_LOG);
2417 //TODO: kill the bastard
2418 goto done;
2419 }
2420 if (channel) {
2421 switch_channel_mark_pre_answered(channel);
2422 DEBUGA_GSMOPEN("gsmopen_call: REMOTE PARTY EARLY MEDIA\n", GSMOPEN_P_LOG);
2423 } else {
2424 ERRORA("No channel???\n", GSMOPEN_P_LOG);
2425 //TODO: kill the bastard
2426 }
2427
2428 switch_core_session_rwunlock(session);
2429
2430 done:
2431 return 0;
2432 }
2433
outbound_channel_answered(private_t * tech_pvt)2434 int outbound_channel_answered(private_t * tech_pvt)
2435 {
2436 switch_core_session_t *session = NULL;
2437 switch_channel_t *channel = NULL;
2438
2439 if (!zstr(tech_pvt->session_uuid_str)) {
2440 session = switch_core_session_locate(tech_pvt->session_uuid_str);
2441 } else {
2442 ERRORA("No session???\n", GSMOPEN_P_LOG);
2443 goto done;
2444 }
2445 if (session) {
2446 channel = switch_core_session_get_channel(session);
2447 } else {
2448 ERRORA("No channel???\n", GSMOPEN_P_LOG);
2449 goto done;
2450 }
2451 if (channel) {
2452 switch_channel_mark_answered(channel);
2453 tech_pvt->phone_callflow = GSMOPEN_STATE_UP;
2454 tech_pvt->interface_state = GSMOPEN_STATE_UP;
2455 //DEBUGA_GSMOPEN("gsmopen_call: %s, answered\n", GSMOPEN_P_LOG, id);
2456 } else {
2457 ERRORA("No channel???\n", GSMOPEN_P_LOG);
2458 }
2459
2460 switch_core_session_rwunlock(session);
2461
2462 done:
2463 DEBUGA_GSMOPEN("outbound_channel_answered!\n", GSMOPEN_P_LOG);
2464
2465 return 0;
2466 }
2467
find_available_gsmopen_interface_rr(private_t * tech_pvt_calling)2468 private_t *find_available_gsmopen_interface_rr(private_t * tech_pvt_calling)
2469 {
2470 private_t *tech_pvt = NULL;
2471 int i;
2472 //int num_interfaces = GSMOPEN_MAX_INTERFACES;
2473 //int num_interfaces = globals.real_interfaces;
2474
2475 switch_mutex_lock(globals.mutex);
2476
2477 /* Fact is the real interface start from 1 */
2478 //XXX no, is just a convention, but you can have it start from 0. I do not, for aestetic reasons :-)
2479 //if (globals.next_interface == 0) globals.next_interface = 1;
2480
2481 for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) {
2482 int interface_id;
2483
2484 interface_id = globals.next_interface;
2485 //interface_id = interface_id < GSMOPEN_MAX_INTERFACES ? interface_id : interface_id - GSMOPEN_MAX_INTERFACES + 1;
2486 globals.next_interface = interface_id + 1 < GSMOPEN_MAX_INTERFACES ? interface_id + 1 : 0;
2487
2488 if (strlen(globals.GSMOPEN_INTERFACES[interface_id].name)) {
2489 int gsmopen_state = 0;
2490
2491 tech_pvt = &globals.GSMOPEN_INTERFACES[interface_id];
2492 gsmopen_state = tech_pvt->interface_state;
2493 DEBUGA_GSMOPEN("gsmopen interface: %d, name: %s, state: %d\n", GSMOPEN_P_LOG, interface_id, globals.GSMOPEN_INTERFACES[interface_id].name,
2494 gsmopen_state);
2495 if ((tech_pvt_calling ? strcmp(tech_pvt->gsmopen_user, tech_pvt_calling->gsmopen_user) : 1)
2496 && (GSMOPEN_STATE_DOWN == gsmopen_state || 0 == gsmopen_state) && (tech_pvt->phone_callflow == CALLFLOW_STATUS_FINISHED
2497 || 0 == tech_pvt->phone_callflow)) {
2498 DEBUGA_GSMOPEN("returning as available gsmopen interface name: %s, state: %d callflow: %d\n", GSMOPEN_P_LOG, tech_pvt->name, gsmopen_state,
2499 tech_pvt->phone_callflow);
2500 /*set to Dialing state to avoid other thread fint it, don't know if it is safe */
2501 //XXX no, it's not safe
2502 if (tech_pvt_calling == NULL) {
2503 tech_pvt->interface_state = GSMOPEN_STATE_SELECTED;
2504 }
2505
2506 switch_mutex_unlock(globals.mutex);
2507 return tech_pvt;
2508 }
2509 } // else {
2510 //DEBUGA_GSMOPEN("GSM interface: %d blank!! A hole here means we cannot hunt the last interface.\n", GSMOPEN_P_LOG, interface_id);
2511 //}
2512 }
2513
2514 switch_mutex_unlock(globals.mutex);
2515 return NULL;
2516 }
2517
2518 #if 1
SWITCH_STANDARD_API(gsm_function)2519 SWITCH_STANDARD_API(gsm_function)
2520 {
2521 char *mycmd = NULL, *argv[10] = { 0 };
2522 int argc = 0;
2523
2524 if (globals.gsm_console)
2525 stream->write_function(stream, "gsm console is: |||%s|||\n", globals.gsm_console->name);
2526 else
2527 stream->write_function(stream, "gsm console is NOT yet assigned\n");
2528
2529 if (!zstr(cmd) && (mycmd = strdup(cmd))) {
2530 argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
2531 }
2532
2533 if (!argc || !argv[0]) {
2534 stream->write_function(stream, "%s", GSM_SYNTAX);
2535 goto end;
2536 }
2537
2538 if (!strcasecmp(argv[0], "list")) {
2539 int i;
2540 char next_flag_char = ' ';
2541
2542 stream->write_function(stream, "F ID\t Name \tIB (F/T) OB (F/T)\tState\tCallFlw\t\tUUID\n");
2543 stream->write_function(stream, "= ====\t ======== \t======= =======\t======\t============\t======\n");
2544
2545 for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) {
2546 next_flag_char = i == globals.next_interface ? '*' : ' ';
2547
2548 if (strlen(globals.GSMOPEN_INTERFACES[i].name)) {
2549 stream->write_function(stream,
2550 "%c %d\t[%s]\t%3ld/%ld\t%6ld/%ld\t%s\t%s\t%s\n",
2551 next_flag_char,
2552 i, globals.GSMOPEN_INTERFACES[i].name,
2553 globals.GSMOPEN_INTERFACES[i].ib_failed_calls,
2554 globals.GSMOPEN_INTERFACES[i].ib_calls,
2555 globals.GSMOPEN_INTERFACES[i].ob_failed_calls,
2556 globals.GSMOPEN_INTERFACES[i].ob_calls,
2557 interface_status[globals.GSMOPEN_INTERFACES[i].interface_state],
2558 phone_callflow[globals.GSMOPEN_INTERFACES[i].phone_callflow], globals.GSMOPEN_INTERFACES[i].session_uuid_str);
2559 } else if (argc > 1 && !strcasecmp(argv[1], "full")) {
2560 stream->write_function(stream, "%c\t%d\n", next_flag_char, i);
2561 }
2562
2563 }
2564 stream->write_function(stream, "\nTotal: %d\n", globals.real_interfaces - 1);
2565
2566 } else if (!strcasecmp(argv[0], "console")) {
2567 int i;
2568 int found = 0;
2569
2570 if (argc == 2) {
2571 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
2572 /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */
2573 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
2574 && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[1], strlen(argv[1])) == 0)) {
2575 globals.gsm_console = &globals.GSMOPEN_INTERFACES[i];
2576 stream->write_function(stream, "gsm console is now: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i,
2577 globals.GSMOPEN_INTERFACES[i].name);
2578 stream->write_function(stream, "gsm console is: |||%s|||\n", globals.gsm_console->name);
2579 found = 1;
2580 break;
2581 }
2582
2583 }
2584 if (!found)
2585 stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[1]);
2586 } else {
2587
2588 stream->write_function(stream, "-ERR Usage: gsm console interface_name\n");
2589 goto end;
2590 }
2591
2592 } else if (!strcasecmp(argv[0], "ciapalino")) {
2593
2594 /* BEGIN: Changes heres */
2595 } else if (!strcasecmp(argv[0], "reload")) {
2596 if (load_config(SOFT_RELOAD) != SWITCH_STATUS_SUCCESS) {
2597 stream->write_function(stream, "gsm reload failed\n");
2598 } else {
2599 stream->write_function(stream, "gsm reload success\n");
2600 }
2601 } else if (!strcasecmp(argv[0], "remove")) {
2602 if (argc == 2) {
2603 if (remove_interface(argv[1]) == SWITCH_STATUS_SUCCESS) {
2604 if (interface_exists(argv[1]) == SWITCH_STATUS_SUCCESS) {
2605 stream->write_function(stream, "gsm remove '%s' failed\n", argv[1]);
2606 } else {
2607 stream->write_function(stream, "gsm remove '%s' success\n", argv[1]);
2608 }
2609 }
2610 } else {
2611 stream->write_function(stream, "-ERR Usage: gsm remove interface_name\n");
2612 goto end;
2613 }
2614 /* END: Changes heres */
2615
2616 } else {
2617 if (globals.gsm_console)
2618 gsmopen_serial_write_AT_noack(globals.gsm_console, (char *) cmd);
2619 else
2620 stream->write_function(stream, "gsm console is NOT yet assigned\n");
2621 }
2622 end:
2623 switch_safe_free(mycmd);
2624
2625 return SWITCH_STATUS_SUCCESS;
2626 }
2627
SWITCH_STANDARD_API(gsmopen_function)2628 SWITCH_STANDARD_API(gsmopen_function)
2629 {
2630 char *mycmd = NULL, *argv[10] = { 0 };
2631 int argc = 0;
2632 private_t *tech_pvt = NULL;
2633
2634 if (!zstr(cmd) && (mycmd = strdup(cmd))) {
2635 argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
2636 }
2637
2638 if (!argc) {
2639 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX);
2640 goto end;
2641 }
2642
2643 if (argc < 2) {
2644 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX);
2645 goto end;
2646 }
2647
2648 if (argv[0]) {
2649 int i;
2650 int found = 0;
2651
2652 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
2653 /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */
2654 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
2655 && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) {
2656 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
2657 stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name);
2658 found = 1;
2659 break;
2660 }
2661
2662 }
2663 if (!found) {
2664 stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]);
2665 switch_safe_free(mycmd);
2666
2667 return SWITCH_STATUS_SUCCESS;
2668 } else {
2669 gsmopen_serial_write_AT_noack(tech_pvt, (char *) &cmd[strlen(argv[0]) + 1]);
2670 }
2671 } else {
2672 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_SYNTAX);
2673 }
2674 end:
2675 switch_safe_free(mycmd);
2676
2677 return SWITCH_STATUS_SUCCESS;
2678 }
2679 #endif //0
SWITCH_STANDARD_API(gsmopen_dump_function)2680 SWITCH_STANDARD_API(gsmopen_dump_function)
2681 {
2682 char *mycmd = NULL, *argv[10] = { 0 };
2683 int argc = 0;
2684 private_t *tech_pvt = NULL;
2685 char value[512];
2686
2687 if (!zstr(cmd) && (mycmd = strdup(cmd))) {
2688 argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
2689 }
2690
2691 if (!argc) {
2692 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_DUMP_SYNTAX);
2693 goto end;
2694 }
2695 if (argc == 1) {
2696 int i;
2697 int found = 0;
2698
2699 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
2700 /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */
2701 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
2702 && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) {
2703 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
2704 //stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name);
2705 found = 1;
2706 break;
2707 }
2708
2709 }
2710 if (!found && (strcmp("list", argv[0]) == 0)) {
2711 int i;
2712 stream->write_function(stream, "gsmopen_dump LIST\n\n");
2713 for (i = 0; i < GSMOPEN_MAX_INTERFACES; i++) {
2714 if (strlen(globals.GSMOPEN_INTERFACES[i].name)) {
2715 stream->write_function(stream, "dumping interface '%s'\n\n", globals.GSMOPEN_INTERFACES[i].name);
2716 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
2717
2718
2719 stream->write_function(stream, "interface_name = %s\n", tech_pvt->name);
2720 stream->write_function(stream, "interface_id = %s\n", tech_pvt->id);
2721 snprintf(value, sizeof(value)-1, "%d", tech_pvt->active);
2722 stream->write_function(stream, "active = %s\n", value);
2723 if(!tech_pvt->network_creg_not_supported){
2724 snprintf(value, sizeof(value)-1, "%d", tech_pvt->not_registered);
2725 stream->write_function(stream, "not_registered = %s\n", value);
2726 snprintf(value, sizeof(value)-1, "%d", tech_pvt->home_network_registered);
2727 stream->write_function(stream, "home_network_registered = %s\n", value);
2728 snprintf(value, sizeof(value)-1, "%d", tech_pvt->roaming_registered);
2729 stream->write_function(stream, "roaming_registered = %s\n", value);
2730 }else{
2731 stream->write_function(stream, "not_registered = %s\n", "N/A");
2732 stream->write_function(stream, "home_network_registered = %s\n", "N/A");
2733 stream->write_function(stream, "roaming_registered = %s\n", "N/A");
2734 }
2735 snprintf(value, sizeof(value)-1, "%d", tech_pvt->got_signal);
2736 stream->write_function(stream, "got_signal = %s\n", value);
2737 snprintf(value, sizeof(value)-1, "%d", tech_pvt->running);
2738 stream->write_function(stream, "running = %s\n", value);
2739 stream->write_function(stream, "imei = %s\n", tech_pvt->imei);
2740 stream->write_function(stream, "imsi = %s\n", tech_pvt->imsi);
2741 snprintf(value, sizeof(value)-1, "%d", tech_pvt->controldev_dead);
2742 stream->write_function(stream, "controldev_dead = %s\n", value);
2743 stream->write_function(stream, "controldevice_name = %s\n", tech_pvt->controldevice_name);
2744 snprintf(value, sizeof(value)-1, "%d", tech_pvt->no_sound);
2745 stream->write_function(stream, "no_sound = %s\n", value);
2746 #ifdef GSMOPEN_ALSA
2747 stream->write_function(stream, "alsacname = %s\n", tech_pvt->alsacname);
2748 stream->write_function(stream, "alsapname = %s\n", tech_pvt->alsapname);
2749 #endif// GSMOPEN_ALSA
2750 #ifdef GSMOPEN_PORTAUDIO
2751 snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiocindex);
2752 stream->write_function(stream, "portaudiocindex = %s\n", value);
2753 snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiopindex);
2754 stream->write_function(stream, "portaudiopindex = %s\n", value);
2755 snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexecho);
2756 stream->write_function(stream, "speexecho = %s\n", value);
2757 snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexpreprocess);
2758 stream->write_function(stream, "speexpreprocess = %s\n", value);
2759 #endif// GSMOPEN_PORTAUDIO
2760 snprintf(value, sizeof(value)-1, "%f", tech_pvt->playback_boost);
2761 stream->write_function(stream, "playback_boost = %s\n", value);
2762 snprintf(value, sizeof(value)-1, "%f", tech_pvt->capture_boost);
2763 stream->write_function(stream, "capture_boost = %s\n", value);
2764 stream->write_function(stream, "dialplan = %s\n", tech_pvt->dialplan);
2765 stream->write_function(stream, "context = %s\n", tech_pvt->context);
2766 stream->write_function(stream, "destination = %s\n", tech_pvt->destination);
2767 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_calls);
2768 stream->write_function(stream, "ib_calls = %s\n", value);
2769 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_calls);
2770 stream->write_function(stream, "ob_calls = %s\n", value);
2771 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_failed_calls);
2772 stream->write_function(stream, "ib_failed_calls = %s\n", value);
2773 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_failed_calls);
2774 stream->write_function(stream, "ob_failed_calls = %s\n", value);
2775 snprintf(value, sizeof(value)-1, "%d", tech_pvt->interface_state);
2776 stream->write_function(stream, "interface_state = %s\n", value);
2777 snprintf(value, sizeof(value)-1, "%d", tech_pvt->phone_callflow);
2778 stream->write_function(stream, "phone_callflow = %s\n", value);
2779 stream->write_function(stream, "session_uuid_str = %s\n", tech_pvt->session_uuid_str);
2780 stream->write_function(stream, "\n");
2781
2782 dump_event(tech_pvt);
2783 }
2784
2785 }
2786
2787 } else if(found){
2788 stream->write_function(stream, "dumping interface '%s'\n\n", argv[0]);
2789 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
2790
2791
2792 stream->write_function(stream, "interface_name = %s\n", tech_pvt->name);
2793 stream->write_function(stream, "interface_id = %s\n", tech_pvt->id);
2794 snprintf(value, sizeof(value)-1, "%d", tech_pvt->active);
2795 stream->write_function(stream, "active = %s\n", value);
2796 if(!tech_pvt->network_creg_not_supported){
2797 snprintf(value, sizeof(value)-1, "%d", tech_pvt->not_registered);
2798 stream->write_function(stream, "not_registered = %s\n", value);
2799 snprintf(value, sizeof(value)-1, "%d", tech_pvt->home_network_registered);
2800 stream->write_function(stream, "home_network_registered = %s\n", value);
2801 snprintf(value, sizeof(value)-1, "%d", tech_pvt->roaming_registered);
2802 stream->write_function(stream, "roaming_registered = %s\n", value);
2803 }else{
2804 stream->write_function(stream, "not_registered = %s\n", "N/A");
2805 stream->write_function(stream, "home_network_registered = %s\n", "N/A");
2806 stream->write_function(stream, "roaming_registered = %s\n", "N/A");
2807 }
2808 snprintf(value, sizeof(value)-1, "%d", tech_pvt->got_signal);
2809 stream->write_function(stream, "got_signal = %s\n", value);
2810 snprintf(value, sizeof(value)-1, "%d", tech_pvt->running);
2811 stream->write_function(stream, "running = %s\n", value);
2812 stream->write_function(stream, "imei = %s\n", tech_pvt->imei);
2813 stream->write_function(stream, "imsi = %s\n", tech_pvt->imsi);
2814 snprintf(value, sizeof(value)-1, "%d", tech_pvt->controldev_dead);
2815 stream->write_function(stream, "controldev_dead = %s\n", value);
2816 stream->write_function(stream, "controldevice_name = %s\n", tech_pvt->controldevice_name);
2817 snprintf(value, sizeof(value)-1, "%d", tech_pvt->no_sound);
2818 stream->write_function(stream, "no_sound = %s\n", value);
2819 #ifdef GSMOPEN_ALSA
2820 stream->write_function(stream, "alsacname = %s\n", tech_pvt->alsacname);
2821 stream->write_function(stream, "alsapname = %s\n", tech_pvt->alsapname);
2822 #endif// GSMOPEN_ALSA
2823 #ifdef GSMOPEN_PORTAUDIO
2824 snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiocindex);
2825 stream->write_function(stream, "portaudiocindex = %s\n", value);
2826 snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiopindex);
2827 stream->write_function(stream, "portaudiopindex = %s\n", value);
2828 snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexecho);
2829 stream->write_function(stream, "speexecho = %s\n", value);
2830 snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexpreprocess);
2831 stream->write_function(stream, "speexpreprocess = %s\n", value);
2832 #endif// GSMOPEN_PORTAUDIO
2833 snprintf(value, sizeof(value)-1, "%f", tech_pvt->playback_boost);
2834 stream->write_function(stream, "playback_boost = %s\n", value);
2835 snprintf(value, sizeof(value)-1, "%f", tech_pvt->capture_boost);
2836 stream->write_function(stream, "capture_boost = %s\n", value);
2837 stream->write_function(stream, "dialplan = %s\n", tech_pvt->dialplan);
2838 stream->write_function(stream, "context = %s\n", tech_pvt->context);
2839 stream->write_function(stream, "destination = %s\n", tech_pvt->destination);
2840 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_calls);
2841 stream->write_function(stream, "ib_calls = %s\n", value);
2842 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_calls);
2843 stream->write_function(stream, "ob_calls = %s\n", value);
2844 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_failed_calls);
2845 stream->write_function(stream, "ib_failed_calls = %s\n", value);
2846 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_failed_calls);
2847 stream->write_function(stream, "ob_failed_calls = %s\n", value);
2848 snprintf(value, sizeof(value)-1, "%d", tech_pvt->interface_state);
2849 stream->write_function(stream, "interface_state = %s\n", value);
2850 snprintf(value, sizeof(value)-1, "%d", tech_pvt->phone_callflow);
2851 stream->write_function(stream, "phone_callflow = %s\n", value);
2852 stream->write_function(stream, "session_uuid_str = %s\n", tech_pvt->session_uuid_str);
2853 stream->write_function(stream, "\n");
2854
2855 dump_event(tech_pvt);
2856 } else{
2857 stream->write_function(stream, "interface '%s' was not found\n", argv[0]);
2858 }
2859 } else {
2860 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_DUMP_SYNTAX);
2861 }
2862 end:
2863 switch_safe_free(mycmd);
2864
2865 return SWITCH_STATUS_SUCCESS;
2866 }
SWITCH_STANDARD_API(gsmopen_boost_audio_function)2867 SWITCH_STANDARD_API(gsmopen_boost_audio_function)
2868 {
2869 char *mycmd = NULL, *argv[10] = { 0 };
2870 int argc = 0;
2871 //private_t *tech_pvt;
2872
2873 if (!zstr(cmd) && (mycmd = strdup(cmd))) {
2874 argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
2875 }
2876
2877 if (argc == 1 || argc==3) {
2878 int i;
2879 int found = 0;
2880
2881 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
2882 /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */
2883 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
2884 && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) {
2885 //tech_pvt = &globals.GSMOPEN_INTERFACES[i];
2886 stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name);
2887 found = 1;
2888 break;
2889 }
2890
2891 }
2892 if (!found) {
2893 stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]);
2894
2895 } else {
2896 if (argc == 1) {
2897 stream->write_function(stream,"[%s] capture boost is %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].capture_boost);
2898 stream->write_function(stream,"[%s] playback boost is %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].playback_boost);
2899 stream->write_function(stream, "%s usage: %s", argv[0], GSMOPEN_BOOST_AUDIO_SYNTAX);
2900 goto end;
2901 } else if ((strncmp("play", argv[1], strlen(argv[1])) == 0)) {
2902 if (switch_is_number(argv[2])) {
2903 stream->write_function(stream,"[%s] playback boost was %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].playback_boost);
2904 gsmopen_store_boost(argv[2], &globals.GSMOPEN_INTERFACES[i].playback_boost); //FIXME
2905 stream->write_function(stream,"[%s] playback boost is now %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].playback_boost);
2906 }
2907 }else if ((strncmp("capt", argv[1], strlen(argv[1])) == 0)) {
2908 if (switch_is_number(argv[2])) {
2909 stream->write_function(stream,"[%s] capture boost was %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].capture_boost);
2910 gsmopen_store_boost(argv[2], &globals.GSMOPEN_INTERFACES[i].capture_boost); //FIXME
2911 stream->write_function(stream,"[%s] capture boost is now %f\n", globals.GSMOPEN_INTERFACES[i].name, globals.GSMOPEN_INTERFACES[i].capture_boost);
2912 }
2913 } else {
2914 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_BOOST_AUDIO_SYNTAX);
2915 }
2916 }
2917 } else {
2918 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_BOOST_AUDIO_SYNTAX);
2919 }
2920 end:
2921 switch_safe_free(mycmd);
2922
2923 return SWITCH_STATUS_SUCCESS;
2924 }
2925
2926
2927 #if 0
2928 int gsmopen_transfer(private_t * tech_pvt, char *id, char *value)
2929 {
2930 char msg_to_gsmopen[1024];
2931 int i;
2932 int found = 0;
2933 private_t *giovatech;
2934 struct timeval timenow;
2935
2936 switch_mutex_lock(globals.mutex);
2937
2938 gettimeofday(&timenow, NULL);
2939 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
2940 if (strlen(globals.GSMOPEN_INTERFACES[i].name)) {
2941
2942 giovatech = &globals.GSMOPEN_INTERFACES[i];
2943 //NOTICA("gsmopen interface: %d, name: %s, state: %d, value=%s, giovatech->callid_number=%s, giovatech->gsmopen_user=%s\n", GSMOPEN_P_LOG, i, giovatech->name, giovatech->interface_state, value, giovatech->callid_number, giovatech->gsmopen_user);
2944 //FIXME check a timestamp here
2945 if (strlen(giovatech->gsmopen_call_id) && (giovatech->interface_state != GSMOPEN_STATE_DOWN) && (!strcmp(giovatech->gsmopen_user, tech_pvt->gsmopen_user)) && (!strcmp(giovatech->callid_number, value)) && ((((timenow.tv_sec - giovatech->answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->answer_time.tv_usec)) < 500000)) { //0.5sec
2946 found = 1;
2947 DEBUGA_GSMOPEN
2948 ("FOUND (name=%s, giovatech->interface_state=%d != GSMOPEN_STATE_DOWN) && (giovatech->gsmopen_user=%s == tech_pvt->gsmopen_user=%s) && (giovatech->callid_number=%s == value=%s)\n",
2949 GSMOPEN_P_LOG, giovatech->name, giovatech->interface_state, giovatech->gsmopen_user, tech_pvt->gsmopen_user, giovatech->callid_number,
2950 value)
2951 break;
2952 }
2953 }
2954 }
2955
2956 if (found) {
2957 //tech_pvt->callid_number[0]='\0';
2958 //sprintf(msg_to_gsmopen, "ALTER CALL %s END HANGUP", id);
2959 //gsmopen_signaling_write(tech_pvt, msg_to_gsmopen);
2960 switch_mutex_unlock(globals.mutex);
2961 return 0;
2962 }
2963 DEBUGA_GSMOPEN("NOT FOUND\n", GSMOPEN_P_LOG);
2964
2965 if (!tech_pvt || !tech_pvt->gsmopen_call_id || !strlen(tech_pvt->gsmopen_call_id)) {
2966 /* we are not inside an active call */
2967 DEBUGA_GSMOPEN("We're NO MORE in a call now %s\n", GSMOPEN_P_LOG, (tech_pvt && tech_pvt->gsmopen_call_id) ? tech_pvt->gsmopen_call_id : "");
2968 switch_mutex_unlock(globals.mutex);
2969
2970 } else {
2971
2972 /* we're owned, we're in a call, let's try to transfer */
2973 /************************** TODO
2974 Checking here if it is possible to transfer this call to Test2
2975 -> GET CALL 288 CAN_TRANSFER Test2
2976 <- CALL 288 CAN_TRANSFER test2 TRUE
2977 **********************************/
2978
2979 private_t *available_gsmopen_interface = NULL;
2980
2981 gettimeofday(&timenow, NULL);
2982 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
2983 if (strlen(globals.GSMOPEN_INTERFACES[i].name)) {
2984
2985 giovatech = &globals.GSMOPEN_INTERFACES[i];
2986 //NOTICA("gsmopen interface: %d, name: %s, state: %d, value=%s, giovatech->callid_number=%s, giovatech->gsmopen_user=%s\n", GSMOPEN_P_LOG, i, giovatech->name, giovatech->interface_state, value, giovatech->callid_number, giovatech->gsmopen_user);
2987 //FIXME check a timestamp here
2988 if (strlen(giovatech->gsmopen_transfer_call_id) && (giovatech->interface_state != GSMOPEN_STATE_DOWN) && (!strcmp(giovatech->gsmopen_user, tech_pvt->gsmopen_user)) && (!strcmp(giovatech->transfer_callid_number, value)) && ((((timenow.tv_sec - giovatech->transfer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->transfer_time.tv_usec)) < 1000000)) { //1.0 sec
2989 found = 1;
2990 DEBUGA_GSMOPEN
2991 ("FOUND (name=%s, giovatech->interface_state=%d != GSMOPEN_STATE_DOWN) && (giovatech->gsmopen_user=%s == tech_pvt->gsmopen_user=%s) && (giovatech->transfer_callid_number=%s == value=%s)\n",
2992 GSMOPEN_P_LOG, giovatech->name, giovatech->interface_state,
2993 giovatech->gsmopen_user, tech_pvt->gsmopen_user, giovatech->transfer_callid_number, value)
2994 break;
2995 }
2996 }
2997 }
2998
2999 if (found) {
3000 //tech_pvt->callid_number[0]='\0';
3001 //sprintf(msg_to_gsmopen, "ALTER CALL %s END HANGUP", id);
3002 //gsmopen_signaling_write(tech_pvt, msg_to_gsmopen);
3003 switch_mutex_unlock(globals.mutex);
3004 return 0;
3005 }
3006 DEBUGA_GSMOPEN("NOT FOUND\n", GSMOPEN_P_LOG);
3007
3008 available_gsmopen_interface = find_available_gsmopen_interface_rr(tech_pvt);
3009 if (available_gsmopen_interface) {
3010 /* there is a gsmopen interface idle, let's transfer the call to it */
3011
3012 //FIXME write a timestamp here
3013 gettimeofday(&tech_pvt->transfer_time, NULL);
3014 switch_copy_string(tech_pvt->gsmopen_transfer_call_id, id, sizeof(tech_pvt->gsmopen_transfer_call_id) - 1);
3015
3016 switch_copy_string(tech_pvt->transfer_callid_number, value, sizeof(tech_pvt->transfer_callid_number) - 1);
3017
3018 DEBUGA_GSMOPEN
3019 ("Let's transfer the gsmopen_call %s to %s interface (with gsmopen_user: %s), because we are already in a gsmopen call(%s)\n",
3020 GSMOPEN_P_LOG, tech_pvt->gsmopen_call_id, available_gsmopen_interface->name, available_gsmopen_interface->gsmopen_user, id);
3021
3022 //FIXME why this? the inbound call will come, eventually, on that other interface
3023 //available_gsmopen_interface->ib_calls++;
3024
3025 sprintf(msg_to_gsmopen, "ALTER CALL %s TRANSFER %s", id, available_gsmopen_interface->gsmopen_user);
3026 //gsmopen_signaling_write(tech_pvt, msg_to_gsmopen);
3027 if (tech_pvt->interface_state == GSMOPEN_STATE_SELECTED) {
3028 tech_pvt->interface_state = GSMOPEN_STATE_IDLE; //we marked it GSMOPEN_STATE_SELECTED just in case it has to make an outbound call
3029 }
3030 } else {
3031 /* no gsmopen interfaces idle, do nothing */
3032 DEBUGA_GSMOPEN
3033 ("Not answering the gsmopen_call %s, because we are already in a gsmopen call(%s) and not transferring, because no other gsmopen interfaces are available\n",
3034 GSMOPEN_P_LOG, id, tech_pvt->gsmopen_call_id);
3035 sprintf(msg_to_gsmopen, "ALTER CALL %s END HANGUP", id);
3036 //gsmopen_signaling_write(tech_pvt, msg_to_gsmopen);
3037 }
3038 switch_sleep(10000);
3039 DEBUGA_GSMOPEN
3040 ("We have NOT answered a GSM RING from gsmopen_call %s, because we are already in a gsmopen call (%s)\n",
3041 GSMOPEN_P_LOG, id, tech_pvt->gsmopen_call_id);
3042
3043 switch_mutex_unlock(globals.mutex);
3044 }
3045 return 0;
3046 }
3047 #endif //0
3048
gsmopen_do_gsmopenapi_thread_func(void * obj)3049 void *gsmopen_do_gsmopenapi_thread_func(void *obj)
3050 {
3051
3052 private_t *tech_pvt = (private_t *) obj;
3053 time_t now_timestamp;
3054
3055 //if (gsmopen_present(GSMopenHandles))
3056 while (running && tech_pvt->running) {
3057 int res;
3058 //gsmopen_sleep(1000000); //1 sec
3059 //DEBUGA_GSMOPEN("ciao!\n", GSMOPEN_P_LOG);
3060 res = gsmopen_serial_read(tech_pvt);
3061 if (res == -1) { //manage the graceful interface shutdown
3062 tech_pvt->controldev_dead = 1;
3063 close(tech_pvt->controldevfd);
3064 ERRORA("gsmopen_serial_monitor failed, declaring %s dead\n", GSMOPEN_P_LOG, tech_pvt->controldevice_name);
3065 tech_pvt->running=0;
3066 alarm_event(tech_pvt, ALARM_FAILED_INTERFACE, "gsmopen_serial_monitor failed, declaring interface dead");
3067 tech_pvt->active=0;
3068 tech_pvt->name[0]='\0';
3069 switch_sleep(1000000);
3070 } else if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL && tech_pvt->interface_state == GSMOPEN_STATE_RING
3071 && tech_pvt->phone_callflow != CALLFLOW_CALL_HANGUP_REQUESTED) {
3072 //WARNINGA("INCOMING RING\n", GSMOPEN_P_LOG);
3073
3074 gsmopen_ring(tech_pvt);
3075
3076 //FIXME gsmopen_answer(tech_pvt);
3077 //new_inbound_channel(tech_pvt);
3078 //FIXME if (!gsmopen_new(p, AST_STATE_RING, tech_pvt->context)) {
3079 //FIXME ERRORA("gsmopen_new failed! BAD BAD BAD\n", GSMOPEN_P_LOG);
3080 //FIXME }
3081
3082
3083 } else if (tech_pvt->controldevprotocol != PROTOCOL_NO_SERIAL && tech_pvt->interface_state == GSMOPEN_STATE_DIALING) {
3084 WARNINGA("WE'RE DIALING, let's take the earlymedia\n", GSMOPEN_P_LOG);
3085 tech_pvt->interface_state = CALLFLOW_STATUS_EARLYMEDIA;
3086 remote_party_is_early_media(tech_pvt);
3087 //new_inbound_channel(tech_pvt);
3088 //FIXME if (!gsmopen_new(p, AST_STATE_RING, tech_pvt->context)) {
3089 //FIXME ERRORA("gsmopen_new failed! BAD BAD BAD\n", GSMOPEN_P_LOG);
3090 //FIXME }
3091
3092
3093
3094
3095 } else if (tech_pvt->interface_state == CALLFLOW_CALL_REMOTEANSWER) {
3096 WARNINGA("REMOTE PARTY ANSWERED\n", GSMOPEN_P_LOG);
3097 outbound_channel_answered(tech_pvt);
3098 //new_inbound_channel(tech_pvt);
3099 //FIXME if (!gsmopen_new(p, AST_STATE_RING, tech_pvt->context)) {
3100 //FIXME ERRORA("gsmopen_new failed! BAD BAD BAD\n", GSMOPEN_P_LOG);
3101 //FIXME }
3102 }
3103 switch_sleep(100); //give other threads a chance
3104 time(&now_timestamp);
3105
3106 if ((now_timestamp - tech_pvt->gsmopen_serial_synced_timestamp) > tech_pvt->gsmopen_serial_sync_period) { //TODO find a sensible period. 5min? in config?
3107 gsmopen_serial_sync(tech_pvt);
3108 gsmopen_serial_getstatus_AT(tech_pvt);
3109 }
3110 }
3111 DEBUGA_GSMOPEN("EXIT\n", GSMOPEN_P_LOG);
3112 //running = 0;
3113 return NULL;
3114
3115 }
3116
3117
SWITCH_STANDARD_API(sendsms_function)3118 SWITCH_STANDARD_API(sendsms_function)
3119 {
3120 char *mycmd = NULL, *argv[3] = { 0 };
3121 int argc = 0;
3122 private_t *tech_pvt = NULL;
3123
3124 if (!zstr(cmd) && (mycmd = strdup(cmd))) {
3125 argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
3126 }
3127
3128 if (!argc) {
3129 stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX);
3130 goto end;
3131 }
3132
3133 if (argc < 3) {
3134 stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX);
3135 goto end;
3136 }
3137
3138 if (argv[0]) {
3139 int i;
3140 int found = 0;
3141
3142 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
3143 /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */
3144 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
3145 && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) {
3146 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
3147 stream->write_function(stream, "Trying to send your SMS: interface=%s, dest=%s, text=%s\n", argv[0], argv[1], argv[2]);
3148 found = 1;
3149 break;
3150 }
3151
3152 }
3153 if (!found) {
3154 stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]);
3155 switch_safe_free(mycmd);
3156
3157 return SWITCH_STATUS_SUCCESS;
3158 } else {
3159 //gsmopen_sendsms(tech_pvt, (char *) argv[1], (char *) argv[2]);
3160 NOTICA("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n", GSMOPEN_P_LOG, GSMOPEN_CHAT_PROTO, tech_pvt->name,
3161 argv[1], "SIMPLE MESSAGE", switch_str_nil(argv[2]), tech_pvt->name);
3162
3163 compat_chat_send(GSMOPEN_CHAT_PROTO, tech_pvt->name, argv[1], "SIMPLE MESSAGE", switch_str_nil(argv[2]), NULL, tech_pvt->name);
3164 }
3165 } else {
3166 stream->write_function(stream, "ERROR, usage: %s", SENDSMS_SYNTAX);
3167 }
3168 end:
3169 switch_safe_free(mycmd);
3170
3171 return SWITCH_STATUS_SUCCESS;
3172 }
3173
dump_event_full(private_t * tech_pvt,int is_alarm,int alarm_code,const char * alarm_message)3174 int dump_event_full(private_t * tech_pvt, int is_alarm, int alarm_code, const char *alarm_message)
3175 {
3176 switch_event_t *event;
3177 char value[512];
3178 switch_core_session_t *session = NULL;
3179 switch_channel_t *channel = NULL;
3180 switch_status_t status;
3181
3182 session = switch_core_session_locate(tech_pvt->session_uuid_str);
3183 if(session){
3184 channel = switch_core_session_get_channel(session);
3185 }
3186
3187 if (is_alarm){
3188 ERRORA("ALARM on interface %s: \n", GSMOPEN_P_LOG, tech_pvt->name );
3189 status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ALARM);
3190 }else{
3191 DEBUGA_GSMOPEN("DUMP on interface %s: \n", GSMOPEN_P_LOG, tech_pvt->name );
3192 status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_DUMP);
3193 }
3194 if (status == SWITCH_STATUS_SUCCESS) {
3195 if (is_alarm){
3196 snprintf(value, sizeof(value)-1, "%d", alarm_code);
3197 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm_code", value);
3198 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm_message", alarm_message);
3199 }
3200 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_name", tech_pvt->name);
3201 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_id", tech_pvt->id);
3202 snprintf(value, sizeof(value)-1, "%d", tech_pvt->active);
3203 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "active", value);
3204 if(!tech_pvt->network_creg_not_supported){
3205 snprintf(value, sizeof(value)-1, "%d", tech_pvt->not_registered);
3206 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "not_registered", value);
3207 snprintf(value, sizeof(value)-1, "%d", tech_pvt->home_network_registered);
3208 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "home_network_registered", value);
3209 snprintf(value, sizeof(value)-1, "%d", tech_pvt->roaming_registered);
3210 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "roaming_registered", value);
3211 }else{
3212 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "not_registered", "N/A");
3213 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "home_network_registered", "N/A");
3214 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "roaming_registered", "N/A");
3215 }
3216 snprintf(value, sizeof(value)-1, "%d", tech_pvt->got_signal);
3217 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "got_signal", value);
3218 snprintf(value, sizeof(value)-1, "%d", tech_pvt->running);
3219 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "running", value);
3220 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "imei", tech_pvt->imei);
3221 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "imsi", tech_pvt->imsi);
3222 snprintf(value, sizeof(value)-1, "%d", tech_pvt->controldev_dead);
3223 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "controldev_dead", value);
3224 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "controldevice_name", tech_pvt->controldevice_name);
3225 snprintf(value, sizeof(value)-1, "%d", tech_pvt->no_sound);
3226 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "no_sound", value);
3227 #ifdef GSMOPEN_ALSA
3228 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alsacname", tech_pvt->alsacname);
3229 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alsapname", tech_pvt->alsapname);
3230 #endif// GSMOPEN_ALSA
3231 #ifdef GSMOPEN_PORTAUDIO
3232 snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiocindex);
3233 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "portaudiocindex", value);
3234 snprintf(value, sizeof(value)-1, "%d", tech_pvt->portaudiopindex);
3235 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "portaudiopindex", value);
3236 snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexecho);
3237 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "speexecho", value);
3238 snprintf(value, sizeof(value)-1, "%d", tech_pvt->speexpreprocess);
3239 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "speexpreprocess", value);
3240 #endif// GSMOPEN_PORTAUDIO
3241 snprintf(value, sizeof(value)-1, "%f", tech_pvt->playback_boost);
3242 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "playback_boost", value);
3243 snprintf(value, sizeof(value)-1, "%f", tech_pvt->capture_boost);
3244 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "capture_boost", value);
3245 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "dialplan", tech_pvt->dialplan);
3246 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "context", tech_pvt->context);
3247 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "destination", tech_pvt->destination);
3248 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_calls);
3249 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ib_calls", value);
3250 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_calls);
3251 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ob_calls", value);
3252 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ib_failed_calls);
3253 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ib_failed_calls", value);
3254 snprintf(value, sizeof(value)-1, "%lu", tech_pvt->ob_failed_calls);
3255 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ob_failed_calls", value);
3256 snprintf(value, sizeof(value)-1, "%d", tech_pvt->interface_state);
3257 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "interface_state", value);
3258 snprintf(value, sizeof(value)-1, "%d", tech_pvt->phone_callflow);
3259 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "phone_callflow", value);
3260 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "session_uuid_str", tech_pvt->session_uuid_str);
3261 if (strlen(tech_pvt->session_uuid_str)) {
3262 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true");
3263 } else { //no session
3264 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false");
3265 }
3266 if (channel) {
3267 switch_channel_event_set_data(channel, event);
3268 }
3269 switch_event_fire(&event);
3270 } else {
3271 ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name);
3272 }
3273
3274 if (session) {
3275 switch_core_session_rwunlock(session);
3276 }
3277 return 0;
3278 }
3279
dump_event(private_t * tech_pvt)3280 int dump_event(private_t * tech_pvt)
3281 {
3282 return dump_event_full(tech_pvt, 0, 0, NULL);
3283 }
3284
3285
alarm_event(private_t * tech_pvt,int alarm_code,const char * alarm_message)3286 int alarm_event(private_t * tech_pvt, int alarm_code, const char *alarm_message)
3287 {
3288 return dump_event_full(tech_pvt, 1, alarm_code, alarm_message);
3289 }
3290
sms_incoming(private_t * tech_pvt)3291 int sms_incoming(private_t * tech_pvt)
3292 {
3293 switch_event_t *event;
3294 switch_core_session_t *session = NULL;
3295 int event_sent_to_esl = 0;
3296
3297 //DEBUGA_GSMOPEN("received SMS on interface %s: %s\n", GSMOPEN_P_LOG, tech_pvt->name, tech_pvt->sms_message);
3298 DEBUGA_GSMOPEN("received SMS on interface %s: DATE=%s, SENDER=%s, BODY=%s|\n", GSMOPEN_P_LOG, tech_pvt->name, tech_pvt->sms_date, tech_pvt->sms_sender,
3299 tech_pvt->sms_body);
3300
3301 if (!zstr(tech_pvt->session_uuid_str)) {
3302 session = switch_core_session_locate(tech_pvt->session_uuid_str);
3303 }
3304 if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
3305 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", GSMOPEN_CHAT_PROTO);
3306 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name);
3307 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname);
3308 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->sms_sender);
3309 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "date", tech_pvt->sms_date);
3310 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "userdataheader", tech_pvt->sms_userdataheader);
3311 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "datacodingscheme", tech_pvt->sms_datacodingscheme);
3312 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "servicecentreaddress", tech_pvt->sms_servicecentreaddress);
3313 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "messagetype", "%d", tech_pvt->sms_messagetype);
3314 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "chatname", tech_pvt->chatmessages[which].chatname);
3315 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "id", tech_pvt->chatmessages[which].id);
3316 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE");
3317 switch_event_add_body(event, "%s\n", tech_pvt->sms_body);
3318 if (session) {
3319 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true");
3320 if (switch_core_session_queue_event(session, &event) != SWITCH_STATUS_SUCCESS) {
3321 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
3322 switch_event_fire(&event);
3323 }
3324 } else { //no session
3325 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false");
3326 switch_event_fire(&event);
3327 event_sent_to_esl = 1;
3328 }
3329
3330 } else {
3331 ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name);
3332 }
3333
3334 if (!event_sent_to_esl) {
3335
3336 if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
3337 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", GSMOPEN_CHAT_PROTO);
3338 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", tech_pvt->name);
3339 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", tech_pvt->chatmessages[which].from_dispname);
3340 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->chatmessages[which].from_handle);
3341 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", tech_pvt->sms_sender);
3342 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "date", tech_pvt->sms_date);
3343 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "datacodingscheme", tech_pvt->sms_datacodingscheme);
3344 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "servicecentreaddress", tech_pvt->sms_servicecentreaddress);
3345 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "messagetype", "%d", tech_pvt->sms_messagetype);
3346 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE");
3347 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "chatname", tech_pvt->chatmessages[which].chatname);
3348 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "id", tech_pvt->chatmessages[which].id);
3349 switch_event_add_body(event, "%s\n", tech_pvt->sms_body);
3350 if (session) {
3351 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "true");
3352 } else { //no session
3353 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "during-call", "false");
3354 }
3355 switch_event_fire(&event);
3356 } else {
3357 ERRORA("cannot create event on interface %s. WHY?????\n", GSMOPEN_P_LOG, tech_pvt->name);
3358 }
3359 }
3360
3361 if (session) {
3362 switch_core_session_rwunlock(session);
3363 }
3364 //memset(&tech_pvt->chatmessages[which], '\0', sizeof(&tech_pvt->chatmessages[which]) );
3365 //memset(tech_pvt->sms_message, '\0', sizeof(tech_pvt->sms_message));
3366 return 0;
3367 }
3368
3369
3370 #ifdef NOTDEF
SWITCH_STANDARD_API(gsmopen_chat_function)3371 SWITCH_STANDARD_API(gsmopen_chat_function)
3372 {
3373 char *mycmd = NULL, *argv[10] = { 0 };
3374 int argc = 0;
3375 private_t *tech_pvt = NULL;
3376 //int tried =0;
3377 int i;
3378 int found = 0;
3379 //char skype_msg[1024];
3380
3381 if (!zstr(cmd) && (mycmd = strdup(cmd))) {
3382 argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
3383 }
3384
3385 if (!argc) {
3386 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_CHAT_SYNTAX);
3387 goto end;
3388 }
3389
3390 if (argc < 3) {
3391 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_CHAT_SYNTAX);
3392 goto end;
3393 }
3394
3395 if (argv[0]) {
3396 for (i = 0; !found && i < GSMOPEN_MAX_INTERFACES; i++) {
3397 /* we've been asked for a normal interface name, or we have not found idle interfaces to serve as the "ANY" interface */
3398 if (strlen(globals.GSMOPEN_INTERFACES[i].name)
3399 && (strncmp(globals.GSMOPEN_INTERFACES[i].name, argv[0], strlen(argv[0])) == 0)) {
3400 tech_pvt = &globals.GSMOPEN_INTERFACES[i];
3401 stream->write_function(stream, "Using interface: globals.GSMOPEN_INTERFACES[%d].name=|||%s|||\n", i, globals.GSMOPEN_INTERFACES[i].name);
3402 found = 1;
3403 break;
3404 }
3405
3406 }
3407 if (!found) {
3408 stream->write_function(stream, "ERROR: A GSMopen interface with name='%s' was not found\n", argv[0]);
3409 goto end;
3410 } else {
3411
3412 //chat_send(const char *proto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint);
3413 //chat_send(p*roto, const char *from, const char *to, const char *subject, const char *body, const char *type, const char *hint);
3414 //chat_send(GSMOPEN_CHAT_PROTO, tech_pvt->skype_user, argv[1], "SIMPLE MESSAGE", switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, hint);
3415
3416 NOTICA("chat_send(proto=%s, from=%s, to=%s, subject=%s, body=%s, type=NULL, hint=%s)\n", GSMOPEN_P_LOG, GSMOPEN_CHAT_PROTO, tech_pvt->skype_user,
3417 argv[1], "SIMPLE MESSAGE", switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), tech_pvt->name);
3418
3419 chat_send(GSMOPEN_CHAT_PROTO, tech_pvt->skype_user, argv[1], "SIMPLE MESSAGE",
3420 switch_str_nil((char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]), NULL, tech_pvt->name);
3421
3422 //NOTICA("TEXT is: %s\n", GSMOPEN_P_LOG, (char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1] );
3423 //snprintf(skype_msg, sizeof(skype_msg), "CHAT CREATE %s", argv[1]);
3424 //gsmopen_signaling_write(tech_pvt, skype_msg);
3425 //switch_sleep(100);
3426 }
3427 } else {
3428 stream->write_function(stream, "ERROR, usage: %s", GSMOPEN_CHAT_SYNTAX);
3429 goto end;
3430 }
3431
3432 #ifdef NOTDEF
3433
3434 found = 0;
3435
3436 while (!found) {
3437 for (i = 0; i < MAX_CHATS; i++) {
3438 if (!strcmp(tech_pvt->chats[i].dialog_partner, argv[1])) {
3439 snprintf(skype_msg, sizeof(skype_msg), "CHATMESSAGE %s %s", tech_pvt->chats[i].chatname,
3440 (char *) &cmd[strlen(argv[0]) + 1 + strlen(argv[1]) + 1]);
3441 gsmopen_signaling_write(tech_pvt, skype_msg);
3442 found = 1;
3443 break;
3444 }
3445 }
3446 if (found) {
3447 break;
3448 }
3449 if (tried > 1000) {
3450 stream->write_function(stream, "ERROR: no chat with dialog_partner='%s' was found\n", argv[1]);
3451 break;
3452 }
3453 switch_sleep(1000);
3454 }
3455 #endif //NOTDEF
3456
3457 end:
3458 switch_safe_free(mycmd);
3459
3460 return SWITCH_STATUS_SUCCESS;
3461 }
3462 #endif // NOTDEF
3463
3464
3465 /* For Emacs:
3466 * Local Variables:
3467 * mode:c
3468 * indent-tabs-mode:t
3469 * tab-width:4
3470 * c-basic-offset:4
3471 * End:
3472 * For VIM:
3473 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet expandtab:
3474 */
3475