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

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

01867 {
01868    char tmp[256];
01869    strncpy(tmp, chan->name, 256);
01870    strncpy(chan->name, newname, sizeof(chan->name) - 1);
01871    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
01872 }

struct ast_channel* ast_channel_alloc int  needalertpipe  ) 
 

Create a channel structure.

Returns NULL on failure to allocate

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

Referenced by ast_async_goto().

00264 {
00265    struct ast_channel *tmp;
00266    struct ast_channel_pvt *pvt;
00267    int x;
00268    int flags;
00269    struct varshead *headp;        
00270            
00271    
00272    /* If shutting down, don't allocate any new channels */
00273    if (shutting_down)
00274       return NULL;
00275    ast_mutex_lock(&chlock);
00276    tmp = malloc(sizeof(struct ast_channel));
00277    if (tmp) {
00278       memset(tmp, 0, sizeof(struct ast_channel));
00279       pvt = malloc(sizeof(struct ast_channel_pvt));
00280       if (pvt) {
00281          memset(pvt, 0, sizeof(struct ast_channel_pvt));
00282          tmp->sched = sched_context_create();
00283          if (tmp->sched) {
00284             for (x=0;x<AST_MAX_FDS - 1;x++)
00285                tmp->fds[x] = -1;
00286             if (needqueue &&  
00287                pipe(pvt->alertpipe)) {
00288                ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
00289                free(pvt);
00290                free(tmp);
00291                tmp = NULL;
00292                pvt = NULL;
00293             } else {
00294                /* Make sure we've got it done right if they don't */
00295                if (needqueue) {
00296                   flags = fcntl(pvt->alertpipe[0], F_GETFL);
00297                   fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00298                   flags = fcntl(pvt->alertpipe[1], F_GETFL);
00299                   fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00300                } else
00301                   pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
00302 #ifdef ZAPTEL_OPTIMIZATIONS
00303                tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00304 #else
00305                tmp->timingfd = -1;              
00306 #endif
00307                /* Always watch the alertpipe */
00308                tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
00309                /* And timing pipe */
00310                tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00311                strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
00312                tmp->pvt = pvt;
00313                /* Initial state */
00314                tmp->_state = AST_STATE_DOWN;
00315                tmp->stack = -1;
00316                tmp->streamid = -1;
00317                tmp->appl = NULL;
00318                tmp->data = NULL;
00319                tmp->fin = 0;
00320                tmp->fout = 0;
00321                snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
00322                headp=&tmp->varshead;
00323                ast_mutex_init(&tmp->lock);
00324                     AST_LIST_HEAD_INIT(headp);
00325                tmp->vars=ast_var_assign("tempvar","tempval");
00326                AST_LIST_INSERT_HEAD(headp,tmp->vars,entries);
00327                strncpy(tmp->context, "default", sizeof(tmp->context)-1);
00328                strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
00329                strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
00330                tmp->priority=1;
00331                tmp->amaflags = ast_default_amaflags;
00332                strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
00333                tmp->next = channels;
00334                channels= tmp;
00335             }
00336          } else {
00337             ast_log(LOG_WARNING, "Unable to create schedule context\n");
00338             free(tmp);
00339             tmp = NULL;
00340          }
00341       } else {
00342          ast_log(LOG_WARNING, "Out of memory\n");
00343          free(tmp);
00344          tmp = NULL;
00345       }
00346    } else 
00347       ast_log(LOG_WARNING, "Out of memory\n");
00348    ast_mutex_unlock(&chlock);
00349    return tmp;
00350 }

void ast_channel_free struct ast_channel  ) 
 

Free a channel structure.

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

00490 {
00491    struct ast_channel *last=NULL, *cur;
00492    int fd;
00493    struct ast_var_t *vardata;
00494    struct ast_frame *f, *fp;
00495    struct varshead *headp;
00496    char name[AST_CHANNEL_NAME];
00497    
00498    headp=&chan->varshead;
00499    
00500    ast_mutex_lock(&chlock);
00501    cur = channels;
00502    while(cur) {
00503       if (cur == chan) {
00504          if (last)
00505             last->next = cur->next;
00506          else
00507             channels = cur->next;
00508          break;
00509       }
00510       last = cur;
00511       cur = cur->next;
00512    }
00513    if (!cur)
00514       ast_log(LOG_WARNING, "Unable to find channel in list\n");
00515    if (chan->pvt->pvt)
00516       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00517 
00518    strncpy(name, chan->name, sizeof(name)-1);
00519    
00520    /* Stop monitoring */
00521    if (chan->monitor) {
00522       chan->monitor->stop( chan, 0 );
00523    }
00524 
00525    /* Free translatosr */
00526    if (chan->pvt->readtrans)
00527       ast_translator_free_path(chan->pvt->readtrans);
00528    if (chan->pvt->writetrans)
00529       ast_translator_free_path(chan->pvt->writetrans);
00530    if (chan->pbx) 
00531       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00532    if (chan->dnid)
00533       free(chan->dnid);
00534    if (chan->callerid)
00535       free(chan->callerid);   
00536    if (chan->ani)
00537       free(chan->ani);
00538    if (chan->rdnis)
00539       free(chan->rdnis);
00540    ast_mutex_destroy(&chan->lock);
00541    /* Close pipes if appropriate */
00542    if ((fd = chan->pvt->alertpipe[0]) > -1)
00543       close(fd);
00544    if ((fd = chan->pvt->alertpipe[1]) > -1)
00545       close(fd);
00546    if ((fd = chan->timingfd) > -1)
00547       close(fd);
00548    f = chan->pvt->readq;
00549    chan->pvt->readq = NULL;
00550    while(f) {
00551       fp = f;
00552       f = f->next;
00553       ast_frfree(fp);
00554    }
00555    
00556    /* loop over the variables list, freeing all data and deleting list items */
00557    /* no need to lock the list, as the channel is already locked */
00558    
00559    while (!AST_LIST_EMPTY(headp)) {           /* List Deletion. */
00560                vardata = AST_LIST_FIRST(headp);
00561                AST_LIST_REMOVE_HEAD(headp, entries);
00562 //             printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata));
00563                ast_var_delete(vardata);
00564    }
00565                                                     
00566 
00567    free(chan->pvt);
00568    chan->pvt = NULL;
00569    free(chan);
00570    ast_mutex_unlock(&chlock);
00571 
00572    ast_device_state_changed(name);
00573 }

int ast_queue_control struct ast_channel chan,
int  control,
int  lock
 

Definition at line 409 of file channel.c.

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

00410 {
00411    struct ast_frame f = { AST_FRAME_CONTROL, };
00412    f.subclass = control;
00413    return ast_queue_frame(chan, &f, lock);
00414 }

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

Queue an outgoing frame, locking if necessary

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

00353 {
00354    struct ast_frame *f;
00355    struct ast_frame *prev, *cur;
00356    int blah = 1;
00357    int qlen = 0;
00358    /* Build us a copy and free the original one */
00359    f = ast_frdup(fin);
00360    if (!f) {
00361       ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00362       return -1;
00363    }
00364    if (lock)
00365       ast_mutex_lock(&chan->lock);
00366    prev = NULL;
00367    cur = chan->pvt->readq;
00368    while(cur) {
00369       prev = cur;
00370       cur = cur->next;
00371       qlen++;
00372    }
00373    /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00374    if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
00375       if (fin->frametype != AST_FRAME_VOICE) {
00376          ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00377          CRASH;
00378       } else {
00379          ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00380          ast_frfree(f);
00381          if (lock)
00382             ast_mutex_unlock(&chan->lock);
00383          return 0;
00384       }
00385    }
00386    if (prev)
00387       prev->next = f;
00388    else
00389       chan->pvt->readq = f;
00390    if (chan->pvt->alertpipe[1] > -1) {
00391       if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00392          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00393             chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00394    } else if (chan->blocking) {
00395       pthread_kill(chan->blocker, SIGURG);
00396    }
00397    if (lock)
00398       ast_mutex_unlock(&chan->lock);
00399    return 0;
00400 }

int ast_queue_hangup struct ast_channel chan,
int  lock
 

Definition at line 402 of file channel.c.

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

00403 {
00404    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00405    chan->_softhangup |= AST_SOFTHANGUP_DEV;
00406    return ast_queue_frame(chan, &f, lock);
00407 }

int ast_setstate struct ast_channel chan,
int  state
 

Change the state of a channel

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

02097 {
02098    if (chan->_state != state) {
02099       int oldstate = chan->_state;
02100       chan->_state = state;
02101       if (oldstate == AST_STATE_DOWN) {
02102          ast_device_state_changed(chan->name);
02103          manager_event(EVENT_FLAG_CALL, "Newchannel",
02104          "Channel: %s\r\n"
02105          "State: %s\r\n"
02106          "Callerid: %s\r\n"
02107          "Uniqueid: %s\r\n",
02108          chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02109       } else {
02110          manager_event(EVENT_FLAG_CALL, "Newstate", 
02111             "Channel: %s\r\n"
02112             "State: %s\r\n"
02113             "Callerid: %s\r\n"
02114             "Uniqueid: %s\r\n",
02115             chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02116       }
02117    }
02118    return 0;
02119 }


Generated on Fri Oct 31 07:05:11 2003 for Asterisk by doxygen 1.3.4