Sat Sep 16 05:47:53 2006

Asterisk developer's documentation


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

Variables

static struct ast_cli_entry cli_show_features
static const char desc [] = "Feature Proxy Channel"
static struct feature_pvtfeatures
static struct ast_channel_tech features_tech
static char show_features_usage []
static const char tdesc [] = "Feature Proxy Channel Driver"
static const char type [] = "Feature"
static 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 available(), features_hangup(), ss_thread(), zap_show_channel(), zt_bridge(), zt_call(), zt_handle_event(), zt_hangup(), zt_read(), 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_hangup(), features_request(), get_alarms(), handle_init_event(), mkintf(), reset_conf(), restore_conference(), restore_gains(), save_conference(), send_callerid(), ss_thread(), 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(), available(), features_hangup(), ss_thread(), zap_show_channel(), zt_answer(), zt_bridge(), 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 591 of file chan_features.c.

00592 {
00593    return (char *) desc;
00594 }

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

Definition at line 399 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(), LOG_NOTICE, malloc, feature_pvt::next, and feature_pvt::tech.

Referenced by features_request().

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

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

static 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          p->subchan->cid.cid_name = p->owner->cid.cid_name ? 
00332             strdup(p->owner->cid.cid_name) : NULL;
00333          p->subchan->cid.cid_num = p->owner->cid.cid_num ? 
00334             strdup(p->owner->cid.cid_num) : NULL;
00335          p->subchan->cid.cid_ani = p->owner->cid.cid_ani ? 
00336             strdup(p->owner->cid.cid_ani) : NULL;
00337          p->subchan->cid.cid_rdnis = p->owner->cid.cid_rdnis ? 
00338             strdup(p->owner->cid.cid_rdnis) : NULL;
00339       
00340          p->subchan->cid.cid_pres = p->owner->cid.cid_pres;
00341          strncpy(p->subchan->language, p->owner->language, sizeof(p->subchan->language) - 1);
00342          strncpy(p->subchan->accountcode, p->owner->accountcode, sizeof(p->subchan->accountcode) - 1);
00343          p->subchan->cdrflags = p->owner->cdrflags;
00344          res = ast_call(p->subchan, dest2, timeout);
00345          update_features(p, x);
00346       } else
00347          ast_log(LOG_NOTICE, "Uhm yah, not quite there with the call waiting...\n");
00348       ast_mutex_unlock(&p->lock);
00349    }
00350    return res;
00351 }

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

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

static int features_hangup ( struct ast_channel ast  )  [static]

Definition at line 353 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(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, feature_pvt::subchan, feature_pvt::subs, and ast_channel::tech_pvt.

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

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

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

Definition at line 453 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, features_tech, 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_lock, and ast_channel::writeformat.

Referenced by features_request().

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

static struct ast_frame * features_read ( struct ast_channel ast  )  [static]

Definition at line 241 of file chan_features.c.

References AST_FRAME_NULL, 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 }

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

Definition at line 501 of file chan_features.c.

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

00502 {
00503    struct feature_pvt *p;
00504    struct ast_channel *chan = NULL;
00505 
00506    p = features_alloc(data, format);
00507    if (p && !p->subs[SUB_REAL].owner)
00508       chan = features_new(p, AST_STATE_DOWN, SUB_REAL);
00509    if (chan)
00510       update_features(p,SUB_REAL);
00511    return chan;
00512 }

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

Definition at line 514 of file chan_features.c.

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

00515 {
00516    struct feature_pvt *p;
00517 
00518    if (argc != 3)
00519       return RESULT_SHOWUSAGE;
00520    ast_mutex_lock(&featurelock);
00521    p = features;
00522    while(p) {
00523       ast_mutex_lock(&p->lock);
00524       ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "<unowned>", p->tech, p->dest);
00525       ast_mutex_unlock(&p->lock);
00526       p = p->next;
00527    }
00528    if (!features)
00529       ast_cli(fd, "No feature channels in use\n");
00530    ast_mutex_unlock(&featurelock);
00531    return RESULT_SUCCESS;
00532 }

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

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

static 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 586 of file chan_features.c.

References ASTERISK_GPL_KEY.

00587 {
00588    return ASTERISK_GPL_KEY;
00589 }

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 542 of file chan_features.c.

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

00543 {
00544    /* Make sure we can register our sip channel type */
00545    if (ast_channel_register(&features_tech)) {
00546       ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
00547       return -1;
00548    }
00549    ast_cli_register(&cli_show_features);
00550    return 0;
00551 }

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 553 of file chan_features.c.

00554 {
00555    return 0;
00556 }

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

00559 {
00560    struct feature_pvt *p, *prev;
00561    /* First, take us out of the channel loop */
00562    ast_cli_unregister(&cli_show_features);
00563    ast_channel_unregister(&features_tech);
00564    if (!ast_mutex_lock(&featurelock)) {
00565       /* Hangup all interfaces if they have an owner */
00566       for (p = features; p; p = p->next) {
00567          prev = p;
00568          if (p->owner)
00569             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
00570          free(prev);
00571       }
00572       features = NULL;
00573       ast_mutex_unlock(&featurelock);
00574    } else {
00575       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
00576       return -1;
00577    }     
00578    return 0;
00579 }

static void update_features ( struct feature_pvt p,
int  index 
) [static]

Definition at line 176 of file chan_features.c.

References ast_channel::alertpipe, AST_MAX_FDS, 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 581 of file chan_features.c.

00582 {
00583    return usecnt;
00584 }


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 538 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 ast_feature_interpret(), features_alloc(), features_hangup(), features_show(), unload_module(), and zt_new().

struct ast_channel_tech features_tech [static]

Definition at line 107 of file chan_features.c.

Referenced by features_new(), 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 534 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.


Generated on Sat Sep 16 05:47:53 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7