Rework channel structure to eliminate "pvt" portion of channel (bug #3573)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@5137 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
b0180cc4f6
commit
8ba4898a1e
|
@ -1 +1 @@
|
|||
3
|
||||
4
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/config.h>
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/features.h>
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
|
@ -51,7 +50,7 @@ static int sendtext_exec(struct ast_channel *chan, void *data)
|
|||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
ast_mutex_lock(&chan->lock);
|
||||
if (!chan->pvt->send_text) {
|
||||
if (!chan->tech->send_text) {
|
||||
ast_mutex_unlock(&chan->lock);
|
||||
/* Does not support transport */
|
||||
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->cid.cid_num))
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <asterisk/file.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/config.h>
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <asterisk/sched.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/translate.h>
|
||||
|
|
472
channel.c
472
channel.c
|
@ -25,7 +25,6 @@
|
|||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/musiconhold.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <asterisk/file.h>
|
||||
|
@ -67,11 +66,7 @@ unsigned long global_fin = 0, global_fout = 0;
|
|||
/* XXX Lock appropriately in more functions XXX */
|
||||
|
||||
struct chanlist {
|
||||
char type[80];
|
||||
char description[80];
|
||||
int capabilities;
|
||||
struct ast_channel * (*requester)(const char *type, int format, void *data, int *cause);
|
||||
int (*devicestate)(void *data);
|
||||
const struct ast_channel_tech *tech;
|
||||
struct chanlist *next;
|
||||
} *backends = NULL;
|
||||
struct ast_channel *channels = NULL;
|
||||
|
@ -92,7 +87,7 @@ static int show_channeltypes(int fd, int argc, char *argv[])
|
|||
return -1;
|
||||
}
|
||||
while (cl) {
|
||||
ast_cli(fd, FORMAT, cl->type, cl->description);
|
||||
ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description);
|
||||
cl = cl->next;
|
||||
}
|
||||
ast_mutex_unlock(&chlock);
|
||||
|
@ -113,8 +108,8 @@ time_t myt;
|
|||
|
||||
/* if soft hangup flag, return true */
|
||||
if (chan->_softhangup) return 1;
|
||||
/* if no private structure, return true */
|
||||
if (!chan->pvt->pvt) return 1;
|
||||
/* if no technology private data, return true */
|
||||
if (!chan->tech_pvt) return 1;
|
||||
/* if no hangup scheduled, just return here */
|
||||
if (!chan->whentohangup) return 0;
|
||||
time(&myt); /* get current time */
|
||||
|
@ -184,51 +179,39 @@ void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
|
|||
return;
|
||||
}
|
||||
|
||||
int ast_channel_register(const char *type, const char *description, int capabilities,
|
||||
struct ast_channel *(*requester)(const char *type, int format, void *data, int *cause))
|
||||
int ast_channel_register(const struct ast_channel_tech *tech)
|
||||
{
|
||||
return ast_channel_register_ex(type, description, capabilities, requester, NULL);
|
||||
}
|
||||
struct chanlist *chan;
|
||||
|
||||
ast_mutex_lock(&chlock);
|
||||
|
||||
int ast_channel_register_ex(const char *type, const char *description, int capabilities,
|
||||
struct ast_channel *(*requester)(const char *type, int format, void *data, int *cause),
|
||||
int (*devicestate)(void *data))
|
||||
{
|
||||
struct chanlist *chan, *last=NULL;
|
||||
if (ast_mutex_lock(&chlock)) {
|
||||
ast_log(LOG_WARNING, "Unable to lock channel list\n");
|
||||
return -1;
|
||||
}
|
||||
chan = backends;
|
||||
while (chan) {
|
||||
if (!strcasecmp(type, chan->type)) {
|
||||
ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type);
|
||||
if (!strcasecmp(tech->type, chan->tech->type)) {
|
||||
ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
|
||||
ast_mutex_unlock(&chlock);
|
||||
return -1;
|
||||
}
|
||||
last = chan;
|
||||
chan = chan->next;
|
||||
}
|
||||
chan = malloc(sizeof(struct chanlist));
|
||||
|
||||
chan = malloc(sizeof(*chan));
|
||||
if (!chan) {
|
||||
ast_log(LOG_WARNING, "Out of memory\n");
|
||||
ast_mutex_unlock(&chlock);
|
||||
return -1;
|
||||
}
|
||||
strncpy(chan->type, type, sizeof(chan->type)-1);
|
||||
strncpy(chan->description, description, sizeof(chan->description)-1);
|
||||
chan->capabilities = capabilities;
|
||||
chan->requester = requester;
|
||||
chan->devicestate = devicestate;
|
||||
chan->next = NULL;
|
||||
if (last)
|
||||
last->next = chan;
|
||||
else
|
||||
backends = chan;
|
||||
chan->tech = tech;
|
||||
chan->next = backends;
|
||||
backends = chan;
|
||||
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description);
|
||||
else if (option_verbose > 1)
|
||||
ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description);
|
||||
ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
|
||||
|
||||
if (option_verbose > 1)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
|
||||
chan->tech->description);
|
||||
|
||||
ast_mutex_unlock(&chlock);
|
||||
return 0;
|
||||
}
|
||||
|
@ -302,95 +285,100 @@ int ast_best_codec(int fmts)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct ast_channel_tech null_tech = {
|
||||
.type = "NULL",
|
||||
.description "Null channel (should not see this)",
|
||||
};
|
||||
|
||||
struct ast_channel *ast_channel_alloc(int needqueue)
|
||||
{
|
||||
struct ast_channel *tmp;
|
||||
struct ast_channel_pvt *pvt;
|
||||
int x;
|
||||
int flags;
|
||||
struct varshead *headp;
|
||||
|
||||
|
||||
|
||||
/* If shutting down, don't allocate any new channels */
|
||||
if (shutting_down)
|
||||
return NULL;
|
||||
|
||||
ast_mutex_lock(&chlock);
|
||||
tmp = malloc(sizeof(struct ast_channel));
|
||||
if (tmp) {
|
||||
memset(tmp, 0, sizeof(struct ast_channel));
|
||||
pvt = malloc(sizeof(struct ast_channel_pvt));
|
||||
if (pvt) {
|
||||
memset(pvt, 0, sizeof(struct ast_channel_pvt));
|
||||
tmp->sched = sched_context_create();
|
||||
if (tmp->sched) {
|
||||
for (x=0;x<AST_MAX_FDS - 1;x++)
|
||||
tmp->fds[x] = -1;
|
||||
if (!tmp) {
|
||||
ast_log(LOG_WARNING, "Out of memory\n");
|
||||
ast_mutex_unlock(&chlock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(tmp, 0, sizeof(struct ast_channel));
|
||||
tmp->sched = sched_context_create();
|
||||
if (!tmp->sched) {
|
||||
ast_log(LOG_WARNING, "Unable to create schedule context\n");
|
||||
free(tmp);
|
||||
ast_mutex_unlock(&chlock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (x=0;x<AST_MAX_FDS - 1;x++)
|
||||
tmp->fds[x] = -1;
|
||||
|
||||
#ifdef ZAPTEL_OPTIMIZATIONS
|
||||
tmp->timingfd = open("/dev/zap/timer", O_RDWR);
|
||||
if (tmp->timingfd > -1) {
|
||||
/* Check if timing interface supports new
|
||||
ping/pong scheme */
|
||||
flags = 1;
|
||||
if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
|
||||
needqueue = 0;
|
||||
}
|
||||
tmp->timingfd = open("/dev/zap/timer", O_RDWR);
|
||||
if (tmp->timingfd > -1) {
|
||||
/* Check if timing interface supports new
|
||||
ping/pong scheme */
|
||||
flags = 1;
|
||||
if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
|
||||
needqueue = 0;
|
||||
}
|
||||
#else
|
||||
tmp->timingfd = -1;
|
||||
tmp->timingfd = -1;
|
||||
#endif
|
||||
if (needqueue &&
|
||||
pipe(pvt->alertpipe)) {
|
||||
ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
|
||||
free(pvt);
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
pvt = NULL;
|
||||
} else {
|
||||
if (needqueue) {
|
||||
flags = fcntl(pvt->alertpipe[0], F_GETFL);
|
||||
fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
|
||||
flags = fcntl(pvt->alertpipe[1], F_GETFL);
|
||||
fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
|
||||
} else
|
||||
/* Make sure we've got it done right if they don't */
|
||||
pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
|
||||
/* Always watch the alertpipe */
|
||||
tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
|
||||
/* And timing pipe */
|
||||
tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
|
||||
strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
|
||||
tmp->pvt = pvt;
|
||||
/* Initial state */
|
||||
tmp->_state = AST_STATE_DOWN;
|
||||
tmp->streamid = -1;
|
||||
tmp->appl = NULL;
|
||||
tmp->data = NULL;
|
||||
tmp->fin = global_fin;
|
||||
tmp->fout = global_fout;
|
||||
snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
|
||||
headp=&tmp->varshead;
|
||||
ast_mutex_init(&tmp->lock);
|
||||
AST_LIST_HEAD_INIT(headp);
|
||||
strncpy(tmp->context, "default", sizeof(tmp->context)-1);
|
||||
strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
|
||||
strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
|
||||
tmp->priority=1;
|
||||
tmp->amaflags = ast_default_amaflags;
|
||||
strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
|
||||
tmp->next = channels;
|
||||
channels= tmp;
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Unable to create schedule context\n");
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Out of memory\n");
|
||||
|
||||
if (needqueue) {
|
||||
if (pipe(tmp->alertpipe)) {
|
||||
ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
ast_mutex_unlock(&chlock);
|
||||
return NULL;
|
||||
} else {
|
||||
flags = fcntl(tmp->alertpipe[0], F_GETFL);
|
||||
fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
|
||||
flags = fcntl(tmp->alertpipe[1], F_GETFL);
|
||||
fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Out of memory\n");
|
||||
/* Make sure we've got it done right if they don't */
|
||||
tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
|
||||
|
||||
/* Always watch the alertpipe */
|
||||
tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0];
|
||||
/* And timing pipe */
|
||||
tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
|
||||
strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
|
||||
/* Initial state */
|
||||
tmp->_state = AST_STATE_DOWN;
|
||||
tmp->streamid = -1;
|
||||
tmp->appl = NULL;
|
||||
tmp->data = NULL;
|
||||
tmp->fin = global_fin;
|
||||
tmp->fout = global_fout;
|
||||
snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
|
||||
headp = &tmp->varshead;
|
||||
ast_mutex_init(&tmp->lock);
|
||||
AST_LIST_HEAD_INIT(headp);
|
||||
strncpy(tmp->context, "default", sizeof(tmp->context)-1);
|
||||
strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
|
||||
strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
|
||||
tmp->priority = 1;
|
||||
tmp->amaflags = ast_default_amaflags;
|
||||
strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
|
||||
|
||||
tmp->tech = &null_tech;
|
||||
|
||||
tmp->next = channels;
|
||||
channels = tmp;
|
||||
|
||||
ast_mutex_unlock(&chlock);
|
||||
return tmp;
|
||||
}
|
||||
|
@ -409,7 +397,7 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
|
|||
}
|
||||
ast_mutex_lock(&chan->lock);
|
||||
prev = NULL;
|
||||
cur = chan->pvt->readq;
|
||||
cur = chan->readq;
|
||||
while(cur) {
|
||||
if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
|
||||
/* Don't bother actually queueing anything after a hangup */
|
||||
|
@ -436,9 +424,9 @@ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
|
|||
if (prev)
|
||||
prev->next = f;
|
||||
else
|
||||
chan->pvt->readq = f;
|
||||
if (chan->pvt->alertpipe[1] > -1) {
|
||||
if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
|
||||
chan->readq = f;
|
||||
if (chan->alertpipe[1] > -1) {
|
||||
if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
|
||||
ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
|
||||
chan->name, f->frametype, f->subclass, qlen, strerror(errno));
|
||||
#ifdef ZAPTEL_OPTIMIZATIONS
|
||||
|
@ -632,8 +620,10 @@ void ast_channel_free(struct ast_channel *chan)
|
|||
ast_mutex_lock(&cur->lock);
|
||||
ast_mutex_unlock(&cur->lock);
|
||||
}
|
||||
if (chan->pvt->pvt)
|
||||
if (chan->tech_pvt) {
|
||||
ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
|
||||
free(chan->tech_pvt);
|
||||
}
|
||||
|
||||
strncpy(name, chan->name, sizeof(name)-1);
|
||||
|
||||
|
@ -647,23 +637,23 @@ void ast_channel_free(struct ast_channel *chan)
|
|||
ast_moh_cleanup(chan);
|
||||
|
||||
/* Free translatosr */
|
||||
if (chan->pvt->readtrans)
|
||||
ast_translator_free_path(chan->pvt->readtrans);
|
||||
if (chan->pvt->writetrans)
|
||||
ast_translator_free_path(chan->pvt->writetrans);
|
||||
if (chan->readtrans)
|
||||
ast_translator_free_path(chan->readtrans);
|
||||
if (chan->writetrans)
|
||||
ast_translator_free_path(chan->writetrans);
|
||||
if (chan->pbx)
|
||||
ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
|
||||
free_cid(&chan->cid);
|
||||
ast_mutex_destroy(&chan->lock);
|
||||
/* Close pipes if appropriate */
|
||||
if ((fd = chan->pvt->alertpipe[0]) > -1)
|
||||
if ((fd = chan->alertpipe[0]) > -1)
|
||||
close(fd);
|
||||
if ((fd = chan->pvt->alertpipe[1]) > -1)
|
||||
if ((fd = chan->alertpipe[1]) > -1)
|
||||
close(fd);
|
||||
if ((fd = chan->timingfd) > -1)
|
||||
close(fd);
|
||||
f = chan->pvt->readq;
|
||||
chan->pvt->readq = NULL;
|
||||
f = chan->readq;
|
||||
chan->readq = NULL;
|
||||
while(f) {
|
||||
fp = f;
|
||||
f = f->next;
|
||||
|
@ -678,10 +668,7 @@ void ast_channel_free(struct ast_channel *chan)
|
|||
/* printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata)); */
|
||||
ast_var_delete(vardata);
|
||||
}
|
||||
|
||||
|
||||
free(chan->pvt);
|
||||
chan->pvt = NULL;
|
||||
free(chan);
|
||||
ast_mutex_unlock(&chlock);
|
||||
|
||||
|
@ -714,14 +701,14 @@ int ast_softhangup(struct ast_channel *chan, int cause)
|
|||
|
||||
static void free_translation(struct ast_channel *clone)
|
||||
{
|
||||
if (clone->pvt->writetrans)
|
||||
ast_translator_free_path(clone->pvt->writetrans);
|
||||
if (clone->pvt->readtrans)
|
||||
ast_translator_free_path(clone->pvt->readtrans);
|
||||
clone->pvt->writetrans = NULL;
|
||||
clone->pvt->readtrans = NULL;
|
||||
clone->pvt->rawwriteformat = clone->nativeformats;
|
||||
clone->pvt->rawreadformat = clone->nativeformats;
|
||||
if (clone->writetrans)
|
||||
ast_translator_free_path(clone->writetrans);
|
||||
if (clone->readtrans)
|
||||
ast_translator_free_path(clone->readtrans);
|
||||
clone->writetrans = NULL;
|
||||
clone->readtrans = NULL;
|
||||
clone->rawwriteformat = clone->nativeformats;
|
||||
clone->rawreadformat = clone->nativeformats;
|
||||
}
|
||||
|
||||
int ast_hangup(struct ast_channel *chan)
|
||||
|
@ -775,8 +762,8 @@ int ast_hangup(struct ast_channel *chan)
|
|||
if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
|
||||
if (chan->pvt->hangup)
|
||||
res = chan->pvt->hangup(chan);
|
||||
if (chan->tech->hangup)
|
||||
res = chan->tech->hangup(chan);
|
||||
} else
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
|
||||
|
@ -791,32 +778,34 @@ int ast_hangup(struct ast_channel *chan)
|
|||
return res;
|
||||
}
|
||||
|
||||
void ast_channel_unregister(const char *type)
|
||||
void ast_channel_unregister(const struct ast_channel_tech *tech)
|
||||
{
|
||||
struct chanlist *chan, *last=NULL;
|
||||
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
|
||||
if (ast_mutex_lock(&chlock)) {
|
||||
ast_log(LOG_WARNING, "Unable to lock channel list\n");
|
||||
return;
|
||||
}
|
||||
if (option_verbose > 1)
|
||||
ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type);
|
||||
ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
|
||||
|
||||
ast_mutex_lock(&chlock);
|
||||
|
||||
chan = backends;
|
||||
while(chan) {
|
||||
if (!strcasecmp(chan->type, type)) {
|
||||
while (chan) {
|
||||
if (chan->tech == tech) {
|
||||
if (last)
|
||||
last->next = chan->next;
|
||||
else
|
||||
backends = backends->next;
|
||||
free(chan);
|
||||
ast_mutex_unlock(&chlock);
|
||||
|
||||
if (option_verbose > 1)
|
||||
ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
|
||||
|
||||
return;
|
||||
}
|
||||
last = chan;
|
||||
chan = chan->next;
|
||||
}
|
||||
|
||||
ast_mutex_unlock(&chlock);
|
||||
}
|
||||
|
||||
|
@ -832,8 +821,8 @@ int ast_answer(struct ast_channel *chan)
|
|||
switch(chan->_state) {
|
||||
case AST_STATE_RINGING:
|
||||
case AST_STATE_RING:
|
||||
if (chan->pvt->answer)
|
||||
res = chan->pvt->answer(chan);
|
||||
if (chan->tech->answer)
|
||||
res = chan->tech->answer(chan);
|
||||
ast_setstate(chan, AST_STATE_UP);
|
||||
if (chan->cdr)
|
||||
ast_cdr_answer(chan->cdr);
|
||||
|
@ -1269,8 +1258,8 @@ struct ast_frame *ast_read(struct ast_channel *chan)
|
|||
|
||||
/* Read and ignore anything on the alertpipe, but read only
|
||||
one sizeof(blah) per frame that we send from it */
|
||||
if (chan->pvt->alertpipe[0] > -1) {
|
||||
read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
|
||||
if (chan->alertpipe[0] > -1) {
|
||||
read(chan->alertpipe[0], &blah, sizeof(blah));
|
||||
}
|
||||
#ifdef ZAPTEL_OPTIMIZATIONS
|
||||
if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
|
||||
|
@ -1285,7 +1274,7 @@ struct ast_frame *ast_read(struct ast_channel *chan)
|
|||
#if 0
|
||||
ast_log(LOG_NOTICE, "Oooh, there's a PING!\n");
|
||||
#endif
|
||||
if (!chan->pvt->readq || !chan->pvt->readq->next) {
|
||||
if (!chan->readq || !chan->readq->next) {
|
||||
/* Acknowledge PONG unless we need it again */
|
||||
#if 0
|
||||
ast_log(LOG_NOTICE, "Sending a PONG!\n");
|
||||
|
@ -1318,9 +1307,9 @@ struct ast_frame *ast_read(struct ast_channel *chan)
|
|||
}
|
||||
#endif
|
||||
/* Check for pending read queue */
|
||||
if (chan->pvt->readq) {
|
||||
f = chan->pvt->readq;
|
||||
chan->pvt->readq = f->next;
|
||||
if (chan->readq) {
|
||||
f = chan->readq;
|
||||
chan->readq = f->next;
|
||||
/* Interpret hangup and return NULL */
|
||||
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
|
||||
ast_frfree(f);
|
||||
|
@ -1329,8 +1318,8 @@ struct ast_frame *ast_read(struct ast_channel *chan)
|
|||
} else {
|
||||
chan->blocker = pthread_self();
|
||||
if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
|
||||
if (chan->pvt->exception)
|
||||
f = chan->pvt->exception(chan);
|
||||
if (chan->tech->exception)
|
||||
f = chan->tech->exception(chan);
|
||||
else {
|
||||
ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
|
||||
f = &null_frame;
|
||||
|
@ -1338,8 +1327,8 @@ struct ast_frame *ast_read(struct ast_channel *chan)
|
|||
/* Clear the exception flag */
|
||||
ast_clear_flag(chan, AST_FLAG_EXCEPTION);
|
||||
} else
|
||||
if (chan->pvt->read)
|
||||
f = chan->pvt->read(chan);
|
||||
if (chan->tech->read)
|
||||
f = chan->tech->read(chan);
|
||||
else
|
||||
ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
|
||||
}
|
||||
|
@ -1374,8 +1363,8 @@ struct ast_frame *ast_read(struct ast_channel *chan)
|
|||
if (ast_writestream(chan->monitor->read_stream, f) < 0)
|
||||
ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
|
||||
}
|
||||
if (chan->pvt->readtrans) {
|
||||
f = ast_translate(chan->pvt->readtrans, f, 1);
|
||||
if (chan->readtrans) {
|
||||
f = ast_translate(chan->readtrans, f, 1);
|
||||
if (!f)
|
||||
f = &null_frame;
|
||||
}
|
||||
|
@ -1449,10 +1438,10 @@ int ast_indicate(struct ast_channel *chan, int condition)
|
|||
if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
|
||||
return -1;
|
||||
ast_mutex_lock(&chan->lock);
|
||||
if (chan->pvt->indicate)
|
||||
res = chan->pvt->indicate(chan, condition);
|
||||
if (chan->tech->indicate)
|
||||
res = chan->tech->indicate(chan, condition);
|
||||
ast_mutex_unlock(&chan->lock);
|
||||
if (!chan->pvt->indicate || res) {
|
||||
if (!chan->tech->indicate || res) {
|
||||
/*
|
||||
* Device does not support (that) indication, lets fake
|
||||
* it by doing our own tone generation. (PM2002)
|
||||
|
@ -1529,8 +1518,8 @@ int ast_sendtext(struct ast_channel *chan, char *text)
|
|||
if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
|
||||
return -1;
|
||||
CHECK_BLOCKING(chan);
|
||||
if (chan->pvt->send_text)
|
||||
res = chan->pvt->send_text(chan, text);
|
||||
if (chan->tech->send_text)
|
||||
res = chan->tech->send_text(chan, text);
|
||||
ast_clear_flag(chan, AST_FLAG_BLOCKING);
|
||||
return res;
|
||||
}
|
||||
|
@ -1539,9 +1528,9 @@ static int do_senddigit(struct ast_channel *chan, char digit)
|
|||
{
|
||||
int res = -1;
|
||||
|
||||
if (chan->pvt->send_digit)
|
||||
res = chan->pvt->send_digit(chan, digit);
|
||||
if (!chan->pvt->send_digit || res) {
|
||||
if (chan->tech->send_digit)
|
||||
res = chan->tech->send_digit(chan, digit);
|
||||
if (!chan->tech->send_digit || res) {
|
||||
/*
|
||||
* Device does not support DTMF tones, lets fake
|
||||
* it by doing our own generation. (PM2002)
|
||||
|
@ -1591,7 +1580,7 @@ int ast_prod(struct ast_channel *chan)
|
|||
/* Send an empty audio frame to get things moving */
|
||||
if (chan->_state != AST_STATE_UP) {
|
||||
ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
|
||||
a.subclass = chan->pvt->rawwriteformat;
|
||||
a.subclass = chan->rawwriteformat;
|
||||
a.data = nothing + AST_FRIENDLY_OFFSET;
|
||||
a.src = "ast_prod";
|
||||
if (ast_write(chan, &a))
|
||||
|
@ -1603,7 +1592,7 @@ int ast_prod(struct ast_channel *chan)
|
|||
int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
|
||||
{
|
||||
int res;
|
||||
if (!chan->pvt->write_video)
|
||||
if (!chan->tech->write_video)
|
||||
return 0;
|
||||
res = ast_write(chan, fr);
|
||||
if (!res)
|
||||
|
@ -1657,32 +1646,32 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
|
|||
CHECK_BLOCKING(chan);
|
||||
break;
|
||||
case AST_FRAME_TEXT:
|
||||
if (chan->pvt->send_text)
|
||||
res = chan->pvt->send_text(chan, (char *) fr->data);
|
||||
if (chan->tech->send_text)
|
||||
res = chan->tech->send_text(chan, (char *) fr->data);
|
||||
else
|
||||
res = 0;
|
||||
break;
|
||||
case AST_FRAME_HTML:
|
||||
if (chan->pvt->send_html)
|
||||
res = chan->pvt->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
|
||||
if (chan->tech->send_html)
|
||||
res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
|
||||
else
|
||||
res = 0;
|
||||
break;
|
||||
case AST_FRAME_VIDEO:
|
||||
/* XXX Handle translation of video codecs one day XXX */
|
||||
if (chan->pvt->write_video)
|
||||
res = chan->pvt->write_video(chan, fr);
|
||||
if (chan->tech->write_video)
|
||||
res = chan->tech->write_video(chan, fr);
|
||||
else
|
||||
res = 0;
|
||||
break;
|
||||
default:
|
||||
if (chan->pvt->write) {
|
||||
if (chan->pvt->writetrans) {
|
||||
f = ast_translate(chan->pvt->writetrans, fr, 0);
|
||||
if (chan->tech->write) {
|
||||
if (chan->writetrans) {
|
||||
f = ast_translate(chan->writetrans, fr, 0);
|
||||
} else
|
||||
f = fr;
|
||||
if (f) {
|
||||
res = chan->pvt->write(chan, f);
|
||||
res = chan->tech->write(chan, f);
|
||||
if( chan->monitor &&
|
||||
chan->monitor->write_stream &&
|
||||
f && ( f->frametype == AST_FRAME_VOICE ) ) {
|
||||
|
@ -1746,14 +1735,14 @@ int ast_set_write_format(struct ast_channel *chan, int fmts)
|
|||
}
|
||||
|
||||
/* Now we have a good choice for both. We'll write using our native format. */
|
||||
chan->pvt->rawwriteformat = native;
|
||||
chan->rawwriteformat = native;
|
||||
/* User perspective is fmt */
|
||||
chan->writeformat = fmt;
|
||||
/* Free any write translation we have right now */
|
||||
if (chan->pvt->writetrans)
|
||||
ast_translator_free_path(chan->pvt->writetrans);
|
||||
if (chan->writetrans)
|
||||
ast_translator_free_path(chan->writetrans);
|
||||
/* Build a translation path from the user write format to the raw writing format */
|
||||
chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
|
||||
chan->writetrans = ast_translator_build_path(chan->rawwriteformat, chan->writeformat);
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
|
||||
ast_mutex_unlock(&chan->lock);
|
||||
|
@ -1779,14 +1768,14 @@ int ast_set_read_format(struct ast_channel *chan, int fmts)
|
|||
}
|
||||
|
||||
/* Now we have a good choice for both. We'll write using our native format. */
|
||||
chan->pvt->rawreadformat = native;
|
||||
chan->rawreadformat = native;
|
||||
/* User perspective is fmt */
|
||||
chan->readformat = fmt;
|
||||
/* Free any read translation we have right now */
|
||||
if (chan->pvt->readtrans)
|
||||
ast_translator_free_path(chan->pvt->readtrans);
|
||||
if (chan->readtrans)
|
||||
ast_translator_free_path(chan->readtrans);
|
||||
/* Build a translation path from the raw read format to the user reading format */
|
||||
chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
|
||||
chan->readtrans = ast_translator_build_path(chan->readformat, chan->rawreadformat);
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Set channel %s to read format %s\n",
|
||||
chan->name, ast_getformatname(chan->readformat));
|
||||
|
@ -1934,18 +1923,18 @@ struct ast_channel *ast_request(const char *type, int format, void *data, int *c
|
|||
}
|
||||
chan = backends;
|
||||
while(chan) {
|
||||
if (!strcasecmp(type, chan->type)) {
|
||||
capabilities = chan->capabilities;
|
||||
if (!strcasecmp(type, chan->tech->type)) {
|
||||
capabilities = chan->tech->capabilities;
|
||||
fmt = format;
|
||||
res = ast_translator_best_choice(&fmt, &capabilities);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
|
||||
ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
|
||||
ast_mutex_unlock(&chlock);
|
||||
return NULL;
|
||||
}
|
||||
ast_mutex_unlock(&chlock);
|
||||
if (chan->requester)
|
||||
c = chan->requester(type, capabilities, data, cause);
|
||||
if (chan->tech->requester)
|
||||
c = chan->tech->requester(type, capabilities, data, cause);
|
||||
if (c) {
|
||||
if (c->_state == AST_STATE_DOWN) {
|
||||
manager_event(EVENT_FLAG_CALL, "Newchannel",
|
||||
|
@ -2010,12 +1999,12 @@ int ast_device_state(char *device)
|
|||
}
|
||||
chanls = backends;
|
||||
while(chanls) {
|
||||
if (!strcasecmp(tech, chanls->type)) {
|
||||
if (!strcasecmp(tech, chanls->tech->type)) {
|
||||
ast_mutex_unlock(&chlock);
|
||||
if (!chanls->devicestate)
|
||||
if (!chanls->tech->devicestate)
|
||||
return ast_parse_device_state(device);
|
||||
else {
|
||||
res = chanls->devicestate(number);
|
||||
res = chanls->tech->devicestate(number);
|
||||
if (res == AST_DEVICE_UNKNOWN)
|
||||
return ast_parse_device_state(device);
|
||||
else
|
||||
|
@ -2037,8 +2026,8 @@ int ast_call(struct ast_channel *chan, char *addr, int timeout)
|
|||
/* Stop if we're a zombie or need a soft hangup */
|
||||
ast_mutex_lock(&chan->lock);
|
||||
if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan))
|
||||
if (chan->pvt->call)
|
||||
res = chan->pvt->call(chan, addr, timeout);
|
||||
if (chan->tech->call)
|
||||
res = chan->tech->call(chan, addr, timeout);
|
||||
ast_mutex_unlock(&chan->lock);
|
||||
return res;
|
||||
}
|
||||
|
@ -2052,8 +2041,8 @@ int ast_transfer(struct ast_channel *chan, char *dest)
|
|||
/* Stop if we're a zombie or need a soft hangup */
|
||||
ast_mutex_lock(&chan->lock);
|
||||
if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
|
||||
if (chan->pvt->transfer) {
|
||||
res = chan->pvt->transfer(chan, dest);
|
||||
if (chan->tech->transfer) {
|
||||
res = chan->tech->transfer(chan, dest);
|
||||
if (!res)
|
||||
res = 1;
|
||||
} else
|
||||
|
@ -2146,22 +2135,22 @@ int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, in
|
|||
|
||||
int ast_channel_supports_html(struct ast_channel *chan)
|
||||
{
|
||||
if (chan->pvt->send_html)
|
||||
if (chan->tech->send_html)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ast_channel_sendhtml(struct ast_channel *chan, int subclass, char *data, int datalen)
|
||||
{
|
||||
if (chan->pvt->send_html)
|
||||
return chan->pvt->send_html(chan, subclass, data, datalen);
|
||||
if (chan->tech->send_html)
|
||||
return chan->tech->send_html(chan, subclass, data, datalen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ast_channel_sendurl(struct ast_channel *chan, char *url)
|
||||
{
|
||||
if (chan->pvt->send_html)
|
||||
return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
|
||||
if (chan->tech->send_html)
|
||||
return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2340,7 +2329,8 @@ int ast_do_masquerade(struct ast_channel *original)
|
|||
int res=0;
|
||||
int origstate;
|
||||
struct ast_frame *cur, *prev;
|
||||
struct ast_channel_pvt *p;
|
||||
const struct ast_channel_tech *t;
|
||||
void *t_pvt;
|
||||
struct ast_callerid tmpcid;
|
||||
struct ast_channel *clone = original->masq;
|
||||
int rformat = original->readformat;
|
||||
|
@ -2391,15 +2381,39 @@ int ast_do_masquerade(struct ast_channel *original)
|
|||
manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
|
||||
manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
|
||||
|
||||
/* Swap the guts */
|
||||
p = original->pvt;
|
||||
original->pvt = clone->pvt;
|
||||
clone->pvt = p;
|
||||
/* Swap the technlogies */
|
||||
t = original->tech;
|
||||
original->tech = clone->tech;
|
||||
clone->tech = t;
|
||||
|
||||
t_pvt = original->tech_pvt;
|
||||
original->tech_pvt = clone->tech_pvt;
|
||||
clone->tech_pvt = t_pvt;
|
||||
|
||||
/* Swap the readq's */
|
||||
cur = original->readq;
|
||||
original->readq = clone->readq;
|
||||
clone->readq = cur;
|
||||
|
||||
/* Swap the alertpipes */
|
||||
for (i = 0; i < 2; i++) {
|
||||
x = original->alertpipe[i];
|
||||
original->alertpipe[i] = clone->alertpipe[i];
|
||||
clone->alertpipe[i] = x;
|
||||
}
|
||||
|
||||
/* Swap the raw formats */
|
||||
x = original->rawreadformat;
|
||||
original->rawreadformat = clone->rawreadformat;
|
||||
clone->rawreadformat = x;
|
||||
x = original->rawwriteformat;
|
||||
original->rawwriteformat = clone->rawwriteformat;
|
||||
clone->rawwriteformat = x;
|
||||
|
||||
/* Save any pending frames on both sides. Start by counting
|
||||
* how many we're going to need... */
|
||||
prev = NULL;
|
||||
cur = clone->pvt->readq;
|
||||
cur = clone->readq;
|
||||
x = 0;
|
||||
while(cur) {
|
||||
x++;
|
||||
|
@ -2409,12 +2423,12 @@ int ast_do_masquerade(struct ast_channel *original)
|
|||
/* If we had any, prepend them to the ones already in the queue, and
|
||||
* load up the alertpipe */
|
||||
if (prev) {
|
||||
prev->next = original->pvt->readq;
|
||||
original->pvt->readq = clone->pvt->readq;
|
||||
clone->pvt->readq = NULL;
|
||||
if (original->pvt->alertpipe[1] > -1) {
|
||||
prev->next = original->readq;
|
||||
original->readq = clone->readq;
|
||||
clone->readq = NULL;
|
||||
if (original->alertpipe[1] > -1) {
|
||||
for (i=0;i<x;i++)
|
||||
write(original->pvt->alertpipe[1], &x, sizeof(x));
|
||||
write(original->alertpipe[1], &x, sizeof(x));
|
||||
}
|
||||
}
|
||||
clone->_softhangup = AST_SOFTHANGUP_DEV;
|
||||
|
@ -2428,15 +2442,15 @@ int ast_do_masquerade(struct ast_channel *original)
|
|||
original->_state = clone->_state;
|
||||
clone->_state = origstate;
|
||||
|
||||
if (clone->pvt->fixup){
|
||||
res = clone->pvt->fixup(original, clone);
|
||||
if (clone->tech->fixup){
|
||||
res = clone->tech->fixup(original, clone);
|
||||
if (res)
|
||||
ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
|
||||
}
|
||||
|
||||
/* Start by disconnecting the original's physical side */
|
||||
if (clone->pvt->hangup)
|
||||
res = clone->pvt->hangup(clone);
|
||||
if (clone->tech->hangup)
|
||||
res = clone->tech->hangup(clone);
|
||||
if (res) {
|
||||
ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n");
|
||||
ast_mutex_unlock(&clone->lock);
|
||||
|
@ -2500,8 +2514,8 @@ int ast_do_masquerade(struct ast_channel *original)
|
|||
|
||||
/* Okay. Last thing is to let the channel driver know about all this mess, so he
|
||||
can fix up everything as best as possible */
|
||||
if (original->pvt->fixup) {
|
||||
res = original->pvt->fixup(clone, original);
|
||||
if (original->tech->fixup) {
|
||||
res = original->tech->fixup(clone, original);
|
||||
if (res) {
|
||||
ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n",
|
||||
original->type, original->name);
|
||||
|
@ -2622,8 +2636,8 @@ struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
|
|||
{
|
||||
struct ast_channel *bridged;
|
||||
bridged = chan->_bridge;
|
||||
if (bridged && bridged->pvt->bridged_channel)
|
||||
bridged = bridged->pvt->bridged_channel(chan, bridged);
|
||||
if (bridged && bridged->tech->bridged_channel)
|
||||
bridged = bridged->tech->bridged_channel(chan, bridged);
|
||||
return bridged;
|
||||
}
|
||||
|
||||
|
@ -2772,12 +2786,12 @@ int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct as
|
|||
ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",c0->name,c1->name,ast_test_flag(c0, AST_FLAG_ZOMBIE)?"Yes":"No",ast_check_hangup(c0)?"Yes":"No",ast_test_flag(c1, AST_FLAG_ZOMBIE)?"Yes":"No",ast_check_hangup(c1)?"Yes":"No");
|
||||
break;
|
||||
}
|
||||
if (c0->pvt->bridge && config->timelimit==0 &&
|
||||
(c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
|
||||
if (c0->tech->bridge && config->timelimit==0 &&
|
||||
(c0->tech->bridge == c1->tech->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
|
||||
/* Looks like they share a bridge code */
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
|
||||
if (!(res = c0->pvt->bridge(c0, c1, config->flags, fo, rc))) {
|
||||
if (!(res = c0->tech->bridge(c0, c1, config->flags, fo, rc))) {
|
||||
c0->_bridge = NULL;
|
||||
c1->_bridge = NULL;
|
||||
manager_event(EVENT_FLAG_CALL, "Unlink",
|
||||
|
@ -2903,8 +2917,8 @@ tackygoto:
|
|||
int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
|
||||
{
|
||||
int res;
|
||||
if (chan->pvt->setoption) {
|
||||
res = chan->pvt->setoption(chan, option, data, datalen);
|
||||
if (chan->tech->setoption) {
|
||||
res = chan->tech->setoption(chan, option, data, datalen);
|
||||
if (res < 0)
|
||||
return res;
|
||||
} else {
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -45,20 +44,20 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
static char *desc = "Agent Proxy Channel";
|
||||
static char *channeltype = "Agent";
|
||||
static char *tdesc = "Call Agent Proxy Channel";
|
||||
static char *config = "agents.conf";
|
||||
static const char desc[] = "Agent Proxy Channel";
|
||||
static const char channeltype[] = "Agent";
|
||||
static const char tdesc[] = "Call Agent Proxy Channel";
|
||||
static const char config[] = "agents.conf";
|
||||
|
||||
static char *app = "AgentLogin";
|
||||
static char *app2 = "AgentCallbackLogin";
|
||||
static char *app3 = "AgentMonitorOutgoing";
|
||||
static const char app[] = "AgentLogin";
|
||||
static const char app2[] = "AgentCallbackLogin";
|
||||
static const char app3[] = "AgentMonitorOutgoing";
|
||||
|
||||
static char *synopsis = "Call agent login";
|
||||
static char *synopsis2 = "Call agent callback login";
|
||||
static char *synopsis3 = "Record agent's outgoing call";
|
||||
static const char synopsis[] = "Call agent login";
|
||||
static const char synopsis2[] = "Call agent callback login";
|
||||
static const char synopsis3[] = "Record agent's outgoing call";
|
||||
|
||||
static char *descrip =
|
||||
static const char descrip[] =
|
||||
" AgentLogin([AgentNo][|options]):\n"
|
||||
"Asks the agent to login to the system. Always returns -1. While\n"
|
||||
"logged in, the agent can receive calls and will hear a 'beep'\n"
|
||||
|
@ -67,17 +66,15 @@ static char *descrip =
|
|||
"The option string may contain zero or more of the following characters:\n"
|
||||
" 's' -- silent login - do not announce the login ok segment after agent logged in/off\n";
|
||||
|
||||
static char *descrip2 =
|
||||
static const char descrip2[] =
|
||||
" AgentCallbackLogin([AgentNo][|[options][exten]@context]):\n"
|
||||
"Asks the agent to login to the system with callback.\n"
|
||||
"The agent's callback extension is called (optionally with the specified\n"
|
||||
"context).\n"
|
||||
"The option string may contain zero or more of the following characters:\n"
|
||||
" 's' -- silent login - do not announce the login ok segment agent logged in/off\n";
|
||||
|
||||
|
||||
|
||||
static char *descrip3 =
|
||||
static const char descrip3[] =
|
||||
" AgentMonitorOutgoing([options]):\n"
|
||||
"Tries to figure out the id of the agent who is placing outgoing call based on\n"
|
||||
"comparision of the callerid of the current interface and the global variable \n"
|
||||
|
@ -95,7 +92,7 @@ static char *descrip3 =
|
|||
" agentid is not known.\n"
|
||||
" It's handy if you want to have one context for agent and non-agent calls.\n";
|
||||
|
||||
static char mandescr_agents[] =
|
||||
static const char mandescr_agents[] =
|
||||
"Description: Will list info about all possible agents.\n"
|
||||
"Variables: NONE\n";
|
||||
|
||||
|
@ -106,15 +103,13 @@ static char moh[80] = "default";
|
|||
#define AST_MAX_FILENAME_LEN 256
|
||||
|
||||
/* Persistent Agents astdb family */
|
||||
static const char *pa_family = "/Agents";
|
||||
static const char pa_family[] = "/Agents";
|
||||
/* The maximum lengh of each persistent member agent database entry */
|
||||
#define PA_MAX_LEN 2048
|
||||
/* queues.conf [general] option */
|
||||
static int persistent_agents = 0;
|
||||
static void dump_agents(void);
|
||||
|
||||
static int capability = -1;
|
||||
|
||||
static ast_group_t group;
|
||||
static int autologoff;
|
||||
static int wrapuptime;
|
||||
|
@ -176,10 +171,10 @@ static struct agent_pvt {
|
|||
ast_set_read_format(ast, ast->readformat); \
|
||||
ast_set_write_format(ast, ast->writeformat); \
|
||||
} \
|
||||
if (p->chan->readformat != ast->pvt->rawreadformat) \
|
||||
ast_set_read_format(p->chan, ast->pvt->rawreadformat); \
|
||||
if (p->chan->writeformat != ast->pvt->rawwriteformat) \
|
||||
ast_set_write_format(p->chan, ast->pvt->rawwriteformat); \
|
||||
if (p->chan->readformat != ast->rawreadformat) \
|
||||
ast_set_read_format(p->chan, ast->rawreadformat); \
|
||||
if (p->chan->writeformat != ast->rawwriteformat) \
|
||||
ast_set_write_format(p->chan, ast->rawwriteformat); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
@ -198,7 +193,37 @@ static struct agent_pvt {
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
static struct ast_channel *agent_request(const char *type, int format, void *data, int *cause);
|
||||
static int agent_devicestate(void *data);
|
||||
static int agent_digit(struct ast_channel *ast, char digit);
|
||||
static int agent_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int agent_hangup(struct ast_channel *ast);
|
||||
static int agent_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *agent_read(struct ast_channel *ast);
|
||||
static int agent_write(struct ast_channel *ast, struct ast_frame *f);
|
||||
static int agent_sendhtml(struct ast_channel *ast, int subclass, char *data, int datalen);
|
||||
static int agent_indicate(struct ast_channel *ast, int condition);
|
||||
static int agent_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
|
||||
|
||||
static const struct ast_channel_tech agent_tech = {
|
||||
.type = channeltype,
|
||||
.description = tdesc,
|
||||
.capabilities = -1,
|
||||
.requester = agent_request,
|
||||
.devicestate = agent_devicestate,
|
||||
.send_digit = agent_digit,
|
||||
.call = agent_call,
|
||||
.hangup = agent_hangup,
|
||||
.answer = agent_answer,
|
||||
.read = agent_read,
|
||||
.write = agent_write,
|
||||
.send_html = agent_sendhtml,
|
||||
.exception = agent_read,
|
||||
.indicate = agent_indicate,
|
||||
.fixup = agent_fixup,
|
||||
.bridged_channel = agent_bridgedchannel,
|
||||
};
|
||||
|
||||
static void agent_unlink(struct agent_pvt *agent)
|
||||
{
|
||||
|
@ -281,7 +306,7 @@ static int agent_cleanup(struct agent_pvt *p)
|
|||
{
|
||||
struct ast_channel *chan = p->owner;
|
||||
p->owner = NULL;
|
||||
chan->pvt->pvt = NULL;
|
||||
chan->tech_pvt = NULL;
|
||||
p->app_sleep_cond = 1;
|
||||
/* Release ownership of the agent to other threads (presumably running the login app). */
|
||||
ast_mutex_unlock(&p->app_lock);
|
||||
|
@ -333,12 +358,12 @@ static int __agent_start_monitoring(struct ast_channel *ast, struct agent_pvt *p
|
|||
|
||||
static int agent_start_monitoring(struct ast_channel *ast, int needlock)
|
||||
{
|
||||
return __agent_start_monitoring(ast, ast->pvt->pvt, needlock);
|
||||
return __agent_start_monitoring(ast, ast->tech_pvt, needlock);
|
||||
}
|
||||
|
||||
static struct ast_frame *agent_read(struct ast_channel *ast)
|
||||
{
|
||||
struct agent_pvt *p = ast->pvt->pvt;
|
||||
struct agent_pvt *p = ast->tech_pvt;
|
||||
struct ast_frame *f = NULL;
|
||||
static struct ast_frame null_frame = { AST_FRAME_NULL, };
|
||||
static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
|
||||
|
@ -427,7 +452,7 @@ static struct ast_frame *agent_read(struct ast_channel *ast)
|
|||
|
||||
static int agent_sendhtml(struct ast_channel *ast, int subclass, char *data, int datalen)
|
||||
{
|
||||
struct agent_pvt *p = ast->pvt->pvt;
|
||||
struct agent_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (p->chan)
|
||||
|
@ -438,7 +463,7 @@ static int agent_sendhtml(struct ast_channel *ast, int subclass, char *data, int
|
|||
|
||||
static int agent_write(struct ast_channel *ast, struct ast_frame *f)
|
||||
{
|
||||
struct agent_pvt *p = ast->pvt->pvt;
|
||||
struct agent_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
CHECK_FORMATS(ast, p);
|
||||
ast_mutex_lock(&p->lock);
|
||||
|
@ -459,7 +484,7 @@ static int agent_write(struct ast_channel *ast, struct ast_frame *f)
|
|||
|
||||
static int agent_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct agent_pvt *p = newchan->pvt->pvt;
|
||||
struct agent_pvt *p = newchan->tech_pvt;
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (p->owner != oldchan) {
|
||||
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
|
||||
|
@ -473,7 +498,7 @@ static int agent_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
|||
|
||||
static int agent_indicate(struct ast_channel *ast, int condition)
|
||||
{
|
||||
struct agent_pvt *p = ast->pvt->pvt;
|
||||
struct agent_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (p->chan)
|
||||
|
@ -486,11 +511,11 @@ static int agent_indicate(struct ast_channel *ast, int condition)
|
|||
|
||||
static int agent_digit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
struct agent_pvt *p = ast->pvt->pvt;
|
||||
struct agent_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (p->chan)
|
||||
res = p->chan->pvt->send_digit(p->chan, digit);
|
||||
res = p->chan->tech->send_digit(p->chan, digit);
|
||||
else
|
||||
res = 0;
|
||||
ast_mutex_unlock(&p->lock);
|
||||
|
@ -499,7 +524,7 @@ static int agent_digit(struct ast_channel *ast, char digit)
|
|||
|
||||
static int agent_call(struct ast_channel *ast, char *dest, int timeout)
|
||||
{
|
||||
struct agent_pvt *p = ast->pvt->pvt;
|
||||
struct agent_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
int newstate=0;
|
||||
ast_mutex_lock(&p->lock);
|
||||
|
@ -586,11 +611,11 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
|
||||
static int agent_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct agent_pvt *p = ast->pvt->pvt;
|
||||
struct agent_pvt *p = ast->tech_pvt;
|
||||
int howlong = 0;
|
||||
ast_mutex_lock(&p->lock);
|
||||
p->owner = NULL;
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
p->app_sleep_cond = 1;
|
||||
p->acknowledged = 0;
|
||||
|
||||
|
@ -783,7 +808,7 @@ static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct
|
|||
struct ast_channel *ret=NULL;
|
||||
|
||||
|
||||
p = bridge->pvt->pvt;
|
||||
p = bridge->tech_pvt;
|
||||
if (chan == p->chan)
|
||||
ret = bridge->_bridge;
|
||||
else if (chan == bridge->_bridge)
|
||||
|
@ -806,21 +831,22 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
|
|||
#endif
|
||||
tmp = ast_channel_alloc(0);
|
||||
if (tmp) {
|
||||
tmp->tech = &agent_tech;
|
||||
if (p->chan) {
|
||||
tmp->nativeformats = p->chan->nativeformats;
|
||||
tmp->writeformat = p->chan->writeformat;
|
||||
tmp->pvt->rawwriteformat = p->chan->writeformat;
|
||||
tmp->rawwriteformat = p->chan->writeformat;
|
||||
tmp->readformat = p->chan->readformat;
|
||||
tmp->pvt->rawreadformat = p->chan->readformat;
|
||||
tmp->rawreadformat = p->chan->readformat;
|
||||
strncpy(tmp->language, p->chan->language, sizeof(tmp->language)-1);
|
||||
strncpy(tmp->context, p->chan->context, sizeof(tmp->context)-1);
|
||||
strncpy(tmp->exten, p->chan->exten, sizeof(tmp->exten)-1);
|
||||
} else {
|
||||
tmp->nativeformats = AST_FORMAT_SLINEAR;
|
||||
tmp->writeformat = AST_FORMAT_SLINEAR;
|
||||
tmp->pvt->rawwriteformat = AST_FORMAT_SLINEAR;
|
||||
tmp->rawwriteformat = AST_FORMAT_SLINEAR;
|
||||
tmp->readformat = AST_FORMAT_SLINEAR;
|
||||
tmp->pvt->rawreadformat = AST_FORMAT_SLINEAR;
|
||||
tmp->rawreadformat = AST_FORMAT_SLINEAR;
|
||||
}
|
||||
if (p->pending)
|
||||
snprintf(tmp->name, sizeof(tmp->name), "Agent/P%s-%d", p->agent, rand() & 0xffff);
|
||||
|
@ -829,18 +855,7 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
|
|||
tmp->type = channeltype;
|
||||
/* Safe, agentlock already held */
|
||||
ast_setstate(tmp, state);
|
||||
tmp->pvt->pvt = p;
|
||||
tmp->pvt->send_digit = agent_digit;
|
||||
tmp->pvt->call = agent_call;
|
||||
tmp->pvt->hangup = agent_hangup;
|
||||
tmp->pvt->answer = agent_answer;
|
||||
tmp->pvt->read = agent_read;
|
||||
tmp->pvt->write = agent_write;
|
||||
tmp->pvt->send_html = agent_sendhtml;
|
||||
tmp->pvt->exception = agent_read;
|
||||
tmp->pvt->indicate = agent_indicate;
|
||||
tmp->pvt->fixup = agent_fixup;
|
||||
tmp->pvt->bridged_channel = agent_bridgedchannel;
|
||||
tmp->tech_pvt = p;
|
||||
p->owner = tmp;
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
usecnt++;
|
||||
|
@ -867,7 +882,7 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state)
|
|||
{
|
||||
ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n");
|
||||
p->owner = NULL;
|
||||
tmp->pvt->pvt = NULL;
|
||||
tmp->tech_pvt = NULL;
|
||||
p->app_sleep_cond = 1;
|
||||
ast_channel_free( tmp );
|
||||
ast_mutex_unlock(&p->lock); /* For other thread to read the condition. */
|
||||
|
@ -2092,7 +2107,7 @@ static int agent_devicestate(void *data)
|
|||
int load_module()
|
||||
{
|
||||
/* Make sure we can register our agent channel type */
|
||||
if (ast_channel_register_ex(channeltype, tdesc, capability, agent_request, agent_devicestate)) {
|
||||
if (ast_channel_register(&agent_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
|
||||
return -1;
|
||||
}
|
||||
|
@ -2134,7 +2149,7 @@ int unload_module()
|
|||
/* Unregister manager command */
|
||||
ast_manager_unregister("Agents");
|
||||
/* Unregister channel */
|
||||
ast_channel_unregister(channeltype);
|
||||
ast_channel_unregister(&agent_tech);
|
||||
if (!ast_mutex_lock(&agentlock)) {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
p = agents;
|
||||
|
@ -2168,6 +2183,6 @@ char *key()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/config.h>
|
||||
|
@ -76,10 +75,10 @@ static int silencethreshold = 1000;
|
|||
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
||||
AST_MUTEX_DEFINE_STATIC(alsalock);
|
||||
|
||||
static char *type = "Console";
|
||||
static char *desc = "ALSA Console Channel Driver";
|
||||
static char *tdesc = "ALSA Console Channel Driver";
|
||||
static char *config = "alsa.conf";
|
||||
static const char type[] = "Console";
|
||||
static const char desc[] = "ALSA Console Channel Driver";
|
||||
static const char tdesc[] = "ALSA Console Channel Driver";
|
||||
static const char config[] = "alsa.conf";
|
||||
|
||||
static char context[AST_MAX_EXTENSION] = "default";
|
||||
static char language[MAX_LANGUAGE] = "";
|
||||
|
@ -142,6 +141,34 @@ static int silencelen=0;
|
|||
static int offset=0;
|
||||
static int nosound=0;
|
||||
|
||||
/* ZZ */
|
||||
static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause);
|
||||
static int alsa_digit(struct ast_channel *c, char digit);
|
||||
static int alsa_text(struct ast_channel *c, char *text);
|
||||
static int alsa_hangup(struct ast_channel *c);
|
||||
static int alsa_answer(struct ast_channel *c);
|
||||
static struct ast_frame *alsa_read(struct ast_channel *chan);
|
||||
static int alsa_call(struct ast_channel *c, char *dest, int timeout);
|
||||
static int alsa_write(struct ast_channel *chan, struct ast_frame *f);
|
||||
static int alsa_indicate(struct ast_channel *chan, int cond);
|
||||
static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
|
||||
static const struct ast_channel_tech alsa_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_SLINEAR,
|
||||
.requester = alsa_request,
|
||||
.send_digit = alsa_digit,
|
||||
.send_text = alsa_text,
|
||||
.hangup = alsa_hangup,
|
||||
.answer = alsa_answer,
|
||||
.read = alsa_read,
|
||||
.call = alsa_call,
|
||||
.write = alsa_write,
|
||||
.indicate = alsa_indicate,
|
||||
.fixup = alsa_fixup,
|
||||
};
|
||||
|
||||
static int send_sound(void)
|
||||
{
|
||||
short myframe[FRAME_SIZE];
|
||||
|
@ -520,7 +547,7 @@ static int alsa_hangup(struct ast_channel *c)
|
|||
int res;
|
||||
ast_mutex_lock(&alsalock);
|
||||
cursound = -1;
|
||||
c->pvt->pvt = NULL;
|
||||
c->tech_pvt = NULL;
|
||||
alsa.owner = NULL;
|
||||
ast_verbose( " << Hangup on console >> \n");
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
|
@ -677,7 +704,7 @@ static struct ast_frame *alsa_read(struct ast_channel *chan)
|
|||
|
||||
static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct chan_alsa_pvt *p = newchan->pvt->pvt;
|
||||
struct chan_alsa_pvt *p = newchan->tech_pvt;
|
||||
ast_mutex_lock(&alsalock);
|
||||
p->owner = newchan;
|
||||
ast_mutex_unlock(&alsalock);
|
||||
|
@ -717,22 +744,14 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
|
|||
struct ast_channel *tmp;
|
||||
tmp = ast_channel_alloc(1);
|
||||
if (tmp) {
|
||||
tmp->tech = &alsa_tech;
|
||||
snprintf(tmp->name, sizeof(tmp->name), "ALSA/%s", indevname);
|
||||
tmp->type = type;
|
||||
tmp->fds[0] = readdev;
|
||||
tmp->nativeformats = AST_FORMAT_SLINEAR;
|
||||
tmp->readformat = AST_FORMAT_SLINEAR;
|
||||
tmp->writeformat = AST_FORMAT_SLINEAR;
|
||||
tmp->pvt->pvt = p;
|
||||
tmp->pvt->send_digit = alsa_digit;
|
||||
tmp->pvt->send_text = alsa_text;
|
||||
tmp->pvt->hangup = alsa_hangup;
|
||||
tmp->pvt->answer = alsa_answer;
|
||||
tmp->pvt->read = alsa_read;
|
||||
tmp->pvt->call = alsa_call;
|
||||
tmp->pvt->write = alsa_write;
|
||||
tmp->pvt->indicate = alsa_indicate;
|
||||
tmp->pvt->fixup = alsa_fixup;
|
||||
tmp->tech_pvt = p;
|
||||
if (strlen(p->context))
|
||||
strncpy(tmp->context, p->context, sizeof(tmp->context)-1);
|
||||
if (strlen(p->exten))
|
||||
|
@ -1027,7 +1046,7 @@ int load_module()
|
|||
return 0;
|
||||
}
|
||||
|
||||
res = ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR, alsa_request);
|
||||
res = ast_channel_register(&alsa_tech);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", type);
|
||||
return -1;
|
||||
|
@ -1048,6 +1067,8 @@ int load_module()
|
|||
int unload_module()
|
||||
{
|
||||
int x;
|
||||
|
||||
ast_channel_unregister(&alsa_tech);
|
||||
for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
|
||||
ast_cli_unregister(myclis + x);
|
||||
close(readdev);
|
||||
|
@ -1065,7 +1086,7 @@ int unload_module()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
int usecount()
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -42,11 +41,9 @@
|
|||
#include <sys/signal.h>
|
||||
|
||||
|
||||
static char *desc = "Feature Proxy Channel";
|
||||
static char *type = "Feature";
|
||||
static char *tdesc = "Feature Proxy Channel Driver";
|
||||
|
||||
static int capability = -1;
|
||||
static const char desc[] = "Feature Proxy Channel";
|
||||
static const char type[] = "Feature";
|
||||
static const char tdesc[] = "Feature Proxy Channel Driver";
|
||||
|
||||
static int usecnt =0;
|
||||
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
||||
|
@ -78,6 +75,32 @@ static struct feature_pvt {
|
|||
#define SUB_CALLWAIT 1 /* Call-Waiting call on hold */
|
||||
#define SUB_THREEWAY 2 /* Three-way call */
|
||||
|
||||
static struct ast_channel *features_request(const char *type, int format, void *data, int *cause);
|
||||
static int features_digit(struct ast_channel *ast, char digit);
|
||||
static int features_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int features_hangup(struct ast_channel *ast);
|
||||
static int features_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *features_read(struct ast_channel *ast);
|
||||
static int features_write(struct ast_channel *ast, struct ast_frame *f);
|
||||
static int features_indicate(struct ast_channel *ast, int condition);
|
||||
static int features_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
|
||||
static const struct ast_channel_tech features_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = -1,
|
||||
.requester = features_request,
|
||||
.send_digit = features_digit,
|
||||
.call = features_call,
|
||||
.hangup = features_hangup,
|
||||
.answer = features_answer,
|
||||
.read = features_read,
|
||||
.write = features_write,
|
||||
.exception = features_read,
|
||||
.indicate = features_indicate,
|
||||
.fixup = features_fixup,
|
||||
};
|
||||
|
||||
static inline void init_sub(struct feature_sub *sub)
|
||||
{
|
||||
sub->inthreeway = 0;
|
||||
|
@ -123,8 +146,8 @@ static void restore_channel(struct feature_pvt *p, int index)
|
|||
{
|
||||
/* Restore timing/alertpipe */
|
||||
p->subs[index].owner->timingfd = p->subs[index].timingfdbackup;
|
||||
p->subs[index].owner->pvt->alertpipe[0] = p->subs[index].alertpipebackup[0];
|
||||
p->subs[index].owner->pvt->alertpipe[1] = p->subs[index].alertpipebackup[1];
|
||||
p->subs[index].owner->alertpipe[0] = p->subs[index].alertpipebackup[0];
|
||||
p->subs[index].owner->alertpipe[1] = p->subs[index].alertpipebackup[1];
|
||||
p->subs[index].owner->fds[AST_MAX_FDS-1] = p->subs[index].alertpipebackup[0];
|
||||
p->subs[index].owner->fds[AST_MAX_FDS-2] = p->subs[index].timingfdbackup;
|
||||
}
|
||||
|
@ -142,8 +165,8 @@ static void update_features(struct feature_pvt *p, int index)
|
|||
if (!index) {
|
||||
/* Copy timings from master channel */
|
||||
p->subs[index].owner->timingfd = p->subchan->timingfd;
|
||||
p->subs[index].owner->pvt->alertpipe[0] = p->subchan->pvt->alertpipe[0];
|
||||
p->subs[index].owner->pvt->alertpipe[1] = p->subchan->pvt->alertpipe[1];
|
||||
p->subs[index].owner->alertpipe[0] = p->subchan->alertpipe[0];
|
||||
p->subs[index].owner->alertpipe[1] = p->subchan->alertpipe[1];
|
||||
if (p->subs[index].owner->nativeformats != p->subchan->readformat) {
|
||||
p->subs[index].owner->nativeformats = p->subchan->readformat;
|
||||
if (p->subs[index].owner->readformat)
|
||||
|
@ -180,7 +203,7 @@ static void swap_subs(struct feature_pvt *p, int a, int b)
|
|||
|
||||
static int features_answer(struct ast_channel *ast)
|
||||
{
|
||||
struct feature_pvt *p = ast->pvt->pvt;
|
||||
struct feature_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
int x;
|
||||
ast_mutex_lock(&p->lock);
|
||||
|
@ -194,7 +217,7 @@ static int features_answer(struct ast_channel *ast)
|
|||
static struct ast_frame *features_read(struct ast_channel *ast)
|
||||
{
|
||||
static struct ast_frame null_frame = { AST_FRAME_NULL, };
|
||||
struct feature_pvt *p = ast->pvt->pvt;
|
||||
struct feature_pvt *p = ast->tech_pvt;
|
||||
struct ast_frame *f;
|
||||
int x;
|
||||
|
||||
|
@ -211,7 +234,7 @@ static struct ast_frame *features_read(struct ast_channel *ast)
|
|||
|
||||
static int features_write(struct ast_channel *ast, struct ast_frame *f)
|
||||
{
|
||||
struct feature_pvt *p = ast->pvt->pvt;
|
||||
struct feature_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
int x;
|
||||
ast_mutex_lock(&p->lock);
|
||||
|
@ -224,7 +247,7 @@ static int features_write(struct ast_channel *ast, struct ast_frame *f)
|
|||
|
||||
static int features_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct feature_pvt *p = newchan->pvt->pvt;
|
||||
struct feature_pvt *p = newchan->tech_pvt;
|
||||
int x;
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (p->owner == oldchan)
|
||||
|
@ -239,7 +262,7 @@ static int features_fixup(struct ast_channel *oldchan, struct ast_channel *newch
|
|||
|
||||
static int features_indicate(struct ast_channel *ast, int condition)
|
||||
{
|
||||
struct feature_pvt *p = ast->pvt->pvt;
|
||||
struct feature_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
int x;
|
||||
/* Queue up a frame representing the indication as a control frame */
|
||||
|
@ -253,7 +276,7 @@ static int features_indicate(struct ast_channel *ast, int condition)
|
|||
|
||||
static int features_digit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
struct feature_pvt *p = ast->pvt->pvt;
|
||||
struct feature_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
int x;
|
||||
/* Queue up a frame representing the indication as a control frame */
|
||||
|
@ -267,7 +290,7 @@ static int features_digit(struct ast_channel *ast, char digit)
|
|||
|
||||
static int features_call(struct ast_channel *ast, char *dest, int timeout)
|
||||
{
|
||||
struct feature_pvt *p = ast->pvt->pvt;
|
||||
struct feature_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
int x;
|
||||
char *dest2;
|
||||
|
@ -311,7 +334,7 @@ static int features_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
|
||||
static int features_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct feature_pvt *p = ast->pvt->pvt;
|
||||
struct feature_pvt *p = ast->tech_pvt;
|
||||
struct feature_pvt *cur, *prev=NULL;
|
||||
int x;
|
||||
|
||||
|
@ -322,7 +345,7 @@ static int features_hangup(struct ast_channel *ast)
|
|||
p->subs[x].owner = NULL;
|
||||
/* XXX Re-arrange, unconference, etc XXX */
|
||||
}
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
|
||||
|
||||
if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
|
||||
|
@ -425,6 +448,7 @@ static struct ast_channel *features_new(struct feature_pvt *p, int state, int in
|
|||
if (!tmp)
|
||||
return NULL;
|
||||
if (tmp) {
|
||||
tmp->tech = &features_tech;
|
||||
for (x=1;x<4;x++) {
|
||||
snprintf(tmp->name, sizeof(tmp->name), "Feature/%s/%s-%d", p->tech, p->dest, x);
|
||||
for (y=0;y<3;y++) {
|
||||
|
@ -438,21 +462,12 @@ static struct ast_channel *features_new(struct feature_pvt *p, int state, int in
|
|||
}
|
||||
tmp->type = type;
|
||||
ast_setstate(tmp, state);
|
||||
tmp->writeformat = p->subchan->writeformat;;
|
||||
tmp->pvt->rawwriteformat = p->subchan->pvt->rawwriteformat;
|
||||
tmp->writeformat = p->subchan->writeformat;
|
||||
tmp->rawwriteformat = p->subchan->rawwriteformat;
|
||||
tmp->readformat = p->subchan->readformat;
|
||||
tmp->pvt->rawreadformat = p->subchan->pvt->rawreadformat;
|
||||
tmp->rawreadformat = p->subchan->rawreadformat;
|
||||
tmp->nativeformats = p->subchan->readformat;
|
||||
tmp->pvt->pvt = p;
|
||||
tmp->pvt->send_digit = features_digit;
|
||||
tmp->pvt->call = features_call;
|
||||
tmp->pvt->hangup = features_hangup;
|
||||
tmp->pvt->answer = features_answer;
|
||||
tmp->pvt->read = features_read;
|
||||
tmp->pvt->write = features_write;
|
||||
tmp->pvt->exception = features_read;
|
||||
tmp->pvt->indicate = features_indicate;
|
||||
tmp->pvt->fixup = features_fixup;
|
||||
tmp->tech_pvt = p;
|
||||
p->subs[index].owner = tmp;
|
||||
if (!p->owner)
|
||||
p->owner = tmp;
|
||||
|
@ -509,7 +524,7 @@ static struct ast_cli_entry cli_show_features = {
|
|||
int load_module()
|
||||
{
|
||||
/* Make sure we can register our sip channel type */
|
||||
if (ast_channel_register(type, tdesc, capability, features_request)) {
|
||||
if (ast_channel_register(&features_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
return -1;
|
||||
}
|
||||
|
@ -527,7 +542,7 @@ int unload_module()
|
|||
struct feature_pvt *p;
|
||||
/* First, take us out of the channel loop */
|
||||
ast_cli_unregister(&cli_show_features);
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(&features_tech);
|
||||
if (!ast_mutex_lock(&featurelock)) {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
p = features;
|
||||
|
@ -561,6 +576,6 @@ char *key()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ extern "C" {
|
|||
#include <asterisk/lock.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/pbx.h>
|
||||
|
@ -88,10 +87,10 @@ rfc2833_cb on_set_rfc2833_payload;
|
|||
int h323debug;
|
||||
|
||||
/** Variables required by Asterisk */
|
||||
static char *type = "H323";
|
||||
static char *desc = "The NuFone Network's Open H.323 Channel Driver";
|
||||
static char *tdesc = "The NuFone Network's Open H.323 Channel Driver";
|
||||
static char *config = "h323.conf";
|
||||
static const char type[] = "H323";
|
||||
static const char desc[] = "The NuFone Network's Open H.323 Channel Driver";
|
||||
static const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver";
|
||||
static const char config[] = "h323.conf";
|
||||
static char default_context[AST_MAX_EXTENSION] = "default";
|
||||
static struct sockaddr_in bindaddr;
|
||||
|
||||
|
@ -184,6 +183,35 @@ static pthread_t monitor_thread = AST_PTHREADT_NULL;
|
|||
static int restart_monitor(void);
|
||||
static int h323_do_reload(void);
|
||||
|
||||
static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause);
|
||||
static int oh323_digit(struct ast_channel *c, char digit);
|
||||
static int oh323_call(struct ast_channel *c, char *dest, int timeout);
|
||||
static int oh323_hangup(struct ast_channel *c);
|
||||
static int oh323_answer(struct ast_channel *c);
|
||||
static struct ast_frame *oh323_read(struct ast_channel *c);
|
||||
static int oh323_write(struct ast_channel *c, struct ast_frame *frame);
|
||||
static int oh323_indicate(struct ast_channel *c, int condition);
|
||||
static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
|
||||
static const struct ast_channel_tech oh323_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_ULAW,
|
||||
.requester = oh323_request,
|
||||
.send_digit = oh323_digit,
|
||||
.call = oh323_call,
|
||||
.hangup = oh323_hangup,
|
||||
.answer = oh323_answer,
|
||||
.read = oh323_read,
|
||||
.write = oh323_write,
|
||||
.indicate = oh323_indicate,
|
||||
.fixup = oh323_fixup,
|
||||
/* disable, for now */
|
||||
#if 0
|
||||
.bridge = ast_rtp_bridge,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void __oh323_destroy(struct oh323_pvt *p)
|
||||
{
|
||||
struct oh323_pvt *cur, *prev = NULL;
|
||||
|
@ -196,7 +224,7 @@ static void __oh323_destroy(struct oh323_pvt *p)
|
|||
if (p->owner) {
|
||||
ast_mutex_lock(&p->owner->lock);
|
||||
ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
|
||||
p->owner->pvt->pvt = NULL;
|
||||
p->owner->tech_pvt = NULL;
|
||||
ast_mutex_unlock(&p->owner->lock);
|
||||
}
|
||||
cur = iflist;
|
||||
|
@ -464,7 +492,7 @@ static struct oh323_peer *build_peer(char *name, struct ast_variable *v)
|
|||
*/
|
||||
static int oh323_digit(struct ast_channel *c, char digit)
|
||||
{
|
||||
struct oh323_pvt *p = (struct oh323_pvt *) c->pvt->pvt;
|
||||
struct oh323_pvt *p = (struct oh323_pvt *) c->tech_pvt;
|
||||
if (p && p->rtp && (p->dtmfmode & H323_DTMF_RFC2833)) {
|
||||
ast_rtp_senddigit(p->rtp, digit);
|
||||
}
|
||||
|
@ -483,7 +511,7 @@ static int oh323_digit(struct ast_channel *c, char digit)
|
|||
static int oh323_call(struct ast_channel *c, char *dest, int timeout)
|
||||
{
|
||||
int res = 0;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *)c->pvt->pvt;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
|
||||
char addr[INET_ADDRSTRLEN];
|
||||
char called_addr[1024];
|
||||
|
||||
|
@ -528,7 +556,7 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
|
|||
static int oh323_answer(struct ast_channel *c)
|
||||
{
|
||||
int res;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) c->pvt->pvt;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
|
||||
|
||||
res = h323_answering_call(pvt->cd.call_token, 0);
|
||||
|
||||
|
@ -540,11 +568,11 @@ static int oh323_answer(struct ast_channel *c)
|
|||
|
||||
static int oh323_hangup(struct ast_channel *c)
|
||||
{
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) c->pvt->pvt;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
|
||||
int needcancel = 0;
|
||||
int q931cause = AST_CAUSE_NORMAL_CLEARING;
|
||||
|
||||
if (!c->pvt->pvt) {
|
||||
if (!c->tech_pvt) {
|
||||
ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -558,14 +586,14 @@ static int oh323_hangup(struct ast_channel *c)
|
|||
if (!c || (c->_state != AST_STATE_UP)) {
|
||||
needcancel = 1;
|
||||
}
|
||||
pvt = (struct oh323_pvt *)c->pvt->pvt;
|
||||
pvt = (struct oh323_pvt *)c->tech_pvt;
|
||||
|
||||
/* Free dsp used for in-band DTMF detection */
|
||||
if (pvt->vad) {
|
||||
ast_dsp_free(pvt->vad);
|
||||
}
|
||||
pvt->owner = NULL;
|
||||
c->pvt->pvt = NULL;
|
||||
c->tech_pvt = NULL;
|
||||
|
||||
if (c->hangupcause) {
|
||||
q931cause = c->hangupcause;
|
||||
|
@ -648,7 +676,7 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
|
|||
static struct ast_frame *oh323_read(struct ast_channel *c)
|
||||
{
|
||||
struct ast_frame *fr;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *)c->pvt->pvt;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
|
||||
ast_mutex_lock(&pvt->lock);
|
||||
fr = oh323_rtp_read(pvt);
|
||||
ast_mutex_unlock(&pvt->lock);
|
||||
|
@ -657,7 +685,7 @@ static struct ast_frame *oh323_read(struct ast_channel *c)
|
|||
|
||||
static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
|
||||
{
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) c->pvt->pvt;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
|
||||
int res = 0;
|
||||
if (frame->frametype != AST_FRAME_VOICE) {
|
||||
if (frame->frametype == AST_FRAME_IMAGE) {
|
||||
|
@ -686,7 +714,7 @@ static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
|
|||
static int oh323_indicate(struct ast_channel *c, int condition)
|
||||
{
|
||||
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) c->pvt->pvt;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
|
||||
|
||||
ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, pvt->cd.call_token);
|
||||
|
||||
|
@ -733,7 +761,7 @@ static int oh323_indicate(struct ast_channel *c, int condition)
|
|||
|
||||
static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->pvt->pvt;
|
||||
struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt;
|
||||
|
||||
ast_mutex_lock(&pvt->lock);
|
||||
if (pvt->owner != oldchan) {
|
||||
|
@ -760,6 +788,7 @@ static struct ast_channel *oh323_new(struct oh323_pvt *pvt, int state, const cha
|
|||
ast_update_use_count();
|
||||
ast_mutex_lock(&pvt->lock);
|
||||
if (ch) {
|
||||
tmp->tech = &oh323_tech;
|
||||
snprintf(ch->name, sizeof(ch->name), "H323/%s", host);
|
||||
ch->nativeformats = pvt->capability;
|
||||
if (!ch->nativeformats) {
|
||||
|
@ -772,28 +801,16 @@ static struct ast_channel *oh323_new(struct oh323_pvt *pvt, int state, const cha
|
|||
ch->rings = 1;
|
||||
}
|
||||
ch->writeformat = fmt;
|
||||
ch->pvt->rawwriteformat = fmt;
|
||||
ch->rawwriteformat = fmt;
|
||||
ch->readformat = fmt;
|
||||
ch->pvt->rawreadformat = fmt;
|
||||
ch->rawreadformat = fmt;
|
||||
/* Allocate dsp for in-band DTMF support */
|
||||
if (pvt->dtmfmode & H323_DTMF_INBAND) {
|
||||
pvt->vad = ast_dsp_new();
|
||||
ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT);
|
||||
}
|
||||
/* Register channel functions. */
|
||||
ch->pvt->pvt = pvt;
|
||||
ch->pvt->send_digit = oh323_digit;
|
||||
ch->pvt->call = oh323_call;
|
||||
ch->pvt->hangup = oh323_hangup;
|
||||
ch->pvt->answer = oh323_answer;
|
||||
ch->pvt->read = oh323_read;
|
||||
ch->pvt->write = oh323_write;
|
||||
ch->pvt->indicate = oh323_indicate;
|
||||
ch->pvt->fixup = oh323_fixup;
|
||||
/* disable, for now */
|
||||
#if 0
|
||||
ch->pvt->bridge = ast_rtp_bridge;
|
||||
#endif
|
||||
ch->tech_pvt = pvt;
|
||||
/* Set the owner of this channel */
|
||||
pvt->owner = ch;
|
||||
|
||||
|
@ -1990,7 +2007,7 @@ static struct ast_cli_entry cli_h323_reload =
|
|||
static struct ast_rtp *oh323_get_rtp_peer(struct ast_channel *chan)
|
||||
{
|
||||
struct oh323_pvt *p;
|
||||
p = (struct oh323_pvt *) chan->pvt->pvt;
|
||||
p = (struct oh323_pvt *) chan->tech_pvt;
|
||||
if (p && p->rtp && p->bridge) {
|
||||
return p->rtp;
|
||||
}
|
||||
|
@ -2041,7 +2058,7 @@ static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, str
|
|||
}
|
||||
|
||||
mode = convertcap(chan->writeformat);
|
||||
p = (struct oh323_pvt *) chan->pvt->pvt;
|
||||
p = (struct oh323_pvt *) chan->tech_pvt;
|
||||
if (!p) {
|
||||
ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
|
||||
return -1;
|
||||
|
@ -2053,9 +2070,10 @@ static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, str
|
|||
}
|
||||
|
||||
static struct ast_rtp_protocol oh323_rtp = {
|
||||
get_rtp_info: oh323_get_rtp_peer,
|
||||
get_vrtp_info: oh323_get_vrtp_peer,
|
||||
set_rtp_peer: oh323_set_rtp_peer,
|
||||
.type = type,
|
||||
.get_rtp_info = oh323_get_rtp_peer,
|
||||
.get_vrtp_info = oh323_get_vrtp_peer,
|
||||
.set_rtp_peer= oh323_set_rtp_peer,
|
||||
};
|
||||
|
||||
int load_module()
|
||||
|
@ -2077,7 +2095,7 @@ int load_module()
|
|||
return 0;
|
||||
} else {
|
||||
/* Make sure we can register our channel type */
|
||||
if (ast_channel_register(type, tdesc, capability, oh323_request)) {
|
||||
if (ast_channel_register(&oh323_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
h323_end_process();
|
||||
return -1;
|
||||
|
@ -2092,7 +2110,6 @@ int load_module()
|
|||
ast_cli_register(&cli_show_tokens);
|
||||
ast_cli_register(&cli_h323_reload);
|
||||
|
||||
oh323_rtp.type = type;
|
||||
ast_rtp_proto_register(&oh323_rtp);
|
||||
|
||||
/* Register our callback functions */
|
||||
|
@ -2140,7 +2157,7 @@ int unload_module()
|
|||
ast_cli_unregister(&cli_show_tokens);
|
||||
ast_cli_unregister(&cli_h323_reload);
|
||||
ast_rtp_proto_unregister(&oh323_rtp);
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(&oh323_tech);
|
||||
|
||||
if (!ast_mutex_lock(&iflock)) {
|
||||
/* hangup all interfaces if they have an owner */
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <asterisk/lock.h>
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/pbx.h>
|
||||
|
@ -102,9 +101,9 @@
|
|||
|
||||
static struct ast_codec_pref prefs;
|
||||
|
||||
static char *desc = "Inter Asterisk eXchange (Ver 2)";
|
||||
static char *tdesc = "Inter Asterisk eXchange Driver (Ver 2)";
|
||||
static char *channeltype = "IAX2";
|
||||
static const char desc[] = "Inter Asterisk eXchange (Ver 2)";
|
||||
static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
|
||||
static const char channeltype[] = "IAX2";
|
||||
|
||||
static char context[80] = "default";
|
||||
|
||||
|
@ -609,6 +608,45 @@ static void prune_peers(void);
|
|||
static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
|
||||
static int iax2_provision(struct sockaddr_in *end, char *dest, const char *template, int force);
|
||||
|
||||
static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
|
||||
static int iax2_devicestate(void *data);
|
||||
static int iax2_digit(struct ast_channel *c, char digit);
|
||||
static int iax2_sendtext(struct ast_channel *c, char *text);
|
||||
static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
|
||||
static int iax2_sendhtml(struct ast_channel *c, int subclass, char *data, int datalen);
|
||||
static int iax2_call(struct ast_channel *c, char *dest, int timeout);
|
||||
static int iax2_hangup(struct ast_channel *c);
|
||||
static int iax2_answer(struct ast_channel *c);
|
||||
static struct ast_frame *iax2_read(struct ast_channel *c);
|
||||
static int iax2_write(struct ast_channel *c, struct ast_frame *f);
|
||||
static int iax2_indicate(struct ast_channel *c, int condition);
|
||||
static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
|
||||
static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
|
||||
static int iax2_transfer(struct ast_channel *c, char *dest);
|
||||
static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
|
||||
|
||||
static const struct ast_channel_tech iax2_tech = {
|
||||
.type = channeltype,
|
||||
.description = tdesc,
|
||||
.capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
|
||||
.requester = iax2_request,
|
||||
.devicestate = iax2_devicestate,
|
||||
.send_digit = iax2_digit,
|
||||
.send_text = iax2_sendtext,
|
||||
.send_image = iax2_sendimage,
|
||||
.send_html = iax2_sendhtml,
|
||||
.call = iax2_call,
|
||||
.hangup = iax2_hangup,
|
||||
.answer = iax2_answer,
|
||||
.read = iax2_read,
|
||||
.write = iax2_write,
|
||||
.write_video = iax2_write,
|
||||
.indicate = iax2_indicate,
|
||||
.setoption = iax2_setoption,
|
||||
.bridge = iax2_bridge,
|
||||
.transfer = iax2_transfer,
|
||||
.fixup = iax2_fixup,
|
||||
};
|
||||
|
||||
static int send_ping(void *data)
|
||||
{
|
||||
|
@ -1410,7 +1448,7 @@ static int iax2_predestroy(int callno)
|
|||
c = pvt->owner;
|
||||
if (c) {
|
||||
c->_softhangup |= AST_SOFTHANGUP_DEV;
|
||||
c->pvt->pvt = NULL;
|
||||
c->tech_pvt = NULL;
|
||||
ast_queue_hangup(c);
|
||||
pvt->owner = NULL;
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
|
@ -2174,29 +2212,29 @@ static int iax2_transmit(struct iax_frame *fr)
|
|||
|
||||
static int iax2_digit(struct ast_channel *c, char digit)
|
||||
{
|
||||
return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
|
||||
return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
|
||||
}
|
||||
|
||||
static int iax2_sendtext(struct ast_channel *c, char *text)
|
||||
{
|
||||
|
||||
return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_TEXT,
|
||||
return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
|
||||
0, 0, text, strlen(text) + 1, -1);
|
||||
}
|
||||
|
||||
static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
|
||||
{
|
||||
return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
|
||||
return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
|
||||
}
|
||||
|
||||
static int iax2_sendhtml(struct ast_channel *c, int subclass, char *data, int datalen)
|
||||
{
|
||||
return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_HTML, subclass, 0, data, datalen, -1);
|
||||
return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, data, datalen, -1);
|
||||
}
|
||||
|
||||
static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
|
||||
{
|
||||
unsigned short callno = PTR_TO_CALLNO(newchan->pvt->pvt);
|
||||
unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
|
||||
ast_mutex_lock(&iaxsl[callno]);
|
||||
if (iaxs[callno])
|
||||
iaxs[callno]->owner = newchan;
|
||||
|
@ -2487,7 +2525,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
|
|||
char *portno = NULL;
|
||||
char *opts = "";
|
||||
int encmethods=iax2_encryption;
|
||||
unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
|
||||
unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
|
||||
char *stringp=NULL;
|
||||
char storedusern[80], storedsecret[80];
|
||||
char tz[80] = "";
|
||||
|
@ -2629,7 +2667,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
|
|||
|
||||
static int iax2_hangup(struct ast_channel *c)
|
||||
{
|
||||
unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
|
||||
unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
|
||||
int alreadygone;
|
||||
struct iax_ie_data ied;
|
||||
memset(&ied, 0, sizeof(ied));
|
||||
|
@ -2664,7 +2702,7 @@ static int iax2_setoption(struct ast_channel *c, int option, void *data, int dat
|
|||
h->flag = AST_OPTION_FLAG_REQUEST;
|
||||
h->option = htons(option);
|
||||
memcpy(h->data, data, datalen);
|
||||
res = send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_CONTROL,
|
||||
res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
|
||||
AST_CONTROL_OPTION, 0, (char *)h, datalen + sizeof(struct ast_option_header), -1);
|
||||
free(h);
|
||||
return res;
|
||||
|
@ -2731,8 +2769,8 @@ static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags
|
|||
int res = -1;
|
||||
int transferstarted=0;
|
||||
struct ast_frame *f;
|
||||
unsigned short callno0 = PTR_TO_CALLNO(c0->pvt->pvt);
|
||||
unsigned short callno1 = PTR_TO_CALLNO(c1->pvt->pvt);
|
||||
unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
|
||||
unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
|
||||
struct timeval waittimer = {0, 0}, tv;
|
||||
|
||||
lock_both(callno0, callno1);
|
||||
|
@ -2884,7 +2922,7 @@ tackygoto:
|
|||
|
||||
static int iax2_answer(struct ast_channel *c)
|
||||
{
|
||||
unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
|
||||
unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Answering\n");
|
||||
return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
|
||||
|
@ -2892,7 +2930,7 @@ static int iax2_answer(struct ast_channel *c)
|
|||
|
||||
static int iax2_indicate(struct ast_channel *c, int condition)
|
||||
{
|
||||
unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
|
||||
unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
|
||||
return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
|
||||
|
@ -2900,7 +2938,7 @@ static int iax2_indicate(struct ast_channel *c, int condition)
|
|||
|
||||
static int iax2_transfer(struct ast_channel *c, char *dest)
|
||||
{
|
||||
unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
|
||||
unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
|
||||
struct iax_ie_data ied;
|
||||
char tmp[256] = "", *context;
|
||||
strncpy(tmp, dest, sizeof(tmp) - 1);
|
||||
|
@ -2952,6 +2990,7 @@ static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
|
|||
ast_mutex_lock(&iaxsl[callno]);
|
||||
i = iaxs[callno];
|
||||
if (i && tmp) {
|
||||
tmp->tech = &iax2_tech;
|
||||
if (!ast_strlen_zero(i->username))
|
||||
snprintf(tmp->name, sizeof(tmp->name), "IAX2/%s@%s-%d", i->username, i->host, i->callno);
|
||||
else
|
||||
|
@ -2961,21 +3000,8 @@ static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
|
|||
tmp->nativeformats = capability;
|
||||
tmp->readformat = ast_best_codec(capability);
|
||||
tmp->writeformat = ast_best_codec(capability);
|
||||
tmp->pvt->pvt = CALLNO_TO_PTR(i->callno);
|
||||
tmp->pvt->send_digit = iax2_digit;
|
||||
tmp->pvt->send_text = iax2_sendtext;
|
||||
tmp->pvt->send_image = iax2_sendimage;
|
||||
tmp->pvt->send_html = iax2_sendhtml;
|
||||
tmp->pvt->call = iax2_call;
|
||||
tmp->pvt->hangup = iax2_hangup;
|
||||
tmp->pvt->answer = iax2_answer;
|
||||
tmp->pvt->read = iax2_read;
|
||||
tmp->pvt->write = iax2_write;
|
||||
tmp->pvt->write_video = iax2_write;
|
||||
tmp->pvt->indicate = iax2_indicate;
|
||||
tmp->pvt->setoption = iax2_setoption;
|
||||
tmp->pvt->bridge = iax2_bridge;
|
||||
tmp->pvt->transfer = iax2_transfer;
|
||||
tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
|
||||
|
||||
if (!ast_strlen_zero(i->cid_num))
|
||||
tmp->cid.cid_num = strdup(i->cid_num);
|
||||
if (!ast_strlen_zero(i->cid_name))
|
||||
|
@ -2996,7 +3022,6 @@ static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
|
|||
strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
|
||||
strncpy(tmp->exten, i->exten, sizeof(tmp->exten)-1);
|
||||
tmp->adsicpe = i->peeradsicpe;
|
||||
tmp->pvt->fixup = iax2_fixup;
|
||||
i->owner = tmp;
|
||||
i->capability = capability;
|
||||
ast_setstate(tmp, state);
|
||||
|
@ -4065,7 +4090,7 @@ static struct ast_cli_entry cli_no_debug =
|
|||
|
||||
static int iax2_write(struct ast_channel *c, struct ast_frame *f)
|
||||
{
|
||||
unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
|
||||
unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
|
||||
int res = -1;
|
||||
ast_mutex_lock(&iaxsl[callno]);
|
||||
if (iaxs[callno]) {
|
||||
|
@ -6999,7 +7024,7 @@ static int iax2_prov_app(struct ast_channel *chan, void *data)
|
|||
char *sdata;
|
||||
char *opts;
|
||||
int force =0;
|
||||
unsigned short callno = PTR_TO_CALLNO(chan->pvt->pvt);
|
||||
unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
|
||||
char iabuf[INET_ADDRSTRLEN];
|
||||
if (!data || ast_strlen_zero(data))
|
||||
data = "default";
|
||||
|
@ -8427,7 +8452,7 @@ static int __unload_module(void)
|
|||
ast_cli_unregister(&cli_show_peer);
|
||||
ast_cli_unregister(&cli_prune_realtime);
|
||||
ast_unregister_switch(&iax2_switch);
|
||||
ast_channel_unregister(channeltype);
|
||||
ast_channel_unregister(&iax2_tech);
|
||||
delete_users();
|
||||
iax_provision_unload();
|
||||
return 0;
|
||||
|
@ -8516,7 +8541,7 @@ int load_module(void)
|
|||
|
||||
set_config(config, 0);
|
||||
|
||||
if (ast_channel_register_ex(channeltype, tdesc, iax2_capability, iax2_request, iax2_devicestate)) {
|
||||
if (ast_channel_register(&iax2_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
|
||||
__unload_module();
|
||||
return -1;
|
||||
|
@ -8560,7 +8585,7 @@ int load_module(void)
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
int usecount()
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -41,11 +40,9 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
static char *desc = "Local Proxy Channel";
|
||||
static char *type = "Local";
|
||||
static char *tdesc = "Local Proxy Channel Driver";
|
||||
|
||||
static int capability = -1;
|
||||
static const char desc[] = "Local Proxy Channel";
|
||||
static const char type[] = "Local";
|
||||
static const char tdesc[] = "Local Proxy Channel Driver";
|
||||
|
||||
static int usecnt =0;
|
||||
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
||||
|
@ -55,6 +52,34 @@ AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
|||
/* Protect the interface list (of sip_pvt's) */
|
||||
AST_MUTEX_DEFINE_STATIC(locallock);
|
||||
|
||||
static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
|
||||
static int local_digit(struct ast_channel *ast, char digit);
|
||||
static int local_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int local_hangup(struct ast_channel *ast);
|
||||
static int local_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *local_read(struct ast_channel *ast);
|
||||
static int local_write(struct ast_channel *ast, struct ast_frame *f);
|
||||
static int local_indicate(struct ast_channel *ast, int condition);
|
||||
static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
static int local_sendhtml(struct ast_channel *ast, int subclass, char *data, int datalen);
|
||||
|
||||
static const struct ast_channel_tech local_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = -1,
|
||||
.requester = local_request,
|
||||
.send_digit = local_digit,
|
||||
.call = local_call,
|
||||
.hangup = local_hangup,
|
||||
.answer = local_answer,
|
||||
.read = local_read,
|
||||
.write = local_write,
|
||||
.exception = local_read,
|
||||
.indicate = local_indicate,
|
||||
.fixup = local_fixup,
|
||||
.send_html = local_sendhtml,
|
||||
};
|
||||
|
||||
static struct local_pvt {
|
||||
ast_mutex_t lock; /* Channel private lock */
|
||||
char context[AST_MAX_EXTENSION]; /* Context to call */
|
||||
|
@ -120,7 +145,7 @@ retrylock:
|
|||
|
||||
static int local_answer(struct ast_channel *ast)
|
||||
{
|
||||
struct local_pvt *p = ast->pvt->pvt;
|
||||
struct local_pvt *p = ast->tech_pvt;
|
||||
int isoutbound;
|
||||
int res = -1;
|
||||
ast_mutex_lock(&p->lock);
|
||||
|
@ -139,7 +164,7 @@ static void check_bridge(struct local_pvt *p, int isoutbound)
|
|||
{
|
||||
if (p->alreadymasqed || p->nooptimization)
|
||||
return;
|
||||
if (isoutbound && p->chan && p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */ && p->owner && !p->owner->pvt->readq) {
|
||||
if (isoutbound && p->chan && p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */ && p->owner && !p->owner->readq) {
|
||||
/* Masquerade bridged channel into owner */
|
||||
/* Lock everything we need, one by one, and give up if
|
||||
we can't get everything. Remember, we'll get another
|
||||
|
@ -152,7 +177,7 @@ static void check_bridge(struct local_pvt *p, int isoutbound)
|
|||
}
|
||||
ast_mutex_unlock(&(p->chan->_bridge)->lock);
|
||||
}
|
||||
} else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && !p->chan->pvt->readq) {
|
||||
} else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && !p->chan->readq) {
|
||||
/* Masquerade bridged channel into chan */
|
||||
if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
|
||||
if (!ast_mutex_trylock(&p->chan->lock)) {
|
||||
|
@ -173,7 +198,7 @@ static struct ast_frame *local_read(struct ast_channel *ast)
|
|||
|
||||
static int local_write(struct ast_channel *ast, struct ast_frame *f)
|
||||
{
|
||||
struct local_pvt *p = ast->pvt->pvt;
|
||||
struct local_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
int isoutbound;
|
||||
|
||||
|
@ -189,7 +214,7 @@ static int local_write(struct ast_channel *ast, struct ast_frame *f)
|
|||
|
||||
static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct local_pvt *p = newchan->pvt->pvt;
|
||||
struct local_pvt *p = newchan->tech_pvt;
|
||||
ast_mutex_lock(&p->lock);
|
||||
if ((p->owner != oldchan) && (p->chan != oldchan)) {
|
||||
ast_log(LOG_WARNING, "old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
|
||||
|
@ -206,7 +231,7 @@ static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
|||
|
||||
static int local_indicate(struct ast_channel *ast, int condition)
|
||||
{
|
||||
struct local_pvt *p = ast->pvt->pvt;
|
||||
struct local_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
struct ast_frame f = { AST_FRAME_CONTROL, };
|
||||
int isoutbound;
|
||||
|
@ -221,7 +246,7 @@ static int local_indicate(struct ast_channel *ast, int condition)
|
|||
|
||||
static int local_digit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
struct local_pvt *p = ast->pvt->pvt;
|
||||
struct local_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
struct ast_frame f = { AST_FRAME_DTMF, };
|
||||
int isoutbound;
|
||||
|
@ -235,7 +260,7 @@ static int local_digit(struct ast_channel *ast, char digit)
|
|||
|
||||
static int local_sendhtml(struct ast_channel *ast, int subclass, char *data, int datalen)
|
||||
{
|
||||
struct local_pvt *p = ast->pvt->pvt;
|
||||
struct local_pvt *p = ast->tech_pvt;
|
||||
int res = -1;
|
||||
struct ast_frame f = { AST_FRAME_HTML, };
|
||||
int isoutbound;
|
||||
|
@ -251,7 +276,7 @@ static int local_sendhtml(struct ast_channel *ast, int subclass, char *data, int
|
|||
|
||||
static int local_call(struct ast_channel *ast, char *dest, int timeout)
|
||||
{
|
||||
struct local_pvt *p = ast->pvt->pvt;
|
||||
struct local_pvt *p = ast->tech_pvt;
|
||||
int res;
|
||||
|
||||
ast_mutex_lock(&p->lock);
|
||||
|
@ -313,7 +338,7 @@ static void local_destroy(struct local_pvt *p)
|
|||
|
||||
static int local_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct local_pvt *p = ast->pvt->pvt;
|
||||
struct local_pvt *p = ast->tech_pvt;
|
||||
int isoutbound;
|
||||
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
|
||||
struct local_pvt *cur, *prev=NULL;
|
||||
|
@ -326,7 +351,7 @@ static int local_hangup(struct ast_channel *ast)
|
|||
p->launchedpbx = 0;
|
||||
} else
|
||||
p->owner = NULL;
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
usecnt--;
|
||||
|
@ -432,6 +457,7 @@ static struct ast_channel *local_new(struct local_pvt *p, int state)
|
|||
tmp = NULL;
|
||||
}
|
||||
if (tmp) {
|
||||
tmp2->tech = tmp->tech = &local_tech;
|
||||
tmp->nativeformats = p->reqformat;
|
||||
tmp2->nativeformats = p->reqformat;
|
||||
snprintf(tmp->name, sizeof(tmp->name), "Local/%s@%s-%04x,1", p->exten, p->context, randnum);
|
||||
|
@ -442,34 +468,14 @@ static struct ast_channel *local_new(struct local_pvt *p, int state)
|
|||
ast_setstate(tmp2, AST_STATE_RING);
|
||||
tmp->writeformat = p->reqformat;;
|
||||
tmp2->writeformat = p->reqformat;
|
||||
tmp->pvt->rawwriteformat = p->reqformat;
|
||||
tmp2->pvt->rawwriteformat = p->reqformat;
|
||||
tmp->rawwriteformat = p->reqformat;
|
||||
tmp2->rawwriteformat = p->reqformat;
|
||||
tmp->readformat = p->reqformat;
|
||||
tmp2->readformat = p->reqformat;
|
||||
tmp->pvt->rawreadformat = p->reqformat;
|
||||
tmp2->pvt->rawreadformat = p->reqformat;
|
||||
tmp->pvt->pvt = p;
|
||||
tmp2->pvt->pvt = p;
|
||||
tmp->pvt->send_digit = local_digit;
|
||||
tmp2->pvt->send_digit = local_digit;
|
||||
tmp->pvt->send_html = local_sendhtml;
|
||||
tmp2->pvt->send_html = local_sendhtml;
|
||||
tmp->pvt->call = local_call;
|
||||
tmp2->pvt->call = local_call;
|
||||
tmp->pvt->hangup = local_hangup;
|
||||
tmp2->pvt->hangup = local_hangup;
|
||||
tmp->pvt->answer = local_answer;
|
||||
tmp2->pvt->answer = local_answer;
|
||||
tmp->pvt->read = local_read;
|
||||
tmp2->pvt->read = local_read;
|
||||
tmp->pvt->write = local_write;
|
||||
tmp2->pvt->write = local_write;
|
||||
tmp->pvt->exception = local_read;
|
||||
tmp2->pvt->exception = local_read;
|
||||
tmp->pvt->indicate = local_indicate;
|
||||
tmp2->pvt->indicate = local_indicate;
|
||||
tmp->pvt->fixup = local_fixup;
|
||||
tmp2->pvt->fixup = local_fixup;
|
||||
tmp->rawreadformat = p->reqformat;
|
||||
tmp2->rawreadformat = p->reqformat;
|
||||
tmp->tech_pvt = p;
|
||||
tmp2->tech_pvt = p;
|
||||
p->owner = tmp;
|
||||
p->chan = tmp2;
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
|
@ -528,8 +534,8 @@ static struct ast_cli_entry cli_show_locals = {
|
|||
|
||||
int load_module()
|
||||
{
|
||||
/* Make sure we can register our sip channel type */
|
||||
if (ast_channel_register(type, tdesc, capability, local_request)) {
|
||||
/* Make sure we can register our channel type */
|
||||
if (ast_channel_register(&local_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
return -1;
|
||||
}
|
||||
|
@ -547,7 +553,7 @@ int unload_module()
|
|||
struct local_pvt *p;
|
||||
/* First, take us out of the channel loop */
|
||||
ast_cli_unregister(&cli_show_locals);
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(&local_tech);
|
||||
if (!ast_mutex_lock(&locallock)) {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
p = locals;
|
||||
|
@ -581,6 +587,6 @@ char *key()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -114,10 +113,10 @@
|
|||
#define INADDR_NONE (in_addr_t)(-1)
|
||||
#endif
|
||||
|
||||
static char *desc = "Media Gateway Control Protocol (MGCP)";
|
||||
static char *type = "MGCP";
|
||||
static char *tdesc = "Media Gateway Control Protocol (MGCP)";
|
||||
static char *config = "mgcp.conf";
|
||||
static const char desc[] = "Media Gateway Control Protocol (MGCP)";
|
||||
static const char type[] = "MGCP";
|
||||
static const char tdesc[] = "Media Gateway Control Protocol (MGCP)";
|
||||
static const char config[] = "mgcp.conf";
|
||||
|
||||
#define MGCP_DTMF_RFC2833 (1 << 0)
|
||||
#define MGCP_DTMF_INBAND (1 << 1)
|
||||
|
@ -245,7 +244,6 @@ static pthread_t monitor_thread = AST_PTHREADT_NULL;
|
|||
|
||||
static int restart_monitor(void);
|
||||
|
||||
/* Just about everybody seems to support ulaw, so make it a nice default */
|
||||
static int capability = AST_FORMAT_ULAW;
|
||||
static int nonCodecCapability = AST_RTP_DTMF;
|
||||
|
||||
|
@ -467,6 +465,32 @@ static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub
|
|||
static int mgcp_do_reload(void);
|
||||
static int mgcp_reload(int fd, int argc, char *argv[]);
|
||||
|
||||
static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause);
|
||||
static int mgcp_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int mgcp_hangup(struct ast_channel *ast);
|
||||
static int mgcp_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *mgcp_read(struct ast_channel *ast);
|
||||
static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame);
|
||||
static int mgcp_indicate(struct ast_channel *ast, int ind);
|
||||
static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
static int mgcp_senddigit(struct ast_channel *ast, char digit);
|
||||
|
||||
static const struct ast_channel_tech mgcp_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_ULAW,
|
||||
.requester = mgcp_request,
|
||||
.call = mgcp_call,
|
||||
.hangup = mgcp_hangup,
|
||||
.answer = mgcp_answer,
|
||||
.read = mgcp_read,
|
||||
.write = mgcp_write,
|
||||
.indicate = mgcp_indicate,
|
||||
.fixup = mgcp_fixup,
|
||||
.send_digit = mgcp_senddigit,
|
||||
.bridge = ast_rtp_bridge,
|
||||
};
|
||||
|
||||
static int has_voicemail(struct mgcp_endpoint *p)
|
||||
{
|
||||
return ast_app_has_voicemail(p->mailbox, NULL);
|
||||
|
@ -859,7 +883,7 @@ static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
if (mgcpdebug) {
|
||||
ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_call(%s)\n", ast->name);
|
||||
}
|
||||
sub = ast->pvt->pvt;
|
||||
sub = ast->tech_pvt;
|
||||
p = sub->parent;
|
||||
headp = &ast->varshead;
|
||||
AST_LIST_TRAVERSE(headp,current,entries) {
|
||||
|
@ -941,13 +965,13 @@ static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
|
||||
static int mgcp_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct mgcp_subchannel *sub = ast->pvt->pvt;
|
||||
struct mgcp_subchannel *sub = ast->tech_pvt;
|
||||
struct mgcp_endpoint *p = sub->parent;
|
||||
|
||||
if (option_debug) {
|
||||
ast_log(LOG_DEBUG, "mgcp_hangup(%s)\n", ast->name);
|
||||
}
|
||||
if (!ast->pvt->pvt) {
|
||||
if (!ast->tech_pvt) {
|
||||
ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -999,7 +1023,7 @@ static int mgcp_hangup(struct ast_channel *ast)
|
|||
transmit_notify_request(sub, "");
|
||||
}
|
||||
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
sub->alreadygone = 0;
|
||||
sub->outgoing = 0;
|
||||
sub->cxmode = MGCP_CX_INACTIVE;
|
||||
|
@ -1138,7 +1162,7 @@ static struct ast_cli_entry cli_audit_endpoint =
|
|||
static int mgcp_answer(struct ast_channel *ast)
|
||||
{
|
||||
int res = 0;
|
||||
struct mgcp_subchannel *sub = ast->pvt->pvt;
|
||||
struct mgcp_subchannel *sub = ast->tech_pvt;
|
||||
struct mgcp_endpoint *p = sub->parent;
|
||||
|
||||
ast_mutex_lock(&sub->lock);
|
||||
|
@ -1199,7 +1223,7 @@ static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub)
|
|||
static struct ast_frame *mgcp_read(struct ast_channel *ast)
|
||||
{
|
||||
struct ast_frame *f;
|
||||
struct mgcp_subchannel *sub = ast->pvt->pvt;
|
||||
struct mgcp_subchannel *sub = ast->tech_pvt;
|
||||
ast_mutex_lock(&sub->lock);
|
||||
f = mgcp_rtp_read(sub);
|
||||
ast_mutex_unlock(&sub->lock);
|
||||
|
@ -1208,7 +1232,7 @@ static struct ast_frame *mgcp_read(struct ast_channel *ast)
|
|||
|
||||
static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
|
||||
{
|
||||
struct mgcp_subchannel *sub = ast->pvt->pvt;
|
||||
struct mgcp_subchannel *sub = ast->tech_pvt;
|
||||
int res = 0;
|
||||
if (frame->frametype != AST_FRAME_VOICE) {
|
||||
if (frame->frametype == AST_FRAME_IMAGE)
|
||||
|
@ -1238,7 +1262,7 @@ static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
|
|||
|
||||
static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct mgcp_subchannel *sub = newchan->pvt->pvt;
|
||||
struct mgcp_subchannel *sub = newchan->tech_pvt;
|
||||
|
||||
ast_mutex_lock(&sub->lock);
|
||||
ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name);
|
||||
|
@ -1254,7 +1278,7 @@ static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
|||
|
||||
static int mgcp_senddigit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
struct mgcp_subchannel *sub = ast->pvt->pvt;
|
||||
struct mgcp_subchannel *sub = ast->tech_pvt;
|
||||
char tmp[4];
|
||||
|
||||
tmp[0] = 'D';
|
||||
|
@ -1301,7 +1325,7 @@ static char *control2str(int ind) {
|
|||
|
||||
static int mgcp_indicate(struct ast_channel *ast, int ind)
|
||||
{
|
||||
struct mgcp_subchannel *sub = ast->pvt->pvt;
|
||||
struct mgcp_subchannel *sub = ast->tech_pvt;
|
||||
int res = 0;
|
||||
|
||||
if (mgcpdebug) {
|
||||
|
@ -1343,6 +1367,7 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state)
|
|||
i = sub->parent;
|
||||
tmp = ast_channel_alloc(1);
|
||||
if (tmp) {
|
||||
tmp->tech = &mgcp_tech;
|
||||
tmp->nativeformats = i->capability;
|
||||
if (!tmp->nativeformats)
|
||||
tmp->nativeformats = capability;
|
||||
|
@ -1363,19 +1388,10 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state)
|
|||
if (state == AST_STATE_RING)
|
||||
tmp->rings = 1;
|
||||
tmp->writeformat = fmt;
|
||||
tmp->pvt->rawwriteformat = fmt;
|
||||
tmp->rawwriteformat = fmt;
|
||||
tmp->readformat = fmt;
|
||||
tmp->pvt->rawreadformat = fmt;
|
||||
tmp->pvt->pvt = sub;
|
||||
tmp->pvt->call = mgcp_call;
|
||||
tmp->pvt->hangup = mgcp_hangup;
|
||||
tmp->pvt->answer = mgcp_answer;
|
||||
tmp->pvt->read = mgcp_read;
|
||||
tmp->pvt->write = mgcp_write;
|
||||
tmp->pvt->indicate = mgcp_indicate;
|
||||
tmp->pvt->fixup = mgcp_fixup;
|
||||
tmp->pvt->send_digit = mgcp_senddigit;
|
||||
tmp->pvt->bridge = ast_rtp_bridge;
|
||||
tmp->rawreadformat = fmt;
|
||||
tmp->tech_pvt = sub;
|
||||
if (strlen(i->language))
|
||||
strncpy(tmp->language, i->language, sizeof(tmp->language)-1);
|
||||
if (strlen(i->accountcode))
|
||||
|
@ -2528,7 +2544,7 @@ static void start_rtp(struct mgcp_subchannel *sub)
|
|||
static void *mgcp_ss(void *data)
|
||||
{
|
||||
struct ast_channel *chan = data;
|
||||
struct mgcp_subchannel *sub = chan->pvt->pvt;
|
||||
struct mgcp_subchannel *sub = chan->tech_pvt;
|
||||
struct mgcp_endpoint *p = sub->parent;
|
||||
char exten[AST_MAX_EXTENSION] = "";
|
||||
int len = 0;
|
||||
|
@ -3881,7 +3897,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
|
|||
static struct ast_rtp *mgcp_get_rtp_peer(struct ast_channel *chan)
|
||||
{
|
||||
struct mgcp_subchannel *sub;
|
||||
sub = chan->pvt->pvt;
|
||||
sub = chan->tech_pvt;
|
||||
if (sub && sub->rtp && sub->parent->canreinvite)
|
||||
return sub->rtp;
|
||||
return NULL;
|
||||
|
@ -3891,7 +3907,7 @@ static int mgcp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, stru
|
|||
{
|
||||
/* XXX Is there such thing as video support with MGCP? XXX */
|
||||
struct mgcp_subchannel *sub;
|
||||
sub = chan->pvt->pvt;
|
||||
sub = chan->tech_pvt;
|
||||
if (sub) {
|
||||
transmit_modify_with_sdp(sub, rtp, codecs);
|
||||
return 0;
|
||||
|
@ -3900,8 +3916,9 @@ static int mgcp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, stru
|
|||
}
|
||||
|
||||
static struct ast_rtp_protocol mgcp_rtp = {
|
||||
get_rtp_info: mgcp_get_rtp_peer,
|
||||
set_rtp_peer: mgcp_set_rtp_peer,
|
||||
.type = type,
|
||||
.get_rtp_info = mgcp_get_rtp_peer,
|
||||
.set_rtp_peer = mgcp_set_rtp_peer,
|
||||
};
|
||||
|
||||
static int mgcp_do_debug(int fd, int argc, char *argv[])
|
||||
|
@ -4226,11 +4243,10 @@ int load_module()
|
|||
|
||||
if (!(res = reload_config())) {
|
||||
/* Make sure we can register our mgcp channel type */
|
||||
if (ast_channel_register(type, tdesc, capability, mgcp_request)) {
|
||||
if (ast_channel_register(&mgcp_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
return -1;
|
||||
}
|
||||
mgcp_rtp.type = type;
|
||||
ast_rtp_proto_register(&mgcp_rtp);
|
||||
ast_cli_register(&cli_show_endpoints);
|
||||
ast_cli_register(&cli_audit_endpoint);
|
||||
|
@ -4274,7 +4290,7 @@ int unload_module()
|
|||
#if 0
|
||||
struct mgcp_endpoint *p, *pl;
|
||||
/* First, take us out of the channel loop */
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(&mgcp_tech);
|
||||
if (!ast_mutex_lock(&gatelock)) {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
p = iflist;
|
||||
|
@ -4339,5 +4355,5 @@ char *key()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -39,10 +38,10 @@
|
|||
/* Up to 10 seconds for an echo to arrive */
|
||||
#define ECHO_TIMEOUT 10
|
||||
|
||||
static char *desc = "Generic Voice Modem Driver";
|
||||
static char *tdesc = "Generic Voice Modem Channel Driver";
|
||||
static char *type = "Modem";
|
||||
static char *config = "modem.conf";
|
||||
static const char desc[] = "Generic Voice Modem Driver";
|
||||
static const char tdesc[] = "Generic Voice Modem Channel Driver";
|
||||
static const char type[] = "Modem";
|
||||
static const char config[] = "modem.conf";
|
||||
static char dialtype = 'T';
|
||||
static int gmode = MODEM_MODE_IMMEDIATE;
|
||||
|
||||
|
@ -97,6 +96,29 @@ static pthread_t monitor_thread = AST_PTHREADT_NULL;
|
|||
|
||||
static int restart_monitor(void);
|
||||
|
||||
static struct ast_channel *modem_request(const char *type, int format, void *data, int *cause);
|
||||
static int modem_digit(struct ast_channel *ast, char digit);
|
||||
static int modem_call(struct ast_channel *ast, char *idest, int timeout);
|
||||
static int modem_hangup(struct ast_channel *ast);
|
||||
static int modem_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *modem_read(struct ast_channel *);
|
||||
static int modem_write(struct ast_channel *ast, struct ast_frame *frame);
|
||||
static int modem_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
|
||||
static const struct ast_channel_tech modem_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_SLINEAR,
|
||||
.requester = modem_request,
|
||||
.send_digit = modem_digit,
|
||||
.call = modem_call,
|
||||
.hangup = modem_hangup,
|
||||
.answer = modem_answer,
|
||||
.read = modem_read,
|
||||
.write = modem_write,
|
||||
.fixup = modem_fixup,
|
||||
};
|
||||
|
||||
/* The private structures of the Phone Jack channels are linked for
|
||||
selecting outgoing channels */
|
||||
|
||||
|
@ -105,7 +127,7 @@ static struct ast_modem_pvt *iflist = NULL;
|
|||
static int modem_digit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
struct ast_modem_pvt *p;
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
if (p->mc->dialdigit)
|
||||
return p->mc->dialdigit(p, digit);
|
||||
ast_log(LOG_DEBUG, "Channel %s lacks digit dialing\n", ast->name);
|
||||
|
@ -114,8 +136,6 @@ static int modem_digit(struct ast_channel *ast, char digit)
|
|||
|
||||
static struct ast_modem_driver *drivers = NULL;
|
||||
|
||||
static struct ast_frame *modem_read(struct ast_channel *);
|
||||
|
||||
static struct ast_modem_driver *find_capability(char *ident)
|
||||
{
|
||||
struct ast_modem_driver *mc;
|
||||
|
@ -191,7 +211,7 @@ static int modem_call(struct ast_channel *ast, char *idest, int timeout)
|
|||
ast_log(LOG_WARNING, "Destination %s requres a real destination (device:destination)\n", idest);
|
||||
return -1;
|
||||
}
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
strncpy(dstr, where + p->stripmsd, sizeof(dstr) - 1);
|
||||
/* if not a transfer or just sending tones, must be in correct state */
|
||||
if (strcasecmp(rdest, "transfer") && strcasecmp(rdest,"sendtones")) {
|
||||
|
@ -421,7 +441,7 @@ static int modem_hangup(struct ast_channel *ast)
|
|||
struct ast_modem_pvt *p;
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "modem_hangup(%s)\n", ast->name);
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
/* Hang up */
|
||||
if (p->mc->hangup)
|
||||
p->mc->hangup(p);
|
||||
|
@ -432,7 +452,7 @@ static int modem_hangup(struct ast_channel *ast)
|
|||
memset(p->cid_num, 0, sizeof(p->cid_num));
|
||||
memset(p->cid_name, 0, sizeof(p->cid_name));
|
||||
memset(p->dnid, 0, sizeof(p->dnid));
|
||||
((struct ast_modem_pvt *)(ast->pvt->pvt))->owner = NULL;
|
||||
((struct ast_modem_pvt *)(ast->tech_pvt))->owner = NULL;
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
usecnt--;
|
||||
if (usecnt < 0)
|
||||
|
@ -441,7 +461,7 @@ static int modem_hangup(struct ast_channel *ast)
|
|||
ast_update_use_count();
|
||||
if (option_verbose > 2)
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
ast_setstate(ast, AST_STATE_DOWN);
|
||||
restart_monitor();
|
||||
return 0;
|
||||
|
@ -453,7 +473,7 @@ static int modem_answer(struct ast_channel *ast)
|
|||
int res=0;
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "modem_answer(%s)\n", ast->name);
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
if (p->mc->answer) {
|
||||
res = p->mc->answer(p);
|
||||
}
|
||||
|
@ -479,7 +499,7 @@ static char modem_2digit(char c)
|
|||
#endif
|
||||
static struct ast_frame *modem_read(struct ast_channel *ast)
|
||||
{
|
||||
struct ast_modem_pvt *p = ast->pvt->pvt;
|
||||
struct ast_modem_pvt *p = ast->tech_pvt;
|
||||
struct ast_frame *fr=NULL;
|
||||
if (p->mc->read)
|
||||
fr = p->mc->read(p);
|
||||
|
@ -490,7 +510,7 @@ static int modem_write(struct ast_channel *ast, struct ast_frame *frame)
|
|||
{
|
||||
int res=0;
|
||||
long flags;
|
||||
struct ast_modem_pvt *p = ast->pvt->pvt;
|
||||
struct ast_modem_pvt *p = ast->tech_pvt;
|
||||
|
||||
/* Modems tend to get upset when they receive data whilst in
|
||||
* command mode. This makes esp. dial commands short lived.
|
||||
|
@ -512,7 +532,7 @@ static int modem_write(struct ast_channel *ast, struct ast_frame *frame)
|
|||
|
||||
static int modem_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct ast_modem_pvt *p = newchan->pvt->pvt;
|
||||
struct ast_modem_pvt *p = newchan->tech_pvt;
|
||||
ast_log(LOG_WARNING, "fixup called\n");
|
||||
if (p->owner!=oldchan) {
|
||||
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n",oldchan,p->owner);
|
||||
|
@ -527,6 +547,7 @@ struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
|
|||
struct ast_channel *tmp;
|
||||
tmp = ast_channel_alloc(1);
|
||||
if (tmp) {
|
||||
tmp->tech = &modem_tech;
|
||||
snprintf(tmp->name, sizeof(tmp->name), "Modem[%s]/%s", i->mc->name, i->dev + 5);
|
||||
tmp->type = type;
|
||||
tmp->fds[0] = i->fd;
|
||||
|
@ -534,14 +555,7 @@ struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
|
|||
ast_setstate(tmp, state);
|
||||
if (state == AST_STATE_RING)
|
||||
tmp->rings = 1;
|
||||
tmp->pvt->pvt = i;
|
||||
tmp->pvt->send_digit = modem_digit;
|
||||
tmp->pvt->call = modem_call;
|
||||
tmp->pvt->hangup = modem_hangup;
|
||||
tmp->pvt->answer = modem_answer;
|
||||
tmp->pvt->read = modem_read;
|
||||
tmp->pvt->write = modem_write;
|
||||
tmp->pvt->fixup = modem_fixup;
|
||||
tmp->tech_pvt = i;
|
||||
strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
|
||||
|
||||
if (!ast_strlen_zero(i->cid_num))
|
||||
|
@ -889,7 +903,7 @@ static int __unload_module(void)
|
|||
{
|
||||
struct ast_modem_pvt *p, *pl;
|
||||
/* First, take us out of the channel loop */
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(&modem_tech);
|
||||
if (!ast_mutex_lock(&iflock)) {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
p = iflist;
|
||||
|
@ -1052,8 +1066,7 @@ int load_module()
|
|||
v = v->next;
|
||||
}
|
||||
ast_mutex_unlock(&iflock);
|
||||
if (ast_channel_register(type, tdesc, /* XXX Don't know our types -- maybe we should register more than one XXX */
|
||||
AST_FORMAT_SLINEAR, modem_request)) {
|
||||
if (ast_channel_register(&modem_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
ast_config_destroy(cfg);
|
||||
__unload_module();
|
||||
|
@ -1076,7 +1089,7 @@ int usecount(void)
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
char *key()
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -31,9 +30,9 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <nbs.h>
|
||||
|
||||
static char *desc = "Network Broadcast Sound Support";
|
||||
static char *type = "NBS";
|
||||
static char *tdesc = "Network Broadcast Sound Driver";
|
||||
static const char desc[] = "Network Broadcast Sound Support";
|
||||
static const char type[] = "NBS";
|
||||
static const char tdesc[] = "Network Broadcast Sound Driver";
|
||||
|
||||
static int usecnt =0;
|
||||
|
||||
|
@ -54,11 +53,28 @@ struct nbs_pvt {
|
|||
struct ast_frame fr; /* "null" frame */
|
||||
};
|
||||
|
||||
static struct ast_channel *nbs_request(const char *type, int format, void *data, int *cause);
|
||||
static int nbs_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int nbs_hangup(struct ast_channel *ast);
|
||||
static struct ast_frame *nbs_xread(struct ast_channel *ast);
|
||||
static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame);
|
||||
|
||||
static const struct ast_channel_tech nbs_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_SLINEAR,
|
||||
.requester = nbs_request,
|
||||
.call = nbs_call,
|
||||
.hangup = nbs_hangup,
|
||||
.read = nbs_xread,
|
||||
.write = nbs_xwrite,
|
||||
};
|
||||
|
||||
static int nbs_call(struct ast_channel *ast, char *dest, int timeout)
|
||||
{
|
||||
struct nbs_pvt *p;
|
||||
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
|
||||
if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
|
||||
ast_log(LOG_WARNING, "nbs_call called on %s, neither down nor reserved\n", ast->name);
|
||||
|
@ -135,22 +151,22 @@ static struct nbs_pvt *nbs_alloc(void *data)
|
|||
static int nbs_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct nbs_pvt *p;
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "nbs_hangup(%s)\n", ast->name);
|
||||
if (!ast->pvt->pvt) {
|
||||
if (!ast->tech_pvt) {
|
||||
ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
|
||||
return 0;
|
||||
}
|
||||
nbs_destroy(p);
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
ast_setstate(ast, AST_STATE_DOWN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ast_frame *nbs_xread(struct ast_channel *ast)
|
||||
{
|
||||
struct nbs_pvt *p = ast->pvt->pvt;
|
||||
struct nbs_pvt *p = ast->tech_pvt;
|
||||
|
||||
|
||||
/* Some nice norms */
|
||||
|
@ -170,7 +186,7 @@ static struct ast_frame *nbs_xread(struct ast_channel *ast)
|
|||
|
||||
static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame)
|
||||
{
|
||||
struct nbs_pvt *p = ast->pvt->pvt;
|
||||
struct nbs_pvt *p = ast->tech_pvt;
|
||||
/* Write a frame of (presumably voice) data */
|
||||
if (frame->frametype != AST_FRAME_VOICE) {
|
||||
if (frame->frametype != AST_FRAME_IMAGE)
|
||||
|
@ -196,22 +212,19 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state)
|
|||
struct ast_channel *tmp;
|
||||
tmp = ast_channel_alloc(1);
|
||||
if (tmp) {
|
||||
tmp->tech = &nbs_tech;
|
||||
snprintf(tmp->name, sizeof(tmp->name), "NBS/%s", i->stream);
|
||||
tmp->type = type;
|
||||
tmp->fds[0] = nbs_fd(i->nbs);
|
||||
tmp->nativeformats = prefformat;
|
||||
tmp->pvt->rawreadformat = prefformat;
|
||||
tmp->pvt->rawwriteformat = prefformat;
|
||||
tmp->rawreadformat = prefformat;
|
||||
tmp->rawwriteformat = prefformat;
|
||||
tmp->writeformat = prefformat;
|
||||
tmp->readformat = prefformat;
|
||||
ast_setstate(tmp, state);
|
||||
if (state == AST_STATE_RING)
|
||||
tmp->rings = 1;
|
||||
tmp->pvt->pvt = i;
|
||||
tmp->pvt->call = nbs_call;
|
||||
tmp->pvt->hangup = nbs_hangup;
|
||||
tmp->pvt->read = nbs_xread;
|
||||
tmp->pvt->write = nbs_xwrite;
|
||||
tmp->tech_pvt = i;
|
||||
strncpy(tmp->context, context, sizeof(tmp->context)-1);
|
||||
strncpy(tmp->exten, "s", sizeof(tmp->exten) - 1);
|
||||
tmp->language[0] = '\0';
|
||||
|
@ -256,7 +269,7 @@ static struct ast_channel *nbs_request(const char *type, int format, void *data,
|
|||
static int __unload_module(void)
|
||||
{
|
||||
/* First, take us out of the channel loop */
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(&nbs_tech);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -267,9 +280,8 @@ int unload_module(void)
|
|||
|
||||
int load_module()
|
||||
{
|
||||
/* Make sure we can register our Adtranphone channel type */
|
||||
if (ast_channel_register(type, tdesc,
|
||||
AST_FORMAT_SLINEAR, nbs_request)) {
|
||||
/* Make sure we can register our channel type */
|
||||
if (ast_channel_register(&nbs_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
__unload_module();
|
||||
return -1;
|
||||
|
@ -288,7 +300,7 @@ int usecount()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
char *key()
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <asterisk/logger.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/config.h>
|
||||
|
@ -75,10 +74,10 @@ static int playbackonly = 0;
|
|||
|
||||
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
||||
|
||||
static char *type = "Console";
|
||||
static char *desc = "OSS Console Channel Driver";
|
||||
static char *tdesc = "OSS Console Channel Driver";
|
||||
static char *config = "oss.conf";
|
||||
static const char type[] = "Console";
|
||||
static const char desc[] = "OSS Console Channel Driver";
|
||||
static const char tdesc[] = "OSS Console Channel Driver";
|
||||
static const char config[] = "oss.conf";
|
||||
|
||||
static char context[AST_MAX_EXTENSION] = "default";
|
||||
static char language[MAX_LANGUAGE] = "";
|
||||
|
@ -116,6 +115,33 @@ static struct chan_oss_pvt {
|
|||
char context[AST_MAX_EXTENSION];
|
||||
} oss;
|
||||
|
||||
static struct ast_channel *oss_request(const char *type, int format, void *data, int *cause);
|
||||
static int oss_digit(struct ast_channel *c, char digit);
|
||||
static int oss_text(struct ast_channel *c, char *text);
|
||||
static int oss_hangup(struct ast_channel *c);
|
||||
static int oss_answer(struct ast_channel *c);
|
||||
static struct ast_frame *oss_read(struct ast_channel *chan);
|
||||
static int oss_call(struct ast_channel *c, char *dest, int timeout);
|
||||
static int oss_write(struct ast_channel *chan, struct ast_frame *f);
|
||||
static int oss_indicate(struct ast_channel *chan, int cond);
|
||||
static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
|
||||
static const struct ast_channel_tech oss_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_SLINEAR,
|
||||
.requester = oss_request,
|
||||
.send_digit = oss_digit,
|
||||
.send_text = oss_text,
|
||||
.hangup = oss_hangup,
|
||||
.answer = oss_answer,
|
||||
.read = oss_read,
|
||||
.call = oss_call,
|
||||
.write = oss_write,
|
||||
.indicate = oss_indicate,
|
||||
.fixup = oss_fixup,
|
||||
};
|
||||
|
||||
static int time_has_passed(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
@ -500,7 +526,7 @@ static int oss_hangup(struct ast_channel *c)
|
|||
{
|
||||
int res = 0;
|
||||
cursound = -1;
|
||||
c->pvt->pvt = NULL;
|
||||
c->tech_pvt = NULL;
|
||||
oss.owner = NULL;
|
||||
ast_verbose( " << Hangup on console >> \n");
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
|
@ -676,7 +702,7 @@ static struct ast_frame *oss_read(struct ast_channel *chan)
|
|||
|
||||
static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct chan_oss_pvt *p = newchan->pvt->pvt;
|
||||
struct chan_oss_pvt *p = newchan->tech_pvt;
|
||||
p->owner = newchan;
|
||||
return 0;
|
||||
}
|
||||
|
@ -712,22 +738,14 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
|
|||
struct ast_channel *tmp;
|
||||
tmp = ast_channel_alloc(1);
|
||||
if (tmp) {
|
||||
tmp->tech = &oss_tech;
|
||||
snprintf(tmp->name, sizeof(tmp->name), "OSS/%s", DEV_DSP + 5);
|
||||
tmp->type = type;
|
||||
tmp->fds[0] = sounddev;
|
||||
tmp->nativeformats = AST_FORMAT_SLINEAR;
|
||||
tmp->readformat = AST_FORMAT_SLINEAR;
|
||||
tmp->writeformat = AST_FORMAT_SLINEAR;
|
||||
tmp->pvt->pvt = p;
|
||||
tmp->pvt->send_digit = oss_digit;
|
||||
tmp->pvt->send_text = oss_text;
|
||||
tmp->pvt->hangup = oss_hangup;
|
||||
tmp->pvt->answer = oss_answer;
|
||||
tmp->pvt->read = oss_read;
|
||||
tmp->pvt->call = oss_call;
|
||||
tmp->pvt->write = oss_write;
|
||||
tmp->pvt->indicate = oss_indicate;
|
||||
tmp->pvt->fixup = oss_fixup;
|
||||
tmp->tech_pvt = p;
|
||||
if (strlen(p->context))
|
||||
strncpy(tmp->context, p->context, sizeof(tmp->context)-1);
|
||||
if (strlen(p->exten))
|
||||
|
@ -1019,7 +1037,7 @@ int load_module()
|
|||
}
|
||||
if (!full_duplex)
|
||||
ast_log(LOG_WARNING, "XXX I don't work right with non-full duplex sound cards XXX\n");
|
||||
res = ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR, oss_request);
|
||||
res = ast_channel_register(&oss_tech);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", type);
|
||||
return -1;
|
||||
|
@ -1056,6 +1074,8 @@ int load_module()
|
|||
int unload_module()
|
||||
{
|
||||
int x;
|
||||
|
||||
ast_channel_unregister(&oss_tech);
|
||||
for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
|
||||
ast_cli_unregister(myclis + x);
|
||||
close(sounddev);
|
||||
|
@ -1072,7 +1092,7 @@ int unload_module()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
int usecount()
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include <ctype.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -62,10 +61,10 @@
|
|||
#define PHONE_MAX_BUF 480
|
||||
#define DEFAULT_GAIN 0x100
|
||||
|
||||
static char *desc = "Linux Telephony API Support";
|
||||
static char *type = "Phone";
|
||||
static char *tdesc = "Standard Linux Telephony API Driver";
|
||||
static char *config = "phone.conf";
|
||||
static const char desc[] = "Linux Telephony API Support";
|
||||
static const char type[] = "Phone";
|
||||
static const char tdesc[] = "Standard Linux Telephony API Driver";
|
||||
static const char config[] = "phone.conf";
|
||||
|
||||
/* Default context for dialtone mode */
|
||||
static char context[AST_MAX_EXTENSION] = "default";
|
||||
|
@ -132,11 +131,52 @@ static struct phone_pvt {
|
|||
static char cid_num[AST_MAX_EXTENSION];
|
||||
static char cid_name[AST_MAX_EXTENSION];
|
||||
|
||||
static struct ast_channel *phone_request(const char *type, int format, void *data, int *cause);
|
||||
static int phone_digit(struct ast_channel *ast, char digit);
|
||||
static int phone_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int phone_hangup(struct ast_channel *ast);
|
||||
static int phone_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *phone_read(struct ast_channel *ast);
|
||||
static int phone_write(struct ast_channel *ast, struct ast_frame *frame);
|
||||
static struct ast_frame *phone_exception(struct ast_channel *ast);
|
||||
static int phone_send_text(struct ast_channel *ast, char *text);
|
||||
|
||||
static const struct ast_channel_tech phone_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW,
|
||||
.requester = phone_request,
|
||||
.send_digit = phone_digit,
|
||||
.call = phone_call,
|
||||
.hangup = phone_hangup,
|
||||
.answer = phone_answer,
|
||||
.read = phone_read,
|
||||
.write = phone_write,
|
||||
.exception = phone_exception,
|
||||
};
|
||||
|
||||
static struct ast_channel_tech phone_tech_fxs = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.requester = phone_request,
|
||||
.send_digit = phone_digit,
|
||||
.call = phone_call,
|
||||
.hangup = phone_hangup,
|
||||
.answer = phone_answer,
|
||||
.read = phone_read,
|
||||
.write = phone_write,
|
||||
.exception = phone_exception,
|
||||
.write_video = phone_write,
|
||||
.send_text = phone_send_text,
|
||||
};
|
||||
|
||||
static struct ast_channel_tech *cur_tech;
|
||||
|
||||
static int phone_digit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
struct phone_pvt *p;
|
||||
int outdigit;
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
ast_log(LOG_NOTICE, "Dialed %c\n", digit);
|
||||
switch(digit) {
|
||||
case '0':
|
||||
|
@ -202,7 +242,7 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
if (ast->cid.cid_num)
|
||||
strncpy(cid.number, ast->cid.cid_num, sizeof(cid.number) - 1);
|
||||
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
|
||||
if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
|
||||
ast_log(LOG_WARNING, "phone_call called on %s, neither down nor reserved\n", ast->name);
|
||||
|
@ -233,10 +273,10 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
static int phone_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct phone_pvt *p;
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "phone_hangup(%s)\n", ast->name);
|
||||
if (!ast->pvt->pvt) {
|
||||
if (!ast->tech_pvt) {
|
||||
ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -270,7 +310,7 @@ static int phone_hangup(struct ast_channel *ast)
|
|||
p->obuflen = 0;
|
||||
p->dialtone = 0;
|
||||
memset(p->ext, 0, sizeof(p->ext));
|
||||
((struct phone_pvt *)(ast->pvt->pvt))->owner = NULL;
|
||||
((struct phone_pvt *)(ast->tech_pvt))->owner = NULL;
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
usecnt--;
|
||||
if (usecnt < 0)
|
||||
|
@ -279,7 +319,7 @@ static int phone_hangup(struct ast_channel *ast)
|
|||
ast_update_use_count();
|
||||
if (option_verbose > 2)
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
ast_setstate(ast, AST_STATE_DOWN);
|
||||
restart_monitor();
|
||||
return 0;
|
||||
|
@ -288,10 +328,10 @@ static int phone_hangup(struct ast_channel *ast)
|
|||
static int phone_setup(struct ast_channel *ast)
|
||||
{
|
||||
struct phone_pvt *p;
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
ioctl(p->fd, PHONE_CPT_STOP);
|
||||
/* Nothing to answering really, just start recording */
|
||||
if (ast->pvt->rawreadformat == AST_FORMAT_G723_1) {
|
||||
if (ast->rawreadformat == AST_FORMAT_G723_1) {
|
||||
/* Prefer g723 */
|
||||
ioctl(p->fd, PHONE_REC_STOP);
|
||||
if (p->lastinput != AST_FORMAT_G723_1) {
|
||||
|
@ -301,7 +341,7 @@ static int phone_setup(struct ast_channel *ast)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (ast->pvt->rawreadformat == AST_FORMAT_SLINEAR) {
|
||||
} else if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
|
||||
ioctl(p->fd, PHONE_REC_STOP);
|
||||
if (p->lastinput != AST_FORMAT_SLINEAR) {
|
||||
p->lastinput = AST_FORMAT_SLINEAR;
|
||||
|
@ -310,7 +350,7 @@ static int phone_setup(struct ast_channel *ast)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (ast->pvt->rawreadformat == AST_FORMAT_ULAW) {
|
||||
} else if (ast->rawreadformat == AST_FORMAT_ULAW) {
|
||||
ioctl(p->fd, PHONE_REC_STOP);
|
||||
if (p->lastinput != AST_FORMAT_ULAW) {
|
||||
p->lastinput = AST_FORMAT_ULAW;
|
||||
|
@ -321,16 +361,16 @@ static int phone_setup(struct ast_channel *ast)
|
|||
}
|
||||
} else if (p->mode == MODE_FXS) {
|
||||
ioctl(p->fd, PHONE_REC_STOP);
|
||||
if (p->lastinput != ast->pvt->rawreadformat) {
|
||||
p->lastinput = ast->pvt->rawreadformat;
|
||||
if (ioctl(p->fd, PHONE_REC_CODEC, ast->pvt->rawreadformat)) {
|
||||
if (p->lastinput != ast->rawreadformat) {
|
||||
p->lastinput = ast->rawreadformat;
|
||||
if (ioctl(p->fd, PHONE_REC_CODEC, ast->rawreadformat)) {
|
||||
ast_log(LOG_WARNING, "Failed to set codec to %d\n",
|
||||
ast->pvt->rawreadformat);
|
||||
ast->rawreadformat);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(ast->pvt->rawreadformat));
|
||||
ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(ast->rawreadformat));
|
||||
return -1;
|
||||
}
|
||||
if (ioctl(p->fd, PHONE_REC_START)) {
|
||||
|
@ -346,7 +386,7 @@ static int phone_setup(struct ast_channel *ast)
|
|||
static int phone_answer(struct ast_channel *ast)
|
||||
{
|
||||
struct phone_pvt *p;
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
/* In case it's a LineJack, take it off hook */
|
||||
if (p->mode == MODE_FXO) {
|
||||
if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_OFF_HOOK))
|
||||
|
@ -380,7 +420,7 @@ static struct ast_frame *phone_exception(struct ast_channel *ast)
|
|||
{
|
||||
int res;
|
||||
union telephony_exception phonee;
|
||||
struct phone_pvt *p = ast->pvt->pvt;
|
||||
struct phone_pvt *p = ast->tech_pvt;
|
||||
char digit;
|
||||
|
||||
/* Some nice norms */
|
||||
|
@ -443,7 +483,7 @@ static struct ast_frame *phone_exception(struct ast_channel *ast)
|
|||
static struct ast_frame *phone_read(struct ast_channel *ast)
|
||||
{
|
||||
int res;
|
||||
struct phone_pvt *p = ast->pvt->pvt;
|
||||
struct phone_pvt *p = ast->tech_pvt;
|
||||
|
||||
|
||||
/* Some nice norms */
|
||||
|
@ -530,13 +570,13 @@ static int phone_write_buf(struct phone_pvt *p, char *buf, int len, int frlen)
|
|||
static int phone_send_text(struct ast_channel *ast, char *text)
|
||||
{
|
||||
int length = strlen(text);
|
||||
return phone_write_buf(ast->pvt->pvt, text, length, length) ==
|
||||
return phone_write_buf(ast->tech_pvt, text, length, length) ==
|
||||
length ? 0 : -1;
|
||||
}
|
||||
|
||||
static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
|
||||
{
|
||||
struct phone_pvt *p = ast->pvt->pvt;
|
||||
struct phone_pvt *p = ast->tech_pvt;
|
||||
int res;
|
||||
int maxfr=0;
|
||||
char *pos;
|
||||
|
@ -713,6 +753,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
|
|||
struct phone_codec_data codec;
|
||||
tmp = ast_channel_alloc(1);
|
||||
if (tmp) {
|
||||
tmp->tech = cur_tech;
|
||||
snprintf(tmp->name, sizeof(tmp->name), "Phone/%s", i->dev + 5);
|
||||
tmp->type = type;
|
||||
tmp->fds[0] = i->fd;
|
||||
|
@ -721,36 +762,25 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte
|
|||
ioctl(i->fd, PHONE_QUERY_CODEC, &codec) == 0) {
|
||||
if (codec.type == LINEAR16)
|
||||
tmp->nativeformats =
|
||||
tmp->pvt->rawreadformat =
|
||||
tmp->pvt->rawwriteformat =
|
||||
tmp->rawreadformat =
|
||||
tmp->rawwriteformat =
|
||||
AST_FORMAT_SLINEAR;
|
||||
else {
|
||||
tmp->nativeformats =
|
||||
tmp->pvt->rawreadformat =
|
||||
tmp->pvt->rawwriteformat =
|
||||
tmp->rawreadformat =
|
||||
tmp->rawwriteformat =
|
||||
prefformat & ~AST_FORMAT_SLINEAR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tmp->nativeformats = prefformat;
|
||||
tmp->pvt->rawreadformat = prefformat;
|
||||
tmp->pvt->rawwriteformat = prefformat;
|
||||
tmp->rawreadformat = prefformat;
|
||||
tmp->rawwriteformat = prefformat;
|
||||
}
|
||||
ast_setstate(tmp, state);
|
||||
if (state == AST_STATE_RING)
|
||||
tmp->rings = 1;
|
||||
tmp->pvt->pvt = i;
|
||||
tmp->pvt->send_digit = phone_digit;
|
||||
tmp->pvt->call = phone_call;
|
||||
tmp->pvt->hangup = phone_hangup;
|
||||
tmp->pvt->answer = phone_answer;
|
||||
tmp->pvt->read = phone_read;
|
||||
tmp->pvt->write = phone_write;
|
||||
if (i->mode == MODE_FXS) {
|
||||
tmp->pvt->write_video = phone_write;
|
||||
tmp->pvt->send_text = phone_send_text;
|
||||
}
|
||||
tmp->pvt->exception = phone_exception;
|
||||
tmp->tech_pvt = i;
|
||||
strncpy(tmp->context, context, sizeof(tmp->context)-1);
|
||||
if (strlen(i->ext))
|
||||
strncpy(tmp->exten, i->ext, sizeof(tmp->exten)-1);
|
||||
|
@ -1172,7 +1202,7 @@ static int __unload_module(void)
|
|||
{
|
||||
struct phone_pvt *p, *pl;
|
||||
/* First, take us out of the channel loop */
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(cur_tech);
|
||||
if (!ast_mutex_lock(&iflock)) {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
p = iflist;
|
||||
|
@ -1312,10 +1342,16 @@ int load_module()
|
|||
v = v->next;
|
||||
}
|
||||
ast_mutex_unlock(&iflock);
|
||||
|
||||
if (mode == MODE_FXS) {
|
||||
phone_tech_fxs.capabilities = prefformat;
|
||||
cur_tech = &phone_tech_fxs;
|
||||
} else
|
||||
cur_tech = (struct ast_channel_tech *) &phone_tech;
|
||||
|
||||
/* Make sure we can register our Adtranphone channel type */
|
||||
if (ast_channel_register(type, tdesc, mode != MODE_FXS ?
|
||||
AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR |
|
||||
AST_FORMAT_ULAW : prefformat, phone_request)) {
|
||||
|
||||
if (ast_channel_register(cur_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
ast_config_destroy(cfg);
|
||||
__unload_module();
|
||||
|
@ -1338,7 +1374,7 @@ int usecount()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
char *key()
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -110,11 +109,10 @@ static int default_expiry = DEFAULT_DEFAULT_EXPIRY;
|
|||
#define DEBUG_READ 0 /* Recieved data */
|
||||
#define DEBUG_SEND 1 /* Transmit data */
|
||||
|
||||
static char *desc = "Session Initiation Protocol (SIP)";
|
||||
static char *channeltype = "SIP";
|
||||
static char *tdesc = "Session Initiation Protocol (SIP)";
|
||||
static char *config = "sip.conf";
|
||||
static char *notify_config = "sip_notify.conf";
|
||||
static const char desc[] = "Session Initiation Protocol (SIP)";
|
||||
static const char channeltype[] = "SIP";
|
||||
static const char config[] = "sip.conf";
|
||||
static const char notify_config[] = "sip_notify.conf";
|
||||
|
||||
#define DEFAULT_SIP_PORT 5060 /* From RFC 2543 */
|
||||
#define SIP_MAX_PACKET 4096 /* Also from RFC 2543, should sub headers tho */
|
||||
|
@ -615,6 +613,40 @@ static int sip_do_reload(void);
|
|||
static int expire_register(void *data);
|
||||
static int callevents = 0;
|
||||
|
||||
static struct ast_channel *sip_request(const char *type, int format, void *data, int *cause);
|
||||
static int sip_devicestate(void *data);
|
||||
static int sip_sendtext(struct ast_channel *ast, char *text);
|
||||
static int sip_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int sip_hangup(struct ast_channel *ast);
|
||||
static int sip_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *sip_read(struct ast_channel *ast);
|
||||
static int sip_write(struct ast_channel *ast, struct ast_frame *frame);
|
||||
static int sip_indicate(struct ast_channel *ast, int condition);
|
||||
static int sip_transfer(struct ast_channel *ast, char *dest);
|
||||
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
static int sip_senddigit(struct ast_channel *ast, char digit);
|
||||
static int sip_sendtext(struct ast_channel *ast, char *text);
|
||||
|
||||
static const struct ast_channel_tech sip_tech = {
|
||||
.type = channeltype,
|
||||
.description = "Session Initiation Protocol (SIP)",
|
||||
.capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
|
||||
.requester = sip_request,
|
||||
.devicestate = sip_devicestate,
|
||||
.call = sip_call,
|
||||
.hangup = sip_hangup,
|
||||
.answer = sip_answer,
|
||||
.read = sip_read,
|
||||
.write = sip_write,
|
||||
.write_video = sip_write,
|
||||
.indicate = sip_indicate,
|
||||
.transfer = sip_transfer,
|
||||
.fixup = sip_fixup,
|
||||
.send_digit = sip_senddigit,
|
||||
.bridge = ast_rtp_bridge,
|
||||
.send_text = sip_sendtext,
|
||||
};
|
||||
|
||||
/*--- sip_debug_test_addr: See if we pass debug IP filter */
|
||||
static inline int sip_debug_test_addr(struct sockaddr_in *addr)
|
||||
{
|
||||
|
@ -1066,7 +1098,7 @@ static char *ditch_braces(char *tmp)
|
|||
/* Called from PBX core text message functions */
|
||||
static int sip_sendtext(struct ast_channel *ast, char *text)
|
||||
{
|
||||
struct sip_pvt *p = ast->pvt->pvt;
|
||||
struct sip_pvt *p = ast->tech_pvt;
|
||||
int debug=sip_debug_test_pvt(p);
|
||||
|
||||
if (debug)
|
||||
|
@ -1452,7 +1484,7 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
struct ast_var_t *current;
|
||||
int addsipheaders = 0;
|
||||
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
|
||||
ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
|
||||
return -1;
|
||||
|
@ -1563,7 +1595,7 @@ static void __sip_destroy(struct sip_pvt *p, int lockowner)
|
|||
if (lockowner)
|
||||
ast_mutex_lock(&p->owner->lock);
|
||||
ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
|
||||
p->owner->pvt->pvt = NULL;
|
||||
p->owner->tech_pvt = NULL;
|
||||
if (lockowner)
|
||||
ast_mutex_unlock(&p->owner->lock);
|
||||
}
|
||||
|
@ -1757,12 +1789,12 @@ static char *hangup_cause2sip(int cause)
|
|||
/* Part of PBX interface */
|
||||
static int sip_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct sip_pvt *p = ast->pvt->pvt;
|
||||
struct sip_pvt *p = ast->tech_pvt;
|
||||
int needcancel = 0;
|
||||
struct ast_flags locflags = {0};
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "sip_hangup(%s)\n", ast->name);
|
||||
if (!ast->pvt->pvt) {
|
||||
if (!p) {
|
||||
ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1785,15 +1817,15 @@ static int sip_hangup(struct ast_channel *ast)
|
|||
ast_mutex_unlock(&p->lock);
|
||||
return 0;
|
||||
}
|
||||
if (!ast || (ast->_state != AST_STATE_UP))
|
||||
if (ast->_state != AST_STATE_UP)
|
||||
needcancel = 1;
|
||||
/* Disconnect */
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
if (p->vad) {
|
||||
ast_dsp_free(p->vad);
|
||||
}
|
||||
p->owner = NULL;
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
usecnt--;
|
||||
|
@ -1850,7 +1882,7 @@ static int sip_answer(struct ast_channel *ast)
|
|||
{
|
||||
int res = 0,fmt;
|
||||
char *codec;
|
||||
struct sip_pvt *p = ast->pvt->pvt;
|
||||
struct sip_pvt *p = ast->tech_pvt;
|
||||
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (ast->_state != AST_STATE_UP) {
|
||||
|
@ -1883,7 +1915,7 @@ static int sip_answer(struct ast_channel *ast)
|
|||
/*--- sip_write: Send response, support audio media ---*/
|
||||
static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
|
||||
{
|
||||
struct sip_pvt *p = ast->pvt->pvt;
|
||||
struct sip_pvt *p = ast->tech_pvt;
|
||||
int res = 0;
|
||||
if (frame->frametype == AST_FRAME_VOICE) {
|
||||
if (!(frame->subclass & ast->nativeformats)) {
|
||||
|
@ -1930,7 +1962,7 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
|
|||
Basically update any ->owner links ----*/
|
||||
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct sip_pvt *p = newchan->pvt->pvt;
|
||||
struct sip_pvt *p = newchan->tech_pvt;
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (p->owner != oldchan) {
|
||||
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
|
||||
|
@ -1946,7 +1978,7 @@ static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
|||
/* within one call, we're able to transmit in many methods simultaneously */
|
||||
static int sip_senddigit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
struct sip_pvt *p = ast->pvt->pvt;
|
||||
struct sip_pvt *p = ast->tech_pvt;
|
||||
int res = 0;
|
||||
ast_mutex_lock(&p->lock);
|
||||
switch (ast_test_flag(p, SIP_DTMF)) {
|
||||
|
@ -1969,7 +2001,7 @@ static int sip_senddigit(struct ast_channel *ast, char digit)
|
|||
/*--- sip_transfer: Transfer SIP call */
|
||||
static int sip_transfer(struct ast_channel *ast, char *dest)
|
||||
{
|
||||
struct sip_pvt *p = ast->pvt->pvt;
|
||||
struct sip_pvt *p = ast->tech_pvt;
|
||||
int res;
|
||||
|
||||
ast_mutex_lock(&p->lock);
|
||||
|
@ -1987,7 +2019,7 @@ static int sip_transfer(struct ast_channel *ast, char *dest)
|
|||
the indication - busy signal, congestion etc */
|
||||
static int sip_indicate(struct ast_channel *ast, int condition)
|
||||
{
|
||||
struct sip_pvt *p = ast->pvt->pvt;
|
||||
struct sip_pvt *p = ast->tech_pvt;
|
||||
int res = 0;
|
||||
|
||||
ast_mutex_lock(&p->lock);
|
||||
|
@ -2061,6 +2093,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
|
|||
tmp = ast_channel_alloc(1);
|
||||
ast_mutex_lock(&i->lock);
|
||||
if (tmp) {
|
||||
tmp->tech = &sip_tech;
|
||||
/* Select our native format based on codec preference until we receive
|
||||
something from another device to the contrary. */
|
||||
ast_mutex_lock(&i->lock);
|
||||
|
@ -2100,23 +2133,10 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, char *title)
|
|||
tmp->rings = 1;
|
||||
tmp->adsicpe = AST_ADSI_UNAVAILABLE;
|
||||
tmp->writeformat = fmt;
|
||||
tmp->pvt->rawwriteformat = fmt;
|
||||
tmp->rawwriteformat = fmt;
|
||||
tmp->readformat = fmt;
|
||||
tmp->pvt->rawreadformat = fmt;
|
||||
tmp->pvt->pvt = i;
|
||||
tmp->pvt->send_text = sip_sendtext;
|
||||
tmp->pvt->call = sip_call;
|
||||
tmp->pvt->hangup = sip_hangup;
|
||||
tmp->pvt->answer = sip_answer;
|
||||
tmp->pvt->read = sip_read;
|
||||
tmp->pvt->write = sip_write;
|
||||
tmp->pvt->write_video = sip_write;
|
||||
tmp->pvt->indicate = sip_indicate;
|
||||
tmp->pvt->transfer = sip_transfer;
|
||||
tmp->pvt->fixup = sip_fixup;
|
||||
tmp->pvt->send_digit = sip_senddigit;
|
||||
|
||||
tmp->pvt->bridge = ast_rtp_bridge;
|
||||
tmp->rawreadformat = fmt;
|
||||
tmp->tech_pvt = i;
|
||||
|
||||
tmp->callgroup = i->callgroup;
|
||||
tmp->pickupgroup = i->pickupgroup;
|
||||
|
@ -2337,7 +2357,7 @@ static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p
|
|||
static struct ast_frame *sip_read(struct ast_channel *ast)
|
||||
{
|
||||
struct ast_frame *fr;
|
||||
struct sip_pvt *p = ast->pvt->pvt;
|
||||
struct sip_pvt *p = ast->tech_pvt;
|
||||
ast_mutex_lock(&p->lock);
|
||||
fr = sip_rtp_read(ast, p);
|
||||
time(&p->lastrtprx);
|
||||
|
@ -9762,7 +9782,7 @@ static struct ast_rtp *sip_get_rtp_peer(struct ast_channel *chan)
|
|||
{
|
||||
struct sip_pvt *p;
|
||||
struct ast_rtp *rtp = NULL;
|
||||
p = chan->pvt->pvt;
|
||||
p = chan->tech_pvt;
|
||||
if (p) {
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (p->rtp && ast_test_flag(p, SIP_CAN_REINVITE))
|
||||
|
@ -9776,7 +9796,7 @@ static struct ast_rtp *sip_get_vrtp_peer(struct ast_channel *chan)
|
|||
{
|
||||
struct sip_pvt *p;
|
||||
struct ast_rtp *rtp = NULL;
|
||||
p = chan->pvt->pvt;
|
||||
p = chan->tech_pvt;
|
||||
if (p) {
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (p->vrtp && ast_test_flag(p, SIP_CAN_REINVITE))
|
||||
|
@ -9790,7 +9810,7 @@ static struct ast_rtp *sip_get_vrtp_peer(struct ast_channel *chan)
|
|||
static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs)
|
||||
{
|
||||
struct sip_pvt *p;
|
||||
p = chan->pvt->pvt;
|
||||
p = chan->tech_pvt;
|
||||
if (p) {
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (rtp)
|
||||
|
@ -9861,7 +9881,7 @@ static int sip_dtmfmode(struct ast_channel *chan, void *data)
|
|||
ast_mutex_unlock(&chan->lock);
|
||||
return 0;
|
||||
}
|
||||
p = chan->pvt->pvt;
|
||||
p = chan->tech_pvt;
|
||||
if (p) {
|
||||
ast_mutex_lock(&p->lock);
|
||||
if (!strcasecmp(mode,"info")) {
|
||||
|
@ -9966,7 +9986,7 @@ static int sip_getheader(struct ast_channel *chan, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
p = chan->pvt->pvt;
|
||||
p = chan->tech_pvt;
|
||||
content = get_header(&p->initreq, header); /* Get the header */
|
||||
if (!ast_strlen_zero(content)) {
|
||||
pbx_builtin_setvar_helper(chan, varname, content);
|
||||
|
@ -10064,12 +10084,13 @@ static int sip_sipredirect(struct sip_pvt *p, char *dest)
|
|||
/*--- sip_get_codec: Return peers codec ---*/
|
||||
static int sip_get_codec(struct ast_channel *chan)
|
||||
{
|
||||
struct sip_pvt *p = chan->pvt->pvt;
|
||||
struct sip_pvt *p = chan->tech_pvt;
|
||||
return p->peercapability;
|
||||
}
|
||||
|
||||
/*--- sip_rtp: Interface structure with callbacks used to connect to rtp module --*/
|
||||
static struct ast_rtp_protocol sip_rtp = {
|
||||
type: channeltype,
|
||||
get_rtp_info: sip_get_rtp_peer,
|
||||
get_vrtp_info: sip_get_vrtp_peer,
|
||||
set_rtp_peer: sip_set_rtp_peer,
|
||||
|
@ -10170,7 +10191,7 @@ int load_module()
|
|||
res = reload_config();
|
||||
if (!res) {
|
||||
/* Make sure we can register our sip channel type */
|
||||
if (ast_channel_register_ex(channeltype, tdesc, ((AST_FORMAT_MAX_AUDIO << 1) - 1), sip_request, sip_devicestate)) {
|
||||
if (ast_channel_register(&sip_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
|
||||
return -1;
|
||||
}
|
||||
|
@ -10194,7 +10215,6 @@ int load_module()
|
|||
ast_cli_register(&cli_no_history);
|
||||
ast_cli_register(&cli_sip_reload);
|
||||
ast_cli_register(&cli_inuse_show);
|
||||
sip_rtp.type = channeltype;
|
||||
ast_rtp_proto_register(&sip_rtp);
|
||||
ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
|
||||
ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
|
||||
|
@ -10237,7 +10257,7 @@ int unload_module()
|
|||
ast_cli_unregister(&cli_sip_reload);
|
||||
ast_cli_unregister(&cli_inuse_show);
|
||||
ast_rtp_proto_unregister(&sip_rtp);
|
||||
ast_channel_unregister(channeltype);
|
||||
ast_channel_unregister(&sip_tech);
|
||||
if (!ast_mutex_lock(&iflock)) {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
p = iflist;
|
||||
|
@ -10310,7 +10330,7 @@ char *key()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -56,10 +55,10 @@
|
|||
/************************************************************************************/
|
||||
/* Skinny/Asterisk Protocol Settings */
|
||||
/************************************************************************************/
|
||||
static char *desc = "Skinny Client Control Protocol (Skinny)";
|
||||
static char *tdesc = "Skinny Client Control Protocol (Skinny)";
|
||||
static char *type = "Skinny";
|
||||
static char *config = "skinny.conf";
|
||||
static const char desc[] = "Skinny Client Control Protocol (Skinny)";
|
||||
static const char tdesc[] = "Skinny Client Control Protocol (Skinny)";
|
||||
static const char type[] = "Skinny";
|
||||
static const char config[] = "skinny.conf";
|
||||
|
||||
/* Just about everybody seems to support ulaw, so make it a nice default */
|
||||
static int capability = AST_FORMAT_ULAW;
|
||||
|
@ -796,6 +795,32 @@ static struct skinnysession {
|
|||
struct skinnysession *next;
|
||||
} *sessions = NULL;
|
||||
|
||||
static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause);
|
||||
static int skinny_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int skinny_hangup(struct ast_channel *ast);
|
||||
static int skinny_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *skinny_read(struct ast_channel *ast);
|
||||
static int skinny_write(struct ast_channel *ast, struct ast_frame *frame);
|
||||
static int skinny_indicate(struct ast_channel *ast, int ind);
|
||||
static int skinny_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
static int skinny_senddigit(struct ast_channel *ast, char digit);
|
||||
|
||||
static const struct ast_channel_tech skinny_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_ULAW,
|
||||
.requester = skinny_request,
|
||||
.call = skinny_call,
|
||||
.hangup = skinny_hangup,
|
||||
.answer = skinny_answer,
|
||||
.read = skinny_read,
|
||||
.write = skinny_write,
|
||||
.indicate = skinny_indicate,
|
||||
.fixup = skinny_fixup,
|
||||
.send_digit = skinny_senddigit,
|
||||
/* .bridge = ast_rtp_bridge, */
|
||||
};
|
||||
|
||||
static skinny_req *req_alloc(size_t size)
|
||||
{
|
||||
skinny_req *req;
|
||||
|
@ -1103,7 +1128,7 @@ static struct ast_rtp *skinny_get_vrtp_peer(struct ast_channel *chan)
|
|||
static struct ast_rtp *skinny_get_rtp_peer(struct ast_channel *chan)
|
||||
{
|
||||
struct skinny_subchannel *sub;
|
||||
sub = chan->pvt->pvt;
|
||||
sub = chan->tech_pvt;
|
||||
if (sub && sub->rtp)
|
||||
return sub->rtp;
|
||||
return NULL;
|
||||
|
@ -1112,7 +1137,7 @@ static struct ast_rtp *skinny_get_rtp_peer(struct ast_channel *chan)
|
|||
static int skinny_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs)
|
||||
{
|
||||
struct skinny_subchannel *sub;
|
||||
sub = chan->pvt->pvt;
|
||||
sub = chan->tech_pvt;
|
||||
if (sub) {
|
||||
/* transmit_modify_with_sdp(sub, rtp); @@FIXME@@ if needed */
|
||||
return 0;
|
||||
|
@ -1121,9 +1146,10 @@ static int skinny_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, st
|
|||
}
|
||||
|
||||
static struct ast_rtp_protocol skinny_rtp = {
|
||||
get_rtp_info: skinny_get_rtp_peer,
|
||||
get_vrtp_info: skinny_get_vrtp_peer,
|
||||
set_rtp_peer: skinny_set_rtp_peer,
|
||||
.type = type,
|
||||
.get_rtp_info = skinny_get_rtp_peer,
|
||||
.get_vrtp_info = skinny_get_vrtp_peer,
|
||||
.set_rtp_peer = skinny_set_rtp_peer,
|
||||
};
|
||||
|
||||
static int skinny_do_debug(int fd, int argc, char *argv[])
|
||||
|
@ -1403,7 +1429,7 @@ static void start_rtp(struct skinny_subchannel *sub)
|
|||
static void *skinny_ss(void *data)
|
||||
{
|
||||
struct ast_channel *chan = data;
|
||||
struct skinny_subchannel *sub = chan->pvt->pvt;
|
||||
struct skinny_subchannel *sub = chan->tech_pvt;
|
||||
struct skinny_line *l = sub->parent;
|
||||
struct skinnysession *s = l->parent->session;
|
||||
char exten[AST_MAX_EXTENSION] = "";
|
||||
|
@ -1627,7 +1653,7 @@ static int skinny_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
struct skinny_subchannel *sub;
|
||||
struct skinnysession *session;
|
||||
|
||||
sub = ast->pvt->pvt;
|
||||
sub = ast->tech_pvt;
|
||||
l = sub->parent;
|
||||
session = l->parent->session;
|
||||
|
||||
|
@ -1736,14 +1762,14 @@ static int skinny_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
|
||||
static int skinny_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct skinny_subchannel *sub = ast->pvt->pvt;
|
||||
struct skinny_subchannel *sub = ast->tech_pvt;
|
||||
struct skinny_line *l = sub->parent;
|
||||
struct skinnysession *s = l->parent->session;
|
||||
|
||||
if (skinnydebug) {
|
||||
ast_verbose("skinny_hangup(%s) on %s@%s\n", ast->name, l->name, l->parent->name);
|
||||
}
|
||||
if (!ast->pvt->pvt) {
|
||||
if (!ast->tech_pvt) {
|
||||
ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1765,7 +1791,7 @@ static int skinny_hangup(struct ast_channel *ast)
|
|||
}
|
||||
ast_mutex_lock(&sub->lock);
|
||||
sub->owner = NULL;
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
sub->alreadygone = 0;
|
||||
sub->outgoing = 0;
|
||||
if (sub->rtp) {
|
||||
|
@ -1779,7 +1805,7 @@ static int skinny_hangup(struct ast_channel *ast)
|
|||
static int skinny_answer(struct ast_channel *ast)
|
||||
{
|
||||
int res = 0;
|
||||
struct skinny_subchannel *sub = ast->pvt->pvt;
|
||||
struct skinny_subchannel *sub = ast->tech_pvt;
|
||||
struct skinny_line *l = sub->parent;
|
||||
sub->cxmode = SKINNY_CX_SENDRECV;
|
||||
if (!sub->rtp) {
|
||||
|
@ -1814,7 +1840,7 @@ static struct ast_frame *skinny_rtp_read(struct skinny_subchannel *sub)
|
|||
static struct ast_frame *skinny_read(struct ast_channel *ast)
|
||||
{
|
||||
struct ast_frame *fr;
|
||||
struct skinny_subchannel *sub = ast->pvt->pvt;
|
||||
struct skinny_subchannel *sub = ast->tech_pvt;
|
||||
ast_mutex_lock(&sub->lock);
|
||||
fr = skinny_rtp_read(sub);
|
||||
ast_mutex_unlock(&sub->lock);
|
||||
|
@ -1823,7 +1849,7 @@ static struct ast_frame *skinny_read(struct ast_channel *ast)
|
|||
|
||||
static int skinny_write(struct ast_channel *ast, struct ast_frame *frame)
|
||||
{
|
||||
struct skinny_subchannel *sub = ast->pvt->pvt;
|
||||
struct skinny_subchannel *sub = ast->tech_pvt;
|
||||
int res = 0;
|
||||
if (frame->frametype != AST_FRAME_VOICE) {
|
||||
if (frame->frametype == AST_FRAME_IMAGE)
|
||||
|
@ -1851,7 +1877,7 @@ static int skinny_write(struct ast_channel *ast, struct ast_frame *frame)
|
|||
|
||||
static int skinny_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct skinny_subchannel *sub = newchan->pvt->pvt;
|
||||
struct skinny_subchannel *sub = newchan->tech_pvt;
|
||||
ast_log(LOG_NOTICE, "skinny_fixup(%s, %s)\n", oldchan->name, newchan->name);
|
||||
if (sub->owner != oldchan) {
|
||||
ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner);
|
||||
|
@ -1864,7 +1890,7 @@ static int skinny_fixup(struct ast_channel *oldchan, struct ast_channel *newchan
|
|||
static int skinny_senddigit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
#if 0
|
||||
struct skinny_subchannel *sub = ast->pvt->pvt;
|
||||
struct skinny_subchannel *sub = ast->tech_pvt;
|
||||
int tmp;
|
||||
/* not right */
|
||||
sprintf(tmp, "%d", digit);
|
||||
|
@ -1910,7 +1936,7 @@ static char *control2str(int ind) {
|
|||
|
||||
static int skinny_indicate(struct ast_channel *ast, int ind)
|
||||
{
|
||||
struct skinny_subchannel *sub = ast->pvt->pvt;
|
||||
struct skinny_subchannel *sub = ast->tech_pvt;
|
||||
struct skinny_line *l = sub->parent;
|
||||
struct skinnysession *s = l->parent->session;
|
||||
|
||||
|
@ -1973,6 +1999,7 @@ static struct ast_channel *skinny_new(struct skinny_subchannel *sub, int state)
|
|||
l = sub->parent;
|
||||
tmp = ast_channel_alloc(1);
|
||||
if (tmp) {
|
||||
tmp->tech = &skinny_tech;
|
||||
tmp->nativeformats = l->capability;
|
||||
if (!tmp->nativeformats)
|
||||
tmp->nativeformats = capability;
|
||||
|
@ -1985,19 +2012,10 @@ static struct ast_channel *skinny_new(struct skinny_subchannel *sub, int state)
|
|||
if (state == AST_STATE_RING)
|
||||
tmp->rings = 1;
|
||||
tmp->writeformat = fmt;
|
||||
tmp->pvt->rawwriteformat = fmt;
|
||||
tmp->rawwriteformat = fmt;
|
||||
tmp->readformat = fmt;
|
||||
tmp->pvt->rawreadformat = fmt;
|
||||
tmp->pvt->pvt = sub;
|
||||
tmp->pvt->call = skinny_call;
|
||||
tmp->pvt->hangup = skinny_hangup;
|
||||
tmp->pvt->answer = skinny_answer;
|
||||
tmp->pvt->read = skinny_read;
|
||||
tmp->pvt->write = skinny_write;
|
||||
tmp->pvt->indicate = skinny_indicate;
|
||||
tmp->pvt->fixup = skinny_fixup;
|
||||
tmp->pvt->send_digit = skinny_senddigit;
|
||||
/* tmp->pvt->bridge = ast_rtp_bridge; */
|
||||
tmp->rawreadformat = fmt;
|
||||
tmp->tech_pvt = sub;
|
||||
if (!ast_strlen_zero(l->language))
|
||||
strncpy(tmp->language, l->language, sizeof(tmp->language)-1);
|
||||
if (!ast_strlen_zero(l->accountcode))
|
||||
|
@ -3019,12 +3037,11 @@ int load_module()
|
|||
/* Announce our presence to Asterisk */
|
||||
if (!res) {
|
||||
/* Make sure we can register our skinny channel type */
|
||||
if (ast_channel_register(type, tdesc, capability, skinny_request)) {
|
||||
if (ast_channel_register(&skinny_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
skinny_rtp.type = type;
|
||||
ast_rtp_proto_register(&skinny_rtp);
|
||||
ast_cli_register(&cli_show_lines);
|
||||
ast_cli_register(&cli_debug);
|
||||
|
@ -3088,6 +3105,7 @@ int unload_module()
|
|||
}
|
||||
|
||||
ast_rtp_proto_register(&skinny_rtp);
|
||||
ast_channel_unregister(&skinny_tech);
|
||||
ast_cli_register(&cli_show_lines);
|
||||
ast_cli_register(&cli_debug);
|
||||
ast_cli_register(&cli_no_debug);
|
||||
|
@ -3113,5 +3131,5 @@ char *key()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ extern "C" {
|
|||
#include <asterisk/lock.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -76,10 +75,10 @@ extern "C" {
|
|||
#endif
|
||||
/**/
|
||||
|
||||
static char *desc = "VoiceTronix V6PCI/V12PCI/V4PCI API Support";
|
||||
static char *type = "vpb";
|
||||
static char *tdesc = "Standard VoiceTronix API Driver";
|
||||
static char *config = "vpb.conf";
|
||||
static const char desc[] = "VoiceTronix V6PCI/V12PCI/V4PCI API Support";
|
||||
static const char type[] = "vpb";
|
||||
static const char tdesc[] = "Standard VoiceTronix API Driver";
|
||||
static const char config[] = "vpb.conf";
|
||||
|
||||
/* Default context for dialtone mode */
|
||||
static char context[AST_MAX_EXTENSION] = "default";
|
||||
|
@ -311,6 +310,33 @@ static struct vpb_pvt {
|
|||
static struct ast_channel *vpb_new(struct vpb_pvt *i, int state, char *context);
|
||||
static void *do_chanreads(void *pvt);
|
||||
|
||||
static struct ast_channel *vpb_request(const char *type, int format, void *data, int *cause);
|
||||
static int vpb_digit(struct ast_channel *ast, char digit);
|
||||
static int vpb_call(struct ast_channel *ast, char *dest, int timeout);
|
||||
static int vpb_hangup(struct ast_channel *ast);
|
||||
static int vpb_answer(struct ast_channel *ast);
|
||||
static struct ast_frame *vpb_read(struct ast_channel *ast);
|
||||
static int vpb_write(struct ast_channel *ast, struct ast_frame *frame);
|
||||
static int vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
|
||||
static int vpb_indicate(struct ast_channel *ast, int condition);
|
||||
static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
|
||||
static const struct ast_channel_tech vpb_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_SLINEAR,
|
||||
.requester = vpb_request,
|
||||
.send_digit = vpb_digit,
|
||||
.call = vpb_call,
|
||||
.hangup = vpb_hangup,
|
||||
.answer = vpb_answer,
|
||||
.read = vpb_read,
|
||||
.write = vpb_write,
|
||||
.bridge = vpb_bridge,
|
||||
.indicate = vpb_indicate,
|
||||
.fixup = vpb_fixup,
|
||||
};
|
||||
|
||||
/* Can't get vpb_bridge() working on v4pci without either a horrible
|
||||
* high pitched feedback noise or bad hiss noise depending on gain settings
|
||||
* Get asterisk to do the bridging
|
||||
|
@ -325,8 +351,8 @@ static void *do_chanreads(void *pvt);
|
|||
/* This is the Native bridge code, which Asterisk will try before using its own bridging code */
|
||||
static int vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
|
||||
{
|
||||
struct vpb_pvt *p0 = (struct vpb_pvt *)c0->pvt->pvt;
|
||||
struct vpb_pvt *p1 = (struct vpb_pvt *)c1->pvt->pvt;
|
||||
struct vpb_pvt *p0 = (struct vpb_pvt *)c0->tech_pvt;
|
||||
struct vpb_pvt *p1 = (struct vpb_pvt *)c1->tech_pvt;
|
||||
int i, res;
|
||||
|
||||
struct ast_channel *cs[3];
|
||||
|
@ -449,11 +475,11 @@ static int vpb_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
|
|||
*rc = who;
|
||||
ast_log(LOG_DEBUG, "%s: vpb_bridge: Got a [%s]\n",p0->dev, f ? "digit" : "hangup");
|
||||
/*
|
||||
if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
|
||||
if ((c0->tech_pvt == pvt0) && (!c0->_softhangup)) {
|
||||
if (pr0->set_rtp_peer(c0, NULL, NULL, 0))
|
||||
ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
|
||||
}
|
||||
if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
|
||||
if ((c1->tech_pvt == pvt1) && (!c1->_softhangup)) {
|
||||
if (pr1->set_rtp_peer(c1, NULL, NULL, 0))
|
||||
ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
|
||||
}
|
||||
|
@ -1556,10 +1582,13 @@ static struct vpb_pvt *mkif(int board, int channel, int mode, int gains, float t
|
|||
|
||||
static int vpb_indicate(struct ast_channel *ast, int condition)
|
||||
{
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->pvt->pvt;
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
|
||||
int res = 0;
|
||||
int tmp = 0;
|
||||
|
||||
if (!use_ast_ind)
|
||||
return 0;
|
||||
|
||||
if (option_verbose > 3)
|
||||
ast_verbose(VERBOSE_PREFIX_4 "%s: vpb_indicate [%d] state[%d]\n", p->dev, condition,ast->_state);
|
||||
/*
|
||||
|
@ -1623,7 +1652,7 @@ static int vpb_indicate(struct ast_channel *ast, int condition)
|
|||
|
||||
static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)newchan->pvt->pvt;
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)newchan->tech_pvt;
|
||||
int res = 0;
|
||||
|
||||
/*
|
||||
|
@ -1653,10 +1682,13 @@ static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
|||
|
||||
static int vpb_digit(struct ast_channel *ast, char digit)
|
||||
{
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->pvt->pvt;
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
|
||||
char s[2];
|
||||
int res = 0;
|
||||
|
||||
if (!use_ast_dtmf)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
if (option_verbose > 3) ast_verbose("%s: LOCKING in digit \n", p->dev);
|
||||
if (option_verbose > 3) ast_verbose("%s: LOCKING count[%d] owner[%d] \n", p->dev, p->lock.__m_count,p->lock.__m_owner);
|
||||
|
@ -1684,7 +1716,7 @@ static int vpb_digit(struct ast_channel *ast, char digit)
|
|||
/* Places a call out of a VPB channel */
|
||||
static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
|
||||
{
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->pvt->pvt;
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
|
||||
int res = 0,i;
|
||||
char *s = strrchr(dest, '/');
|
||||
char dialstring[254] = "";
|
||||
|
@ -1798,7 +1830,7 @@ static int vpb_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
|
||||
static int vpb_hangup(struct ast_channel *ast)
|
||||
{
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->pvt->pvt;
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
|
||||
VPB_EVENT je;
|
||||
char str[VPB_MAX_STR];
|
||||
int res =0 ;
|
||||
|
@ -1812,8 +1844,7 @@ static int vpb_hangup(struct ast_channel *ast)
|
|||
if (option_verbose > 1)
|
||||
ast_verbose(VERBOSE_PREFIX_2 "%s: Hangup requested\n", ast->name);
|
||||
|
||||
|
||||
if (!ast->pvt || !ast->pvt->pvt) {
|
||||
if (!ast->tech || !ast->tech_pvt) {
|
||||
ast_log(LOG_WARNING, "%s: channel not connected?\n", ast->name);
|
||||
res = ast_mutex_unlock(&p->lock);
|
||||
/*
|
||||
|
@ -1894,7 +1925,7 @@ static int vpb_hangup(struct ast_channel *ast)
|
|||
p->dialtone = 0;
|
||||
|
||||
p->owner = NULL;
|
||||
ast->pvt->pvt=NULL;
|
||||
ast->tech_pvt=NULL;
|
||||
|
||||
/* Free up ast dsp if we have one */
|
||||
if ((use_ast_dtmfdet)&&(p->vad)) {
|
||||
|
@ -1924,7 +1955,7 @@ static int vpb_hangup(struct ast_channel *ast)
|
|||
|
||||
static int vpb_answer(struct ast_channel *ast)
|
||||
{
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->pvt->pvt;
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
|
||||
VPB_EVENT je;
|
||||
int ret;
|
||||
int res = 0;
|
||||
|
@ -1998,7 +2029,7 @@ static int vpb_answer(struct ast_channel *ast)
|
|||
|
||||
static struct ast_frame *vpb_read(struct ast_channel *ast)
|
||||
{
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->pvt->pvt;
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
|
||||
static struct ast_frame f = {AST_FRAME_NULL};
|
||||
|
||||
f.src = type;
|
||||
|
@ -2073,7 +2104,7 @@ int a_gain_vector(float g, short *v, int n)
|
|||
/* Writes a frame of voice data to a VPB channel */
|
||||
static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
|
||||
{
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->pvt->pvt;
|
||||
struct vpb_pvt *p = (struct vpb_pvt *)ast->tech_pvt;
|
||||
int res = 0, fmt = 0;
|
||||
struct timeval play_buf_time_start,play_buf_time_finish;
|
||||
/* ast_mutex_lock(&p->lock); */
|
||||
|
@ -2279,9 +2310,9 @@ static void *do_chanreads(void *pvt)
|
|||
}
|
||||
ast_mutex_unlock(&p->play_dtmf_lock);
|
||||
|
||||
/* afmt = (p->owner) ? p->owner->pvt->rawreadformat : AST_FORMAT_SLINEAR; */
|
||||
/* afmt = (p->owner) ? p->owner->rawreadformat : AST_FORMAT_SLINEAR; */
|
||||
if (p->owner){
|
||||
afmt = p->owner->pvt->rawreadformat;
|
||||
afmt = p->owner->rawreadformat;
|
||||
/* ast_log(LOG_DEBUG,"%s: Record using owner format [%s]\n", p->dev, ast2vpbformatname(afmt)); */
|
||||
}
|
||||
else {
|
||||
|
@ -2437,6 +2468,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
|
|||
|
||||
tmp = ast_channel_alloc(1);
|
||||
if (tmp) {
|
||||
tmp->tech = &vpb_tech;
|
||||
strncpy(tmp->name, me->dev, sizeof(tmp->name) - 1);
|
||||
tmp->type = type;
|
||||
|
||||
|
@ -2445,8 +2477,8 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
|
|||
* linear since we can then adjust volume in this modules.
|
||||
*/
|
||||
tmp->nativeformats = prefformat;
|
||||
tmp->pvt->rawreadformat = AST_FORMAT_SLINEAR;
|
||||
tmp->pvt->rawwriteformat = AST_FORMAT_SLINEAR;
|
||||
tmp->rawreadformat = AST_FORMAT_SLINEAR;
|
||||
tmp->rawwriteformat = AST_FORMAT_SLINEAR;
|
||||
ast_setstate(tmp, state);
|
||||
if (state == AST_STATE_RING) {
|
||||
tmp->rings = 1;
|
||||
|
@ -2455,19 +2487,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
|
|||
ast_callerid_split(me->callerid, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));
|
||||
ast_set_callerid(tmp, cid_num, cid_name, cid_num);
|
||||
}
|
||||
tmp->pvt->pvt = me;
|
||||
/* set call backs */
|
||||
if (use_ast_dtmf == 0)
|
||||
tmp->pvt->send_digit = vpb_digit;
|
||||
tmp->pvt->call = vpb_call;
|
||||
tmp->pvt->hangup = vpb_hangup;
|
||||
tmp->pvt->answer = vpb_answer;
|
||||
tmp->pvt->read = vpb_read;
|
||||
tmp->pvt->write = vpb_write;
|
||||
tmp->pvt->bridge = vpb_bridge;
|
||||
if (use_ast_ind == 0)
|
||||
tmp->pvt->indicate = vpb_indicate;
|
||||
tmp->pvt->fixup = vpb_fixup;
|
||||
tmp->tech_pvt = me;
|
||||
|
||||
strncpy(tmp->context, context, sizeof(tmp->context)-1);
|
||||
if (strlen(me->ext))
|
||||
|
@ -2741,7 +2761,7 @@ int load_module()
|
|||
|
||||
ast_config_destroy(cfg);
|
||||
|
||||
if (!error && ast_channel_register(type, tdesc, prefformat, vpb_request) != 0) {
|
||||
if (!error && ast_channel_register(&vpb_tech) != 0) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
error = -1;
|
||||
}
|
||||
|
@ -2760,7 +2780,7 @@ int unload_module()
|
|||
{
|
||||
struct vpb_pvt *p;
|
||||
/* First, take us out of the channel loop */
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(&vpb_tech);
|
||||
|
||||
ast_mutex_lock(&iflock); {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
|
@ -2827,7 +2847,7 @@ int usecount()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
char *key()
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <string.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
|
@ -97,7 +96,7 @@
|
|||
|
||||
#define AST_LAW(p) (((p)->law == ZT_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
|
||||
|
||||
static char *desc = "Zapata Telephony"
|
||||
static const char desc[] = "Zapata Telephony"
|
||||
#ifdef ZAPATA_PRI
|
||||
" w/PRI"
|
||||
#endif
|
||||
|
@ -106,7 +105,7 @@ static char *desc = "Zapata Telephony"
|
|||
#endif
|
||||
;
|
||||
|
||||
static char *tdesc = "Zapata Telephony Driver"
|
||||
static const char tdesc[] = "Zapata Telephony Driver"
|
||||
#ifdef ZAPATA_PRI
|
||||
" w/PRI"
|
||||
#endif
|
||||
|
@ -115,8 +114,8 @@ static char *tdesc = "Zapata Telephony Driver"
|
|||
#endif
|
||||
;
|
||||
|
||||
static char *type = "Zap";
|
||||
static char *config = "zapata.conf";
|
||||
static const char type[] = "Zap";
|
||||
static const char config[] = "zapata.conf";
|
||||
|
||||
#define SIG_EM ZT_SIG_EM
|
||||
#define SIG_EMWINK (0x100000 | ZT_SIG_EM)
|
||||
|
@ -614,6 +613,39 @@ static struct zt_pvt {
|
|||
int polarity;
|
||||
} *iflist = NULL, *ifend = NULL;
|
||||
|
||||
static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
|
||||
static int zt_digit(struct ast_channel *ast, char digit);
|
||||
static int zt_sendtext(struct ast_channel *c, char *text);
|
||||
static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
|
||||
static int zt_hangup(struct ast_channel *ast);
|
||||
static int zt_answer(struct ast_channel *ast);
|
||||
struct ast_frame *zt_read(struct ast_channel *ast);
|
||||
static int zt_write(struct ast_channel *ast, struct ast_frame *frame);
|
||||
static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
|
||||
struct ast_frame *zt_exception(struct ast_channel *ast);
|
||||
static int zt_indicate(struct ast_channel *chan, int condition);
|
||||
static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
|
||||
|
||||
static const struct ast_channel_tech zap_tech = {
|
||||
.type = type,
|
||||
.description = tdesc,
|
||||
.capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW,
|
||||
.requester = zt_request,
|
||||
.send_digit = zt_digit,
|
||||
.send_text = zt_sendtext,
|
||||
.call = zt_call,
|
||||
.hangup = zt_hangup,
|
||||
.answer = zt_answer,
|
||||
.read = zt_read,
|
||||
.write = zt_write,
|
||||
.bridge = zt_bridge,
|
||||
.exception = zt_exception,
|
||||
.indicate = zt_indicate,
|
||||
.fixup = zt_fixup,
|
||||
.setoption = zt_setoption,
|
||||
};
|
||||
|
||||
#ifdef ZAPATA_PRI
|
||||
#define GET_CHANNEL(p) ((p)->bearer ? (p)->bearer->channel : p->channel)
|
||||
#else
|
||||
|
@ -908,7 +940,7 @@ static int zt_digit(struct ast_channel *ast, char digit)
|
|||
struct zt_pvt *p;
|
||||
int res = 0;
|
||||
int index;
|
||||
p = ast->pvt->pvt;
|
||||
p = ast->tech_pvt;
|
||||
ast_mutex_lock(&p->lock);
|
||||
index = zt_get_index(ast, p, 0);
|
||||
if ((index == SUB_REAL) && p->owner) {
|
||||
|
@ -1505,7 +1537,7 @@ static int send_callerid(struct zt_pvt *p)
|
|||
|
||||
static int zt_callwait(struct ast_channel *ast)
|
||||
{
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
|
||||
if (p->cidspill) {
|
||||
ast_log(LOG_WARNING, "Spill already exists?!?\n");
|
||||
|
@ -1536,7 +1568,7 @@ static int zt_callwait(struct ast_channel *ast)
|
|||
|
||||
static int zt_call(struct ast_channel *ast, char *rdest, int timeout)
|
||||
{
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
int x, res, index;
|
||||
char *c, *n, *l;
|
||||
#ifdef ZAPATA_PRI
|
||||
|
@ -2026,14 +2058,14 @@ static int zt_hangup(struct ast_channel *ast)
|
|||
int res;
|
||||
int index,x, law;
|
||||
/*static int restore_gains(struct zt_pvt *p);*/
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
struct zt_pvt *tmp = NULL;
|
||||
struct zt_pvt *prev = NULL;
|
||||
ZT_PARAMS par;
|
||||
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "zt_hangup(%s)\n", ast->name);
|
||||
if (!ast->pvt->pvt) {
|
||||
if (!ast->tech_pvt) {
|
||||
ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -2314,7 +2346,7 @@ static int zt_hangup(struct ast_channel *ast)
|
|||
|
||||
p->callwaitingrepeat = 0;
|
||||
p->cidcwexpire = 0;
|
||||
ast->pvt->pvt = NULL;
|
||||
ast->tech_pvt = NULL;
|
||||
ast_mutex_unlock(&p->lock);
|
||||
ast_mutex_lock(&usecnt_lock);
|
||||
usecnt--;
|
||||
|
@ -2345,7 +2377,7 @@ static int zt_hangup(struct ast_channel *ast)
|
|||
|
||||
static int zt_answer(struct ast_channel *ast)
|
||||
{
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
int res=0;
|
||||
int index;
|
||||
int oldstate = ast->_state;
|
||||
|
@ -2437,7 +2469,7 @@ static int zt_setoption(struct ast_channel *chan, int option, void *data, int da
|
|||
char *cp;
|
||||
int x;
|
||||
|
||||
struct zt_pvt *p = chan->pvt->pvt;
|
||||
struct zt_pvt *p = chan->tech_pvt;
|
||||
|
||||
|
||||
if ((option != AST_OPTION_TONE_VERIFY) && (option != AST_OPTION_AUDIO_MODE) &&
|
||||
|
@ -2680,8 +2712,8 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
|
|||
ast_mutex_lock(&c0->lock);
|
||||
ast_mutex_lock(&c1->lock);
|
||||
|
||||
p0 = c0->pvt->pvt;
|
||||
p1 = c1->pvt->pvt;
|
||||
p0 = c0->tech_pvt;
|
||||
p1 = c1->tech_pvt;
|
||||
/* cant do pseudo-channels here */
|
||||
if (!p0 || (!p0->sig) || !p1 || (!p1->sig)) {
|
||||
ast_mutex_unlock(&c0->lock);
|
||||
|
@ -2689,8 +2721,8 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
|
|||
return -2;
|
||||
}
|
||||
|
||||
op0 = p0 = c0->pvt->pvt;
|
||||
op1 = p1 = c1->pvt->pvt;
|
||||
op0 = p0 = c0->tech_pvt;
|
||||
op1 = p1 = c1->tech_pvt;
|
||||
ofd1 = c0->fds[0];
|
||||
ofd2 = c1->fds[0];
|
||||
oi1 = zt_get_index(c0, p0, 0);
|
||||
|
@ -2836,8 +2868,8 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
|
|||
and then balking if anything is wrong */
|
||||
ast_mutex_lock(&c0->lock);
|
||||
ast_mutex_lock(&c1->lock);
|
||||
p0 = c0->pvt->pvt;
|
||||
p1 = c1->pvt->pvt;
|
||||
p0 = c0->tech_pvt;
|
||||
p1 = c1->tech_pvt;
|
||||
|
||||
#ifdef PRI_2BCT
|
||||
q931c0 = p0->call;
|
||||
|
@ -2880,14 +2912,14 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
|
|||
ast_log(LOG_DEBUG, "Ooh, empty read...\n");
|
||||
continue;
|
||||
}
|
||||
if (who->pvt->pvt == op0)
|
||||
if (who->tech_pvt == op0)
|
||||
op0->ignoredtmf = 1;
|
||||
else if (who->pvt->pvt == op1)
|
||||
else if (who->tech_pvt == op1)
|
||||
op1->ignoredtmf = 1;
|
||||
f = ast_read(who);
|
||||
if (who->pvt->pvt == op0)
|
||||
if (who->tech_pvt == op0)
|
||||
op0->ignoredtmf = 0;
|
||||
else if (who->pvt->pvt == op1)
|
||||
else if (who->tech_pvt == op1)
|
||||
op1->ignoredtmf = 0;
|
||||
if (!f) {
|
||||
*fo = NULL;
|
||||
|
@ -2930,11 +2962,9 @@ static int zt_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags,
|
|||
}
|
||||
}
|
||||
|
||||
static int zt_indicate(struct ast_channel *chan, int condition);
|
||||
|
||||
static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
|
||||
{
|
||||
struct zt_pvt *p = newchan->pvt->pvt;
|
||||
struct zt_pvt *p = newchan->tech_pvt;
|
||||
int x;
|
||||
ast_mutex_lock(&p->lock);
|
||||
ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
|
||||
|
@ -3173,7 +3203,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
|
|||
int res,x;
|
||||
int index;
|
||||
char *c;
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
pthread_t threadid;
|
||||
pthread_attr_t attr;
|
||||
struct ast_channel *chan;
|
||||
|
@ -3852,7 +3882,7 @@ static struct ast_frame *zt_handle_event(struct ast_channel *ast)
|
|||
|
||||
static struct ast_frame *__zt_exception(struct ast_channel *ast)
|
||||
{
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
int res;
|
||||
int usedindex=-1;
|
||||
int index;
|
||||
|
@ -3957,7 +3987,7 @@ static struct ast_frame *__zt_exception(struct ast_channel *ast)
|
|||
|
||||
struct ast_frame *zt_exception(struct ast_channel *ast)
|
||||
{
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
struct ast_frame *f;
|
||||
ast_mutex_lock(&p->lock);
|
||||
f = __zt_exception(ast);
|
||||
|
@ -3967,7 +3997,7 @@ struct ast_frame *zt_exception(struct ast_channel *ast)
|
|||
|
||||
struct ast_frame *zt_read(struct ast_channel *ast)
|
||||
{
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
int res;
|
||||
int index;
|
||||
void *readbuf;
|
||||
|
@ -4082,15 +4112,15 @@ struct ast_frame *zt_read(struct ast_channel *ast)
|
|||
return &p->subs[index].f;
|
||||
}
|
||||
|
||||
if (ast->pvt->rawreadformat == AST_FORMAT_SLINEAR) {
|
||||
if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
|
||||
if (!p->subs[index].linear) {
|
||||
p->subs[index].linear = 1;
|
||||
res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
|
||||
if (res)
|
||||
ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, index);
|
||||
}
|
||||
} else if ((ast->pvt->rawreadformat == AST_FORMAT_ULAW) ||
|
||||
(ast->pvt->rawreadformat == AST_FORMAT_ALAW)) {
|
||||
} else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
|
||||
(ast->rawreadformat == AST_FORMAT_ALAW)) {
|
||||
if (p->subs[index].linear) {
|
||||
p->subs[index].linear = 0;
|
||||
res = zt_setlinear(p->subs[index].zfd, p->subs[index].linear);
|
||||
|
@ -4098,7 +4128,7 @@ struct ast_frame *zt_read(struct ast_channel *ast)
|
|||
ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to campanded mode.\n", p->channel, index);
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->pvt->rawreadformat));
|
||||
ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
|
||||
ast_mutex_unlock(&p->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -4175,7 +4205,7 @@ struct ast_frame *zt_read(struct ast_channel *ast)
|
|||
}
|
||||
|
||||
p->subs[index].f.frametype = AST_FRAME_VOICE;
|
||||
p->subs[index].f.subclass = ast->pvt->rawreadformat;
|
||||
p->subs[index].f.subclass = ast->rawreadformat;
|
||||
p->subs[index].f.samples = READ_SIZE;
|
||||
p->subs[index].f.mallocd = 0;
|
||||
p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
|
||||
|
@ -4313,7 +4343,7 @@ static int my_zt_write(struct zt_pvt *p, unsigned char *buf, int len, int index,
|
|||
|
||||
static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
|
||||
{
|
||||
struct zt_pvt *p = ast->pvt->pvt;
|
||||
struct zt_pvt *p = ast->tech_pvt;
|
||||
int res;
|
||||
unsigned char outbuf[4096];
|
||||
int index;
|
||||
|
@ -4399,7 +4429,7 @@ static int zt_write(struct ast_channel *ast, struct ast_frame *frame)
|
|||
|
||||
static int zt_indicate(struct ast_channel *chan, int condition)
|
||||
{
|
||||
struct zt_pvt *p = chan->pvt->pvt;
|
||||
struct zt_pvt *p = chan->tech_pvt;
|
||||
int res=-1;
|
||||
int index;
|
||||
int func = ZT_FLASH;
|
||||
|
@ -4606,6 +4636,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
|
|||
}
|
||||
tmp = ast_channel_alloc(0);
|
||||
if (tmp) {
|
||||
tmp->tech = &zap_tech;
|
||||
ps.channo = i->channel;
|
||||
res = ioctl(i->subs[SUB_REAL].zfd, ZT_GET_PARAMS, &ps);
|
||||
if (res) {
|
||||
|
@ -4643,9 +4674,9 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
|
|||
tmp->fds[0] = i->subs[index].zfd;
|
||||
tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw;
|
||||
/* Start out assuming ulaw since it's smaller :) */
|
||||
tmp->pvt->rawreadformat = deflaw;
|
||||
tmp->rawreadformat = deflaw;
|
||||
tmp->readformat = deflaw;
|
||||
tmp->pvt->rawwriteformat = deflaw;
|
||||
tmp->rawwriteformat = deflaw;
|
||||
tmp->writeformat = deflaw;
|
||||
i->subs[index].linear = 0;
|
||||
zt_setlinear(i->subs[index].zfd, i->subs[index].linear);
|
||||
|
@ -4689,19 +4720,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
|
|||
|
||||
if (state == AST_STATE_RING)
|
||||
tmp->rings = 1;
|
||||
tmp->pvt->pvt = i;
|
||||
tmp->pvt->send_digit = zt_digit;
|
||||
tmp->pvt->send_text = zt_sendtext;
|
||||
tmp->pvt->call = zt_call;
|
||||
tmp->pvt->hangup = zt_hangup;
|
||||
tmp->pvt->answer = zt_answer;
|
||||
tmp->pvt->read = zt_read;
|
||||
tmp->pvt->write = zt_write;
|
||||
tmp->pvt->bridge = zt_bridge;
|
||||
tmp->pvt->exception = zt_exception;
|
||||
tmp->pvt->indicate = zt_indicate;
|
||||
tmp->pvt->fixup = zt_fixup;
|
||||
tmp->pvt->setoption = zt_setoption;
|
||||
tmp->tech_pvt = i;
|
||||
if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
|
||||
/* Only FXO signalled stuff can be picked up */
|
||||
tmp->callgroup = i->callgroup;
|
||||
|
@ -4828,7 +4847,7 @@ static int zt_wink(struct zt_pvt *p, int index)
|
|||
static void *ss_thread(void *data)
|
||||
{
|
||||
struct ast_channel *chan = data;
|
||||
struct zt_pvt *p = chan->pvt->pvt;
|
||||
struct zt_pvt *p = chan->tech_pvt;
|
||||
char exten[AST_MAX_EXTENSION]="";
|
||||
char exten2[AST_MAX_EXTENSION]="";
|
||||
unsigned char buf[256];
|
||||
|
@ -5310,7 +5329,7 @@ static void *ss_thread(void *data)
|
|||
struct zt_pvt *pbridge = NULL;
|
||||
/* set up the private struct of the bridged one, if any */
|
||||
if (nbridge && ast_bridged_channel(nbridge))
|
||||
pbridge = ast_bridged_channel(nbridge)->pvt->pvt;
|
||||
pbridge = ast_bridged_channel(nbridge)->tech_pvt;
|
||||
if (nbridge && pbridge &&
|
||||
(!strcmp(nbridge->type,"Zap")) &&
|
||||
(!strcmp(ast_bridged_channel(nbridge)->type, "Zap")) &&
|
||||
|
@ -7286,7 +7305,7 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
|
|||
if (pri->pvts[principle]->owner) {
|
||||
snprintf(pri->pvts[principle]->owner->name, sizeof(pri->pvts[principle]->owner->name),
|
||||
"Zap/%d:%d-%d", pri->trunkgroup, pri->pvts[principle]->channel, 1);
|
||||
pri->pvts[principle]->owner->pvt->pvt = pri->pvts[principle];
|
||||
pri->pvts[principle]->owner->tech_pvt = pri->pvts[principle];
|
||||
pri->pvts[principle]->owner->fds[0] = pri->pvts[principle]->subs[SUB_REAL].zfd;
|
||||
pri->pvts[principle]->subs[SUB_REAL].owner = pri->pvts[x]->subs[SUB_REAL].owner;
|
||||
} else
|
||||
|
@ -7331,7 +7350,7 @@ static int pri_fixup_principle(struct zt_pri *pri, int principle, q931_call *c)
|
|||
static void *do_idle_thread(void *vchan)
|
||||
{
|
||||
struct ast_channel *chan = vchan;
|
||||
struct zt_pvt *pvt = chan->pvt->pvt;
|
||||
struct zt_pvt *pvt = chan->tech_pvt;
|
||||
struct ast_frame *f;
|
||||
char ex[80];
|
||||
/* Wait up to 30 seconds for an answer */
|
||||
|
@ -9291,7 +9310,7 @@ static int __unload_module(void)
|
|||
ast_manager_unregister( "ZapDNDon" );
|
||||
ast_manager_unregister("ZapShowChannels");
|
||||
ast_unregister_application(app_callingpres);
|
||||
ast_channel_unregister(type);
|
||||
ast_channel_unregister(&zap_tech);
|
||||
if (!ast_mutex_lock(&iflock)) {
|
||||
/* Hangup all interfaces if they have an owner */
|
||||
p = iflist;
|
||||
|
@ -10134,7 +10153,7 @@ int load_module(void)
|
|||
if(res) {
|
||||
return -1;
|
||||
}
|
||||
if (ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR | AST_FORMAT_ULAW, zt_request)) {
|
||||
if (ast_channel_register(&zap_tech)) {
|
||||
ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
|
||||
__unload_module();
|
||||
return -1;
|
||||
|
@ -10175,7 +10194,7 @@ static int zt_sendtext(struct ast_channel *c, char *text)
|
|||
#define ASCII_BYTES_PER_CHAR 80
|
||||
|
||||
unsigned char *buf,*mybuf;
|
||||
struct zt_pvt *p = c->pvt->pvt;
|
||||
struct zt_pvt *p = c->tech_pvt;
|
||||
struct pollfd fds[1];
|
||||
int size,res,fd,len,x;
|
||||
int bytes=0;
|
||||
|
@ -10289,7 +10308,7 @@ int usecount()
|
|||
|
||||
char *description()
|
||||
{
|
||||
return desc;
|
||||
return (char *) desc;
|
||||
}
|
||||
|
||||
char *key()
|
||||
|
|
1
cli.c
1
cli.c
|
@ -19,7 +19,6 @@
|
|||
#include <asterisk/module.h>
|
||||
#include <asterisk/pbx.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/manager.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <asterisk/lock.h>
|
||||
|
|
1
dsp.c
1
dsp.c
|
@ -31,7 +31,6 @@
|
|||
#include <sys/types.h>
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/dsp.h>
|
||||
#include <asterisk/ulaw.h>
|
||||
|
|
9
image.c
9
image.c
|
@ -22,7 +22,6 @@
|
|||
#include <asterisk/sched.h>
|
||||
#include <asterisk/options.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/image.h>
|
||||
|
@ -69,9 +68,9 @@ void ast_image_unregister(struct ast_imager *img)
|
|||
|
||||
int ast_supports_images(struct ast_channel *chan)
|
||||
{
|
||||
if (!chan || !chan->pvt)
|
||||
if (!chan || !chan->tech)
|
||||
return 0;
|
||||
if (!chan->pvt->send_image)
|
||||
if (!chan->tech->send_image)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -162,10 +161,10 @@ int ast_send_image(struct ast_channel *chan, char *filename)
|
|||
{
|
||||
struct ast_frame *f;
|
||||
int res = -1;
|
||||
if (chan->pvt->send_image) {
|
||||
if (chan->tech->send_image) {
|
||||
f = ast_read_image(filename, chan->language, -1);
|
||||
if (f) {
|
||||
res = chan->pvt->send_image(chan, f);
|
||||
res = chan->tech->send_image(chan, f);
|
||||
ast_frfree(f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <asterisk/frame.h>
|
||||
#include <asterisk/sched.h>
|
||||
#include <asterisk/chanvars.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#if defined(__APPLE__)
|
||||
|
@ -75,6 +76,75 @@ struct ast_callerid {
|
|||
int cid_tns;
|
||||
};
|
||||
|
||||
/*! Structure to describe a channel "technology" */
|
||||
|
||||
struct ast_channel_tech {
|
||||
const char * const type;
|
||||
const char * const description;
|
||||
|
||||
int capabilities;
|
||||
|
||||
struct ast_channel *(* const requester)(const char *type, int format, void *data, int *cause);
|
||||
|
||||
int (* const devicestate)(void *data);
|
||||
|
||||
/*! Send a literal DTMF digit */
|
||||
int (* const send_digit)(struct ast_channel *chan, char digit);
|
||||
|
||||
/*! Call a given phone number (address, etc), but don't
|
||||
take longer than timeout seconds to do so. */
|
||||
int (* const call)(struct ast_channel *chan, char *addr, int timeout);
|
||||
|
||||
/*! Hangup (and possibly destroy) the channel */
|
||||
int (* const hangup)(struct ast_channel *chan);
|
||||
|
||||
/*! Answer the line */
|
||||
int (* const answer)(struct ast_channel *chan);
|
||||
|
||||
/*! Read a frame, in standard format */
|
||||
struct ast_frame * (* const read)(struct ast_channel *chan);
|
||||
|
||||
/*! Write a frame, in standard format */
|
||||
int (* const write)(struct ast_channel *chan, struct ast_frame *frame);
|
||||
|
||||
/*! Display or transmit text */
|
||||
int (* const send_text)(struct ast_channel *chan, char *text);
|
||||
|
||||
/*! Display or send an image */
|
||||
int (* const send_image)(struct ast_channel *chan, struct ast_frame *frame);
|
||||
|
||||
/*! Send HTML data */
|
||||
int (* const send_html)(struct ast_channel *chan, int subclass, char *data, int len);
|
||||
|
||||
/*! Handle an exception, reading a frame */
|
||||
struct ast_frame * (* const exception)(struct ast_channel *chan);
|
||||
|
||||
/*! Bridge two channels of the same type together */
|
||||
int (* const bridge)(struct ast_channel *c0, struct ast_channel *c1, int flags,
|
||||
struct ast_frame **fo, struct ast_channel **rc);
|
||||
|
||||
/*! Indicate a particular condition (e.g. AST_CONTROL_BUSY or AST_CONTROL_RINGING or AST_CONTROL_CONGESTION */
|
||||
int (* const indicate)(struct ast_channel *c, int condition);
|
||||
|
||||
/*! Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links */
|
||||
int (* const fixup)(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
|
||||
/*! Set a given option */
|
||||
int (* const setoption)(struct ast_channel *chan, int option, void *data, int datalen);
|
||||
|
||||
/*! Query a given option */
|
||||
int (* const queryoption)(struct ast_channel *chan, int option, void *data, int *datalen);
|
||||
|
||||
/*! Blind transfer other side */
|
||||
int (* const transfer)(struct ast_channel *chan, char *newdest);
|
||||
|
||||
/*! Write a frame, in standard format */
|
||||
int (* const write_video)(struct ast_channel *chan, struct ast_frame *frame);
|
||||
|
||||
/*! Find bridged channel */
|
||||
struct ast_channel *(* const bridged_channel)(struct ast_channel *chan, struct ast_channel *bridge);
|
||||
};
|
||||
|
||||
/*! Main Channel structure associated with a channel. */
|
||||
/*!
|
||||
* This is the side of it mostly used by the pbx and call management.
|
||||
|
@ -82,6 +152,12 @@ struct ast_callerid {
|
|||
struct ast_channel {
|
||||
/*! ASCII Description of channel name */
|
||||
char name[AST_CHANNEL_NAME];
|
||||
|
||||
/*! Technology */
|
||||
const struct ast_channel_tech *tech;
|
||||
/*! Private data used by the technology driver */
|
||||
void *tech_pvt;
|
||||
|
||||
/*! Language requested */
|
||||
char language[MAX_LANGUAGE];
|
||||
/*! Type of channel */
|
||||
|
@ -219,6 +295,17 @@ struct ast_channel {
|
|||
/*! channel flags of AST_FLAG_ type */
|
||||
unsigned int flags;
|
||||
|
||||
struct ast_frame *readq;
|
||||
int alertpipe[2];
|
||||
/*! Write translation path */
|
||||
struct ast_trans_pvt *writetrans;
|
||||
/*! Read translation path */
|
||||
struct ast_trans_pvt *readtrans;
|
||||
/*! Raw read format */
|
||||
int rawreadformat;
|
||||
/*! Raw write format */
|
||||
int rawwriteformat;
|
||||
|
||||
/*! For easy linking */
|
||||
struct ast_channel *next;
|
||||
|
||||
|
@ -331,6 +418,25 @@ struct outgoing_helper {
|
|||
/*! Device is unavailable */
|
||||
#define AST_DEVICE_UNAVAILABLE 5
|
||||
|
||||
/*! Create a channel structure */
|
||||
/*! Returns NULL on failure to allocate */
|
||||
struct ast_channel *ast_channel_alloc(int needalertpipe);
|
||||
|
||||
/*! Queue an outgoing frame */
|
||||
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f);
|
||||
|
||||
int ast_queue_hangup(struct ast_channel *chan);
|
||||
|
||||
int ast_queue_control(struct ast_channel *chan, int control);
|
||||
|
||||
/*! Change the state of a channel */
|
||||
int ast_setstate(struct ast_channel *chan, int state);
|
||||
|
||||
void ast_change_name(struct ast_channel *chan, char *newname);
|
||||
|
||||
/*! Free a channel structure */
|
||||
void ast_channel_free(struct ast_channel *);
|
||||
|
||||
/*! Requests a channel */
|
||||
/*!
|
||||
* \param type type of channel to request
|
||||
|
@ -378,32 +484,20 @@ struct ast_channel *ast_request_and_dial(const char *type, int format, void *dat
|
|||
|
||||
struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, struct outgoing_helper *oh);
|
||||
|
||||
/*! Registers a channel */
|
||||
/*! Register a channel technology */
|
||||
/*!
|
||||
* \param type type of channel you are registering
|
||||
* \param description short description of the channel
|
||||
* \param capabilities a bit mask of the capabilities of the channel
|
||||
* \param requester a function pointer that properly responds to a call. See one of the channel drivers for details.
|
||||
* \param tech Structure defining channel technology or "type"
|
||||
* Called by a channel module to register the kind of channels it supports.
|
||||
* It supplies a brief type, a longer, but still short description, and a
|
||||
* routine that creates a channel
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int ast_channel_register(const char *type, const char *description, int capabilities,
|
||||
struct ast_channel* (*requester)(const char *type, int format, void *data, int *cause));
|
||||
int ast_channel_register(const struct ast_channel_tech *tech);
|
||||
|
||||
/* Same like the upper function but with support for devicestate */
|
||||
int ast_channel_register_ex(const char *type, const char *description, int capabilities,
|
||||
struct ast_channel *(*requester)(const char *type, int format, void *data, int *cause),
|
||||
int (*devicestate)(void *data));
|
||||
|
||||
/*! Unregister a channel class */
|
||||
/*! Unregister a channel technology */
|
||||
/*
|
||||
* \param type the character string that corresponds to the channel you wish to unregister
|
||||
* Basically just unregisters the channel with the asterisk channel system
|
||||
* \param tech Structure defining channel technology or "type" that was previously registered
|
||||
* No return value.
|
||||
*/
|
||||
void ast_channel_unregister(const char *type);
|
||||
void ast_channel_unregister(const struct ast_channel_tech *tech);
|
||||
|
||||
/*! Hang up a channel */
|
||||
/*!
|
||||
|
@ -898,5 +992,4 @@ extern char *ast_print_group(char *buf, int buflen, ast_group_t group);
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Private channel definitions for channel implementations only.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _ASTERISK_CHANNEL_PVT_H
|
||||
#define _ASTERISK_CHANNEL_PVT_H
|
||||
|
||||
#include <asterisk/channel.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
struct ast_channel_pvt {
|
||||
/*! Private data used by channel backend */
|
||||
void *pvt;
|
||||
struct ast_frame *readq;
|
||||
int alertpipe[2];
|
||||
/*! Write translation path */
|
||||
struct ast_trans_pvt *writetrans;
|
||||
/*! Read translation path */
|
||||
struct ast_trans_pvt *readtrans;
|
||||
/*! Raw read format */
|
||||
int rawreadformat;
|
||||
/*! Raw write format */
|
||||
int rawwriteformat;
|
||||
/*! Send a literal DTMF digit */
|
||||
int (*send_digit)(struct ast_channel *chan, char digit);
|
||||
/*! Call a given phone number (address, etc), but don't
|
||||
take longer than timeout seconds to do so. */
|
||||
int (*call)(struct ast_channel *chan, char *addr, int timeout);
|
||||
/*! Hangup (and possibly destroy) the channel */
|
||||
int (*hangup)(struct ast_channel *chan);
|
||||
/*! Answer the line */
|
||||
int (*answer)(struct ast_channel *chan);
|
||||
/*! Read a frame, in standard format */
|
||||
struct ast_frame * (*read)(struct ast_channel *chan);
|
||||
/*! Write a frame, in standard format */
|
||||
int (*write)(struct ast_channel *chan, struct ast_frame *frame);
|
||||
/*! Display or transmit text */
|
||||
int (*send_text)(struct ast_channel *chan, char *text);
|
||||
/*! Display or send an image */
|
||||
int (*send_image)(struct ast_channel *chan, struct ast_frame *frame);
|
||||
/*! Send HTML data */
|
||||
int (*send_html)(struct ast_channel *chan, int subclass, char *data, int len);
|
||||
/*! Handle an exception, reading a frame */
|
||||
struct ast_frame * (*exception)(struct ast_channel *chan);
|
||||
/*! Bridge two channels of the same type together */
|
||||
int (*bridge)(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
|
||||
/*! Indicate a particular condition (e.g. AST_CONTROL_BUSY or AST_CONTROL_RINGING or AST_CONTROL_CONGESTION */
|
||||
int (*indicate)(struct ast_channel *c, int condition);
|
||||
/*! Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links */
|
||||
int (*fixup)(struct ast_channel *oldchan, struct ast_channel *newchan);
|
||||
/*! Set a given option */
|
||||
int (*setoption)(struct ast_channel *chan, int option, void *data, int datalen);
|
||||
/*! Query a given option */
|
||||
int (*queryoption)(struct ast_channel *chan, int option, void *data, int *datalen);
|
||||
/*! Blind transfer other side */
|
||||
int (*transfer)(struct ast_channel *chan, char *newdest);
|
||||
/*! Write a frame, in standard format */
|
||||
int (*write_video)(struct ast_channel *chan, struct ast_frame *frame);
|
||||
/*! Find bridged channel */
|
||||
struct ast_channel * (*bridged_channel)(struct ast_channel *chan, struct ast_channel *bridge);
|
||||
};
|
||||
|
||||
/*! Create a channel structure */
|
||||
/*! Returns NULL on failure to allocate */
|
||||
struct ast_channel *ast_channel_alloc(int needalertpipe);
|
||||
|
||||
/*! Queue an outgoing frame */
|
||||
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f);
|
||||
|
||||
int ast_queue_hangup(struct ast_channel *chan);
|
||||
|
||||
int ast_queue_control(struct ast_channel *chan, int control);
|
||||
|
||||
/*! Change the state of a channel */
|
||||
int ast_setstate(struct ast_channel *chan, int state);
|
||||
|
||||
void ast_change_name(struct ast_channel *chan, char *newname);
|
||||
|
||||
/*! Free a channel structure */
|
||||
void ast_channel_free(struct ast_channel *);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -36,11 +36,14 @@ extern "C" {
|
|||
#define AST_RTP_MAX AST_RTP_CISCO_DTMF
|
||||
|
||||
struct ast_rtp_protocol {
|
||||
struct ast_rtp *(*get_rtp_info)(struct ast_channel *chan); /* Get RTP struct, or NULL if unwilling to transfer */
|
||||
struct ast_rtp *(*get_vrtp_info)(struct ast_channel *chan); /* Get RTP struct, or NULL if unwilling to transfer */
|
||||
int (*set_rtp_peer)(struct ast_channel *chan, struct ast_rtp *peer, struct ast_rtp *vpeer, int codecs); /* Set RTP peer */
|
||||
int (*get_codec)(struct ast_channel *chan);
|
||||
char *type;
|
||||
/* Get RTP struct, or NULL if unwilling to transfer */
|
||||
struct ast_rtp *(* const get_rtp_info)(struct ast_channel *chan);
|
||||
/* Get RTP struct, or NULL if unwilling to transfer */
|
||||
struct ast_rtp *(* const get_vrtp_info)(struct ast_channel *chan);
|
||||
/* Set RTP peer */
|
||||
int (* const set_rtp_peer)(struct ast_channel *chan, struct ast_rtp *peer, struct ast_rtp *vpeer, int codecs);
|
||||
int (* const get_codec)(struct ast_channel *chan);
|
||||
const char * const type;
|
||||
struct ast_rtp_protocol *next;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
|
||||
#define CHAR_DLE 0x10
|
||||
#define CHAR_ETX 0x03
|
||||
|
|
1
pbx.c
1
pbx.c
|
@ -26,7 +26,6 @@
|
|||
#include <asterisk/term.h>
|
||||
#include <asterisk/manager.h>
|
||||
#include <asterisk/ast_expr.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/linkedlists.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <asterisk/utils.h>
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <asterisk/module.h>
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/file.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/cli.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/md5.h>
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <asterisk/translate.h>
|
||||
#include <asterisk/app.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/features.h>
|
||||
#include <asterisk/musiconhold.h>
|
||||
#include <asterisk/config.h>
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <asterisk/module.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/say.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/musiconhold.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/utils.h>
|
||||
|
|
17
rtp.c
17
rtp.c
|
@ -33,7 +33,6 @@
|
|||
#include <asterisk/channel.h>
|
||||
#include <asterisk/acl.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/config.h>
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/utils.h>
|
||||
|
@ -1509,8 +1508,8 @@ int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, st
|
|||
ast_mutex_unlock(&c1->lock);
|
||||
return -1;
|
||||
}
|
||||
pvt0 = c0->pvt->pvt;
|
||||
pvt1 = c1->pvt->pvt;
|
||||
pvt0 = c0->tech_pvt;
|
||||
pvt1 = c1->tech_pvt;
|
||||
p0 = pr0->get_rtp_info(c0);
|
||||
if (pr0->get_vrtp_info)
|
||||
vp0 = pr0->get_vrtp_info(c0);
|
||||
|
@ -1568,15 +1567,15 @@ int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, st
|
|||
oldcodec0 = codec0;
|
||||
oldcodec1 = codec1;
|
||||
for (;;) {
|
||||
if ((c0->pvt->pvt != pvt0) ||
|
||||
(c1->pvt->pvt != pvt1) ||
|
||||
if ((c0->tech_pvt != pvt0) ||
|
||||
(c1->tech_pvt != pvt1) ||
|
||||
(c0->masq || c0->masqr || c1->masq || c1->masqr)) {
|
||||
ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
|
||||
if (c0->pvt->pvt == pvt0) {
|
||||
if (c0->tech_pvt == pvt0) {
|
||||
if (pr0->set_rtp_peer(c0, NULL, NULL, 0))
|
||||
ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
|
||||
}
|
||||
if (c1->pvt->pvt == pvt1) {
|
||||
if (c1->tech_pvt == pvt1) {
|
||||
if (pr1->set_rtp_peer(c1, NULL, NULL, 0))
|
||||
ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
|
||||
}
|
||||
|
@ -1641,11 +1640,11 @@ int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, st
|
|||
*rc = who;
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
|
||||
if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
|
||||
if ((c0->tech_pvt == pvt0) && (!c0->_softhangup)) {
|
||||
if (pr0->set_rtp_peer(c0, NULL, NULL, 0))
|
||||
ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
|
||||
}
|
||||
if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
|
||||
if ((c1->tech_pvt == pvt1) && (!c1->_softhangup)) {
|
||||
if (pr1->set_rtp_peer(c1, NULL, NULL, 0))
|
||||
ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <asterisk/lock.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/channel_pvt.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/translate.h>
|
||||
#include <asterisk/options.h>
|
||||
|
|
Reference in New Issue