#include <asterisk/channel.h>Go to the source code of this file.
Functions | |
| ast_channel * | ast_channel_alloc (int needalertpipe) |
| Create a channel structure. | |
| 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. | |
|
||||||||||||
|
Definition at line 2247 of file channel.c. References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid. 02248 {
02249 char tmp[256];
02250 strncpy(tmp, chan->name, sizeof(tmp) - 1);
02251 strncpy(chan->name, newname, sizeof(chan->name) - 1);
02252 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
02253 }
|
|
|
Create a channel structure. Returns NULL on failure to allocate Definition at line 288 of file channel.c. References ast_alloc_uniqueid(), ast_default_accountcode, ast_default_amaflags, 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(), defaultlanguage, free, LOG_WARNING, malloc, ast_channel_pvt::pvt, and sched_context_create(). Referenced by ast_async_goto(), and ast_pbx_outgoing_exten(). 00289 {
00290 struct ast_channel *tmp;
00291 struct ast_channel_pvt *pvt;
00292 int x;
00293 int flags;
00294 struct varshead *headp;
00295 char *tmpuniqueid;
00296
00297
00298 /* If shutting down, don't allocate any new channels */
00299 if (shutting_down)
00300 return NULL;
00301 ast_mutex_lock(&chlock);
00302 tmp = malloc(sizeof(struct ast_channel));
00303 if (tmp) {
00304 memset(tmp, 0, sizeof(struct ast_channel));
00305 pvt = malloc(sizeof(struct ast_channel_pvt));
00306 if (pvt) {
00307 memset(pvt, 0, sizeof(struct ast_channel_pvt));
00308 tmp->sched = sched_context_create();
00309 if (tmp->sched) {
00310 for (x=0;x<AST_MAX_FDS - 1;x++)
00311 tmp->fds[x] = -1;
00312 #ifdef ZAPTEL_OPTIMIZATIONS
00313 tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00314 if (tmp->timingfd > -1) {
00315 /* Check if timing interface supports new
00316 ping/pong scheme */
00317 flags = 1;
00318 if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00319 needqueue = 0;
00320 }
00321 #else
00322 tmp->timingfd = -1;
00323 #endif
00324 if (needqueue &&
00325 pipe(pvt->alertpipe)) {
00326 ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
00327 free(pvt);
00328 free(tmp);
00329 tmp = NULL;
00330 pvt = NULL;
00331 } else {
00332 if (needqueue) {
00333 flags = fcntl(pvt->alertpipe[0], F_GETFL);
00334 fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00335 flags = fcntl(pvt->alertpipe[1], F_GETFL);
00336 fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00337 } else
00338 /* Make sure we've got it done right if they don't */
00339 pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
00340 /* Always watch the alertpipe */
00341 tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
00342 /* And timing pipe */
00343 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00344 strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
00345 tmp->pvt = pvt;
00346 /* Initial state */
00347 tmp->_state = AST_STATE_DOWN;
00348 tmp->stack = -1;
00349 tmp->streamid = -1;
00350 tmp->appl = NULL;
00351 tmp->data = NULL;
00352 tmp->fin = 0;
00353 tmp->fout = 0;
00354 tmpuniqueid = ast_alloc_uniqueid();
00355 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), tmpuniqueid);
00356 if (tmpuniqueid) {
00357 free(tmpuniqueid);
00358 tmpuniqueid = NULL;
00359 }
00360 headp=&tmp->varshead;
00361 ast_mutex_init(&tmp->lock);
00362 AST_LIST_HEAD_INIT(headp);
00363 tmp->vars=ast_var_assign("tempvar","tempval");
00364 AST_LIST_INSERT_HEAD(headp,tmp->vars,entries);
00365 strncpy(tmp->context, "default", sizeof(tmp->context)-1);
00366 strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
00367 strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
00368 tmp->priority=1;
00369 tmp->amaflags = ast_default_amaflags;
00370 strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
00371 tmp->next = channels;
00372 channels= tmp;
00373 }
00374 } else {
00375 ast_log(LOG_WARNING, "Unable to create schedule context\n");
00376 free(tmp);
00377 tmp = NULL;
00378 }
00379 } else {
00380 ast_log(LOG_WARNING, "Out of memory\n");
00381 free(tmp);
00382 tmp = NULL;
00383 }
00384 } else
00385 ast_log(LOG_WARNING, "Out of memory\n");
00386 ast_mutex_unlock(&chlock);
00387 return tmp;
00388 }
|
|
|
Free a channel structure.
Definition at line 594 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(). 00595 {
00596 struct ast_channel *last=NULL, *cur;
00597 int fd;
00598 struct ast_var_t *vardata;
00599 struct ast_frame *f, *fp;
00600 struct varshead *headp;
00601 char name[AST_CHANNEL_NAME];
00602
00603 headp=&chan->varshead;
00604
00605 ast_mutex_lock(&chlock);
00606 cur = channels;
00607 while(cur) {
00608 if (cur == chan) {
00609 if (last)
00610 last->next = cur->next;
00611 else
00612 channels = cur->next;
00613 break;
00614 }
00615 last = cur;
00616 cur = cur->next;
00617 }
00618 if (!cur)
00619 ast_log(LOG_WARNING, "Unable to find channel in list\n");
00620 else {
00621 /* Lock and unlock the channel just to be sure nobody
00622 has it locked still */
00623 ast_mutex_lock(&cur->lock);
00624 ast_mutex_unlock(&cur->lock);
00625 }
00626 if (chan->pvt->pvt)
00627 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00628
00629 strncpy(name, chan->name, sizeof(name)-1);
00630
00631 /* Stop monitoring */
00632 if (chan->monitor) {
00633 chan->monitor->stop( chan, 0 );
00634 }
00635
00636 /* Free translatosr */
00637 if (chan->pvt->readtrans)
00638 ast_translator_free_path(chan->pvt->readtrans);
00639 if (chan->pvt->writetrans)
00640 ast_translator_free_path(chan->pvt->writetrans);
00641 if (chan->pbx)
00642 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00643 if (chan->dnid)
00644 free(chan->dnid);
00645 if (chan->callerid)
00646 free(chan->callerid);
00647 if (chan->ani)
00648 free(chan->ani);
00649 if (chan->rdnis)
00650 free(chan->rdnis);
00651 ast_mutex_destroy(&chan->lock);
00652 /* Close pipes if appropriate */
00653 if ((fd = chan->pvt->alertpipe[0]) > -1)
00654 close(fd);
00655 if ((fd = chan->pvt->alertpipe[1]) > -1)
00656 close(fd);
00657 if ((fd = chan->timingfd) > -1)
00658 close(fd);
00659 f = chan->pvt->readq;
00660 chan->pvt->readq = NULL;
00661 while(f) {
00662 fp = f;
00663 f = f->next;
00664 ast_frfree(fp);
00665 }
00666
00667 /* loop over the variables list, freeing all data and deleting list items */
00668 /* no need to lock the list, as the channel is already locked */
00669
00670 while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */
00671 vardata = AST_LIST_FIRST(headp);
00672 AST_LIST_REMOVE_HEAD(headp, entries);
00673 // printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata));
00674 ast_var_delete(vardata);
00675 }
00676
00677
00678 free(chan->pvt);
00679 chan->pvt = NULL;
00680 free(chan);
00681 ast_mutex_unlock(&chlock);
00682
00683 ast_device_state_changed(name);
00684 }
|
|
||||||||||||
|
Definition at line 454 of file channel.c. References AST_FRAME_CONTROL, ast_queue_frame(), and ast_frame::subclass. 00455 {
00456 struct ast_frame f = { AST_FRAME_CONTROL, };
00457 f.subclass = control;
00458 return ast_queue_frame(chan, &f);
00459 }
|
|
||||||||||||
|
Queue an outgoing frame Definition at line 390 of file channel.c. References ast_channel_pvt::alertpipe, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_VOICE, 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_frame::prev, ast_channel::pvt, ast_channel_pvt::readq, ast_frame::subclass, and ast_channel::timingfd. Referenced by ast_channel_masquerade(), ast_channel_masquerade_locked(), ast_do_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), and ast_softhangup_nolock(). 00391 {
00392 struct ast_frame *f;
00393 struct ast_frame *prev, *cur;
00394 int blah = 1;
00395 int qlen = 0;
00396 /* Build us a copy and free the original one */
00397 f = ast_frdup(fin);
00398 if (!f) {
00399 ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00400 return -1;
00401 }
00402 ast_mutex_lock(&chan->lock);
00403 prev = NULL;
00404 cur = chan->pvt->readq;
00405 while(cur) {
00406 if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00407 /* Don't bother actually queueing anything after a hangup */
00408 ast_frfree(f);
00409 ast_mutex_unlock(&chan->lock);
00410 return 0;
00411 }
00412 prev = cur;
00413 cur = cur->next;
00414 qlen++;
00415 }
00416 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00417 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) {
00418 if (fin->frametype != AST_FRAME_VOICE) {
00419 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00420 CRASH;
00421 } else {
00422 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00423 ast_frfree(f);
00424 ast_mutex_unlock(&chan->lock);
00425 return 0;
00426 }
00427 }
00428 if (prev)
00429 prev->next = f;
00430 else
00431 chan->pvt->readq = f;
00432 if (chan->pvt->alertpipe[1] > -1) {
00433 if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00434 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00435 chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00436 #ifdef ZAPTEL_OPTIMIZATIONS
00437 } else if (chan->timingfd > -1) {
00438 ioctl(chan->timingfd, ZT_TIMERPING, &blah);
00439 #endif
00440 } else if (chan->blocking) {
00441 pthread_kill(chan->blocker, SIGURG);
00442 }
00443 ast_mutex_unlock(&chan->lock);
00444 return 0;
00445 }
|
|
|
Definition at line 447 of file channel.c. References ast_channel::_softhangup, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), and AST_SOFTHANGUP_DEV. 00448 {
00449 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00450 chan->_softhangup |= AST_SOFTHANGUP_DEV;
00451 return ast_queue_frame(chan, &f);
00452 }
|
|
||||||||||||
|
Change the state of a channel Definition at line 2501 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(). 02502 {
02503 if (chan->_state != state) {
02504 int oldstate = chan->_state;
02505 chan->_state = state;
02506 if (oldstate == AST_STATE_DOWN) {
02507 ast_device_state_changed(chan->name);
02508 manager_event(EVENT_FLAG_CALL, "Newchannel",
02509 "Channel: %s\r\n"
02510 "State: %s\r\n"
02511 "CallerID: %s\r\n"
02512 "Uniqueid: %s\r\n",
02513 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02514 } else {
02515 ast_device_state_changed(chan->name);
02516 manager_event(EVENT_FLAG_CALL, "Newstate",
02517 "Channel: %s\r\n"
02518 "State: %s\r\n"
02519 "CallerID: %s\r\n"
02520 "Uniqueid: %s\r\n",
02521 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02522 }
02523 }
02524 return 0;
02525 }
|
1.4.2