dect
/
asterisk
Archived
13
0
Fork 0

Version 0.1.9 from FTP

git-svn-id: http://svn.digium.com/svn/asterisk/trunk@353 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
markster 2001-08-23 17:57:10 +00:00
parent 1128564a80
commit a64eaf9e1c
9 changed files with 440 additions and 28 deletions

View File

@ -6,6 +6,13 @@ and TSU 120e to the project. (http://www.adtran.com)
* Thanks to QuickNet Technologies for their donation of an Internet
PhoneJack card to the project. (http://www.quicknet.net)
=== DEVELOPMENT SUPPORT ===
I'd like to thank the following companies for helping fund development of
Asterisk:
* Celera Networks - US Digital
* Adtran, Inc.
=== OTHER SOURCE CODE IN ASTERISK ===
I did not implement the codecs in asterisk. Here is the copyright on the

26
README
View File

@ -1,7 +1,11 @@
The Asterisk Open Source PBX
by Mark Spencer <markster@linux-support.net>
Copyright (C) 1999, Mark Spencer
Copyright (C) 2001, Linux Support Services, Inc.
================================================================
* SECURITY
It is imperative that you read and fully understand the contents of
the SECURITY file before you attempt to configure an Asterisk server.
* WHAT IS ASTERISK
Asterisk is an Open Source PBX and telephony toolkit. It is, in a
sense, middleware between Internet and telephony channels on the bottom,
@ -10,7 +14,27 @@ on the project itself, please visit the Asterisk home page at:
http://www.asteriskpbx.com
* LICENSING
Asterisk is distributed under GNU General Public License. The GPL also
must apply to all loadable modules as well, except as defined below.
Linux Support Services, Inc. retains copyright to all of the core
Asterisk system, and therefore can grant, at its sole discression, the
ability for companies, individuals, or organizations to create proprietary
or Open Source (but non-GPL'd) modules which may be dynamically linked at
runtime with the portions of Asterisk which fall under our copyright
umbrella, or are distributed under more flexible licenses than GPL. At
this time (5/21/2001) the only component of Asterisk which is covered
under GPL and not under our Copyright is the Xing MP3 decoder.
If you wish to use our code in other GPL programs, don't worry -- there
is no requirement that you provide the same exemption in your GPL'd
products (although if you've written a module for Asterisk we would
strongly encourage you to make the same excemption that we do).
If you have any questions, whatsoever, regarding our licensing policy,
please contact us.
* REQUIRED COMPONENTS
== Linux ==

38
SECURITY Executable file
View File

@ -0,0 +1,38 @@
==== Security Notes with Asterisk ====
PLEASE READ THE FOLLOWING IMPORTANT SECURITY RELATED INFORMATION.
IMPROPER CONFIGURATION OF ASTERISK COULD ALLOW UNAUTHORIZED USE OF YOUR
FACILITIES, POTENTIALLY INCURRING SUBSTANTIAL CHARGES.
First and foremost remember this:
USE THE EXTENSION CONTEXTS TO ISOLATE OUTGOING OR TOLL SERVICES FROM ANY
INCOMING CONNECTIONS.
You should consider that if any channel, incoming line, etc can enter an
extension context that it has the capability of accessing any extension
within that context.
Therefore, you should NOT allow access to outgoing or toll services in
contexts that are accessible (especially without a password) from incoming
channels, be they IAX channels, FX or other trunks, or even untrusted
stations within you network. In particular, never ever put outgoing toll
services in the "default" context. To make things easier, you can include
the "default" context within other private contexts by using:
include => default
in the appropriate section. A well designed PBX might look like this:
[longdistance]
exten => _91NXXNXXXXXX,1,Dial,Tor/g2/BYEXTENSION
include => local
[local]
exten => _9NXXNXXX,1,Dial,Tor/g2/BYEXTENSION
include => default
[default]
exten => 6123,Dial,Tor/1

89
apps/app_image.c Executable file
View File

@ -0,0 +1,89 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to transmit an image
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
static char *tdesc = "Image Transmission Application";
static char *app = "SendImage";
static char *synopsis = "Send an image file";
static char *descrip =
" SendImage(filename): Sends an image on a channel. If the channel\n"
"does not support image transport, and there exists a step with\n"
"priority n + 101, then execution will continue at that step.\n"
"Otherwise, execution will continue at the next priority level.\n"
"SendImage only returns 0 if the image was sent correctly or if\n"
"the channel does not support image transport, and -1 otherwise.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int sendimage_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "SendImage requires an argument (filename)\n");
return -1;
}
LOCAL_USER_ADD(u);
if (!ast_supports_images(chan)) {
/* Does not support transport */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
return 0;
}
res = ast_send_image(chan, data);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, sendimage_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@ -31,10 +31,11 @@ static char *app = "System";
static char *synopsis = "Execute a system command";
static char *descrip =
" System(command): Executes a command by using system(). Returns -1 on failure to execute\n"
" the specified command. If the command itself executes but is in error, and if there exists\n"
" a priority n + 101, where 'n' is the priority of the current instance, then the channel will\n"
" will be setup to continue at that priority level. Otherwise, System returns 0.\n";
" System(command): Executes a command by using system(). Returns -1 on\n"
"failure to execute the specified command. If the command itself executes\n"
"but is in error, and if there exists a priority n + 101, where 'n' is the\n"
"priority of the current instance, then the channel will be setup to\n"
"continue at that priority level. Otherwise, System returns 0.\n";
STANDARD_LOCAL_USER;
@ -58,7 +59,7 @@ static int skel_exec(struct ast_channel *chan, void *data)
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
res = -1;
} else {
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101))
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority+=100;
res = 0;
}

137
apps/app_url.c Executable file
View File

@ -0,0 +1,137 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to transmit a URL
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
static char *tdesc = "Send URL Applications";
static char *app = "SendURL";
static char *synopsis = "Send a URL";
static char *descrip =
" SendURL(URL[|option]): Requests client go to URL. If the client\n"
"does not support html transport, and there exists a step with\n"
"priority n + 101, then execution will continue at that step.\n"
"Otherwise, execution will continue at the next priority level.\n"
"SendURL only returns 0 if the URL was sent correctly or if\n"
"the channel does not support HTML transport, and -1 otherwise.\n"
"If the option 'wait' is specified, execution will wait for an\n"
"acknowledgement that the URL has been loaded before continuing\n"
"and will return -1 if the peer is unable to load the URL\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int sendurl_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
char tmp[256];
char *options;
int option_wait=0;
struct ast_frame *f;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "SendURL requires an argument (URL)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp));
strtok(tmp, "|");
options = strtok(NULL, "|");
if (options && !strcasecmp(options, "wait"))
option_wait = 1;
LOCAL_USER_ADD(u);
if (!ast_channel_supports_html(chan)) {
/* Does not support transport */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
LOCAL_USER_REMOVE(u);
return 0;
}
res = ast_channel_sendurl(chan, tmp);
if (res > -1) {
if (option_wait) {
for(;;) {
/* Wait for an event */
res = ast_waitfor(chan, -1);
if (res < 0)
break;
f = ast_read(chan);
if (!f) {
res = -1;
break;
}
if (f->frametype == AST_FRAME_HTML) {
switch(f->subclass) {
case AST_HTML_LDCOMPLETE:
res = 0;
ast_frfree(f);
goto out;
break;
case AST_HTML_NOSUPPORT:
/* Does not support transport */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
res = 0;
goto out;
break;
default:
ast_log(LOG_WARNING, "Don't know what to do with HTML subclass %d\n", f->subclass);
};
}
ast_frfree(f);
}
}
}
out:
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, sendurl_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@ -62,7 +62,7 @@ struct callerid_state *callerid_new(void)
{
struct callerid_state *cid;
cid = malloc(sizeof(struct callerid_state));
memset(cid, 0, sizeof(*cid));
memset(cid, 0, sizeof(struct callerid_state));
if (cid) {
cid->fskd.spb = 7; /* 1200 baud */
cid->fskd.hdlc = 0; /* Async */
@ -146,6 +146,10 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len)
while(mylen >= 80) {
olen = mylen;
res = fsk_serie(&cid->fskd, buf, &mylen, &b);
if (mylen < 0) {
ast_log(LOG_ERROR, "fsk_serie made mylen < 0 (%d)\n", mylen);
return -1;
}
buf += (olen - mylen);
if (res < 0) {
ast_log(LOG_NOTICE, "fsk_serie failed\n");
@ -263,7 +267,8 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len)
if (mylen) {
memcpy(cid->oldstuff, buf, mylen * 2);
cid->oldlen = mylen * 2;
}
} else
cid->oldlen = 0;
free(obuf);
return 0;
}
@ -444,7 +449,7 @@ void ast_shrink_phone_number(char *n)
int ast_isphonenumber(char *n)
{
int x;
if (!n)
if (!n || !strlen(n))
return 0;
for (x=0;n[x];x++)
if (!strchr("0123456789", n[x]))
@ -483,7 +488,7 @@ int ast_callerid_parse(char *instr, char **name, char **location)
} else {
strncpy(tmp, instr, sizeof(tmp));
ast_shrink_phone_number(tmp);
if (!ast_isphonenumber(tmp)) {
if (ast_isphonenumber(tmp)) {
/* Assume it's just a location */
*name = NULL;
*location = instr;

View File

@ -56,6 +56,7 @@ static struct timeval lasttime;
static int usecnt;
static int needanswer = 0;
static int needringing = 0;
static int needhangup = 0;
static int silencesuppression = 0;
static int silencethreshold = 1000;
@ -438,6 +439,7 @@ static int oss_call(struct ast_channel *c, char *dest, int timeout)
needanswer = 1;
} else {
ast_verbose( " << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
needringing = 1;
write(sndcmd[1], &res, sizeof(res));
}
return 0;
@ -591,7 +593,15 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
f.src = type;
f.mallocd = 0;
if (needringing) {
f.frametype = AST_FRAME_CONTROL;
f.subclass = AST_CONTROL_RINGING;
needringing = 0;
return &f;
}
if (needhangup) {
needhangup = 0;
return NULL;
}
if (strlen(text2send)) {
@ -632,8 +642,10 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
}
res = read(sounddev, buf + AST_FRIENDLY_OFFSET + readpos, FRAME_SIZE * 2 - readpos);
if (res < 0) {
ast_log(LOG_WARNING, "Error reading from sound device: %s\n", strerror(errno));
ast_log(LOG_WARNING, "Error reading from sound device (If you're running 'artsd' then kill it): %s\n", strerror(errno));
#if 0
CRASH;
#endif
return NULL;
}
readpos += res;
@ -641,6 +653,10 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
if (readpos >= FRAME_SIZE * 2) {
/* A real frame */
readpos = 0;
if (chan->state != AST_STATE_UP) {
/* Don't transmit unless it's up */
return &f;
}
f.frametype = AST_FRAME_VOICE;
f.subclass = AST_FORMAT_SLINEAR;
f.timelen = FRAME_SIZE / 8;
@ -887,7 +903,7 @@ static int console_dial(int fd, int argc, char *argv[])
if (tmp2 && strlen(tmp2))
myc = tmp2;
}
if (ast_exists_extension(NULL, myc, mye, 1)) {
if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
strncpy(oss.exten, mye, sizeof(oss.exten));
strncpy(oss.context, myc, sizeof(oss.context));
hookstate = 1;

View File

@ -35,6 +35,7 @@
#include "DialTone.h"
#define PHONE_MAX_BUF 480
#define DEFAULT_GAIN 0x100
static char *desc = "Linux Telephony API Support";
static char *type = "Phone";
@ -52,7 +53,7 @@ static int echocancel = AEC_OFF;
static int silencesupression = 0;
static int prefformat = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR;
static int prefformat = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
@ -90,13 +91,19 @@ static struct phone_pvt {
char buf[PHONE_MAX_BUF]; /* Static buffer for reading frames */
int obuflen;
int dialtone;
int txgain, rxgain; /* gain control for playing, recording */
/* 0x100 - 1.0, 0x200 - 2.0, 0x80 - 0.5 */
int cpt; /* Call Progress Tone playing? */
int silencesupression;
char context[AST_MAX_EXTENSION];
char obuf[PHONE_MAX_BUF * 2];
char ext[AST_MAX_EXTENSION];
char language[MAX_LANGUAGE];
char callerid[AST_MAX_EXTENSION];
} *iflist = NULL;
static char callerid[AST_MAX_EXTENSION];
static int phone_digit(struct ast_channel *ast, char digit)
{
struct phone_pvt *p;
@ -179,6 +186,7 @@ static int phone_hangup(struct ast_channel *ast)
if (option_debug)
ast_log(LOG_DEBUG, "Got hunghup, giving busy signal\n");
ioctl(p->fd, PHONE_BUSY);
p->cpt = 1;
}
p->lastformat = -1;
p->lastinput = -1;
@ -226,6 +234,15 @@ static int phone_setup(struct ast_channel *ast)
return -1;
}
}
} else if (ast->pvt->rawreadformat == AST_FORMAT_ULAW) {
ioctl(p->fd, PHONE_REC_STOP);
if (p->lastinput != AST_FORMAT_ULAW) {
p->lastinput = AST_FORMAT_ULAW;
if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
ast_log(LOG_WARNING, "Failed to set codec to signed linear 16\n");
return -1;
}
}
} else {
ast_log(LOG_WARNING, "Can't do format %d\n", ast->pvt->rawreadformat);
return -1;
@ -397,8 +414,16 @@ static int phone_write_buf(struct phone_pvt *p, char *buf, int len, int frlen)
#endif
if (res != frlen) {
if (res < 1) {
/*
* Card is in non-blocking mode now and it works well now, but there are
* lot of messages like this. So, this message is temporarily disabled.
*/
#if 0
ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
return -1;
#else
return 0;
#endif
} else {
ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frlen);
}
@ -427,7 +452,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
ast_frfree(frame);
return -1;
}
if (!(frame->subclass & (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR))) {
if (!(frame->subclass &
(AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW))) {
ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
ast_frfree(frame);
return -1;
@ -479,6 +505,25 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
p->obuflen = 0;
}
maxfr = 480;
} else if (frame->subclass == AST_FORMAT_ULAW) {
if (p->lastformat != AST_FORMAT_ULAW) {
ioctl(p->fd, PHONE_PLAY_STOP);
ioctl(p->fd, PHONE_REC_STOP);
if (ioctl(p->fd, PHONE_PLAY_CODEC, ULAW)) {
ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
return -1;
}
if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
return -1;
}
p->lastformat = AST_FORMAT_ULAW;
p->lastinput = AST_FORMAT_ULAW;
codecset = 1;
/* Reset output buffer */
p->obuflen = 0;
}
maxfr = 240;
}
if (codecset) {
ioctl(p->fd, PHONE_REC_DEPTH, 3);
@ -517,8 +562,14 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
if (res != expected) {
if (res < 0)
ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
/*
* Card is in non-blocking mode now and it works well now, but there are
* lot of messages like this. So, this message is temporarily disabled.
*/
#if 0
else
ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
#endif
return -1;
}
sofar += res;
@ -553,6 +604,8 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
strncpy(tmp->exten, i->ext, sizeof(tmp->exten));
if (strlen(i->language))
strncpy(tmp->language, i->language, sizeof(tmp->language));
if (strlen(i->callerid))
tmp->callerid = strdup(i->callerid);
i->owner = tmp;
ast_pthread_mutex_lock(&usecnt_lock);
usecnt++;
@ -561,6 +614,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
if (state != AST_STATE_DOWN) {
if (state == AST_STATE_RING) {
ioctl(tmp->fds[0], PHONE_RINGBACK);
i->cpt = 1;
}
if (ast_pbx_start(tmp)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
@ -603,7 +657,7 @@ static void phone_check_exception(struct phone_pvt *i)
i->dialtone = 0;
if (strlen(i->ext) < AST_MAX_EXTENSION - 1)
strcat(i->ext, digit);
if (ast_exists_extension(NULL, i->context, i->ext, 1)) {
if (ast_exists_extension(NULL, i->context, i->ext, 1, i->callerid)) {
/* It's a valid extension in its context, get moving! */
phone_new(i, AST_STATE_RING, i->context);
/* No need to restart monitor, we are the monitor */
@ -613,10 +667,10 @@ static void phone_check_exception(struct phone_pvt *i)
ast_pthread_mutex_unlock(&usecnt_lock);
ast_update_use_count();
}
} else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1)) {
} else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1, i->callerid)) {
/* There is nothing in the specified extension that can match anymore.
Try the default */
if (ast_exists_extension(NULL, "default", i->ext, 1)) {
if (ast_exists_extension(NULL, "default", i->ext, 1, i->callerid)) {
/* Check the default, too... */
phone_new(i, AST_STATE_RING, "default");
if (i->owner) {
@ -626,11 +680,12 @@ static void phone_check_exception(struct phone_pvt *i)
ast_update_use_count();
}
/* XXX This should probably be justified better XXX */
} else if (!ast_canmatch_extension(NULL, "default", i->ext, 1)) {
} else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->callerid)) {
/* It's not a valid extension, give a busy signal */
if (option_debug)
ast_log(LOG_DEBUG, "%s can't match anything in %s or default\n", i->ext, i->context);
ioctl(i->fd, PHONE_BUSY);
i->cpt = 1;
}
}
#if 0
@ -665,7 +720,11 @@ static void phone_check_exception(struct phone_pvt *i)
ast_update_use_count();
}
memset(i->ext, 0, sizeof(i->ext));
ioctl(i->fd, PHONE_CPT_STOP);
if (i->cpt)
{
ioctl(i->fd, PHONE_CPT_STOP);
i->cpt = 0;
}
ioctl(i->fd, PHONE_PLAY_STOP);
ioctl(i->fd, PHONE_REC_STOP);
i->dialtone = 0;
@ -833,13 +892,11 @@ static int restart_monitor()
return 0;
}
static struct phone_pvt *mkif(char *iface, int mode)
static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
{
/* Make a phone_pvt structure for this interface */
struct phone_pvt *tmp;
#if 0
int flags;
#endif
tmp = malloc(sizeof(struct phone_pvt));
if (tmp) {
@ -852,6 +909,9 @@ static struct phone_pvt *mkif(char *iface, int mode)
if (mode == MODE_FXO) {
if (ioctl(tmp->fd, IXJCTL_PORT, PORT_PSTN))
ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
} else {
if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS))
ast_log(LOG_DEBUG, "Unable to set port to PSTN\n");
}
ioctl(tmp->fd, PHONE_PLAY_STOP);
ioctl(tmp->fd, PHONE_REC_STOP);
@ -867,10 +927,8 @@ static struct phone_pvt *mkif(char *iface, int mode)
ioctl(tmp->fd, PHONE_VAD, tmp->silencesupression);
#endif
tmp->mode = mode;
#if 0
flags = fcntl(tmp->fd, F_GETFL);
fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
#endif
tmp->owner = NULL;
tmp->lastformat = -1;
tmp->lastinput = -1;
@ -882,6 +940,12 @@ static struct phone_pvt *mkif(char *iface, int mode)
tmp->next = NULL;
tmp->obuflen = 0;
tmp->dialtone = 0;
tmp->cpt = 0;
strncpy(tmp->callerid, callerid, sizeof(tmp->callerid));
tmp->txgain = txgain;
ioctl(tmp->fd, PHONE_PLAY_VOLUME, tmp->txgain);
tmp->rxgain = rxgain;
ioctl(tmp->fd, PHONE_REC_VOLUME, tmp->rxgain);
}
return tmp;
}
@ -894,7 +958,7 @@ static struct ast_channel *phone_request(char *type, int format, void *data)
char *name = data;
oldformat = format;
format &= (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR);
format &= (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
if (!format) {
ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
return NULL;
@ -919,12 +983,36 @@ static struct ast_channel *phone_request(char *type, int format, void *data)
return tmp;
}
/* parse gain value from config file */
static int parse_gain_value(char *gain_type, char *value)
{
float gain;
/* try to scan number */
if (sscanf(value, "%f", &gain) != 1)
{
ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n",
value, gain_type, config);
return DEFAULT_GAIN;
}
/* multiplicate gain by 1.0 gain value */
gain = gain * (float)DEFAULT_GAIN;
/* percentage? */
if (value[strlen(value) - 1] == '%')
return (int)(gain / (float)100);
return (int)gain;
}
int load_module()
{
struct ast_config *cfg;
struct ast_variable *v;
struct phone_pvt *tmp;
int mode = MODE_IMMEDIATE;
int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */
cfg = ast_load(config);
/* We *must* have a config file otherwise stop immediately */
@ -941,7 +1029,7 @@ int load_module()
while(v) {
/* Create the interface list */
if (!strcasecmp(v->name, "device")) {
tmp = mkif(v->value, mode);
tmp = mkif(v->value, mode, txgain, rxgain);
if (tmp) {
tmp->next = iflist;
iflist = tmp;
@ -957,6 +1045,8 @@ int load_module()
silencesupression = ast_true(v->value);
} else if (!strcasecmp(v->name, "language")) {
strncpy(language, v->value, sizeof(language));
} else if (!strcasecmp(v->name, "callerid")) {
strncpy(callerid, v->value, sizeof(callerid));
} else if (!strcasecmp(v->name, "mode")) {
if (!strncasecmp(v->value, "di", 2))
mode = MODE_DIALTONE;
@ -988,12 +1078,17 @@ int load_module()
echocancel = AEC_HIGH;
} else
ast_log(LOG_WARNING, "Unknown echo cancellation '%s'\n", v->value);
}
} else if (!strcasecmp(v->name, "txgain")) {
txgain = parse_gain_value(v->name, v->value);
} else if (!strcasecmp(v->name, "rxgain")) {
rxgain = parse_gain_value(v->name, v->value);
}
v = v->next;
}
ast_pthread_mutex_unlock(&iflock);
/* Make sure we can register our Adtranphone channel type */
if (ast_channel_register(type, tdesc, AST_FORMAT_G723_1, phone_request)) {
if (ast_channel_register(type, tdesc,
AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, phone_request)) {
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
ast_destroy(cfg);
unload_module();