diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-03-04 06:47:24 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-03-04 06:47:24 +0000 |
commit | 8ba4898a1eece83e44568bf8a4373a3de341a40c (patch) | |
tree | d4f64d65fd10bb76d2839b641fa20091909210c5 /channel.c | |
parent | b0180cc4f641d4097a85f52b887ac0bef130604b (diff) |
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
Diffstat (limited to 'channel.c')
-rwxr-xr-x | channel.c | 472 |
1 files changed, 243 insertions, 229 deletions
@@ -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 { |