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

channel_pvt.h File Reference

#include <asterisk/channel.h>

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


Function Documentation

void ast_change_name struct ast_channel chan,
char *  newname
 

Definition at line 1919 of file channel.c.

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

01920 {
01921    char tmp[256];
01922    strncpy(tmp, chan->name, 256);
01923    strncpy(chan->name, newname, sizeof(chan->name) - 1);
01924    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
01925 }

struct ast_channel* ast_channel_alloc int  needalertpipe  ) 
 

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 }

void ast_channel_free struct ast_channel  ) 
 

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 }

int ast_queue_control struct ast_channel chan,
int  control,
int  lock
 

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 }

int ast_queue_frame struct ast_channel chan,
struct ast_frame f,
int  lock
 

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 }

int ast_queue_hangup struct ast_channel chan,
int  lock
 

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 }

int ast_setstate struct ast_channel chan,
int  state
 

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 }


Generated on Fri Feb 27 12:19:47 2004 for Asterisk by doxygen 1.3.5