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  *
29  * mod_esf.c -- Extra SIP Functionality
30  *
31  */
32 #include <switch.h>
33 #include <g711.h>
34 
35 SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load);
36 SWITCH_MODULE_DEFINITION(mod_esf, mod_esf_load, NULL, NULL);
37 
38 
39 
40 #ifdef _MSC_VER
41 #pragma pack(push, r1, 1)
42 #else
43 #pragma pack(1)
44 #endif
45 
46 
47 struct polycom_packet {
48 	switch_byte_t op;
49 	switch_byte_t channel;
50 	uint32_t serno;
51 	uint8_t cid_len;
52 	unsigned char cid[13];
53 };
54 
55 typedef struct polycom_packet polycom_packet_t;
56 
57 typedef struct {
58 	switch_byte_t codec;
59 	switch_byte_t flags;
60 	uint32_t seq;
61 } polycom_audio_header_t;
62 
63 
64 typedef struct polycom_alert_packet {
65 	polycom_packet_t header;
66 	polycom_audio_header_t audio_header;
67 	uint8_t data[];
68 } polycom_alert_packet_t;
69 
70 
71 #ifdef _MSC_VER
72 #pragma pack(pop, r1)
73 #else
74 #pragma pack()
75 #endif
76 
77 struct ls_control_packet {
78 	uint32_t unique_id;
79 	uint32_t command;
80 	uint32_t ip;
81 	uint32_t port;
82 };
83 
84 typedef struct ls_control_packet ls_control_packet_t;
85 
86 typedef enum {
87 	LS_START_BCAST = 6,
88 	LS_STOP_BCAST = 7
89 } ls_command_t;
90 
91 typedef enum {
92 	SEND_TYPE_UNKNOWN = 0,
93 	SEND_TYPE_RTP = 1,
94 	SEND_TYPE_NOMEDIA = 2
95 } ls_how_t;
96 
97 static uint32_t SERNO = 0;
98 
99 switch_mutex_t *MUTEX = NULL;
100 
get_serno(void)101 uint32_t get_serno(void)
102 {
103 	uint32_t r = 0;
104 
105 	switch_mutex_lock(MUTEX);
106 	r = SERNO;
107 	switch_mutex_unlock(MUTEX);
108 
109 	return r;
110 }
111 
112 
inc_serno(void)113 void inc_serno(void)
114 {
115 	switch_mutex_lock(MUTEX);
116 	SERNO++;
117 	switch_mutex_unlock(MUTEX);
118 
119 }
120 
dec_serno(void)121 void dec_serno(void)
122 {
123 	switch_mutex_lock(MUTEX);
124 	SERNO--;
125 	switch_mutex_unlock(MUTEX);
126 
127 }
128 
129 
SWITCH_STANDARD_APP(bcast_function)130 SWITCH_STANDARD_APP(bcast_function)
131 {
132 	switch_channel_t *channel = switch_core_session_get_channel(session);
133 	switch_socket_t *socket = NULL, *polycom_socket = NULL;
134 	switch_sockaddr_t *audio_addr = NULL, *control_packet_addr = NULL, *polycom_addr = NULL, *local_addr = NULL;
135 	switch_frame_t *read_frame = NULL;
136 	switch_status_t status;
137 	switch_size_t bytes;
138 	ls_control_packet_t control_packet;
139 	unsigned char polycom_buf[1024] = { 0 };
140 	unsigned char last_polycom_buf[1024] = { 0 };
141 	uint32_t last_polycom_len = 0;
142 	polycom_packet_t *polycom_packet = (polycom_packet_t *) polycom_buf;
143 	polycom_alert_packet_t *alert_packet = (polycom_alert_packet_t *) polycom_buf;
144 	switch_codec_t codec = { 0 };
145 	switch_codec_t write_codec = { 0 };
146 	switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
147 	const char *err;
148 	switch_rtp_t *rtp_session = NULL;
149 	switch_port_t rtp_port = 0;
150 	ls_how_t ready = SEND_TYPE_UNKNOWN;
151 	char *mydata, *argv[5];
152 	char *mcast_ip = "224.168.168.168";
153 	switch_port_t mcast_port = 34567;
154 	switch_port_t mcast_control_port = 6061;
155 	char *mcast_port_str = "34567";
156 	char *polycom_ip = "224.0.1.116";
157 	const char *source_ip = NULL;
158 	switch_port_t polycom_port = 5001;
159 	const char *var;
160 	switch_codec_implementation_t read_impl = { 0 };
161 	int mcast_ttl = 1;
162 	const char *caller_id_name = NULL;
163 	int x = 0;
164 	uint32_t seq = 0;
165 	const char *codec_name = "PCMU";
166 	int read_rate = 8000;
167 	int need_transcode = 0;
168 
169 	inc_serno();
170 
171 	switch_core_session_get_read_impl(session, &read_impl);
172 
173 	if (!zstr((char *) data)) {
174 		mydata = switch_core_session_strdup(session, data);
175 		assert(mydata != NULL);
176 
177 		switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
178 
179 		if ((var = switch_channel_get_variable(channel, "esf_multicast_ip"))) {
180 			mcast_ip = switch_core_session_strdup(session, var);
181 		}
182 
183 		if (!zstr(argv[0])) {
184 			mcast_ip = argv[0];
185 		}
186 
187 		if (!zstr(argv[1])) {
188 			mcast_port_str = argv[1];
189 			mcast_port = (switch_port_t) atoi(mcast_port_str);
190 		}
191 
192 		if (!zstr(argv[2])) {
193 			mcast_control_port = (switch_port_t) atoi(argv[2]);
194 		}
195 
196 		if (!zstr(argv[3])) {
197 			mcast_ttl = atoi(argv[3]);
198 			if (mcast_ttl < 1 || mcast_ttl > 255) {
199 				mcast_ttl = 1;
200 			}
201 		}
202 	}
203 
204 	switch_channel_set_variable_printf(channel, "multicast_ttl", "%d", mcast_ttl);
205 
206 
207 	if (switch_true(switch_channel_get_variable(channel, SWITCH_BYPASS_MEDIA_VARIABLE))) {
208 		switch_core_session_message_t msg = { 0 };
209 
210 		ready = SEND_TYPE_NOMEDIA;
211 
212 		switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, mcast_ip);
213 		switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, mcast_port_str);
214 
215 		/* special answer with the mcast addr */
216 		msg.from = __FILE__;
217 		msg.string_arg = "recvonly";
218 		msg.message_id = SWITCH_MESSAGE_INDICATE_BROADCAST;
219 		switch_core_session_receive_message(session, &msg);
220 	} else {
221 		switch_channel_answer(channel);
222 	}
223 
224 	if (!(source_ip = switch_channel_get_variable(channel, "esf_multicast_bind_ip"))) {
225 		if (!(source_ip = switch_channel_get_variable(channel, "local_ip_v4"))) {
226 			source_ip = "127.0.0.1";
227 		}
228 	}
229 
230 	/* everyone */
231 
232 	if (switch_sockaddr_info_get(&local_addr, source_ip, SWITCH_UNSPEC,
233 								 0, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
234 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "address Error\n");
235 		goto fail;
236 	}
237 
238 	if (switch_socket_create(&socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
239 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 1\n");
240 		goto fail;
241 	}
242 
243 	if (switch_socket_opt_set(socket, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) {
244 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Option Error\n");
245 		goto fail;
246 	}
247 
248 	if (switch_sockaddr_info_get(&control_packet_addr, mcast_ip, SWITCH_UNSPEC,
249 								 mcast_control_port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
250 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 3\n");
251 		goto fail;
252 	}
253 
254 	if (switch_socket_bind(socket, local_addr) != SWITCH_STATUS_SUCCESS) {
255 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket bind Error\n");
256 		goto fail;
257 	}
258 
259 	if (switch_mcast_interface(socket, local_addr) != SWITCH_STATUS_SUCCESS) {
260 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket interface Error\n");
261 		goto fail;
262 	}
263 
264 	if (switch_mcast_join(socket, control_packet_addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
265 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Multicast Error\n");
266 		goto fail;
267 	}
268 
269 
270 	if (switch_mcast_hops(socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) {
271 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n");
272 		goto fail;
273 	}
274 
275 	/* polycom */
276 
277 
278 	if (switch_sockaddr_info_get(&polycom_addr, polycom_ip, SWITCH_UNSPEC,
279 								 polycom_port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
280 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 3\n");
281 		goto fail;
282 	}
283 
284 	if (switch_socket_create(&polycom_socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
285 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 1\n");
286 		goto fail;
287 	}
288 
289 	if (switch_socket_opt_set(polycom_socket, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) {
290 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Option Error\n");
291 		goto fail;
292 	}
293 
294 	if (switch_socket_bind(polycom_socket, local_addr) != SWITCH_STATUS_SUCCESS) {
295 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket bind Error\n");
296 		goto fail;
297 	}
298 
299 
300 	if (switch_mcast_interface(polycom_socket, local_addr) != SWITCH_STATUS_SUCCESS) {
301 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket interface Error\n");
302 		goto fail;
303 	}
304 
305 	if (switch_mcast_join(polycom_socket, polycom_addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
306 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Multicast Error\n");
307 		goto fail;
308 	}
309 
310 
311 	if (switch_mcast_hops(polycom_socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) {
312 		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n");
313 		goto fail;
314 	}
315 
316 
317 	while (!ready) {
318 		status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
319 
320 		if (!SWITCH_READ_ACCEPTABLE(status) || !read_frame) {
321 			goto fail;
322 		}
323 
324 
325 		if (switch_test_flag(read_frame, SFF_CNG)) {
326 			continue;
327 		}
328 
329 
330 		ready = SEND_TYPE_RTP;
331 	}
332 
333 
334 	alert_packet->audio_header.codec = 0x00;
335 	alert_packet->audio_header.flags = 0;
336 
337 	if ((var = switch_channel_get_variable(channel, "esf_multicast_write_codec"))) {
338 		if (!strcasecmp(var, "PCMU")) {
339 			codec_name = var;
340 		} else if (!strcasecmp(var, "G722")) {
341 			codec_name = var;
342 			read_rate = 16000;
343 			alert_packet->audio_header.codec = 0x09;
344 		}
345 	}
346 
347 
348 	if (ready == SEND_TYPE_RTP) {
349 		if (strcasecmp(read_impl.iananame, codec_name)) {
350 			need_transcode = 1;
351 
352 			if (switch_core_codec_init(&codec,
353 									   "L16",
354 									   NULL,
355 									   NULL,
356 									   read_rate,
357 									   20,
358 									   1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
359 									   NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
360 				switch_core_session_set_read_codec(session, &codec);
361 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activation Success\n");
362 			} else {
363 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Activation Fail\n");
364 				goto fail;
365 			}
366 
367 			if (switch_core_codec_init(&write_codec,
368 									   codec_name,
369 									   NULL,
370 									   NULL,
371 									   8000,
372 									   20,
373 									   1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
374 									   NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
375 				switch_core_session_set_read_codec(session, &codec);
376 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activation Success\n");
377 			} else {
378 				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Activation Fail\n");
379 				goto fail;
380 			}
381 		}
382 
383 
384 		if (!(rtp_port = switch_rtp_request_port(source_ip))) {
385 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Port Error\n");
386 			goto fail;
387 		}
388 
389 		rtp_session = switch_rtp_new(source_ip,
390 									 rtp_port,
391 									 mcast_ip,
392 									 mcast_port,
393 									 alert_packet->audio_header.codec,
394 									 160,
395 									 20000, flags, "soft", &err, switch_core_session_get_pool(session), 0, 0);
396 
397 		if (!switch_rtp_ready(rtp_session)) {
398 			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error\n");
399 			goto fail;
400 		}
401 
402 	} else if (ready == SEND_TYPE_NOMEDIA) {
403 		switch_yield(10000);
404 	}
405 
406 	control_packet.unique_id = htonl((u_long) switch_epoch_time_now(NULL));
407 	control_packet.command = htonl(LS_START_BCAST);
408 	control_packet.ip = inet_addr(mcast_ip);
409 	control_packet.port = htonl(mcast_port);
410 
411 	bytes = 16;
412 	switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes);
413 	bytes = 16;
414 	switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes);
415 
416 
417 	if (!(caller_id_name = switch_channel_get_variable(channel, "caller_id_name"))) {
418 		caller_id_name = "FreeSWITCH";
419 	}
420 
421 	strncpy((char *)polycom_packet->cid, caller_id_name, sizeof(polycom_packet->cid));
422 	polycom_packet->cid_len = 13;
423 
424 	polycom_packet->op = 0x0F;
425 	polycom_packet->channel = 0x1a;
426 	polycom_packet->serno = htonl(get_serno());
427 
428 	if ((var = switch_channel_get_variable(channel, "esf_multicast_channel"))) {
429 		int channel_no = atoi(var);
430 
431 		if (channel_no > 0 && channel_no < 255) {
432 			polycom_packet->channel = (uint8_t) channel_no;
433 		}
434 	}
435 
436 	for (x = 0; x < 32; x++) {
437 		bytes = sizeof(polycom_packet_t);
438 		switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_packet, &bytes);
439 		//switch_yield(30000);
440 	}
441 
442 	polycom_packet->op = 0x10;
443 
444 	if ((var = switch_channel_get_variable(channel, "esf_multicast_alert_sound"))) {
445 		switch_ivr_displace_session(session, var, 0, "mr");
446 	}
447 
448 	while (switch_channel_ready(channel)) {
449 
450 		status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
451 
452 		if (!SWITCH_READ_ACCEPTABLE(status)) {
453 			break;
454 		}
455 
456 		if (switch_test_flag(read_frame, SFF_CNG)) {
457 			continue;
458 		}
459 
460 		if (ready == SEND_TYPE_RTP) {
461 			unsigned char *ebuf;
462 			unsigned char encoded_data[4192];
463 			uint32_t encoded_datalen = sizeof(encoded_data);
464 
465 			if (need_transcode) {
466 				uint32_t rate = codec.implementation->actual_samples_per_second;
467 				uint32_t flag = 0;
468 
469 				ebuf = encoded_data;
470 
471 				switch_core_codec_encode(&write_codec,
472 										 &codec,
473 										 read_frame->data,
474 										 read_frame->datalen,
475 										 read_impl.actual_samples_per_second,
476 										 ebuf, &encoded_datalen, &rate, &flag);
477 
478 				if (read_frame->buflen >= encoded_datalen) {
479 					memcpy(read_frame->data, encoded_data, encoded_datalen);
480 				}
481 
482 				read_frame->datalen = encoded_datalen;
483 
484 			} else {
485 				ebuf = read_frame->data;
486 				encoded_datalen = read_frame->datalen;
487 			}
488 
489 			switch_rtp_write_frame(rtp_session, read_frame);
490 
491 			seq += 160;
492 
493 			alert_packet->audio_header.seq = htonl(seq);
494 
495 			if (last_polycom_len) {
496 				memcpy(alert_packet->data, last_polycom_buf, last_polycom_len);
497 				memcpy(alert_packet->data + last_polycom_len, ebuf, encoded_datalen);
498 			} else {
499 				memcpy(alert_packet->data, ebuf, encoded_datalen);
500 			}
501 
502 			bytes = sizeof(*alert_packet) + encoded_datalen + last_polycom_len;
503 
504 			switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_buf, &bytes);
505 
506 			last_polycom_len = encoded_datalen;
507 			memcpy((void *)last_polycom_buf, (void *)ebuf, last_polycom_len);
508 
509 		} else {
510 			bytes = read_frame->packetlen;
511 			switch_socket_sendto(socket, audio_addr, 0, read_frame->packet, &bytes);
512 		}
513 	}
514 
515 	control_packet.unique_id = htonl((u_long) switch_epoch_time_now(NULL));
516 	control_packet.command = htonl(LS_STOP_BCAST);
517 	bytes = 8;
518 	switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes);
519 	bytes = 8;
520 	switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes);
521 
522 
523 	polycom_packet->op = 0xFF;
524 	//switch_yield(50000);
525 
526 	for (x = 0; x < 12; x++) {
527 		bytes = sizeof(*polycom_packet);
528 		switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_packet, &bytes);
529 		//switch_yield(30000);
530 	}
531 
532   fail:
533 
534 	switch_core_session_set_read_codec(session, NULL);
535 	if (switch_core_codec_ready(&codec)) {
536 		switch_core_codec_destroy(&codec);
537 	}
538 
539 	if (rtp_session && ready == SEND_TYPE_RTP && switch_rtp_ready(rtp_session)) {
540 		switch_rtp_destroy(&rtp_session);
541 	}
542 
543 	if (socket) {
544 		switch_socket_close(socket);
545 	}
546 
547 	if (polycom_socket) {
548 		switch_socket_close(polycom_socket);
549 	}
550 
551 	if (rtp_port) {
552 		switch_rtp_release_port(source_ip, rtp_port);
553 	}
554 
555 	dec_serno();
556 
557 	return;
558 }
559 
SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load)560 SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load)
561 {
562 	switch_application_interface_t *app_interface;
563 
564 	switch_mutex_init(&MUTEX, SWITCH_MUTEX_NESTED, pool);
565 
566 	/* connect my internal structure to the blank pointer passed to me */
567 	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
568 	SWITCH_ADD_APP(app_interface, "esf_page_group", NULL, NULL, bcast_function, NULL, SAF_NONE);
569 
570 	/* indicate that the module should continue to be loaded */
571 	return SWITCH_STATUS_SUCCESS;
572 }
573 
574 /* For Emacs:
575  * Local Variables:
576  * mode:c
577  * indent-tabs-mode:t
578  * tab-width:4
579  * c-basic-offset:4
580  * End:
581  * For VIM:
582  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
583  */
584