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  * Brian K. West <brian@freeswitch.org>
27  *
28  * mod_b64.c -- The B64 ultra-low delay audio codec (http://www.b64-codec.org/)
29  *
30  */
31 
32 #include "switch.h"
33 
34 SWITCH_MODULE_LOAD_FUNCTION(mod_b64_load);
35 SWITCH_MODULE_DEFINITION(mod_b64, mod_b64_load, NULL, NULL);
36 
37 #define HEADER "----Come to ClueCon Every August!    "
38 #define HLEN strlen(HEADER)
39 
switch_codec_b64_init(switch_codec_t * codec,switch_codec_flag_t flags,const switch_codec_settings_t * codec_settings)40 static switch_status_t switch_codec_b64_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
41 {
42 	return SWITCH_STATUS_SUCCESS;
43 }
44 
switch_codec_b64_destroy(switch_codec_t * codec)45 static switch_status_t switch_codec_b64_destroy(switch_codec_t *codec)
46 {
47 
48 	codec->private_info = NULL;
49 	return SWITCH_STATUS_SUCCESS;
50 }
51 
rot(char * p,char min,char max,int i)52 static int rot(char *p, char min, char max, int i)
53 {
54 	int r = 0;
55 	int c;
56 
57 	if (*p >= min && *p <= max) {
58 		if ((c = *p + i) <= max) {
59 			*p = c;
60 		} else {
61 			*p = *p - i;
62 		}
63 		r++;
64 	}
65 
66 	return r;
67 }
68 
rot13_buffer(char * buf,size_t len)69 static void rot13_buffer(char *buf, size_t len)
70 {
71 	char *p = buf;
72 	char *e = buf + len;
73 
74 	while(p < e) {
75 		if (!rot(p, 'a', 'z', 13)) {
76 			rot(p, 'A', 'Z', 13);
77 		}
78 		p++;
79 	}
80 }
81 
switch_codec_b64_encode(switch_codec_t * codec,switch_codec_t * other_codec,void * decoded_data,uint32_t decoded_data_len,uint32_t decoded_rate,void * encoded_data,uint32_t * encoded_data_len,uint32_t * encoded_rate,unsigned int * flag)82 static switch_status_t switch_codec_b64_encode(switch_codec_t *codec,
83 										  switch_codec_t *other_codec,
84 										  void *decoded_data,
85 										  uint32_t decoded_data_len,
86 										  uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate,
87 										  unsigned int *flag)
88 {
89 	char *p = encoded_data;
90 	strncpy(p, HEADER, *encoded_data_len - HLEN);
91 	p += HLEN;
92 	encoded_data = p;
93 	*encoded_data_len -= HLEN;
94 
95 	switch_b64_encode((unsigned char *) decoded_data, decoded_data_len, (unsigned char *) encoded_data, *encoded_data_len);
96 	*encoded_data_len = strlen(encoded_data);
97 	rot13_buffer(encoded_data, *encoded_data_len);
98 	*encoded_data_len += HLEN;
99 
100 	return SWITCH_STATUS_SUCCESS;
101 
102 }
103 
switch_codec_b64_decode(switch_codec_t * codec,switch_codec_t * other_codec,void * encoded_data,uint32_t encoded_data_len,uint32_t encoded_rate,void * decoded_data,uint32_t * decoded_data_len,uint32_t * decoded_rate,unsigned int * flag)104 static switch_status_t switch_codec_b64_decode(switch_codec_t *codec,
105 										  switch_codec_t *other_codec,
106 										  void *encoded_data,
107 										  uint32_t encoded_data_len,
108 										  uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate,
109 										  unsigned int *flag)
110 {
111 
112 	char *p = encoded_data;
113 
114 	if (strncmp(p, HEADER, HLEN)) {
115 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "HEADER CHECK ERROR!");
116 		return SWITCH_STATUS_FALSE;
117 	}
118 
119 	p += HLEN;
120 	encoded_data = p;
121 	encoded_data_len -= HLEN;
122 
123 	rot13_buffer(encoded_data, encoded_data_len);
124 	switch_b64_decode(encoded_data, decoded_data, *decoded_data_len);
125 	*decoded_data_len = codec->implementation->decoded_bytes_per_packet;
126 
127 	return SWITCH_STATUS_SUCCESS;
128 }
129 
SWITCH_MODULE_LOAD_FUNCTION(mod_b64_load)130 SWITCH_MODULE_LOAD_FUNCTION(mod_b64_load)
131 {
132 	switch_codec_interface_t *codec_interface;
133 	int samples = 160;
134 	int bytes = 320;
135 	int mss = 20000;
136 	int x = 0;
137 	int rate = 8000;
138 	int bits = 171200;
139 
140 	/* connect my internal structure to the blank pointer passed to me */
141 	*module_interface = switch_loadable_module_create_module_interface(pool, modname);
142 
143 	SWITCH_ADD_CODEC(codec_interface, "B64 (STANDARD)");
144 
145 	for (x = 0; x < 3; x++) {
146 		switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO,	/* enumeration defining the type of the codec */
147 											 116,	/* the IANA code number */
148 											 "b64",/* the IANA code name */
149 											 NULL,	/* default fmtp to send (can be overridden by the init function) */
150 											 rate,	/* samples transferred per second */
151 											 rate,	/* actual samples transferred per second */
152 											 bits,	/* bits transferred per second */
153 											 mss,	/* number of microseconds per frame */
154 											 samples,	/* number of samples per frame */
155 											 bytes,	/* number of bytes per frame decompressed */
156 											 0,	/* number of bytes per frame compressed */
157 											 1,	/* number of channels represented */
158 											 1,	/* number of frames per network packet */
159 											 switch_codec_b64_init,	/* function to initialize a codec handle using this implementation */
160 											 switch_codec_b64_encode,	/* function to encode raw data into encoded data */
161 											 switch_codec_b64_decode,	/* function to decode encoded data into raw data */
162 											 switch_codec_b64_destroy);	/* deinitalize a codec handle using this implementation */
163 
164 		bytes *= 2;
165 		samples *= 2;
166 		rate *= 2;
167 		bits *= 2;
168 
169 	}
170 
171 	/* indicate that the module should continue to be loaded */
172 	return SWITCH_STATUS_SUCCESS;
173 }
174 
175 /* For Emacs:
176  * Local Variables:
177  * mode:c
178  * indent-tabs-mode:t
179  * tab-width:4
180  * c-basic-offset:4
181  * End:
182  * For VIM:
183  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
184  */
185 
186