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

channel_pvt.h File Reference

#include <asterisk/channel.h>

Go to the source code of this file.

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 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 }

struct ast_channel* ast_channel_alloc int  needalertpipe  ) 
 

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 }

void ast_channel_free struct ast_channel  ) 
 

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 }

int ast_queue_control struct ast_channel chan,
int  control
 

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 }

int ast_queue_frame struct ast_channel chan,
struct ast_frame f
 

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 }

int ast_queue_hangup struct ast_channel chan  ) 
 

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 }

int ast_setstate struct ast_channel chan,
int  state
 

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 }


Generated on Sat Nov 25 19:10:00 2006 for Asterisk by  doxygen 1.4.2