asterisk/asterisk.patch

changeset 202
f29abea29121
child 310
73d852a30c9a
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/asterisk/asterisk.patch	Mon Apr 27 12:19:05 2009 +0200
     1.3 @@ -0,0 +1,2265 @@
     1.4 +Index: cdr/cdr_sqlite.c
     1.5 +diff -Nau cdr/cdr_sqlite.c.orig cdr/cdr_sqlite.c
     1.6 +--- cdr/cdr_sqlite.c.orig	2007-06-14 23:50:40.000000000 +0200
     1.7 ++++ cdr/cdr_sqlite.c	2009-04-24 00:30:33.000000000 +0200
     1.8 +@@ -58,7 +58,7 @@
     1.9 + #define DATE_FORMAT "%Y-%m-%d %T"
    1.10 + 
    1.11 + static char *name = "sqlite";
    1.12 +-static sqlite* db = NULL;
    1.13 ++static sqlite3 *db = NULL;
    1.14 + 
    1.15 + AST_MUTEX_DEFINE_STATIC(sqlite_lock);
    1.16 + 
    1.17 +@@ -92,10 +92,10 @@
    1.18 + static int sqlite_log(struct ast_cdr *cdr)
    1.19 + {
    1.20 + 	int res = 0;
    1.21 +-	char *zErr = 0;
    1.22 + 	struct tm tm;
    1.23 + 	time_t t;
    1.24 + 	char startstr[80], answerstr[80], endstr[80];
    1.25 ++    char *cdrsql = 0;
    1.26 + 	int count;
    1.27 + 
    1.28 + 	ast_mutex_lock(&sqlite_lock);
    1.29 +@@ -113,7 +113,7 @@
    1.30 + 	strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
    1.31 + 
    1.32 + 	for(count=0; count<5; count++) {
    1.33 +-		res = sqlite_exec_printf(db,
    1.34 ++		cdrsql = sqlite3_mprintf(
    1.35 + 			"INSERT INTO cdr ("
    1.36 + 				"clid,src,dst,dcontext,"
    1.37 + 				"channel,dstchannel,lastapp,lastdata, "
    1.38 +@@ -138,8 +138,7 @@
    1.39 + #				if LOG_USERFIELD
    1.40 + 				",'%q'"
    1.41 + #				endif
    1.42 +-			")", NULL, NULL, &zErr,
    1.43 +-				cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
    1.44 ++			")", cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
    1.45 + 				cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
    1.46 + 				startstr, answerstr, endstr,
    1.47 + 				cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
    1.48 +@@ -151,16 +150,13 @@
    1.49 + 				,cdr->userfield
    1.50 + #				endif
    1.51 + 			);
    1.52 ++			res = sqlite3_exec(db, cdrsql, 0, 0, 0);
    1.53 ++			sqlite3_free(cdrsql);
    1.54 + 		if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
    1.55 + 			break;
    1.56 + 		usleep(200);
    1.57 + 	}
    1.58 + 	
    1.59 +-	if (zErr) {
    1.60 +-		ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
    1.61 +-		free(zErr);
    1.62 +-	}
    1.63 +-
    1.64 + 	ast_mutex_unlock(&sqlite_lock);
    1.65 + 	return res;
    1.66 + }
    1.67 +@@ -168,7 +164,7 @@
    1.68 + static int unload_module(void)
    1.69 + {
    1.70 + 	if (db)
    1.71 +-		sqlite_close(db);
    1.72 ++		sqlite3_close(db);
    1.73 + 	ast_cdr_unregister(name);
    1.74 + 	return 0;
    1.75 + }
    1.76 +@@ -181,17 +177,16 @@
    1.77 + 
    1.78 + 	/* is the database there? */
    1.79 + 	snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
    1.80 +-	db = sqlite_open(fn, 0660, &zErr);
    1.81 ++	sqlite3_open(fn, &db);
    1.82 + 	if (!db) {
    1.83 +-		ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
    1.84 +-		free(zErr);
    1.85 ++		ast_log(LOG_ERROR, "cdr_sqlite: %s\n", sqlite3_errmsg(db));
    1.86 + 		return -1;
    1.87 + 	}
    1.88 + 
    1.89 + 	/* is the table there? */
    1.90 +-	res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
    1.91 ++	res = sqlite3_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
    1.92 + 	if (res) {
    1.93 +-		res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
    1.94 ++		res = sqlite3_exec(db, sql_create_table, NULL, NULL, &zErr);
    1.95 + 		if (res) {
    1.96 + 			ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
    1.97 + 			free(zErr);
    1.98 +@@ -210,7 +205,7 @@
    1.99 + 
   1.100 + err:
   1.101 + 	if (db)
   1.102 +-		sqlite_close(db);
   1.103 ++		sqlite3_close(db);
   1.104 + 	return -1;
   1.105 + }
   1.106 + 
   1.107 +Index: channels/chan_sip.c
   1.108 +diff -Nau channels/chan_sip.c.orig channels/chan_sip.c
   1.109 +--- channels/chan_sip.c.orig	2009-04-02 19:20:22.000000000 +0200
   1.110 ++++ channels/chan_sip.c	2009-04-24 00:30:33.000000000 +0200
   1.111 +@@ -7469,7 +7469,7 @@
   1.112 + 
   1.113 + 	ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
   1.114 + 	c = get_in_brackets(from);
   1.115 +-	if (strncasecmp(c, "sip:", 4)) {
   1.116 ++	if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
   1.117 + 		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
   1.118 + 		return -1;
   1.119 + 	}
   1.120 +@@ -7477,7 +7477,7 @@
   1.121 + 
   1.122 + 	ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
   1.123 + 	c = get_in_brackets(to);
   1.124 +-	if (strncasecmp(c, "sip:", 4)) {
   1.125 ++	if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
   1.126 + 		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
   1.127 + 		return -1;
   1.128 + 	}
   1.129 +@@ -8004,7 +8004,10 @@
   1.130 + 	of = get_in_brackets(from);
   1.131 + 	ast_string_field_set(p, from, of);
   1.132 + 	if (strncasecmp(of, "sip:", 4))
   1.133 +-		ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
   1.134 ++		if (strncasecmp(of, "sips:", 5))
   1.135 ++			ast_log(LOG_NOTICE, "From address missing 'sip:' or 'sips:', using it anyway\n");
   1.136 ++		else
   1.137 ++			of += 5;
   1.138 + 	else
   1.139 + 		of += 4;
   1.140 + 	/* Get just the username part */
   1.141 +@@ -8280,7 +8283,10 @@
   1.142 + 
   1.143 + 	/* Make sure it's a SIP URL */
   1.144 + 	if (strncasecmp(contact, "sip:", 4)) {
   1.145 +-		ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
   1.146 ++		if (strncasecmp(contact, "sips:", 5))
   1.147 ++			ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip: or sips:) trying to use anyway\n", contact);
   1.148 ++		else
   1.149 ++			contact += 5;
   1.150 + 	} else
   1.151 + 		contact += 4;
   1.152 + 
   1.153 +@@ -8409,7 +8415,10 @@
   1.154 + 
   1.155 + 	/* Make sure it's a SIP URL */
   1.156 + 	if (strncasecmp(curi, "sip:", 4)) {
   1.157 +-		ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
   1.158 ++		if (strncasecmp(curi, "sips:", 5))
   1.159 ++			ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip: or sips:) trying to use anyway\n", curi);
   1.160 ++		else
   1.161 ++			curi += 5;
   1.162 + 	} else
   1.163 + 		curi += 4;
   1.164 + 	/* Ditch q */
   1.165 +@@ -9000,9 +9009,12 @@
   1.166 + 
   1.167 + 	if (!strncasecmp(c, "sip:", 4)) {
   1.168 + 		name = c + 4;
   1.169 ++	}
   1.170 ++	else if (!strncasecmp(c, "sips:", 5)) {
   1.171 ++		name = c + 5;
   1.172 + 	} else {
   1.173 + 		name = c;
   1.174 +-		ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
   1.175 ++		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));
   1.176 + 	}
   1.177 + 
   1.178 + 	/* Strip off the domain name */
   1.179 +@@ -9162,10 +9174,15 @@
   1.180 + 		return 0;
   1.181 + 	c = get_in_brackets(tmp);
   1.182 + 	if (strncasecmp(c, "sip:", 4)) {
   1.183 +-		ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
   1.184 +-		return -1;
   1.185 ++		if (strncasecmp(c, "sips:", 5)) {
   1.186 ++			ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", c);
   1.187 ++			return -1;
   1.188 ++		}
   1.189 ++		else
   1.190 ++			c += 5;
   1.191 + 	}
   1.192 +-	c += 4;
   1.193 ++	else
   1.194 ++		c += 4;
   1.195 + 	a = c;
   1.196 + 	strsep(&a, "@;");	/* trim anything after @ or ; */
   1.197 + 	if (sip_debug_test_pvt(p))
   1.198 +@@ -9200,10 +9217,15 @@
   1.199 + 	uri = get_in_brackets(tmp);
   1.200 + 
   1.201 + 	if (strncasecmp(uri, "sip:", 4)) {
   1.202 +-		ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
   1.203 +-		return -1;
   1.204 ++		if (strncasecmp(uri, "sips:", 5)) {
   1.205 ++			ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
   1.206 ++			return -1;
   1.207 ++		}
   1.208 ++		else
   1.209 ++			uri += 5;
   1.210 + 	}
   1.211 +-	uri += 4;
   1.212 ++	else
   1.213 ++		uri += 4;
   1.214 + 
   1.215 + 	/* Now find the From: caller ID and name */
   1.216 + 	ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
   1.217 +@@ -9217,10 +9239,15 @@
   1.218 + 	
   1.219 + 	if (!ast_strlen_zero(from)) {
   1.220 + 		if (strncasecmp(from, "sip:", 4)) {
   1.221 +-			ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
   1.222 +-			return -1;
   1.223 ++			if (strncasecmp(from, "sips:", 5)) {
   1.224 ++				ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
   1.225 ++				return -1;
   1.226 ++			}
   1.227 ++			else
   1.228 ++				from += 5;
   1.229 + 		}
   1.230 +-		from += 4;
   1.231 ++		else
   1.232 ++			from += 4;
   1.233 + 		if ((a = strchr(from, '@')))
   1.234 + 			*a++ = '\0';
   1.235 + 		else
   1.236 +@@ -9397,10 +9424,15 @@
   1.237 + 		ast_uri_decode(refer_to);
   1.238 + 
   1.239 + 	if (strncasecmp(refer_to, "sip:", 4)) {
   1.240 +-		ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
   1.241 +-		return -3;
   1.242 ++		if (strncasecmp(refer_to, "sips:", 5)) {
   1.243 ++			ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
   1.244 ++			return -3;
   1.245 ++		}
   1.246 ++		else
   1.247 ++			refer_to += 5;			/* Skip sips: */
   1.248 + 	}
   1.249 +-	refer_to += 4;			/* Skip sip: */
   1.250 ++	else
   1.251 ++		refer_to += 4;			/* Skip sip: */
   1.252 + 
   1.253 + 	/* Get referred by header if it exists */
   1.254 + 	p_referred_by = get_header(req, "Referred-By");
   1.255 +@@ -9417,9 +9449,13 @@
   1.256 + 		}
   1.257 + 
   1.258 + 		referred_by_uri = get_in_brackets(h_referred_by);
   1.259 +-		if(strncasecmp(referred_by_uri, "sip:", 4)) {
   1.260 +-			ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
   1.261 +-			referred_by_uri = (char *) NULL;
   1.262 ++		if (strncasecmp(referred_by_uri, "sip:", 4)) {
   1.263 ++			if (strncasecmp(referred_by_uri, "sips:", 5)) {
   1.264 ++				ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
   1.265 ++				referred_by_uri = (char *) NULL;
   1.266 ++			}
   1.267 ++			else
   1.268 ++				referred_by_uri += 5;		/* Skip sips: */
   1.269 + 		} else {
   1.270 + 			referred_by_uri += 4;		/* Skip sip: */
   1.271 + 		}
   1.272 +@@ -9547,10 +9583,15 @@
   1.273 + 		ast_uri_decode(c);
   1.274 + 	
   1.275 + 	if (strncasecmp(c, "sip:", 4)) {
   1.276 +-		ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
   1.277 +-		return -1;
   1.278 ++		if (strncasecmp(c, "sips:", 5)) {
   1.279 ++			ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
   1.280 ++			return -1;
   1.281 ++		}
   1.282 ++		else
   1.283 ++			c += 5;
   1.284 + 	}
   1.285 +-	c += 4;
   1.286 ++	else
   1.287 ++		c += 4;
   1.288 + 	if ((a = strchr(c, ';'))) 	/* Remove arguments */
   1.289 + 		*a = '\0';
   1.290 + 	
   1.291 +@@ -9761,6 +9802,8 @@
   1.292 + 		t = uri2;
   1.293 + 		if (!strncasecmp(t, "sip:", 4))
   1.294 + 			t+= 4;
   1.295 ++		else if (!strncasecmp(t, "sips:", 5))
   1.296 ++			t+= 5;
   1.297 + 		ast_string_field_set(p, exten, t);
   1.298 + 		t = strchr(p->exten, '@');
   1.299 + 		if (t)
   1.300 +@@ -9771,7 +9814,10 @@
   1.301 + 	/* save the URI part of the From header */
   1.302 + 	ast_string_field_set(p, from, of);
   1.303 + 	if (strncasecmp(of, "sip:", 4)) {
   1.304 +-		ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
   1.305 ++		if (strncasecmp(of, "sips:", 5))
   1.306 ++			ast_log(LOG_NOTICE, "From address missing 'sip:' or 'sips:', using it anyway\n");
   1.307 ++		else
   1.308 ++			of += 5;
   1.309 + 	} else
   1.310 + 		of += 4;
   1.311 + 	/* Get just the username part */
   1.312 +@@ -12379,6 +12425,8 @@
   1.313 + 	if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
   1.314 + 		if (!strncasecmp(s, "sip:", 4))
   1.315 + 			s += 4;
   1.316 ++		else if (!strncasecmp(s, "sips:", 5))
   1.317 ++			s += 5;
   1.318 + 		e = strchr(s, ';');
   1.319 + 		if (e)
   1.320 + 			*e = '\0';
   1.321 +@@ -12404,6 +12452,8 @@
   1.322 + 	
   1.323 + 		if (!strncasecmp(s, "sip:", 4))
   1.324 + 			s += 4;
   1.325 ++		else if (!strncasecmp(s, "sips:", 5))
   1.326 ++			s += 5;
   1.327 + 		if (option_debug > 1)
   1.328 + 			ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
   1.329 + 		if (p->owner) {
   1.330 +Index: codecs/codec_g722.c
   1.331 +diff -Nau codecs/codec_g722.c.orig codecs/codec_g722.c
   1.332 +--- codecs/codec_g722.c.orig	1970-01-01 01:00:00.000000000 +0100
   1.333 ++++ codecs/codec_g722.c	2009-04-24 00:30:33.000000000 +0200
   1.334 +@@ -0,0 +1,306 @@
   1.335 ++/*
   1.336 ++ * Asterisk -- An open source telephony toolkit.
   1.337 ++ *
   1.338 ++ * Copyright (C) 1999 - 2008, Digium, Inc.
   1.339 ++ *
   1.340 ++ * Matthew Fredrickson <creslin@digium.com>
   1.341 ++ * Russell Bryant <russell@digium.com>
   1.342 ++ *
   1.343 ++ * Special thanks to Steve Underwood for the implementation
   1.344 ++ * and for doing the 8khz<->g.722 direct translation code.
   1.345 ++ *
   1.346 ++ * See http://www.asterisk.org for more information about
   1.347 ++ * the Asterisk project. Please do not directly contact
   1.348 ++ * any of the maintainers of this project for assistance;
   1.349 ++ * the project provides a web site, mailing lists and IRC
   1.350 ++ * channels for your use.
   1.351 ++ *
   1.352 ++ * This program is free software, distributed under the terms of
   1.353 ++ * the GNU General Public License Version 2. See the LICENSE file
   1.354 ++ * at the top of the source tree.
   1.355 ++ */
   1.356 ++
   1.357 ++/*! \file
   1.358 ++ *
   1.359 ++ * \brief codec_g722.c - translate between signed linear and ITU G.722-64kbps
   1.360 ++ *
   1.361 ++ * \author Matthew Fredrickson <creslin@digium.com>
   1.362 ++ * \author Russell Bryant <russell@digium.com>
   1.363 ++ *
   1.364 ++ * \arg http://soft-switch.org/downloads/non-gpl-bits.tgz
   1.365 ++ * \arg http://lists.digium.com/pipermail/asterisk-dev/2006-September/022866.html
   1.366 ++ *
   1.367 ++ * \ingroup codecs
   1.368 ++ */
   1.369 ++
   1.370 ++#include "asterisk.h"
   1.371 ++
   1.372 ++ASTERISK_FILE_VERSION(__FILE__, "$Revision: 106501 $")
   1.373 ++
   1.374 ++#include "asterisk/linkedlists.h"
   1.375 ++#include "asterisk/module.h"
   1.376 ++#include "asterisk/config.h"
   1.377 ++#include "asterisk/options.h"
   1.378 ++#include "asterisk/translate.h"
   1.379 ++#include "asterisk/utils.h"
   1.380 ++
   1.381 ++#define BUFFER_SAMPLES   8096	/* size for the translation buffers */
   1.382 ++#define BUF_SHIFT	5
   1.383 ++
   1.384 ++/* Sample frame data */
   1.385 ++
   1.386 ++#include "g722/g722.h"
   1.387 ++#include "slin_g722_ex.h"
   1.388 ++#include "g722_slin_ex.h"
   1.389 ++
   1.390 ++struct g722_encoder_pvt {
   1.391 ++	g722_encode_state_t g722;
   1.392 ++};
   1.393 ++
   1.394 ++struct g722_decoder_pvt {
   1.395 ++	g722_decode_state_t g722;
   1.396 ++};
   1.397 ++
   1.398 ++/*! \brief init a new instance of g722_encoder_pvt. */
   1.399 ++static int lintog722_new(struct ast_trans_pvt *pvt)
   1.400 ++{
   1.401 ++	struct g722_encoder_pvt *tmp = pvt->pvt;
   1.402 ++
   1.403 ++	g722_encode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
   1.404 ++
   1.405 ++	return 0;
   1.406 ++}
   1.407 ++
   1.408 ++static int lin16tog722_new(struct ast_trans_pvt *pvt)
   1.409 ++{
   1.410 ++	struct g722_encoder_pvt *tmp = pvt->pvt;
   1.411 ++
   1.412 ++	g722_encode_init(&tmp->g722, 64000, 0);
   1.413 ++
   1.414 ++	return 0;
   1.415 ++}
   1.416 ++
   1.417 ++/*! \brief init a new instance of g722_encoder_pvt. */
   1.418 ++static int g722tolin_new(struct ast_trans_pvt *pvt)
   1.419 ++{
   1.420 ++	struct g722_decoder_pvt *tmp = pvt->pvt;
   1.421 ++
   1.422 ++	g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
   1.423 ++
   1.424 ++	return 0;
   1.425 ++}
   1.426 ++
   1.427 ++static int g722tolin16_new(struct ast_trans_pvt *pvt)
   1.428 ++{
   1.429 ++	struct g722_decoder_pvt *tmp = pvt->pvt;
   1.430 ++
   1.431 ++	g722_decode_init(&tmp->g722, 64000, 0);
   1.432 ++
   1.433 ++	return 0;
   1.434 ++}
   1.435 ++
   1.436 ++static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
   1.437 ++{
   1.438 ++	struct g722_decoder_pvt *tmp = pvt->pvt;
   1.439 ++	int out_samples;
   1.440 ++	int in_samples;
   1.441 ++
   1.442 ++	/* g722_decode expects the samples to be in the invalid samples / 2 format */
   1.443 ++	in_samples = f->samples / 2;
   1.444 ++
   1.445 ++	out_samples = g722_decode(&tmp->g722, (int16_t *) &pvt->outbuf[pvt->samples * sizeof(int16_t)], 
   1.446 ++		(uint8_t *) f->data, in_samples);
   1.447 ++
   1.448 ++	pvt->samples += out_samples;
   1.449 ++
   1.450 ++	pvt->datalen += (out_samples * sizeof(int16_t));
   1.451 ++
   1.452 ++	return 0;
   1.453 ++}
   1.454 ++
   1.455 ++static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
   1.456 ++{
   1.457 ++	struct g722_encoder_pvt *tmp = pvt->pvt;
   1.458 ++	int outlen;
   1.459 ++
   1.460 ++	outlen = g722_encode(&tmp->g722, (uint8_t *) (&pvt->outbuf[pvt->datalen]), 
   1.461 ++		(int16_t *) f->data, f->samples);
   1.462 ++
   1.463 ++	pvt->samples += outlen * 2;
   1.464 ++
   1.465 ++	pvt->datalen += outlen;
   1.466 ++
   1.467 ++	return 0;
   1.468 ++}
   1.469 ++
   1.470 ++static struct ast_frame *g722tolin_sample(void)
   1.471 ++{
   1.472 ++	static struct ast_frame f = {
   1.473 ++		.frametype = AST_FRAME_VOICE,
   1.474 ++		.subclass = AST_FORMAT_G722,
   1.475 ++		.datalen = sizeof(g722_slin_ex),
   1.476 ++		.samples = sizeof(g722_slin_ex) * 2,
   1.477 ++		.src = __PRETTY_FUNCTION__,
   1.478 ++		.data = g722_slin_ex,
   1.479 ++	};
   1.480 ++
   1.481 ++	return &f;
   1.482 ++}
   1.483 ++
   1.484 ++static struct ast_frame *g722tolin16_sample(void)
   1.485 ++{
   1.486 ++	static struct ast_frame f = {
   1.487 ++		.frametype = AST_FRAME_VOICE,
   1.488 ++		.subclass = AST_FORMAT_G722,
   1.489 ++		.datalen = sizeof(slin_g722_ex),
   1.490 ++		.samples = sizeof(slin_g722_ex) * 2,
   1.491 ++		.src = __PRETTY_FUNCTION__,
   1.492 ++		.data = slin_g722_ex,
   1.493 ++	};
   1.494 ++
   1.495 ++	return &f;
   1.496 ++}
   1.497 ++
   1.498 ++static struct ast_frame *lintog722_sample (void)
   1.499 ++{
   1.500 ++	static struct ast_frame f = {
   1.501 ++		.frametype = AST_FRAME_VOICE,
   1.502 ++		.subclass = AST_FORMAT_SLINEAR,
   1.503 ++		.datalen = sizeof(slin_g722_ex),
   1.504 ++		.samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]),
   1.505 ++		.src = __PRETTY_FUNCTION__,
   1.506 ++		.data = slin_g722_ex,
   1.507 ++	};
   1.508 ++
   1.509 ++	return &f;
   1.510 ++}
   1.511 ++
   1.512 ++static struct ast_frame *lin16tog722_sample (void)
   1.513 ++{
   1.514 ++	static struct ast_frame f = {
   1.515 ++		.frametype = AST_FRAME_VOICE,
   1.516 ++		.subclass = AST_FORMAT_SLINEAR16,
   1.517 ++		.datalen = sizeof(slin_g722_ex),
   1.518 ++		.samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]),
   1.519 ++		.src = __PRETTY_FUNCTION__,
   1.520 ++		.data = slin_g722_ex,
   1.521 ++	};
   1.522 ++
   1.523 ++	return &f;
   1.524 ++}
   1.525 ++
   1.526 ++static struct ast_translator g722tolin = {
   1.527 ++	.name = "g722tolin",
   1.528 ++	.srcfmt = AST_FORMAT_G722,
   1.529 ++	.dstfmt = AST_FORMAT_SLINEAR,
   1.530 ++	.newpvt = g722tolin_new,	/* same for both directions */
   1.531 ++	.framein = g722tolin_framein,
   1.532 ++	.sample = g722tolin_sample,
   1.533 ++	.desc_size = sizeof(struct g722_decoder_pvt),
   1.534 ++	.buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
   1.535 ++	.buf_size = BUFFER_SAMPLES,
   1.536 ++	.plc_samples = 160,
   1.537 ++};
   1.538 ++
   1.539 ++static struct ast_translator lintog722 = {
   1.540 ++	.name = "lintog722",
   1.541 ++	.srcfmt = AST_FORMAT_SLINEAR,
   1.542 ++	.dstfmt = AST_FORMAT_G722,
   1.543 ++	.newpvt = lintog722_new,	/* same for both directions */
   1.544 ++	.framein = lintog722_framein,
   1.545 ++	.sample = lintog722_sample,
   1.546 ++	.desc_size = sizeof(struct g722_encoder_pvt),
   1.547 ++	.buffer_samples = BUFFER_SAMPLES * 2,
   1.548 ++	.buf_size = BUFFER_SAMPLES,
   1.549 ++};
   1.550 ++
   1.551 ++static struct ast_translator g722tolin16 = {
   1.552 ++	.name = "g722tolin16",
   1.553 ++	.srcfmt = AST_FORMAT_G722,
   1.554 ++	.dstfmt = AST_FORMAT_SLINEAR16,
   1.555 ++	.newpvt = g722tolin16_new,	/* same for both directions */
   1.556 ++	.framein = g722tolin_framein,
   1.557 ++	.sample = g722tolin16_sample,
   1.558 ++	.desc_size = sizeof(struct g722_decoder_pvt),
   1.559 ++	.buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
   1.560 ++	.buf_size = BUFFER_SAMPLES,
   1.561 ++	.plc_samples = 160,
   1.562 ++};
   1.563 ++
   1.564 ++static struct ast_translator lin16tog722 = {
   1.565 ++	.name = "lin16tog722",
   1.566 ++	.srcfmt = AST_FORMAT_SLINEAR16,
   1.567 ++	.dstfmt = AST_FORMAT_G722,
   1.568 ++	.newpvt = lin16tog722_new,	/* same for both directions */
   1.569 ++	.framein = lintog722_framein,
   1.570 ++	.sample = lin16tog722_sample,
   1.571 ++	.desc_size = sizeof(struct g722_encoder_pvt),
   1.572 ++	.buffer_samples = BUFFER_SAMPLES * 2,
   1.573 ++	.buf_size = BUFFER_SAMPLES,
   1.574 ++};
   1.575 ++
   1.576 ++static int parse_config(int reload)
   1.577 ++{
   1.578 ++	struct ast_variable *var;
   1.579 ++	struct ast_config *cfg = ast_config_load("codecs.conf");
   1.580 ++
   1.581 ++	if (cfg == NULL)
   1.582 ++		return 0;
   1.583 ++	if (cfg == CONFIG_STATUS_FILEUNCHANGED)
   1.584 ++		return 0;
   1.585 ++	for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
   1.586 ++		if (!strcasecmp(var->name, "genericplc")) {
   1.587 ++			g722tolin.useplc = ast_true(var->value) ? 1 : 0;
   1.588 ++			if (option_verbose > 2)
   1.589 ++				ast_verbose(VERBOSE_PREFIX_3 "codec_g722: %susing generic PLC\n",
   1.590 ++					g722tolin.useplc ? "" : "not ");
   1.591 ++		}
   1.592 ++	}
   1.593 ++	ast_config_destroy(cfg);
   1.594 ++	return 0;
   1.595 ++}
   1.596 ++
   1.597 ++static int reload(void)
   1.598 ++{
   1.599 ++	if (parse_config(1))
   1.600 ++		return AST_MODULE_LOAD_DECLINE;
   1.601 ++	return AST_MODULE_LOAD_SUCCESS;
   1.602 ++}
   1.603 ++
   1.604 ++static int unload_module(void)
   1.605 ++{
   1.606 ++	int res = 0;
   1.607 ++
   1.608 ++	res |= ast_unregister_translator(&g722tolin);
   1.609 ++	res |= ast_unregister_translator(&lintog722);
   1.610 ++	res |= ast_unregister_translator(&g722tolin16);
   1.611 ++	res |= ast_unregister_translator(&lin16tog722);
   1.612 ++
   1.613 ++	return res;
   1.614 ++}
   1.615 ++
   1.616 ++static int load_module(void)
   1.617 ++{
   1.618 ++	int res = 0;
   1.619 ++
   1.620 ++	if (parse_config(0))
   1.621 ++		return AST_MODULE_LOAD_DECLINE;
   1.622 ++
   1.623 ++	res |= ast_register_translator(&g722tolin);
   1.624 ++	res |= ast_register_translator(&lintog722);
   1.625 ++	res |= ast_register_translator(&g722tolin16);
   1.626 ++	res |= ast_register_translator(&lin16tog722);
   1.627 ++
   1.628 ++	if (res) {
   1.629 ++		unload_module();
   1.630 ++		return AST_MODULE_LOAD_FAILURE;
   1.631 ++	}	
   1.632 ++
   1.633 ++	return AST_MODULE_LOAD_SUCCESS;
   1.634 ++}
   1.635 ++
   1.636 ++AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder",
   1.637 ++		.load = load_module,
   1.638 ++		.unload = unload_module,
   1.639 ++		.reload = reload,
   1.640 ++	       );
   1.641 +Index: codecs/g722/g722_decode.c
   1.642 +diff -Nau codecs/g722/g722_decode.c.orig codecs/g722/g722_decode.c
   1.643 +--- codecs/g722/g722_decode.c.orig	1970-01-01 01:00:00.000000000 +0100
   1.644 ++++ codecs/g722/g722_decode.c	2009-04-24 00:30:33.000000000 +0200
   1.645 +@@ -0,0 +1,398 @@
   1.646 ++/*
   1.647 ++ * SpanDSP - a series of DSP components for telephony
   1.648 ++ *
   1.649 ++ * g722_decode.c - The ITU G.722 codec, decode part.
   1.650 ++ *
   1.651 ++ * Written by Steve Underwood <steveu@coppice.org>
   1.652 ++ *
   1.653 ++ * Copyright (C) 2005 Steve Underwood
   1.654 ++ *
   1.655 ++ *  Despite my general liking of the GPL, I place my own contributions 
   1.656 ++ *  to this code in the public domain for the benefit of all mankind -
   1.657 ++ *  even the slimy ones who might try to proprietize my work and use it
   1.658 ++ *  to my detriment.
   1.659 ++ *
   1.660 ++ * Based in part on a single channel G.722 codec which is:
   1.661 ++ *
   1.662 ++ * Copyright (c) CMU 1993
   1.663 ++ * Computer Science, Speech Group
   1.664 ++ * Chengxiang Lu and Alex Hauptmann
   1.665 ++ *
   1.666 ++ * $Id: g722_decode.c 48661 2006-12-21 00:08:21Z mattf $
   1.667 ++ */
   1.668 ++
   1.669 ++/*! \file */
   1.670 ++
   1.671 ++#ifdef HAVE_CONFIG_H
   1.672 ++#include <config.h>
   1.673 ++#endif
   1.674 ++
   1.675 ++#include <stdio.h>
   1.676 ++#include <inttypes.h>
   1.677 ++#include <memory.h>
   1.678 ++#include <stdlib.h>
   1.679 ++#if 0
   1.680 ++#include <tgmath.h>
   1.681 ++#endif
   1.682 ++
   1.683 ++#include "g722.h"
   1.684 ++
   1.685 ++#if !defined(FALSE)
   1.686 ++#define FALSE 0
   1.687 ++#endif
   1.688 ++#if !defined(TRUE)
   1.689 ++#define TRUE (!FALSE)
   1.690 ++#endif
   1.691 ++
   1.692 ++static __inline__ int16_t saturate(int32_t amp)
   1.693 ++{
   1.694 ++    int16_t amp16;
   1.695 ++
   1.696 ++    /* Hopefully this is optimised for the common case - not clipping */
   1.697 ++    amp16 = (int16_t) amp;
   1.698 ++    if (amp == amp16)
   1.699 ++        return amp16;
   1.700 ++    if (amp > INT16_MAX)
   1.701 ++        return  INT16_MAX;
   1.702 ++    return  INT16_MIN;
   1.703 ++}
   1.704 ++/*- End of function --------------------------------------------------------*/
   1.705 ++
   1.706 ++static void block4(g722_decode_state_t *s, int band, int d);
   1.707 ++
   1.708 ++static void block4(g722_decode_state_t *s, int band, int d)
   1.709 ++{
   1.710 ++    int wd1;
   1.711 ++    int wd2;
   1.712 ++    int wd3;
   1.713 ++    int i;
   1.714 ++
   1.715 ++    /* Block 4, RECONS */
   1.716 ++    s->band[band].d[0] = d;
   1.717 ++    s->band[band].r[0] = saturate(s->band[band].s + d);
   1.718 ++
   1.719 ++    /* Block 4, PARREC */
   1.720 ++    s->band[band].p[0] = saturate(s->band[band].sz + d);
   1.721 ++
   1.722 ++    /* Block 4, UPPOL2 */
   1.723 ++    for (i = 0;  i < 3;  i++)
   1.724 ++        s->band[band].sg[i] = s->band[band].p[i] >> 15;
   1.725 ++    wd1 = saturate(s->band[band].a[1] << 2);
   1.726 ++
   1.727 ++    wd2 = (s->band[band].sg[0] == s->band[band].sg[1])  ?  -wd1  :  wd1;
   1.728 ++    if (wd2 > 32767)
   1.729 ++        wd2 = 32767;
   1.730 ++    wd3 = (s->band[band].sg[0] == s->band[band].sg[2])  ?  128  :  -128;
   1.731 ++    wd3 += (wd2 >> 7);
   1.732 ++    wd3 += (s->band[band].a[2]*32512) >> 15;
   1.733 ++    if (wd3 > 12288)
   1.734 ++        wd3 = 12288;
   1.735 ++    else if (wd3 < -12288)
   1.736 ++        wd3 = -12288;
   1.737 ++    s->band[band].ap[2] = wd3;
   1.738 ++
   1.739 ++    /* Block 4, UPPOL1 */
   1.740 ++    s->band[band].sg[0] = s->band[band].p[0] >> 15;
   1.741 ++    s->band[band].sg[1] = s->band[band].p[1] >> 15;
   1.742 ++    wd1 = (s->band[band].sg[0] == s->band[band].sg[1])  ?  192  :  -192;
   1.743 ++    wd2 = (s->band[band].a[1]*32640) >> 15;
   1.744 ++
   1.745 ++    s->band[band].ap[1] = saturate(wd1 + wd2);
   1.746 ++    wd3 = saturate(15360 - s->band[band].ap[2]);
   1.747 ++    if (s->band[band].ap[1] > wd3)
   1.748 ++        s->band[band].ap[1] = wd3;
   1.749 ++    else if (s->band[band].ap[1] < -wd3)
   1.750 ++        s->band[band].ap[1] = -wd3;
   1.751 ++
   1.752 ++    /* Block 4, UPZERO */
   1.753 ++    wd1 = (d == 0)  ?  0  :  128;
   1.754 ++    s->band[band].sg[0] = d >> 15;
   1.755 ++    for (i = 1;  i < 7;  i++)
   1.756 ++    {
   1.757 ++        s->band[band].sg[i] = s->band[band].d[i] >> 15;
   1.758 ++        wd2 = (s->band[band].sg[i] == s->band[band].sg[0])  ?  wd1  :  -wd1;
   1.759 ++        wd3 = (s->band[band].b[i]*32640) >> 15;
   1.760 ++        s->band[band].bp[i] = saturate(wd2 + wd3);
   1.761 ++    }
   1.762 ++
   1.763 ++    /* Block 4, DELAYA */
   1.764 ++    for (i = 6;  i > 0;  i--)
   1.765 ++    {
   1.766 ++        s->band[band].d[i] = s->band[band].d[i - 1];
   1.767 ++        s->band[band].b[i] = s->band[band].bp[i];
   1.768 ++    }
   1.769 ++    
   1.770 ++    for (i = 2;  i > 0;  i--)
   1.771 ++    {
   1.772 ++        s->band[band].r[i] = s->band[band].r[i - 1];
   1.773 ++        s->band[band].p[i] = s->band[band].p[i - 1];
   1.774 ++        s->band[band].a[i] = s->band[band].ap[i];
   1.775 ++    }
   1.776 ++
   1.777 ++    /* Block 4, FILTEP */
   1.778 ++    wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
   1.779 ++    wd1 = (s->band[band].a[1]*wd1) >> 15;
   1.780 ++    wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
   1.781 ++    wd2 = (s->band[band].a[2]*wd2) >> 15;
   1.782 ++    s->band[band].sp = saturate(wd1 + wd2);
   1.783 ++
   1.784 ++    /* Block 4, FILTEZ */
   1.785 ++    s->band[band].sz = 0;
   1.786 ++    for (i = 6;  i > 0;  i--)
   1.787 ++    {
   1.788 ++        wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
   1.789 ++        s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
   1.790 ++    }
   1.791 ++    s->band[band].sz = saturate(s->band[band].sz);
   1.792 ++
   1.793 ++    /* Block 4, PREDIC */
   1.794 ++    s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
   1.795 ++}
   1.796 ++/*- End of function --------------------------------------------------------*/
   1.797 ++
   1.798 ++g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options)
   1.799 ++{
   1.800 ++    if (s == NULL)
   1.801 ++    {
   1.802 ++        if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL)
   1.803 ++            return NULL;
   1.804 ++    }
   1.805 ++    memset(s, 0, sizeof(*s));
   1.806 ++    if (rate == 48000)
   1.807 ++        s->bits_per_sample = 6;
   1.808 ++    else if (rate == 56000)
   1.809 ++        s->bits_per_sample = 7;
   1.810 ++    else
   1.811 ++        s->bits_per_sample = 8;
   1.812 ++    if ((options & G722_SAMPLE_RATE_8000))
   1.813 ++        s->eight_k = TRUE;
   1.814 ++    if ((options & G722_PACKED)  &&  s->bits_per_sample != 8)
   1.815 ++        s->packed = TRUE;
   1.816 ++    else
   1.817 ++        s->packed = FALSE;
   1.818 ++    s->band[0].det = 32;
   1.819 ++    s->band[1].det = 8;
   1.820 ++    return s;
   1.821 ++}
   1.822 ++/*- End of function --------------------------------------------------------*/
   1.823 ++
   1.824 ++int g722_decode_release(g722_decode_state_t *s)
   1.825 ++{
   1.826 ++    free(s);
   1.827 ++    return 0;
   1.828 ++}
   1.829 ++/*- End of function --------------------------------------------------------*/
   1.830 ++
   1.831 ++int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
   1.832 ++{
   1.833 ++    static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
   1.834 ++    static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3,  2, 1, 0 };
   1.835 ++    static const int ilb[32] =
   1.836 ++    {
   1.837 ++        2048, 2093, 2139, 2186, 2233, 2282, 2332,
   1.838 ++        2383, 2435, 2489, 2543, 2599, 2656, 2714,
   1.839 ++        2774, 2834, 2896, 2960, 3025, 3091, 3158,
   1.840 ++        3228, 3298, 3371, 3444, 3520, 3597, 3676,
   1.841 ++        3756, 3838, 3922, 4008
   1.842 ++    };
   1.843 ++    static const int wh[3] = {0, -214, 798};
   1.844 ++    static const int rh2[4] = {2, 1, 2, 1};
   1.845 ++    static const int qm2[4] = {-7408, -1616,  7408,   1616};
   1.846 ++    static const int qm4[16] = 
   1.847 ++    {
   1.848 ++              0, -20456, -12896,  -8968, 
   1.849 ++          -6288,  -4240,  -2584,  -1200,
   1.850 ++          20456,  12896,   8968,   6288,
   1.851 ++           4240,   2584,   1200,      0
   1.852 ++    };
   1.853 ++    static const int qm5[32] =
   1.854 ++    {
   1.855 ++           -280,   -280, -23352, -17560,
   1.856 ++         -14120, -11664,  -9752,  -8184,
   1.857 ++          -6864,  -5712,  -4696,  -3784,
   1.858 ++          -2960,  -2208,  -1520,   -880,
   1.859 ++          23352,  17560,  14120,  11664,
   1.860 ++           9752,   8184,   6864,   5712,
   1.861 ++           4696,   3784,   2960,   2208,
   1.862 ++           1520,    880,    280,   -280
   1.863 ++    };
   1.864 ++    static const int qm6[64] =
   1.865 ++    {
   1.866 ++           -136,   -136,   -136,   -136,
   1.867 ++         -24808, -21904, -19008, -16704,
   1.868 ++         -14984, -13512, -12280, -11192,
   1.869 ++         -10232,  -9360,  -8576,  -7856,
   1.870 ++          -7192,  -6576,  -6000,  -5456,
   1.871 ++          -4944,  -4464,  -4008,  -3576,
   1.872 ++          -3168,  -2776,  -2400,  -2032,
   1.873 ++          -1688,  -1360,  -1040,   -728,
   1.874 ++          24808,  21904,  19008,  16704,
   1.875 ++          14984,  13512,  12280,  11192,
   1.876 ++          10232,   9360,   8576,   7856,
   1.877 ++           7192,   6576,   6000,   5456,
   1.878 ++           4944,   4464,   4008,   3576,
   1.879 ++           3168,   2776,   2400,   2032,
   1.880 ++           1688,   1360,   1040,    728,
   1.881 ++            432,    136,   -432,   -136
   1.882 ++    };
   1.883 ++    static const int qmf_coeffs[12] =
   1.884 ++    {
   1.885 ++           3,  -11,   12,   32, -210,  951, 3876, -805,  362, -156,   53,  -11,
   1.886 ++    };
   1.887 ++
   1.888 ++    int dlowt;
   1.889 ++    int rlow;
   1.890 ++    int ihigh;
   1.891 ++    int dhigh;
   1.892 ++    int rhigh;
   1.893 ++    int xout1;
   1.894 ++    int xout2;
   1.895 ++    int wd1;
   1.896 ++    int wd2;
   1.897 ++    int wd3;
   1.898 ++    int code;
   1.899 ++    int outlen;
   1.900 ++    int i;
   1.901 ++    int j;
   1.902 ++
   1.903 ++    outlen = 0;
   1.904 ++    rhigh = 0;
   1.905 ++    for (j = 0;  j < len;  )
   1.906 ++    {
   1.907 ++        if (s->packed)
   1.908 ++        {
   1.909 ++            /* Unpack the code bits */
   1.910 ++            if (s->in_bits < s->bits_per_sample)
   1.911 ++            {
   1.912 ++                s->in_buffer |= (g722_data[j++] << s->in_bits);
   1.913 ++                s->in_bits += 8;
   1.914 ++            }
   1.915 ++            code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
   1.916 ++            s->in_buffer >>= s->bits_per_sample;
   1.917 ++            s->in_bits -= s->bits_per_sample;
   1.918 ++        }
   1.919 ++        else
   1.920 ++        {
   1.921 ++            code = g722_data[j++];
   1.922 ++        }
   1.923 ++
   1.924 ++        switch (s->bits_per_sample)
   1.925 ++        {
   1.926 ++        default:
   1.927 ++        case 8:
   1.928 ++            wd1 = code & 0x3F;
   1.929 ++            ihigh = (code >> 6) & 0x03;
   1.930 ++            wd2 = qm6[wd1];
   1.931 ++            wd1 >>= 2;
   1.932 ++            break;
   1.933 ++        case 7:
   1.934 ++            wd1 = code & 0x1F;
   1.935 ++            ihigh = (code >> 5) & 0x03;
   1.936 ++            wd2 = qm5[wd1];
   1.937 ++            wd1 >>= 1;
   1.938 ++            break;
   1.939 ++        case 6:
   1.940 ++            wd1 = code & 0x0F;
   1.941 ++            ihigh = (code >> 4) & 0x03;
   1.942 ++            wd2 = qm4[wd1];
   1.943 ++            break;
   1.944 ++        }
   1.945 ++        /* Block 5L, LOW BAND INVQBL */
   1.946 ++        wd2 = (s->band[0].det*wd2) >> 15;
   1.947 ++        /* Block 5L, RECONS */
   1.948 ++        rlow = s->band[0].s + wd2;
   1.949 ++        /* Block 6L, LIMIT */
   1.950 ++        if (rlow > 16383)
   1.951 ++            rlow = 16383;
   1.952 ++        else if (rlow < -16384)
   1.953 ++            rlow = -16384;
   1.954 ++
   1.955 ++        /* Block 2L, INVQAL */
   1.956 ++        wd2 = qm4[wd1];
   1.957 ++        dlowt = (s->band[0].det*wd2) >> 15;
   1.958 ++
   1.959 ++        /* Block 3L, LOGSCL */
   1.960 ++        wd2 = rl42[wd1];
   1.961 ++        wd1 = (s->band[0].nb*127) >> 7;
   1.962 ++        wd1 += wl[wd2];
   1.963 ++        if (wd1 < 0)
   1.964 ++            wd1 = 0;
   1.965 ++        else if (wd1 > 18432)
   1.966 ++            wd1 = 18432;
   1.967 ++        s->band[0].nb = wd1;
   1.968 ++            
   1.969 ++        /* Block 3L, SCALEL */
   1.970 ++        wd1 = (s->band[0].nb >> 6) & 31;
   1.971 ++        wd2 = 8 - (s->band[0].nb >> 11);
   1.972 ++        wd3 = (wd2 < 0)  ?  (ilb[wd1] << -wd2)  :  (ilb[wd1] >> wd2);
   1.973 ++        s->band[0].det = wd3 << 2;
   1.974 ++
   1.975 ++        block4(s, 0, dlowt);
   1.976 ++        
   1.977 ++        if (!s->eight_k)
   1.978 ++        {
   1.979 ++            /* Block 2H, INVQAH */
   1.980 ++            wd2 = qm2[ihigh];
   1.981 ++            dhigh = (s->band[1].det*wd2) >> 15;
   1.982 ++            /* Block 5H, RECONS */
   1.983 ++            rhigh = dhigh + s->band[1].s;
   1.984 ++            /* Block 6H, LIMIT */
   1.985 ++            if (rhigh > 16383)
   1.986 ++                rhigh = 16383;
   1.987 ++            else if (rhigh < -16384)
   1.988 ++                rhigh = -16384;
   1.989 ++
   1.990 ++            /* Block 2H, INVQAH */
   1.991 ++            wd2 = rh2[ihigh];
   1.992 ++            wd1 = (s->band[1].nb*127) >> 7;
   1.993 ++            wd1 += wh[wd2];
   1.994 ++            if (wd1 < 0)
   1.995 ++                wd1 = 0;
   1.996 ++            else if (wd1 > 22528)
   1.997 ++                wd1 = 22528;
   1.998 ++            s->band[1].nb = wd1;
   1.999 ++            
  1.1000 ++            /* Block 3H, SCALEH */
  1.1001 ++            wd1 = (s->band[1].nb >> 6) & 31;
  1.1002 ++            wd2 = 10 - (s->band[1].nb >> 11);
  1.1003 ++            wd3 = (wd2 < 0)  ?  (ilb[wd1] << -wd2)  :  (ilb[wd1] >> wd2);
  1.1004 ++            s->band[1].det = wd3 << 2;
  1.1005 ++
  1.1006 ++            block4(s, 1, dhigh);
  1.1007 ++        }
  1.1008 ++
  1.1009 ++        if (s->itu_test_mode)
  1.1010 ++        {
  1.1011 ++            amp[outlen++] = (int16_t) (rlow << 1);
  1.1012 ++            amp[outlen++] = (int16_t) (rhigh << 1);
  1.1013 ++        }
  1.1014 ++        else
  1.1015 ++        {
  1.1016 ++            if (s->eight_k)
  1.1017 ++            {
  1.1018 ++                amp[outlen++] = (int16_t) rlow;
  1.1019 ++            }
  1.1020 ++            else
  1.1021 ++            {
  1.1022 ++                /* Apply the receive QMF */
  1.1023 ++                for (i = 0;  i < 22;  i++)
  1.1024 ++                    s->x[i] = s->x[i + 2];
  1.1025 ++                s->x[22] = rlow + rhigh;
  1.1026 ++                s->x[23] = rlow - rhigh;
  1.1027 ++
  1.1028 ++                xout1 = 0;
  1.1029 ++                xout2 = 0;
  1.1030 ++                for (i = 0;  i < 12;  i++)
  1.1031 ++                {
  1.1032 ++                    xout2 += s->x[2*i]*qmf_coeffs[i];
  1.1033 ++                    xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
  1.1034 ++                }
  1.1035 ++                amp[outlen++] = (int16_t) (xout1 >> 12);
  1.1036 ++                amp[outlen++] = (int16_t) (xout2 >> 12);
  1.1037 ++            }
  1.1038 ++        }
  1.1039 ++    }
  1.1040 ++    return outlen;
  1.1041 ++}
  1.1042 ++/*- End of function --------------------------------------------------------*/
  1.1043 ++/*- End of file ------------------------------------------------------------*/
  1.1044 +Index: codecs/g722/g722_encode.c
  1.1045 +diff -Nau codecs/g722/g722_encode.c.orig codecs/g722/g722_encode.c
  1.1046 +--- codecs/g722/g722_encode.c.orig	1970-01-01 01:00:00.000000000 +0100
  1.1047 ++++ codecs/g722/g722_encode.c	2009-04-24 00:30:33.000000000 +0200
  1.1048 +@@ -0,0 +1,400 @@
  1.1049 ++/*
  1.1050 ++ * SpanDSP - a series of DSP components for telephony
  1.1051 ++ *
  1.1052 ++ * g722_encode.c - The ITU G.722 codec, encode part.
  1.1053 ++ *
  1.1054 ++ * Written by Steve Underwood <steveu@coppice.org>
  1.1055 ++ *
  1.1056 ++ * Copyright (C) 2005 Steve Underwood
  1.1057 ++ *
  1.1058 ++ * All rights reserved.
  1.1059 ++ *
  1.1060 ++ *  Despite my general liking of the GPL, I place my own contributions 
  1.1061 ++ *  to this code in the public domain for the benefit of all mankind -
  1.1062 ++ *  even the slimy ones who might try to proprietize my work and use it
  1.1063 ++ *  to my detriment.
  1.1064 ++ *
  1.1065 ++ * Based on a single channel 64kbps only G.722 codec which is:
  1.1066 ++ *
  1.1067 ++ *****    Copyright (c) CMU    1993      *****
  1.1068 ++ * Computer Science, Speech Group
  1.1069 ++ * Chengxiang Lu and Alex Hauptmann
  1.1070 ++ *
  1.1071 ++ * $Id: g722_encode.c 48661 2006-12-21 00:08:21Z mattf $
  1.1072 ++ */
  1.1073 ++
  1.1074 ++/*! \file */
  1.1075 ++
  1.1076 ++#ifdef HAVE_CONFIG_H
  1.1077 ++#include <config.h>
  1.1078 ++#endif
  1.1079 ++
  1.1080 ++#include <stdio.h>
  1.1081 ++#include <inttypes.h>
  1.1082 ++#include <memory.h>
  1.1083 ++#include <stdlib.h>
  1.1084 ++#if 0
  1.1085 ++#include <tgmath.h>
  1.1086 ++#endif
  1.1087 ++
  1.1088 ++#include "g722.h"
  1.1089 ++
  1.1090 ++#if !defined(FALSE)
  1.1091 ++#define FALSE 0
  1.1092 ++#endif
  1.1093 ++#if !defined(TRUE)
  1.1094 ++#define TRUE (!FALSE)
  1.1095 ++#endif
  1.1096 ++
  1.1097 ++static __inline__ int16_t saturate(int32_t amp)
  1.1098 ++{
  1.1099 ++    int16_t amp16;
  1.1100 ++
  1.1101 ++    /* Hopefully this is optimised for the common case - not clipping */
  1.1102 ++    amp16 = (int16_t) amp;
  1.1103 ++    if (amp == amp16)
  1.1104 ++        return amp16;
  1.1105 ++    if (amp > INT16_MAX)
  1.1106 ++        return  INT16_MAX;
  1.1107 ++    return  INT16_MIN;
  1.1108 ++}
  1.1109 ++/*- End of function --------------------------------------------------------*/
  1.1110 ++
  1.1111 ++static void block4(g722_encode_state_t *s, int band, int d)
  1.1112 ++{
  1.1113 ++    int wd1;
  1.1114 ++    int wd2;
  1.1115 ++    int wd3;
  1.1116 ++    int i;
  1.1117 ++
  1.1118 ++    /* Block 4, RECONS */
  1.1119 ++    s->band[band].d[0] = d;
  1.1120 ++    s->band[band].r[0] = saturate(s->band[band].s + d);
  1.1121 ++
  1.1122 ++    /* Block 4, PARREC */
  1.1123 ++    s->band[band].p[0] = saturate(s->band[band].sz + d);
  1.1124 ++
  1.1125 ++    /* Block 4, UPPOL2 */
  1.1126 ++    for (i = 0;  i < 3;  i++)
  1.1127 ++        s->band[band].sg[i] = s->band[band].p[i] >> 15;
  1.1128 ++    wd1 = saturate(s->band[band].a[1] << 2);
  1.1129 ++
  1.1130 ++    wd2 = (s->band[band].sg[0] == s->band[band].sg[1])  ?  -wd1  :  wd1;
  1.1131 ++    if (wd2 > 32767)
  1.1132 ++        wd2 = 32767;
  1.1133 ++    wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2])  ?  128  :  -128);
  1.1134 ++    wd3 += (s->band[band].a[2]*32512) >> 15;
  1.1135 ++    if (wd3 > 12288)
  1.1136 ++        wd3 = 12288;
  1.1137 ++    else if (wd3 < -12288)
  1.1138 ++        wd3 = -12288;
  1.1139 ++    s->band[band].ap[2] = wd3;
  1.1140 ++
  1.1141 ++    /* Block 4, UPPOL1 */
  1.1142 ++    s->band[band].sg[0] = s->band[band].p[0] >> 15;
  1.1143 ++    s->band[band].sg[1] = s->band[band].p[1] >> 15;
  1.1144 ++    wd1 = (s->band[band].sg[0] == s->band[band].sg[1])  ?  192  :  -192;
  1.1145 ++    wd2 = (s->band[band].a[1]*32640) >> 15;
  1.1146 ++
  1.1147 ++    s->band[band].ap[1] = saturate(wd1 + wd2);
  1.1148 ++    wd3 = saturate(15360 - s->band[band].ap[2]);
  1.1149 ++    if (s->band[band].ap[1] > wd3)
  1.1150 ++        s->band[band].ap[1] = wd3;
  1.1151 ++    else if (s->band[band].ap[1] < -wd3)
  1.1152 ++        s->band[band].ap[1] = -wd3;
  1.1153 ++
  1.1154 ++    /* Block 4, UPZERO */
  1.1155 ++    wd1 = (d == 0)  ?  0  :  128;
  1.1156 ++    s->band[band].sg[0] = d >> 15;
  1.1157 ++    for (i = 1;  i < 7;  i++)
  1.1158 ++    {
  1.1159 ++        s->band[band].sg[i] = s->band[band].d[i] >> 15;
  1.1160 ++        wd2 = (s->band[band].sg[i] == s->band[band].sg[0])  ?  wd1  :  -wd1;
  1.1161 ++        wd3 = (s->band[band].b[i]*32640) >> 15;
  1.1162 ++        s->band[band].bp[i] = saturate(wd2 + wd3);
  1.1163 ++    }
  1.1164 ++
  1.1165 ++    /* Block 4, DELAYA */
  1.1166 ++    for (i = 6;  i > 0;  i--)
  1.1167 ++    {
  1.1168 ++        s->band[band].d[i] = s->band[band].d[i - 1];
  1.1169 ++        s->band[band].b[i] = s->band[band].bp[i];
  1.1170 ++    }
  1.1171 ++    
  1.1172 ++    for (i = 2;  i > 0;  i--)
  1.1173 ++    {
  1.1174 ++        s->band[band].r[i] = s->band[band].r[i - 1];
  1.1175 ++        s->band[band].p[i] = s->band[band].p[i - 1];
  1.1176 ++        s->band[band].a[i] = s->band[band].ap[i];
  1.1177 ++    }
  1.1178 ++
  1.1179 ++    /* Block 4, FILTEP */
  1.1180 ++    wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
  1.1181 ++    wd1 = (s->band[band].a[1]*wd1) >> 15;
  1.1182 ++    wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
  1.1183 ++    wd2 = (s->band[band].a[2]*wd2) >> 15;
  1.1184 ++    s->band[band].sp = saturate(wd1 + wd2);
  1.1185 ++
  1.1186 ++    /* Block 4, FILTEZ */
  1.1187 ++    s->band[band].sz = 0;
  1.1188 ++    for (i = 6;  i > 0;  i--)
  1.1189 ++    {
  1.1190 ++        wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
  1.1191 ++        s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
  1.1192 ++    }
  1.1193 ++    s->band[band].sz = saturate(s->band[band].sz);
  1.1194 ++
  1.1195 ++    /* Block 4, PREDIC */
  1.1196 ++    s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
  1.1197 ++}
  1.1198 ++/*- End of function --------------------------------------------------------*/
  1.1199 ++
  1.1200 ++g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options)
  1.1201 ++{
  1.1202 ++    if (s == NULL)
  1.1203 ++    {
  1.1204 ++        if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL)
  1.1205 ++            return NULL;
  1.1206 ++    }
  1.1207 ++    memset(s, 0, sizeof(*s));
  1.1208 ++    if (rate == 48000)
  1.1209 ++        s->bits_per_sample = 6;
  1.1210 ++    else if (rate == 56000)
  1.1211 ++        s->bits_per_sample = 7;
  1.1212 ++    else
  1.1213 ++        s->bits_per_sample = 8;
  1.1214 ++    if ((options & G722_SAMPLE_RATE_8000))
  1.1215 ++        s->eight_k = TRUE;
  1.1216 ++    if ((options & G722_PACKED)  &&  s->bits_per_sample != 8)
  1.1217 ++        s->packed = TRUE;
  1.1218 ++    else
  1.1219 ++        s->packed = FALSE;
  1.1220 ++    s->band[0].det = 32;
  1.1221 ++    s->band[1].det = 8;
  1.1222 ++    return s;
  1.1223 ++}
  1.1224 ++/*- End of function --------------------------------------------------------*/
  1.1225 ++
  1.1226 ++int g722_encode_release(g722_encode_state_t *s)
  1.1227 ++{
  1.1228 ++    free(s);
  1.1229 ++    return 0;
  1.1230 ++}
  1.1231 ++/*- End of function --------------------------------------------------------*/
  1.1232 ++
  1.1233 ++int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len)
  1.1234 ++{
  1.1235 ++    static const int q6[32] =
  1.1236 ++    {
  1.1237 ++           0,   35,   72,  110,  150,  190,  233,  276,
  1.1238 ++         323,  370,  422,  473,  530,  587,  650,  714,
  1.1239 ++         786,  858,  940, 1023, 1121, 1219, 1339, 1458,
  1.1240 ++        1612, 1765, 1980, 2195, 2557, 2919,    0,    0
  1.1241 ++    };
  1.1242 ++    static const int iln[32] =
  1.1243 ++    {
  1.1244 ++         0, 63, 62, 31, 30, 29, 28, 27,
  1.1245 ++        26, 25, 24, 23, 22, 21, 20, 19,
  1.1246 ++        18, 17, 16, 15, 14, 13, 12, 11,
  1.1247 ++        10,  9,  8,  7,  6,  5,  4,  0
  1.1248 ++    };
  1.1249 ++    static const int ilp[32] =
  1.1250 ++    {
  1.1251 ++         0, 61, 60, 59, 58, 57, 56, 55,
  1.1252 ++        54, 53, 52, 51, 50, 49, 48, 47,
  1.1253 ++        46, 45, 44, 43, 42, 41, 40, 39,
  1.1254 ++        38, 37, 36, 35, 34, 33, 32,  0
  1.1255 ++    };
  1.1256 ++    static const int wl[8] =
  1.1257 ++    {
  1.1258 ++        -60, -30, 58, 172, 334, 538, 1198, 3042
  1.1259 ++    };
  1.1260 ++    static const int rl42[16] =
  1.1261 ++    {
  1.1262 ++        0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
  1.1263 ++    };
  1.1264 ++    static const int ilb[32] =
  1.1265 ++    {
  1.1266 ++        2048, 2093, 2139, 2186, 2233, 2282, 2332,
  1.1267 ++        2383, 2435, 2489, 2543, 2599, 2656, 2714,
  1.1268 ++        2774, 2834, 2896, 2960, 3025, 3091, 3158,
  1.1269 ++        3228, 3298, 3371, 3444, 3520, 3597, 3676,
  1.1270 ++        3756, 3838, 3922, 4008
  1.1271 ++    };
  1.1272 ++    static const int qm4[16] =
  1.1273 ++    {
  1.1274 ++             0, -20456, -12896, -8968,
  1.1275 ++         -6288,  -4240,  -2584, -1200,
  1.1276 ++         20456,  12896,   8968,  6288,
  1.1277 ++          4240,   2584,   1200,     0
  1.1278 ++    };
  1.1279 ++    static const int qm2[4] =
  1.1280 ++    {
  1.1281 ++        -7408,  -1616,   7408,   1616
  1.1282 ++    };
  1.1283 ++    static const int qmf_coeffs[12] =
  1.1284 ++    {
  1.1285 ++           3,  -11,   12,   32, -210,  951, 3876, -805,  362, -156,   53,  -11,
  1.1286 ++    };
  1.1287 ++    static const int ihn[3] = {0, 1, 0};
  1.1288 ++    static const int ihp[3] = {0, 3, 2};
  1.1289 ++    static const int wh[3] = {0, -214, 798};
  1.1290 ++    static const int rh2[4] = {2, 1, 2, 1};
  1.1291 ++
  1.1292 ++    int dlow;
  1.1293 ++    int dhigh;
  1.1294 ++    int el;
  1.1295 ++    int wd;
  1.1296 ++    int wd1;
  1.1297 ++    int ril;
  1.1298 ++    int wd2;
  1.1299 ++    int il4;
  1.1300 ++    int ih2;
  1.1301 ++    int wd3;
  1.1302 ++    int eh;
  1.1303 ++    int mih;
  1.1304 ++    int i;
  1.1305 ++    int j;
  1.1306 ++    /* Low and high band PCM from the QMF */
  1.1307 ++    int xlow;
  1.1308 ++    int xhigh;
  1.1309 ++    int g722_bytes;
  1.1310 ++    /* Even and odd tap accumulators */
  1.1311 ++    int sumeven;
  1.1312 ++    int sumodd;
  1.1313 ++    int ihigh;
  1.1314 ++    int ilow;
  1.1315 ++    int code;
  1.1316 ++
  1.1317 ++    g722_bytes = 0;
  1.1318 ++    xhigh = 0;
  1.1319 ++    for (j = 0;  j < len;  )
  1.1320 ++    {
  1.1321 ++        if (s->itu_test_mode)
  1.1322 ++        {
  1.1323 ++            xlow =
  1.1324 ++            xhigh = amp[j++] >> 1;
  1.1325 ++        }
  1.1326 ++        else
  1.1327 ++        {
  1.1328 ++            if (s->eight_k)
  1.1329 ++            {
  1.1330 ++                xlow = amp[j++];
  1.1331 ++            }
  1.1332 ++            else
  1.1333 ++            {
  1.1334 ++                /* Apply the transmit QMF */
  1.1335 ++                /* Shuffle the buffer down */
  1.1336 ++                for (i = 0;  i < 22;  i++)
  1.1337 ++                    s->x[i] = s->x[i + 2];
  1.1338 ++                s->x[22] = amp[j++];
  1.1339 ++                s->x[23] = amp[j++];
  1.1340 ++    
  1.1341 ++                /* Discard every other QMF output */
  1.1342 ++                sumeven = 0;
  1.1343 ++                sumodd = 0;
  1.1344 ++                for (i = 0;  i < 12;  i++)
  1.1345 ++                {
  1.1346 ++                    sumodd += s->x[2*i]*qmf_coeffs[i];
  1.1347 ++                    sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
  1.1348 ++                }
  1.1349 ++                xlow = (sumeven + sumodd) >> 13;
  1.1350 ++                xhigh = (sumeven - sumodd) >> 13;
  1.1351 ++            }
  1.1352 ++        }
  1.1353 ++        /* Block 1L, SUBTRA */
  1.1354 ++        el = saturate(xlow - s->band[0].s);
  1.1355 ++
  1.1356 ++        /* Block 1L, QUANTL */
  1.1357 ++        wd = (el >= 0)  ?  el  :  -(el + 1);
  1.1358 ++
  1.1359 ++        for (i = 1;  i < 30;  i++)
  1.1360 ++        {
  1.1361 ++            wd1 = (q6[i]*s->band[0].det) >> 12;
  1.1362 ++            if (wd < wd1)
  1.1363 ++                break;
  1.1364 ++        }
  1.1365 ++        ilow = (el < 0)  ?  iln[i]  :  ilp[i];
  1.1366 ++
  1.1367 ++        /* Block 2L, INVQAL */
  1.1368 ++        ril = ilow >> 2;
  1.1369 ++        wd2 = qm4[ril];
  1.1370 ++        dlow = (s->band[0].det*wd2) >> 15;
  1.1371 ++
  1.1372 ++        /* Block 3L, LOGSCL */
  1.1373 ++        il4 = rl42[ril];
  1.1374 ++        wd = (s->band[0].nb*127) >> 7;
  1.1375 ++        s->band[0].nb = wd + wl[il4];
  1.1376 ++        if (s->band[0].nb < 0)
  1.1377 ++            s->band[0].nb = 0;
  1.1378 ++        else if (s->band[0].nb > 18432)
  1.1379 ++            s->band[0].nb = 18432;
  1.1380 ++
  1.1381 ++        /* Block 3L, SCALEL */
  1.1382 ++        wd1 = (s->band[0].nb >> 6) & 31;
  1.1383 ++        wd2 = 8 - (s->band[0].nb >> 11);
  1.1384 ++        wd3 = (wd2 < 0)  ?  (ilb[wd1] << -wd2)  :  (ilb[wd1] >> wd2);
  1.1385 ++        s->band[0].det = wd3 << 2;
  1.1386 ++
  1.1387 ++        block4(s, 0, dlow);
  1.1388 ++        
  1.1389 ++        if (s->eight_k)
  1.1390 ++        {
  1.1391 ++            /* Just leave the high bits as zero */
  1.1392 ++            code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
  1.1393 ++        }
  1.1394 ++        else
  1.1395 ++        {
  1.1396 ++            /* Block 1H, SUBTRA */
  1.1397 ++            eh = saturate(xhigh - s->band[1].s);
  1.1398 ++
  1.1399 ++            /* Block 1H, QUANTH */
  1.1400 ++            wd = (eh >= 0)  ?  eh  :  -(eh + 1);
  1.1401 ++            wd1 = (564*s->band[1].det) >> 12;
  1.1402 ++            mih = (wd >= wd1)  ?  2  :  1;
  1.1403 ++            ihigh = (eh < 0)  ?  ihn[mih]  :  ihp[mih];
  1.1404 ++
  1.1405 ++            /* Block 2H, INVQAH */
  1.1406 ++            wd2 = qm2[ihigh];
  1.1407 ++            dhigh = (s->band[1].det*wd2) >> 15;
  1.1408 ++
  1.1409 ++            /* Block 3H, LOGSCH */
  1.1410 ++            ih2 = rh2[ihigh];
  1.1411 ++            wd = (s->band[1].nb*127) >> 7;
  1.1412 ++            s->band[1].nb = wd + wh[ih2];
  1.1413 ++            if (s->band[1].nb < 0)
  1.1414 ++                s->band[1].nb = 0;
  1.1415 ++            else if (s->band[1].nb > 22528)
  1.1416 ++                s->band[1].nb = 22528;
  1.1417 ++
  1.1418 ++            /* Block 3H, SCALEH */
  1.1419 ++            wd1 = (s->band[1].nb >> 6) & 31;
  1.1420 ++            wd2 = 10 - (s->band[1].nb >> 11);
  1.1421 ++            wd3 = (wd2 < 0)  ?  (ilb[wd1] << -wd2)  :  (ilb[wd1] >> wd2);
  1.1422 ++            s->band[1].det = wd3 << 2;
  1.1423 ++
  1.1424 ++            block4(s, 1, dhigh);
  1.1425 ++            code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
  1.1426 ++        }
  1.1427 ++
  1.1428 ++        if (s->packed)
  1.1429 ++        {
  1.1430 ++            /* Pack the code bits */
  1.1431 ++            s->out_buffer |= (code << s->out_bits);
  1.1432 ++            s->out_bits += s->bits_per_sample;
  1.1433 ++            if (s->out_bits >= 8)
  1.1434 ++            {
  1.1435 ++                g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
  1.1436 ++                s->out_bits -= 8;
  1.1437 ++                s->out_buffer >>= 8;
  1.1438 ++            }
  1.1439 ++        }
  1.1440 ++        else
  1.1441 ++        {
  1.1442 ++            g722_data[g722_bytes++] = (uint8_t) code;
  1.1443 ++        }
  1.1444 ++    }
  1.1445 ++    return g722_bytes;
  1.1446 ++}
  1.1447 ++/*- End of function --------------------------------------------------------*/
  1.1448 ++/*- End of file ------------------------------------------------------------*/
  1.1449 +Index: codecs/g722/g722.h
  1.1450 +diff -Nau codecs/g722/g722.h.orig codecs/g722/g722.h
  1.1451 +--- codecs/g722/g722.h.orig	1970-01-01 01:00:00.000000000 +0100
  1.1452 ++++ codecs/g722/g722.h	2009-04-24 00:30:33.000000000 +0200
  1.1453 +@@ -0,0 +1,148 @@
  1.1454 ++/*
  1.1455 ++ * SpanDSP - a series of DSP components for telephony
  1.1456 ++ *
  1.1457 ++ * g722.h - The ITU G.722 codec.
  1.1458 ++ *
  1.1459 ++ * Written by Steve Underwood <steveu@coppice.org>
  1.1460 ++ *
  1.1461 ++ * Copyright (C) 2005 Steve Underwood
  1.1462 ++ *
  1.1463 ++ *  Despite my general liking of the GPL, I place my own contributions 
  1.1464 ++ *  to this code in the public domain for the benefit of all mankind -
  1.1465 ++ *  even the slimy ones who might try to proprietize my work and use it
  1.1466 ++ *  to my detriment.
  1.1467 ++ *
  1.1468 ++ * Based on a single channel G.722 codec which is:
  1.1469 ++ *
  1.1470 ++ *****    Copyright (c) CMU    1993      *****
  1.1471 ++ * Computer Science, Speech Group
  1.1472 ++ * Chengxiang Lu and Alex Hauptmann
  1.1473 ++ *
  1.1474 ++ * $Id: g722.h 48959 2006-12-25 06:42:15Z rizzo $
  1.1475 ++ */
  1.1476 ++
  1.1477 ++
  1.1478 ++/*! \file */
  1.1479 ++
  1.1480 ++#if !defined(_G722_H_)
  1.1481 ++#define _G722_H_
  1.1482 ++
  1.1483 ++/*! \page g722_page G.722 encoding and decoding
  1.1484 ++\section g722_page_sec_1 What does it do?
  1.1485 ++The G.722 module is a bit exact implementation of the ITU G.722 specification for all three
  1.1486 ++specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests.
  1.1487 ++
  1.1488 ++To allow fast and flexible interworking with narrow band telephony, the encoder and decoder
  1.1489 ++support an option for the linear audio to be an 8k samples/second stream. In this mode the
  1.1490 ++codec is considerably faster, and still fully compatible with wideband terminals using G.722.
  1.1491 ++
  1.1492 ++\section g722_page_sec_2 How does it work?
  1.1493 ++???.
  1.1494 ++*/
  1.1495 ++
  1.1496 ++enum
  1.1497 ++{
  1.1498 ++    G722_SAMPLE_RATE_8000 = 0x0001,
  1.1499 ++    G722_PACKED = 0x0002
  1.1500 ++};
  1.1501 ++
  1.1502 ++#ifndef INT16_MAX
  1.1503 ++#define INT16_MAX       32767
  1.1504 ++#endif
  1.1505 ++#ifndef INT16_MIN
  1.1506 ++#define INT16_MIN       (-32768)
  1.1507 ++#endif
  1.1508 ++
  1.1509 ++typedef struct
  1.1510 ++{
  1.1511 ++    /*! TRUE if the operating in the special ITU test mode, with the band split filters
  1.1512 ++             disabled. */
  1.1513 ++    int itu_test_mode;
  1.1514 ++    /*! TRUE if the G.722 data is packed */
  1.1515 ++    int packed;
  1.1516 ++    /*! TRUE if encode from 8k samples/second */
  1.1517 ++    int eight_k;
  1.1518 ++    /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
  1.1519 ++    int bits_per_sample;
  1.1520 ++
  1.1521 ++    /*! Signal history for the QMF */
  1.1522 ++    int x[24];
  1.1523 ++
  1.1524 ++    struct
  1.1525 ++    {
  1.1526 ++        int s;
  1.1527 ++        int sp;
  1.1528 ++        int sz;
  1.1529 ++        int r[3];
  1.1530 ++        int a[3];
  1.1531 ++        int ap[3];
  1.1532 ++        int p[3];
  1.1533 ++        int d[7];
  1.1534 ++        int b[7];
  1.1535 ++        int bp[7];
  1.1536 ++        int sg[7];
  1.1537 ++        int nb;
  1.1538 ++        int det;
  1.1539 ++    } band[2];
  1.1540 ++
  1.1541 ++    unsigned int in_buffer;
  1.1542 ++    int in_bits;
  1.1543 ++    unsigned int out_buffer;
  1.1544 ++    int out_bits;
  1.1545 ++} g722_encode_state_t;
  1.1546 ++
  1.1547 ++typedef struct
  1.1548 ++{
  1.1549 ++    /*! TRUE if the operating in the special ITU test mode, with the band split filters
  1.1550 ++             disabled. */
  1.1551 ++    int itu_test_mode;
  1.1552 ++    /*! TRUE if the G.722 data is packed */
  1.1553 ++    int packed;
  1.1554 ++    /*! TRUE if decode to 8k samples/second */
  1.1555 ++    int eight_k;
  1.1556 ++    /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
  1.1557 ++    int bits_per_sample;
  1.1558 ++
  1.1559 ++    /*! Signal history for the QMF */
  1.1560 ++    int x[24];
  1.1561 ++
  1.1562 ++    struct
  1.1563 ++    {
  1.1564 ++        int s;
  1.1565 ++        int sp;
  1.1566 ++        int sz;
  1.1567 ++        int r[3];
  1.1568 ++        int a[3];
  1.1569 ++        int ap[3];
  1.1570 ++        int p[3];
  1.1571 ++        int d[7];
  1.1572 ++        int b[7];
  1.1573 ++        int bp[7];
  1.1574 ++        int sg[7];
  1.1575 ++        int nb;
  1.1576 ++        int det;
  1.1577 ++    } band[2];
  1.1578 ++    
  1.1579 ++    unsigned int in_buffer;
  1.1580 ++    int in_bits;
  1.1581 ++    unsigned int out_buffer;
  1.1582 ++    int out_bits;
  1.1583 ++} g722_decode_state_t;
  1.1584 ++
  1.1585 ++#ifdef __cplusplus
  1.1586 ++extern "C" {
  1.1587 ++#endif
  1.1588 ++
  1.1589 ++g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
  1.1590 ++int g722_encode_release(g722_encode_state_t *s);
  1.1591 ++int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
  1.1592 ++
  1.1593 ++g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
  1.1594 ++int g722_decode_release(g722_decode_state_t *s);
  1.1595 ++int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
  1.1596 ++
  1.1597 ++#ifdef __cplusplus
  1.1598 ++}
  1.1599 ++#endif
  1.1600 ++
  1.1601 ++#endif
  1.1602 +Index: codecs/g722/Makefile
  1.1603 +diff -Nau codecs/g722/Makefile.orig codecs/g722/Makefile
  1.1604 +--- codecs/g722/Makefile.orig	1970-01-01 01:00:00.000000000 +0100
  1.1605 ++++ codecs/g722/Makefile	2009-04-24 00:30:33.000000000 +0200
  1.1606 +@@ -0,0 +1,18 @@
  1.1607 ++LIB=libg722.a
  1.1608 ++CFLAGS+=-fPIC
  1.1609 ++
  1.1610 ++include $(ASTTOPDIR)/Makefile.rules
  1.1611 ++
  1.1612 ++OBJS=g722_encode.o g722_decode.o
  1.1613 ++
  1.1614 ++all: $(LIB)
  1.1615 ++
  1.1616 ++$(LIB): $(OBJS)
  1.1617 ++	$(ECHO_PREFIX) echo "   [AR] $^ -> $@"
  1.1618 ++	$(CMD_PREFIX) $(AR) cr $@ $^
  1.1619 ++	$(CMD_PREFIX) $(RANLIB) $@
  1.1620 ++
  1.1621 ++clean:
  1.1622 ++	rm -f $(LIB) *.o
  1.1623 ++	rm -f .*.o.d
  1.1624 ++	rm -f *.s *.i
  1.1625 +Index: codecs/g722_slin_ex.h
  1.1626 +diff -Nau codecs/g722_slin_ex.h.orig codecs/g722_slin_ex.h
  1.1627 +--- codecs/g722_slin_ex.h.orig	1970-01-01 01:00:00.000000000 +0100
  1.1628 ++++ codecs/g722_slin_ex.h	2009-04-24 00:30:33.000000000 +0200
  1.1629 +@@ -0,0 +1,25 @@
  1.1630 ++/*! \file
  1.1631 ++ * \brief g722_slin_ex.h --
  1.1632 ++ *
  1.1633 ++ *	4-bit ADPCM data, 20 milliseconds worth at 8 kHz.
  1.1634 ++ *
  1.1635 ++ * Source: g723.example
  1.1636 ++ *
  1.1637 ++ * Copyright (C) 2001-2005, Digium Inc.
  1.1638 ++ *
  1.1639 ++ * Distributed under the terms of the GNU General Public License
  1.1640 ++ *
  1.1641 ++ */
  1.1642 ++
  1.1643 ++static unsigned char g722_slin_ex[] = {
  1.1644 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1645 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1646 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1647 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1648 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1649 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1650 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1651 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1652 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1.1653 ++	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  1.1654 ++};
  1.1655 +Index: codecs/Makefile
  1.1656 +diff -Nau codecs/Makefile.orig codecs/Makefile
  1.1657 +--- codecs/Makefile.orig	2008-03-26 17:42:35.000000000 +0100
  1.1658 ++++ codecs/Makefile	2009-04-24 00:30:33.000000000 +0200
  1.1659 +@@ -31,6 +31,7 @@
  1.1660 + 
  1.1661 + LIBILBC:=ilbc/libilbc.a
  1.1662 + LIBLPC10:=lpc10/liblpc10.a
  1.1663 ++LIBG722:=g722/libg722.a
  1.1664 + 
  1.1665 + all: _all
  1.1666 + 
  1.1667 +@@ -45,6 +46,7 @@
  1.1668 + 	$(MAKE) -C gsm clean
  1.1669 + 	$(MAKE) -C lpc10 clean
  1.1670 + 	$(MAKE) -C ilbc clean
  1.1671 ++	$(MAKE) -C g722 clean
  1.1672 + 
  1.1673 + gsm/lib/libgsm.a:
  1.1674 + 	@mkdir -p gsm/lib
  1.1675 +@@ -59,3 +61,8 @@
  1.1676 + 	@$(MAKE) -C ilbc all ASTCFLAGS="$(filter-out -Wmissing-prototypes -Wmissing-declarations,$(ASTCFLAGS)) $(AST_NO_STRICT_OVERFLOW)"
  1.1677 + 
  1.1678 + $(if $(filter codec_ilbc,$(EMBEDDED_MODS)),modules.link,codec_ilbc.so): $(LIBILBC)
  1.1679 ++
  1.1680 ++$(LIBG722):
  1.1681 ++	@$(MAKE) -C g722 all
  1.1682 ++
  1.1683 ++$(if $(filter codec_g722,$(EMBEDDED_MODS)),modules.link,codec_g722.so): $(LIBG722)
  1.1684 +Index: codecs/slin_g722_ex.h
  1.1685 +diff -Nau codecs/slin_g722_ex.h.orig codecs/slin_g722_ex.h
  1.1686 +--- codecs/slin_g722_ex.h.orig	1970-01-01 01:00:00.000000000 +0100
  1.1687 ++++ codecs/slin_g722_ex.h	2009-04-24 00:30:33.000000000 +0200
  1.1688 +@@ -0,0 +1,25 @@
  1.1689 ++/*! \file
  1.1690 ++ * \brief slin_g722_ex.h --
  1.1691 ++ *
  1.1692 ++ *	Signed 16-bit audio data, 10 milliseconds worth at 8 kHz.
  1.1693 ++ *
  1.1694 ++ * Source: g723.example
  1.1695 ++ *
  1.1696 ++ * Copyright (C) 2001-2005, Digium Inc.
  1.1697 ++ *
  1.1698 ++ * Distributed under the terms of the GNU General Public License
  1.1699 ++ *
  1.1700 ++ */
  1.1701 ++
  1.1702 ++static signed short slin_g722_ex[] = {
  1.1703 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1704 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1705 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1706 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1707 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1708 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1709 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1710 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1711 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  1.1712 ++	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  1.1713 ++};
  1.1714 +Index: configure
  1.1715 +diff -Nau configure.orig configure
  1.1716 +--- configure.orig	2009-02-18 21:06:45.000000000 +0100
  1.1717 ++++ configure	2009-04-24 00:30:33.000000000 +0200
  1.1718 +@@ -11143,6 +11143,61 @@
  1.1719 + 
  1.1720 + fi
  1.1721 + 
  1.1722 ++{ echo "$as_me:$LINENO: checking for tm_gmtoff in struct tm" >&5
  1.1723 ++echo $ECHO_N "checking for tm_gmtoff in struct tm... $ECHO_C" >&6; }
  1.1724 ++if test "${ac_cv_struct_tm_gmtoff+set}" = set; then
  1.1725 ++  echo $ECHO_N "(cached) $ECHO_C" >&6
  1.1726 ++else
  1.1727 ++  cat >conftest.$ac_ext <<_ACEOF
  1.1728 ++/* confdefs.h.  */
  1.1729 ++_ACEOF
  1.1730 ++cat confdefs.h >>conftest.$ac_ext
  1.1731 ++cat >>conftest.$ac_ext <<_ACEOF
  1.1732 ++/* end confdefs.h.  */
  1.1733 ++$ac_includes_default
  1.1734 ++#include <sys/types.h>
  1.1735 ++#include <$ac_cv_struct_tm>
  1.1736 ++int main() {
  1.1737 ++struct tm tm; tm.tm_gmtoff;
  1.1738 ++; return 0; }
  1.1739 ++_ACEOF
  1.1740 ++rm -f conftest.$ac_objext
  1.1741 ++if { (ac_try="$ac_compile"
  1.1742 ++case "(($ac_try" in
  1.1743 ++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  1.1744 ++  *) ac_try_echo=$ac_try;;
  1.1745 ++esac
  1.1746 ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
  1.1747 ++  (eval "$ac_compile") 2>conftest.er1
  1.1748 ++  ac_status=$?
  1.1749 ++  grep -v '^ *+' conftest.er1 >conftest.err
  1.1750 ++  rm -f conftest.er1
  1.1751 ++  cat conftest.err >&5
  1.1752 ++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  1.1753 ++  (exit $ac_status); } && {
  1.1754 ++	 test -z "$ac_c_werror_flag" ||
  1.1755 ++	 test ! -s conftest.err
  1.1756 ++       } && test -s conftest.$ac_objext; then
  1.1757 ++  ac_cv_struct_tm_gmtoff=yes
  1.1758 ++else
  1.1759 ++  echo "$as_me: failed program was:" >&5
  1.1760 ++sed 's/^/| /' conftest.$ac_ext >&5
  1.1761 ++
  1.1762 ++	ac_cv_struct_tm_gmtoff=no
  1.1763 ++fi
  1.1764 ++
  1.1765 ++rm -f conftest*
  1.1766 ++fi
  1.1767 ++{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm_gmtoff" >&5
  1.1768 ++echo "${ECHO_T}$ac_cv_struct_tm_gmtoff" >&6; }
  1.1769 ++if test $ac_cv_struct_tm_gmtoff = yes; then
  1.1770 ++
  1.1771 ++cat >>confdefs.h <<\_ACEOF
  1.1772 ++#define TM_GMTOFF 1
  1.1773 ++_ACEOF
  1.1774 ++
  1.1775 ++fi
  1.1776 ++
  1.1777 + { echo "$as_me:$LINENO: checking for working volatile" >&5
  1.1778 + echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; }
  1.1779 + if test "${ac_cv_c_volatile+set}" = set; then
  1.1780 +Index: include/asterisk/config.h
  1.1781 +diff -Nau include/asterisk/config.h.orig include/asterisk/config.h
  1.1782 +--- include/asterisk/config.h.orig	2009-02-18 19:30:38.000000000 +0100
  1.1783 ++++ include/asterisk/config.h	2009-04-24 00:30:33.000000000 +0200
  1.1784 +@@ -33,6 +33,8 @@
  1.1785 + 
  1.1786 + struct ast_category;
  1.1787 + 
  1.1788 ++#define	CONFIG_STATUS_FILEUNCHANGED	(void *)-1
  1.1789 ++
  1.1790 + struct ast_variable {
  1.1791 + 	char *name;
  1.1792 + 	char *value;
  1.1793 +Index: include/asterisk/frame.h
  1.1794 +diff -Nau include/asterisk/frame.h.orig include/asterisk/frame.h
  1.1795 +--- include/asterisk/frame.h.orig	2009-03-05 19:22:16.000000000 +0100
  1.1796 ++++ include/asterisk/frame.h	2009-04-24 00:30:33.000000000 +0200
  1.1797 +@@ -260,6 +260,8 @@
  1.1798 + #define AST_FORMAT_G726		(1 << 11)
  1.1799 + /*! G.722 */
  1.1800 + #define AST_FORMAT_G722		(1 << 12)
  1.1801 ++/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
  1.1802 ++#define AST_FORMAT_SLINEAR16   (1 << 15)
  1.1803 + /*! Unsupported audio bits */
  1.1804 + #define AST_FORMAT_AUDIO_UNDEFINED	((1 << 13) | (1 << 14) | (1 << 15))
  1.1805 + /*! Maximum audio format */
  1.1806 +Index: main/editline/np/vis.h
  1.1807 +diff -Nau main/editline/np/vis.h.orig main/editline/np/vis.h
  1.1808 +--- main/editline/np/vis.h.orig	2006-08-21 04:11:39.000000000 +0200
  1.1809 ++++ main/editline/np/vis.h	2009-04-24 00:30:33.000000000 +0200
  1.1810 +@@ -76,6 +76,22 @@
  1.1811 + 
  1.1812 + #include <sys/cdefs.h>
  1.1813 + 
  1.1814 ++/* correct nonportable unsigned type usage */
  1.1815 ++#if !defined(__FreeBSD__) && !defined(__linux__)
  1.1816 ++#ifndef u_int64_t
  1.1817 ++#define u_int64_t unsigned long long
  1.1818 ++#endif
  1.1819 ++#ifndef u_int32_t
  1.1820 ++#define u_int32_t unsigned int
  1.1821 ++#endif
  1.1822 ++#ifndef u_int16_t
  1.1823 ++#define u_int16_t unsigned short
  1.1824 ++#endif
  1.1825 ++#ifndef u_int6_t
  1.1826 ++#define u_int8_t unsigned char
  1.1827 ++#endif
  1.1828 ++#endif
  1.1829 ++
  1.1830 + __BEGIN_DECLS
  1.1831 + char	*vis __P((char *, int, int, int));
  1.1832 + char	*svis __P((char *, int, int, int, const char *));
  1.1833 +Index: main/stdtime/localtime.c
  1.1834 +diff -Nau main/stdtime/localtime.c.orig main/stdtime/localtime.c
  1.1835 +--- main/stdtime/localtime.c.orig	2008-09-27 17:00:48.000000000 +0200
  1.1836 ++++ main/stdtime/localtime.c	2009-04-24 00:30:33.000000000 +0200
  1.1837 +@@ -1134,9 +1134,9 @@
  1.1838 + 	*/
  1.1839 + 	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
  1.1840 + 	tmp->tm_isdst = ttisp->tt_isdst;
  1.1841 +-#ifndef SOLARIS /* Solaris doesn't have this element */
  1.1842 ++#ifdef TM_GMTOFF
  1.1843 + 	tmp->tm_gmtoff = ttisp->tt_gmtoff;
  1.1844 +-#endif
  1.1845 ++#endif /* defined TM_GMTOFF */
  1.1846 + #ifdef TM_ZONE
  1.1847 + 	tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
  1.1848 + #endif /* defined TM_ZONE */
  1.1849 +Index: Makefile.moddir_rules
  1.1850 +diff -Nau Makefile.moddir_rules.orig Makefile.moddir_rules
  1.1851 +--- Makefile.moddir_rules.orig	2008-11-26 19:36:24.000000000 +0100
  1.1852 ++++ Makefile.moddir_rules	2009-04-24 00:30:33.000000000 +0200
  1.1853 +@@ -69,7 +69,9 @@
  1.1854 + 	rm -f modules.link
  1.1855 + 
  1.1856 + install:: all
  1.1857 ++ifneq ($(LOADABLE_MODS),)
  1.1858 + 	for x in $(LOADABLE_MODS:%=%.so); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
  1.1859 ++endif
  1.1860 + 
  1.1861 + uninstall::
  1.1862 + 
  1.1863 +Index: res/res_features.c
  1.1864 +diff -Nau res/res_features.c.orig res/res_features.c
  1.1865 +--- res/res_features.c.orig	2009-03-03 19:27:09.000000000 +0100
  1.1866 ++++ res/res_features.c	2009-04-24 00:30:33.000000000 +0200
  1.1867 +@@ -732,6 +732,10 @@
  1.1868 + 			snprintf(args, len, "%s|%s|m", S_OR(touch_format, "wav"), touch_filename);
  1.1869 + 		}
  1.1870 + 
  1.1871 ++		for( x = 0; x < strlen(touch_filename); x++) {
  1.1872 ++			if (touch_filename[x] == '/')
  1.1873 ++				touch_filename[x] = '-';
  1.1874 ++		}
  1.1875 + 		for( x = 0; x < strlen(args); x++) {
  1.1876 + 			if (args[x] == '/')
  1.1877 + 				args[x] = '-';
  1.1878 +@@ -2774,6 +2778,293 @@
  1.1879 + 	}
  1.1880 + }
  1.1881 + 
  1.1882 ++static char mandescr_bridge[] =
  1.1883 ++"Description: Bridge together two channels already in the PBX\n"
  1.1884 ++"Variables: ( Headers marked with * are required )\n"
  1.1885 ++"   *Channel1: Channel to Bridge to Channel2\n"
  1.1886 ++"   *Channel2: Channel to Bridge to Channel1\n"
  1.1887 ++"        Tone: (Yes|No) Play courtesy tone to Channel 2\n"
  1.1888 ++"\n";
  1.1889 ++
  1.1890 ++/*!
  1.1891 ++ * \brief Actual bridge
  1.1892 ++ * \param chan
  1.1893 ++ * \param tmpchan
  1.1894 ++ * 
  1.1895 ++ * Stop hold music, lock both channels, masq channels,
  1.1896 ++ * after bridge return channel to next priority.
  1.1897 ++*/
  1.1898 ++static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
  1.1899 ++{
  1.1900 ++	ast_moh_stop(chan);
  1.1901 ++	ast_channel_lock(chan);
  1.1902 ++	ast_setstate(tmpchan, chan->_state);
  1.1903 ++	tmpchan->readformat = chan->readformat;
  1.1904 ++	tmpchan->writeformat = chan->writeformat;
  1.1905 ++	ast_channel_masquerade(tmpchan, chan);
  1.1906 ++	ast_channel_lock(tmpchan);
  1.1907 ++	ast_do_masquerade(tmpchan);
  1.1908 ++	/* when returning from bridge, the channel will continue at the next priority */
  1.1909 ++	ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
  1.1910 ++	ast_channel_unlock(tmpchan);
  1.1911 ++	ast_channel_unlock(chan);
  1.1912 ++}
  1.1913 ++
  1.1914 ++/*!
  1.1915 ++ * \brief Bridge channels together
  1.1916 ++ * \param s
  1.1917 ++ * \param m
  1.1918 ++ * 
  1.1919 ++ * Make sure valid channels were specified, 
  1.1920 ++ * send errors if any of the channels could not be found/locked, answer channels if needed,
  1.1921 ++ * create the placeholder channels and grab the other channels 
  1.1922 ++ * make the channels compatible, send error if we fail doing so 
  1.1923 ++ * setup the bridge thread object and start the bridge.
  1.1924 ++ * 
  1.1925 ++ * \retval 0 on success or on incorrect use.
  1.1926 ++ * \retval 1 on failure to bridge channels.
  1.1927 ++*/
  1.1928 ++static int action_bridge(struct mansession *s, const struct message *m)
  1.1929 ++{
  1.1930 ++	const char *channela = astman_get_header(m, "Channel1");
  1.1931 ++	const char *channelb = astman_get_header(m, "Channel2");
  1.1932 ++	const char *playtone = astman_get_header(m, "Tone");
  1.1933 ++	struct ast_channel *chana = NULL, *chanb = NULL;
  1.1934 ++	struct ast_channel *tmpchana = NULL, *tmpchanb = NULL;
  1.1935 ++	struct ast_bridge_thread_obj *tobj = NULL;
  1.1936 ++
  1.1937 ++	/* make sure valid channels were specified */
  1.1938 ++	if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) {
  1.1939 ++		chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela));
  1.1940 ++		chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb));
  1.1941 ++		if (chana)
  1.1942 ++			ast_channel_unlock(chana);
  1.1943 ++		if (chanb)
  1.1944 ++			ast_channel_unlock(chanb);
  1.1945 ++
  1.1946 ++		/* send errors if any of the channels could not be found/locked */
  1.1947 ++		if (!chana) {
  1.1948 ++			char buf[256];
  1.1949 ++			snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela);
  1.1950 ++			astman_send_error(s, m, buf);
  1.1951 ++			return 0;
  1.1952 ++		}
  1.1953 ++		if (!chanb) {
  1.1954 ++			char buf[256];
  1.1955 ++			snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb);
  1.1956 ++			astman_send_error(s, m, buf);
  1.1957 ++			return 0;
  1.1958 ++		}
  1.1959 ++	} else {
  1.1960 ++		astman_send_error(s, m, "Missing channel parameter in request");
  1.1961 ++		return 0;
  1.1962 ++	}
  1.1963 ++
  1.1964 ++	/* Answer the channels if needed */
  1.1965 ++	if (chana->_state != AST_STATE_UP)
  1.1966 ++		ast_answer(chana);
  1.1967 ++	if (chanb->_state != AST_STATE_UP)
  1.1968 ++		ast_answer(chanb);
  1.1969 ++
  1.1970 ++	/* create the placeholder channels and grab the other channels */
  1.1971 ++	if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
  1.1972 ++		NULL, NULL, 0, "Bridge/%s", chana->name))) {
  1.1973 ++		astman_send_error(s, m, "Unable to create temporary channel!");
  1.1974 ++		return 1;
  1.1975 ++	}
  1.1976 ++
  1.1977 ++	if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
  1.1978 ++		NULL, NULL, 0, "Bridge/%s", chanb->name))) {
  1.1979 ++		astman_send_error(s, m, "Unable to create temporary channels!");
  1.1980 ++		ast_channel_free(tmpchana);
  1.1981 ++		return 1;
  1.1982 ++	}
  1.1983 ++
  1.1984 ++	do_bridge_masquerade(chana, tmpchana);
  1.1985 ++	do_bridge_masquerade(chanb, tmpchanb);
  1.1986 ++	
  1.1987 ++	/* make the channels compatible, send error if we fail doing so */
  1.1988 ++	if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
  1.1989 ++		ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name);
  1.1990 ++		astman_send_error(s, m, "Could not make channels compatible for manager bridge");
  1.1991 ++		ast_hangup(tmpchana);
  1.1992 ++		ast_hangup(tmpchanb);
  1.1993 ++		return 1;
  1.1994 ++	}
  1.1995 ++
  1.1996 ++	/* setup the bridge thread object and start the bridge */
  1.1997 ++	if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
  1.1998 ++		ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno));
  1.1999 ++		astman_send_error(s, m, "Unable to spawn a new bridge thread");
  1.2000 ++		ast_hangup(tmpchana);
  1.2001 ++		ast_hangup(tmpchanb);
  1.2002 ++		return 1;
  1.2003 ++	}
  1.2004 ++
  1.2005 ++	tobj->chan = tmpchana;
  1.2006 ++	tobj->peer = tmpchanb;
  1.2007 ++	
  1.2008 ++	if (ast_true(playtone)) {
  1.2009 ++		if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) {
  1.2010 ++			if (ast_waitstream(tmpchanb, "") < 0)
  1.2011 ++				ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name);
  1.2012 ++		}
  1.2013 ++	}
  1.2014 ++
  1.2015 ++	ast_bridge_call_thread_launch(tobj);
  1.2016 ++
  1.2017 ++	astman_send_ack(s, m, "Launched bridge thread with success");
  1.2018 ++
  1.2019 ++	return 0;
  1.2020 ++}
  1.2021 ++
  1.2022 ++static char *app_bridge = "Bridge";
  1.2023 ++static char *bridge_synopsis = "Bridge two channels";
  1.2024 ++static char *bridge_descrip =
  1.2025 ++"Usage: Bridge(channel[,options])\n"
  1.2026 ++"	Allows the ability to bridge two channels via the dialplan.\n"
  1.2027 ++"The current channel is bridged to the specified 'channel'.\n"
  1.2028 ++"  Options:\n"
  1.2029 ++"    p - Play a courtesy tone to 'channel'.\n"
  1.2030 ++"This application sets the following channel variable upon completion:\n"
  1.2031 ++" BRIDGERESULT    The result of the bridge attempt as a text string, one of\n"
  1.2032 ++"           SUCCESS | FAILURE | LOOP | NONEXISTENT | INCOMPATIBLE\n";
  1.2033 ++
  1.2034 ++enum {
  1.2035 ++	BRIDGE_OPT_PLAYTONE = (1 << 0),
  1.2036 ++};
  1.2037 ++
  1.2038 ++AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
  1.2039 ++	AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE)
  1.2040 ++END_OPTIONS );
  1.2041 ++
  1.2042 ++/*!
  1.2043 ++ * \brief Bridge channels
  1.2044 ++ * \param chan
  1.2045 ++ * \param data channel to bridge with.
  1.2046 ++ * 
  1.2047 ++ * Split data, check we aren't bridging with ourself, check valid channel,
  1.2048 ++ * answer call if not already, check compatible channels, setup bridge config
  1.2049 ++ * now bridge call, if transfered party hangs up return to PBX extension.
  1.2050 ++*/
  1.2051 ++static int bridge_exec(struct ast_channel *chan, void *data)
  1.2052 ++{
  1.2053 ++	struct ast_channel *current_dest_chan, *final_dest_chan;
  1.2054 ++	char *tmp_data  = NULL;
  1.2055 ++	struct ast_flags opts = { 0, };
  1.2056 ++	struct ast_bridge_config bconfig = { { 0, }, };
  1.2057 ++
  1.2058 ++	AST_DECLARE_APP_ARGS(args,
  1.2059 ++		AST_APP_ARG(dest_chan);
  1.2060 ++		AST_APP_ARG(options);
  1.2061 ++	);
  1.2062 ++	
  1.2063 ++	if (ast_strlen_zero(data)) {
  1.2064 ++		ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n");
  1.2065 ++		return -1;
  1.2066 ++	}
  1.2067 ++
  1.2068 ++	tmp_data = ast_strdupa(data);
  1.2069 ++	AST_STANDARD_APP_ARGS(args, tmp_data);
  1.2070 ++	if (!ast_strlen_zero(args.options))
  1.2071 ++		ast_app_parse_options(bridge_exec_options, &opts, NULL, args.options);
  1.2072 ++
  1.2073 ++	/* avoid bridge with ourselves */
  1.2074 ++	if (!strncmp(chan->name, args.dest_chan, 
  1.2075 ++		strlen(chan->name) < strlen(args.dest_chan) ? 
  1.2076 ++		strlen(chan->name) : strlen(args.dest_chan))) {
  1.2077 ++		ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name);
  1.2078 ++		manager_event(EVENT_FLAG_CALL, "BridgeExec",
  1.2079 ++					"Response: Failed\r\n"
  1.2080 ++					"Reason: Unable to bridge channel to itself\r\n"
  1.2081 ++					"Channel1: %s\r\n"
  1.2082 ++					"Channel2: %s\r\n",
  1.2083 ++					chan->name, args.dest_chan);
  1.2084 ++		pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
  1.2085 ++		return 0;
  1.2086 ++	}
  1.2087 ++
  1.2088 ++	/* make sure we have a valid end point */
  1.2089 ++	if (!(current_dest_chan = ast_get_channel_by_name_prefix_locked(args.dest_chan, 
  1.2090 ++		strlen(args.dest_chan)))) {
  1.2091 ++		ast_log(LOG_WARNING, "Bridge failed because channel %s does not exist or we "
  1.2092 ++			"cannot get its lock\n", args.dest_chan);
  1.2093 ++		manager_event(EVENT_FLAG_CALL, "BridgeExec",
  1.2094 ++					"Response: Failed\r\n"
  1.2095 ++					"Reason: Cannot grab end point\r\n"
  1.2096 ++					"Channel1: %s\r\n"
  1.2097 ++					"Channel2: %s\r\n", chan->name, args.dest_chan);
  1.2098 ++		pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
  1.2099 ++		return 0;
  1.2100 ++	}
  1.2101 ++	ast_channel_unlock(current_dest_chan);
  1.2102 ++
  1.2103 ++	/* answer the channel if needed */
  1.2104 ++	if (current_dest_chan->_state != AST_STATE_UP)
  1.2105 ++		ast_answer(current_dest_chan);
  1.2106 ++
  1.2107 ++	/* try to allocate a place holder where current_dest_chan will be placed */
  1.2108 ++	if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 
  1.2109 ++		NULL, NULL, 0, "Bridge/%s", current_dest_chan->name))) {
  1.2110 ++		ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan);
  1.2111 ++		manager_event(EVENT_FLAG_CALL, "BridgeExec",
  1.2112 ++					"Response: Failed\r\n"
  1.2113 ++					"Reason: cannot create placeholder\r\n"
  1.2114 ++					"Channel1: %s\r\n"
  1.2115 ++					"Channel2: %s\r\n", chan->name, args.dest_chan);
  1.2116 ++	}
  1.2117 ++	do_bridge_masquerade(current_dest_chan, final_dest_chan);
  1.2118 ++
  1.2119 ++	/* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */
  1.2120 ++	/* try to make compatible, send error if we fail */
  1.2121 ++	if (ast_channel_make_compatible(chan, final_dest_chan) < 0) {
  1.2122 ++		ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name);
  1.2123 ++		manager_event(EVENT_FLAG_CALL, "BridgeExec",
  1.2124 ++					"Response: Failed\r\n"
  1.2125 ++					"Reason: Could not make channels compatible for bridge\r\n"
  1.2126 ++					"Channel1: %s\r\n"
  1.2127 ++					"Channel2: %s\r\n", chan->name, final_dest_chan->name);
  1.2128 ++		ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */
  1.2129 ++		pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE");
  1.2130 ++		return 0;
  1.2131 ++	}
  1.2132 ++
  1.2133 ++	/* Report that the bridge will be successfull */
  1.2134 ++	manager_event(EVENT_FLAG_CALL, "BridgeExec",
  1.2135 ++				"Response: Success\r\n"
  1.2136 ++				"Channel1: %s\r\n"
  1.2137 ++				"Channel2: %s\r\n", chan->name, final_dest_chan->name);
  1.2138 ++
  1.2139 ++	/* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */	
  1.2140 ++	if (ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE) && !ast_strlen_zero(xfersound)) {
  1.2141 ++		if (!ast_streamfile(final_dest_chan, xfersound, final_dest_chan->language)) {
  1.2142 ++			if (ast_waitstream(final_dest_chan, "") < 0)
  1.2143 ++				ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name);
  1.2144 ++		}
  1.2145 ++	}
  1.2146 ++	
  1.2147 ++	/* do the bridge */
  1.2148 ++	ast_bridge_call(chan, final_dest_chan, &bconfig);
  1.2149 ++
  1.2150 ++	/* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */
  1.2151 ++	pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
  1.2152 ++	if (!ast_check_hangup(final_dest_chan)) {
  1.2153 ++		ast_log(LOG_EVENT, "starting new PBX in %s,%s,%d for chan %s\n", 
  1.2154 ++			final_dest_chan->context, final_dest_chan->exten, 
  1.2155 ++			final_dest_chan->priority, final_dest_chan->name);
  1.2156 ++
  1.2157 ++		if (ast_pbx_start(final_dest_chan) != AST_PBX_SUCCESS) {
  1.2158 ++			ast_log(LOG_WARNING, "FAILED continuing PBX on dest chan %s\n", final_dest_chan->name);
  1.2159 ++			ast_hangup(final_dest_chan);
  1.2160 ++		} else
  1.2161 ++			ast_log(LOG_EVENT, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name);
  1.2162 ++	} else {
  1.2163 ++		ast_log(LOG_EVENT, "hangup chan %s since the other endpoint has hung up\n", final_dest_chan->name);
  1.2164 ++		ast_hangup(final_dest_chan);
  1.2165 ++	}
  1.2166 ++
  1.2167 ++	return 0;
  1.2168 ++}
  1.2169 + 
  1.2170 + static int load_config(void) 
  1.2171 + {
  1.2172 +@@ -3034,6 +3325,8 @@
  1.2173 + {
  1.2174 + 	int res;
  1.2175 + 	
  1.2176 ++	ast_register_application(app_bridge, bridge_exec, bridge_synopsis, bridge_descrip);
  1.2177 ++
  1.2178 + 	memset(parking_ext, 0, sizeof(parking_ext));
  1.2179 + 	memset(parking_con, 0, sizeof(parking_con));
  1.2180 + 
  1.2181 +@@ -3048,6 +3341,7 @@
  1.2182 + 		ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
  1.2183 + 		ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
  1.2184 + 			"Park a channel", mandescr_park); 
  1.2185 ++		ast_manager_register2("Bridge", EVENT_FLAG_CALL, action_bridge, "Bridge two channels already in the PBX", mandescr_bridge);
  1.2186 + 	}
  1.2187 + 
  1.2188 + 	res |= ast_devstate_prov_add("Park", metermaidstate);
  1.2189 +Index: apps/app_voicemail.c
  1.2190 +diff -Nau apps/app_voicemail.c.orig apps/app_voicemail.c
  1.2191 +--- apps/app_voicemail.c.orig	2009-04-25 02:38:20.343758775 +0200
  1.2192 ++++ apps/app_voicemail.c	2009-04-25 19:56:25.287569363 +0200
  1.2193 +@@ -115,6 +115,7 @@
  1.2194 + static char imapport[8];
  1.2195 + static char imapflags[128];
  1.2196 + static char imapfolder[64];
  1.2197 ++static int  imapsubfold = 0;
  1.2198 + static char authuser[32];
  1.2199 + static char authpassword[42];
  1.2200 + 
  1.2201 +@@ -4313,6 +4314,7 @@
  1.2202 + 	/* we must use mbox(x) folder names, and copy the message there */
  1.2203 + 	/* simple. huh? */
  1.2204 + 	char sequence[10];
  1.2205 ++	char folder[256];
  1.2206 + 	/* get the real IMAP message number for this message */
  1.2207 + 	snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
  1.2208 + 	if (option_debug > 2)
  1.2209 +@@ -4323,11 +4325,21 @@
  1.2210 + 	} else if (box == 0) {
  1.2211 + 		mail_clearflag(vms->mailstream, sequence, "\\Seen");
  1.2212 + 	}
  1.2213 +-	if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) {
  1.2214 ++	if ((!strcasecmp(mbox(0), vms->curbox) || \
  1.2215 ++        !strcasecmp(mbox(1), vms->curbox)) && \
  1.2216 ++        (box == 0 || box == 1)) {  /* Don't copy data, just change Seen flag */
  1.2217 + 		ast_mutex_unlock(&vms->lock);
  1.2218 + 		return 0;
  1.2219 +-	} else {
  1.2220 +-		int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box)); 
  1.2221 ++	} else if (box > 1) {          /* Do copy data using INBOX or subfolder */
  1.2222 ++		if (imapsubfold == 1)
  1.2223 ++			snprintf(folder, sizeof(folder), "%s%c%s", imapfolder, delimiter, mbox(box));
  1.2224 ++		else
  1.2225 ++			strncpy(folder, mbox(box), sizeof(folder));
  1.2226 ++		int res = !mail_copy(vms->mailstream,sequence,folder);
  1.2227 ++		ast_mutex_unlock(&vms->lock);
  1.2228 ++		return res;
  1.2229 ++	} else {  /* Copy data to INBOX delegating new/old status to Seen flag */
  1.2230 ++		int res = !mail_copy(vms->mailstream,sequence,imapfolder);
  1.2231 + 		ast_mutex_unlock(&vms->lock);
  1.2232 + 		return res;
  1.2233 + 	}
  1.2234 +@@ -7686,6 +7698,10 @@
  1.2235 + #ifndef IMAP_STORAGE
  1.2236 + 				} else if (!cmd) {
  1.2237 + 					vms.deleted[vms.curmsg] = 1;
  1.2238 ++#else
  1.2239 ++				} else if (!cmd && (folder_int(vms.curbox) > 1  || box > 1)) {
  1.2240 ++					vms.deleted[vms.curmsg] = 1;  /* Enforce deletion after */
  1.2241 ++					deleted = 1;                  /* successful copy op */
  1.2242 + #endif
  1.2243 + 				} else {
  1.2244 + 					vms.deleted[vms.curmsg] = 0;
  1.2245 +@@ -8198,6 +8214,7 @@
  1.2246 + 	const char *imap_port;
  1.2247 + 	const char *imap_flags;
  1.2248 + 	const char *imap_folder;
  1.2249 ++	const char *imap_use_subfold;
  1.2250 + 	const char *auth_user;
  1.2251 + 	const char *auth_password;
  1.2252 + 	const char *expunge_on_hangup;
  1.2253 +@@ -8342,6 +8359,15 @@
  1.2254 + 		} else {
  1.2255 + 			ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
  1.2256 + 		}
  1.2257 ++		/* IMAP saved (sub)folder location policy */
  1.2258 ++		if ((imap_use_subfold = ast_variable_retrieve(cfg, "general", "imapsubfold"))) {
  1.2259 ++			if (ast_false(imap_use_subfold))
  1.2260 ++				imapsubfold = 0;
  1.2261 ++			else
  1.2262 ++				imapsubfold = 1;
  1.2263 ++		} else {
  1.2264 ++			imapsubfold = 0;
  1.2265 ++		}
  1.2266 + 
  1.2267 + 		/* There is some very unorthodox casting done here. This is due
  1.2268 + 		 * to the way c-client handles the argument passed in. It expects a 

mercurial