Mon, 27 Apr 2009 12:19:05 +0200
Import new package spec for introduction into repository.
1 Index: cdr/cdr_sqlite.c
2 diff -Nau cdr/cdr_sqlite.c.orig cdr/cdr_sqlite.c
3 --- cdr/cdr_sqlite.c.orig 2007-06-14 23:50:40.000000000 +0200
4 +++ cdr/cdr_sqlite.c 2009-04-24 00:30:33.000000000 +0200
5 @@ -58,7 +58,7 @@
6 #define DATE_FORMAT "%Y-%m-%d %T"
8 static char *name = "sqlite";
9 -static sqlite* db = NULL;
10 +static sqlite3 *db = NULL;
12 AST_MUTEX_DEFINE_STATIC(sqlite_lock);
14 @@ -92,10 +92,10 @@
15 static int sqlite_log(struct ast_cdr *cdr)
16 {
17 int res = 0;
18 - char *zErr = 0;
19 struct tm tm;
20 time_t t;
21 char startstr[80], answerstr[80], endstr[80];
22 + char *cdrsql = 0;
23 int count;
25 ast_mutex_lock(&sqlite_lock);
26 @@ -113,7 +113,7 @@
27 strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
29 for(count=0; count<5; count++) {
30 - res = sqlite_exec_printf(db,
31 + cdrsql = sqlite3_mprintf(
32 "INSERT INTO cdr ("
33 "clid,src,dst,dcontext,"
34 "channel,dstchannel,lastapp,lastdata, "
35 @@ -138,8 +138,7 @@
36 # if LOG_USERFIELD
37 ",'%q'"
38 # endif
39 - ")", NULL, NULL, &zErr,
40 - cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
41 + ")", cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
42 cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
43 startstr, answerstr, endstr,
44 cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
45 @@ -151,16 +150,13 @@
46 ,cdr->userfield
47 # endif
48 );
49 + res = sqlite3_exec(db, cdrsql, 0, 0, 0);
50 + sqlite3_free(cdrsql);
51 if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
52 break;
53 usleep(200);
54 }
56 - if (zErr) {
57 - ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
58 - free(zErr);
59 - }
60 -
61 ast_mutex_unlock(&sqlite_lock);
62 return res;
63 }
64 @@ -168,7 +164,7 @@
65 static int unload_module(void)
66 {
67 if (db)
68 - sqlite_close(db);
69 + sqlite3_close(db);
70 ast_cdr_unregister(name);
71 return 0;
72 }
73 @@ -181,17 +177,16 @@
75 /* is the database there? */
76 snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
77 - db = sqlite_open(fn, 0660, &zErr);
78 + sqlite3_open(fn, &db);
79 if (!db) {
80 - ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
81 - free(zErr);
82 + ast_log(LOG_ERROR, "cdr_sqlite: %s\n", sqlite3_errmsg(db));
83 return -1;
84 }
86 /* is the table there? */
87 - res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
88 + res = sqlite3_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
89 if (res) {
90 - res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
91 + res = sqlite3_exec(db, sql_create_table, NULL, NULL, &zErr);
92 if (res) {
93 ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
94 free(zErr);
95 @@ -210,7 +205,7 @@
97 err:
98 if (db)
99 - sqlite_close(db);
100 + sqlite3_close(db);
101 return -1;
102 }
104 Index: channels/chan_sip.c
105 diff -Nau channels/chan_sip.c.orig channels/chan_sip.c
106 --- channels/chan_sip.c.orig 2009-04-02 19:20:22.000000000 +0200
107 +++ channels/chan_sip.c 2009-04-24 00:30:33.000000000 +0200
108 @@ -7469,7 +7469,7 @@
110 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
111 c = get_in_brackets(from);
112 - if (strncasecmp(c, "sip:", 4)) {
113 + if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
114 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
115 return -1;
116 }
117 @@ -7477,7 +7477,7 @@
119 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
120 c = get_in_brackets(to);
121 - if (strncasecmp(c, "sip:", 4)) {
122 + if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
123 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
124 return -1;
125 }
126 @@ -8004,7 +8004,10 @@
127 of = get_in_brackets(from);
128 ast_string_field_set(p, from, of);
129 if (strncasecmp(of, "sip:", 4))
130 - ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
131 + if (strncasecmp(of, "sips:", 5))
132 + ast_log(LOG_NOTICE, "From address missing 'sip:' or 'sips:', using it anyway\n");
133 + else
134 + of += 5;
135 else
136 of += 4;
137 /* Get just the username part */
138 @@ -8280,7 +8283,10 @@
140 /* Make sure it's a SIP URL */
141 if (strncasecmp(contact, "sip:", 4)) {
142 - ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
143 + if (strncasecmp(contact, "sips:", 5))
144 + ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip: or sips:) trying to use anyway\n", contact);
145 + else
146 + contact += 5;
147 } else
148 contact += 4;
150 @@ -8409,7 +8415,10 @@
152 /* Make sure it's a SIP URL */
153 if (strncasecmp(curi, "sip:", 4)) {
154 - ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
155 + if (strncasecmp(curi, "sips:", 5))
156 + ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip: or sips:) trying to use anyway\n", curi);
157 + else
158 + curi += 5;
159 } else
160 curi += 4;
161 /* Ditch q */
162 @@ -9000,9 +9009,12 @@
164 if (!strncasecmp(c, "sip:", 4)) {
165 name = c + 4;
166 + }
167 + else if (!strncasecmp(c, "sips:", 5)) {
168 + name = c + 5;
169 } else {
170 name = c;
171 - ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
172 + ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip: or sips:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
173 }
175 /* Strip off the domain name */
176 @@ -9162,10 +9174,15 @@
177 return 0;
178 c = get_in_brackets(tmp);
179 if (strncasecmp(c, "sip:", 4)) {
180 - ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c);
181 - return -1;
182 + if (strncasecmp(c, "sips:", 5)) {
183 + ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c);
184 + return -1;
185 + }
186 + else
187 + c += 5;
188 }
189 - c += 4;
190 + else
191 + c += 4;
192 a = c;
193 strsep(&a, "@;"); /* trim anything after @ or ; */
194 if (sip_debug_test_pvt(p))
195 @@ -9200,10 +9217,15 @@
196 uri = get_in_brackets(tmp);
198 if (strncasecmp(uri, "sip:", 4)) {
199 - ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri);
200 - return -1;
201 + if (strncasecmp(uri, "sips:", 5)) {
202 + ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri);
203 + return -1;
204 + }
205 + else
206 + uri += 5;
207 }
208 - uri += 4;
209 + else
210 + uri += 4;
212 /* Now find the From: caller ID and name */
213 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
214 @@ -9217,10 +9239,15 @@
216 if (!ast_strlen_zero(from)) {
217 if (strncasecmp(from, "sip:", 4)) {
218 - ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from);
219 - return -1;
220 + if (strncasecmp(from, "sips:", 5)) {
221 + ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from);
222 + return -1;
223 + }
224 + else
225 + from += 5;
226 }
227 - from += 4;
228 + else
229 + from += 4;
230 if ((a = strchr(from, '@')))
231 *a++ = '\0';
232 else
233 @@ -9397,10 +9424,15 @@
234 ast_uri_decode(refer_to);
236 if (strncasecmp(refer_to, "sip:", 4)) {
237 - ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to);
238 - return -3;
239 + if (strncasecmp(refer_to, "sips:", 5)) {
240 + ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to);
241 + return -3;
242 + }
243 + else
244 + refer_to += 5; /* Skip sips: */
245 }
246 - refer_to += 4; /* Skip sip: */
247 + else
248 + refer_to += 4; /* Skip sip: */
250 /* Get referred by header if it exists */
251 p_referred_by = get_header(req, "Referred-By");
252 @@ -9417,9 +9449,13 @@
253 }
255 referred_by_uri = get_in_brackets(h_referred_by);
256 - if(strncasecmp(referred_by_uri, "sip:", 4)) {
257 - ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
258 - referred_by_uri = (char *) NULL;
259 + if (strncasecmp(referred_by_uri, "sip:", 4)) {
260 + if (strncasecmp(referred_by_uri, "sips:", 5)) {
261 + ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
262 + referred_by_uri = (char *) NULL;
263 + }
264 + else
265 + referred_by_uri += 5; /* Skip sips: */
266 } else {
267 referred_by_uri += 4; /* Skip sip: */
268 }
269 @@ -9547,10 +9583,15 @@
270 ast_uri_decode(c);
272 if (strncasecmp(c, "sip:", 4)) {
273 - ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c);
274 - return -1;
275 + if (strncasecmp(c, "sips:", 5)) {
276 + ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c);
277 + return -1;
278 + }
279 + else
280 + c += 5;
281 }
282 - c += 4;
283 + else
284 + c += 4;
285 if ((a = strchr(c, ';'))) /* Remove arguments */
286 *a = '\0';
288 @@ -9761,6 +9802,8 @@
289 t = uri2;
290 if (!strncasecmp(t, "sip:", 4))
291 t+= 4;
292 + else if (!strncasecmp(t, "sips:", 5))
293 + t+= 5;
294 ast_string_field_set(p, exten, t);
295 t = strchr(p->exten, '@');
296 if (t)
297 @@ -9771,7 +9814,10 @@
298 /* save the URI part of the From header */
299 ast_string_field_set(p, from, of);
300 if (strncasecmp(of, "sip:", 4)) {
301 - ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
302 + if (strncasecmp(of, "sips:", 5))
303 + ast_log(LOG_NOTICE, "From address missing 'sip:' or 'sips:', using it anyway\n");
304 + else
305 + of += 5;
306 } else
307 of += 4;
308 /* Get just the username part */
309 @@ -12379,6 +12425,8 @@
310 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
311 if (!strncasecmp(s, "sip:", 4))
312 s += 4;
313 + else if (!strncasecmp(s, "sips:", 5))
314 + s += 5;
315 e = strchr(s, ';');
316 if (e)
317 *e = '\0';
318 @@ -12404,6 +12452,8 @@
320 if (!strncasecmp(s, "sip:", 4))
321 s += 4;
322 + else if (!strncasecmp(s, "sips:", 5))
323 + s += 5;
324 if (option_debug > 1)
325 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
326 if (p->owner) {
327 Index: codecs/codec_g722.c
328 diff -Nau codecs/codec_g722.c.orig codecs/codec_g722.c
329 --- codecs/codec_g722.c.orig 1970-01-01 01:00:00.000000000 +0100
330 +++ codecs/codec_g722.c 2009-04-24 00:30:33.000000000 +0200
331 @@ -0,0 +1,306 @@
332 +/*
333 + * Asterisk -- An open source telephony toolkit.
334 + *
335 + * Copyright (C) 1999 - 2008, Digium, Inc.
336 + *
337 + * Matthew Fredrickson <creslin@digium.com>
338 + * Russell Bryant <russell@digium.com>
339 + *
340 + * Special thanks to Steve Underwood for the implementation
341 + * and for doing the 8khz<->g.722 direct translation code.
342 + *
343 + * See http://www.asterisk.org for more information about
344 + * the Asterisk project. Please do not directly contact
345 + * any of the maintainers of this project for assistance;
346 + * the project provides a web site, mailing lists and IRC
347 + * channels for your use.
348 + *
349 + * This program is free software, distributed under the terms of
350 + * the GNU General Public License Version 2. See the LICENSE file
351 + * at the top of the source tree.
352 + */
353 +
354 +/*! \file
355 + *
356 + * \brief codec_g722.c - translate between signed linear and ITU G.722-64kbps
357 + *
358 + * \author Matthew Fredrickson <creslin@digium.com>
359 + * \author Russell Bryant <russell@digium.com>
360 + *
361 + * \arg http://soft-switch.org/downloads/non-gpl-bits.tgz
362 + * \arg http://lists.digium.com/pipermail/asterisk-dev/2006-September/022866.html
363 + *
364 + * \ingroup codecs
365 + */
366 +
367 +#include "asterisk.h"
368 +
369 +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 106501 $")
370 +
371 +#include "asterisk/linkedlists.h"
372 +#include "asterisk/module.h"
373 +#include "asterisk/config.h"
374 +#include "asterisk/options.h"
375 +#include "asterisk/translate.h"
376 +#include "asterisk/utils.h"
377 +
378 +#define BUFFER_SAMPLES 8096 /* size for the translation buffers */
379 +#define BUF_SHIFT 5
380 +
381 +/* Sample frame data */
382 +
383 +#include "g722/g722.h"
384 +#include "slin_g722_ex.h"
385 +#include "g722_slin_ex.h"
386 +
387 +struct g722_encoder_pvt {
388 + g722_encode_state_t g722;
389 +};
390 +
391 +struct g722_decoder_pvt {
392 + g722_decode_state_t g722;
393 +};
394 +
395 +/*! \brief init a new instance of g722_encoder_pvt. */
396 +static int lintog722_new(struct ast_trans_pvt *pvt)
397 +{
398 + struct g722_encoder_pvt *tmp = pvt->pvt;
399 +
400 + g722_encode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
401 +
402 + return 0;
403 +}
404 +
405 +static int lin16tog722_new(struct ast_trans_pvt *pvt)
406 +{
407 + struct g722_encoder_pvt *tmp = pvt->pvt;
408 +
409 + g722_encode_init(&tmp->g722, 64000, 0);
410 +
411 + return 0;
412 +}
413 +
414 +/*! \brief init a new instance of g722_encoder_pvt. */
415 +static int g722tolin_new(struct ast_trans_pvt *pvt)
416 +{
417 + struct g722_decoder_pvt *tmp = pvt->pvt;
418 +
419 + g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
420 +
421 + return 0;
422 +}
423 +
424 +static int g722tolin16_new(struct ast_trans_pvt *pvt)
425 +{
426 + struct g722_decoder_pvt *tmp = pvt->pvt;
427 +
428 + g722_decode_init(&tmp->g722, 64000, 0);
429 +
430 + return 0;
431 +}
432 +
433 +static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
434 +{
435 + struct g722_decoder_pvt *tmp = pvt->pvt;
436 + int out_samples;
437 + int in_samples;
438 +
439 + /* g722_decode expects the samples to be in the invalid samples / 2 format */
440 + in_samples = f->samples / 2;
441 +
442 + out_samples = g722_decode(&tmp->g722, (int16_t *) &pvt->outbuf[pvt->samples * sizeof(int16_t)],
443 + (uint8_t *) f->data, in_samples);
444 +
445 + pvt->samples += out_samples;
446 +
447 + pvt->datalen += (out_samples * sizeof(int16_t));
448 +
449 + return 0;
450 +}
451 +
452 +static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
453 +{
454 + struct g722_encoder_pvt *tmp = pvt->pvt;
455 + int outlen;
456 +
457 + outlen = g722_encode(&tmp->g722, (uint8_t *) (&pvt->outbuf[pvt->datalen]),
458 + (int16_t *) f->data, f->samples);
459 +
460 + pvt->samples += outlen * 2;
461 +
462 + pvt->datalen += outlen;
463 +
464 + return 0;
465 +}
466 +
467 +static struct ast_frame *g722tolin_sample(void)
468 +{
469 + static struct ast_frame f = {
470 + .frametype = AST_FRAME_VOICE,
471 + .subclass = AST_FORMAT_G722,
472 + .datalen = sizeof(g722_slin_ex),
473 + .samples = sizeof(g722_slin_ex) * 2,
474 + .src = __PRETTY_FUNCTION__,
475 + .data = g722_slin_ex,
476 + };
477 +
478 + return &f;
479 +}
480 +
481 +static struct ast_frame *g722tolin16_sample(void)
482 +{
483 + static struct ast_frame f = {
484 + .frametype = AST_FRAME_VOICE,
485 + .subclass = AST_FORMAT_G722,
486 + .datalen = sizeof(slin_g722_ex),
487 + .samples = sizeof(slin_g722_ex) * 2,
488 + .src = __PRETTY_FUNCTION__,
489 + .data = slin_g722_ex,
490 + };
491 +
492 + return &f;
493 +}
494 +
495 +static struct ast_frame *lintog722_sample (void)
496 +{
497 + static struct ast_frame f = {
498 + .frametype = AST_FRAME_VOICE,
499 + .subclass = AST_FORMAT_SLINEAR,
500 + .datalen = sizeof(slin_g722_ex),
501 + .samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]),
502 + .src = __PRETTY_FUNCTION__,
503 + .data = slin_g722_ex,
504 + };
505 +
506 + return &f;
507 +}
508 +
509 +static struct ast_frame *lin16tog722_sample (void)
510 +{
511 + static struct ast_frame f = {
512 + .frametype = AST_FRAME_VOICE,
513 + .subclass = AST_FORMAT_SLINEAR16,
514 + .datalen = sizeof(slin_g722_ex),
515 + .samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]),
516 + .src = __PRETTY_FUNCTION__,
517 + .data = slin_g722_ex,
518 + };
519 +
520 + return &f;
521 +}
522 +
523 +static struct ast_translator g722tolin = {
524 + .name = "g722tolin",
525 + .srcfmt = AST_FORMAT_G722,
526 + .dstfmt = AST_FORMAT_SLINEAR,
527 + .newpvt = g722tolin_new, /* same for both directions */
528 + .framein = g722tolin_framein,
529 + .sample = g722tolin_sample,
530 + .desc_size = sizeof(struct g722_decoder_pvt),
531 + .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
532 + .buf_size = BUFFER_SAMPLES,
533 + .plc_samples = 160,
534 +};
535 +
536 +static struct ast_translator lintog722 = {
537 + .name = "lintog722",
538 + .srcfmt = AST_FORMAT_SLINEAR,
539 + .dstfmt = AST_FORMAT_G722,
540 + .newpvt = lintog722_new, /* same for both directions */
541 + .framein = lintog722_framein,
542 + .sample = lintog722_sample,
543 + .desc_size = sizeof(struct g722_encoder_pvt),
544 + .buffer_samples = BUFFER_SAMPLES * 2,
545 + .buf_size = BUFFER_SAMPLES,
546 +};
547 +
548 +static struct ast_translator g722tolin16 = {
549 + .name = "g722tolin16",
550 + .srcfmt = AST_FORMAT_G722,
551 + .dstfmt = AST_FORMAT_SLINEAR16,
552 + .newpvt = g722tolin16_new, /* same for both directions */
553 + .framein = g722tolin_framein,
554 + .sample = g722tolin16_sample,
555 + .desc_size = sizeof(struct g722_decoder_pvt),
556 + .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
557 + .buf_size = BUFFER_SAMPLES,
558 + .plc_samples = 160,
559 +};
560 +
561 +static struct ast_translator lin16tog722 = {
562 + .name = "lin16tog722",
563 + .srcfmt = AST_FORMAT_SLINEAR16,
564 + .dstfmt = AST_FORMAT_G722,
565 + .newpvt = lin16tog722_new, /* same for both directions */
566 + .framein = lintog722_framein,
567 + .sample = lin16tog722_sample,
568 + .desc_size = sizeof(struct g722_encoder_pvt),
569 + .buffer_samples = BUFFER_SAMPLES * 2,
570 + .buf_size = BUFFER_SAMPLES,
571 +};
572 +
573 +static int parse_config(int reload)
574 +{
575 + struct ast_variable *var;
576 + struct ast_config *cfg = ast_config_load("codecs.conf");
577 +
578 + if (cfg == NULL)
579 + return 0;
580 + if (cfg == CONFIG_STATUS_FILEUNCHANGED)
581 + return 0;
582 + for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
583 + if (!strcasecmp(var->name, "genericplc")) {
584 + g722tolin.useplc = ast_true(var->value) ? 1 : 0;
585 + if (option_verbose > 2)
586 + ast_verbose(VERBOSE_PREFIX_3 "codec_g722: %susing generic PLC\n",
587 + g722tolin.useplc ? "" : "not ");
588 + }
589 + }
590 + ast_config_destroy(cfg);
591 + return 0;
592 +}
593 +
594 +static int reload(void)
595 +{
596 + if (parse_config(1))
597 + return AST_MODULE_LOAD_DECLINE;
598 + return AST_MODULE_LOAD_SUCCESS;
599 +}
600 +
601 +static int unload_module(void)
602 +{
603 + int res = 0;
604 +
605 + res |= ast_unregister_translator(&g722tolin);
606 + res |= ast_unregister_translator(&lintog722);
607 + res |= ast_unregister_translator(&g722tolin16);
608 + res |= ast_unregister_translator(&lin16tog722);
609 +
610 + return res;
611 +}
612 +
613 +static int load_module(void)
614 +{
615 + int res = 0;
616 +
617 + if (parse_config(0))
618 + return AST_MODULE_LOAD_DECLINE;
619 +
620 + res |= ast_register_translator(&g722tolin);
621 + res |= ast_register_translator(&lintog722);
622 + res |= ast_register_translator(&g722tolin16);
623 + res |= ast_register_translator(&lin16tog722);
624 +
625 + if (res) {
626 + unload_module();
627 + return AST_MODULE_LOAD_FAILURE;
628 + }
629 +
630 + return AST_MODULE_LOAD_SUCCESS;
631 +}
632 +
633 +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder",
634 + .load = load_module,
635 + .unload = unload_module,
636 + .reload = reload,
637 + );
638 Index: codecs/g722/g722_decode.c
639 diff -Nau codecs/g722/g722_decode.c.orig codecs/g722/g722_decode.c
640 --- codecs/g722/g722_decode.c.orig 1970-01-01 01:00:00.000000000 +0100
641 +++ codecs/g722/g722_decode.c 2009-04-24 00:30:33.000000000 +0200
642 @@ -0,0 +1,398 @@
643 +/*
644 + * SpanDSP - a series of DSP components for telephony
645 + *
646 + * g722_decode.c - The ITU G.722 codec, decode part.
647 + *
648 + * Written by Steve Underwood <steveu@coppice.org>
649 + *
650 + * Copyright (C) 2005 Steve Underwood
651 + *
652 + * Despite my general liking of the GPL, I place my own contributions
653 + * to this code in the public domain for the benefit of all mankind -
654 + * even the slimy ones who might try to proprietize my work and use it
655 + * to my detriment.
656 + *
657 + * Based in part on a single channel G.722 codec which is:
658 + *
659 + * Copyright (c) CMU 1993
660 + * Computer Science, Speech Group
661 + * Chengxiang Lu and Alex Hauptmann
662 + *
663 + * $Id: g722_decode.c 48661 2006-12-21 00:08:21Z mattf $
664 + */
665 +
666 +/*! \file */
667 +
668 +#ifdef HAVE_CONFIG_H
669 +#include <config.h>
670 +#endif
671 +
672 +#include <stdio.h>
673 +#include <inttypes.h>
674 +#include <memory.h>
675 +#include <stdlib.h>
676 +#if 0
677 +#include <tgmath.h>
678 +#endif
679 +
680 +#include "g722.h"
681 +
682 +#if !defined(FALSE)
683 +#define FALSE 0
684 +#endif
685 +#if !defined(TRUE)
686 +#define TRUE (!FALSE)
687 +#endif
688 +
689 +static __inline__ int16_t saturate(int32_t amp)
690 +{
691 + int16_t amp16;
692 +
693 + /* Hopefully this is optimised for the common case - not clipping */
694 + amp16 = (int16_t) amp;
695 + if (amp == amp16)
696 + return amp16;
697 + if (amp > INT16_MAX)
698 + return INT16_MAX;
699 + return INT16_MIN;
700 +}
701 +/*- End of function --------------------------------------------------------*/
702 +
703 +static void block4(g722_decode_state_t *s, int band, int d);
704 +
705 +static void block4(g722_decode_state_t *s, int band, int d)
706 +{
707 + int wd1;
708 + int wd2;
709 + int wd3;
710 + int i;
711 +
712 + /* Block 4, RECONS */
713 + s->band[band].d[0] = d;
714 + s->band[band].r[0] = saturate(s->band[band].s + d);
715 +
716 + /* Block 4, PARREC */
717 + s->band[band].p[0] = saturate(s->band[band].sz + d);
718 +
719 + /* Block 4, UPPOL2 */
720 + for (i = 0; i < 3; i++)
721 + s->band[band].sg[i] = s->band[band].p[i] >> 15;
722 + wd1 = saturate(s->band[band].a[1] << 2);
723 +
724 + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
725 + if (wd2 > 32767)
726 + wd2 = 32767;
727 + wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128;
728 + wd3 += (wd2 >> 7);
729 + wd3 += (s->band[band].a[2]*32512) >> 15;
730 + if (wd3 > 12288)
731 + wd3 = 12288;
732 + else if (wd3 < -12288)
733 + wd3 = -12288;
734 + s->band[band].ap[2] = wd3;
735 +
736 + /* Block 4, UPPOL1 */
737 + s->band[band].sg[0] = s->band[band].p[0] >> 15;
738 + s->band[band].sg[1] = s->band[band].p[1] >> 15;
739 + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
740 + wd2 = (s->band[band].a[1]*32640) >> 15;
741 +
742 + s->band[band].ap[1] = saturate(wd1 + wd2);
743 + wd3 = saturate(15360 - s->band[band].ap[2]);
744 + if (s->band[band].ap[1] > wd3)
745 + s->band[band].ap[1] = wd3;
746 + else if (s->band[band].ap[1] < -wd3)
747 + s->band[band].ap[1] = -wd3;
748 +
749 + /* Block 4, UPZERO */
750 + wd1 = (d == 0) ? 0 : 128;
751 + s->band[band].sg[0] = d >> 15;
752 + for (i = 1; i < 7; i++)
753 + {
754 + s->band[band].sg[i] = s->band[band].d[i] >> 15;
755 + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
756 + wd3 = (s->band[band].b[i]*32640) >> 15;
757 + s->band[band].bp[i] = saturate(wd2 + wd3);
758 + }
759 +
760 + /* Block 4, DELAYA */
761 + for (i = 6; i > 0; i--)
762 + {
763 + s->band[band].d[i] = s->band[band].d[i - 1];
764 + s->band[band].b[i] = s->band[band].bp[i];
765 + }
766 +
767 + for (i = 2; i > 0; i--)
768 + {
769 + s->band[band].r[i] = s->band[band].r[i - 1];
770 + s->band[band].p[i] = s->band[band].p[i - 1];
771 + s->band[band].a[i] = s->band[band].ap[i];
772 + }
773 +
774 + /* Block 4, FILTEP */
775 + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
776 + wd1 = (s->band[band].a[1]*wd1) >> 15;
777 + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
778 + wd2 = (s->band[band].a[2]*wd2) >> 15;
779 + s->band[band].sp = saturate(wd1 + wd2);
780 +
781 + /* Block 4, FILTEZ */
782 + s->band[band].sz = 0;
783 + for (i = 6; i > 0; i--)
784 + {
785 + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
786 + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
787 + }
788 + s->band[band].sz = saturate(s->band[band].sz);
789 +
790 + /* Block 4, PREDIC */
791 + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
792 +}
793 +/*- End of function --------------------------------------------------------*/
794 +
795 +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options)
796 +{
797 + if (s == NULL)
798 + {
799 + if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL)
800 + return NULL;
801 + }
802 + memset(s, 0, sizeof(*s));
803 + if (rate == 48000)
804 + s->bits_per_sample = 6;
805 + else if (rate == 56000)
806 + s->bits_per_sample = 7;
807 + else
808 + s->bits_per_sample = 8;
809 + if ((options & G722_SAMPLE_RATE_8000))
810 + s->eight_k = TRUE;
811 + if ((options & G722_PACKED) && s->bits_per_sample != 8)
812 + s->packed = TRUE;
813 + else
814 + s->packed = FALSE;
815 + s->band[0].det = 32;
816 + s->band[1].det = 8;
817 + return s;
818 +}
819 +/*- End of function --------------------------------------------------------*/
820 +
821 +int g722_decode_release(g722_decode_state_t *s)
822 +{
823 + free(s);
824 + return 0;
825 +}
826 +/*- End of function --------------------------------------------------------*/
827 +
828 +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
829 +{
830 + static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
831 + static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 };
832 + static const int ilb[32] =
833 + {
834 + 2048, 2093, 2139, 2186, 2233, 2282, 2332,
835 + 2383, 2435, 2489, 2543, 2599, 2656, 2714,
836 + 2774, 2834, 2896, 2960, 3025, 3091, 3158,
837 + 3228, 3298, 3371, 3444, 3520, 3597, 3676,
838 + 3756, 3838, 3922, 4008
839 + };
840 + static const int wh[3] = {0, -214, 798};
841 + static const int rh2[4] = {2, 1, 2, 1};
842 + static const int qm2[4] = {-7408, -1616, 7408, 1616};
843 + static const int qm4[16] =
844 + {
845 + 0, -20456, -12896, -8968,
846 + -6288, -4240, -2584, -1200,
847 + 20456, 12896, 8968, 6288,
848 + 4240, 2584, 1200, 0
849 + };
850 + static const int qm5[32] =
851 + {
852 + -280, -280, -23352, -17560,
853 + -14120, -11664, -9752, -8184,
854 + -6864, -5712, -4696, -3784,
855 + -2960, -2208, -1520, -880,
856 + 23352, 17560, 14120, 11664,
857 + 9752, 8184, 6864, 5712,
858 + 4696, 3784, 2960, 2208,
859 + 1520, 880, 280, -280
860 + };
861 + static const int qm6[64] =
862 + {
863 + -136, -136, -136, -136,
864 + -24808, -21904, -19008, -16704,
865 + -14984, -13512, -12280, -11192,
866 + -10232, -9360, -8576, -7856,
867 + -7192, -6576, -6000, -5456,
868 + -4944, -4464, -4008, -3576,
869 + -3168, -2776, -2400, -2032,
870 + -1688, -1360, -1040, -728,
871 + 24808, 21904, 19008, 16704,
872 + 14984, 13512, 12280, 11192,
873 + 10232, 9360, 8576, 7856,
874 + 7192, 6576, 6000, 5456,
875 + 4944, 4464, 4008, 3576,
876 + 3168, 2776, 2400, 2032,
877 + 1688, 1360, 1040, 728,
878 + 432, 136, -432, -136
879 + };
880 + static const int qmf_coeffs[12] =
881 + {
882 + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
883 + };
884 +
885 + int dlowt;
886 + int rlow;
887 + int ihigh;
888 + int dhigh;
889 + int rhigh;
890 + int xout1;
891 + int xout2;
892 + int wd1;
893 + int wd2;
894 + int wd3;
895 + int code;
896 + int outlen;
897 + int i;
898 + int j;
899 +
900 + outlen = 0;
901 + rhigh = 0;
902 + for (j = 0; j < len; )
903 + {
904 + if (s->packed)
905 + {
906 + /* Unpack the code bits */
907 + if (s->in_bits < s->bits_per_sample)
908 + {
909 + s->in_buffer |= (g722_data[j++] << s->in_bits);
910 + s->in_bits += 8;
911 + }
912 + code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
913 + s->in_buffer >>= s->bits_per_sample;
914 + s->in_bits -= s->bits_per_sample;
915 + }
916 + else
917 + {
918 + code = g722_data[j++];
919 + }
920 +
921 + switch (s->bits_per_sample)
922 + {
923 + default:
924 + case 8:
925 + wd1 = code & 0x3F;
926 + ihigh = (code >> 6) & 0x03;
927 + wd2 = qm6[wd1];
928 + wd1 >>= 2;
929 + break;
930 + case 7:
931 + wd1 = code & 0x1F;
932 + ihigh = (code >> 5) & 0x03;
933 + wd2 = qm5[wd1];
934 + wd1 >>= 1;
935 + break;
936 + case 6:
937 + wd1 = code & 0x0F;
938 + ihigh = (code >> 4) & 0x03;
939 + wd2 = qm4[wd1];
940 + break;
941 + }
942 + /* Block 5L, LOW BAND INVQBL */
943 + wd2 = (s->band[0].det*wd2) >> 15;
944 + /* Block 5L, RECONS */
945 + rlow = s->band[0].s + wd2;
946 + /* Block 6L, LIMIT */
947 + if (rlow > 16383)
948 + rlow = 16383;
949 + else if (rlow < -16384)
950 + rlow = -16384;
951 +
952 + /* Block 2L, INVQAL */
953 + wd2 = qm4[wd1];
954 + dlowt = (s->band[0].det*wd2) >> 15;
955 +
956 + /* Block 3L, LOGSCL */
957 + wd2 = rl42[wd1];
958 + wd1 = (s->band[0].nb*127) >> 7;
959 + wd1 += wl[wd2];
960 + if (wd1 < 0)
961 + wd1 = 0;
962 + else if (wd1 > 18432)
963 + wd1 = 18432;
964 + s->band[0].nb = wd1;
965 +
966 + /* Block 3L, SCALEL */
967 + wd1 = (s->band[0].nb >> 6) & 31;
968 + wd2 = 8 - (s->band[0].nb >> 11);
969 + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
970 + s->band[0].det = wd3 << 2;
971 +
972 + block4(s, 0, dlowt);
973 +
974 + if (!s->eight_k)
975 + {
976 + /* Block 2H, INVQAH */
977 + wd2 = qm2[ihigh];
978 + dhigh = (s->band[1].det*wd2) >> 15;
979 + /* Block 5H, RECONS */
980 + rhigh = dhigh + s->band[1].s;
981 + /* Block 6H, LIMIT */
982 + if (rhigh > 16383)
983 + rhigh = 16383;
984 + else if (rhigh < -16384)
985 + rhigh = -16384;
986 +
987 + /* Block 2H, INVQAH */
988 + wd2 = rh2[ihigh];
989 + wd1 = (s->band[1].nb*127) >> 7;
990 + wd1 += wh[wd2];
991 + if (wd1 < 0)
992 + wd1 = 0;
993 + else if (wd1 > 22528)
994 + wd1 = 22528;
995 + s->band[1].nb = wd1;
996 +
997 + /* Block 3H, SCALEH */
998 + wd1 = (s->band[1].nb >> 6) & 31;
999 + wd2 = 10 - (s->band[1].nb >> 11);
1000 + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
1001 + s->band[1].det = wd3 << 2;
1002 +
1003 + block4(s, 1, dhigh);
1004 + }
1005 +
1006 + if (s->itu_test_mode)
1007 + {
1008 + amp[outlen++] = (int16_t) (rlow << 1);
1009 + amp[outlen++] = (int16_t) (rhigh << 1);
1010 + }
1011 + else
1012 + {
1013 + if (s->eight_k)
1014 + {
1015 + amp[outlen++] = (int16_t) rlow;
1016 + }
1017 + else
1018 + {
1019 + /* Apply the receive QMF */
1020 + for (i = 0; i < 22; i++)
1021 + s->x[i] = s->x[i + 2];
1022 + s->x[22] = rlow + rhigh;
1023 + s->x[23] = rlow - rhigh;
1024 +
1025 + xout1 = 0;
1026 + xout2 = 0;
1027 + for (i = 0; i < 12; i++)
1028 + {
1029 + xout2 += s->x[2*i]*qmf_coeffs[i];
1030 + xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
1031 + }
1032 + amp[outlen++] = (int16_t) (xout1 >> 12);
1033 + amp[outlen++] = (int16_t) (xout2 >> 12);
1034 + }
1035 + }
1036 + }
1037 + return outlen;
1038 +}
1039 +/*- End of function --------------------------------------------------------*/
1040 +/*- End of file ------------------------------------------------------------*/
1041 Index: codecs/g722/g722_encode.c
1042 diff -Nau codecs/g722/g722_encode.c.orig codecs/g722/g722_encode.c
1043 --- codecs/g722/g722_encode.c.orig 1970-01-01 01:00:00.000000000 +0100
1044 +++ codecs/g722/g722_encode.c 2009-04-24 00:30:33.000000000 +0200
1045 @@ -0,0 +1,400 @@
1046 +/*
1047 + * SpanDSP - a series of DSP components for telephony
1048 + *
1049 + * g722_encode.c - The ITU G.722 codec, encode part.
1050 + *
1051 + * Written by Steve Underwood <steveu@coppice.org>
1052 + *
1053 + * Copyright (C) 2005 Steve Underwood
1054 + *
1055 + * All rights reserved.
1056 + *
1057 + * Despite my general liking of the GPL, I place my own contributions
1058 + * to this code in the public domain for the benefit of all mankind -
1059 + * even the slimy ones who might try to proprietize my work and use it
1060 + * to my detriment.
1061 + *
1062 + * Based on a single channel 64kbps only G.722 codec which is:
1063 + *
1064 + ***** Copyright (c) CMU 1993 *****
1065 + * Computer Science, Speech Group
1066 + * Chengxiang Lu and Alex Hauptmann
1067 + *
1068 + * $Id: g722_encode.c 48661 2006-12-21 00:08:21Z mattf $
1069 + */
1070 +
1071 +/*! \file */
1072 +
1073 +#ifdef HAVE_CONFIG_H
1074 +#include <config.h>
1075 +#endif
1076 +
1077 +#include <stdio.h>
1078 +#include <inttypes.h>
1079 +#include <memory.h>
1080 +#include <stdlib.h>
1081 +#if 0
1082 +#include <tgmath.h>
1083 +#endif
1084 +
1085 +#include "g722.h"
1086 +
1087 +#if !defined(FALSE)
1088 +#define FALSE 0
1089 +#endif
1090 +#if !defined(TRUE)
1091 +#define TRUE (!FALSE)
1092 +#endif
1093 +
1094 +static __inline__ int16_t saturate(int32_t amp)
1095 +{
1096 + int16_t amp16;
1097 +
1098 + /* Hopefully this is optimised for the common case - not clipping */
1099 + amp16 = (int16_t) amp;
1100 + if (amp == amp16)
1101 + return amp16;
1102 + if (amp > INT16_MAX)
1103 + return INT16_MAX;
1104 + return INT16_MIN;
1105 +}
1106 +/*- End of function --------------------------------------------------------*/
1107 +
1108 +static void block4(g722_encode_state_t *s, int band, int d)
1109 +{
1110 + int wd1;
1111 + int wd2;
1112 + int wd3;
1113 + int i;
1114 +
1115 + /* Block 4, RECONS */
1116 + s->band[band].d[0] = d;
1117 + s->band[band].r[0] = saturate(s->band[band].s + d);
1118 +
1119 + /* Block 4, PARREC */
1120 + s->band[band].p[0] = saturate(s->band[band].sz + d);
1121 +
1122 + /* Block 4, UPPOL2 */
1123 + for (i = 0; i < 3; i++)
1124 + s->band[band].sg[i] = s->band[band].p[i] >> 15;
1125 + wd1 = saturate(s->band[band].a[1] << 2);
1126 +
1127 + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
1128 + if (wd2 > 32767)
1129 + wd2 = 32767;
1130 + wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128);
1131 + wd3 += (s->band[band].a[2]*32512) >> 15;
1132 + if (wd3 > 12288)
1133 + wd3 = 12288;
1134 + else if (wd3 < -12288)
1135 + wd3 = -12288;
1136 + s->band[band].ap[2] = wd3;
1137 +
1138 + /* Block 4, UPPOL1 */
1139 + s->band[band].sg[0] = s->band[band].p[0] >> 15;
1140 + s->band[band].sg[1] = s->band[band].p[1] >> 15;
1141 + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
1142 + wd2 = (s->band[band].a[1]*32640) >> 15;
1143 +
1144 + s->band[band].ap[1] = saturate(wd1 + wd2);
1145 + wd3 = saturate(15360 - s->band[band].ap[2]);
1146 + if (s->band[band].ap[1] > wd3)
1147 + s->band[band].ap[1] = wd3;
1148 + else if (s->band[band].ap[1] < -wd3)
1149 + s->band[band].ap[1] = -wd3;
1150 +
1151 + /* Block 4, UPZERO */
1152 + wd1 = (d == 0) ? 0 : 128;
1153 + s->band[band].sg[0] = d >> 15;
1154 + for (i = 1; i < 7; i++)
1155 + {
1156 + s->band[band].sg[i] = s->band[band].d[i] >> 15;
1157 + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
1158 + wd3 = (s->band[band].b[i]*32640) >> 15;
1159 + s->band[band].bp[i] = saturate(wd2 + wd3);
1160 + }
1161 +
1162 + /* Block 4, DELAYA */
1163 + for (i = 6; i > 0; i--)
1164 + {
1165 + s->band[band].d[i] = s->band[band].d[i - 1];
1166 + s->band[band].b[i] = s->band[band].bp[i];
1167 + }
1168 +
1169 + for (i = 2; i > 0; i--)
1170 + {
1171 + s->band[band].r[i] = s->band[band].r[i - 1];
1172 + s->band[band].p[i] = s->band[band].p[i - 1];
1173 + s->band[band].a[i] = s->band[band].ap[i];
1174 + }
1175 +
1176 + /* Block 4, FILTEP */
1177 + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
1178 + wd1 = (s->band[band].a[1]*wd1) >> 15;
1179 + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
1180 + wd2 = (s->band[band].a[2]*wd2) >> 15;
1181 + s->band[band].sp = saturate(wd1 + wd2);
1182 +
1183 + /* Block 4, FILTEZ */
1184 + s->band[band].sz = 0;
1185 + for (i = 6; i > 0; i--)
1186 + {
1187 + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
1188 + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
1189 + }
1190 + s->band[band].sz = saturate(s->band[band].sz);
1191 +
1192 + /* Block 4, PREDIC */
1193 + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
1194 +}
1195 +/*- End of function --------------------------------------------------------*/
1196 +
1197 +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options)
1198 +{
1199 + if (s == NULL)
1200 + {
1201 + if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL)
1202 + return NULL;
1203 + }
1204 + memset(s, 0, sizeof(*s));
1205 + if (rate == 48000)
1206 + s->bits_per_sample = 6;
1207 + else if (rate == 56000)
1208 + s->bits_per_sample = 7;
1209 + else
1210 + s->bits_per_sample = 8;
1211 + if ((options & G722_SAMPLE_RATE_8000))
1212 + s->eight_k = TRUE;
1213 + if ((options & G722_PACKED) && s->bits_per_sample != 8)
1214 + s->packed = TRUE;
1215 + else
1216 + s->packed = FALSE;
1217 + s->band[0].det = 32;
1218 + s->band[1].det = 8;
1219 + return s;
1220 +}
1221 +/*- End of function --------------------------------------------------------*/
1222 +
1223 +int g722_encode_release(g722_encode_state_t *s)
1224 +{
1225 + free(s);
1226 + return 0;
1227 +}
1228 +/*- End of function --------------------------------------------------------*/
1229 +
1230 +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len)
1231 +{
1232 + static const int q6[32] =
1233 + {
1234 + 0, 35, 72, 110, 150, 190, 233, 276,
1235 + 323, 370, 422, 473, 530, 587, 650, 714,
1236 + 786, 858, 940, 1023, 1121, 1219, 1339, 1458,
1237 + 1612, 1765, 1980, 2195, 2557, 2919, 0, 0
1238 + };
1239 + static const int iln[32] =
1240 + {
1241 + 0, 63, 62, 31, 30, 29, 28, 27,
1242 + 26, 25, 24, 23, 22, 21, 20, 19,
1243 + 18, 17, 16, 15, 14, 13, 12, 11,
1244 + 10, 9, 8, 7, 6, 5, 4, 0
1245 + };
1246 + static const int ilp[32] =
1247 + {
1248 + 0, 61, 60, 59, 58, 57, 56, 55,
1249 + 54, 53, 52, 51, 50, 49, 48, 47,
1250 + 46, 45, 44, 43, 42, 41, 40, 39,
1251 + 38, 37, 36, 35, 34, 33, 32, 0
1252 + };
1253 + static const int wl[8] =
1254 + {
1255 + -60, -30, 58, 172, 334, 538, 1198, 3042
1256 + };
1257 + static const int rl42[16] =
1258 + {
1259 + 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
1260 + };
1261 + static const int ilb[32] =
1262 + {
1263 + 2048, 2093, 2139, 2186, 2233, 2282, 2332,
1264 + 2383, 2435, 2489, 2543, 2599, 2656, 2714,
1265 + 2774, 2834, 2896, 2960, 3025, 3091, 3158,
1266 + 3228, 3298, 3371, 3444, 3520, 3597, 3676,
1267 + 3756, 3838, 3922, 4008
1268 + };
1269 + static const int qm4[16] =
1270 + {
1271 + 0, -20456, -12896, -8968,
1272 + -6288, -4240, -2584, -1200,
1273 + 20456, 12896, 8968, 6288,
1274 + 4240, 2584, 1200, 0
1275 + };
1276 + static const int qm2[4] =
1277 + {
1278 + -7408, -1616, 7408, 1616
1279 + };
1280 + static const int qmf_coeffs[12] =
1281 + {
1282 + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
1283 + };
1284 + static const int ihn[3] = {0, 1, 0};
1285 + static const int ihp[3] = {0, 3, 2};
1286 + static const int wh[3] = {0, -214, 798};
1287 + static const int rh2[4] = {2, 1, 2, 1};
1288 +
1289 + int dlow;
1290 + int dhigh;
1291 + int el;
1292 + int wd;
1293 + int wd1;
1294 + int ril;
1295 + int wd2;
1296 + int il4;
1297 + int ih2;
1298 + int wd3;
1299 + int eh;
1300 + int mih;
1301 + int i;
1302 + int j;
1303 + /* Low and high band PCM from the QMF */
1304 + int xlow;
1305 + int xhigh;
1306 + int g722_bytes;
1307 + /* Even and odd tap accumulators */
1308 + int sumeven;
1309 + int sumodd;
1310 + int ihigh;
1311 + int ilow;
1312 + int code;
1313 +
1314 + g722_bytes = 0;
1315 + xhigh = 0;
1316 + for (j = 0; j < len; )
1317 + {
1318 + if (s->itu_test_mode)
1319 + {
1320 + xlow =
1321 + xhigh = amp[j++] >> 1;
1322 + }
1323 + else
1324 + {
1325 + if (s->eight_k)
1326 + {
1327 + xlow = amp[j++];
1328 + }
1329 + else
1330 + {
1331 + /* Apply the transmit QMF */
1332 + /* Shuffle the buffer down */
1333 + for (i = 0; i < 22; i++)
1334 + s->x[i] = s->x[i + 2];
1335 + s->x[22] = amp[j++];
1336 + s->x[23] = amp[j++];
1337 +
1338 + /* Discard every other QMF output */
1339 + sumeven = 0;
1340 + sumodd = 0;
1341 + for (i = 0; i < 12; i++)
1342 + {
1343 + sumodd += s->x[2*i]*qmf_coeffs[i];
1344 + sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
1345 + }
1346 + xlow = (sumeven + sumodd) >> 13;
1347 + xhigh = (sumeven - sumodd) >> 13;
1348 + }
1349 + }
1350 + /* Block 1L, SUBTRA */
1351 + el = saturate(xlow - s->band[0].s);
1352 +
1353 + /* Block 1L, QUANTL */
1354 + wd = (el >= 0) ? el : -(el + 1);
1355 +
1356 + for (i = 1; i < 30; i++)
1357 + {
1358 + wd1 = (q6[i]*s->band[0].det) >> 12;
1359 + if (wd < wd1)
1360 + break;
1361 + }
1362 + ilow = (el < 0) ? iln[i] : ilp[i];
1363 +
1364 + /* Block 2L, INVQAL */
1365 + ril = ilow >> 2;
1366 + wd2 = qm4[ril];
1367 + dlow = (s->band[0].det*wd2) >> 15;
1368 +
1369 + /* Block 3L, LOGSCL */
1370 + il4 = rl42[ril];
1371 + wd = (s->band[0].nb*127) >> 7;
1372 + s->band[0].nb = wd + wl[il4];
1373 + if (s->band[0].nb < 0)
1374 + s->band[0].nb = 0;
1375 + else if (s->band[0].nb > 18432)
1376 + s->band[0].nb = 18432;
1377 +
1378 + /* Block 3L, SCALEL */
1379 + wd1 = (s->band[0].nb >> 6) & 31;
1380 + wd2 = 8 - (s->band[0].nb >> 11);
1381 + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
1382 + s->band[0].det = wd3 << 2;
1383 +
1384 + block4(s, 0, dlow);
1385 +
1386 + if (s->eight_k)
1387 + {
1388 + /* Just leave the high bits as zero */
1389 + code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
1390 + }
1391 + else
1392 + {
1393 + /* Block 1H, SUBTRA */
1394 + eh = saturate(xhigh - s->band[1].s);
1395 +
1396 + /* Block 1H, QUANTH */
1397 + wd = (eh >= 0) ? eh : -(eh + 1);
1398 + wd1 = (564*s->band[1].det) >> 12;
1399 + mih = (wd >= wd1) ? 2 : 1;
1400 + ihigh = (eh < 0) ? ihn[mih] : ihp[mih];
1401 +
1402 + /* Block 2H, INVQAH */
1403 + wd2 = qm2[ihigh];
1404 + dhigh = (s->band[1].det*wd2) >> 15;
1405 +
1406 + /* Block 3H, LOGSCH */
1407 + ih2 = rh2[ihigh];
1408 + wd = (s->band[1].nb*127) >> 7;
1409 + s->band[1].nb = wd + wh[ih2];
1410 + if (s->band[1].nb < 0)
1411 + s->band[1].nb = 0;
1412 + else if (s->band[1].nb > 22528)
1413 + s->band[1].nb = 22528;
1414 +
1415 + /* Block 3H, SCALEH */
1416 + wd1 = (s->band[1].nb >> 6) & 31;
1417 + wd2 = 10 - (s->band[1].nb >> 11);
1418 + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
1419 + s->band[1].det = wd3 << 2;
1420 +
1421 + block4(s, 1, dhigh);
1422 + code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
1423 + }
1424 +
1425 + if (s->packed)
1426 + {
1427 + /* Pack the code bits */
1428 + s->out_buffer |= (code << s->out_bits);
1429 + s->out_bits += s->bits_per_sample;
1430 + if (s->out_bits >= 8)
1431 + {
1432 + g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
1433 + s->out_bits -= 8;
1434 + s->out_buffer >>= 8;
1435 + }
1436 + }
1437 + else
1438 + {
1439 + g722_data[g722_bytes++] = (uint8_t) code;
1440 + }
1441 + }
1442 + return g722_bytes;
1443 +}
1444 +/*- End of function --------------------------------------------------------*/
1445 +/*- End of file ------------------------------------------------------------*/
1446 Index: codecs/g722/g722.h
1447 diff -Nau codecs/g722/g722.h.orig codecs/g722/g722.h
1448 --- codecs/g722/g722.h.orig 1970-01-01 01:00:00.000000000 +0100
1449 +++ codecs/g722/g722.h 2009-04-24 00:30:33.000000000 +0200
1450 @@ -0,0 +1,148 @@
1451 +/*
1452 + * SpanDSP - a series of DSP components for telephony
1453 + *
1454 + * g722.h - The ITU G.722 codec.
1455 + *
1456 + * Written by Steve Underwood <steveu@coppice.org>
1457 + *
1458 + * Copyright (C) 2005 Steve Underwood
1459 + *
1460 + * Despite my general liking of the GPL, I place my own contributions
1461 + * to this code in the public domain for the benefit of all mankind -
1462 + * even the slimy ones who might try to proprietize my work and use it
1463 + * to my detriment.
1464 + *
1465 + * Based on a single channel G.722 codec which is:
1466 + *
1467 + ***** Copyright (c) CMU 1993 *****
1468 + * Computer Science, Speech Group
1469 + * Chengxiang Lu and Alex Hauptmann
1470 + *
1471 + * $Id: g722.h 48959 2006-12-25 06:42:15Z rizzo $
1472 + */
1473 +
1474 +
1475 +/*! \file */
1476 +
1477 +#if !defined(_G722_H_)
1478 +#define _G722_H_
1479 +
1480 +/*! \page g722_page G.722 encoding and decoding
1481 +\section g722_page_sec_1 What does it do?
1482 +The G.722 module is a bit exact implementation of the ITU G.722 specification for all three
1483 +specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests.
1484 +
1485 +To allow fast and flexible interworking with narrow band telephony, the encoder and decoder
1486 +support an option for the linear audio to be an 8k samples/second stream. In this mode the
1487 +codec is considerably faster, and still fully compatible with wideband terminals using G.722.
1488 +
1489 +\section g722_page_sec_2 How does it work?
1490 +???.
1491 +*/
1492 +
1493 +enum
1494 +{
1495 + G722_SAMPLE_RATE_8000 = 0x0001,
1496 + G722_PACKED = 0x0002
1497 +};
1498 +
1499 +#ifndef INT16_MAX
1500 +#define INT16_MAX 32767
1501 +#endif
1502 +#ifndef INT16_MIN
1503 +#define INT16_MIN (-32768)
1504 +#endif
1505 +
1506 +typedef struct
1507 +{
1508 + /*! TRUE if the operating in the special ITU test mode, with the band split filters
1509 + disabled. */
1510 + int itu_test_mode;
1511 + /*! TRUE if the G.722 data is packed */
1512 + int packed;
1513 + /*! TRUE if encode from 8k samples/second */
1514 + int eight_k;
1515 + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
1516 + int bits_per_sample;
1517 +
1518 + /*! Signal history for the QMF */
1519 + int x[24];
1520 +
1521 + struct
1522 + {
1523 + int s;
1524 + int sp;
1525 + int sz;
1526 + int r[3];
1527 + int a[3];
1528 + int ap[3];
1529 + int p[3];
1530 + int d[7];
1531 + int b[7];
1532 + int bp[7];
1533 + int sg[7];
1534 + int nb;
1535 + int det;
1536 + } band[2];
1537 +
1538 + unsigned int in_buffer;
1539 + int in_bits;
1540 + unsigned int out_buffer;
1541 + int out_bits;
1542 +} g722_encode_state_t;
1543 +
1544 +typedef struct
1545 +{
1546 + /*! TRUE if the operating in the special ITU test mode, with the band split filters
1547 + disabled. */
1548 + int itu_test_mode;
1549 + /*! TRUE if the G.722 data is packed */
1550 + int packed;
1551 + /*! TRUE if decode to 8k samples/second */
1552 + int eight_k;
1553 + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
1554 + int bits_per_sample;
1555 +
1556 + /*! Signal history for the QMF */
1557 + int x[24];
1558 +
1559 + struct
1560 + {
1561 + int s;
1562 + int sp;
1563 + int sz;
1564 + int r[3];
1565 + int a[3];
1566 + int ap[3];
1567 + int p[3];
1568 + int d[7];
1569 + int b[7];
1570 + int bp[7];
1571 + int sg[7];
1572 + int nb;
1573 + int det;
1574 + } band[2];
1575 +
1576 + unsigned int in_buffer;
1577 + int in_bits;
1578 + unsigned int out_buffer;
1579 + int out_bits;
1580 +} g722_decode_state_t;
1581 +
1582 +#ifdef __cplusplus
1583 +extern "C" {
1584 +#endif
1585 +
1586 +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
1587 +int g722_encode_release(g722_encode_state_t *s);
1588 +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
1589 +
1590 +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
1591 +int g722_decode_release(g722_decode_state_t *s);
1592 +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
1593 +
1594 +#ifdef __cplusplus
1595 +}
1596 +#endif
1597 +
1598 +#endif
1599 Index: codecs/g722/Makefile
1600 diff -Nau codecs/g722/Makefile.orig codecs/g722/Makefile
1601 --- codecs/g722/Makefile.orig 1970-01-01 01:00:00.000000000 +0100
1602 +++ codecs/g722/Makefile 2009-04-24 00:30:33.000000000 +0200
1603 @@ -0,0 +1,18 @@
1604 +LIB=libg722.a
1605 +CFLAGS+=-fPIC
1606 +
1607 +include $(ASTTOPDIR)/Makefile.rules
1608 +
1609 +OBJS=g722_encode.o g722_decode.o
1610 +
1611 +all: $(LIB)
1612 +
1613 +$(LIB): $(OBJS)
1614 + $(ECHO_PREFIX) echo " [AR] $^ -> $@"
1615 + $(CMD_PREFIX) $(AR) cr $@ $^
1616 + $(CMD_PREFIX) $(RANLIB) $@
1617 +
1618 +clean:
1619 + rm -f $(LIB) *.o
1620 + rm -f .*.o.d
1621 + rm -f *.s *.i
1622 Index: codecs/g722_slin_ex.h
1623 diff -Nau codecs/g722_slin_ex.h.orig codecs/g722_slin_ex.h
1624 --- codecs/g722_slin_ex.h.orig 1970-01-01 01:00:00.000000000 +0100
1625 +++ codecs/g722_slin_ex.h 2009-04-24 00:30:33.000000000 +0200
1626 @@ -0,0 +1,25 @@
1627 +/*! \file
1628 + * \brief g722_slin_ex.h --
1629 + *
1630 + * 4-bit ADPCM data, 20 milliseconds worth at 8 kHz.
1631 + *
1632 + * Source: g723.example
1633 + *
1634 + * Copyright (C) 2001-2005, Digium Inc.
1635 + *
1636 + * Distributed under the terms of the GNU General Public License
1637 + *
1638 + */
1639 +
1640 +static unsigned char g722_slin_ex[] = {
1641 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1642 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1644 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1647 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1648 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1651 +};
1652 Index: codecs/Makefile
1653 diff -Nau codecs/Makefile.orig codecs/Makefile
1654 --- codecs/Makefile.orig 2008-03-26 17:42:35.000000000 +0100
1655 +++ codecs/Makefile 2009-04-24 00:30:33.000000000 +0200
1656 @@ -31,6 +31,7 @@
1658 LIBILBC:=ilbc/libilbc.a
1659 LIBLPC10:=lpc10/liblpc10.a
1660 +LIBG722:=g722/libg722.a
1662 all: _all
1664 @@ -45,6 +46,7 @@
1665 $(MAKE) -C gsm clean
1666 $(MAKE) -C lpc10 clean
1667 $(MAKE) -C ilbc clean
1668 + $(MAKE) -C g722 clean
1670 gsm/lib/libgsm.a:
1671 @mkdir -p gsm/lib
1672 @@ -59,3 +61,8 @@
1673 @$(MAKE) -C ilbc all ASTCFLAGS="$(filter-out -Wmissing-prototypes -Wmissing-declarations,$(ASTCFLAGS)) $(AST_NO_STRICT_OVERFLOW)"
1675 $(if $(filter codec_ilbc,$(EMBEDDED_MODS)),modules.link,codec_ilbc.so): $(LIBILBC)
1676 +
1677 +$(LIBG722):
1678 + @$(MAKE) -C g722 all
1679 +
1680 +$(if $(filter codec_g722,$(EMBEDDED_MODS)),modules.link,codec_g722.so): $(LIBG722)
1681 Index: codecs/slin_g722_ex.h
1682 diff -Nau codecs/slin_g722_ex.h.orig codecs/slin_g722_ex.h
1683 --- codecs/slin_g722_ex.h.orig 1970-01-01 01:00:00.000000000 +0100
1684 +++ codecs/slin_g722_ex.h 2009-04-24 00:30:33.000000000 +0200
1685 @@ -0,0 +1,25 @@
1686 +/*! \file
1687 + * \brief slin_g722_ex.h --
1688 + *
1689 + * Signed 16-bit audio data, 10 milliseconds worth at 8 kHz.
1690 + *
1691 + * Source: g723.example
1692 + *
1693 + * Copyright (C) 2001-2005, Digium Inc.
1694 + *
1695 + * Distributed under the terms of the GNU General Public License
1696 + *
1697 + */
1698 +
1699 +static signed short slin_g722_ex[] = {
1700 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1701 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1702 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1703 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1704 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1705 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1706 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1707 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1708 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1709 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1710 +};
1711 Index: configure
1712 diff -Nau configure.orig configure
1713 --- configure.orig 2009-02-18 21:06:45.000000000 +0100
1714 +++ configure 2009-04-24 00:30:33.000000000 +0200
1715 @@ -11143,6 +11143,61 @@
1717 fi
1719 +{ echo "$as_me:$LINENO: checking for tm_gmtoff in struct tm" >&5
1720 +echo $ECHO_N "checking for tm_gmtoff in struct tm... $ECHO_C" >&6; }
1721 +if test "${ac_cv_struct_tm_gmtoff+set}" = set; then
1722 + echo $ECHO_N "(cached) $ECHO_C" >&6
1723 +else
1724 + cat >conftest.$ac_ext <<_ACEOF
1725 +/* confdefs.h. */
1726 +_ACEOF
1727 +cat confdefs.h >>conftest.$ac_ext
1728 +cat >>conftest.$ac_ext <<_ACEOF
1729 +/* end confdefs.h. */
1730 +$ac_includes_default
1731 +#include <sys/types.h>
1732 +#include <$ac_cv_struct_tm>
1733 +int main() {
1734 +struct tm tm; tm.tm_gmtoff;
1735 +; return 0; }
1736 +_ACEOF
1737 +rm -f conftest.$ac_objext
1738 +if { (ac_try="$ac_compile"
1739 +case "(($ac_try" in
1740 + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
1741 + *) ac_try_echo=$ac_try;;
1742 +esac
1743 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
1744 + (eval "$ac_compile") 2>conftest.er1
1745 + ac_status=$?
1746 + grep -v '^ *+' conftest.er1 >conftest.err
1747 + rm -f conftest.er1
1748 + cat conftest.err >&5
1749 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
1750 + (exit $ac_status); } && {
1751 + test -z "$ac_c_werror_flag" ||
1752 + test ! -s conftest.err
1753 + } && test -s conftest.$ac_objext; then
1754 + ac_cv_struct_tm_gmtoff=yes
1755 +else
1756 + echo "$as_me: failed program was:" >&5
1757 +sed 's/^/| /' conftest.$ac_ext >&5
1758 +
1759 + ac_cv_struct_tm_gmtoff=no
1760 +fi
1761 +
1762 +rm -f conftest*
1763 +fi
1764 +{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm_gmtoff" >&5
1765 +echo "${ECHO_T}$ac_cv_struct_tm_gmtoff" >&6; }
1766 +if test $ac_cv_struct_tm_gmtoff = yes; then
1767 +
1768 +cat >>confdefs.h <<\_ACEOF
1769 +#define TM_GMTOFF 1
1770 +_ACEOF
1771 +
1772 +fi
1773 +
1774 { echo "$as_me:$LINENO: checking for working volatile" >&5
1775 echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; }
1776 if test "${ac_cv_c_volatile+set}" = set; then
1777 Index: include/asterisk/config.h
1778 diff -Nau include/asterisk/config.h.orig include/asterisk/config.h
1779 --- include/asterisk/config.h.orig 2009-02-18 19:30:38.000000000 +0100
1780 +++ include/asterisk/config.h 2009-04-24 00:30:33.000000000 +0200
1781 @@ -33,6 +33,8 @@
1783 struct ast_category;
1785 +#define CONFIG_STATUS_FILEUNCHANGED (void *)-1
1786 +
1787 struct ast_variable {
1788 char *name;
1789 char *value;
1790 Index: include/asterisk/frame.h
1791 diff -Nau include/asterisk/frame.h.orig include/asterisk/frame.h
1792 --- include/asterisk/frame.h.orig 2009-03-05 19:22:16.000000000 +0100
1793 +++ include/asterisk/frame.h 2009-04-24 00:30:33.000000000 +0200
1794 @@ -260,6 +260,8 @@
1795 #define AST_FORMAT_G726 (1 << 11)
1796 /*! G.722 */
1797 #define AST_FORMAT_G722 (1 << 12)
1798 +/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
1799 +#define AST_FORMAT_SLINEAR16 (1 << 15)
1800 /*! Unsupported audio bits */
1801 #define AST_FORMAT_AUDIO_UNDEFINED ((1 << 13) | (1 << 14) | (1 << 15))
1802 /*! Maximum audio format */
1803 Index: main/editline/np/vis.h
1804 diff -Nau main/editline/np/vis.h.orig main/editline/np/vis.h
1805 --- main/editline/np/vis.h.orig 2006-08-21 04:11:39.000000000 +0200
1806 +++ main/editline/np/vis.h 2009-04-24 00:30:33.000000000 +0200
1807 @@ -76,6 +76,22 @@
1809 #include <sys/cdefs.h>
1811 +/* correct nonportable unsigned type usage */
1812 +#if !defined(__FreeBSD__) && !defined(__linux__)
1813 +#ifndef u_int64_t
1814 +#define u_int64_t unsigned long long
1815 +#endif
1816 +#ifndef u_int32_t
1817 +#define u_int32_t unsigned int
1818 +#endif
1819 +#ifndef u_int16_t
1820 +#define u_int16_t unsigned short
1821 +#endif
1822 +#ifndef u_int6_t
1823 +#define u_int8_t unsigned char
1824 +#endif
1825 +#endif
1826 +
1827 __BEGIN_DECLS
1828 char *vis __P((char *, int, int, int));
1829 char *svis __P((char *, int, int, int, const char *));
1830 Index: main/stdtime/localtime.c
1831 diff -Nau main/stdtime/localtime.c.orig main/stdtime/localtime.c
1832 --- main/stdtime/localtime.c.orig 2008-09-27 17:00:48.000000000 +0200
1833 +++ main/stdtime/localtime.c 2009-04-24 00:30:33.000000000 +0200
1834 @@ -1134,9 +1134,9 @@
1835 */
1836 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1837 tmp->tm_isdst = ttisp->tt_isdst;
1838 -#ifndef SOLARIS /* Solaris doesn't have this element */
1839 +#ifdef TM_GMTOFF
1840 tmp->tm_gmtoff = ttisp->tt_gmtoff;
1841 -#endif
1842 +#endif /* defined TM_GMTOFF */
1843 #ifdef TM_ZONE
1844 tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1845 #endif /* defined TM_ZONE */
1846 Index: Makefile.moddir_rules
1847 diff -Nau Makefile.moddir_rules.orig Makefile.moddir_rules
1848 --- Makefile.moddir_rules.orig 2008-11-26 19:36:24.000000000 +0100
1849 +++ Makefile.moddir_rules 2009-04-24 00:30:33.000000000 +0200
1850 @@ -69,7 +69,9 @@
1851 rm -f modules.link
1853 install:: all
1854 +ifneq ($(LOADABLE_MODS),)
1855 for x in $(LOADABLE_MODS:%=%.so); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
1856 +endif
1858 uninstall::
1860 Index: res/res_features.c
1861 diff -Nau res/res_features.c.orig res/res_features.c
1862 --- res/res_features.c.orig 2009-03-03 19:27:09.000000000 +0100
1863 +++ res/res_features.c 2009-04-24 00:30:33.000000000 +0200
1864 @@ -732,6 +732,10 @@
1865 snprintf(args, len, "%s|%s|m", S_OR(touch_format, "wav"), touch_filename);
1866 }
1868 + for( x = 0; x < strlen(touch_filename); x++) {
1869 + if (touch_filename[x] == '/')
1870 + touch_filename[x] = '-';
1871 + }
1872 for( x = 0; x < strlen(args); x++) {
1873 if (args[x] == '/')
1874 args[x] = '-';
1875 @@ -2774,6 +2778,293 @@
1876 }
1877 }
1879 +static char mandescr_bridge[] =
1880 +"Description: Bridge together two channels already in the PBX\n"
1881 +"Variables: ( Headers marked with * are required )\n"
1882 +" *Channel1: Channel to Bridge to Channel2\n"
1883 +" *Channel2: Channel to Bridge to Channel1\n"
1884 +" Tone: (Yes|No) Play courtesy tone to Channel 2\n"
1885 +"\n";
1886 +
1887 +/*!
1888 + * \brief Actual bridge
1889 + * \param chan
1890 + * \param tmpchan
1891 + *
1892 + * Stop hold music, lock both channels, masq channels,
1893 + * after bridge return channel to next priority.
1894 +*/
1895 +static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
1896 +{
1897 + ast_moh_stop(chan);
1898 + ast_channel_lock(chan);
1899 + ast_setstate(tmpchan, chan->_state);
1900 + tmpchan->readformat = chan->readformat;
1901 + tmpchan->writeformat = chan->writeformat;
1902 + ast_channel_masquerade(tmpchan, chan);
1903 + ast_channel_lock(tmpchan);
1904 + ast_do_masquerade(tmpchan);
1905 + /* when returning from bridge, the channel will continue at the next priority */
1906 + ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
1907 + ast_channel_unlock(tmpchan);
1908 + ast_channel_unlock(chan);
1909 +}
1910 +
1911 +/*!
1912 + * \brief Bridge channels together
1913 + * \param s
1914 + * \param m
1915 + *
1916 + * Make sure valid channels were specified,
1917 + * send errors if any of the channels could not be found/locked, answer channels if needed,
1918 + * create the placeholder channels and grab the other channels
1919 + * make the channels compatible, send error if we fail doing so
1920 + * setup the bridge thread object and start the bridge.
1921 + *
1922 + * \retval 0 on success or on incorrect use.
1923 + * \retval 1 on failure to bridge channels.
1924 +*/
1925 +static int action_bridge(struct mansession *s, const struct message *m)
1926 +{
1927 + const char *channela = astman_get_header(m, "Channel1");
1928 + const char *channelb = astman_get_header(m, "Channel2");
1929 + const char *playtone = astman_get_header(m, "Tone");
1930 + struct ast_channel *chana = NULL, *chanb = NULL;
1931 + struct ast_channel *tmpchana = NULL, *tmpchanb = NULL;
1932 + struct ast_bridge_thread_obj *tobj = NULL;
1933 +
1934 + /* make sure valid channels were specified */
1935 + if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) {
1936 + chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela));
1937 + chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb));
1938 + if (chana)
1939 + ast_channel_unlock(chana);
1940 + if (chanb)
1941 + ast_channel_unlock(chanb);
1942 +
1943 + /* send errors if any of the channels could not be found/locked */
1944 + if (!chana) {
1945 + char buf[256];
1946 + snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela);
1947 + astman_send_error(s, m, buf);
1948 + return 0;
1949 + }
1950 + if (!chanb) {
1951 + char buf[256];
1952 + snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb);
1953 + astman_send_error(s, m, buf);
1954 + return 0;
1955 + }
1956 + } else {
1957 + astman_send_error(s, m, "Missing channel parameter in request");
1958 + return 0;
1959 + }
1960 +
1961 + /* Answer the channels if needed */
1962 + if (chana->_state != AST_STATE_UP)
1963 + ast_answer(chana);
1964 + if (chanb->_state != AST_STATE_UP)
1965 + ast_answer(chanb);
1966 +
1967 + /* create the placeholder channels and grab the other channels */
1968 + if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
1969 + NULL, NULL, 0, "Bridge/%s", chana->name))) {
1970 + astman_send_error(s, m, "Unable to create temporary channel!");
1971 + return 1;
1972 + }
1973 +
1974 + if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
1975 + NULL, NULL, 0, "Bridge/%s", chanb->name))) {
1976 + astman_send_error(s, m, "Unable to create temporary channels!");
1977 + ast_channel_free(tmpchana);
1978 + return 1;
1979 + }
1980 +
1981 + do_bridge_masquerade(chana, tmpchana);
1982 + do_bridge_masquerade(chanb, tmpchanb);
1983 +
1984 + /* make the channels compatible, send error if we fail doing so */
1985 + if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
1986 + ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name);
1987 + astman_send_error(s, m, "Could not make channels compatible for manager bridge");
1988 + ast_hangup(tmpchana);
1989 + ast_hangup(tmpchanb);
1990 + return 1;
1991 + }
1992 +
1993 + /* setup the bridge thread object and start the bridge */
1994 + if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1995 + ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno));
1996 + astman_send_error(s, m, "Unable to spawn a new bridge thread");
1997 + ast_hangup(tmpchana);
1998 + ast_hangup(tmpchanb);
1999 + return 1;
2000 + }
2001 +
2002 + tobj->chan = tmpchana;
2003 + tobj->peer = tmpchanb;
2004 +
2005 + if (ast_true(playtone)) {
2006 + if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) {
2007 + if (ast_waitstream(tmpchanb, "") < 0)
2008 + ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name);
2009 + }
2010 + }
2011 +
2012 + ast_bridge_call_thread_launch(tobj);
2013 +
2014 + astman_send_ack(s, m, "Launched bridge thread with success");
2015 +
2016 + return 0;
2017 +}
2018 +
2019 +static char *app_bridge = "Bridge";
2020 +static char *bridge_synopsis = "Bridge two channels";
2021 +static char *bridge_descrip =
2022 +"Usage: Bridge(channel[,options])\n"
2023 +" Allows the ability to bridge two channels via the dialplan.\n"
2024 +"The current channel is bridged to the specified 'channel'.\n"
2025 +" Options:\n"
2026 +" p - Play a courtesy tone to 'channel'.\n"
2027 +"This application sets the following channel variable upon completion:\n"
2028 +" BRIDGERESULT The result of the bridge attempt as a text string, one of\n"
2029 +" SUCCESS | FAILURE | LOOP | NONEXISTENT | INCOMPATIBLE\n";
2030 +
2031 +enum {
2032 + BRIDGE_OPT_PLAYTONE = (1 << 0),
2033 +};
2034 +
2035 +AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
2036 + AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE)
2037 +END_OPTIONS );
2038 +
2039 +/*!
2040 + * \brief Bridge channels
2041 + * \param chan
2042 + * \param data channel to bridge with.
2043 + *
2044 + * Split data, check we aren't bridging with ourself, check valid channel,
2045 + * answer call if not already, check compatible channels, setup bridge config
2046 + * now bridge call, if transfered party hangs up return to PBX extension.
2047 +*/
2048 +static int bridge_exec(struct ast_channel *chan, void *data)
2049 +{
2050 + struct ast_channel *current_dest_chan, *final_dest_chan;
2051 + char *tmp_data = NULL;
2052 + struct ast_flags opts = { 0, };
2053 + struct ast_bridge_config bconfig = { { 0, }, };
2054 +
2055 + AST_DECLARE_APP_ARGS(args,
2056 + AST_APP_ARG(dest_chan);
2057 + AST_APP_ARG(options);
2058 + );
2059 +
2060 + if (ast_strlen_zero(data)) {
2061 + ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n");
2062 + return -1;
2063 + }
2064 +
2065 + tmp_data = ast_strdupa(data);
2066 + AST_STANDARD_APP_ARGS(args, tmp_data);
2067 + if (!ast_strlen_zero(args.options))
2068 + ast_app_parse_options(bridge_exec_options, &opts, NULL, args.options);
2069 +
2070 + /* avoid bridge with ourselves */
2071 + if (!strncmp(chan->name, args.dest_chan,
2072 + strlen(chan->name) < strlen(args.dest_chan) ?
2073 + strlen(chan->name) : strlen(args.dest_chan))) {
2074 + ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name);
2075 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2076 + "Response: Failed\r\n"
2077 + "Reason: Unable to bridge channel to itself\r\n"
2078 + "Channel1: %s\r\n"
2079 + "Channel2: %s\r\n",
2080 + chan->name, args.dest_chan);
2081 + pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
2082 + return 0;
2083 + }
2084 +
2085 + /* make sure we have a valid end point */
2086 + if (!(current_dest_chan = ast_get_channel_by_name_prefix_locked(args.dest_chan,
2087 + strlen(args.dest_chan)))) {
2088 + ast_log(LOG_WARNING, "Bridge failed because channel %s does not exist or we "
2089 + "cannot get its lock\n", args.dest_chan);
2090 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2091 + "Response: Failed\r\n"
2092 + "Reason: Cannot grab end point\r\n"
2093 + "Channel1: %s\r\n"
2094 + "Channel2: %s\r\n", chan->name, args.dest_chan);
2095 + pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
2096 + return 0;
2097 + }
2098 + ast_channel_unlock(current_dest_chan);
2099 +
2100 + /* answer the channel if needed */
2101 + if (current_dest_chan->_state != AST_STATE_UP)
2102 + ast_answer(current_dest_chan);
2103 +
2104 + /* try to allocate a place holder where current_dest_chan will be placed */
2105 + if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
2106 + NULL, NULL, 0, "Bridge/%s", current_dest_chan->name))) {
2107 + ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan);
2108 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2109 + "Response: Failed\r\n"
2110 + "Reason: cannot create placeholder\r\n"
2111 + "Channel1: %s\r\n"
2112 + "Channel2: %s\r\n", chan->name, args.dest_chan);
2113 + }
2114 + do_bridge_masquerade(current_dest_chan, final_dest_chan);
2115 +
2116 + /* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */
2117 + /* try to make compatible, send error if we fail */
2118 + if (ast_channel_make_compatible(chan, final_dest_chan) < 0) {
2119 + ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name);
2120 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2121 + "Response: Failed\r\n"
2122 + "Reason: Could not make channels compatible for bridge\r\n"
2123 + "Channel1: %s\r\n"
2124 + "Channel2: %s\r\n", chan->name, final_dest_chan->name);
2125 + ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */
2126 + pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE");
2127 + return 0;
2128 + }
2129 +
2130 + /* Report that the bridge will be successfull */
2131 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2132 + "Response: Success\r\n"
2133 + "Channel1: %s\r\n"
2134 + "Channel2: %s\r\n", chan->name, final_dest_chan->name);
2135 +
2136 + /* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */
2137 + if (ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE) && !ast_strlen_zero(xfersound)) {
2138 + if (!ast_streamfile(final_dest_chan, xfersound, final_dest_chan->language)) {
2139 + if (ast_waitstream(final_dest_chan, "") < 0)
2140 + ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name);
2141 + }
2142 + }
2143 +
2144 + /* do the bridge */
2145 + ast_bridge_call(chan, final_dest_chan, &bconfig);
2146 +
2147 + /* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */
2148 + pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
2149 + if (!ast_check_hangup(final_dest_chan)) {
2150 + ast_log(LOG_EVENT, "starting new PBX in %s,%s,%d for chan %s\n",
2151 + final_dest_chan->context, final_dest_chan->exten,
2152 + final_dest_chan->priority, final_dest_chan->name);
2153 +
2154 + if (ast_pbx_start(final_dest_chan) != AST_PBX_SUCCESS) {
2155 + ast_log(LOG_WARNING, "FAILED continuing PBX on dest chan %s\n", final_dest_chan->name);
2156 + ast_hangup(final_dest_chan);
2157 + } else
2158 + ast_log(LOG_EVENT, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name);
2159 + } else {
2160 + ast_log(LOG_EVENT, "hangup chan %s since the other endpoint has hung up\n", final_dest_chan->name);
2161 + ast_hangup(final_dest_chan);
2162 + }
2163 +
2164 + return 0;
2165 +}
2167 static int load_config(void)
2168 {
2169 @@ -3034,6 +3325,8 @@
2170 {
2171 int res;
2173 + ast_register_application(app_bridge, bridge_exec, bridge_synopsis, bridge_descrip);
2174 +
2175 memset(parking_ext, 0, sizeof(parking_ext));
2176 memset(parking_con, 0, sizeof(parking_con));
2178 @@ -3048,6 +3341,7 @@
2179 ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
2180 ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
2181 "Park a channel", mandescr_park);
2182 + ast_manager_register2("Bridge", EVENT_FLAG_CALL, action_bridge, "Bridge two channels already in the PBX", mandescr_bridge);
2183 }
2185 res |= ast_devstate_prov_add("Park", metermaidstate);
2186 Index: apps/app_voicemail.c
2187 diff -Nau apps/app_voicemail.c.orig apps/app_voicemail.c
2188 --- apps/app_voicemail.c.orig 2009-04-25 02:38:20.343758775 +0200
2189 +++ apps/app_voicemail.c 2009-04-25 19:56:25.287569363 +0200
2190 @@ -115,6 +115,7 @@
2191 static char imapport[8];
2192 static char imapflags[128];
2193 static char imapfolder[64];
2194 +static int imapsubfold = 0;
2195 static char authuser[32];
2196 static char authpassword[42];
2198 @@ -4313,6 +4314,7 @@
2199 /* we must use mbox(x) folder names, and copy the message there */
2200 /* simple. huh? */
2201 char sequence[10];
2202 + char folder[256];
2203 /* get the real IMAP message number for this message */
2204 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
2205 if (option_debug > 2)
2206 @@ -4323,11 +4325,21 @@
2207 } else if (box == 0) {
2208 mail_clearflag(vms->mailstream, sequence, "\\Seen");
2209 }
2210 - if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) {
2211 + if ((!strcasecmp(mbox(0), vms->curbox) || \
2212 + !strcasecmp(mbox(1), vms->curbox)) && \
2213 + (box == 0 || box == 1)) { /* Don't copy data, just change Seen flag */
2214 ast_mutex_unlock(&vms->lock);
2215 return 0;
2216 - } else {
2217 - int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box));
2218 + } else if (box > 1) { /* Do copy data using INBOX or subfolder */
2219 + if (imapsubfold == 1)
2220 + snprintf(folder, sizeof(folder), "%s%c%s", imapfolder, delimiter, mbox(box));
2221 + else
2222 + strncpy(folder, mbox(box), sizeof(folder));
2223 + int res = !mail_copy(vms->mailstream,sequence,folder);
2224 + ast_mutex_unlock(&vms->lock);
2225 + return res;
2226 + } else { /* Copy data to INBOX delegating new/old status to Seen flag */
2227 + int res = !mail_copy(vms->mailstream,sequence,imapfolder);
2228 ast_mutex_unlock(&vms->lock);
2229 return res;
2230 }
2231 @@ -7686,6 +7698,10 @@
2232 #ifndef IMAP_STORAGE
2233 } else if (!cmd) {
2234 vms.deleted[vms.curmsg] = 1;
2235 +#else
2236 + } else if (!cmd && (folder_int(vms.curbox) > 1 || box > 1)) {
2237 + vms.deleted[vms.curmsg] = 1; /* Enforce deletion after */
2238 + deleted = 1; /* successful copy op */
2239 #endif
2240 } else {
2241 vms.deleted[vms.curmsg] = 0;
2242 @@ -8198,6 +8214,7 @@
2243 const char *imap_port;
2244 const char *imap_flags;
2245 const char *imap_folder;
2246 + const char *imap_use_subfold;
2247 const char *auth_user;
2248 const char *auth_password;
2249 const char *expunge_on_hangup;
2250 @@ -8342,6 +8359,15 @@
2251 } else {
2252 ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
2253 }
2254 + /* IMAP saved (sub)folder location policy */
2255 + if ((imap_use_subfold = ast_variable_retrieve(cfg, "general", "imapsubfold"))) {
2256 + if (ast_false(imap_use_subfold))
2257 + imapsubfold = 0;
2258 + else
2259 + imapsubfold = 1;
2260 + } else {
2261 + imapsubfold = 0;
2262 + }
2264 /* There is some very unorthodox casting done here. This is due
2265 * to the way c-client handles the argument passed in. It expects a