#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. | |
| int | ast_queue_frame (struct ast_channel *chan, struct ast_frame *f, int lock) |
| int | ast_queue_hangup (struct ast_channel *chan, int lock) |
| int | ast_queue_control (struct ast_channel *chan, int control, int lock) |
| 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 1866 of file channel.c. References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.
|
|
|
Create a channel structure. Returns NULL on failure to allocate Definition at line 263 of file channel.c. References ast_default_accountcode, ast_default_amaflags, AST_LIST_HEAD_INIT, AST_LIST_INSERT_HEAD, ast_log(), AST_MAX_FDS, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, AST_STATE_DOWN, ast_var_assign(), channels, defaultlanguage, free, LOG_WARNING, malloc, and sched_context_create(). Referenced by ast_async_goto().
00264 {
00265 struct ast_channel *tmp;
00266 struct ast_channel_pvt *pvt;
00267 int x;
00268 int flags;
00269 struct varshead *headp;
00270
00271
00272 /* If shutting down, don't allocate any new channels */
00273 if (shutting_down)
00274 return NULL;
00275 ast_mutex_lock(&chlock);
00276 tmp = malloc(sizeof(struct ast_channel));
00277 if (tmp) {
00278 memset(tmp, 0, sizeof(struct ast_channel));
00279 pvt = malloc(sizeof(struct ast_channel_pvt));
00280 if (pvt) {
00281 memset(pvt, 0, sizeof(struct ast_channel_pvt));
00282 tmp->sched = sched_context_create();
00283 if (tmp->sched) {
00284 for (x=0;x<AST_MAX_FDS - 1;x++)
00285 tmp->fds[x] = -1;
00286 if (needqueue &&
00287 pipe(pvt->alertpipe)) {
00288 ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
00289 free(pvt);
00290 free(tmp);
00291 tmp = NULL;
00292 pvt = NULL;
00293 } else {
00294 /* Make sure we've got it done right if they don't */
00295 if (needqueue) {
00296 flags = fcntl(pvt->alertpipe[0], F_GETFL);
00297 fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00298 flags = fcntl(pvt->alertpipe[1], F_GETFL);
00299 fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00300 } else
00301 pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
00302 #ifdef ZAPTEL_OPTIMIZATIONS
00303 tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00304 #else
00305 tmp->timingfd = -1;
00306 #endif
00307 /* Always watch the alertpipe */
00308 tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
00309 /* And timing pipe */
00310 tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00311 strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
00312 tmp->pvt = pvt;
00313 /* Initial state */
00314 tmp->_state = AST_STATE_DOWN;
00315 tmp->stack = -1;
00316 tmp->streamid = -1;
00317 tmp->appl = NULL;
00318 tmp->data = NULL;
00319 tmp->fin = 0;
00320 tmp->fout = 0;
00321 snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
00322 headp=&tmp->varshead;
00323 ast_mutex_init(&tmp->lock);
00324 AST_LIST_HEAD_INIT(headp);
00325 tmp->vars=ast_var_assign("tempvar","tempval");
00326 AST_LIST_INSERT_HEAD(headp,tmp->vars,entries);
00327 strncpy(tmp->context, "default", sizeof(tmp->context)-1);
00328 strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
00329 strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
00330 tmp->priority=1;
00331 tmp->amaflags = ast_default_amaflags;
00332 strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
00333 tmp->next = channels;
00334 channels= tmp;
00335 }
00336 } else {
00337 ast_log(LOG_WARNING, "Unable to create schedule context\n");
00338 free(tmp);
00339 tmp = NULL;
00340 }
00341 } else {
00342 ast_log(LOG_WARNING, "Out of memory\n");
00343 free(tmp);
00344 tmp = NULL;
00345 }
00346 } else
00347 ast_log(LOG_WARNING, "Out of memory\n");
00348 ast_mutex_unlock(&chlock);
00349 return tmp;
00350 }
|
|
|
Free a channel structure.
Definition at line 489 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, channels, 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_hangup().
00490 {
00491 struct ast_channel *last=NULL, *cur;
00492 int fd;
00493 struct ast_var_t *vardata;
00494 struct ast_frame *f, *fp;
00495 struct varshead *headp;
00496 char name[AST_CHANNEL_NAME];
00497
00498 headp=&chan->varshead;
00499
00500 ast_mutex_lock(&chlock);
00501 cur = channels;
00502 while(cur) {
00503 if (cur == chan) {
00504 if (last)
00505 last->next = cur->next;
00506 else
00507 channels = cur->next;
00508 break;
00509 }
00510 last = cur;
00511 cur = cur->next;
00512 }
00513 if (!cur)
00514 ast_log(LOG_WARNING, "Unable to find channel in list\n");
00515 if (chan->pvt->pvt)
00516 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00517
00518 strncpy(name, chan->name, sizeof(name)-1);
00519
00520 /* Stop monitoring */
00521 if (chan->monitor) {
00522 chan->monitor->stop( chan, 0 );
00523 }
00524
00525 /* Free translatosr */
00526 if (chan->pvt->readtrans)
00527 ast_translator_free_path(chan->pvt->readtrans);
00528 if (chan->pvt->writetrans)
00529 ast_translator_free_path(chan->pvt->writetrans);
00530 if (chan->pbx)
00531 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00532 if (chan->dnid)
00533 free(chan->dnid);
00534 if (chan->callerid)
00535 free(chan->callerid);
00536 if (chan->ani)
00537 free(chan->ani);
00538 if (chan->rdnis)
00539 free(chan->rdnis);
00540 ast_mutex_destroy(&chan->lock);
00541 /* Close pipes if appropriate */
00542 if ((fd = chan->pvt->alertpipe[0]) > -1)
00543 close(fd);
00544 if ((fd = chan->pvt->alertpipe[1]) > -1)
00545 close(fd);
00546 if ((fd = chan->timingfd) > -1)
00547 close(fd);
00548 f = chan->pvt->readq;
00549 chan->pvt->readq = NULL;
00550 while(f) {
00551 fp = f;
00552 f = f->next;
00553 ast_frfree(fp);
00554 }
00555
00556 /* loop over the variables list, freeing all data and deleting list items */
00557 /* no need to lock the list, as the channel is already locked */
00558
00559 while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */
00560 vardata = AST_LIST_FIRST(headp);
00561 AST_LIST_REMOVE_HEAD(headp, entries);
00562 // printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata));
00563 ast_var_delete(vardata);
00564 }
00565
00566
00567 free(chan->pvt);
00568 chan->pvt = NULL;
00569 free(chan);
00570 ast_mutex_unlock(&chlock);
00571
00572 ast_device_state_changed(name);
00573 }
|
|
||||||||||||||||
|
Definition at line 409 of file channel.c. References AST_FRAME_CONTROL, ast_queue_frame(), and ast_frame::subclass.
00410 {
00411 struct ast_frame f = { AST_FRAME_CONTROL, };
00412 f.subclass = control;
00413 return ast_queue_frame(chan, &f, lock);
00414 }
|
|
||||||||||||||||
|
Queue an outgoing frame, locking if necessary Definition at line 352 of file channel.c. References ast_channel_pvt::alertpipe, 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_channel::pvt, and ast_channel_pvt::readq. Referenced by ast_channel_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_hangup(), and ast_softhangup_nolock().
00353 {
00354 struct ast_frame *f;
00355 struct ast_frame *prev, *cur;
00356 int blah = 1;
00357 int qlen = 0;
00358 /* Build us a copy and free the original one */
00359 f = ast_frdup(fin);
00360 if (!f) {
00361 ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00362 return -1;
00363 }
00364 if (lock)
00365 ast_mutex_lock(&chan->lock);
00366 prev = NULL;
00367 cur = chan->pvt->readq;
00368 while(cur) {
00369 prev = cur;
00370 cur = cur->next;
00371 qlen++;
00372 }
00373 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00374 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) {
00375 if (fin->frametype != AST_FRAME_VOICE) {
00376 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00377 CRASH;
00378 } else {
00379 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00380 ast_frfree(f);
00381 if (lock)
00382 ast_mutex_unlock(&chan->lock);
00383 return 0;
00384 }
00385 }
00386 if (prev)
00387 prev->next = f;
00388 else
00389 chan->pvt->readq = f;
00390 if (chan->pvt->alertpipe[1] > -1) {
00391 if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00392 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00393 chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00394 } else if (chan->blocking) {
00395 pthread_kill(chan->blocker, SIGURG);
00396 }
00397 if (lock)
00398 ast_mutex_unlock(&chan->lock);
00399 return 0;
00400 }
|
|
||||||||||||
|
Definition at line 402 of file channel.c. References ast_channel::_softhangup, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), and AST_SOFTHANGUP_DEV.
00403 {
00404 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00405 chan->_softhangup |= AST_SOFTHANGUP_DEV;
00406 return ast_queue_frame(chan, &f, lock);
00407 }
|
|
||||||||||||
|
Change the state of a channel Definition at line 2096 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().
02097 {
02098 if (chan->_state != state) {
02099 int oldstate = chan->_state;
02100 chan->_state = state;
02101 if (oldstate == AST_STATE_DOWN) {
02102 ast_device_state_changed(chan->name);
02103 manager_event(EVENT_FLAG_CALL, "Newchannel",
02104 "Channel: %s\r\n"
02105 "State: %s\r\n"
02106 "Callerid: %s\r\n"
02107 "Uniqueid: %s\r\n",
02108 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02109 } else {
02110 manager_event(EVENT_FLAG_CALL, "Newstate",
02111 "Channel: %s\r\n"
02112 "State: %s\r\n"
02113 "Callerid: %s\r\n"
02114 "Uniqueid: %s\r\n",
02115 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02116 }
02117 }
02118 return 0;
02119 }
|
1.3.4