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