Mon Mar 20 08:25:50 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

chan_features.c File Reference

feature Proxy Channel More...

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"

Go to the source code of this file.

Data Structures

struct  feature_pvt
struct  feature_sub

Defines

#define IS_OUTBOUND(a, b)   (a == b->chan ? 1 : 0)
#define SUB_CALLWAIT   1
#define SUB_REAL   0
#define SUB_THREEWAY   2

Functions

 AST_MUTEX_DEFINE_STATIC (featurelock)
 AST_MUTEX_DEFINE_STATIC (usecnt_lock)
char * description ()
 Provides a description of the module.
feature_pvtfeatures_alloc (char *data, int format)
int features_answer (struct ast_channel *ast)
int features_call (struct ast_channel *ast, char *dest, int timeout)
int features_digit (struct ast_channel *ast, char digit)
int features_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
int features_hangup (struct ast_channel *ast)
int features_indicate (struct ast_channel *ast, int condition)
ast_channelfeatures_new (struct feature_pvt *p, int state, int index)
ast_framefeatures_read (struct ast_channel *ast)
ast_channelfeatures_request (const char *type, int format, void *data, int *cause)
int features_show (int fd, int argc, char **argv)
int features_write (struct ast_channel *ast, struct ast_frame *f)
int indexof (struct feature_pvt *p, struct ast_channel *owner, int nullok)
void init_sub (struct feature_sub *sub)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module ()
 Initialize the module.
int reload ()
 Reload stuff.
void restore_channel (struct feature_pvt *p, int index)
int unload_module ()
 Cleanup all module structures, sockets, etc.
void update_features (struct feature_pvt *p, int index)
int usecount ()
 Provides a usecount.

Variables

ast_cli_entry cli_show_features
const char desc [] = "Feature Proxy Channel"
feature_pvtfeatures
const struct ast_channel_tech features_tech
char show_features_usage []
const char tdesc [] = "Feature Proxy Channel Driver"
const char type [] = "Feature"
int usecnt = 0


Detailed Description

feature Proxy Channel

Note:
*** Experimental code ****

Definition in file chan_features.c.


Define Documentation

#define IS_OUTBOUND a,
 )     (a == b->chan ? 1 : 0)
 

Definition at line 70 of file chan_features.c.

Referenced by local_answer(), local_digit(), local_hangup(), local_indicate(), local_sendhtml(), and local_write().

#define SUB_CALLWAIT   1
 

Definition at line 94 of file chan_features.c.

Referenced by ss_thread(), zap_show_channel(), zt_bridge(), zt_call(), zt_handle_event(), zt_hangup(), and zt_request().

#define SUB_REAL   0
 

Definition at line 93 of file chan_features.c.

Referenced by __unload_module(), __zt_exception(), attempt_transfer(), available(), bump_gains(), chandup(), check_for_conference(), destroy_channel(), disable_dtmf_detect(), do_monitor(), enable_dtmf_detect(), features_request(), get_alarms(), handle_init_event(), mkintf(), reset_conf(), restore_conference(), restore_gains(), save_conference(), send_callerid(), ss_thread(), update_conf(), zap_show_channel(), zt_answer(), zt_bridge(), zt_call(), zt_confmute(), zt_digit(), zt_disable_ec(), zt_enable_ec(), zt_handle_event(), zt_hangup(), zt_indicate(), zt_new(), zt_read(), zt_request(), zt_ring_phone(), zt_setoption(), zt_train_ec(), and zt_unlink().

#define SUB_THREEWAY   2
 

Definition at line 95 of file chan_features.c.

Referenced by attempt_transfer(), ss_thread(), zap_show_channel(), zt_answer(), zt_handle_event(), and zt_hangup().


Function Documentation

AST_MUTEX_DEFINE_STATIC featurelock   ) 
 

AST_MUTEX_DEFINE_STATIC usecnt_lock   ) 
 

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 602 of file chan_features.c.

00603 {
00604    return (char *) desc;
00605 }

struct feature_pvt* features_alloc char *  data,
int  format
[static]
 

Definition at line 410 of file chan_features.c.

References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_strdupa, feature_pvt::dest, features, init_sub(), feature_pvt::lock, LOG_NOTICE, malloc, feature_pvt::next, feature_pvt::subchan, feature_pvt::subs, and feature_pvt::tech.

Referenced by features_request().

00411 {
00412    struct feature_pvt *tmp;
00413    char *dest=NULL;
00414    char *tech;
00415    int x;
00416    int status;
00417    struct ast_channel *chan;
00418    
00419    tech = ast_strdupa(data);
00420    if (tech) {
00421       dest = strchr(tech, '/');
00422       if (dest) {
00423          *dest = '\0';
00424          dest++;
00425       }
00426    }
00427    if (!tech || !dest) {
00428       ast_log(LOG_NOTICE, "Format for feature channel is Feature/Tech/Dest ('%s' not valid)!\n", 
00429          data);
00430       return NULL;
00431    }
00432    ast_mutex_lock(&featurelock);
00433    tmp = features;
00434    while(tmp) {
00435       if (!strcasecmp(tmp->tech, tech) && !strcmp(tmp->dest, dest))
00436          break;
00437       tmp = tmp->next;
00438    }
00439    ast_mutex_unlock(&featurelock);
00440    if (!tmp) {
00441       chan = ast_request(tech, format, dest, &status);
00442       if (!chan) {
00443          ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest);
00444          return NULL;
00445       }
00446       tmp = malloc(sizeof(struct feature_pvt));
00447       if (tmp) {
00448          memset(tmp, 0, sizeof(struct feature_pvt));
00449          for (x=0;x<3;x++)
00450             init_sub(tmp->subs + x);
00451          ast_mutex_init(&tmp->lock);
00452          strncpy(tmp->tech, tech, sizeof(tmp->tech) - 1);
00453          strncpy(tmp->dest, dest, sizeof(tmp->dest) - 1);
00454          tmp->subchan = chan;
00455          ast_mutex_lock(&featurelock);
00456          tmp->next = features;
00457          features = tmp;
00458          ast_mutex_unlock(&featurelock);
00459       }
00460    }
00461    return tmp;
00462 }

int features_answer struct ast_channel ast  )  [static]
 

Definition at line 227 of file chan_features.c.

References ast_answer(), ast_mutex_lock(), ast_mutex_unlock(), indexof(), feature_pvt::lock, feature_pvt::subchan, and ast_channel::tech_pvt.

00228 {
00229    struct feature_pvt *p = ast->tech_pvt;
00230    int res = -1;
00231    int x;
00232 
00233    ast_mutex_lock(&p->lock);
00234    x = indexof(p, ast, 0);
00235    if (!x && p->subchan)
00236       res = ast_answer(p->subchan);
00237    ast_mutex_unlock(&p->lock);
00238    return res;
00239 }

int features_call struct ast_channel ast,
char *  dest,
int  timeout
[static]
 

Definition at line 319 of file chan_features.c.

References ast_channel::accountcode, ast_call(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_channel::cdrflags, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, indexof(), ast_channel::language, feature_pvt::lock, LOG_NOTICE, feature_pvt::owner, strdup, feature_pvt::subchan, ast_channel::tech_pvt, and update_features().

00320 {
00321    struct feature_pvt *p = ast->tech_pvt;
00322    int res = -1;
00323    int x;
00324    char *dest2;
00325       
00326    dest2 = strchr(dest, '/');
00327    if (dest2) {
00328       ast_mutex_lock(&p->lock);
00329       x = indexof(p, ast, 0);
00330       if (!x && p->subchan) {
00331          if (p->owner->cid.cid_num)
00332             p->subchan->cid.cid_num = strdup(p->owner->cid.cid_num);
00333          else 
00334             p->subchan->cid.cid_num = NULL;
00335       
00336          if (p->owner->cid.cid_name)
00337             p->subchan->cid.cid_name = strdup(p->owner->cid.cid_name);
00338          else 
00339             p->subchan->cid.cid_name = NULL;
00340       
00341          if (p->owner->cid.cid_rdnis)
00342             p->subchan->cid.cid_rdnis = strdup(p->owner->cid.cid_rdnis);
00343          else
00344             p->subchan->cid.cid_rdnis = NULL;
00345       
00346          if (p->owner->cid.cid_ani)
00347             p->subchan->cid.cid_ani = strdup(p->owner->cid.cid_ani);
00348          else
00349             p->subchan->cid.cid_ani = NULL;
00350       
00351          p->subchan->cid.cid_pres = p->owner->cid.cid_pres;
00352          strncpy(p->subchan->language, p->owner->language, sizeof(p->subchan->language) - 1);
00353          strncpy(p->subchan->accountcode, p->owner->accountcode, sizeof(p->subchan->accountcode) - 1);
00354          p->subchan->cdrflags = p->owner->cdrflags;
00355          res = ast_call(p->subchan, dest2, timeout);
00356          update_features(p, x);
00357       } else
00358          ast_log(LOG_NOTICE, "Uhm yah, not quite there with the call waiting...\n");
00359       ast_mutex_unlock(&p->lock);
00360    }
00361    return res;
00362 }

int features_digit struct ast_channel ast,
char  digit
[static]
 

Definition at line 304 of file chan_features.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_senddigit(), indexof(), feature_pvt::lock, feature_pvt::subchan, and ast_channel::tech_pvt.

00305 {
00306    struct feature_pvt *p = ast->tech_pvt;
00307    int res = -1;
00308    int x;
00309 
00310    /* Queue up a frame representing the indication as a control frame */
00311    ast_mutex_lock(&p->lock);
00312    x = indexof(p, ast, 0);
00313    if (!x && p->subchan)
00314       res = ast_senddigit(p->subchan, digit);
00315    ast_mutex_unlock(&p->lock);
00316    return res;
00317 }

int features_fixup struct ast_channel oldchan,
struct ast_channel newchan
[static]
 

Definition at line 273 of file chan_features.c.

References ast_mutex_lock(), ast_mutex_unlock(), feature_pvt::lock, feature_sub::owner, feature_pvt::owner, feature_pvt::subs, and ast_channel::tech_pvt.

00274 {
00275    struct feature_pvt *p = newchan->tech_pvt;
00276    int x;
00277 
00278    ast_mutex_lock(&p->lock);
00279    if (p->owner == oldchan)
00280       p->owner = newchan;
00281    for (x = 0; x < 3; x++) {
00282       if (p->subs[x].owner == oldchan)
00283          p->subs[x].owner = newchan;
00284    }
00285    ast_mutex_unlock(&p->lock);
00286    return 0;
00287 }

int features_hangup struct ast_channel ast  )  [static]
 

Definition at line 364 of file chan_features.c.

References ast_hangup(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), features, free, indexof(), feature_pvt::lock, feature_pvt::next, feature_sub::owner, restore_channel(), feature_pvt::subchan, feature_pvt::subs, and ast_channel::tech_pvt.

00365 {
00366    struct feature_pvt *p = ast->tech_pvt;
00367    struct feature_pvt *cur, *prev=NULL;
00368    int x;
00369 
00370    ast_mutex_lock(&p->lock);
00371    x = indexof(p, ast, 0);
00372    if (x > -1) {
00373       restore_channel(p, x);
00374       p->subs[x].owner = NULL;
00375       /* XXX Re-arrange, unconference, etc XXX */
00376    }
00377    ast->tech_pvt = NULL;
00378    
00379    
00380    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
00381       ast_mutex_unlock(&p->lock);
00382       /* Remove from list */
00383       ast_mutex_lock(&featurelock);
00384       cur = features;
00385       while(cur) {
00386          if (cur == p) {
00387             if (prev)
00388                prev->next = cur->next;
00389             else
00390                features = cur->next;
00391             break;
00392          }
00393          prev = cur;
00394          cur = cur->next;
00395       }
00396       ast_mutex_unlock(&featurelock);
00397       ast_mutex_lock(&p->lock);
00398       /* And destroy */
00399       if (p->subchan)
00400          ast_hangup(p->subchan);
00401       ast_mutex_unlock(&p->lock);
00402       ast_mutex_destroy(&p->lock);
00403       free(p);
00404       return 0;
00405    }
00406    ast_mutex_unlock(&p->lock);
00407    return 0;
00408 }

int features_indicate struct ast_channel ast,
int  condition
[static]
 

Definition at line 289 of file chan_features.c.

References ast_indicate(), ast_mutex_lock(), ast_mutex_unlock(), indexof(), feature_pvt::lock, feature_pvt::subchan, and ast_channel::tech_pvt.

00290 {
00291    struct feature_pvt *p = ast->tech_pvt;
00292    int res = -1;
00293    int x;
00294 
00295    /* Queue up a frame representing the indication as a control frame */
00296    ast_mutex_lock(&p->lock);
00297    x = indexof(p, ast, 0);
00298    if (!x && p->subchan)
00299       res = ast_indicate(p->subchan, condition);
00300    ast_mutex_unlock(&p->lock);
00301    return res;
00302 }

struct ast_channel* features_new struct feature_pvt p,
int  state,
int  index
[static]
 

Definition at line 464 of file chan_features.c.

References ast_channel_alloc(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), ast_update_use_count(), feature_pvt::dest, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, feature_pvt::owner, feature_sub::owner, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, feature_pvt::subchan, feature_pvt::subs, feature_pvt::tech, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt, and ast_channel::writeformat.

Referenced by features_request().

00465 {
00466    struct ast_channel *tmp;
00467    int x,y;
00468    if (!p->subchan) {
00469       ast_log(LOG_WARNING, "Called upon channel with no subchan:(\n");
00470       return NULL;
00471    }
00472    if (p->subs[index].owner) {
00473       ast_log(LOG_WARNING, "Called to put index %d already there!\n", index);
00474       return NULL;
00475    }
00476    tmp = ast_channel_alloc(0);
00477    if (!tmp) {
00478       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00479       return NULL;
00480    }
00481    tmp->tech = &features_tech;
00482    for (x=1;x<4;x++) {
00483       snprintf(tmp->name, sizeof(tmp->name), "Feature/%s/%s-%d", p->tech, p->dest, x);
00484       for (y=0;y<3;y++) {
00485          if (y == index)
00486             continue;
00487          if (p->subs[y].owner && !strcasecmp(p->subs[y].owner->name, tmp->name))
00488             break;
00489       }
00490       if (y >= 3)
00491          break;
00492    }
00493    tmp->type = type;
00494    ast_setstate(tmp, state);
00495    tmp->writeformat = p->subchan->writeformat;
00496    tmp->rawwriteformat = p->subchan->rawwriteformat;
00497    tmp->readformat = p->subchan->readformat;
00498    tmp->rawreadformat = p->subchan->rawreadformat;
00499    tmp->nativeformats = p->subchan->readformat;
00500    tmp->tech_pvt = p;
00501    p->subs[index].owner = tmp;
00502    if (!p->owner)
00503       p->owner = tmp;
00504    ast_mutex_lock(&usecnt_lock);
00505    usecnt++;
00506    ast_mutex_unlock(&usecnt_lock);
00507    ast_update_use_count();
00508    return tmp;
00509 }

struct ast_frame * features_read struct ast_channel ast  )  [static]
 

Definition at line 241 of file chan_features.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_read(), indexof(), feature_pvt::lock, feature_pvt::subchan, ast_channel::tech_pvt, and update_features().

00242 {
00243    static struct ast_frame null_frame = { AST_FRAME_NULL, };
00244    struct feature_pvt *p = ast->tech_pvt;
00245    struct ast_frame *f;
00246    int x;
00247    
00248    f = &null_frame;
00249    ast_mutex_lock(&p->lock);
00250    x = indexof(p, ast, 0);
00251    if (!x && p->subchan) {
00252       update_features(p, x);
00253       f = ast_read(p->subchan);
00254    }
00255    ast_mutex_unlock(&p->lock);
00256    return f;
00257 }

struct ast_channel * features_request const char *  type,
int  format,
void *  data,
int *  cause
[static]
 

Definition at line 512 of file chan_features.c.

References AST_STATE_DOWN, features_alloc(), features_new(), feature_sub::owner, SUB_REAL, feature_pvt::subs, and update_features().

00513 {
00514    struct feature_pvt *p;
00515    struct ast_channel *chan = NULL;
00516 
00517    p = features_alloc(data, format);
00518    if (p && !p->subs[SUB_REAL].owner)
00519       chan = features_new(p, AST_STATE_DOWN, SUB_REAL);
00520    if (chan)
00521       update_features(p,SUB_REAL);
00522    return chan;
00523 }

int features_show int  fd,
int  argc,
char **  argv
[static]
 

Definition at line 525 of file chan_features.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), feature_pvt::dest, feature_pvt::lock, ast_channel::name, feature_pvt::next, feature_pvt::owner, and feature_pvt::tech.

00526 {
00527    struct feature_pvt *p;
00528 
00529    if (argc != 3)
00530       return RESULT_SHOWUSAGE;
00531    ast_mutex_lock(&featurelock);
00532    p = features;
00533    while(p) {
00534       ast_mutex_lock(&p->lock);
00535       ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "<unowned>", p->tech, p->dest);
00536       ast_mutex_unlock(&p->lock);
00537       p = p->next;
00538    }
00539    if (!features)
00540       ast_cli(fd, "No feature channels in use\n");
00541    ast_mutex_unlock(&featurelock);
00542    return RESULT_SUCCESS;
00543 }

int features_write struct ast_channel ast,
struct ast_frame f
[static]
 

Definition at line 259 of file chan_features.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_write(), indexof(), feature_pvt::lock, feature_pvt::subchan, and ast_channel::tech_pvt.

00260 {
00261    struct feature_pvt *p = ast->tech_pvt;
00262    int res = -1;
00263    int x;
00264 
00265    ast_mutex_lock(&p->lock);
00266    x = indexof(p, ast, 0);
00267    if (!x && p->subchan)
00268       res = ast_write(p->subchan, f);
00269    ast_mutex_unlock(&p->lock);
00270    return res;
00271 }

int indexof struct feature_pvt p,
struct ast_channel owner,
int  nullok
[inline, static]
 

Definition at line 131 of file chan_features.c.

References ast_log(), LOG_WARNING, feature_sub::owner, and feature_pvt::subs.

Referenced by features_answer(), features_call(), features_digit(), features_hangup(), features_indicate(), features_read(), and features_write().

00132 {
00133    int x;
00134    if (!owner) {
00135       ast_log(LOG_WARNING, "indexof called on NULL owner??\n");
00136       return -1;
00137    }
00138    for (x=0; x<3; x++) {
00139       if (owner == p->subs[x].owner)
00140          return x;
00141    }
00142    return -1;
00143 }

void init_sub struct feature_sub sub  )  [inline, static]
 

Definition at line 123 of file chan_features.c.

References feature_sub::alertpipebackup, feature_sub::inthreeway, feature_sub::pfd, and feature_sub::timingfdbackup.

Referenced by features_alloc().

00124 {
00125    sub->inthreeway = 0;
00126    sub->pfd = -1;
00127    sub->timingfdbackup = -1;
00128    sub->alertpipebackup[0] = sub->alertpipebackup[1] = -1;
00129 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 597 of file chan_features.c.

00598 {
00599    return ASTERISK_GPL_KEY;
00600 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 553 of file chan_features.c.

References ast_channel_register(), ast_cli_register(), ast_log(), cli_show_features, features_tech, LOG_ERROR, and type.

00554 {
00555    /* Make sure we can register our sip channel type */
00556    if (ast_channel_register(&features_tech)) {
00557       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
00558       return -1;
00559    }
00560    ast_cli_register(&cli_show_features);
00561    return 0;
00562 }

int reload void   ) 
 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 564 of file chan_features.c.

00565 {
00566    return 0;
00567 }

void restore_channel struct feature_pvt p,
int  index
[static]
 

Definition at line 166 of file chan_features.c.

References ast_channel::alertpipe, feature_sub::alertpipebackup, AST_MAX_FDS, ast_channel::fds, feature_sub::owner, feature_pvt::subs, ast_channel::timingfd, and feature_sub::timingfdbackup.

Referenced by features_hangup(), and update_features().

00167 {
00168    /* Restore timing/alertpipe */
00169    p->subs[index].owner->timingfd = p->subs[index].timingfdbackup;
00170    p->subs[index].owner->alertpipe[0] = p->subs[index].alertpipebackup[0];
00171    p->subs[index].owner->alertpipe[1] = p->subs[index].alertpipebackup[1];
00172    p->subs[index].owner->fds[AST_MAX_FDS-1] = p->subs[index].alertpipebackup[0];
00173    p->subs[index].owner->fds[AST_MAX_FDS-2] = p->subs[index].timingfdbackup;
00174 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 569 of file chan_features.c.

References ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, cli_show_features, features, features_tech, free, LOG_WARNING, feature_pvt::next, and feature_pvt::owner.

00570 {
00571    struct feature_pvt *p, *prev;
00572    /* First, take us out of the channel loop */
00573    ast_cli_unregister(&cli_show_features);
00574    ast_channel_unregister(&features_tech);
00575    if (!ast_mutex_lock(&featurelock)) {
00576       /* Hangup all interfaces if they have an owner */
00577       for (p = features; p; p = p->next) {
00578          prev = p;
00579          if (p->owner)
00580             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
00581          free(prev);
00582       }
00583       features = NULL;
00584       ast_mutex_unlock(&featurelock);
00585    } else {
00586       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
00587       return -1;
00588    }     
00589    return 0;
00590 }

void update_features struct feature_pvt p,
int  index
[static]
 

Definition at line 176 of file chan_features.c.

References ast_channel::alertpipe, ast_set_read_format(), ast_set_write_format(), ast_channel::fds, ast_channel::nativeformats, feature_sub::owner, ast_channel::readformat, restore_channel(), feature_pvt::subchan, feature_pvt::subs, ast_channel::timingfd, and ast_channel::writeformat.

Referenced by features_call(), features_read(), and features_request().

00177 {
00178    int x;
00179    if (p->subs[index].owner) {
00180       for (x=0; x<AST_MAX_FDS; x++) {
00181          if (index) 
00182             p->subs[index].owner->fds[x] = -1;
00183          else
00184             p->subs[index].owner->fds[x] = p->subchan->fds[x];
00185       }
00186       if (!index) {
00187          /* Copy timings from master channel */
00188          p->subs[index].owner->timingfd = p->subchan->timingfd;
00189          p->subs[index].owner->alertpipe[0] = p->subchan->alertpipe[0];
00190          p->subs[index].owner->alertpipe[1] = p->subchan->alertpipe[1];
00191          if (p->subs[index].owner->nativeformats != p->subchan->readformat) {
00192             p->subs[index].owner->nativeformats = p->subchan->readformat;
00193             if (p->subs[index].owner->readformat)
00194                ast_set_read_format(p->subs[index].owner, p->subs[index].owner->readformat);
00195             if (p->subs[index].owner->writeformat)
00196                ast_set_write_format(p->subs[index].owner, p->subs[index].owner->writeformat);
00197          }
00198       } else{
00199          restore_channel(p, index);
00200       }
00201    }
00202 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 592 of file chan_features.c.

00593 {
00594    return usecnt;
00595 }


Variable Documentation

struct ast_cli_entry cli_show_features [static]
 

Initial value:

 {
   { "feature", "show", "channels", NULL }, features_show, 
   "Show status of feature channels", show_features_usage, NULL }

Definition at line 549 of file chan_features.c.

Referenced by load_module(), and unload_module().

const char desc[] = "Feature Proxy Channel" [static]
 

Definition at line 63 of file chan_features.c.

struct feature_pvt * features [static]
 

Referenced by features_alloc(), features_hangup(), and unload_module().

const struct ast_channel_tech features_tech [static]
 

Definition at line 107 of file chan_features.c.

Referenced by load_module(), and unload_module().

char show_features_usage[] [static]
 

Initial value:

 
"Usage: feature show channels\n"
"       Provides summary information on feature channels.\n"

Definition at line 545 of file chan_features.c.

const char tdesc[] = "Feature Proxy Channel Driver" [static]
 

Definition at line 65 of file chan_features.c.

const char type[] = "Feature" [static]
 

Definition at line 64 of file chan_features.c.

int usecnt = 0 [static]
 

Definition at line 67 of file chan_features.c.

Referenced by features_new().


Generated on Mon Mar 20 08:25:50 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1