Thu Jul 9 13:40:57 2009

Asterisk developer's documentation


chan_features.c File Reference

feature Proxy Channel More...

#include "asterisk.h"
#include <fcntl.h>
#include <sys/signal.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.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 "asterisk/stringfields.h"

Go to the source code of this file.

Data Structures

struct  feature_pvt
struct  feature_sub
struct  features

Defines

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

Functions

static void __reg_module (void)
static void __unreg_module (void)
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_begin (struct ast_channel *ast, char digit)
static int features_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
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, const void *data, size_t datalen)
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 char * features_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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)
static int load_module (void)
static void restore_channel (struct feature_pvt *p, int index)
static int unload_module (void)
static void update_features (struct feature_pvt *p, int index)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Feature Proxy Channel" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, }
static const struct ast_module_infoast_module_info = &__mod_info
static struct ast_cli_entry cli_features []
static struct ast_channel_tech features_tech
static const char tdesc [] = "Feature Proxy Channel Driver"


Detailed Description

feature Proxy Channel

Author:
Mark Spencer <markster@digium.com>
Note:
*** Experimental code ****

Definition in file chan_features.c.


Define Documentation

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

Definition at line 59 of file chan_features.c.

Referenced by local_answer(), local_digit_begin(), local_digit_end(), local_hangup(), local_indicate(), local_sendhtml(), local_sendtext(), and local_write().

#define SUB_CALLWAIT   1

Definition at line 82 of file chan_features.c.

#define SUB_REAL   0

Definition at line 81 of file chan_features.c.

#define SUB_THREEWAY   2

Definition at line 83 of file chan_features.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 573 of file chan_features.c.

static void __unreg_module ( void   )  [static]

Definition at line 573 of file chan_features.c.

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

Definition at line 387 of file chan_features.c.

References ast_calloc, ast_copy_string(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_request(), ast_strdupa, chan, feature_pvt::dest, init_sub(), LOG_NOTICE, status, and feature_pvt::tech.

Referenced by features_request().

00388 {
00389    struct feature_pvt *tmp;
00390    char *dest=NULL;
00391    char *tech;
00392    int x;
00393    int status;
00394    struct ast_channel *chan;
00395    
00396    tech = ast_strdupa(data);
00397    if (tech) {
00398       dest = strchr(tech, '/');
00399       if (dest) {
00400          *dest = '\0';
00401          dest++;
00402       }
00403    }
00404    if (!tech || !dest) {
00405       ast_log(LOG_NOTICE, "Format for feature channel is Feature/Tech/Dest ('%s' not valid)!\n", 
00406          data);
00407       return NULL;
00408    }
00409    AST_LIST_LOCK(&features);
00410    AST_LIST_TRAVERSE(&features, tmp, list) {
00411       if (!strcasecmp(tmp->tech, tech) && !strcmp(tmp->dest, dest))
00412          break;
00413    }
00414    AST_LIST_UNLOCK(&features);
00415    if (!tmp) {
00416       chan = ast_request(tech, format, dest, &status);
00417       if (!chan) {
00418          ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest);
00419          return NULL;
00420       }
00421       tmp = ast_calloc(1, sizeof(*tmp));
00422       if (tmp) {
00423          for (x=0;x<3;x++)
00424             init_sub(tmp->subs + x);
00425          ast_mutex_init(&tmp->lock);
00426          ast_copy_string(tmp->tech, tech, sizeof(tmp->tech));
00427          ast_copy_string(tmp->dest, dest, sizeof(tmp->dest));
00428          tmp->subchan = chan;
00429          AST_LIST_LOCK(&features);
00430          AST_LIST_INSERT_HEAD(&features, tmp, list);
00431          AST_LIST_UNLOCK(&features);
00432       }
00433    }
00434    return tmp;
00435 }

static int features_answer ( struct ast_channel ast  )  [static]

Definition at line 217 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.

00218 {
00219    struct feature_pvt *p = ast->tech_pvt;
00220    int res = -1;
00221    int x;
00222 
00223    ast_mutex_lock(&p->lock);
00224    x = indexof(p, ast, 0);
00225    if (!x && p->subchan)
00226       res = ast_answer(p->subchan);
00227    ast_mutex_unlock(&p->lock);
00228    return res;
00229 }

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

Definition at line 324 of file chan_features.c.

References ast_channel::accountcode, accountcode, ast_call(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, ast_string_field_set, 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, language, feature_pvt::lock, LOG_NOTICE, feature_pvt::owner, feature_pvt::subchan, ast_channel::tech_pvt, and update_features().

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

static int features_digit_begin ( struct ast_channel ast,
char  digit 
) [static]

Definition at line 293 of file chan_features.c.

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

00294 {
00295    struct feature_pvt *p = ast->tech_pvt;
00296    int res = -1;
00297    int x;
00298 
00299    /* Queue up a frame representing the indication as a control frame */
00300    ast_mutex_lock(&p->lock);
00301    x = indexof(p, ast, 0);
00302    if (!x && p->subchan)
00303       res = ast_senddigit_begin(p->subchan, digit);
00304    ast_mutex_unlock(&p->lock);
00305 
00306    return res;
00307 }

static int features_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Definition at line 309 of file chan_features.c.

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

00310 {
00311    struct feature_pvt *p = ast->tech_pvt;
00312    int res = -1;
00313    int x;
00314 
00315    /* Queue up a frame representing the indication as a control frame */
00316    ast_mutex_lock(&p->lock);
00317    x = indexof(p, ast, 0);
00318    if (!x && p->subchan)
00319       res = ast_senddigit_end(p->subchan, digit, duration);
00320    ast_mutex_unlock(&p->lock);
00321    return res;
00322 }

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

Definition at line 262 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.

00263 {
00264    struct feature_pvt *p = newchan->tech_pvt;
00265    int x;
00266 
00267    ast_mutex_lock(&p->lock);
00268    if (p->owner == oldchan)
00269       p->owner = newchan;
00270    for (x = 0; x < 3; x++) {
00271       if (p->subs[x].owner == oldchan)
00272          p->subs[x].owner = newchan;
00273    }
00274    ast_mutex_unlock(&p->lock);
00275    return 0;
00276 }

static int features_hangup ( struct ast_channel ast  )  [static]

Definition at line 354 of file chan_features.c.

References ast_free, ast_hangup(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), indexof(), feature_pvt::list, feature_pvt::lock, feature_sub::owner, restore_channel(), SUB_CALLWAIT, SUB_REAL, SUB_THREEWAY, feature_pvt::subchan, feature_pvt::subs, and ast_channel::tech_pvt.

00355 {
00356    struct feature_pvt *p = ast->tech_pvt;
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    if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
00369       ast_mutex_unlock(&p->lock);
00370       /* Remove from list */
00371       AST_LIST_LOCK(&features);
00372       AST_LIST_REMOVE(&features, p, list);
00373       AST_LIST_UNLOCK(&features);
00374       ast_mutex_lock(&p->lock);
00375       /* And destroy */
00376       if (p->subchan)
00377          ast_hangup(p->subchan);
00378       ast_mutex_unlock(&p->lock);
00379       ast_mutex_destroy(&p->lock);
00380       ast_free(p);
00381       return 0;
00382    }
00383    ast_mutex_unlock(&p->lock);
00384    return 0;
00385 }

static int features_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
) [static]

Definition at line 278 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.

00279 {
00280    struct feature_pvt *p = ast->tech_pvt;
00281    int res = -1;
00282    int x;
00283 
00284    /* Queue up a frame representing the indication as a control frame */
00285    ast_mutex_lock(&p->lock);
00286    x = indexof(p, ast, 0);
00287    if (!x && p->subchan)
00288       res = ast_indicate(p->subchan, condition);
00289    ast_mutex_unlock(&p->lock);
00290    return res;
00291 }

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

Definition at line 437 of file chan_features.c.

References asprintf, ast_free, ast_log(), feature_pvt::dest, errno, LOG_WARNING, ast_channel::name, feature_sub::owner, feature_pvt::subchan, feature_pvt::subs, and feature_pvt::tech.

Referenced by features_request().

00438 {
00439    struct ast_channel *tmp;
00440    int x,y;
00441    char *b2 = 0;
00442    if (!p->subchan) {
00443       ast_log(LOG_WARNING, "Called upon channel with no subchan:(\n");
00444       return NULL;
00445    }
00446    if (p->subs[index].owner) {
00447       ast_log(LOG_WARNING, "Called to put index %d already there!\n", index);
00448       return NULL;
00449    }
00450    /* figure out what you want the name to be */
00451    for (x=1;x<4;x++) {
00452       if (b2)
00453          ast_free(b2);
00454       if (asprintf(&b2, "%s/%s-%d", p->tech, p->dest, x) < 0) {
00455          ast_log(LOG_WARNING, "Unable to create channel name: %s\n", strerror(errno));
00456          b2 = NULL;
00457          continue;
00458       }
00459       for (y=0;y<3;y++) {
00460          if (y == index)
00461             continue;
00462          if (p->subs[y].owner && !strcasecmp(p->subs[y].owner->name, b2))
00463             break;
00464       }
00465       if (y >= 3)
00466          break;
00467    }
00468    tmp = ast_channel_alloc(0, state, 0,0, "", "", "", 0, "Feature/%s", b2);
00469    /* free up the name, it was copied into the channel name */
00470    if (b2)
00471       ast_free(b2);
00472    if (!tmp) {
00473       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00474       return NULL;
00475    }
00476    tmp->tech = &features_tech;
00477    tmp->writeformat = p->subchan->writeformat;
00478    tmp->rawwriteformat = p->subchan->rawwriteformat;
00479    tmp->readformat = p->subchan->readformat;
00480    tmp->rawreadformat = p->subchan->rawreadformat;
00481    tmp->nativeformats = p->subchan->readformat;
00482    tmp->tech_pvt = p;
00483    p->subs[index].owner = tmp;
00484    if (!p->owner)
00485       p->owner = tmp;
00486    ast_module_ref(ast_module_info->self);
00487    return tmp;
00488 }

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

Definition at line 231 of file chan_features.c.

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

00232 {
00233    struct feature_pvt *p = ast->tech_pvt;
00234    struct ast_frame *f;
00235    int x;
00236    
00237    f = &ast_null_frame;
00238    ast_mutex_lock(&p->lock);
00239    x = indexof(p, ast, 0);
00240    if (!x && p->subchan) {
00241       update_features(p, x);
00242       f = ast_read(p->subchan);
00243    }
00244    ast_mutex_unlock(&p->lock);
00245    return f;
00246 }

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

Definition at line 491 of file chan_features.c.

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

00492 {
00493    struct feature_pvt *p;
00494    struct ast_channel *chan = NULL;
00495 
00496    p = features_alloc(data, format);
00497    if (p && !p->subs[SUB_REAL].owner)
00498       chan = features_new(p, AST_STATE_DOWN, SUB_REAL);
00499    if (chan)
00500       update_features(p,SUB_REAL);
00501    return chan;
00502 }

static char* features_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 504 of file chan_features.c.

References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, feature_pvt::dest, ast_cli_args::fd, feature_pvt::list, feature_pvt::lock, ast_channel::name, feature_pvt::owner, feature_pvt::tech, and ast_cli_entry::usage.

00505 {
00506    struct feature_pvt *p;
00507 
00508    switch (cmd) {
00509    case CLI_INIT:
00510       e->command = "feature show channels";
00511       e->usage =
00512          "Usage: feature show channels\n"
00513          "       Provides summary information on feature channels.\n";
00514       return NULL;
00515    case CLI_GENERATE:
00516       return NULL;
00517    }
00518 
00519    if (a->argc != 3)
00520       return CLI_SHOWUSAGE;
00521 
00522    if (AST_LIST_EMPTY(&features)) {
00523       ast_cli(a->fd, "No feature channels in use\n");
00524       return CLI_SUCCESS;
00525    }
00526 
00527    AST_LIST_LOCK(&features);
00528    AST_LIST_TRAVERSE(&features, p, list) {
00529       ast_mutex_lock(&p->lock);
00530       ast_cli(a->fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "<unowned>", p->tech, p->dest);
00531       ast_mutex_unlock(&p->lock);
00532    }
00533    AST_LIST_UNLOCK(&features);
00534    return CLI_SUCCESS;
00535 }

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

Definition at line 248 of file chan_features.c.

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

00249 {
00250    struct feature_pvt *p = ast->tech_pvt;
00251    int res = -1;
00252    int x;
00253 
00254    ast_mutex_lock(&p->lock);
00255    x = indexof(p, ast, 0);
00256    if (!x && p->subchan)
00257       res = ast_write(p->subchan, f);
00258    ast_mutex_unlock(&p->lock);
00259    return res;
00260 }

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

Definition at line 121 of file chan_features.c.

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

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

00122 {
00123    int x;
00124    if (!owner) {
00125       ast_log(LOG_WARNING, "indexof called on NULL owner??\n");
00126       return -1;
00127    }
00128    for (x=0; x<3; x++) {
00129       if (owner == p->subs[x].owner)
00130          return x;
00131    }
00132    return -1;
00133 }

static void init_sub ( struct feature_sub sub  )  [inline, static]

Definition at line 113 of file chan_features.c.

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

Referenced by features_alloc().

00114 {
00115    sub->inthreeway = 0;
00116    sub->pfd = -1;
00117    sub->timingfdbackup = -1;
00118    sub->alertpipebackup[0] = sub->alertpipebackup[1] = -1;
00119 }

static int load_module ( void   )  [static]

Definition at line 541 of file chan_features.c.

References ast_channel_register(), ast_cli_register_multiple(), ast_log(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, cli_features, features_tech, and LOG_ERROR.

00542 {
00543    /* Make sure we can register our sip channel type */
00544    if (ast_channel_register(&features_tech)) {
00545       ast_log(LOG_ERROR, "Unable to register channel class 'Feature'\n");
00546       return AST_MODULE_LOAD_FAILURE;
00547    }
00548    ast_cli_register_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
00549    return AST_MODULE_LOAD_SUCCESS;
00550 }

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

Definition at line 156 of file chan_features.c.

References ast_channel::alertpipe, feature_sub::alertpipebackup, AST_ALERT_FD, ast_channel_set_fd(), AST_TIMING_FD, feature_sub::owner, feature_pvt::subs, ast_channel::timingfd, and feature_sub::timingfdbackup.

Referenced by features_hangup(), and update_features().

00157 {
00158    /* Restore timing/alertpipe */
00159    p->subs[index].owner->timingfd = p->subs[index].timingfdbackup;
00160    p->subs[index].owner->alertpipe[0] = p->subs[index].alertpipebackup[0];
00161    p->subs[index].owner->alertpipe[1] = p->subs[index].alertpipebackup[1];
00162    ast_channel_set_fd(p->subs[index].owner, AST_ALERT_FD, p->subs[index].alertpipebackup[0]);
00163    ast_channel_set_fd(p->subs[index].owner, AST_TIMING_FD, p->subs[index].timingfdbackup);
00164 }

static int unload_module ( void   )  [static]

Definition at line 552 of file chan_features.c.

References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, cli_features, features_tech, feature_pvt::list, and feature_pvt::owner.

00553 {
00554    struct feature_pvt *p;
00555    
00556    /* First, take us out of the channel loop */
00557    ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry));
00558    ast_channel_unregister(&features_tech);
00559    
00560    if (!AST_LIST_LOCK(&features))
00561       return -1;
00562    /* Hangup all interfaces if they have an owner */
00563    while ((p = AST_LIST_REMOVE_HEAD(&features, list))) {
00564       if (p->owner)
00565          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
00566       ast_free(p);
00567    }
00568    AST_LIST_UNLOCK(&features);
00569    
00570    return 0;
00571 }

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

Definition at line 166 of file chan_features.c.

References ast_channel::alertpipe, ast_channel_set_fd(), 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().

00167 {
00168    int x;
00169    if (p->subs[index].owner) {
00170       for (x=0; x<AST_MAX_FDS; x++) {
00171          if (index) 
00172             ast_channel_set_fd(p->subs[index].owner, x, -1);
00173          else
00174             ast_channel_set_fd(p->subs[index].owner, x, p->subchan->fds[x]);
00175       }
00176       if (!index) {
00177          /* Copy timings from master channel */
00178          p->subs[index].owner->timingfd = p->subchan->timingfd;
00179          p->subs[index].owner->alertpipe[0] = p->subchan->alertpipe[0];
00180          p->subs[index].owner->alertpipe[1] = p->subchan->alertpipe[1];
00181          if (p->subs[index].owner->nativeformats != p->subchan->readformat) {
00182             p->subs[index].owner->nativeformats = p->subchan->readformat;
00183             if (p->subs[index].owner->readformat)
00184                ast_set_read_format(p->subs[index].owner, p->subs[index].owner->readformat);
00185             if (p->subs[index].owner->writeformat)
00186                ast_set_write_format(p->subs[index].owner, p->subs[index].owner->writeformat);
00187          }
00188       } else{
00189          restore_channel(p, index);
00190       }
00191    }
00192 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Feature Proxy Channel" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static]

Definition at line 573 of file chan_features.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 573 of file chan_features.c.

struct ast_cli_entry cli_features[] [static]

Initial value:

 {
   { .handler =  features_show , .summary =  "List status of feature channels" ,__VA_ARGS__ },
}

Definition at line 537 of file chan_features.c.

struct ast_channel_tech features_tech [static]

Definition at line 96 of file chan_features.c.

Referenced by load_module(), and unload_module().

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

Definition at line 57 of file chan_features.c.


Generated on Thu Jul 9 13:40:57 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7