asterisk/asterisk.patch

Fri, 15 Oct 2010 19:06:09 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 15 Oct 2010 19:06:09 +0200
changeset 263
f4a0b439d0fb
child 310
73d852a30c9a
permissions
-rw-r--r--

Correct shared library and plugin link logic, as well as informal text.
Update file server URL, update build resource estimations, correct RPATH
logic, allow for qmake(1) static to shared library changes via CONFIG
argument, correct documentation broken title and index links, correct
shared library install path, install only one set of (correct) plugins,
install the designer shared library (as required by QtCreator), announce
features related to shared linking using qmake(1), and correclty
substitute hard coded paths in prl and la library files.

     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;
  1003 +            block4(s, 1, dhigh);
  1004 +        }
  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;
  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 + */
  1071 +/*! \file */
  1073 +#ifdef HAVE_CONFIG_H
  1074 +#include <config.h>
  1075 +#endif
  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
  1085 +#include "g722.h"
  1087 +#if !defined(FALSE)
  1088 +#define FALSE 0
  1089 +#endif
  1090 +#if !defined(TRUE)
  1091 +#define TRUE (!FALSE)
  1092 +#endif
  1094 +static __inline__ int16_t saturate(int32_t amp)
  1095 +{
  1096 +    int16_t amp16;
  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 --------------------------------------------------------*/
  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;
  1115 +    /* Block 4, RECONS */
  1116 +    s->band[band].d[0] = d;
  1117 +    s->band[band].r[0] = saturate(s->band[band].s + d);
  1119 +    /* Block 4, PARREC */
  1120 +    s->band[band].p[0] = saturate(s->band[band].sz + d);
  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);
  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;
  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;
  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;
  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 +    }
  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 +    }
  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 +    }
  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);
  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);
  1192 +    /* Block 4, PREDIC */
  1193 +    s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
  1194 +}
  1195 +/*- End of function --------------------------------------------------------*/
  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 --------------------------------------------------------*/
  1223 +int g722_encode_release(g722_encode_state_t *s)
  1224 +{
  1225 +    free(s);
  1226 +    return 0;
  1227 +}
  1228 +/*- End of function --------------------------------------------------------*/
  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};
  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;
  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++];
  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);
  1353 +        /* Block 1L, QUANTL */
  1354 +        wd = (el >= 0)  ?  el  :  -(el + 1);
  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];
  1364 +        /* Block 2L, INVQAL */
  1365 +        ril = ilow >> 2;
  1366 +        wd2 = qm4[ril];
  1367 +        dlow = (s->band[0].det*wd2) >> 15;
  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;
  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;
  1384 +        block4(s, 0, dlow);
  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);
  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];
  1402 +            /* Block 2H, INVQAH */
  1403 +            wd2 = qm2[ihigh];
  1404 +            dhigh = (s->band[1].det*wd2) >> 15;
  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;
  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;
  1421 +            block4(s, 1, dhigh);
  1422 +            code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
  1423 +        }
  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 + */
  1475 +/*! \file */
  1477 +#if !defined(_G722_H_)
  1478 +#define _G722_H_
  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.
  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.
  1489 +\section g722_page_sec_2 How does it work?
  1490 +???.
  1491 +*/
  1493 +enum
  1494 +{
  1495 +    G722_SAMPLE_RATE_8000 = 0x0001,
  1496 +    G722_PACKED = 0x0002
  1497 +};
  1499 +#ifndef INT16_MAX
  1500 +#define INT16_MAX       32767
  1501 +#endif
  1502 +#ifndef INT16_MIN
  1503 +#define INT16_MIN       (-32768)
  1504 +#endif
  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;
  1518 +    /*! Signal history for the QMF */
  1519 +    int x[24];
  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];
  1538 +    unsigned int in_buffer;
  1539 +    int in_bits;
  1540 +    unsigned int out_buffer;
  1541 +    int out_bits;
  1542 +} g722_encode_state_t;
  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;
  1556 +    /*! Signal history for the QMF */
  1557 +    int x[24];
  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];
  1576 +    unsigned int in_buffer;
  1577 +    int in_bits;
  1578 +    unsigned int out_buffer;
  1579 +    int out_bits;
  1580 +} g722_decode_state_t;
  1582 +#ifdef __cplusplus
  1583 +extern "C" {
  1584 +#endif
  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);
  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);
  1594 +#ifdef __cplusplus
  1595 +}
  1596 +#endif
  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
  1607 +include $(ASTTOPDIR)/Makefile.rules
  1609 +OBJS=g722_encode.o g722_decode.o
  1611 +all: $(LIB)
  1613 +$(LIB): $(OBJS)
  1614 +	$(ECHO_PREFIX) echo "   [AR] $^ -> $@"
  1615 +	$(CMD_PREFIX) $(AR) cr $@ $^
  1616 +	$(CMD_PREFIX) $(RANLIB) $@
  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 + */
  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)
  1677 +$(LIBG722):
  1678 +	@$(MAKE) -C g722 all
  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 + */
  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
  1759 +	ac_cv_struct_tm_gmtoff=no
  1760 +fi
  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
  1768 +cat >>confdefs.h <<\_ACEOF
  1769 +#define TM_GMTOFF 1
  1770 +_ACEOF
  1772 +fi
  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
  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
  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);
  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 @@
  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";
  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 +}
  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;
  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);
  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 +	}
  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);
  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 +	}
  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 +	}
  1981 +	do_bridge_masquerade(chana, tmpchana);
  1982 +	do_bridge_masquerade(chanb, tmpchanb);
  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 +	}
  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 +	}
  2002 +	tobj->chan = tmpchana;
  2003 +	tobj->peer = tmpchanb;
  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 +	}
  2012 +	ast_bridge_call_thread_launch(tobj);
  2014 +	astman_send_ack(s, m, "Launched bridge thread with success");
  2016 +	return 0;
  2017 +}
  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";
  2031 +enum {
  2032 +	BRIDGE_OPT_PLAYTONE = (1 << 0),
  2033 +};
  2035 +AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
  2036 +	AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE)
  2037 +END_OPTIONS );
  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, }, };
  2055 +	AST_DECLARE_APP_ARGS(args,
  2056 +		AST_APP_ARG(dest_chan);
  2057 +		AST_APP_ARG(options);
  2058 +	);
  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 +	}
  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);
  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 +	}
  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);
  2100 +	/* answer the channel if needed */
  2101 +	if (current_dest_chan->_state != AST_STATE_UP)
  2102 +		ast_answer(current_dest_chan);
  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);
  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 +	}
  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);
  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 +	}
  2144 +	/* do the bridge */
  2145 +	ast_bridge_call(chan, final_dest_chan, &bconfig);
  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);
  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 +	}
  2164 +	return 0;
  2165 +}
  2167  static int load_config(void) 
  2169 @@ -3034,6 +3325,8 @@
  2171  	int res;
  2173 +	ast_register_application(app_bridge, bridge_exec, bridge_synopsis, bridge_descrip);
  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);
  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");
  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;
  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));
  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 

mercurial