|
|
|
@ -102,11 +102,11 @@ unsigned long global_fin = 0, global_fout = 0;
|
|
|
|
|
|
|
|
|
|
struct chanlist {
|
|
|
|
|
const struct ast_channel_tech *tech;
|
|
|
|
|
struct chanlist *next;
|
|
|
|
|
AST_LIST_ENTRY(chanlist) list;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*! the list of registered channel types */
|
|
|
|
|
static struct chanlist *backends = NULL;
|
|
|
|
|
static AST_LIST_HEAD_NOLOCK_STATIC(backends, chanlist);
|
|
|
|
|
|
|
|
|
|
/*! the list of channels we have */
|
|
|
|
|
static struct ast_channel *channels = NULL;
|
|
|
|
@ -178,7 +178,7 @@ static int show_channeltypes(int fd, int argc, char *argv[])
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to lock channel list\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
for (cl = backends; cl; cl = cl->next) {
|
|
|
|
|
AST_LIST_TRAVERSE(&backends, cl, list) {
|
|
|
|
|
ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
|
|
|
|
|
(cl->tech->devicestate) ? "yes" : "no",
|
|
|
|
|
(cl->tech->indicate) ? "yes" : "no",
|
|
|
|
@ -315,7 +315,7 @@ int ast_channel_register(const struct ast_channel_tech *tech)
|
|
|
|
|
|
|
|
|
|
ast_mutex_lock(&chlock);
|
|
|
|
|
|
|
|
|
|
for (chan = backends; chan; chan = chan->next) {
|
|
|
|
|
AST_LIST_TRAVERSE(&backends, chan, list) {
|
|
|
|
|
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);
|
|
|
|
@ -329,9 +329,7 @@ int ast_channel_register(const struct ast_channel_tech *tech)
|
|
|
|
|
ast_mutex_unlock(&chlock);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
chan->tech = tech;
|
|
|
|
|
chan->next = backends;
|
|
|
|
|
backends = chan;
|
|
|
|
|
AST_LIST_INSERT_HEAD(&backends, chan, list);
|
|
|
|
|
|
|
|
|
|
if (option_debug)
|
|
|
|
|
ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
|
|
|
|
@ -346,29 +344,23 @@ int ast_channel_register(const struct ast_channel_tech *tech)
|
|
|
|
|
|
|
|
|
|
void ast_channel_unregister(const struct ast_channel_tech *tech)
|
|
|
|
|
{
|
|
|
|
|
struct chanlist *chan, *last=NULL;
|
|
|
|
|
struct chanlist *chan;
|
|
|
|
|
|
|
|
|
|
if (option_debug)
|
|
|
|
|
ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
|
|
|
|
|
|
|
|
|
|
ast_mutex_lock(&chlock);
|
|
|
|
|
|
|
|
|
|
for (chan = backends; chan; chan = chan->next) {
|
|
|
|
|
AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
|
|
|
|
|
if (chan->tech == tech) {
|
|
|
|
|
if (last)
|
|
|
|
|
last->next = chan->next;
|
|
|
|
|
else
|
|
|
|
|
backends = backends->next;
|
|
|
|
|
AST_LIST_REMOVE_CURRENT(&backends, list);
|
|
|
|
|
free(chan);
|
|
|
|
|
ast_mutex_unlock(&chlock);
|
|
|
|
|
|
|
|
|
|
if (option_verbose > 1)
|
|
|
|
|
ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
last = chan;
|
|
|
|
|
}
|
|
|
|
|
AST_LIST_TRAVERSE_SAFE_END
|
|
|
|
|
|
|
|
|
|
ast_mutex_unlock(&chlock);
|
|
|
|
|
}
|
|
|
|
@ -376,22 +368,23 @@ void ast_channel_unregister(const struct ast_channel_tech *tech)
|
|
|
|
|
const struct ast_channel_tech *ast_get_channel_tech(const char *name)
|
|
|
|
|
{
|
|
|
|
|
struct chanlist *chanls;
|
|
|
|
|
const struct ast_channel_tech *ret = NULL;
|
|
|
|
|
|
|
|
|
|
if (ast_mutex_lock(&chlock)) {
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (chanls = backends; chanls; chanls = chanls->next) {
|
|
|
|
|
if (strcasecmp(name, chanls->tech->type))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
ast_mutex_unlock(&chlock);
|
|
|
|
|
return chanls->tech;
|
|
|
|
|
AST_LIST_TRAVERSE(&backends, chanls, list) {
|
|
|
|
|
if (!strcasecmp(name, chanls->tech->type)) {
|
|
|
|
|
ret = chanls->tech;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_mutex_unlock(&chlock);
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \brief Gives the string form of a given hangup cause */
|
|
|
|
@ -2491,7 +2484,7 @@ struct ast_channel *ast_request(const char *type, int format, void *data, int *c
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (chan = backends; chan; chan = chan->next) {
|
|
|
|
|
AST_LIST_TRAVERSE(&backends, chan, list) {
|
|
|
|
|
if (strcasecmp(type, chan->tech->type))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|