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  * Anthony Minessale II <anthm@freeswitch.org>
27  *
28  * mod_fsk.c -- FSK data transfer
29  *
30  */
31 #include <switch.h>
32 #include "fsk_callerid.h"
33 
34 /* Prototypes */
35 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fsk_shutdown);
36 SWITCH_MODULE_RUNTIME_FUNCTION(mod_fsk_runtime);
37 SWITCH_MODULE_LOAD_FUNCTION(mod_fsk_load);
38 
39 /* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
40  * Defines a switch_loadable_module_function_table_t and a static const char[] modname
41  */
42 SWITCH_MODULE_DEFINITION(mod_fsk, mod_fsk_load, mod_fsk_shutdown, NULL);
43 
my_write_sample(int16_t * buf,size_t buflen,void * user_data)44 switch_status_t my_write_sample(int16_t *buf, size_t buflen, void *user_data)
45 {
46 	switch_buffer_t *buffer = (switch_buffer_t *) user_data;
47 
48 	switch_buffer_write(buffer, buf, buflen * 2);
49 
50 	return SWITCH_STATUS_SUCCESS;
51 }
52 
write_fsk_data(uint32_t rate,int32_t db,switch_buffer_t * buffer,switch_event_t * event,const char * prefix)53 static switch_status_t write_fsk_data(uint32_t rate, int32_t db, switch_buffer_t *buffer, switch_event_t *event, const char *prefix)
54 {
55 	fsk_modulator_t fsk_trans;
56 	fsk_data_state_t fsk_data = {0};
57 	uint8_t databuf[1024] = "";
58 	char time_str[9];
59 	struct tm tm;
60 	time_t now;
61 	switch_event_header_t *hp;
62 	switch_size_t plen = 0;
63 
64 	memset(&fsk_trans, 0, sizeof(fsk_trans));
65 
66 	time(&now);
67 	localtime_r(&now, &tm);
68 	strftime(time_str, sizeof(time_str), "%m%d%H%M", &tm);
69 
70 	fsk_data_init(&fsk_data, databuf, sizeof(databuf));
71 	fsk_data_add_mdmf(&fsk_data, MDMF_DATETIME, (uint8_t *)time_str, strlen(time_str));
72 
73 	if (prefix) {
74 		plen = strlen(prefix);
75 	}
76 
77 
78 	if (event) {
79 		for (hp = event->headers; hp; hp = hp->next) {
80 			char *packed;
81 			char *name = hp->name;
82 
83 			if (plen && strncasecmp(name, prefix, plen)) {
84 				continue;
85 			}
86 
87 			name += plen;
88 
89 			if (zstr(name)) {
90 				continue;
91 			}
92 
93 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encoding [%s][%s]\n", hp->name, hp->value);
94 
95 			if (!strcasecmp(name, "phone_num")) {
96 				fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NUM, (uint8_t *)hp->value, strlen(hp->value));
97 			} else if (!strcasecmp(name, "phone_name")) {
98 				fsk_data_add_mdmf(&fsk_data, MDMF_PHONE_NAME, (uint8_t *)hp->value, strlen(hp->value));
99 			} else {
100 				packed = switch_mprintf("%q:%q", name, hp->value);
101 				fsk_data_add_mdmf(&fsk_data, MDMF_NAME_VALUE, (uint8_t *)packed, strlen(packed));
102 				free(packed);
103 			}
104 		}
105 	}
106 
107 	fsk_data_add_checksum(&fsk_data);
108 
109 	fsk_modulator_init(&fsk_trans, FSK_BELL202, rate, &fsk_data, db, 180, 5, 300, my_write_sample, buffer);
110 	fsk_modulator_send_all((&fsk_trans));
111 
112 	fsk_demod_destroy(&fsk_data);
113 
114 	return SWITCH_STATUS_SUCCESS;
115 }
116 
117 
SWITCH_STANDARD_APP(fsk_send_function)118 SWITCH_STANDARD_APP(fsk_send_function) {
119 	switch_event_t *event = NULL;
120 	switch_buffer_t *buffer;
121 	switch_slin_data_t sdata = { 0 };
122 	switch_channel_t *channel = switch_core_session_get_channel(session);
123 	switch_frame_t *read_frame;
124 	switch_status_t status;
125 
126 
127 	if (data) {
128 		switch_ivr_sleep(session, 1000, SWITCH_TRUE, NULL);
129 		switch_core_session_send_dtmf_string(session, (const char *) data);
130 		switch_ivr_sleep(session, 1500, SWITCH_TRUE, NULL);
131 	}
132 
133 	if (switch_core_session_set_codec_slin(session, &sdata) != SWITCH_STATUS_SUCCESS) {
134 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
135 						  SWITCH_LOG_ERROR, "FAILURE\n");
136 		return;
137 	}
138 
139 	switch_buffer_create_dynamic(&buffer, 1024, 2048, 0);
140 
141 	switch_channel_get_variables(channel, &event);
142 
143 	write_fsk_data(sdata.codec.implementation->actual_samples_per_second, -14, buffer, event, "fsk_");
144 
145 	while(switch_channel_ready(channel)) {
146 		status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
147 
148 		if (!SWITCH_READ_ACCEPTABLE(status)) {
149 			break;
150 		}
151 
152 		if ((sdata.write_frame.datalen = switch_buffer_read(buffer, sdata.write_frame.data,
153 															 sdata.codec.implementation->decoded_bytes_per_packet)) <= 0) {
154 			break;
155 		}
156 
157 
158 		if (sdata.write_frame.datalen < sdata.codec.implementation->decoded_bytes_per_packet) {
159 			memset((char *)sdata.write_frame.data + sdata.write_frame.datalen, 255,
160 				   sdata.codec.implementation->decoded_bytes_per_packet - sdata.write_frame.datalen);
161 			sdata.write_frame.datalen = sdata.codec.implementation->decoded_bytes_per_packet;
162 		}
163 		sdata.write_frame.samples = sdata.write_frame.datalen / 2;
164 		switch_core_session_write_frame(sdata.session, &sdata.write_frame, SWITCH_IO_FLAG_NONE, 0);
165 	}
166 
167 	switch_event_destroy(&event);
168 	switch_buffer_destroy(&buffer);
169 	switch_core_codec_destroy(&sdata.codec);
170 	switch_core_session_set_read_codec(session, NULL);
171 
172 }
173 
174 typedef struct {
175 	switch_core_session_t *session;
176 	fsk_data_state_t fsk_data;
177 	uint8_t fbuf[512];
178 	int skip;
179 } switch_fsk_detect_t;
180 
181 
182 
183 
fsk_detect_callback(switch_media_bug_t * bug,void * user_data,switch_abc_type_t type)184 static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
185 {
186 	switch_fsk_detect_t *pvt = (switch_fsk_detect_t *) user_data;
187 	//switch_frame_t *frame = NULL;
188 	switch_channel_t *channel = switch_core_session_get_channel(pvt->session);
189 
190 	switch (type) {
191 	case SWITCH_ABC_TYPE_INIT: {
192 		switch_codec_implementation_t read_impl = { 0 };
193 		switch_core_session_get_read_impl(pvt->session, &read_impl);
194 
195 		if (fsk_demod_init(&pvt->fsk_data, read_impl.actual_samples_per_second, pvt->fbuf, sizeof(pvt->fbuf))) {
196 			return SWITCH_FALSE;
197 		}
198 
199 		break;
200 	}
201 	case SWITCH_ABC_TYPE_CLOSE:
202 		{
203 			fsk_demod_destroy(&pvt->fsk_data);
204 		}
205 		break;
206 
207 	case SWITCH_ABC_TYPE_WRITE_REPLACE:
208 	case SWITCH_ABC_TYPE_READ_REPLACE:
209 		{
210 			switch_frame_t *rframe;
211 
212 			if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
213 				rframe = switch_core_media_bug_get_read_replace_frame(bug);
214 			} else {
215 				rframe = switch_core_media_bug_get_write_replace_frame(bug);
216 			}
217 
218 			if (!pvt->skip && fsk_demod_feed(&pvt->fsk_data, rframe->data, rframe->datalen / 2) != SWITCH_STATUS_SUCCESS) {
219 				char str[1024] = "";
220 				size_t type, mlen;
221 				char *sp;
222 				switch_event_t *event;
223 				const char *app_var;
224 				int total = 0;
225 
226 				switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA);
227 
228 				while(fsk_data_parse(&pvt->fsk_data, &type, &sp, &mlen) == SWITCH_STATUS_SUCCESS) {
229 					char *varname = NULL, *val, *p;
230 
231 					switch_copy_string(str, sp, mlen+1);
232 					*(str+mlen) = '\0';
233 					switch_clean_string(str);
234 					//printf("TYPE %u LEN %u VAL [%s]\n", (unsigned)type, (unsigned)mlen, str);
235 
236 					val = str;
237 
238 					switch(type) {
239 					case MDMF_DATETIME:
240 						varname = "fsk_datetime";
241 						break;
242 					case MDMF_PHONE_NAME:
243 						varname = "fsk_phone_name";
244 						break;
245 					case MDMF_PHONE_NUM:
246 						varname = "fsk_phone_num";
247 						break;
248 					case MDMF_NAME_VALUE:
249 						varname = switch_core_session_sprintf(pvt->session, "fsk_%s", val);
250 						if ((p = strchr(varname, ':'))) {
251 							*p++ = '\0';
252 							val = p;
253 						}
254 						break;
255 					default:
256 						break;
257 					}
258 
259 					if (varname && val) {
260 						total++;
261 						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n",
262 										  switch_channel_get_name(channel), varname, val);
263 						switch_channel_set_variable(channel, varname, val);
264 						if (event) {
265 							switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, varname, val);
266 						}
267 					}
268 				}
269 
270 				if (event) {
271 					if (switch_core_session_queue_event(pvt->session, &event) != SWITCH_STATUS_SUCCESS) {
272 						switch_event_destroy(&event);
273 					}
274 				}
275 
276 				if (total && (app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) {
277 					char *app_arg;
278 
279 					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n",
280 									  switch_channel_get_name(channel), app_var);
281 					if ((app_arg = strchr(app_var, ' '))) {
282 						*app_arg++ = '\0';
283 					}
284 					switch_core_session_execute_application(pvt->session, app_var, app_arg);
285 				}
286 
287 				pvt->skip = 10;
288 			}
289 
290 			memset(rframe->data, 255, rframe->datalen);
291 
292 			if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
293 				switch_core_media_bug_set_read_replace_frame(bug, rframe);
294 			} else {
295 				switch_core_media_bug_set_write_replace_frame(bug, rframe);
296 			}
297 
298 			if (pvt->skip && !--pvt->skip) {
299 				return SWITCH_FALSE;
300 			}
301 
302 		}
303 		break;
304 	case SWITCH_ABC_TYPE_WRITE:
305 	default:
306 		break;
307 	}
308 
309 	return SWITCH_TRUE;
310 }
311 
stop_fsk_detect_session(switch_core_session_t * session)312 switch_status_t stop_fsk_detect_session(switch_core_session_t *session)
313 {
314 	switch_media_bug_t *bug;
315 	switch_channel_t *channel = switch_core_session_get_channel(session);
316 
317 	if ((bug = switch_channel_get_private(channel, "fsk"))) {
318 		switch_channel_set_private(channel, "fsk", NULL);
319 		switch_core_media_bug_remove(session, &bug);
320 		return SWITCH_STATUS_SUCCESS;
321 	}
322 	return SWITCH_STATUS_FALSE;
323 }
324 
fsk_detect_session(switch_core_session_t * session,const char * flags)325 switch_status_t fsk_detect_session(switch_core_session_t *session, const char *flags)
326 {
327 	switch_channel_t *channel = switch_core_session_get_channel(session);
328 	switch_media_bug_t *bug;
329 	switch_status_t status;
330 	switch_fsk_detect_t *pvt = { 0 };
331 	switch_codec_implementation_t read_impl = { 0 };
332 	int bflags = SMBF_READ_REPLACE;
333 
334 	if (strchr(flags, 'w')) {
335 		bflags = SMBF_WRITE_REPLACE;
336 	}
337 
338 	switch_core_session_get_read_impl(session, &read_impl);
339 
340 	if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) {
341 		return SWITCH_STATUS_MEMERR;
342 	}
343 
344    	pvt->session = session;
345 
346 
347 	if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
348 		return SWITCH_STATUS_FALSE;
349 	}
350 
351 	if ((status = switch_core_media_bug_add(session, "fsk_detect", NULL,
352                                             fsk_detect_callback, pvt, 0, bflags | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) {
353 		return status;
354 	}
355 
356 	switch_channel_set_private(channel, "fsk", bug);
357 
358 	return SWITCH_STATUS_SUCCESS;
359 }
360 
361 
SWITCH_STANDARD_APP(fsk_recv_function)362 SWITCH_STANDARD_APP(fsk_recv_function)
363 {
364 	fsk_detect_session(session, data);
365 }
366 
SWITCH_STANDARD_APP(fsk_display_function)367 SWITCH_STANDARD_APP(fsk_display_function)
368 {
369 	/* expected to be called via 'execute_on_fsk' -- passes display update over FSK */
370 
371 	const char *cid_name, *cid_num;
372 	switch_channel_t *channel = switch_core_session_get_channel(session);
373 	switch_core_session_message_t *msg;
374 	switch_core_session_t *psession = NULL, *usession = NULL;
375 	char *flags = (char *) data;
376 
377 	cid_name = switch_channel_get_variable(channel, "fsk_phone_name");
378 	cid_num = switch_channel_get_variable(channel, "fsk_phone_num");
379 
380 	if (zstr(cid_name)) {
381 		cid_name = cid_num;
382 	}
383 
384 	if (zstr(cid_num)) {
385 		return;
386 	}
387 
388 	if (strchr(flags, 'b')) {
389 		if (switch_core_session_get_partner(session, &psession) == SWITCH_STATUS_SUCCESS) {
390 			usession = psession;
391 		}
392 	}
393 
394 	if (!usession) {
395 		usession = session;
396 	}
397 
398 	msg = switch_core_session_alloc(usession, sizeof(*msg));
399 	MESSAGE_STAMP_FFL(msg);
400 	msg->message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
401 	msg->string_array_arg[0] = switch_core_session_strdup(usession, cid_name);
402 	msg->string_array_arg[1] = switch_core_session_strdup(usession, cid_num);
403 	msg->from = __FILE__;
404 	switch_core_session_queue_message(usession, msg);
405 
406 	if (psession) {
407 		switch_core_session_rwunlock(psession);
408 		psession = NULL;
409 	}
410 }
411 
SWITCH_STANDARD_APP(fsk_simplify_function)412 SWITCH_STANDARD_APP(fsk_simplify_function)
413 {
414 	/* expected to be called via 'execute_on_fsk' -- redirects call to point-to-point and eliminates legs in the middle */
415 	switch_channel_t *channel = switch_core_session_get_channel(session);
416 	const char *sip_uri, *fsk_simplify_profile, *fsk_simplify_context;
417 	char *bridgeto;
418 
419 	if (!(sip_uri = switch_channel_get_variable(channel, "fsk_uri"))) {
420 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Missing URI field!\n", switch_channel_get_name(channel));
421 	}
422 
423 	if (!(fsk_simplify_profile = switch_channel_get_variable(channel, "fsk_simplify_profile"))) {
424 		fsk_simplify_profile = "internal";
425 	}
426 
427 	fsk_simplify_context = switch_channel_get_variable(channel, "fsk_simplify_context");
428 
429 	if (!zstr(sip_uri)) {
430 		switch_core_session_t *psession;
431 		switch_channel_t *pchannel;
432 
433 		bridgeto = switch_core_session_sprintf(session, "bridge:sofia/%s/sip:%s", fsk_simplify_profile, sip_uri);
434 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s transfering to [%s]\n",
435 						  switch_channel_get_name(channel), bridgeto);
436 
437 
438 		if (switch_core_session_get_partner(session, &psession) == SWITCH_STATUS_SUCCESS) {
439 			pchannel = switch_core_session_get_channel(psession);
440 			switch_channel_set_flag(pchannel, CF_REDIRECT);
441 			switch_channel_set_flag(pchannel, CF_TRANSFER);
442 		}
443 
444 		switch_ivr_session_transfer(session, bridgeto, "inline", fsk_simplify_context);
445 
446 		if (psession) {
447 			switch_ivr_session_transfer(psession, "sleep:5000", "inline", NULL);
448 			switch_core_session_rwunlock(psession);
449 		}
450 	}
451 }
452 
453 /* Macro expands to: switch_status_t mod_fsk_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
SWITCH_MODULE_LOAD_FUNCTION(mod_fsk_load)454 SWITCH_MODULE_LOAD_FUNCTION(mod_fsk_load)
455 {
456 	switch_application_interface_t *app_interface;
457 
458 	/* connect my internal structure to the blank pointer passed to me */
459 	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
460 
461 	SWITCH_ADD_APP(app_interface, "fsk_send", "fsk_send", NULL, fsk_send_function, NULL, SAF_NONE);
462 	SWITCH_ADD_APP(app_interface, "fsk_recv", "fsk_recv", NULL, fsk_recv_function, NULL, SAF_NONE);
463 	SWITCH_ADD_APP(app_interface, "fsk_simplify", "fsk_simplify", NULL, fsk_simplify_function, NULL, SAF_NONE);
464 	SWITCH_ADD_APP(app_interface, "fsk_display", "fsk_display", NULL, fsk_display_function, NULL, SAF_NONE);
465 
466 	/* indicate that the module should continue to be loaded */
467 	return SWITCH_STATUS_SUCCESS;
468 }
469 
470 /*
471   Called when the system shuts down
472   Macro expands to: switch_status_t mod_fsk_shutdown() */
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fsk_shutdown)473 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fsk_shutdown)
474 {
475 	/* Cleanup dynamically allocated config settings */
476 
477 	return SWITCH_STATUS_SUCCESS;
478 }
479 
480 /* For Emacs:
481  * Local Variables:
482  * mode:c
483  * indent-tabs-mode:t
484  * tab-width:4
485  * c-basic-offset:4
486  * End:
487  * For VIM:
488  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet
489  */
490