asterisk/asterisk.patch

Mon, 27 Apr 2009 12:19:05 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 27 Apr 2009 12:19:05 +0200
changeset 202
f29abea29121
child 310
73d852a30c9a
permissions
-rw-r--r--

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;
  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