channel_pvt.h File Reference

#include <asterisk/channel.h>

Include dependency graph for channel_pvt.h:

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

Go to the source code of this file.

Data Structures

struct  ast_channel_pvt

Functions

struct 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 2196 of file channel.c.

02197 {
02198    char tmp[256];
02199    strncpy(tmp, chan->name, sizeof(tmp) - 1);
02200    strncpy(chan->name, newname, sizeof(chan->name) - 1);
02201    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
02202 }

struct ast_channel* ast_channel_alloc ( int  needalertpipe  )  [read]

Create a channel structure.

Returns NULL on failure to allocate

Definition at line 274 of file channel.c.

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 561 of file channel.c.

00562 {
00563    struct ast_channel *last=NULL, *cur;
00564    int fd;
00565    struct ast_var_t *vardata;
00566    struct ast_frame *f, *fp;
00567    struct varshead *headp;
00568    char name[AST_CHANNEL_NAME];
00569    
00570    headp=&chan->varshead;
00571    
00572    ast_mutex_lock(&chlock);
00573    cur = channels;
00574    while(cur) {
00575       if (cur == chan) {
00576          if (last)
00577             last->next = cur->next;
00578          else
00579             channels = cur->next;
00580          break;
00581       }
00582       last = cur;
00583       cur = cur->next;
00584    }
00585    if (!cur)
00586       ast_log(LOG_WARNING, "Unable to find channel in list\n");
00587    else {
00588       /* Lock and unlock the channel just to be sure nobody
00589          has it locked still */
00590       ast_mutex_lock(&cur->lock);
00591       ast_mutex_unlock(&cur->lock);
00592    }
00593    if (chan->pvt->pvt)
00594       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00595 
00596    strncpy(name, chan->name, sizeof(name)-1);
00597    
00598    /* Stop monitoring */
00599    if (chan->monitor) {
00600       chan->monitor->stop( chan, 0 );
00601    }
00602 
00603    /* Free translatosr */
00604    if (chan->pvt->readtrans)
00605       ast_translator_free_path(chan->pvt->readtrans);
00606    if (chan->pvt->writetrans)
00607       ast_translator_free_path(chan->pvt->writetrans);
00608    if (chan->pbx) 
00609       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00610    if (chan->dnid)
00611       free(chan->dnid);
00612    if (chan->callerid)
00613       free(chan->callerid);   
00614    if (chan->ani)
00615       free(chan->ani);
00616    if (chan->rdnis)
00617       free(chan->rdnis);
00618    ast_mutex_destroy(&chan->lock);
00619    /* Close pipes if appropriate */
00620    if ((fd = chan->pvt->alertpipe[0]) > -1)
00621       close(fd);
00622    if ((fd = chan->pvt->alertpipe[1]) > -1)
00623       close(fd);
00624    if ((fd = chan->timingfd) > -1)
00625       close(fd);
00626    f = chan->pvt->readq;
00627    chan->pvt->readq = NULL;
00628    while(f) {
00629       fp = f;
00630       f = f->next;
00631       ast_frfree(fp);
00632    }
00633    
00634    /* loop over the variables list, freeing all data and deleting list items */
00635    /* no need to lock the list, as the channel is already locked */
00636    
00637    while (!AST_LIST_EMPTY(headp)) {           /* List Deletion. */
00638                vardata = AST_LIST_FIRST(headp);
00639                AST_LIST_REMOVE_HEAD(headp, entries);
00640 //             printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata));
00641                ast_var_delete(vardata);
00642    }
00643                                                     
00644 
00645    free(chan->pvt);
00646    chan->pvt = NULL;
00647    free(chan);
00648    ast_mutex_unlock(&chlock);
00649 
00650    ast_device_state_changed(name);
00651 }

int ast_queue_control ( struct ast_channel chan,
int  control 
)

Definition at line 434 of file channel.c.

00435 {
00436    struct ast_frame f = { AST_FRAME_CONTROL, };
00437    f.subclass = control;
00438    return ast_queue_frame(chan, &f);
00439 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame f 
)

Queue an outgoing frame

Definition at line 370 of file channel.c.

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

int ast_queue_hangup ( struct ast_channel chan  ) 

Definition at line 427 of file channel.c.

00428 {
00429    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00430    chan->_softhangup |= AST_SOFTHANGUP_DEV;
00431    return ast_queue_frame(chan, &f);
00432 }

int ast_setstate ( struct ast_channel chan,
int  state 
)

Change the state of a channel

Definition at line 2455 of file channel.c.

02456 {
02457    if (chan->_state != state) {
02458       int oldstate = chan->_state;
02459       chan->_state = state;
02460       if (oldstate == AST_STATE_DOWN) {
02461          ast_device_state_changed(chan->name);
02462          manager_event(EVENT_FLAG_CALL, "Newchannel",
02463          "Channel: %s\r\n"
02464          "State: %s\r\n"
02465          "CallerID: %s\r\n"
02466          "Uniqueid: %s\r\n",
02467          chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02468       } else {
02469          manager_event(EVENT_FLAG_CALL, "Newstate", 
02470             "Channel: %s\r\n"
02471             "State: %s\r\n"
02472             "CallerID: %s\r\n"
02473             "Uniqueid: %s\r\n",
02474             chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02475       }
02476    }
02477    return 0;
02478 }


Generated on Wed Oct 28 17:00:51 2009 for Asterisk by  doxygen 1.5.6