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