#include <asterisk/channel.h>Go to the source code of this file.
Data Structures | |
| struct | ast_channel_pvt |
Functions | |
| ast_channel * | ast_channel_alloc (int needalertpipe) |
| Create a channel structure. More... | |
| 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) |
| int | ast_setstate (struct ast_channel *chan, int state) |
| void | ast_change_name (struct ast_channel *chan, char *newname) |
| void | ast_channel_free (struct ast_channel *) |
| Free a channel structure. More... | |
|
||||||||||||
|
Definition at line 2184 of file channel.c. References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.
02185 {
02186 char tmp[256];
02187 strncpy(tmp, chan->name, sizeof(tmp) - 1);
02188 strncpy(chan->name, newname, sizeof(chan->name) - 1);
02189 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
02190 }
|
|
|
Create a channel structure. Returns NULL on failure to allocate Definition at line 274 of file channel.c. References ast_channel::_state, ast_channel::accountcode, ast_channel_pvt::alertpipe, ast_channel::amaflags, ast_channel::appl, AST_LIST_HEAD_INIT, AST_LIST_INSERT_HEAD, ast_log(), AST_MAX_FDS, ast_mutex_lock, ast_mutex_unlock, AST_STATE_DOWN, ast_var_assign(), ast_channel::context, ast_channel::data, ast_channel::exten, ast_channel::fds, ast_channel::fin, ast_channel::fout, free, ast_channel::language, ast_channel::lock, LOG_WARNING, malloc, ast_channel::name, ast_channel::next, ast_channel::priority, ast_channel::pvt, ast_channel::sched, sched_context_create(), ast_channel::stack, ast_channel::streamid, ast_channel::timingfd, ast_channel::uniqueid, and ast_channel::vars. Referenced by ast_async_goto(), and ast_pbx_outgoing_exten().
00275 {
00276 struct ast_channel *tmp;
00277 struct ast_channel_pvt *pvt;
00278 int x;
00279 int flags;
00280 struct varshead *headp;
00281
00282
00283 /* If shutting down, don't allocate any new channels */
00284 if (shutting_down)
00285 return NULL;
00286 ast_mutex_lock(&chlock);
00287 tmp = malloc(sizeof(struct ast_channel));
00288 if (tmp) {
00289 memset(tmp, 0, sizeof(struct ast_channel));
00290 pvt = malloc(sizeof(struct ast_channel_pvt));
00291 if (pvt) {
00292 memset(pvt, 0, sizeof(struct ast_channel_pvt));
00293 tmp->sched = sched_context_create();
00294 if (tmp->sched) {
00295 for (x=0;x<AST_MAX_FDS - 1;x++)
00296 tmp->fds[x] = -1;
00297 #ifdef ZAPTEL_OPTIMIZATIONS
00298 tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00299 if (tmp->timingfd > -1) {
00300 /* Check if timing interface supports new
00301 ping/pong scheme */
00302 flags = 1;
00303 if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00304 needqueue = 0;
00305 }
00306 #else
00307 tmp->timingfd = -1;
00308 #endif
00309 if (needqueue &&
00310 pipe(pvt->alertpipe)) {
00311 ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
00312 free(pvt);
00313 free(tmp);
00314 tmp = NULL;
00315 pvt = NULL;
00316 } else {
00317 if (needqueue) {
00318 flags = fcntl(pvt->alertpipe[0], F_GETFL);
00319 fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00320 flags = fcntl(pvt->alertpipe[1], F_GETFL);
00321 fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00322 } else
00323 /* Make sure we've got it done right if they don't */
00324 pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
00325 /* Always watch the alertpipe */
00326 tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
00327 /* And timing pipe */
00328 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00329 strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
00330 tmp->pvt = pvt;
00331 /* Initial state */
00332 tmp->_state = AST_STATE_DOWN;
00333 tmp->stack = -1;
00334 tmp->streamid = -1;
00335 tmp->appl = NULL;
00336 tmp->data = NULL;
00337 tmp->fin = 0;
00338 tmp->fout = 0;
00339 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
00340 headp=&tmp->varshead;
00341 ast_mutex_init(&tmp->lock);
00342 AST_LIST_HEAD_INIT(headp);
00343 tmp->vars=ast_var_assign("tempvar","tempval");
00344 AST_LIST_INSERT_HEAD(headp,tmp->vars,entries);
00345 strncpy(tmp->context, "default", sizeof(tmp->context)-1);
00346 strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
00347 strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
00348 tmp->priority=1;
00349 tmp->amaflags = ast_default_amaflags;
00350 strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
00351 tmp->next = channels;
00352 channels= tmp;
00353 }
00354 } else {
00355 ast_log(LOG_WARNING, "Unable to create schedule context\n");
00356 free(tmp);
00357 tmp = NULL;
00358 }
00359 } else {
00360 ast_log(LOG_WARNING, "Out of memory\n");
00361 free(tmp);
00362 tmp = NULL;
00363 }
00364 } else
00365 ast_log(LOG_WARNING, "Out of memory\n");
00366 ast_mutex_unlock(&chlock);
00367 return tmp;
00368 }
|
|
|
Free a channel structure.
Definition at line 561 of file channel.c. References ast_channel_pvt::alertpipe, ast_channel::ani, AST_CHANNEL_NAME, ast_device_state_changed(), ast_frfree(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_translator_free_path(), ast_var_delete(), ast_channel::callerid, ast_channel::dnid, free, ast_channel::lock, LOG_WARNING, ast_channel::monitor, ast_channel::name, ast_frame::next, ast_channel::next, ast_channel::pbx, ast_channel_pvt::pvt, ast_channel::pvt, ast_channel::rdnis, ast_channel_pvt::readq, ast_channel_pvt::readtrans, ast_channel_monitor::stop, ast_channel::timingfd, and ast_channel_pvt::writetrans. Referenced by ast_do_masquerade(), and ast_hangup().
00562 {
00563 struct ast_channel *last=NULL, *cur;
00564 int fd;
00565 struct ast_var_t *vardata;
00566 struct ast_frame *f, *fp;
00567 struct varshead *headp;
00568 char name[AST_CHANNEL_NAME];
00569
00570 headp=&chan->varshead;
00571
00572 ast_mutex_lock(&chlock);
00573 cur = channels;
00574 while(cur) {
00575 if (cur == chan) {
00576 if (last)
00577 last->next = cur->next;
00578 else
00579 channels = cur->next;
00580 break;
00581 }
00582 last = cur;
00583 cur = cur->next;
00584 }
00585 if (!cur)
00586 ast_log(LOG_WARNING, "Unable to find channel in list\n");
00587 else {
00588 /* Lock and unlock the channel just to be sure nobody
00589 has it locked still */
00590 ast_mutex_lock(&cur->lock);
00591 ast_mutex_unlock(&cur->lock);
00592 }
00593 if (chan->pvt->pvt)
00594 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00595
00596 strncpy(name, chan->name, sizeof(name)-1);
00597
00598 /* Stop monitoring */
00599 if (chan->monitor) {
00600 chan->monitor->stop( chan, 0 );
00601 }
00602
00603 /* Free translatosr */
00604 if (chan->pvt->readtrans)
00605 ast_translator_free_path(chan->pvt->readtrans);
00606 if (chan->pvt->writetrans)
00607 ast_translator_free_path(chan->pvt->writetrans);
00608 if (chan->pbx)
00609 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00610 if (chan->dnid)
00611 free(chan->dnid);
00612 if (chan->callerid)
00613 free(chan->callerid);
00614 if (chan->ani)
00615 free(chan->ani);
00616 if (chan->rdnis)
00617 free(chan->rdnis);
00618 ast_mutex_destroy(&chan->lock);
00619 /* Close pipes if appropriate */
00620 if ((fd = chan->pvt->alertpipe[0]) > -1)
00621 close(fd);
00622 if ((fd = chan->pvt->alertpipe[1]) > -1)
00623 close(fd);
00624 if ((fd = chan->timingfd) > -1)
00625 close(fd);
00626 f = chan->pvt->readq;
00627 chan->pvt->readq = NULL;
00628 while(f) {
00629 fp = f;
00630 f = f->next;
00631 ast_frfree(fp);
00632 }
00633
00634 /* loop over the variables list, freeing all data and deleting list items */
00635 /* no need to lock the list, as the channel is already locked */
00636
00637 while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */
00638 vardata = AST_LIST_FIRST(headp);
00639 AST_LIST_REMOVE_HEAD(headp, entries);
00640 // printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata));
00641 ast_var_delete(vardata);
00642 }
00643
00644
00645 free(chan->pvt);
00646 chan->pvt = NULL;
00647 free(chan);
00648 ast_mutex_unlock(&chlock);
00649
00650 ast_device_state_changed(name);
00651 }
|
|
||||||||||||
|
Definition at line 434 of file channel.c. References ast_queue_frame(), and ast_frame::subclass.
00435 {
00436 struct ast_frame f = { AST_FRAME_CONTROL, };
00437 f.subclass = control;
00438 return ast_queue_frame(chan, &f);
00439 }
|
|
||||||||||||
|
Queue an outgoing frame Definition at line 370 of file channel.c. References ast_channel_pvt::alertpipe, ast_frdup(), ast_frfree(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_channel::blocker, ast_channel::blocking, CRASH, ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_frame::next, ast_channel::pvt, ast_channel_pvt::readq, ast_frame::subclass, and ast_channel::timingfd. Referenced by ast_channel_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), and ast_softhangup_nolock().
00371 {
00372 struct ast_frame *f;
00373 struct ast_frame *prev, *cur;
00374 int blah = 1;
00375 int qlen = 0;
00376 /* Build us a copy and free the original one */
00377 f = ast_frdup(fin);
00378 if (!f) {
00379 ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00380 return -1;
00381 }
00382 ast_mutex_lock(&chan->lock);
00383 prev = NULL;
00384 cur = chan->pvt->readq;
00385 while(cur) {
00386 if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00387 /* Don't bother actually queueing anything after a hangup */
00388 ast_frfree(f);
00389 ast_mutex_unlock(&chan->lock);
00390 return 0;
00391 }
00392 prev = cur;
00393 cur = cur->next;
00394 qlen++;
00395 }
00396 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00397 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) {
00398 if (fin->frametype != AST_FRAME_VOICE) {
00399 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00400 CRASH;
00401 } else {
00402 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00403 ast_frfree(f);
00404 ast_mutex_unlock(&chan->lock);
00405 return 0;
00406 }
00407 }
00408 if (prev)
00409 prev->next = f;
00410 else
00411 chan->pvt->readq = f;
00412 if (chan->pvt->alertpipe[1] > -1) {
00413 if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00414 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00415 chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00416 #ifdef ZAPTEL_OPTIMIZATIONS
00417 } else if (chan->timingfd > -1) {
00418 ioctl(chan->timingfd, ZT_TIMERPING, &blah);
00419 #endif
00420 } else if (chan->blocking) {
00421 pthread_kill(chan->blocker, SIGURG);
00422 }
00423 ast_mutex_unlock(&chan->lock);
00424 return 0;
00425 }
|
|
|
Definition at line 427 of file channel.c. References ast_channel::_softhangup, ast_queue_frame(), and AST_SOFTHANGUP_DEV.
00428 {
00429 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00430 chan->_softhangup |= AST_SOFTHANGUP_DEV;
00431 return ast_queue_frame(chan, &f);
00432 }
|
|
||||||||||||
|
Change the state of a channel Definition at line 2429 of file channel.c. References ast_channel::_state, ast_device_state_changed(), ast_state2str(), AST_STATE_DOWN, ast_channel::callerid, EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid. Referenced by ast_answer(), ast_async_goto(), and ast_read().
02430 {
02431 if (chan->_state != state) {
02432 int oldstate = chan->_state;
02433 chan->_state = state;
02434 if (oldstate == AST_STATE_DOWN) {
02435 ast_device_state_changed(chan->name);
02436 manager_event(EVENT_FLAG_CALL, "Newchannel",
02437 "Channel: %s\r\n"
02438 "State: %s\r\n"
02439 "Callerid: %s\r\n"
02440 "Uniqueid: %s\r\n",
02441 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02442 } else {
02443 manager_event(EVENT_FLAG_CALL, "Newstate",
02444 "Channel: %s\r\n"
02445 "State: %s\r\n"
02446 "Callerid: %s\r\n"
02447 "Uniqueid: %s\r\n",
02448 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02449 }
02450 }
02451 return 0;
02452 }
|
1.2.15