Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

channel_pvt.h File Reference

#include <asterisk/channel.h>

Include dependency graph for channel_pvt.h:

Include dependency graph

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

struct  ast_channel_pvt

Functions

ast_channelast_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.


Function Documentation

void ast_change_name struct ast_channel chan,
char *  newname
 

Definition at line 2109 of file channel.c.

References EVENT_FLAG_CALL, manager_event(), ast_channel::name, and ast_channel::uniqueid.

02110 { 02111 char tmp[256]; 02112 strncpy(tmp, chan->name, 256); 02113 strncpy(chan->name, newname, sizeof(chan->name) - 1); 02114 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid); 02115 }

struct ast_channel* ast_channel_alloc int  needalertpipe  ) 
 

Create a channel structure.

Returns NULL on failure to allocate

Definition at line 274 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_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(), 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 }

void ast_channel_free struct ast_channel  ) 
 

Free a channel structure.

Definition at line 526 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_do_masquerade(), and ast_hangup().

00527 { 00528 struct ast_channel *last=NULL, *cur; 00529 int fd; 00530 struct ast_var_t *vardata; 00531 struct ast_frame *f, *fp; 00532 struct varshead *headp; 00533 char name[AST_CHANNEL_NAME]; 00534 00535 headp=&chan->varshead; 00536 00537 ast_mutex_lock(&chlock); 00538 cur = channels; 00539 while(cur) { 00540 if (cur == chan) { 00541 if (last) 00542 last->next = cur->next; 00543 else 00544 channels = cur->next; 00545 break; 00546 } 00547 last = cur; 00548 cur = cur->next; 00549 } 00550 if (!cur) 00551 ast_log(LOG_WARNING, "Unable to find channel in list\n"); 00552 else { 00553 /* Lock and unlock the channel just to be sure nobody 00554 has it locked still */ 00555 ast_mutex_lock(&cur->lock); 00556 ast_mutex_unlock(&cur->lock); 00557 } 00558 if (chan->pvt->pvt) 00559 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 00560 00561 strncpy(name, chan->name, sizeof(name)-1); 00562 00563 /* Stop monitoring */ 00564 if (chan->monitor) { 00565 chan->monitor->stop( chan, 0 ); 00566 } 00567 00568 /* Free translatosr */ 00569 if (chan->pvt->readtrans) 00570 ast_translator_free_path(chan->pvt->readtrans); 00571 if (chan->pvt->writetrans) 00572 ast_translator_free_path(chan->pvt->writetrans); 00573 if (chan->pbx) 00574 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 00575 if (chan->dnid) 00576 free(chan->dnid); 00577 if (chan->callerid) 00578 free(chan->callerid); 00579 if (chan->ani) 00580 free(chan->ani); 00581 if (chan->rdnis) 00582 free(chan->rdnis); 00583 ast_mutex_destroy(&chan->lock); 00584 /* Close pipes if appropriate */ 00585 if ((fd = chan->pvt->alertpipe[0]) > -1) 00586 close(fd); 00587 if ((fd = chan->pvt->alertpipe[1]) > -1) 00588 close(fd); 00589 if ((fd = chan->timingfd) > -1) 00590 close(fd); 00591 f = chan->pvt->readq; 00592 chan->pvt->readq = NULL; 00593 while(f) { 00594 fp = f; 00595 f = f->next; 00596 ast_frfree(fp); 00597 } 00598 00599 /* loop over the variables list, freeing all data and deleting list items */ 00600 /* no need to lock the list, as the channel is already locked */ 00601 00602 while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */ 00603 vardata = AST_LIST_FIRST(headp); 00604 AST_LIST_REMOVE_HEAD(headp, entries); 00605 // printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata)); 00606 ast_var_delete(vardata); 00607 } 00608 00609 00610 free(chan->pvt); 00611 chan->pvt = NULL; 00612 free(chan); 00613 ast_mutex_unlock(&chlock); 00614 00615 ast_device_state_changed(name); 00616 }

int ast_queue_control struct ast_channel chan,
int  control
 

Definition at line 428 of file channel.c.

References AST_FRAME_CONTROL, ast_queue_frame(), and ast_frame::subclass.

00429 { 00430 struct ast_frame f = { AST_FRAME_CONTROL, }; 00431 f.subclass = control; 00432 return ast_queue_frame(chan, &f); 00433 }

int ast_queue_frame struct ast_channel chan,
struct ast_frame f
 

Queue an outgoing frame

Definition at line 370 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, ast_channel_pvt::readq, 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 prev = cur; 00387 cur = cur->next; 00388 qlen++; 00389 } 00390 /* Allow up to 96 voice frames outstanding, and up to 128 total frames */ 00391 if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen > 128)) { 00392 if (fin->frametype != AST_FRAME_VOICE) { 00393 ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name); 00394 CRASH; 00395 } else { 00396 ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name); 00397 ast_frfree(f); 00398 ast_mutex_unlock(&chan->lock); 00399 return 0; 00400 } 00401 } 00402 if (prev) 00403 prev->next = f; 00404 else 00405 chan->pvt->readq = f; 00406 if (chan->pvt->alertpipe[1] > -1) { 00407 if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah)) 00408 ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n", 00409 chan->name, f->frametype, f->subclass, qlen, strerror(errno)); 00410 #ifdef ZAPTEL_OPTIMIZATIONS 00411 } else if (chan->timingfd > -1) { 00412 ioctl(chan->timingfd, ZT_TIMERPING, &blah); 00413 #endif 00414 } else if (chan->blocking) { 00415 pthread_kill(chan->blocker, SIGURG); 00416 } 00417 ast_mutex_unlock(&chan->lock); 00418 return 0; 00419 }

int ast_queue_hangup struct ast_channel chan  ) 
 

Definition at line 421 of file channel.c.

References ast_channel::_softhangup, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), and AST_SOFTHANGUP_DEV.

00422 { 00423 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; 00424 chan->_softhangup |= AST_SOFTHANGUP_DEV; 00425 return ast_queue_frame(chan, &f); 00426 }

int ast_setstate struct ast_channel chan,
int  state
 

Change the state of a channel

Definition at line 2350 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().

02351 { 02352 if (chan->_state != state) { 02353 int oldstate = chan->_state; 02354 chan->_state = state; 02355 if (oldstate == AST_STATE_DOWN) { 02356 ast_device_state_changed(chan->name); 02357 manager_event(EVENT_FLAG_CALL, "Newchannel", 02358 "Channel: %s\r\n" 02359 "State: %s\r\n" 02360 "Callerid: %s\r\n" 02361 "Uniqueid: %s\r\n", 02362 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid); 02363 } else { 02364 manager_event(EVENT_FLAG_CALL, "Newstate", 02365 "Channel: %s\r\n" 02366 "State: %s\r\n" 02367 "Callerid: %s\r\n" 02368 "Uniqueid: %s\r\n", 02369 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid); 02370 } 02371 } 02372 return 0; 02373 }


Generated on Sat Jun 12 16:41:10 2004 for Asterisk by doxygen 1.3.7