1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, 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  * Contributor(s):
25  *
26  * Marc Olivier Chouinard <mochouinard@moctel.com>
27  *
28  *
29  * mod_esl.c -- Allow to generate remote ESL commands
30  *
31  */
32 #include <switch.h>
33 
34 #include <esl.h>
35 
36 /* Prototypes */
37 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_esl_shutdown);
38 SWITCH_MODULE_RUNTIME_FUNCTION(mod_esl_runtime);
39 SWITCH_MODULE_LOAD_FUNCTION(mod_esl_load);
40 
41 /* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
42  * Defines a switch_loadable_module_function_table_t and a static const char[] modname
43  */
44 SWITCH_MODULE_DEFINITION(mod_esl, mod_esl_load, mod_esl_shutdown, NULL);
45 
SWITCH_STANDARD_API(single_esl_api_function)46 SWITCH_STANDARD_API(single_esl_api_function)
47 {
48 	esl_handle_t handle = {{0}};
49 	char *host = "127.0.0.1";
50 	char *s_port = NULL;
51 	int port = 8021;
52 	char *username = NULL;
53 	char *password = "ClueCon";
54 	char *args = NULL;
55 	char *s_timeout = NULL;
56 	int timeout = 5000;
57 	char *dup = strdup(cmd);
58 	char *send = NULL;
59 
60 	username = dup;
61 
62 	if (username && (password = strchr(username, '|'))) {
63 		*password++ = '\0';
64 	}
65 
66 	if (password && (host = strchr(password, ' '))) {
67 		*host++ = '\0';
68 	}
69 
70 	if (host && (s_timeout = strchr(host, ' '))) {
71 		*s_timeout++ = '\0';
72 	}
73 
74 	if (host && (s_port = strchr(host, ':'))) {
75 		*s_port++ = '\0';
76 	}
77 
78 	if (s_timeout && (args = strchr(s_timeout, ' '))) {
79 		*args++ = '\0';
80 	}
81 
82 	if (!zstr(s_port)) {
83 		port = atoi(s_port);
84 	}
85 
86 	if (zstr(host) || zstr(password) || zstr(args) || zstr(s_timeout)) {
87 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad parameters\n");
88 		goto end;
89 	}
90 
91 
92 	timeout = atoi(s_timeout);
93 
94 
95 	if  (esl_connect_timeout(&handle, host, port, username, password, timeout) != ESL_SUCCESS) {
96 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to connect to remote ESL at %s:%d\n",
97 				host, port);
98 		goto end;
99 	} else {
100 		send = switch_mprintf("api %s", args);
101 		if (esl_send_recv_timed(&handle, send, timeout) != ESL_SUCCESS) {
102 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Disconnected from remote ESL at %s:%d\n",
103 					host, port);
104 			goto end;
105 		} else {
106 			stream->write_function(stream, handle.last_sr_event->body);
107 		}
108 	}
109 
110 end:
111 	esl_disconnect(&handle);
112 	memset(&handle, 0, sizeof(handle));
113 	switch_safe_free(send);
114 	switch_safe_free(dup);
115 
116 	return SWITCH_STATUS_SUCCESS;
117 }
118 
119 /* Macro expands to: switch_status_t mod_esl_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
SWITCH_MODULE_LOAD_FUNCTION(mod_esl_load)120 SWITCH_MODULE_LOAD_FUNCTION(mod_esl_load)
121 {
122 	switch_api_interface_t *api_interface;
123 
124 	/* connect my internal structure to the blank pointer passed to me */
125 	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
126 
127 	SWITCH_ADD_API(api_interface, "single_esl", "Allow to do a single connection api call to a remote ESL server", single_esl_api_function, "[<user>]|<password> <host>[:<port>] <timeout> <remote api> <arguments>");
128 
129 	/* indicate that the module should continue to be loaded */
130 	return SWITCH_STATUS_SUCCESS;
131 }
132 
133 /*
134   Called when the system shuts down
135   Macro expands to: switch_status_t mod_esl_shutdown() */
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_esl_shutdown)136 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_esl_shutdown)
137 {
138 	return SWITCH_STATUS_SUCCESS;
139 }
140 
141 /* For Emacs:
142  * Local Variables:
143  * mode:c
144  * indent-tabs-mode:t
145  * tab-width:4
146  * c-basic-offset:4
147  * End:
148  * For VIM:
149  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet
150  */
151