Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:27 2009

## 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"`

Include dependency graph for chan_features.c:

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_pvt * | features_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_channel * | features_new (struct feature_pvt *p, int state, int index)
static struct ast_frame * | features_read (struct ast_channel *ast)
static struct ast_channel * | features_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_pvt * | features
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,
|  | b |  | ) | (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(), 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(), 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, read]`

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(), feature_pvt::lock, LOG_NOTICE, malloc, feature_pvt::next, feature_pvt::subchan, feature_pvt::subs, 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, read]`

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, 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, read]`

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, read]`

Definition at line 501 of file chan_features.c.

References AST_STATE_DOWN, features_alloc(), features_new(), feature_sub::owner, 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.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

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(), 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, features, 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.

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

struct ast_channel_tech features_tech`[static]`

Definition at line 107 of file chan_features.c.

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.