|
|
@ -69,9 +69,6 @@ AST_MUTEX_DEFINE_STATIC(usecnt_lock);
|
|
|
|
|
|
|
|
|
|
|
|
#define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
|
|
|
|
#define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
|
|
|
|
|
|
|
|
|
|
|
|
/* 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 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_digit(struct ast_channel *ast, char digit);
|
|
|
|
static int local_call(struct ast_channel *ast, char *dest, int timeout);
|
|
|
|
static int local_call(struct ast_channel *ast, char *dest, int timeout);
|
|
|
@ -101,7 +98,7 @@ static const struct ast_channel_tech local_tech = {
|
|
|
|
.send_html = local_sendhtml,
|
|
|
|
.send_html = local_sendhtml,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static struct local_pvt {
|
|
|
|
struct local_pvt {
|
|
|
|
ast_mutex_t lock; /* Channel private lock */
|
|
|
|
ast_mutex_t lock; /* Channel private lock */
|
|
|
|
char context[AST_MAX_CONTEXT]; /* Context to call */
|
|
|
|
char context[AST_MAX_CONTEXT]; /* Context to call */
|
|
|
|
char exten[AST_MAX_EXTENSION]; /* Extension to call */
|
|
|
|
char exten[AST_MAX_EXTENSION]; /* Extension to call */
|
|
|
@ -113,8 +110,10 @@ static struct local_pvt {
|
|
|
|
int nooptimization; /* Don't leave masq state */
|
|
|
|
int nooptimization; /* Don't leave masq state */
|
|
|
|
struct ast_channel *owner; /* Master Channel */
|
|
|
|
struct ast_channel *owner; /* Master Channel */
|
|
|
|
struct ast_channel *chan; /* Outbound channel */
|
|
|
|
struct ast_channel *chan; /* Outbound channel */
|
|
|
|
struct local_pvt *next; /* Next entity */
|
|
|
|
AST_LIST_ENTRY(local_pvt) list; /* Next entity */
|
|
|
|
} *locals = NULL;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static AST_LIST_HEAD_STATIC(locals, local_pvt);
|
|
|
|
|
|
|
|
|
|
|
|
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
|
|
|
|
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -357,23 +356,19 @@ static int local_call(struct ast_channel *ast, char *dest, int timeout)
|
|
|
|
#if 0
|
|
|
|
#if 0
|
|
|
|
static void local_destroy(struct local_pvt *p)
|
|
|
|
static void local_destroy(struct local_pvt *p)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct local_pvt *cur, *prev = NULL;
|
|
|
|
struct local_pvt *cur;
|
|
|
|
ast_mutex_lock(&locallock);
|
|
|
|
|
|
|
|
cur = locals;
|
|
|
|
AST_LIST_LOCK(&locals);
|
|
|
|
while(cur) {
|
|
|
|
AST_LIST_TRAVERSE_SAFE_BEGIN(&locals, cur, list) {
|
|
|
|
if (cur == p) {
|
|
|
|
if (cur == p) {
|
|
|
|
if (prev)
|
|
|
|
AST_LIST_REMOVE_CURRENT(&locals, list);
|
|
|
|
prev->next = cur->next;
|
|
|
|
ast_mutex_destroy(&cur->lock);
|
|
|
|
else
|
|
|
|
|
|
|
|
locals = cur->next;
|
|
|
|
|
|
|
|
ast_mutex_destroy(cur);
|
|
|
|
|
|
|
|
free(cur);
|
|
|
|
free(cur);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
prev = cur;
|
|
|
|
|
|
|
|
cur = cur->next;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast_mutex_unlock(&locallock);
|
|
|
|
AST_LIST_TRAVERSE_SAFE_END
|
|
|
|
|
|
|
|
AST_LIST_UNLOCK(&locals);
|
|
|
|
if (!cur)
|
|
|
|
if (!cur)
|
|
|
|
ast_log(LOG_WARNING, "Unable ot find local '%s@%s' in local list\n", p->exten, p->context);
|
|
|
|
ast_log(LOG_WARNING, "Unable ot find local '%s@%s' in local list\n", p->exten, p->context);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -385,7 +380,6 @@ static int local_hangup(struct ast_channel *ast)
|
|
|
|
struct local_pvt *p = ast->tech_pvt;
|
|
|
|
struct local_pvt *p = ast->tech_pvt;
|
|
|
|
int isoutbound;
|
|
|
|
int isoutbound;
|
|
|
|
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
|
|
|
|
struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
|
|
|
|
struct local_pvt *cur, *prev=NULL;
|
|
|
|
|
|
|
|
struct ast_channel *ochan = NULL;
|
|
|
|
struct ast_channel *ochan = NULL;
|
|
|
|
int glaredetect;
|
|
|
|
int glaredetect;
|
|
|
|
const char *status;
|
|
|
|
const char *status;
|
|
|
@ -415,20 +409,9 @@ static int local_hangup(struct ast_channel *ast)
|
|
|
|
p->cancelqueue = 1;
|
|
|
|
p->cancelqueue = 1;
|
|
|
|
ast_mutex_unlock(&p->lock);
|
|
|
|
ast_mutex_unlock(&p->lock);
|
|
|
|
/* Remove from list */
|
|
|
|
/* Remove from list */
|
|
|
|
ast_mutex_lock(&locallock);
|
|
|
|
AST_LIST_LOCK(&locals);
|
|
|
|
cur = locals;
|
|
|
|
AST_LIST_REMOVE(&locals, p, list);
|
|
|
|
while(cur) {
|
|
|
|
AST_LIST_UNLOCK(&locals);
|
|
|
|
if (cur == p) {
|
|
|
|
|
|
|
|
if (prev)
|
|
|
|
|
|
|
|
prev->next = cur->next;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
locals = cur->next;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
prev = cur;
|
|
|
|
|
|
|
|
cur = cur->next;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ast_mutex_unlock(&locallock);
|
|
|
|
|
|
|
|
/* Grab / release lock just in case */
|
|
|
|
/* Grab / release lock just in case */
|
|
|
|
ast_mutex_lock(&p->lock);
|
|
|
|
ast_mutex_lock(&p->lock);
|
|
|
|
ast_mutex_unlock(&p->lock);
|
|
|
|
ast_mutex_unlock(&p->lock);
|
|
|
@ -484,10 +467,9 @@ static struct local_pvt *local_alloc(char *data, int format)
|
|
|
|
tmp = NULL;
|
|
|
|
tmp = NULL;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
/* Add to list */
|
|
|
|
/* Add to list */
|
|
|
|
ast_mutex_lock(&locallock);
|
|
|
|
AST_LIST_LOCK(&locals);
|
|
|
|
tmp->next = locals;
|
|
|
|
AST_LIST_INSERT_HEAD(&locals, tmp, list);
|
|
|
|
locals = tmp;
|
|
|
|
AST_LIST_UNLOCK(&locals);
|
|
|
|
ast_mutex_unlock(&locallock);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return tmp;
|
|
|
|
return tmp;
|
|
|
@ -563,17 +545,15 @@ static int locals_show(int fd, int argc, char **argv)
|
|
|
|
|
|
|
|
|
|
|
|
if (argc != 3)
|
|
|
|
if (argc != 3)
|
|
|
|
return RESULT_SHOWUSAGE;
|
|
|
|
return RESULT_SHOWUSAGE;
|
|
|
|
ast_mutex_lock(&locallock);
|
|
|
|
if (AST_LIST_EMPTY(&locals))
|
|
|
|
p = locals;
|
|
|
|
ast_cli(fd, "No local channels in use\n");
|
|
|
|
while(p) {
|
|
|
|
AST_LIST_LOCK(&locals);
|
|
|
|
|
|
|
|
AST_LIST_TRAVERSE(&locals, p, list) {
|
|
|
|
ast_mutex_lock(&p->lock);
|
|
|
|
ast_mutex_lock(&p->lock);
|
|
|
|
ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
|
|
|
|
ast_cli(fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
|
|
|
|
ast_mutex_unlock(&p->lock);
|
|
|
|
ast_mutex_unlock(&p->lock);
|
|
|
|
p = p->next;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!locals)
|
|
|
|
AST_LIST_UNLOCK(&locals);
|
|
|
|
ast_cli(fd, "No local channels in use\n");
|
|
|
|
|
|
|
|
ast_mutex_unlock(&locallock);
|
|
|
|
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
return RESULT_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -611,16 +591,14 @@ int unload_module()
|
|
|
|
/* First, take us out of the channel loop */
|
|
|
|
/* First, take us out of the channel loop */
|
|
|
|
ast_cli_unregister(&cli_show_locals);
|
|
|
|
ast_cli_unregister(&cli_show_locals);
|
|
|
|
ast_channel_unregister(&local_tech);
|
|
|
|
ast_channel_unregister(&local_tech);
|
|
|
|
if (!ast_mutex_lock(&locallock)) {
|
|
|
|
if (!AST_LIST_LOCK(&locals)) {
|
|
|
|
/* Hangup all interfaces if they have an owner */
|
|
|
|
/* Hangup all interfaces if they have an owner */
|
|
|
|
p = locals;
|
|
|
|
AST_LIST_TRAVERSE(&locals, p, list) {
|
|
|
|
while(p) {
|
|
|
|
|
|
|
|
if (p->owner)
|
|
|
|
if (p->owner)
|
|
|
|
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
|
|
|
|
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
|
|
|
|
p = p->next;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
locals = NULL;
|
|
|
|
AST_LIST_UNLOCK(&locals);
|
|
|
|
ast_mutex_unlock(&locallock);
|
|
|
|
AST_LIST_HEAD_DESTROY(&locals);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
|
|
|
|
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|