![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
chan_features.c File Reference
Definition in file chan_features.c.
#include "asterisk.h"
#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/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 "asterisk/stringfields.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 | |
| static | AST_LIST_HEAD_STATIC (features, feature_pvt) |
| AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Feature Proxy Channel") | |
| 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_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_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) |
| 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_cli_entry | cli_features [] |
| static const struct ast_channel_tech | features_tech |
| static const char | show_features_usage [] |
| static const char | tdesc [] = "Feature Proxy Channel Driver" |
|
|
Definition at line 68 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(). |
|
|
Definition at line 91 of file chan_features.c. Referenced by available(), features_hangup(), ss_thread(), zt_bridge(), zt_call(), zt_handle_event(), zt_hangup(), and zt_read(). |
|
|
|
Definition at line 92 of file chan_features.c. Referenced by attempt_transfer(), available(), features_hangup(), ss_thread(), zt_answer(), zt_bridge(), zt_handle_event(), and zt_hangup(). |
|
||||||||||||
|
|
|
||||||||||||
|
|
|
||||||||||||
|
Definition at line 397 of file chan_features.c. References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_request(), ast_strdupa, feature_pvt::dest, init_sub(), LOG_NOTICE, malloc, and feature_pvt::tech. Referenced by features_request(). 00398 { 00399 struct feature_pvt *tmp; 00400 char *dest=NULL; 00401 char *tech; 00402 int x; 00403 int status; 00404 struct ast_channel *chan; 00405 00406 tech = ast_strdupa(data); 00407 if (tech) { 00408 dest = strchr(tech, '/'); 00409 if (dest) { 00410 *dest = '\0'; 00411 dest++; 00412 } 00413 } 00414 if (!tech || !dest) { 00415 ast_log(LOG_NOTICE, "Format for feature channel is Feature/Tech/Dest ('%s' not valid)!\n", 00416 data); 00417 return NULL; 00418 } 00419 AST_LIST_LOCK(&features); 00420 AST_LIST_TRAVERSE(&features, tmp, list) { 00421 if (!strcasecmp(tmp->tech, tech) && !strcmp(tmp->dest, dest)) 00422 break; 00423 } 00424 AST_LIST_UNLOCK(&features); 00425 if (!tmp) { 00426 chan = ast_request(tech, format, dest, &status); 00427 if (!chan) { 00428 ast_log(LOG_NOTICE, "Unable to allocate subchannel '%s/%s'\n", tech, dest); 00429 return NULL; 00430 } 00431 tmp = malloc(sizeof(struct feature_pvt)); 00432 if (tmp) { 00433 memset(tmp, 0, sizeof(struct feature_pvt)); 00434 for (x=0;x<3;x++) 00435 init_sub(tmp->subs + x); 00436 ast_mutex_init(&tmp->lock); 00437 ast_copy_string(tmp->tech, tech, sizeof(tmp->tech)); 00438 ast_copy_string(tmp->dest, dest, sizeof(tmp->dest)); 00439 tmp->subchan = chan; 00440 AST_LIST_LOCK(&features); 00441 AST_LIST_INSERT_HEAD(&features, tmp, list); 00442 AST_LIST_UNLOCK(&features); 00443 } 00444 } 00445 return tmp; 00446 }
|
|
|
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 }
|
|
||||||||||||||||
|
||||||||||||
|
Definition at line 303 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. 00304 { 00305 struct feature_pvt *p = ast->tech_pvt; 00306 int res = -1; 00307 int x; 00308 00309 /* Queue up a frame representing the indication as a control frame */ 00310 ast_mutex_lock(&p->lock); 00311 x = indexof(p, ast, 0); 00312 if (!x && p->subchan) 00313 res = ast_senddigit_begin(p->subchan, digit); 00314 ast_mutex_unlock(&p->lock); 00315 00316 return res; 00317 }
|
|
||||||||||||||||
|
Definition at line 319 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. 00320 { 00321 struct feature_pvt *p = ast->tech_pvt; 00322 int res = -1; 00323 int x; 00324 00325 /* Queue up a frame representing the indication as a control frame */ 00326 ast_mutex_lock(&p->lock); 00327 x = indexof(p, ast, 0); 00328 if (!x && p->subchan) 00329 res = ast_senddigit_end(p->subchan, digit, duration); 00330 ast_mutex_unlock(&p->lock); 00331 return res; 00332 }
|
|
||||||||||||
|
Definition at line 272 of file chan_features.c. References ast_mutex_lock(), feature_pvt::lock, feature_sub::owner, feature_pvt::owner, feature_pvt::subs, and ast_channel::tech_pvt. 00273 { 00274 struct feature_pvt *p = newchan->tech_pvt; 00275 int x; 00276 00277 ast_mutex_lock(&p->lock); 00278 if (p->owner == oldchan) 00279 p->owner = newchan; 00280 for (x = 0; x < 3; x++) { 00281 if (p->subs[x].owner == oldchan) 00282 p->subs[x].owner = newchan; 00283 } 00284 ast_mutex_unlock(&p->lock); 00285 return 0; 00286 }
|
|
|
Definition at line 364 of file chan_features.c. References ast_hangup(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), free, indexof(), 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. 00365 { 00366 struct feature_pvt *p = ast->tech_pvt; 00367 int x; 00368 00369 ast_mutex_lock(&p->lock); 00370 x = indexof(p, ast, 0); 00371 if (x > -1) { 00372 restore_channel(p, x); 00373 p->subs[x].owner = NULL; 00374 /* XXX Re-arrange, unconference, etc XXX */ 00375 } 00376 ast->tech_pvt = NULL; 00377 00378 if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) { 00379 ast_mutex_unlock(&p->lock); 00380 /* Remove from list */ 00381 AST_LIST_LOCK(&features); 00382 AST_LIST_REMOVE(&features, p, list); 00383 AST_LIST_UNLOCK(&features); 00384 ast_mutex_lock(&p->lock); 00385 /* And destroy */ 00386 if (p->subchan) 00387 ast_hangup(p->subchan); 00388 ast_mutex_unlock(&p->lock); 00389 ast_mutex_destroy(&p->lock); 00390 free(p); 00391 return 0; 00392 } 00393 ast_mutex_unlock(&p->lock); 00394 return 0; 00395 }
|
|
||||||||||||||||||||
|
Definition at line 288 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. 00289 { 00290 struct feature_pvt *p = ast->tech_pvt; 00291 int res = -1; 00292 int x; 00293 00294 /* Queue up a frame representing the indication as a control frame */ 00295 ast_mutex_lock(&p->lock); 00296 x = indexof(p, ast, 0); 00297 if (!x && p->subchan) 00298 res = ast_indicate(p->subchan, condition); 00299 ast_mutex_unlock(&p->lock); 00300 return res; 00301 }
|
|
||||||||||||||||
|
Definition at line 448 of file chan_features.c. References asprintf, ast_log(), feature_pvt::dest, free, LOG_WARNING, feature_sub::owner, feature_pvt::subchan, feature_pvt::subs, and feature_pvt::tech. Referenced by features_request(). 00449 { 00450 struct ast_channel *tmp; 00451 int x,y; 00452 char *b2 = 0; 00453 if (!p->subchan) { 00454 ast_log(LOG_WARNING, "Called upon channel with no subchan:(\n"); 00455 return NULL; 00456 } 00457 if (p->subs[index].owner) { 00458 ast_log(LOG_WARNING, "Called to put index %d already there!\n", index); 00459 return NULL; 00460 } 00461 /* figure out what you want the name to be */ 00462 for (x=1;x<4;x++) { 00463 if (b2) 00464 free(b2); 00465 asprintf(&b2, "Feature/%s/%s-%d", p->tech, p->dest, x); 00466 for (y=0;y<3;y++) { 00467 if (y == index) 00468 continue; 00469 if (p->subs[y].owner && !strcasecmp(p->subs[y].owner->name, b2)) 00470 break; 00471 } 00472 if (y >= 3) 00473 break; 00474 } 00475 tmp = ast_channel_alloc(0, state, 0,0, b2); 00476 /* free up the name, it was copied into the channel name */ 00477 if (b2) 00478 free(b2); 00479 if (!tmp) { 00480 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 00481 return NULL; 00482 } 00483 tmp->tech = &features_tech; 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_module_ref(ast_module_info->self); 00494 return tmp; 00495 }
|
|
|
Definition at line 241 of file chan_features.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_read(), indexof(), feature_pvt::lock, feature_pvt::subchan, ast_channel::tech_pvt, and update_features(). 00242 { 00243 struct feature_pvt *p = ast->tech_pvt; 00244 struct ast_frame *f; 00245 int x; 00246 00247 f = &ast_null_frame; 00248 ast_mutex_lock(&p->lock); 00249 x = indexof(p, ast, 0); 00250 if (!x && p->subchan) { 00251 update_features(p, x); 00252 f = ast_read(p->subchan); 00253 } 00254 ast_mutex_unlock(&p->lock); 00255 return f; 00256 }
|
|
||||||||||||||||||||
|
Definition at line 498 of file chan_features.c. References AST_STATE_DOWN, features_alloc(), features_new(), SUB_REAL, feature_pvt::subs, and update_features(). 00499 { 00500 struct feature_pvt *p; 00501 struct ast_channel *chan = NULL; 00502 00503 p = features_alloc(data, format); 00504 if (p && !p->subs[SUB_REAL].owner) 00505 chan = features_new(p, AST_STATE_DOWN, SUB_REAL); 00506 if (chan) 00507 update_features(p,SUB_REAL); 00508 return chan; 00509 }
|
|
||||||||||||||||
|
Definition at line 511 of file chan_features.c. References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), feature_pvt::dest, feature_pvt::lock, feature_pvt::owner, RESULT_SHOWUSAGE, RESULT_SUCCESS, and feature_pvt::tech. 00512 { 00513 struct feature_pvt *p; 00514 00515 if (argc != 3) 00516 return RESULT_SHOWUSAGE; 00517 00518 if (AST_LIST_EMPTY(&features)) { 00519 ast_cli(fd, "No feature channels in use\n"); 00520 return RESULT_SUCCESS; 00521 } 00522 00523 AST_LIST_LOCK(&features); 00524 AST_LIST_TRAVERSE(&features, p, list) { 00525 ast_mutex_lock(&p->lock); 00526 ast_cli(fd, "%s -- %s/%s\n", p->owner ? p->owner->name : "<unowned>", p->tech, p->dest); 00527 ast_mutex_unlock(&p->lock); 00528 } 00529 AST_LIST_UNLOCK(&features); 00530 return RESULT_SUCCESS; 00531 }
|
|
||||||||||||
|
Definition at line 258 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. 00259 { 00260 struct feature_pvt *p = ast->tech_pvt; 00261 int res = -1; 00262 int x; 00263 00264 ast_mutex_lock(&p->lock); 00265 x = indexof(p, ast, 0); 00266 if (!x && p->subchan) 00267 res = ast_write(p->subchan, f); 00268 ast_mutex_unlock(&p->lock); 00269 return res; 00270 }
|
|
||||||||||||||||
|
Definition at line 130 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(). 00131 { 00132 int x; 00133 if (!owner) { 00134 ast_log(LOG_WARNING, "indexof called on NULL owner??\n"); 00135 return -1; 00136 } 00137 for (x=0; x<3; x++) { 00138 if (owner == p->subs[x].owner) 00139 return x; 00140 } 00141 return -1; 00142 }
|
|
|
Definition at line 122 of file chan_features.c. References feature_sub::alertpipebackup, feature_sub::inthreeway, feature_sub::pfd, and feature_sub::timingfdbackup. Referenced by features_alloc(). 00123 { 00124 sub->inthreeway = 0; 00125 sub->pfd = -1; 00126 sub->timingfdbackup = -1; 00127 sub->alertpipebackup[0] = sub->alertpipebackup[1] = -1; 00128 }
|
|
|
Definition at line 543 of file chan_features.c. References ast_channel_register(), ast_cli_register_multiple(), ast_log(), cli_features, features_tech, and LOG_ERROR. 00544 { 00545 /* Make sure we can register our sip channel type */ 00546 if (ast_channel_register(&features_tech)) { 00547 ast_log(LOG_ERROR, "Unable to register channel class 'Feature'\n"); 00548 return -1; 00549 } 00550 ast_cli_register_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry)); 00551 return 0; 00552 }
|
|
||||||||||||
|
Definition at line 165 of file chan_features.c. References ast_channel::alertpipe, feature_sub::alertpipebackup, AST_ALERT_FD, AST_TIMING_FD, ast_channel::fds, feature_sub::owner, feature_pvt::subs, ast_channel::timingfd, and feature_sub::timingfdbackup. Referenced by features_hangup(). 00166 { 00167 /* Restore timing/alertpipe */ 00168 p->subs[index].owner->timingfd = p->subs[index].timingfdbackup; 00169 p->subs[index].owner->alertpipe[0] = p->subs[index].alertpipebackup[0]; 00170 p->subs[index].owner->alertpipe[1] = p->subs[index].alertpipebackup[1]; 00171 p->subs[index].owner->fds[AST_ALERT_FD] = p->subs[index].alertpipebackup[0]; 00172 p->subs[index].owner->fds[AST_TIMING_FD] = p->subs[index].timingfdbackup; 00173 }
|
|
|
Definition at line 554 of file chan_features.c. References ast_channel_unregister(), ast_cli_unregister_multiple(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, cli_features, features_tech, free, and feature_pvt::owner. 00555 { 00556 struct feature_pvt *p; 00557 00558 /* First, take us out of the channel loop */ 00559 ast_cli_unregister_multiple(cli_features, sizeof(cli_features) / sizeof(struct ast_cli_entry)); 00560 ast_channel_unregister(&features_tech); 00561 00562 if (!AST_LIST_LOCK(&features)) 00563 return -1; 00564 /* Hangup all interfaces if they have an owner */ 00565 AST_LIST_TRAVERSE_SAFE_BEGIN(&features, p, list) { 00566 if (p->owner) 00567 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 00568 AST_LIST_REMOVE_CURRENT(&features, list); 00569 free(p); 00570 } 00571 AST_LIST_TRAVERSE_SAFE_END 00572 AST_LIST_UNLOCK(&features); 00573 00574 return 0; 00575 }
|
|
||||||||||||
|
|
Initial value: {
{ { "feature", "show", "channels", NULL },
features_show, "List status of feature channels",
show_features_usage },
}
Definition at line 537 of file chan_features.c. Referenced by load_module(), and unload_module(). |
|
|
Definition at line 105 of file chan_features.c. Referenced by load_module(), and unload_module(). |
|
|
Initial value: "Usage: feature show channels\n" " Provides summary information on feature channels.\n" Definition at line 533 of file chan_features.c. |
|
|
Definition at line 66 of file chan_features.c. |