chan_ooh323.c File Reference

#include "chan_ooh323.h"
#include <math.h>

Include dependency graph for chan_ooh323.c:

Go to the source code of this file.

Data Structures

struct  ast_peer_list
struct  ast_user_list
struct  ooh323_config
struct  ooh323_peer
struct  ooh323_pvt
struct  ooh323_user

Defines

#define DEFAULT_CONTEXT   "default"
#define DEFAULT_H323ACCNT   "ast_h323"
#define DEFAULT_H323ID   "Asterisk PBX"
#define DEFAULT_LOGFILE   "/var/log/asterisk/h323_log"
#define FAXDETECT_CNG   1
#define FAXDETECT_T38   2
#define FORMAT   "%-15.15s %-15.15s %-23.23s %-s\n"
#define FORMAT1   "%-15.15s %-15.15s %-15.15s %-s\n"
#define FORMAT_STRING_SIZE   512
#define H323_ALREADYGONE   (1<<5)
#define H323_DISABLEGK   (1<<7)
#define H323_FASTSTART   (1<<3)
#define H323_GKROUTED   (1<<1)
#define H323_NEEDDESTROY   (1<<6)
#define H323_NEEDSTART   (1<<8)
#define H323_OUTGOING   (1<<4)
#define H323_SILENCESUPPRESSION   (1<<0)
#define H323_TUNNELING   (1<<2)
#define MAXT30   240
#define T38_DISABLED   0
#define T38_ENABLED   1
#define T38_FAXGW   1
#define T38TOAUDIOTIMEOUT   30

Functions

static void __reg_module (void)
static void __unreg_module (void)
static struct ooh323_peerbuild_peer (const char *name, struct ast_variable *v, int friend_type)
static struct ooh323_userbuild_user (const char *name, struct ast_variable *v)
void close_rtp_connection (ooCallData *call)
void close_udptl_connection (ooCallData *call)
int configure_local_rtp (struct ooh323_pvt *p, ooCallData *call)
int delete_peers ()
int delete_users ()
static void * do_monitor (void *data)
static struct ooh323_pvtfind_call (ooCallData *call)
struct ooh323_peerfind_friend (const char *name, int port)
struct ooh323_peerfind_peer (const char *name, int port)
struct ooh323_userfind_user (const char *name, const char *ip)
static int function_ooh323_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 OOH323 Dialplan function - reads ooh323 settings.
static int function_ooh323_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 OOH323 Dialplan function - writes ooh323 settings.
char * handle_cli_ooh323_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_ooh323_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_ooh323_show_config (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_ooh323_show_gk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_ooh323_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_ooh323_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_ooh323_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_ooh323_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int load_module (void)
int onAlerting (ooCallData *call)
int onCallCleared (ooCallData *call)
int onCallEstablished (ooCallData *call)
void onModeChanged (ooCallData *call, int t38mode)
int onNewCallCreated (ooCallData *call)
int onOutgoingCall (ooCallData *call)
int onProgress (ooCallData *call)
static struct ooh323_pvtooh323_alloc (int callref, char *callToken)
static int ooh323_answer (struct ast_channel *ast)
static int ooh323_call (struct ast_channel *ast, const char *dest, int timeout)
int ooh323_convert_hangupcause_asteriskToH323 (int cause)
int ooh323_convert_hangupcause_h323ToAsterisk (int cause)
int ooh323_convertAsteriskCapToH323Cap (struct ast_format *format)
void ooh323_delete_peer (struct ooh323_peer *peer)
int ooh323_destroy (struct ooh323_pvt *p)
static int ooh323_digit_begin (struct ast_channel *ast, char digit)
static int ooh323_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
static int ooh323_do_reload (void)
static int ooh323_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static void ooh323_get_codec (struct ast_channel *chan, struct ast_format_cap *result)
static enum ast_rtp_glue_result ooh323_get_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance **rtp)
static enum ast_rtp_glue_result ooh323_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp_instance **rtp)
static int ooh323_hangup (struct ast_channel *ast)
static int ooh323_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
static struct ast_channelooh323_new (struct ooh323_pvt *i, int state, const char *host, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
int ooh323_onReceivedDigit (OOH323CallData *call, const char *digit)
int ooh323_onReceivedSetup (ooCallData *call, Q931Message *pmsg)
static int ooh323_queryoption (struct ast_channel *ast, int option, void *data, int *datalen)
static struct ast_frameooh323_read (struct ast_channel *ast)
static struct ast_channelooh323_request (const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
struct ast_frameooh323_rtp_read (struct ast_channel *ast, struct ooh323_pvt *p)
void ooh323_set_read_format (ooCallData *call, struct ast_format *fmt)
static int ooh323_set_rtp_peer (struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active)
void ooh323_set_write_format (ooCallData *call, struct ast_format *fmt, int txframes)
static int ooh323_write (struct ast_channel *ast, struct ast_frame *f)
int reload_config (int reload)
static int reload_module (void)
int restart_monitor (void)
 Start the channel monitor thread.
void setup_rtp_connection (ooCallData *call, const char *remoteIp, int remotePort)
void setup_rtp_remote (ooCallData *call, const char *remoteIp, int remotePort)
void setup_udptl_connection (ooCallData *call, const char *remoteIp, int remotePort)
static int unload_module (void)
int update_our_aliases (ooCallData *call, struct ooh323_pvt *p)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Objective Systems H323 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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER }
static struct ast_module_infoast_module_info = &__mod_info
struct ast_sockaddr bindaddr
static long callnumber = 0
static struct ast_cli_entry cli_ooh323 []
static const char config [] = "ooh323.conf"
static struct ast_jb_conf default_jbconf
static int g729onlyA = 0
static char gAccountcode [80] = DEFAULT_H323ACCNT
static struct ooAliases * gAliasList
static int gAMAFLAGS
static int gANIasDNI = 0
static int gBeMaster = 0
static char gCallerID [AST_MAX_EXTENSION] = ""
static struct ast_format_capgCap
static char gContext [AST_MAX_EXTENSION] = DEFAULT_CONTEXT
static int gDirectRTP = 0
static int gDTMFCodec = 101
static int gDTMFMode = H323_DTMF_RFC2833
static int gEarlyDirect = 0
static int gFastStart = 1
static int gFAXdetect = FAXDETECT_CNG
static char gGatekeeper [100]
OOBOOL gH323Debug = FALSE
OOH323EndPoint gH323ep
static int gIncomingLimit = 1024
static char gIP [2+8 *4+7]
static int gIsGateway = 0
static struct ast_jb_conf global_jbconf
static char gLogFile [256] = DEFAULT_LOGFILE
static int gMediaWaitForConnect = 0
static int gNat = FALSE
static int gOutgoingLimit = 1024
static int gPort = 1720
static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper
static int gRTDRCount = 0
static int gRTDRInterval = 0
static int gRTPTimeout = 60
static int gT38Support = T38_FAXGW
static int gTOS = 0
static int gTRCLVL = OOTRCLVLERR
static int gTunneling = 1
static ast_mutex_t h323_reload_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static int h323_reloading = 0
static struct ooh323_pvtiflist
static ast_mutex_t iflock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct io_contextio
static int manufacturer = 0
static pthread_t monitor_thread = AST_PTHREADT_NULL
static ast_mutex_t monlock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
struct ast_modulemyself
static struct ooh323_config ooconfig
static struct ast_rtp_glue ooh323_rtp
static struct ast_channel_tech ooh323_tech
static ast_mutex_t ooh323c_cn_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct ast_peer_list peerl
static struct ast_sched_contextsched
static int t35countrycode = 0
static int t35extensions = 0
static const char tdesc [] = "Objective Systems H323 Channel Driver"
static const char type [] = "OOH323"
static int usecnt = 0
static ast_mutex_t usecnt_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }
static struct ast_user_list userl
int v6mode = 0
static char vendor [AST_MAX_EXTENSION] = ""
static char version [AST_MAX_EXTENSION] = ""


Define Documentation

#define DEFAULT_CONTEXT   "default"

#define DEFAULT_H323ACCNT   "ast_h323"

Definition at line 34 of file chan_ooh323.c.

Referenced by reload_config().

#define DEFAULT_H323ID   "Asterisk PBX"

Definition at line 32 of file chan_ooh323.c.

Referenced by reload_config().

#define DEFAULT_LOGFILE   "/var/log/asterisk/h323_log"

Definition at line 33 of file chan_ooh323.c.

Referenced by reload_config().

#define FAXDETECT_CNG   1

#define FAXDETECT_T38   2

#define FORMAT   "%-15.15s %-15.15s %-23.23s %-s\n"

#define FORMAT1   "%-15.15s %-15.15s %-15.15s %-s\n"

#define FORMAT_STRING_SIZE   512

Definition at line 28 of file chan_ooh323.c.

Referenced by handle_cli_ooh323_show_config(), and handle_cli_ooh323_show_gk().

#define H323_ALREADYGONE   (1<<5)

Definition at line 42 of file chan_ooh323.c.

Referenced by onCallCleared(), ooh323_hangup(), and ooh323_indicate().

#define H323_DISABLEGK   (1<<7)

Definition at line 44 of file chan_ooh323.c.

Referenced by ooh323_alloc(), ooh323_call(), and ooh323_onReceivedSetup().

#define H323_FASTSTART   (1<<3)

Definition at line 40 of file chan_ooh323.c.

#define H323_GKROUTED   (1<<1)

Definition at line 38 of file chan_ooh323.c.

#define H323_NEEDDESTROY   (1<<6)

Definition at line 43 of file chan_ooh323.c.

Referenced by do_monitor(), onCallCleared(), ooh323_hangup(), and ooh323_onReceivedSetup().

#define H323_NEEDSTART   (1<<8)

Definition at line 45 of file chan_ooh323.c.

#define H323_OUTGOING   (1<<4)

#define H323_SILENCESUPPRESSION   (1<<0)

Definition at line 37 of file chan_ooh323.c.

#define H323_TUNNELING   (1<<2)

Definition at line 39 of file chan_ooh323.c.

#define MAXT30   240

Definition at line 47 of file chan_ooh323.c.

#define T38_DISABLED   0

#define T38_ENABLED   1

#define T38_FAXGW   1

#define T38TOAUDIOTIMEOUT   30

Definition at line 48 of file chan_ooh323.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 5196 of file chan_ooh323.c.

static void __unreg_module ( void   )  [static]

Definition at line 5196 of file chan_ooh323.c.

static struct ooh323_peer* build_peer ( const char *  name,
struct ast_variable v,
int  friend_type 
) [static, read]

Definition at line 2472 of file chan_ooh323.c.

References ooh323_peer::accountcode, ooh323_peer::amaflags, ast_calloc, ast_channel_string2amaflag(), ast_copy_string(), ast_false(), ast_format_cap_alloc, ast_format_cap_append_from_cap(), ast_format_cap_update_by_allow_disallow(), ast_free, ast_log, AST_MEDIA_TYPE_UNKNOWN, ast_mutex_init, ast_parse_arg(), ast_sockaddr_stringify_host(), ast_strdup, ast_strdupa, ast_true(), ast_verb, buf, ooh323_peer::cap, ooh323_peer::directrtp, ooh323_peer::dtmfcodec, ooh323_peer::dtmfmode, ooh323_peer::e164, ooh323_peer::earlydirect, ooh323_peer::email, ooh323_peer::faststart, ooh323_peer::faxdetect, FAXDETECT_CNG, FAXDETECT_T38, g729onlyA, ooh323_peer::g729onlyA, gAccountcode, gAMAFLAGS, gDirectRTP, gDTMFCodec, gDTMFMode, gEarlyDirect, gFastStart, gFAXdetect, gH323Debug, gNat, gRTPTimeout, gT38Support, gTunneling, ooh323_peer::h245tunneling, H323_DTMF_CISCO, H323_DTMF_H245ALPHANUMERIC, H323_DTMF_H245SIGNAL, H323_DTMF_INBAND, H323_DTMF_INBANDRELAX, H323_DTMF_Q931, H323_DTMF_RFC2833, ooh323_peer::h323id, ooh323_peer::ip, ast_variable::lineno, ooh323_peer::lock, LOG_ERROR, LOG_WARNING, ooh323_peer::mFriend, ast_variable::name, ooh323_peer::name, ooh323_peer::nat, ast_variable::next, NULL, ooh323_delete_peer(), ooh323_peer::outgoinglimit, PARSE_ADDR, ooh323_peer::port, ooh323_peer::rtdrcount, ooh323_peer::rtdrinterval, ooh323_peer::rtpmask, ooh323_peer::rtpmaskstr, ooh323_peer::rtptimeout, strsep(), T38_DISABLED, T38_ENABLED, T38_FAXGW, ooh323_peer::t38support, tmp(), ooh323_peer::url, and ast_variable::value.

Referenced by realtime_peer(), register_realtime_peers_with_callbackextens(), reload_config(), and set_config().

02473 {
02474    struct ooh323_peer *peer = NULL;
02475 
02476    if (gH323Debug)
02477       ast_verb(0, "---   build_peer\n");
02478 
02479    peer = ast_calloc(1, sizeof(*peer));
02480    if (peer) {
02481       memset(peer, 0, sizeof(struct ooh323_peer));
02482       if (!(peer->cap = ast_format_cap_alloc(0))) {
02483          ast_free(peer);
02484          return NULL;
02485       }
02486       ast_mutex_init(&peer->lock);
02487       ast_copy_string(peer->name, name, sizeof(peer->name));
02488       ast_format_cap_append_from_cap(peer->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
02489       peer->rtptimeout = gRTPTimeout;
02490       peer->nat = gNat;
02491       ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
02492       peer->amaflags = gAMAFLAGS;
02493       peer->dtmfmode = gDTMFMode;
02494       peer->dtmfcodec = gDTMFCodec;
02495       peer->faxdetect = gFAXdetect;
02496       peer->t38support = gT38Support;
02497       peer->faststart = gFastStart;
02498       peer->h245tunneling = gTunneling;
02499       peer->directrtp = gDirectRTP;
02500       peer->earlydirect = gEarlyDirect;
02501       peer->g729onlyA = g729onlyA;
02502       peer->port = 1720;
02503       if (0 == friend_type) {
02504          peer->mFriend = 1;
02505       }
02506 
02507       while (v) {
02508          if (!strcasecmp(v->name, "h323id")) {
02509        if (!(peer->h323id = ast_strdup(v->value))) {
02510                ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
02511                                   "peer %s\n", name);
02512                ooh323_delete_peer(peer);
02513                return NULL;
02514             }
02515          } else if (!strcasecmp(v->name, "e164")) {
02516             int valid = 1;
02517             const char *tmp;
02518             for(tmp = v->value; *tmp; tmp++) {
02519                if (!isdigit(*tmp)) {
02520                   valid = 0;
02521                   break;
02522                }
02523             }
02524             if (valid) {
02525                if (!(peer->e164 = ast_strdup(v->value))) {
02526                   ast_log(LOG_ERROR, "Could not allocate memory for e164 of "
02527                                   "peer %s\n", name);
02528                   ooh323_delete_peer(peer);
02529                   return NULL;
02530                }
02531             } else {
02532                ast_log(LOG_ERROR, "Invalid e164: %s for peer %s\n", v->value, name);
02533             }
02534          } else  if (!strcasecmp(v->name, "email")) {
02535             if (!(peer->email = ast_strdup(v->value))) {
02536                ast_log(LOG_ERROR, "Could not allocate memory for email of "
02537                                   "peer %s\n", name);
02538                ooh323_delete_peer(peer);
02539                return NULL;
02540             }
02541          } else if (!strcasecmp(v->name, "url")) {
02542             if (!(peer->url = ast_strdup(v->value))) {
02543                ast_log(LOG_ERROR, "Could not allocate memory for h323id of "
02544                                   "peer %s\n", name);
02545                ooh323_delete_peer(peer);
02546                return NULL;
02547             }
02548          } else if (!strcasecmp(v->name, "port")) {
02549             peer->port = atoi(v->value);
02550                } else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "ip")) {
02551             struct ast_sockaddr p;
02552             if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
02553                ast_copy_string(peer->ip, ast_sockaddr_stringify_host(&p), sizeof(peer->ip));
02554             } else { 
02555                         ast_copy_string(peer->ip, v->value, sizeof(peer->ip));
02556             }
02557          
02558          } else if (!strcasecmp(v->name, "outgoinglimit")) {
02559                      peer->outgoinglimit = atoi(v->value);
02560                      if (peer->outgoinglimit < 0)
02561                peer->outgoinglimit = 0;
02562          } else if (!strcasecmp(v->name, "accountcode")) {
02563             ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
02564          } else if (!strcasecmp(v->name, "faststart")) {
02565             peer->faststart = ast_true(v->value);
02566          } else if (!strcasecmp(v->name, "h245tunneling")) {
02567             peer->h245tunneling = ast_true(v->value);
02568          } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
02569             peer->directrtp = ast_true(v->value);
02570             peer->earlydirect = ast_true(v->value);
02571          } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
02572             peer->earlydirect = ast_true(v->value);
02573          } else if (!strcasecmp(v->name, "g729onlyA")) {
02574             peer->g729onlyA = ast_true(v->value);
02575          } else if (!strcasecmp(v->name, "nat")) {
02576             peer->nat = ast_true(v->value);
02577          } else if (!strcasecmp(v->name, "rtptimeout")) {
02578                      peer->rtptimeout = atoi(v->value);
02579                      if(peer->rtptimeout < 0)
02580                peer->rtptimeout = gRTPTimeout;
02581          } else if (!strcasecmp(v->name, "rtpmask")) {
02582             if ((peer->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
02583                (regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED) 
02584                                  == 0)) {
02585                ast_mutex_init(&peer->rtpmask->lock);
02586                peer->rtpmask->inuse = 1;
02587                ast_copy_string(peer->rtpmaskstr, v->value, 
02588                         sizeof(peer->rtpmaskstr));
02589             } else peer->rtpmask = NULL;
02590          } else if (!strcasecmp(v->name, "disallow")) {
02591             ast_format_cap_update_by_allow_disallow(peer->cap, v->value, 0);
02592          } else if (!strcasecmp(v->name, "allow")) {
02593             const char* tcodecs = v->value;
02594             if (!strcasecmp(v->value, "all")) {
02595                tcodecs = "ulaw,alaw,g729,g723,gsm";
02596             }
02597             ast_format_cap_update_by_allow_disallow(peer->cap, tcodecs, 1);
02598          } else if (!strcasecmp(v->name,  "amaflags")) {
02599             peer->amaflags = ast_channel_string2amaflag(v->value);
02600          } else if (!strcasecmp(v->name, "roundtrip")) {
02601             sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval);
02602          } else if (!strcasecmp(v->name, "dtmfmode")) {
02603             if (!strcasecmp(v->value, "rfc2833"))
02604                peer->dtmfmode = H323_DTMF_RFC2833;
02605             if (!strcasecmp(v->value, "cisco"))
02606                peer->dtmfmode = H323_DTMF_CISCO;
02607             else if (!strcasecmp(v->value, "q931keypad"))
02608                peer->dtmfmode = H323_DTMF_Q931;
02609             else if (!strcasecmp(v->value, "h245alphanumeric"))
02610                peer->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
02611             else if (!strcasecmp(v->value, "h245signal"))
02612                peer->dtmfmode = H323_DTMF_H245SIGNAL;
02613             else if (!strcasecmp(v->value, "inband"))
02614                peer->dtmfmode = H323_DTMF_INBAND;
02615          } else if (!strcasecmp(v->name, "relaxdtmf")) {
02616             peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
02617          } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
02618             peer->dtmfcodec = atoi(v->value);
02619          } else if (!strcasecmp(v->name, "faxdetect")) {
02620             if (ast_true(v->value)) {
02621                peer->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
02622             } else if (ast_false(v->value)) {
02623                peer->faxdetect = 0;
02624             } else {
02625                char *buf = ast_strdupa(v->value);
02626                char *word, *next = buf;
02627                peer->faxdetect = 0;
02628                while ((word = strsep(&next, ","))) {
02629                   if (!strcasecmp(word, "cng")) {
02630                      peer->faxdetect |= FAXDETECT_CNG;
02631                   } else if (!strcasecmp(word, "t38")) {
02632                      peer->faxdetect |= FAXDETECT_T38;
02633                   } else {
02634                      ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
02635                   }
02636                }
02637 
02638             }
02639          } else if (!strcasecmp(v->name, "t38support")) {
02640             if (!strcasecmp(v->value, "disabled"))
02641                peer->t38support = T38_DISABLED;
02642             if (!strcasecmp(v->value, "no"))
02643                peer->t38support = T38_DISABLED;
02644             else if (!strcasecmp(v->value, "faxgw"))
02645                peer->t38support = T38_FAXGW;
02646             else if (!strcasecmp(v->value, "yes"))
02647                peer->t38support = T38_ENABLED;
02648          }
02649          v = v->next;
02650       }
02651    }
02652 
02653    if (gH323Debug)
02654       ast_verb(0, "+++   build_peer\n");
02655 
02656    return peer;
02657 }

static struct ooh323_user* build_user ( const char *  name,
struct ast_variable v 
) [static, read]

Definition at line 2325 of file chan_ooh323.c.

References ooh323_user::accountcode, ooh323_user::amaflags, ooh323_user::aniasdni, ast_calloc, ast_channel_string2amaflag(), ast_copy_string(), ast_false(), ast_format_cap_alloc, ast_format_cap_append_from_cap(), ast_format_cap_update_by_allow_disallow(), ast_free, ast_log, AST_MEDIA_TYPE_UNKNOWN, ast_mutex_init, ast_parse_arg(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_true(), ast_verb, buf, ooh323_user::cap, ooh323_user::context, ooh323_user::directrtp, ooh323_user::dtmfcodec, ooh323_user::dtmfmode, ooh323_user::earlydirect, ooh323_user::faststart, ooh323_user::faxdetect, FAXDETECT_CNG, FAXDETECT_T38, g729onlyA, ooh323_user::g729onlyA, gAccountcode, gAMAFLAGS, gContext, gDirectRTP, gDTMFCodec, gDTMFMode, gEarlyDirect, gFastStart, gFAXdetect, gH323Debug, gNat, gRTPTimeout, gT38Support, gTunneling, ooh323_user::h245tunneling, H323_DTMF_CISCO, H323_DTMF_H245ALPHANUMERIC, H323_DTMF_H245SIGNAL, H323_DTMF_INBAND, H323_DTMF_INBANDRELAX, H323_DTMF_Q931, H323_DTMF_RFC2833, ooh323_user::incominglimit, ast_variable::lineno, ooh323_user::lock, LOG_WARNING, ooh323_user::mIP, ooh323_user::mUseIP, ast_variable::name, ooh323_user::name, ooh323_user::nat, ast_variable::next, NULL, PARSE_ADDR, ooh323_user::rtdrcount, ooh323_user::rtdrinterval, ooh323_user::rtpmask, ooh323_user::rtpmaskstr, ooh323_user::rtptimeout, strsep(), T38_DISABLED, T38_ENABLED, T38_FAXGW, ooh323_user::t38support, and ast_variable::value.

Referenced by ast_phoneprov_add_extension(), realtime_user(), reload_config(), and set_config().

02326 {
02327    struct ooh323_user *user = NULL;
02328 
02329    if (gH323Debug)
02330       ast_verb(0, "---   build_user\n");
02331 
02332       user = ast_calloc(1,sizeof(struct ooh323_user));
02333    if (user) {
02334       memset(user, 0, sizeof(struct ooh323_user));
02335       if (!(user->cap = ast_format_cap_alloc(0))) {
02336          ast_free(user);
02337          return NULL;
02338       }
02339       ast_mutex_init(&user->lock);
02340       ast_copy_string(user->name, name, sizeof(user->name));
02341       ast_format_cap_append_from_cap(user->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
02342       user->rtptimeout = gRTPTimeout;
02343       user->nat = gNat;
02344       user->dtmfmode = gDTMFMode;
02345       user->dtmfcodec = gDTMFCodec;
02346       user->faxdetect = gFAXdetect;
02347       user->t38support = gT38Support;
02348       user->faststart = gFastStart;
02349       user->h245tunneling = gTunneling;
02350       user->directrtp = gDirectRTP;
02351       user->earlydirect = gEarlyDirect;
02352       user->g729onlyA = g729onlyA;
02353       /* set default context */
02354       ast_copy_string(user->context, gContext, sizeof(user->context));
02355       ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode));
02356       user->amaflags = gAMAFLAGS;
02357 
02358       while (v) {
02359          if (!strcasecmp(v->name, "context")) {
02360             ast_copy_string(user->context, v->value, sizeof(user->context));
02361          } else if (!strcasecmp(v->name, "incominglimit")) {
02362             user->incominglimit = atoi(v->value);
02363             if (user->incominglimit < 0)
02364                user->incominglimit = 0;
02365          } else if (!strcasecmp(v->name, "accountcode")) {
02366                      ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
02367          } else if (!strcasecmp(v->name, "roundtrip")) {
02368             sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval);
02369          } else if (!strcasecmp(v->name, "faststart")) {
02370             user->faststart = ast_true(v->value);
02371          } else if (!strcasecmp(v->name, "h245tunneling")) {
02372             user->h245tunneling = ast_true(v->value);
02373          } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
02374             user->directrtp = ast_true(v->value);
02375             user->earlydirect = ast_true(v->value);
02376          } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
02377             user->earlydirect = ast_true(v->value);
02378          } else if (!strcasecmp(v->name, "g729onlyA")) {
02379             user->g729onlyA = ast_true(v->value);
02380          } else if (!strcasecmp(v->name, "nat")) {
02381             user->nat = ast_true(v->value);
02382          } else if (!strcasecmp(v->name, "rtptimeout")) {
02383             user->rtptimeout = atoi(v->value);
02384             if (user->rtptimeout < 0)
02385                user->rtptimeout = gRTPTimeout;
02386          } else if (!strcasecmp(v->name, "rtpmask")) {
02387             if ((user->rtpmask = ast_calloc(1, sizeof(struct OOH323Regex))) &&
02388                (regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED) 
02389                                  == 0)) {
02390                ast_mutex_init(&user->rtpmask->lock);
02391                user->rtpmask->inuse = 1;
02392                ast_copy_string(user->rtpmaskstr, v->value, 
02393                         sizeof(user->rtpmaskstr));
02394             } else user->rtpmask = NULL;
02395          } else if (!strcasecmp(v->name, "disallow")) {
02396             ast_format_cap_update_by_allow_disallow(user->cap,  v->value, 0);
02397          } else if (!strcasecmp(v->name, "allow")) {
02398             const char* tcodecs = v->value;
02399             if (!strcasecmp(v->value, "all")) {
02400                tcodecs = "ulaw,alaw,g729,g723,gsm";
02401             }
02402             ast_format_cap_update_by_allow_disallow(user->cap,  tcodecs, 1);
02403          } else if (!strcasecmp(v->name, "amaflags")) {
02404             user->amaflags = ast_channel_string2amaflag(v->value);
02405                } else if (!strcasecmp(v->name, "ip") || !strcasecmp(v->name, "host")) {
02406             struct ast_sockaddr p;
02407             if (!ast_parse_arg(v->value, PARSE_ADDR, &p)) {
02408                ast_copy_string(user->mIP, ast_sockaddr_stringify_addr(&p), sizeof(user->mIP)-1);
02409             } else { 
02410                         ast_copy_string(user->mIP, v->value, sizeof(user->mIP)-1);
02411             }
02412                      user->mUseIP = 1;
02413          } else if (!strcasecmp(v->name, "dtmfmode")) {
02414             if (!strcasecmp(v->value, "rfc2833"))
02415                user->dtmfmode = H323_DTMF_RFC2833;
02416             if (!strcasecmp(v->value, "cisco"))
02417                user->dtmfmode = H323_DTMF_CISCO;
02418             else if (!strcasecmp(v->value, "q931keypad"))
02419                user->dtmfmode = H323_DTMF_Q931;
02420             else if (!strcasecmp(v->value, "h245alphanumeric"))
02421                user->dtmfmode = H323_DTMF_H245ALPHANUMERIC;
02422             else if (!strcasecmp(v->value, "h245signal"))
02423                user->dtmfmode = H323_DTMF_H245SIGNAL;
02424             else if (!strcasecmp(v->value, "inband"))
02425                user->dtmfmode = H323_DTMF_INBAND;
02426          } else if (!strcasecmp(v->name, "relaxdtmf")) {
02427             user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
02428          } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
02429             user->dtmfcodec = atoi(v->value);
02430          } else if (!strcasecmp(v->name, "faxdetect")) {
02431             if (ast_true(v->value)) {
02432                user->faxdetect = FAXDETECT_CNG | FAXDETECT_T38;
02433             } else if (ast_false(v->value)) {
02434                user->faxdetect = 0;
02435             } else {
02436                char *buf = ast_strdupa(v->value);
02437                char *word, *next = buf;
02438                user->faxdetect = 0;
02439                while ((word = strsep(&next, ","))) {
02440                   if (!strcasecmp(word, "cng")) {
02441                      user->faxdetect |= FAXDETECT_CNG;
02442                   } else if (!strcasecmp(word, "t38")) {
02443                      user->faxdetect |= FAXDETECT_T38;
02444                   } else {
02445                      ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
02446                   }
02447                }
02448 
02449             }
02450          } else if (!strcasecmp(v->name, "t38support")) {
02451             if (!strcasecmp(v->value, "disabled"))
02452                user->t38support = T38_DISABLED;
02453             if (!strcasecmp(v->value, "no"))
02454                user->t38support = T38_DISABLED;
02455             else if (!strcasecmp(v->value, "faxgw"))
02456                user->t38support = T38_FAXGW;
02457             else if (!strcasecmp(v->value, "yes"))
02458                user->t38support = T38_ENABLED;
02459          } else if (!strcasecmp(v->name, "aniasdni")) {
02460             user->aniasdni = ast_true(v->value);
02461          }
02462          v = v->next;
02463       }
02464    }
02465 
02466    if (gH323Debug)
02467       ast_verb(0, "+++   build_user\n");
02468 
02469    return user;
02470 }

void close_rtp_connection ( ooCallData *  call  ) 

Definition at line 4755 of file chan_ooh323.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_stop(), ast_verb, find_call, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, and ooh323_pvt::rtp.

Referenced by ooh323c_stop_transmit_channel().

04756 {
04757    struct ooh323_pvt *p = NULL;
04758 
04759    if(gH323Debug)
04760       ast_verb(0, "---   close_rtp_connection\n");
04761 
04762    p = find_call(call);
04763    if (!p) {
04764       ast_log(LOG_ERROR, "Couldn't find matching call to close rtp "
04765                          "connection\n");
04766       return;
04767    }
04768    ast_mutex_lock(&p->lock);
04769    if (p->rtp) {
04770       ast_rtp_instance_stop(p->rtp);
04771    }
04772    ast_mutex_unlock(&p->lock);
04773 
04774    if(gH323Debug)
04775       ast_verb(0, "+++   close_rtp_connection\n");
04776 
04777    return;
04778 }

void close_udptl_connection ( ooCallData *  call  ) 

Definition at line 4846 of file chan_ooh323.c.

References ast_channel_trylock, ast_channel_unlock, AST_CONTROL_T38_PARAMETERS, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_queue_control_data(), AST_T38_TERMINATED, ast_verb, DEADLOCK_AVOIDANCE, find_call, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, ooh323_pvt::owner, ast_control_t38_parameters::request_response, T38_ENABLED, ooh323_pvt::t38_tx_enable, and ooh323_pvt::t38support.

Referenced by ooh323c_stop_transmit_datachannel().

04847 {
04848    struct ooh323_pvt *p = NULL;
04849 
04850       if(gH323Debug)
04851       ast_verb(0, "---   close_udptl_connection\n");
04852 
04853    p = find_call(call);
04854    if (!p) {
04855             ast_log(LOG_ERROR, "Couldn't find matching call to close udptl "
04856                          "connection\n");
04857       return;
04858    }
04859    ast_mutex_lock(&p->lock);
04860    if (p->owner) {
04861       while (p->owner && ast_channel_trylock(p->owner)) {
04862          ast_debug(1, "Failed to grab lock, trying again\n");
04863          DEADLOCK_AVOIDANCE(&p->lock);
04864       }
04865       if (!p->owner) {
04866          ast_mutex_unlock(&p->lock);
04867          ast_log(LOG_ERROR, "Channel has no owner\n");
04868          return;
04869       }
04870    } else {
04871       ast_mutex_unlock(&p->lock);
04872       ast_log(LOG_ERROR, "Channel has no owner\n");
04873       return;
04874    }
04875 
04876    p->t38_tx_enable = 0;
04877    if (p->t38support == T38_ENABLED) {
04878       struct ast_control_t38_parameters parameters = { .request_response = 0 };
04879       parameters.request_response = AST_T38_TERMINATED;
04880       ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
04881    }
04882 
04883    ast_channel_unlock(p->owner);
04884    ast_mutex_unlock(&p->lock);
04885 
04886       if(gH323Debug)
04887       ast_verb(0, "+++   close_udptl_connection\n");
04888 
04889    return;
04890 }

int configure_local_rtp ( struct ooh323_pvt p,
ooCallData *  call 
)

Definition at line 4544 of file chan_ooh323.c.

References ao2_ref, ast_channel_set_fd(), ast_channel_trylock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_format_cap_count(), ast_format_cap_get_format(), ast_format_cap_get_framing(), ast_log, ast_mutex_unlock, ast_parse_arg(), ast_rtp_codecs_payloads_set_rtpmap_type(), ast_rtp_codecs_set_framing(), ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_local_address(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_RTCP, ast_sockaddr_copy(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_udptl_fd(), ast_udptl_get_us(), ast_udptl_new_with_bindaddr(), ast_udptl_set_far_max_datagram(), ast_verb, bindaddr, ooh323_pvt::cap, DEADLOCK_AVOIDANCE, ooh323_pvt::dtmfcodec, ooh323_pvt::dtmfmode, errno, format, gH323Debug, gTOS, H323_DTMF_CISCO, H323_DTMF_RFC2833, ooh323_pvt::lock, LOG_ERROR, LOG_WARNING, ooh323_pvt::nat, NULL, ooh323_convertAsteriskCapToH323Cap(), ooh323_pvt::owner, PARSE_ADDR, ooh323_pvt::rtdrcount, ooh323_pvt::rtdrinterval, ooh323_pvt::rtp, ooh323_pvt::rtptimeout, and ooh323_pvt::udptl.

Referenced by onNewCallCreated(), onOutgoingCall(), and ooh323_onReceivedSetup().

04545 {
04546    char lhost[INET6_ADDRSTRLEN];
04547    unsigned lport = 0;
04548    struct ast_sockaddr tmp;
04549    ooMediaInfo mediaInfo;
04550    int x;
04551 
04552    if (gH323Debug)
04553       ast_verb(0, "---   configure_local_rtp\n");
04554 
04555    memset(&mediaInfo, 0, sizeof(mediaInfo));
04556    if (ast_parse_arg(call->localIP, PARSE_ADDR, &tmp)) {
04557       ast_sockaddr_copy(&tmp, &bindaddr);
04558    }
04559    if (!(p->rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
04560       ast_log(LOG_WARNING, "Unable to create RTP session: %s\n",
04561          strerror(errno));
04562       return 0;
04563    }
04564 
04565    ast_rtp_instance_set_qos(p->rtp, gTOS, 0, "ooh323-rtp");
04566 
04567    if (!(p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &tmp))) {
04568       ast_log(LOG_WARNING, "Unable to create UDPTL session: %s\n",
04569          strerror(errno));
04570       return 0;
04571    }
04572    ast_udptl_set_far_max_datagram(p->udptl, 144);
04573 
04574    if (p->owner) {
04575       while (p->owner && ast_channel_trylock(p->owner)) {
04576          ast_debug(1,"Failed to grab lock, trying again\n");
04577          DEADLOCK_AVOIDANCE(&p->lock);
04578       }
04579       if (!p->owner) {
04580          ast_mutex_unlock(&p->lock);
04581          ast_log(LOG_ERROR, "Channel has no owner\n");
04582          return 0;
04583       }
04584    } else {
04585       ast_log(LOG_ERROR, "Channel has no owner\n");
04586       return 0;
04587    }
04588 
04589    ast_channel_set_fd(p->owner, 0, ast_rtp_instance_fd(p->rtp, 0));
04590    ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1));
04591    ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl));
04592 
04593    ast_channel_unlock(p->owner);
04594 
04595    if (p->rtp) {
04596       if (p->cap) {
04597          ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(p->rtp),
04598             ast_format_cap_get_framing(p->cap));
04599       }
04600       if (p->nat) {
04601          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, 1);
04602       }
04603       if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
04604          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
04605          ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
04606              p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
04607       }
04608       if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
04609          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
04610          ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
04611              p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
04612       }
04613       /* figure out our local RTP port and tell the H.323 stack about it*/
04614       ast_rtp_instance_get_local_address(p->rtp, &tmp);
04615       ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
04616       lport = ast_sockaddr_port(&tmp);
04617 
04618       if (p->rtptimeout) {
04619          ast_rtp_instance_set_timeout(p->rtp, p->rtptimeout);
04620       }
04621       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1);
04622       
04623    }
04624 
04625    if (p->rtdrcount) {
04626       if (gH323Debug)
04627          ast_verb(0, "Setup RTDR info: %d, %d\n", p->rtdrinterval, p->rtdrcount);
04628       call->rtdrInterval = p->rtdrinterval;
04629       call->rtdrCount = p->rtdrcount;
04630    }
04631 
04632 
04633    ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
04634    mediaInfo.lMediaPort = lport;
04635    mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort + 1;
04636    for (x = 0; x < ast_format_cap_count(p->cap); x++) {
04637       struct ast_format *format = ast_format_cap_get_format(p->cap, x);
04638 
04639       strcpy(mediaInfo.dir, "transmit");
04640       mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(format);
04641       ooAddMediaInfo(call, mediaInfo);
04642       strcpy(mediaInfo.dir, "receive");
04643       ooAddMediaInfo(call, mediaInfo);
04644       if (mediaInfo.cap == OO_G729A) {
04645          strcpy(mediaInfo.dir, "transmit");
04646          mediaInfo.cap = OO_G729;
04647          ooAddMediaInfo(call, mediaInfo);
04648          strcpy(mediaInfo.dir, "receive");
04649          ooAddMediaInfo(call, mediaInfo);
04650 
04651          strcpy(mediaInfo.dir, "transmit");
04652          mediaInfo.cap = OO_G729B;
04653          ooAddMediaInfo(call, mediaInfo);
04654          strcpy(mediaInfo.dir, "receive");
04655          ooAddMediaInfo(call, mediaInfo);
04656       }
04657 
04658       ao2_ref(format, -1);
04659    }
04660 
04661    if (p->udptl) {
04662       ast_udptl_get_us(p->udptl, &tmp);
04663       ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
04664       lport = ast_sockaddr_port(&tmp);
04665       ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
04666       mediaInfo.lMediaPort = lport;
04667       mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
04668       mediaInfo.cap = OO_T38;
04669       strcpy(mediaInfo.dir, "transmit");
04670       ooAddMediaInfo(call, mediaInfo);
04671       strcpy(mediaInfo.dir, "receive");
04672       ooAddMediaInfo(call, mediaInfo);
04673    }
04674 
04675    if (gH323Debug)
04676       ast_verb(0, "+++   configure_local_rtp\n");
04677 
04678    return 1;
04679 }

int delete_peers ( void   ) 

Definition at line 4175 of file chan_ooh323.c.

References ast_free, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_peer_list::lock, ooh323_peer::next, NULL, peerl, and ast_peer_list::peers.

Referenced by reload_config(), and unload_module().

04176 {
04177    struct ooh323_peer *cur = NULL, *prev = NULL;
04178    ast_mutex_lock(&peerl.lock);
04179    cur = peerl.peers;
04180    while (cur) {
04181       prev = cur;
04182       cur = cur->next;
04183 
04184       ast_mutex_destroy(&prev->lock);
04185       ast_free(prev->h323id);
04186       ast_free(prev->email);
04187       ast_free(prev->url);
04188       ast_free(prev->e164);
04189       if(prev->rtpmask) {
04190       ast_mutex_lock(&prev->rtpmask->lock);
04191       prev->rtpmask->inuse--;
04192       ast_mutex_unlock(&prev->rtpmask->lock);
04193       if (prev->rtpmask->inuse == 0) {
04194          regfree(&prev->rtpmask->regex);
04195          ast_mutex_destroy(&prev->rtpmask->lock);
04196          ast_free(prev->rtpmask);
04197             }
04198       }
04199       ast_free(prev);
04200 
04201       if (cur == peerl.peers) {
04202          break;
04203       }
04204    }
04205    peerl.peers = NULL;
04206    ast_mutex_unlock(&peerl.lock);
04207    return 0;
04208 }

int delete_users ( void   ) 

Definition at line 4210 of file chan_ooh323.c.

References ao2_cleanup, ast_free, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_user_list::lock, ooh323_user::next, NULL, userl, and ast_user_list::users.

Referenced by __unload_module(), reload(), reload_config(), set_config_destroy(), and unload_module().

04211 {
04212    struct ooh323_user *cur = NULL, *prev = NULL;
04213    ast_mutex_lock(&userl.lock);
04214    cur = userl.users;
04215    while (cur) {
04216       prev = cur;
04217       cur = cur->next;
04218       ast_mutex_destroy(&prev->lock);
04219 
04220             if(prev->rtpmask) {
04221          ast_mutex_lock(&prev->rtpmask->lock);
04222          prev->rtpmask->inuse--;
04223          ast_mutex_unlock(&prev->rtpmask->lock);
04224          if (prev->rtpmask->inuse == 0) {
04225             regfree(&prev->rtpmask->regex);
04226             ast_mutex_destroy(&prev->rtpmask->lock);
04227             ast_free(prev->rtpmask);
04228                }
04229             }
04230          ao2_cleanup(prev->cap);
04231       ast_free(prev);
04232       if (cur == userl.users) {
04233          break;
04234       }
04235    }
04236    userl.users = NULL;
04237    ast_mutex_unlock(&userl.lock);
04238    return 0;
04239 }

static void* do_monitor ( void *  data  )  [static]

Definition at line 3944 of file chan_ooh323.c.

References ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_io_wait(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_sendcng(), ast_sched_runq(), ast_sched_wait(), ast_sockaddr_isnull(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_test_flag, ast_verb, gGatekeeper, gH323ep, gRasGkMode, H323_NEEDDESTROY, h323_reload_lock, h323_reloading, iflist, iflock, ooh323_pvt::lastrtprx, ooh323_pvt::lastrtptx, LOG_NOTICE, monlock, ooh323_pvt::next, NULL, ooh323_destroy(), ooh323_do_reload(), ooh323_pvt::owner, ooh323_pvt::redirip, ooh323_pvt::rtp, and ooh323_pvt::rtptimeout.

Referenced by restart_monitor().

03945 {
03946    int res;
03947    int reloading;
03948    struct ooh323_pvt *h323 = NULL;
03949    time_t t;
03950 
03951    for (;;) {
03952       struct ooh323_pvt *h323_next;
03953       /* Check for a reload request */
03954       ast_mutex_lock(&h323_reload_lock);
03955       reloading = h323_reloading;
03956       h323_reloading = 0;
03957       ast_mutex_unlock(&h323_reload_lock);
03958       if (reloading) {
03959          ast_verb(1, "Reloading H.323\n");
03960          ooh323_do_reload();
03961       }
03962       if (gH323ep.gkClient && gH323ep.gkClient->state == GkClientStopped) {
03963          ooGkClientDestroy();
03964          ast_verb(0, "Restart stopped gatekeeper client\n");
03965          ooGkClientInit(gRasGkMode, (gRasGkMode == RasUseSpecificGatekeeper) ? 
03966                            gGatekeeper : 0, 0);
03967          ooGkClientStart(gH323ep.gkClient);
03968       }
03969 
03970       /* Check for interfaces needing to be killed */
03971       ast_mutex_lock(&iflock);
03972       time(&t);
03973       h323 = iflist;
03974       while (h323) {
03975          h323_next = h323->next;
03976 
03977          if (h323->rtp && h323->rtptimeout && h323->lastrtptx &&
03978             h323->lastrtptx + h323->rtptimeout < t) {
03979             ast_rtp_instance_sendcng(h323->rtp, 0);
03980             h323->lastrtptx = time(NULL);
03981          }
03982 
03983          if (h323->rtp && h323->owner && h323->rtptimeout &&
03984             h323->lastrtprx && ast_sockaddr_isnull(&h323->redirip) &&
03985             h323->lastrtprx + h323->rtptimeout < t) {
03986             if (!ast_channel_trylock(h323->owner)) {
03987                ast_softhangup_nolock(h323->owner, AST_SOFTHANGUP_DEV);
03988                ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", ast_channel_name(h323->owner), (long) (t - h323->lastrtprx));
03989                ast_channel_unlock(h323->owner);
03990             }
03991             
03992          }
03993 
03994          if (ast_test_flag(h323, H323_NEEDDESTROY)) {
03995             ooh323_destroy (h323);
03996          } /* else if (ast_test_flag(h323, H323_NEEDSTART) && h323->owner) {
03997      ast_channel_lock(h323->owner);
03998           if (ast_pbx_start(h323->owner)) {
03999             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", h323->owner->name);
04000             ast_channel_unlock(h323->owner);
04001             ast_hangup(h323->owner);
04002           }
04003           ast_channel_unlock(h323->owner);
04004      ast_clear_flag(h323, H323_NEEDSTART);
04005     } */
04006          h323 = h323_next;
04007       }
04008       ast_mutex_unlock(&iflock);
04009       pthread_testcancel();
04010 
04011       /* Wait for sched or io */
04012       res = ast_sched_wait(sched);
04013       if ((res < 0) || (res > 1000)) {
04014          res = 1000;
04015       }
04016       res = ast_io_wait(io, res);
04017       pthread_testcancel();
04018       ast_mutex_lock(&monlock);
04019       if (res >= 0) {
04020          ast_sched_runq(sched);
04021       }
04022       ast_mutex_unlock(&monlock);
04023    }
04024    /* Never reached */
04025    return NULL;
04026 }

static struct ooh323_pvt* find_call ( ooCallData *  call  )  [static, read]

Definition at line 761 of file chan_ooh323.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verb, ooh323_pvt::callToken, gH323Debug, iflist, iflock, and ooh323_pvt::next.

00762 {
00763    struct ooh323_pvt *p;
00764 
00765    if (gH323Debug)
00766       ast_verb(0, "---   find_call\n");
00767 
00768    ast_mutex_lock(&iflock);
00769 
00770    for (p = iflist; p; p = p->next) {
00771       if (p->callToken && !strcmp(p->callToken, call->callToken)) {
00772          break;
00773       }
00774    }
00775    ast_mutex_unlock(&iflock);
00776 
00777    if (gH323Debug)
00778       ast_verb(0, "+++   find_call\n");
00779 
00780    return p;
00781 }

struct ooh323_peer * find_friend ( const char *  name,
int  port 
) [read]

Definition at line 809 of file chan_ooh323.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verb, gH323Debug, ooh323_peer::ip, ast_peer_list::lock, ooh323_peer::next, peerl, ast_peer_list::peers, and ooh323_peer::port.

00810 {
00811    struct ooh323_peer *peer;  
00812 
00813    if (gH323Debug)
00814       ast_verb(0, "---   find_friend \"%s\"\n", name);
00815 
00816 
00817    ast_mutex_lock(&peerl.lock);
00818    for (peer = peerl.peers; peer; peer = peer->next) {
00819       if (gH323Debug) {
00820          ast_verb(0, "     comparing with \"%s\"\n", peer->ip);
00821       }
00822       if (!strcmp(peer->ip, name)) {
00823          if (port <= 0 || (port > 0 && peer->port == port)) {
00824             break;
00825          }
00826       }
00827    }
00828    ast_mutex_unlock(&peerl.lock);
00829 
00830    if (gH323Debug) {
00831       if (peer) {
00832          ast_verb(0, "     found matching friend\n");
00833       }
00834       ast_verb(0, "+++   find_friend \"%s\"\n", name);
00835    }
00836 
00837    return peer;      
00838 }

struct ooh323_peer* find_peer ( const char *  name,
int  port 
) [read]

Definition at line 841 of file chan_ooh323.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verb, ooh323_peer::e164, gH323Debug, ooh323_peer::h323id, ooh323_peer::ip, ast_peer_list::lock, ooh323_peer::name, ooh323_peer::next, peerl, and ast_peer_list::peers.

Referenced by ast_iax2_new(), calltoken_required(), create_addr(), dundi_encrypt(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), handle_command_response(), iax2_devicestate(), ooh323_request(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), and update_registry().

00842 {
00843    struct ooh323_peer *peer;
00844 
00845    if (gH323Debug)
00846       ast_verb(0, "---   find_peer \"%s\"\n", name);
00847 
00848 
00849    ast_mutex_lock(&peerl.lock);
00850    for (peer = peerl.peers; peer; peer = peer->next) {
00851       if (gH323Debug) {
00852          ast_verb(0, "     comparing with \"%s\"\n", peer->ip);
00853       }
00854       if (!strcasecmp(peer->name, name))
00855          break;
00856       if (peer->h323id && !strcasecmp(peer->h323id, name))
00857          break;
00858       if (peer->e164 && !strcasecmp(peer->e164, name))
00859          break;
00860       /*
00861       if (!strcmp(peer->ip, name)) {
00862          if (port > 0 && peer->port == port) { break; }
00863          else if (port <= 0) { break; }
00864       }
00865       */
00866    }
00867    ast_mutex_unlock(&peerl.lock);
00868 
00869    if (gH323Debug) {
00870       if (peer) {
00871          ast_verb(0, "     found matching peer\n");
00872       }
00873       ast_verb(0, "+++   find_peer \"%s\"\n", name);
00874    }
00875 
00876    return peer;      
00877 }

struct ooh323_user* find_user ( const char *  name,
const char *  ip 
) [read]

Definition at line 783 of file chan_ooh323.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verb, gH323Debug, ast_user_list::lock, ooh323_user::mIP, ooh323_user::mUseIP, ooh323_user::name, ooh323_user::next, userl, and ast_user_list::users.

Referenced by acf_mailbox_exists(), acf_vm_info(), admin_exec(), advanced_options(), ast_phoneprov_add_extension(), calltoken_required(), forward_message(), handle_cli_iax2_prune_realtime(), leave_voicemail(), msg_create_from_file(), ooh323_destroy(), ooh323_onReceivedSetup(), play_message_by_id(), pp_each_extension_helper(), requirecalltoken_mark_auto(), vm_authenticate(), vm_box_exists(), vm_execmain(), vm_mailbox_snapshot_create(), vm_msg_forward(), vm_msg_move(), vm_msg_play(), and vm_msg_remove().

00784 {
00785    struct ooh323_user *user;
00786 
00787    if (gH323Debug)
00788       ast_verb(0, "---   find_user: %s, %s\n",name,ip);
00789 
00790    ast_mutex_lock(&userl.lock);
00791 
00792    for (user = userl.users; user; user = user->next) {
00793       if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
00794          break;
00795       }
00796       if (name && !strcmp(user->name, name)) {
00797          break;
00798       }
00799    }
00800 
00801    ast_mutex_unlock(&userl.lock);
00802 
00803    if (gH323Debug)
00804       ast_verb(0, "+++   find_user\n");
00805 
00806    return user;
00807 }

static int function_ooh323_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

OOH323 Dialplan function - reads ooh323 settings.

Definition at line 3631 of file chan_ooh323.c.

References ast_channel_lock, ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_copy_string(), ast_log, ast_mutex_lock, ast_mutex_unlock, ooh323_pvt::callee_dialedDigits, ooh323_pvt::callee_email, ooh323_pvt::callee_h323id, ooh323_pvt::callee_url, ooh323_pvt::caller_dialedDigits, ooh323_pvt::caller_email, ooh323_pvt::caller_h323id, ooh323_pvt::caller_url, ooh323_pvt::faxdetect, ooh323_pvt::lock, LOG_ERROR, ooh323_pvt::t38support, and type.

03632 {
03633    struct ooh323_pvt *p = ast_channel_tech_pvt(chan);
03634 
03635    ast_channel_lock(chan);
03636    if (!p) {
03637       ast_channel_unlock(chan);
03638       return -1;
03639    }
03640 
03641    if (strcmp(ast_channel_tech(chan)->type, "OOH323")) {
03642       ast_log(LOG_ERROR, "This function is only supported on OOH323 channels, Channel is %s\n", ast_channel_tech(chan)->type);
03643       ast_channel_unlock(chan);
03644       return -1;
03645    }
03646 
03647    ast_mutex_lock(&p->lock);
03648    if (!strcasecmp(data, "faxdetect")) {
03649       ast_copy_string(buf, p->faxdetect ? "1" : "0", len);
03650    } else if (!strcasecmp(data, "t38support")) {
03651       ast_copy_string(buf, p->t38support ? "1" : "0", len);
03652    } else if (!strcasecmp(data, "caller_h323id")) {
03653       ast_copy_string(buf, p->caller_h323id, len);
03654    } else if (!strcasecmp(data, "caller_dialeddigits")) {
03655       ast_copy_string(buf, p->caller_dialedDigits, len);
03656    } else if (!strcasecmp(data, "caller_email")) {
03657       ast_copy_string(buf, p->caller_email, len);
03658    } else if (!strcasecmp(data, "h323id_url")) {
03659       ast_copy_string(buf, p->caller_url, len);
03660    } else if (!strcasecmp(data, "callee_h323id")) {
03661       ast_copy_string(buf, p->callee_h323id, len);
03662    } else if (!strcasecmp(data, "callee_dialeddigits")) {
03663       ast_copy_string(buf, p->callee_dialedDigits, len);
03664    } else if (!strcasecmp(data, "callee_email")) {
03665       ast_copy_string(buf, p->callee_email, len);
03666    } else if (!strcasecmp(data, "callee_url")) {
03667       ast_copy_string(buf, p->callee_url, len);
03668    }
03669    ast_mutex_unlock(&p->lock);
03670 
03671    ast_channel_unlock(chan);
03672    return 0;
03673 }

static int function_ooh323_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

OOH323 Dialplan function - writes ooh323 settings.

Definition at line 3676 of file chan_ooh323.c.

References ast_channel_lock, ast_channel_tech(), ast_channel_tech_pvt(), ast_channel_unlock, ast_false(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strdupa, ast_true(), buf, ooh323_pvt::faxdetect, FAXDETECT_CNG, FAXDETECT_T38, ooh323_pvt::lock, LOG_ERROR, LOG_WARNING, ooh323_pvt::next, strsep(), ooh323_pvt::t38support, and type.

03677 {
03678    struct ooh323_pvt *p = ast_channel_tech_pvt(chan);
03679    int res = -1;
03680 
03681    ast_channel_lock(chan);
03682    if (!p) {
03683       ast_channel_unlock(chan);
03684       return -1;
03685    }
03686 
03687    if (strcmp(ast_channel_tech(chan)->type, "OOH323")) {
03688       ast_log(LOG_ERROR, "This function is only supported on OOH323 channels, Channel is %s\n", ast_channel_tech(chan)->type);
03689       ast_channel_unlock(chan);
03690       return -1;
03691    }
03692 
03693    ast_mutex_lock(&p->lock);
03694    if (!strcasecmp(data, "faxdetect")) {
03695       if (ast_true(value)) {
03696          p->faxdetect = 1;
03697          res = 0;
03698       } else if (ast_false(value)) {
03699          p->faxdetect = 0;
03700          res = 0;
03701       } else {
03702          char *buf = ast_strdupa(value);
03703          char *word, *next = buf;
03704          p->faxdetect = 0;
03705          res = 0;
03706          while ((word = strsep(&next, ","))) {
03707             if (!strcasecmp(word, "cng")) {
03708                p->faxdetect |= FAXDETECT_CNG;
03709             } else if (!strcasecmp(word, "t38")) {
03710                p->faxdetect |= FAXDETECT_T38;
03711             } else {
03712                ast_log(LOG_WARNING, "Unknown faxdetect mode '%s'.\n", word);
03713                res = -1;
03714             }
03715          }
03716 
03717       }
03718    } else if (!strcasecmp(data, "t38support")) {
03719       if (ast_true(value)) {
03720          p->t38support = 1;
03721          res = 0;
03722       } else {
03723          p->t38support = 0;
03724          res = 0;
03725       }
03726    }
03727    ast_mutex_unlock(&p->lock);
03728    ast_channel_unlock(chan);
03729 
03730    return res;
03731 }

char* handle_cli_ooh323_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)

Definition at line 2732 of file chan_ooh323.c.

References ast_cli_args::argc, ast_mutex_lock, ast_mutex_unlock, ast_verb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, gH323Debug, h323_reload_lock, h323_reloading, NULL, restart_monitor(), and ast_cli_entry::usage.

02733 {
02734 
02735        switch (cmd) {
02736        case CLI_INIT:
02737                e->command = "ooh323 reload";
02738                e->usage =
02739                        "Usage: ooh323 reload\n"
02740                        "                Reload OOH323 config.\n";
02741                return NULL;
02742        case CLI_GENERATE:
02743                return NULL;
02744        }
02745 
02746        if (a->argc != 2)
02747                return CLI_SHOWUSAGE;
02748 
02749    if (gH323Debug)
02750       ast_verb(0, "---   ooh323_reload\n");
02751 
02752    ast_mutex_lock(&h323_reload_lock);
02753    if (h323_reloading) {
02754       ast_verb(0, "Previous OOH323 reload not yet done\n");
02755    } else {
02756       h323_reloading = 1;
02757    }
02758    ast_mutex_unlock(&h323_reload_lock);
02759    restart_monitor();
02760 
02761    if (gH323Debug)
02762       ast_verb(0, "+++   ooh323_reload\n");
02763 
02764    return 0;
02765 }

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

Definition at line 3412 of file chan_ooh323.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, gH323Debug, NULL, TRUE, and ast_cli_entry::usage.

03413 {
03414    switch (cmd) {
03415    case CLI_INIT:
03416       e->command = "ooh323 set debug [off]";
03417       e->usage =
03418          "Usage: ooh323 set debug [off]\n"
03419          "      Enables/Disables debugging of OOH323 channel driver\n";
03420       return NULL;
03421    case CLI_GENERATE:
03422       return NULL;
03423    }
03424 
03425    if (a->argc < 3 || a->argc > 4)
03426       return CLI_SHOWUSAGE;
03427    if (a->argc == 4 && strcasecmp(a->argv[3], "off"))
03428       return CLI_SHOWUSAGE;
03429 
03430    gH323Debug = (a->argc == 4) ? FALSE : TRUE;
03431    ast_cli(a->fd, "OOH323 Debugging %s\n", gH323Debug ? "Enabled" : "Disabled");
03432 
03433    return CLI_SUCCESS;
03434 }

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

Definition at line 3504 of file chan_ooh323.c.

References ast_cli_args::argc, ast_channel_amaflags2string(), ast_cli(), ast_format_cap_get_names(), ast_str_alloca, callnumber, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FAXDETECT_CNG, FAXDETECT_T38, ast_cli_args::fd, FORMAT_STRING_SIZE, gAccountcode, gAliasList, gAMAFLAGS, gCallerID, gContext, gDirectRTP, gDTMFCodec, gDTMFMode, gEarlyDirect, gFastStart, gFAXdetect, gGatekeeper, gH323ep, gIP, gLogFile, gMediaWaitForConnect, gPort, gRasGkMode, gRTDRCount, gRTDRInterval, gT38Support, gTunneling, H323_DTMF_CISCO, H323_DTMF_H245ALPHANUMERIC, H323_DTMF_H245SIGNAL, H323_DTMF_INBAND, H323_DTMF_INBANDRELAX, H323_DTMF_Q931, H323_DTMF_RFC2833, ooh323_config::mTCPPortEnd, ooh323_config::mTCPPortStart, NULL, ooconfig, T38_DISABLED, T38_FAXGW, ast_cli_entry::usage, and value.

03505 {
03506    char value[FORMAT_STRING_SIZE];
03507    struct ast_str *codec_buf = ast_str_alloca(64);
03508    ooAliases *pAlias = NULL, *pAliasNext = NULL;;
03509 
03510    switch (cmd) {
03511    case CLI_INIT:
03512       e->command = "ooh323 show config";
03513       e->usage =
03514          "Usage: ooh323 show config\n"
03515          "      Shows global configuration of H.323 channel driver\n";
03516       return NULL;
03517    case CLI_GENERATE:
03518       return NULL;
03519    }
03520 
03521    if (a->argc != 3)
03522       return CLI_SHOWUSAGE;
03523 
03524    ast_cli(a->fd, "\nObjective Open H.323 Channel Driver's Config:\n");
03525    snprintf(value, sizeof(value), "%s:%d", gIP, gPort);
03526    ast_cli(a->fd, "%-20s%s\n", "IP:Port: ", value);
03527    ast_cli(a->fd, "%-20s%d-%d\n", "H.225 port range: ", ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd);
03528    ast_cli(a->fd, "%-20s%s\n", "FastStart", gFastStart?"yes":"no");
03529    ast_cli(a->fd, "%-20s%s\n", "Tunneling", gTunneling?"yes":"no");
03530    ast_cli(a->fd, "%-20s%s\n", "CallerId", gCallerID);
03531    ast_cli(a->fd, "%-20s%s\n", "MediaWaitForConnect", gMediaWaitForConnect?"yes":"no");
03532    ast_cli(a->fd, "%-20s%s\n", "DirectRTP", gDirectRTP ? "yes" : "no");
03533    ast_cli(a->fd, "%-20s%s\n", "EarlyDirectRTP", gEarlyDirect ? "yes" : "no");
03534 
03535 #if (0)
03536       extern OOH323EndPoint gH323ep;
03537    ast_cli(a->fd, "%-20s%s\n", "FASTSTART",
03538       (OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART) != 0) ? "yes" : "no");
03539    ast_cli(a->fd, "%-20s%s\n", "TUNNELING",
03540       (OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING) != 0) ? "yes" : "no");
03541    ast_cli(a->fd, "%-20s%s\n", "MEDIAWAITFORCONN",
03542       (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN) != 0) ? "yes" : "no");
03543 #endif
03544 
03545    if (gRasGkMode == RasNoGatekeeper) {
03546       snprintf(value, sizeof(value), "%s", "No Gatekeeper");
03547    } else if (gRasGkMode == RasDiscoverGatekeeper) {
03548       snprintf(value, sizeof(value), "%s", "Discover");
03549    } else {
03550       snprintf(value, sizeof(value), "%s", gGatekeeper);
03551    }
03552    ast_cli(a->fd,  "%-20s%s\n", "Gatekeeper:", value);
03553    ast_cli(a->fd,  "%-20s%s\n", "H.323 LogFile:", gLogFile);
03554    ast_cli(a->fd,  "%-20s%s\n", "Context:", gContext);
03555    ast_cli(a->fd,  "%-20s%s\n", "Capability:",
03556       ast_format_cap_get_names(gCap, &codec_buf));
03557    ast_cli(a->fd, "%-20s", "DTMF Mode: ");
03558    if (gDTMFMode & H323_DTMF_CISCO) {
03559       ast_cli(a->fd, "%s\n", "cisco");
03560       ast_cli(a->fd, "%-20.15s%d\n", "DTMF Codec: ", gDTMFCodec);
03561    } else if (gDTMFMode & H323_DTMF_RFC2833) {
03562       ast_cli(a->fd, "%s\n", "rfc2833");
03563       ast_cli(a->fd, "%-20.15s%d\n", "DTMF Codec: ", gDTMFCodec);
03564    } else if (gDTMFMode & H323_DTMF_Q931) {
03565       ast_cli(a->fd, "%s\n", "q931keypad");
03566    } else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC) {
03567       ast_cli(a->fd, "%s\n", "h245alphanumeric");
03568    } else if (gDTMFMode & H323_DTMF_H245SIGNAL) {
03569       ast_cli(a->fd, "%s\n", "h245signal");
03570    } else if (gDTMFMode & H323_DTMF_INBAND && gDTMFMode & H323_DTMF_INBANDRELAX) {
03571       ast_cli(a->fd, "%s\n", "inband-relaxed");
03572    } else if (gDTMFMode & H323_DTMF_INBAND) {
03573       ast_cli(a->fd, "%s\n", "inband");
03574    } else {
03575       ast_cli(a->fd, "%s\n", "unknown");
03576    }
03577 
03578    ast_cli(a->fd,"%-20s", "T.38 Mode: ");
03579    if (gT38Support == T38_DISABLED) {
03580       ast_cli(a->fd, "%s\n", "disabled");
03581    } else if (gT38Support == T38_FAXGW) {
03582       ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
03583    }
03584    if (gFAXdetect == (FAXDETECT_CNG | FAXDETECT_T38)) {
03585       ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Yes");
03586    } else if (gFAXdetect & FAXDETECT_CNG) {
03587       ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Cng");
03588    } else if (gFAXdetect & FAXDETECT_T38) {
03589       ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "T.38");
03590    } else {
03591       ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "No");
03592    }
03593 
03594    if (gRTDRCount && gRTDRInterval) {
03595       ast_cli(a->fd, "%-20.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval);
03596    }
03597 
03598    ast_cli(a->fd, "%-20s%ld\n", "Call counter: ", callnumber);
03599    ast_cli(a->fd, "%-20s%s\n", "AccountCode: ", gAccountcode);
03600    ast_cli(a->fd, "%-20s%s\n", "AMA flags: ", ast_channel_amaflags2string(gAMAFLAGS));
03601 
03602    pAlias = gAliasList;
03603    if(pAlias) {
03604       ast_cli(a->fd, "%-20s\n", "Aliases: ");
03605    }
03606    while (pAlias) {
03607       pAliasNext = pAlias->next;
03608       if (pAliasNext) {
03609          ast_cli(a->fd,"\t%-30s\t%-30s\n",pAlias->value, pAliasNext->value);
03610          pAlias = pAliasNext->next;
03611       } else {
03612          ast_cli(a->fd,"\t%-30s\n",pAlias->value);
03613          pAlias = pAlias->next;
03614       }
03615    }
03616    return CLI_SUCCESS;
03617 }

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

Definition at line 3443 of file chan_ooh323.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT_STRING_SIZE, gGatekeeper, gH323ep, gRasGkMode, NULL, ast_cli_entry::usage, and value.

03444 {
03445    char value[FORMAT_STRING_SIZE];
03446 
03447    switch (cmd) {
03448    case CLI_INIT:
03449       e->command = "ooh323 show gk";
03450       e->usage =
03451          "Usage: ooh323 show gk\n"
03452          "      Shows Gatekeeper connection state\n";
03453       return NULL;
03454    case CLI_GENERATE:
03455       return NULL;
03456    }
03457 
03458    if (a->argc != 3)
03459       return CLI_SHOWUSAGE;
03460 
03461    ast_cli(a->fd, "\nGateKeeper connection state:\n");
03462    if (!gH323ep.gkClient) {
03463       ast_cli(a->fd, "No Gatekeeper is configured\n");
03464       return CLI_SUCCESS;
03465    }
03466 
03467    if (gRasGkMode == RasNoGatekeeper) {
03468       snprintf(value, sizeof(value), "%s", "No Gatekeeper");
03469    } else if (gRasGkMode == RasDiscoverGatekeeper) {
03470       snprintf(value, sizeof(value), "%s", "Discover");
03471    } else {
03472       snprintf(value, sizeof(value), "%s", gGatekeeper);
03473    }
03474    ast_cli(a->fd,  "%-20s%s\n", "Gatekeeper:", value);
03475    switch(gH323ep.gkClient->state) {
03476    case GkClientIdle:
03477       ast_cli(a->fd, "%-20s%s\n", "GK state:", "Idle");
03478       break;
03479    case GkClientDiscovered:
03480       ast_cli(a->fd, "%-20s%s\n", "GK state:", "Discovered");
03481       break;
03482    case GkClientRegistered:
03483       ast_cli(a->fd, "%-20s%s\n", "GK state:", "Registered");
03484       break;
03485    case GkClientUnregistered:
03486       ast_cli(a->fd, "%-20s%s\n", "GK state:", "Unregistered");
03487       break;
03488    case GkClientGkErr:
03489       ast_cli(a->fd, "%-20s%s\n", "GK state:", "Error");
03490       break;
03491    case GkClientFailed:
03492       ast_cli(a->fd, "%-20s%s\n", "GK state:", "Failed");
03493       break;
03494    case GkClientStopped:
03495       ast_cli(a->fd, "%-20s%s\n", "GK state:", "Shutdown");
03496       break;
03497    default:
03498       break;
03499    }
03500 
03501    return CLI_SUCCESS;
03502 }

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

Definition at line 3134 of file chan_ooh323.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_channel_amaflags2string(), ast_cli(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FAXDETECT_CNG, FAXDETECT_T38, ast_cli_args::fd, H323_DTMF_CISCO, H323_DTMF_H245ALPHANUMERIC, H323_DTMF_H245SIGNAL, H323_DTMF_INBAND, H323_DTMF_INBANDRELAX, H323_DTMF_Q931, H323_DTMF_RFC2833, ooh323_peer::lock, ast_peer_list::lock, ooh323_peer::next, NULL, peerl, ast_peer_list::peers, T38_DISABLED, T38_FAXGW, and ast_cli_entry::usage.

03135 {
03136    char ip_port[30];
03137    struct ooh323_peer *prev = NULL, *peer = NULL;
03138    
03139    switch (cmd) {
03140    case CLI_INIT:
03141       e->command = "ooh323 show peer";
03142       e->usage =
03143          "Usage: ooh323 show peer <name>\n"
03144          "      List details of specific OOH323 peer.\n";
03145       return NULL;
03146    case CLI_GENERATE:
03147       return NULL;
03148    }
03149 
03150    if (a->argc != 4)
03151       return CLI_SHOWUSAGE;
03152 
03153    ast_mutex_lock(&peerl.lock);
03154    peer = peerl.peers;
03155    while (peer) {
03156       ast_mutex_lock(&peer->lock);
03157       if (!strcmp(peer->name, a->argv[3])) {
03158          break;
03159       } else {
03160          prev = peer;
03161          peer = peer->next;
03162          ast_mutex_unlock(&prev->lock);
03163       }
03164    }
03165 
03166    if (peer) {
03167       sprintf(ip_port, "%s:%d", peer->ip, peer->port);
03168       ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name);
03169       ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no",
03170                peer->h245tunneling?"yes":"no");
03171       ast_cli(a->fd, "%-15s%s\n", "DirectRTP", peer->directrtp ? "yes" : "no");
03172       ast_cli(a->fd, "%-15s%s\n", "EarlyDirectRTP", peer->earlydirect ? "yes" : "no");
03173       ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
03174       if (peer->dtmfmode & H323_DTMF_CISCO) {
03175          ast_cli(a->fd, "%s\n", "cisco");
03176          ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
03177       } else if (peer->dtmfmode & H323_DTMF_RFC2833) {
03178          ast_cli(a->fd, "%s\n", "rfc2833");
03179          ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec);
03180       } else if (peer->dtmfmode & H323_DTMF_Q931) {
03181          ast_cli(a->fd, "%s\n", "q931keypad");
03182       } else if (peer->dtmfmode & H323_DTMF_H245ALPHANUMERIC) {
03183          ast_cli(a->fd, "%s\n", "h245alphanumeric");
03184       } else if (peer->dtmfmode & H323_DTMF_H245SIGNAL) {
03185          ast_cli(a->fd, "%s\n", "h245signal");
03186       } else if (peer->dtmfmode & H323_DTMF_INBAND && peer->dtmfmode & H323_DTMF_INBANDRELAX) {
03187          ast_cli(a->fd, "%s\n", "inband-relaxed");
03188       } else if (peer->dtmfmode & H323_DTMF_INBAND) {
03189          ast_cli(a->fd, "%s\n", "inband");
03190       } else {
03191          ast_cli(a->fd, "%s\n", "unknown");
03192       }
03193       ast_cli(a->fd,"%-15s", "T.38 Mode: ");
03194       if (peer->t38support == T38_DISABLED) {
03195          ast_cli(a->fd, "%s\n", "disabled");
03196       } else if (peer->t38support == T38_FAXGW) {
03197          ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
03198       }
03199       if (peer->faxdetect == (FAXDETECT_CNG | FAXDETECT_T38)) {
03200          ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Yes");
03201       } else if (peer->faxdetect & FAXDETECT_CNG) {
03202          ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Cng");
03203       } else if (peer->faxdetect & FAXDETECT_T38) {
03204          ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "T.38");
03205       } else {
03206          ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "No");
03207       }
03208 
03209       ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode);
03210       ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", ast_channel_amaflags2string(peer->amaflags));
03211       ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port);
03212       ast_cli(a->fd, "%-15.15s%u\n", "OutgoingLimit: ", peer->outgoinglimit);
03213       ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout);
03214       ast_cli(a->fd, "%-15.15s%s\n", "nat: ", peer->nat?"yes":"no");
03215       if (peer->rtpmaskstr[0]) {
03216          ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", peer->rtpmaskstr);
03217       }
03218       if (peer->rtdrcount && peer->rtdrinterval) {
03219          ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", peer->rtdrcount, peer->rtdrinterval);
03220       }
03221       ast_mutex_unlock(&peer->lock);
03222    } else {
03223       ast_cli(a->fd, "Peer %s not found\n", a->argv[3]);
03224       ast_cli(a->fd, "\n");
03225    }
03226    ast_mutex_unlock(&peerl.lock);
03227 
03228    return CLI_SUCCESS;
03229 }

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

Definition at line 3231 of file chan_ooh323.c.

References ast_cli_args::argc, ast_cli(), ast_format_cap_get_names(), ast_mutex_lock, ast_mutex_unlock, ast_str_alloca, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, ooh323_peer::lock, ast_peer_list::lock, ooh323_peer::next, NULL, peerl, ast_peer_list::peers, and ast_cli_entry::usage.

03232 {
03233    struct ooh323_peer *prev = NULL, *peer = NULL;
03234    struct ast_str *codec_buf = ast_str_alloca(64);
03235    char ip_port[30];
03236 #define FORMAT  "%-15.15s  %-15.15s  %-23.23s  %-s\n"
03237 
03238    switch (cmd) {
03239    case CLI_INIT:
03240       e->command = "ooh323 show peers";
03241       e->usage =
03242          "Usage: ooh323 show peers\n"
03243          "      Lists all known OOH323 peers.\n";
03244       return NULL;
03245    case CLI_GENERATE:
03246       return NULL;
03247    }
03248 
03249    if (a->argc != 3)
03250       return CLI_SHOWUSAGE;
03251 
03252    ast_cli(a->fd, FORMAT, "Name", "Accountcode", "ip:port", "Formats");
03253 
03254    ast_mutex_lock(&peerl.lock);
03255    peer = peerl.peers;
03256    while (peer) {
03257       ast_mutex_lock(&peer->lock);
03258       snprintf(ip_port, sizeof(ip_port), "%s:%d", peer->ip, peer->port);
03259       ast_cli(a->fd, FORMAT, peer->name, 
03260                peer->accountcode,
03261                ip_port,
03262                ast_format_cap_get_names(peer->cap, &codec_buf));
03263       prev = peer;
03264       peer = peer->next;
03265       ast_mutex_unlock(&prev->lock);
03266 
03267    }
03268    ast_mutex_unlock(&peerl.lock);
03269 #undef FORMAT
03270    return CLI_SUCCESS;
03271 }

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

Definition at line 3273 of file chan_ooh323.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_channel_amaflags2string(), ast_cli(), ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FAXDETECT_CNG, FAXDETECT_T38, ast_cli_args::fd, H323_DTMF_CISCO, H323_DTMF_H245ALPHANUMERIC, H323_DTMF_H245SIGNAL, H323_DTMF_INBAND, H323_DTMF_INBANDRELAX, H323_DTMF_Q931, H323_DTMF_RFC2833, ooh323_user::lock, ast_user_list::lock, ooh323_user::next, NULL, T38_DISABLED, T38_FAXGW, ast_cli_entry::usage, userl, and ast_user_list::users.

03274 {
03275    struct ooh323_user *prev = NULL, *user = NULL;
03276 
03277    switch (cmd) {
03278    case CLI_INIT:
03279       e->command = "ooh323 show user";
03280       e->usage =
03281          "Usage: ooh323 show user <name>\n"
03282          "      List details of specific OOH323 user.\n";
03283       return NULL;
03284    case CLI_GENERATE:
03285       return NULL;
03286    }
03287 
03288    if (a->argc != 4)
03289       return CLI_SHOWUSAGE;
03290 
03291 
03292    ast_mutex_lock(&userl.lock);
03293    user = userl.users;
03294    while (user) {
03295       ast_mutex_lock(&user->lock);
03296       if (!strcmp(user->name, a->argv[3])) {
03297          break;
03298       } else {
03299          prev = user;
03300          user = user->next;
03301          ast_mutex_unlock(&prev->lock);
03302       }
03303    }
03304 
03305    if (user) {
03306       ast_cli(a->fd, "%-15.15s%s\n", "Name: ", user->name);
03307       ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", user->faststart?"yes":"no",
03308                user->h245tunneling?"yes":"no");
03309       ast_cli(a->fd, "%-15s%s\n", "DirectRTP", user->directrtp ? "yes" : "no");
03310       ast_cli(a->fd, "%-15s%s\n", "EarlyDirectRTP", user->earlydirect ? "yes" : "no");
03311       ast_cli(a->fd, "%-15.15s", "DTMF Mode: ");
03312       if (user->dtmfmode & H323_DTMF_CISCO) {
03313          ast_cli(a->fd, "%s\n", "cisco");
03314          ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
03315       } else if (user->dtmfmode & H323_DTMF_RFC2833) {
03316          ast_cli(a->fd, "%s\n", "rfc2833");
03317          ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec);
03318       } else if (user->dtmfmode & H323_DTMF_Q931) {
03319          ast_cli(a->fd, "%s\n", "q931keypad");
03320       } else if (user->dtmfmode & H323_DTMF_H245ALPHANUMERIC) {
03321          ast_cli(a->fd, "%s\n", "h245alphanumeric");
03322       } else if (user->dtmfmode & H323_DTMF_H245SIGNAL) {
03323          ast_cli(a->fd, "%s\n", "h245signal");
03324       } else if (user->dtmfmode & H323_DTMF_INBAND && user->dtmfmode & H323_DTMF_INBANDRELAX) {
03325          ast_cli(a->fd, "%s\n", "inband-relaxed");
03326       } else if (user->dtmfmode & H323_DTMF_INBAND) {
03327          ast_cli(a->fd, "%s\n", "inband");
03328       } else {
03329          ast_cli(a->fd, "%s\n", "unknown");
03330       }
03331       ast_cli(a->fd,"%-15s", "T.38 Mode: ");
03332       if (user->t38support == T38_DISABLED) {
03333          ast_cli(a->fd, "%s\n", "disabled");
03334       } else if (user->t38support == T38_FAXGW) {
03335          ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible");
03336       }
03337       if (user->faxdetect == (FAXDETECT_CNG | FAXDETECT_T38)) {
03338          ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Yes");
03339       } else if (user->faxdetect & FAXDETECT_CNG) {
03340          ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "Cng");
03341       } else if (user->faxdetect & FAXDETECT_T38) {
03342          ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "T.38");
03343       } else {
03344          ast_cli(a->fd,"%-20s%s\n", "FAX Detect:", "No");
03345       }
03346 
03347       ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", user->accountcode);
03348       ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", ast_channel_amaflags2string(user->amaflags));
03349       ast_cli(a->fd, "%-15.15s%s\n", "Context: ", user->context);
03350       ast_cli(a->fd, "%-15.15s%d\n", "IncomingLimit: ", user->incominglimit);
03351       ast_cli(a->fd, "%-15.15s%u\n", "InUse: ", user->inUse);
03352       ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", user->rtptimeout);
03353       ast_cli(a->fd, "%-15.15s%s\n", "nat: ", user->nat?"yes":"no");
03354       if (user->rtpmaskstr[0]) {
03355          ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", user->rtpmaskstr);
03356       }
03357       ast_mutex_unlock(&user->lock);
03358       if (user->rtdrcount && user->rtdrinterval) {
03359          ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", user->rtdrcount, user->rtdrinterval);
03360       }
03361    } else {
03362       ast_cli(a->fd, "User %s not found\n", a->argv[3]);
03363       ast_cli(a->fd, "\n");
03364    }
03365    ast_mutex_unlock(&userl.lock);
03366 
03367    return CLI_SUCCESS;
03368 }

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

Definition at line 3370 of file chan_ooh323.c.

References ast_cli_args::argc, ast_cli(), ast_format_cap_get_names(), ast_mutex_lock, ast_mutex_unlock, ast_str_alloca, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, ast_cli_args::fd, FORMAT1, ooh323_user::lock, ast_user_list::lock, ooh323_user::next, NULL, RESULT_SUCCESS, ast_cli_entry::usage, userl, and ast_user_list::users.

03371 {
03372    struct ooh323_user *prev = NULL, *user = NULL;
03373    struct ast_str *codec_buf = ast_str_alloca(64);
03374 #define FORMAT1  "%-15.15s  %-15.15s  %-15.15s  %-s\n"
03375 
03376    switch (cmd) {
03377    case CLI_INIT:
03378       e->command = "ooh323 show users";
03379       e->usage =
03380          "Usage: ooh323 show users \n"
03381          "      Lists all known OOH323 users.\n";
03382       return NULL;
03383    case CLI_GENERATE:
03384       return NULL;
03385    }
03386 
03387    if (a->argc != 3)
03388       return CLI_SHOWUSAGE;
03389 
03390 
03391    ast_cli(a->fd, FORMAT1, "Username", "Accountcode", "Context", "Formats");
03392 
03393    ast_mutex_lock(&userl.lock);
03394    user = userl.users;
03395    while(user)
03396    {
03397       ast_mutex_lock(&user->lock);
03398          ast_cli(a->fd, FORMAT1, user->name, 
03399                user->accountcode, user->context,
03400                ast_format_cap_get_names(user->cap, &codec_buf));
03401       prev = user;
03402       user = user->next;
03403       ast_mutex_unlock(&prev->lock);
03404 
03405    }
03406    ast_mutex_unlock(&userl.lock);
03407 #undef FORMAT1
03408    return RESULT_SUCCESS;
03409 
03410 }

static int load_module ( void   )  [static]

Definition at line 3733 of file chan_ooh323.c.

References ao2_ref, ast_channel_register(), ast_cli_register_multiple(), ast_debug, ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_ulaw, ast_log, AST_MEDIA_TYPE_UNKNOWN, AST_MODULE_LOAD_DECLINE, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_register_atexit(), ast_rtp_glue_register, ast_sched_context_create(), ast_channel_tech::capabilities, ooh323_peer::e164, ooh323_peer::email, gAliasList, gBeMaster, gCallerID, gDTMFCodec, gDTMFMode, gFastStart, gGatekeeper, gIP, gIsGateway, gLogFile, gMediaWaitForConnect, gPort, gRasGkMode, gTRCLVL, gTunneling, ooh323_peer::h323id, io_context_create(), ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_WARNING, manufacturer, ooh323_config::mTCPPortEnd, ooh323_config::mTCPPortStart, ooh323_peer::next, NULL, onAlerting(), onCallCleared(), onCallEstablished(), onModeChanged(), onNewCallCreated(), onOutgoingCall(), onProgress(), ooconfig, ooh323_onReceivedDigit(), ooh323_onReceivedSetup(), ooh323c_set_capability(), ooh323c_start_stack_thread(), peerl, ast_peer_list::peers, reload_config(), restart_monitor(), setup_rtp_remote(), t35countrycode, t35extensions, type, ooh323_peer::url, userl, ast_user_list::users, v6mode, vendor, and version.

03734 {
03735    struct ooAliases * pNewAlias = NULL;
03736    struct ooh323_peer *peer = NULL;
03737    OOH225MsgCallbacks h225Callbacks = {0, 0, 0, 0};
03738 
03739    OOH323CALLBACKS h323Callbacks = {
03740       .onNewCallCreated = onNewCallCreated,
03741       .onAlerting = onAlerting,
03742       .onProgress = onProgress,
03743       .onIncomingCall = NULL,
03744       .onOutgoingCall = onOutgoingCall,
03745       .onCallEstablished = onCallEstablished,
03746       .onCallCleared = onCallCleared,
03747       .openLogicalChannels = NULL,
03748       .onReceivedDTMF = ooh323_onReceivedDigit,
03749       .onModeChanged = onModeChanged,
03750       .onMediaChanged = (cb_OnMediaChanged) setup_rtp_remote,
03751    };
03752    if (!(gCap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
03753       return AST_MODULE_LOAD_DECLINE; 
03754    }
03755    if (!(ooh323_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
03756       ao2_ref(gCap, -1);
03757       gCap = NULL;
03758       return AST_MODULE_LOAD_DECLINE;
03759    }
03760    ast_format_cap_append(gCap, ast_format_ulaw, 0);
03761    ast_format_cap_append_by_type(ooh323_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
03762 
03763    myself = ast_module_info->self;
03764 
03765    h225Callbacks.onReceivedSetup = &ooh323_onReceivedSetup;
03766 
03767    userl.users = NULL;
03768    ast_mutex_init(&userl.lock);
03769    peerl.peers = NULL;
03770    ast_mutex_init(&peerl.lock);
03771  
03772 #if 0    
03773    ast_register_atexit(&ast_ooh323c_exit);
03774 #endif
03775 
03776    if (!(sched = ast_sched_context_create())) {
03777       ast_log(LOG_WARNING, "Unable to create schedule context\n");
03778    }
03779    if (!(io = io_context_create())) {
03780       ast_log(LOG_WARNING, "Unable to create I/O context\n");
03781    }
03782 
03783 
03784    if (!reload_config(0)) {
03785 
03786       /* fire up the H.323 Endpoint */     
03787       if (OO_OK != ooH323EpInitialize(OO_CALLMODE_AUDIOCALL, gLogFile)) {
03788                ast_log(LOG_ERROR, "Failed to initialize OOH323 endpoint-"
03789                             "OOH323 Disabled\n");
03790          ao2_ref(gCap, -1);
03791          gCap = NULL;
03792          ao2_ref(ooh323_tech.capabilities, -1);
03793          ooh323_tech.capabilities = NULL;
03794          return AST_MODULE_LOAD_DECLINE;
03795       }
03796 
03797       /* Make sure we can register our OOH323 channel type */
03798       if (ast_channel_register(&ooh323_tech)) {
03799          ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
03800          ao2_ref(gCap, -1);
03801          gCap = NULL;
03802          ao2_ref(ooh323_tech.capabilities, -1);
03803          ooh323_tech.capabilities = NULL;
03804          return AST_MODULE_LOAD_DECLINE;
03805       }
03806       ast_rtp_glue_register(&ooh323_rtp);
03807       ast_cli_register_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry));
03808 
03809       if (gIsGateway)
03810          ooH323EpSetAsGateway();
03811 
03812             ooH323EpSetVersionInfo(t35countrycode, t35extensions, manufacturer,
03813                             vendor, version);
03814       ooH323EpDisableAutoAnswer();
03815       ooH323EpSetH225MsgCallbacks(h225Callbacks);
03816             ooH323EpSetTraceLevel(gTRCLVL);
03817       ooH323EpSetLocalAddress(gIP, gPort);
03818       if (v6mode) {
03819          ast_debug(1, "OOH323 channel is in IP6 mode\n");
03820       }
03821       ooH323EpSetCallerID(gCallerID);
03822  
03823       if(ooH323EpSetTCPPortRange(ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd) == OO_FAILED) {
03824          ast_log(LOG_ERROR, "h225portrange: Failed to set range\n");
03825       }
03826 
03827       /* Set aliases if any */
03828       for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
03829          switch (pNewAlias->type) {
03830          case T_H225AliasAddress_h323_ID:
03831             ooH323EpAddAliasH323ID(pNewAlias->value);
03832             break;
03833          case T_H225AliasAddress_dialedDigits:  
03834             ooH323EpAddAliasDialedDigits(pNewAlias->value);
03835             break;
03836          case T_H225AliasAddress_email_ID:   
03837             ooH323EpAddAliasEmailID(pNewAlias->value);
03838             break;
03839          default:
03840             ;
03841          }
03842       }
03843 
03844       ast_mutex_lock(&peerl.lock);
03845       peer = peerl.peers;
03846       while (peer) {
03847          if(peer->h323id) ooH323EpAddAliasH323ID(peer->h323id);
03848          if(peer->email)  ooH323EpAddAliasEmailID(peer->email);
03849          if(peer->e164)   ooH323EpAddAliasDialedDigits(peer->e164);
03850                if(peer->url)    ooH323EpAddAliasURLID(peer->url);
03851          peer = peer->next;
03852       }
03853       ast_mutex_unlock(&peerl.lock);
03854    
03855 
03856       if (gMediaWaitForConnect)
03857          ooH323EpEnableMediaWaitForConnect();
03858       else 
03859          ooH323EpDisableMediaWaitForConnect();
03860 
03861       /* Fast start and tunneling options */
03862       if (gFastStart)
03863          ooH323EpEnableFastStart();
03864       else
03865          ooH323EpDisableFastStart();
03866 
03867       if (!gTunneling)
03868          ooH323EpDisableH245Tunneling();
03869 
03870       if (gBeMaster)
03871          ooH323EpTryBeMaster(1);
03872 
03873             ooH323EpEnableManualRingback();
03874 
03875       /* Gatekeeper */
03876       if (gRasGkMode == RasUseSpecificGatekeeper)
03877          ooGkClientInit(gRasGkMode, gGatekeeper, 0);
03878       else if (gRasGkMode == RasDiscoverGatekeeper)
03879          ooGkClientInit(gRasGkMode, 0, 0);
03880 
03881       /* Register callbacks */
03882       ooH323EpSetH323Callbacks(h323Callbacks);
03883 
03884       /* Add endpoint capabilities */
03885       if (ooh323c_set_capability(gCap, gDTMFMode, gDTMFCodec) < 0) {
03886          ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n");
03887          ao2_ref(gCap, -1);
03888          gCap = NULL;
03889          ao2_ref(ooh323_tech.capabilities, -1);
03890          ooh323_tech.capabilities = NULL;
03891          return 1;
03892       }
03893   
03894       /* Create H.323 listener */
03895       if (ooCreateH323Listener() != OO_OK) {
03896                ast_log(LOG_ERROR, "OOH323 Listener Creation failure. "
03897                             "OOH323 DISABLED\n");
03898       
03899          ooH323EpDestroy();
03900          ao2_ref(gCap, -1);
03901          gCap = NULL;
03902          ao2_ref(ooh323_tech.capabilities, -1);
03903          ooh323_tech.capabilities = NULL;
03904          return 1;
03905       }
03906 
03907       if (ooh323c_start_stack_thread() < 0) {
03908          ast_log(LOG_ERROR, "Failed to start OOH323 stack thread. "
03909                             "OOH323 DISABLED\n");
03910          ooH323EpDestroy();
03911          ao2_ref(gCap, -1);
03912          gCap = NULL;
03913          ao2_ref(ooh323_tech.capabilities, -1);
03914          ooh323_tech.capabilities = NULL;
03915          return 1;
03916       }
03917       /* And start the monitor for the first time */
03918       restart_monitor();
03919    } else {
03920       ast_log(LOG_ERROR, "Can't load ooh323 config file, OOH323 Disabled\n");
03921       return AST_MODULE_LOAD_DECLINE;
03922    }
03923 
03924    return 0;
03925 }

int onAlerting ( ooCallData *  call  ) 

Definition at line 1639 of file chan_ooh323.c.

References ast_channel_queue_connected_line_update(), ast_channel_trylock, ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_RINGING, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_party_connected_line_init(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verb, c, DEADLOCK_AVOIDANCE, find_call, gH323Debug, ast_party_connected_line::id, ast_set_party_connected_line::id, ooh323_pvt::lock, LOG_ERROR, ast_party_id::name, ast_set_party_id::name, NULL, ooh323_pvt::owner, ast_party_connected_line::source, ast_party_name::str, and ast_party_name::valid.

Referenced by load_module().

01640 {
01641    struct ooh323_pvt *p = NULL;
01642    struct ast_channel *c = NULL;
01643 
01644    if (gH323Debug)
01645       ast_verb(0, "--- onAlerting %s\n", call->callToken);
01646 
01647       p = find_call(call);
01648 
01649       if(!p) {
01650       ast_log(LOG_ERROR, "No matching call found\n");
01651       return -1;
01652    }  
01653    ast_mutex_lock(&p->lock);
01654    if (!p->owner) {
01655       ast_mutex_unlock(&p->lock);
01656       ast_debug(1, "Channel has no owner\n");
01657       return 0;
01658    }
01659    while (p->owner && ast_channel_trylock(p->owner)) {
01660       ast_debug(1, "Failed to grab lock, trying again\n");
01661       DEADLOCK_AVOIDANCE(&p->lock);
01662    }
01663    if (!p->owner) {
01664       ast_mutex_unlock(&p->lock);
01665       ast_log(LOG_ERROR, "Channel has no owner\n");
01666       return 0;
01667    }
01668    c = p->owner;
01669 
01670    if (call->remoteDisplayName) {
01671       struct ast_party_connected_line connected;
01672       struct ast_set_party_connected_line update_connected;
01673 
01674       memset(&update_connected, 0, sizeof(update_connected));
01675       update_connected.id.name = 1;
01676       ast_party_connected_line_init(&connected);
01677       connected.id.name.valid = 1;
01678       connected.id.name.str = (char *) call->remoteDisplayName;
01679       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
01680       ast_channel_queue_connected_line_update(c, &connected, &update_connected);
01681    }
01682    if (ast_channel_state(c) != AST_STATE_UP)
01683       ast_setstate(c, AST_STATE_RINGING);
01684 
01685    ast_queue_control(c, AST_CONTROL_RINGING);
01686          ast_channel_unlock(c);
01687          ast_mutex_unlock(&p->lock);
01688 
01689    if (gH323Debug)
01690       ast_verb(0, "+++ onAlerting %s\n", call->callToken);
01691 
01692    return OO_OK;
01693 }

int onCallCleared ( ooCallData *  call  ) 

Definition at line 2193 of file chan_ooh323.c.

References ast_channel_hangupcause_set(), ast_channel_softhangup_internal_flag_add(), ast_channel_tech_pvt_set(), ast_channel_trylock, ast_channel_unlock, ast_cond_signal, ast_debug, ast_module_unref, ast_mutex_lock, ast_mutex_unlock, ast_queue_hangup_with_cause(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, ast_verb, DEADLOCK_AVOIDANCE, find_call, gH323Debug, H323_ALREADYGONE, H323_NEEDDESTROY, ooh323_pvt::lock, NULL, ooh323c_stop_call_thread(), ooh323_pvt::owner, ooh323_pvt::rtp, ooh323_pvt::rtpcond, usecnt, and usecnt_lock.

Referenced by load_module().

02194 {
02195    struct ooh323_pvt *p = NULL;
02196    int ownerLock = 0;
02197 
02198    if (gH323Debug)
02199       ast_verb(0, "---   onCallCleared %s \n", call->callToken);
02200 
02201 
02202    if ((p = find_call(call))) {
02203    ast_mutex_lock(&p->lock);
02204   
02205    while (p->owner) {
02206       if (ast_channel_trylock(p->owner)) {
02207          ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n");
02208                ast_debug(1, "Failed to grab lock, trying again\n");
02209          DEADLOCK_AVOIDANCE(&p->lock);
02210       } else {
02211                ownerLock = 1; break;
02212       }
02213    }
02214 
02215    if (ownerLock) {
02216       if (!ast_test_flag(p, H323_ALREADYGONE)) { 
02217 
02218          ast_set_flag(p, H323_ALREADYGONE);
02219          ast_channel_hangupcause_set(p->owner, call->q931cause);
02220          ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
02221          ast_queue_hangup_with_cause(p->owner,call->q931cause);
02222       }
02223       }
02224 
02225       if(p->owner) {
02226          ast_channel_tech_pvt_set(p->owner, NULL);
02227       ast_channel_unlock(p->owner);
02228          p->owner = NULL;
02229       ast_module_unref(myself);
02230    }
02231 
02232    if (!p->rtp) {
02233       ast_cond_signal(&p->rtpcond);
02234    }
02235 
02236    ast_set_flag(p, H323_NEEDDESTROY);
02237 
02238       ooh323c_stop_call_thread(call);
02239 
02240    ast_mutex_unlock(&p->lock);
02241       ast_mutex_lock(&usecnt_lock);
02242       usecnt--;
02243       ast_mutex_unlock(&usecnt_lock);
02244 
02245     }
02246 
02247    if (gH323Debug)
02248       ast_verb(0, "+++   onCallCleared\n");
02249 
02250    return OO_OK;
02251 }

int onCallEstablished ( ooCallData *  call  ) 

Definition at line 2138 of file chan_ooh323.c.

References ast_channel_queue_connected_line_update(), ast_channel_trylock, ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_ANSWER, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_party_connected_line_init(), ast_publish_channel_state(), ast_queue_control(), ast_test_flag, ast_verb, c, DEADLOCK_AVOIDANCE, find_call, gH323Debug, H323_OUTGOING, ast_party_connected_line::id, ast_set_party_connected_line::id, ooh323_pvt::lock, LOG_ERROR, ast_party_id::name, ast_set_party_id::name, NULL, ooh323_pvt::owner, ast_party_connected_line::source, ast_party_name::str, and ast_party_name::valid.

Referenced by load_module().

02139 {
02140    struct ooh323_pvt *p = NULL;
02141 
02142    if (gH323Debug)
02143       ast_verb(0, "---   onCallEstablished %s\n", call->callToken);
02144 
02145 
02146    if (!(p = find_call(call))) {
02147       ast_log(LOG_ERROR, "Failed to find a matching call.\n");
02148       return -1;
02149    }
02150 
02151       if(ast_test_flag(p, H323_OUTGOING)) {
02152       ast_mutex_lock(&p->lock);
02153       if (!p->owner) {
02154          ast_mutex_unlock(&p->lock);
02155          ast_log(LOG_ERROR, "Channel has no owner\n");
02156          return -1;
02157       }
02158    
02159       while (p->owner && ast_channel_trylock(p->owner)) {
02160          ast_debug(1, "Failed to grab lock, trying again\n");
02161          DEADLOCK_AVOIDANCE(&p->lock);
02162       }
02163       if (p->owner) {
02164          struct ast_channel* c = p->owner;
02165 
02166          if (call->remoteDisplayName) {
02167             struct ast_party_connected_line connected;
02168             struct ast_set_party_connected_line update_connected;
02169 
02170             memset(&update_connected, 0, sizeof(update_connected));
02171             update_connected.id.name = 1;
02172             ast_party_connected_line_init(&connected);
02173             connected.id.name.valid = 1;
02174             connected.id.name.str = (char *) call->remoteDisplayName;
02175             connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
02176             ast_channel_queue_connected_line_update(c, &connected, &update_connected);
02177          }
02178 
02179          ast_queue_control(c, AST_CONTROL_ANSWER);
02180          ast_publish_channel_state(c);
02181          ast_channel_unlock(p->owner);
02182       }
02183       ast_mutex_unlock(&p->lock);
02184 
02185    }
02186 
02187    if (gH323Debug)
02188       ast_verb(0, "+++   onCallEstablished %s\n", call->callToken);
02189 
02190    return OO_OK;
02191 }

void onModeChanged ( ooCallData *  call,
int  t38mode 
)

Definition at line 5023 of file chan_ooh323.c.

References ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_macrocontext(), ast_channel_name(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_T38_PARAMETERS, ast_debug, ast_exists_extension(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_queue_control_data(), AST_T38_RATE_14400, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_TERMINATE, ast_udptl_get_far_max_ifp(), ast_udptl_set_far_max_datagram(), ast_verb, ooh323_pvt::chmodepend, DEADLOCK_AVOIDANCE, ooh323_pvt::faxdetect, FAXDETECT_T38, ooh323_pvt::faxdetected, ooh323_pvt::faxmode, find_call, gH323Debug, ast_party_caller::id, ooh323_pvt::lock, LOG_ERROR, LOG_NOTICE, ast_control_t38_parameters::max_ifp, NULL, ast_party_id::number, ooh323_pvt::owner, pbx_builtin_setvar_helper(), ast_control_t38_parameters::rate, ast_control_t38_parameters::request_response, S_COR, S_OR, ast_party_number::str, T38_ENABLED, ooh323_pvt::t38_init, ooh323_pvt::t38support, ooh323_pvt::udptl, ast_party_number::valid, and ast_control_t38_parameters::version.

Referenced by load_module().

05023                                                   {
05024         struct ooh323_pvt *p;
05025 
05026    p = find_call(call);
05027    if (!p) {
05028       ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
05029       return;
05030    }
05031 
05032    ast_mutex_lock(&p->lock);
05033 
05034    if (gH323Debug)
05035             ast_debug(1, "change mode to %d for %s\n", t38mode, call->callToken);
05036 
05037    if (t38mode == p->faxmode) {
05038       if (gH323Debug)
05039          ast_debug(1, "mode for %s is already %d\n", call->callToken,
05040                t38mode);
05041       p->chmodepend = 0;
05042       ast_mutex_unlock(&p->lock);
05043       return;
05044    }
05045 
05046    if (p->owner) {
05047       while (p->owner && ast_channel_trylock(p->owner)) {
05048          ast_debug(1,"Failed to grab lock, trying again\n");
05049          DEADLOCK_AVOIDANCE(&p->lock);
05050       }
05051       if (!p->owner) {
05052          p->chmodepend = 0;
05053          ast_mutex_unlock(&p->lock);
05054          ast_log(LOG_ERROR, "Channel has no owner\n");
05055          return;
05056       }
05057    } else {
05058       p->chmodepend = 0;
05059       ast_mutex_unlock(&p->lock);
05060       ast_log(LOG_ERROR, "Channel has no owner\n");
05061       return;
05062    }
05063 
05064    if (t38mode) {
05065 
05066 
05067       if (p->t38support == T38_ENABLED) {
05068          struct ast_control_t38_parameters parameters = { .request_response = 0 };
05069 
05070          if ((p->faxdetect & FAXDETECT_T38) && !p->faxdetected) {
05071                            const char *target_context;
05072             ast_debug(1, "* Detected T.38 Request\n");
05073             target_context = S_OR(ast_channel_macrocontext(p->owner), ast_channel_context(p->owner));
05074                            if ((strcmp(ast_channel_exten(p->owner), "fax")) &&
05075                                  (ast_exists_extension(p->owner, target_context, "fax", 1,
05076                                  S_COR(ast_channel_caller(p->owner)->id.number.valid, ast_channel_caller(p->owner)->id.number.str, NULL)))) {
05077                                  ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n", ast_channel_name(p->owner));
05078                                  pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", ast_channel_exten(p->owner));
05079                                  if (ast_async_goto(p->owner, target_context, "fax", 1)) {
05080                                           ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(p->owner),target_context);
05081                }
05082                                 }
05083                                 p->faxdetected = 1;
05084          }
05085 
05086 /* AST_T38_CONTROL mode */
05087 
05088          parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
05089          if (call->T38FarMaxDatagram) {
05090             ast_udptl_set_far_max_datagram(p->udptl, call->T38FarMaxDatagram);
05091          } else {
05092             ast_udptl_set_far_max_datagram(p->udptl, 144);
05093          }
05094          if (call->T38Version) {
05095             parameters.version = call->T38Version;
05096          }
05097          parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
05098          parameters.rate = AST_T38_RATE_14400;
05099          ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, 
05100                      &parameters, sizeof(parameters));
05101          p->faxmode = 1;
05102 
05103 
05104       }
05105    } else {
05106       if (p->t38support == T38_ENABLED) {
05107          struct ast_control_t38_parameters parameters = { .request_response = 0 };
05108          parameters.request_response = AST_T38_REQUEST_TERMINATE;
05109          parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
05110          parameters.rate = AST_T38_RATE_14400;
05111          ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, 
05112                      &parameters, sizeof(parameters));
05113       }
05114       p->faxmode = 0;
05115       p->faxdetected = 0;
05116       p->t38_init = 0;
05117    }
05118 
05119    p->chmodepend = 0;
05120    ast_channel_unlock(p->owner);
05121    ast_mutex_unlock(&p->lock);
05122 }

int onNewCallCreated ( ooCallData *  call  ) 

Definition at line 2046 of file chan_ooh323.c.

References ast_cond_signal, ast_format_cap_get_names(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_str_alloca, ast_strlen_zero, ast_verb, ooh323_pvt::caller_dialedDigits, ooh323_pvt::caller_h323id, ooh323_pvt::callerid_name, ooh323_pvt::callerid_num, ooh323_pvt::cap, configure_local_rtp(), ooh323_pvt::dtmfcodec, ooh323_pvt::dtmfmode, ooh323_pvt::exten, find_call, ooh323_pvt::g729onlyA, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, ooh323c_set_capability_for_call(), ooh323c_start_call_thread(), ooh323_pvt::rtpcond, ooh323_pvt::t38support, and ooh323_pvt::username.

Referenced by load_module().

02047 {
02048    struct ooh323_pvt *p = NULL;
02049    int i = 0;
02050 
02051    if (gH323Debug)
02052       ast_verb(0, "---   onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken);
02053 
02054       ast_mutex_lock(&call->Lock);
02055       if (ooh323c_start_call_thread(call)) {
02056          ast_log(LOG_ERROR,"Failed to create call thread.\n");
02057          ast_mutex_unlock(&call->Lock);
02058          return -1;
02059       }
02060 
02061    if (!strcmp(call->callType, "outgoing")) {
02062       p = find_call(call);
02063       if (!p) {
02064                ast_log(LOG_ERROR, "Failed to find a matching call.\n");
02065          ast_mutex_unlock(&call->Lock);
02066          return -1;
02067       }
02068       ast_mutex_lock(&p->lock);
02069 
02070       if (!ast_strlen_zero(p->callerid_name)) {
02071          ooCallSetCallerId(call, p->callerid_name);
02072       }
02073       if (!ast_strlen_zero(p->callerid_num)) {
02074          i = 0;
02075          while (*(p->callerid_num + i) != '\0') {
02076                      if(!isdigit(*(p->callerid_num+i))) { break; }
02077             i++;
02078          }
02079                if(*(p->callerid_num+i) == '\0')
02080             ooCallSetCallingPartyNumber(call, p->callerid_num);
02081                else {
02082                      if(ast_strlen_zero(p->callerid_name))
02083                ooCallSetCallerId(call, p->callerid_num);
02084          }
02085       }
02086       
02087       if (!ast_strlen_zero(p->caller_h323id))
02088          ooCallAddAliasH323ID(call, p->caller_h323id);
02089 
02090       if (!ast_strlen_zero(p->caller_dialedDigits)) {
02091          if (gH323Debug) {
02092             ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
02093          }
02094          ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
02095       } else if (!ast_strlen_zero(p->callerid_num)) {
02096          if (ooIsDailedDigit(p->callerid_num)) {
02097             if (gH323Debug) {
02098                ast_verb(0, "setting callid number %s\n", p->callerid_num);
02099             }
02100             ooCallAddAliasDialedDigits(call, p->callerid_num);
02101          } else if (ast_strlen_zero(p->caller_h323id)) {
02102             ooCallAddAliasH323ID(call, p->callerid_num);
02103          }
02104       }
02105   
02106 
02107       if (!ast_strlen_zero(p->exten))  {
02108          if (ooIsDailedDigit(p->exten)) {
02109             ooCallSetCalledPartyNumber(call, p->exten);
02110             ooCallAddRemoteAliasDialedDigits(call, p->exten);
02111          } else {
02112            ooCallAddRemoteAliasH323ID(call, p->exten);
02113          }
02114       }
02115 
02116       if (gH323Debug) {
02117          struct ast_str *codec_buf = ast_str_alloca(64);
02118 
02119          ast_verb(0, " Outgoing call %s(%s) - Codec prefs - %s\n", 
02120             p->username?p->username:"NULL", call->callToken,
02121             ast_format_cap_get_names(p->cap, &codec_buf));
02122       }
02123 
02124             ooh323c_set_capability_for_call(call, p->cap,
02125                                      p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA);
02126 
02127       configure_local_rtp(p, call);
02128       ast_cond_signal(&p->rtpcond);
02129       ast_mutex_unlock(&p->lock);
02130    }
02131 
02132       ast_mutex_unlock(&call->Lock);
02133    if (gH323Debug)
02134       ast_verb(0, "+++   onNewCallCreated %s\n", call->callToken);
02135    return OO_OK;
02136 }

int onOutgoingCall ( ooCallData *  call  ) 

Definition at line 1973 of file chan_ooh323.c.

References ast_copy_string(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero, ast_verb, ooh323_pvt::caller_dialedDigits, ooh323_pvt::caller_h323id, ooh323_pvt::callerid_name, ooh323_pvt::callerid_num, configure_local_rtp(), find_call, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, ooh323_pvt::rtp, ooh323_pvt::rtpmask, and ooh323_pvt::rtpmaskstr.

Referenced by load_module().

01974 {
01975    struct ooh323_pvt *p = NULL;
01976    int i = 0;
01977 
01978    if (gH323Debug)
01979       ast_verb(0, "---   onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken);
01980 
01981    if (!strcmp(call->callType, "outgoing")) {
01982       p = find_call(call);
01983       if (!p) {
01984                ast_log(LOG_ERROR, "Failed to find a matching call.\n");
01985          return -1;
01986       }
01987       ast_mutex_lock(&p->lock);
01988 
01989       if (!ast_strlen_zero(p->callerid_name)) {
01990          ooCallSetCallerId(call, p->callerid_name);
01991       }
01992       if (!ast_strlen_zero(p->callerid_num)) {
01993          i = 0;
01994          while (*(p->callerid_num + i) != '\0') {
01995                      if(!isdigit(*(p->callerid_num+i))) { break; }
01996             i++;
01997          }
01998                if(*(p->callerid_num+i) == '\0')
01999             ooCallSetCallingPartyNumber(call, p->callerid_num);
02000                else {
02001                      if(!p->callerid_name)
02002                ooCallSetCallerId(call, p->callerid_num);
02003          }
02004       }
02005       
02006       if (!ast_strlen_zero(p->caller_h323id))
02007          ooCallAddAliasH323ID(call, p->caller_h323id);
02008 
02009       if (!ast_strlen_zero(p->caller_dialedDigits)) {
02010          if (gH323Debug) {
02011             ast_verb(0, "Setting dialed digits %s\n", p->caller_dialedDigits);
02012          }
02013          ooCallAddAliasDialedDigits(call, p->caller_dialedDigits);
02014       } else if (!ast_strlen_zero(p->callerid_num)) {
02015          if (ooIsDailedDigit(p->callerid_num)) {
02016             if (gH323Debug) {
02017                ast_verb(0, "setting callid number %s\n", p->callerid_num);
02018             }
02019             ooCallAddAliasDialedDigits(call, p->callerid_num);
02020          } else if (ast_strlen_zero(p->caller_h323id)) {
02021             ooCallAddAliasH323ID(call, p->callerid_num);
02022          }
02023       }
02024       if (p->rtpmask && p->rtpmaskstr[0]) {
02025          call->rtpMask = p->rtpmask;
02026          ast_mutex_lock(&call->rtpMask->lock);
02027          call->rtpMask->inuse++;
02028          ast_mutex_unlock(&call->rtpMask->lock);
02029          ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
02030       }
02031 
02032       if (!p->rtp && !configure_local_rtp(p, call)) {
02033          ast_mutex_unlock(&p->lock);
02034          return OO_FAILED;
02035       }
02036 
02037       ast_mutex_unlock(&p->lock);
02038    }
02039 
02040    if (gH323Debug)
02041       ast_verb(0, "+++   onOutgoingCall %s\n", call->callToken);
02042    return OO_OK;
02043 }

int onProgress ( ooCallData *  call  ) 

Definition at line 1695 of file chan_ooh323.c.

References ast_channel_queue_connected_line_update(), ast_channel_trylock, ast_channel_unlock, AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER, AST_CONTROL_PROGRESS, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_party_connected_line_init(), ast_queue_control(), ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_verb, c, DEADLOCK_AVOIDANCE, find_call, gH323Debug, ast_party_connected_line::id, ast_set_party_connected_line::id, ooh323_pvt::lock, LOG_ERROR, ast_party_id::name, ast_set_party_id::name, NULL, ooh323_pvt::owner, ast_party_connected_line::source, ast_party_name::str, and ast_party_name::valid.

Referenced by load_module().

01696 {
01697    struct ooh323_pvt *p = NULL;
01698    struct ast_channel *c = NULL;
01699 
01700    if (gH323Debug)
01701       ast_verb(0, "--- onProgress %s\n", call->callToken);
01702 
01703       p = find_call(call);
01704 
01705       if(!p) {
01706       ast_log(LOG_ERROR, "No matching call found\n");
01707       return -1;
01708    }  
01709    ast_mutex_lock(&p->lock);
01710    if (!p->owner) {
01711       ast_mutex_unlock(&p->lock);
01712       ast_log(LOG_ERROR, "Channel has no owner\n");
01713       return 0;
01714    }
01715    while (p->owner && ast_channel_trylock(p->owner)) {
01716       ast_debug(1, "Failed to grab lock, trying again\n");
01717       DEADLOCK_AVOIDANCE(&p->lock);
01718    }
01719    if (!p->owner) {
01720       ast_mutex_unlock(&p->lock);
01721       ast_log(LOG_ERROR, "Channel has no owner\n");
01722       return 0;
01723    }
01724    c = p->owner;
01725 
01726    if (call->remoteDisplayName) {
01727       struct ast_party_connected_line connected;
01728       struct ast_set_party_connected_line update_connected;
01729 
01730       memset(&update_connected, 0, sizeof(update_connected));
01731       update_connected.id.name = 1;
01732       ast_party_connected_line_init(&connected);
01733       connected.id.name.valid = 1;
01734       connected.id.name.str = (char *) call->remoteDisplayName;
01735       connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
01736       ast_channel_queue_connected_line_update(c, &connected, &update_connected);
01737    }
01738    if (ast_channel_state(c) != AST_STATE_UP)
01739       ast_setstate(c, AST_STATE_RINGING);
01740 
01741    ast_queue_control(c, AST_CONTROL_PROGRESS);
01742          ast_channel_unlock(c);
01743          ast_mutex_unlock(&p->lock);
01744 
01745    if (gH323Debug)
01746       ast_verb(0, "+++ onProgress %s\n", call->callToken);
01747 
01748    return OO_OK;
01749 }

static struct ooh323_pvt* ooh323_alloc ( int  callref,
char *  callToken 
) [static, read]

Definition at line 507 of file chan_ooh323.c.

References ooh323_pvt::accountcode, ooh323_pvt::amaflags, ooh323_pvt::aniasdni, ast_calloc, ast_copy_string(), ast_format_cap_alloc, ast_format_cap_append_from_cap(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_free, ast_log, AST_MEDIA_TYPE_UNKNOWN, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_strdup, ast_verb, ooh323_pvt::call_reference, ooh323_pvt::callToken, ooh323_pvt::cap, ooh323_pvt::chmodepend, ooh323_pvt::context, ooh323_pvt::dtmfcodec, ooh323_pvt::dtmfmode, ooh323_pvt::faxdetect, ooh323_pvt::faxdetected, ooh323_pvt::faxmode, ooh323_pvt::flags, g729onlyA, ooh323_pvt::g729onlyA, gAccountcode, gAMAFLAGS, gANIasDNI, gContext, gDTMFCodec, gDTMFMode, gFAXdetect, gH323Debug, gNat, gRasGkMode, gRTDRCount, gRTDRInterval, gRTPTimeout, gT38Support, H323_DISABLEGK, iflist, iflock, ooh323_pvt::lock, LOG_ERROR, ooh323_pvt::nat, ooh323_pvt::next, NULL, ooh323_pvt::rtdrcount, ooh323_pvt::rtdrinterval, ooh323_pvt::rtptimeout, and ooh323_pvt::t38support.

Referenced by ooh323_onReceivedSetup(), and ooh323_request().

00508 {
00509    struct ooh323_pvt *pvt = NULL;
00510 
00511    if (gH323Debug) {
00512       ast_verb(0, "---   ooh323_alloc\n");
00513    }
00514 
00515    if (!(pvt = ast_calloc(1, sizeof(*pvt)))) {
00516       ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
00517       return NULL;
00518    }
00519    if (!(pvt->cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
00520       ast_free(pvt);
00521       ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
00522       return NULL;
00523    }
00524 
00525    ast_mutex_init(&pvt->lock);
00526    ast_mutex_lock(&pvt->lock);
00527 
00528    pvt->faxmode = 0;
00529    pvt->chmodepend = 0;
00530    pvt->faxdetected = 0;
00531    pvt->faxdetect = gFAXdetect;
00532    pvt->t38support = gT38Support;
00533    pvt->rtptimeout = gRTPTimeout;
00534    pvt->nat = gNat;
00535    pvt->rtdrinterval = gRTDRInterval;
00536    pvt->rtdrcount = gRTDRCount;
00537    pvt->g729onlyA = g729onlyA;
00538 
00539    pvt->call_reference = callref;
00540    if (callToken)
00541       pvt->callToken = ast_strdup(callToken);
00542 
00543    /* whether to use gk for this call */
00544    if (gRasGkMode == RasNoGatekeeper)
00545       OO_SETFLAG(pvt->flags, H323_DISABLEGK);
00546 
00547    pvt->dtmfmode = gDTMFMode;
00548    pvt->dtmfcodec = gDTMFCodec;
00549    ast_copy_string(pvt->context, gContext, sizeof(pvt->context));
00550    ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
00551 
00552    pvt->amaflags = gAMAFLAGS;
00553    ast_format_cap_append_from_cap(pvt->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
00554 
00555    pvt->aniasdni = gANIasDNI;
00556 
00557    ast_mutex_unlock(&pvt->lock); 
00558    /* Add to interface list */
00559    ast_mutex_lock(&iflock);
00560    pvt->next = iflist;
00561    iflist = pvt;
00562    ast_mutex_unlock(&iflock);
00563 
00564    if (gH323Debug) {
00565       ast_verb(0, "+++   ooh323_alloc\n");
00566    }
00567 
00568    return pvt;
00569 }

static int ooh323_answer ( struct ast_channel ast  )  [static]

Definition at line 1105 of file chan_ooh323.c.

References ooh323_pvt::alertsent, ast_channel_lock, ast_channel_name(), ast_channel_tech_pvt(), ast_channel_unlock, ast_debug, ast_free, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_UP, ast_strdup, ast_verb, ooh323_pvt::callToken, gH323Debug, ooh323_pvt::lock, NULL, and option_debug.

01106 {
01107    struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
01108    char *callToken = (char *)NULL;
01109 
01110    if (gH323Debug)
01111       ast_verb(0, "--- ooh323_answer\n");
01112 
01113    if (p) {
01114 
01115       ast_mutex_lock(&p->lock);
01116       callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
01117       if (ast_channel_state(ast) != AST_STATE_UP) {
01118          ast_channel_lock(ast);
01119          if (!p->alertsent) {
01120                if (gH323Debug) {
01121                ast_debug(1, "Sending forced ringback for %s, res = %u\n", 
01122                   callToken, ooManualRingback(callToken));
01123             } else {
01124                   ooManualRingback(callToken);
01125             }
01126             p->alertsent = 1;
01127          }
01128          ast_setstate(ast, AST_STATE_UP);
01129                if (option_debug)
01130             ast_debug(1, "ooh323_answer(%s)\n", ast_channel_name(ast));
01131          ast_channel_unlock(ast);
01132          ooAnswerCall(p->callToken);
01133       }
01134       if (callToken) {
01135          ast_free(callToken);
01136       }
01137       ast_mutex_unlock(&p->lock);
01138    }
01139 
01140    if (gH323Debug)
01141       ast_verb(0, "+++ ooh323_answer\n");
01142 
01143   return 0;
01144 }

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

Definition at line 941 of file chan_ooh323.c.

References ast_channel_connected(), ast_channel_name(), ast_channel_tech_pvt(), ast_channel_transfercapability(), ast_copy_string(), ast_free, ast_log, AST_MAX_EXTENSION, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdup, ast_verb, ooh323_pvt::caller_dialedDigits, ooh323_pvt::caller_email, ooh323_pvt::caller_h323id, ooh323_pvt::caller_url, ooh323_pvt::callerid_name, ooh323_pvt::callerid_num, ooh323_pvt::callToken, ooh323_pvt::faststart, ooh323_pvt::flags, gCallerID, gH323Debug, ooh323_pvt::h245tunneling, H323_DISABLEGK, H323_OUTGOING, ooh323_pvt::host, ast_party_connected_line::id, ooh323_pvt::lock, LOG_ERROR, LOG_WARNING, ast_party_id::name, name, NULL, pbx_builtin_getvar_helper(), ooh323_pvt::port, ast_party_name::str, TRUE, and ast_party_name::valid.

00942 {
00943    struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
00944    char destination[256];
00945       int res=0, i;
00946    const char *val = NULL;
00947    ooCallOptions opts = {
00948       .fastStart = TRUE,
00949       .tunneling = TRUE,
00950       .disableGk = TRUE,
00951             .callMode = OO_CALLMODE_AUDIOCALL,
00952             .transfercap = 0
00953    };
00954 
00955    if (gH323Debug)
00956       ast_verb(0, "---   ooh323_call- %s\n", dest);
00957 
00958 
00959       if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
00960       ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "
00961                         "reserved\n", ast_channel_name(ast));
00962       return -1;
00963    }
00964    ast_mutex_lock(&p->lock);
00965    ast_set_flag(p, H323_OUTGOING);
00966    if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
00967       ast_free(p->callerid_num);
00968       p->callerid_num = ast_strdup(ast_channel_connected(ast)->id.number.str);
00969    }
00970 
00971    if (ast_channel_connected(ast)->id.name.valid && ast_channel_connected(ast)->id.name.str) {
00972       ast_free(p->callerid_name);
00973       p->callerid_name = ast_strdup(ast_channel_connected(ast)->id.name.str);
00974    } else if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {
00975       ast_free(p->callerid_name);
00976       p->callerid_name = ast_strdup(ast_channel_connected(ast)->id.number.str);
00977    } else {
00978       ast_channel_connected(ast)->id.name.valid = 1;
00979       ast_free(ast_channel_connected(ast)->id.name.str);
00980       ast_channel_connected(ast)->id.name.str = ast_strdup(gCallerID);
00981       ast_free(p->callerid_name);
00982       p->callerid_name = ast_strdup(ast_channel_connected(ast)->id.name.str);
00983    }
00984 
00985    /* Retrieve vars */
00986 
00987 
00988    if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) {
00989       ast_copy_string(p->caller_h323id, val, sizeof(p->caller_h323id));
00990    }
00991    
00992    if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) {
00993       ast_copy_string(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits));
00994             if(!p->callerid_num)
00995          p->callerid_num = ast_strdup(val);
00996    }
00997 
00998    if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) {
00999       ast_copy_string(p->caller_email, val, sizeof(p->caller_email));
01000    }
01001 
01002    if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) {
01003       ast_copy_string(p->caller_url, val, sizeof(p->caller_url));
01004    }
01005 
01006    if (p->host && p->port != 0)
01007       snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port);
01008    else if (p->host)
01009       snprintf(destination, sizeof(destination), "%s", p->host);
01010    else
01011       ast_copy_string(destination, dest, sizeof(destination));
01012 
01013    destination[sizeof(destination)-1]='\0';
01014 
01015    opts.transfercap = ast_channel_transfercapability(ast);
01016    opts.fastStart = p->faststart;
01017    opts.tunneling = p->h245tunneling;
01018 
01019    for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000);
01020 
01021    if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) {
01022       res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);
01023    } else {
01024       res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);
01025    }
01026 
01027    ast_mutex_unlock(&p->lock);
01028    if (res != OO_OK) {
01029       ast_log(LOG_ERROR, "Failed to make call\n");
01030             return -1; /* ToDO: cleanup */
01031    }
01032    if (gH323Debug)
01033       ast_verb(0, "+++   ooh323_call\n");
01034 
01035   return 0;
01036 }

int ooh323_convert_hangupcause_asteriskToH323 ( int  cause  ) 

Definition at line 5126 of file chan_ooh323.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_FAILURE, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL, and AST_CAUSE_UNALLOCATED.

Referenced by ooh323_hangup(), and ooh323_onReceivedSetup().

05127 {
05128    switch (cause) {
05129    case AST_CAUSE_CALL_REJECTED:
05130       return OO_REASON_REMOTE_REJECTED;
05131    case AST_CAUSE_UNALLOCATED:
05132       return OO_REASON_NOUSER;
05133    case AST_CAUSE_BUSY:
05134       return OO_REASON_REMOTE_BUSY;
05135    case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL:
05136       return OO_REASON_NOCOMMON_CAPABILITIES;
05137    case AST_CAUSE_CONGESTION:
05138       return OO_REASON_REMOTE_BUSY;
05139    case AST_CAUSE_NO_ANSWER:
05140       return OO_REASON_REMOTE_NOANSWER;
05141    case AST_CAUSE_NORMAL:
05142       return OO_REASON_REMOTE_CLEARED;
05143    case AST_CAUSE_FAILURE:
05144    default:
05145       return OO_REASON_UNKNOWN;
05146    }
05147 
05148    return 0;
05149 
05150 
05151 }

int ooh323_convert_hangupcause_h323ToAsterisk ( int  cause  ) 

Definition at line 5153 of file chan_ooh323.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_FAILURE, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL, and AST_CAUSE_UNALLOCATED.

05154 {
05155    switch (cause) {
05156    case OO_REASON_REMOTE_REJECTED:
05157       return AST_CAUSE_CALL_REJECTED;
05158    case OO_REASON_NOUSER: 
05159       return AST_CAUSE_UNALLOCATED;
05160    case OO_REASON_REMOTE_BUSY:
05161    case OO_REASON_LOCAL_BUSY:
05162       return AST_CAUSE_BUSY;
05163    case OO_REASON_NOCOMMON_CAPABILITIES:  /* No codecs approved */
05164       return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05165    case OO_REASON_REMOTE_CONGESTED:
05166    case OO_REASON_LOCAL_CONGESTED:
05167       return AST_CAUSE_CONGESTION;
05168    case OO_REASON_REMOTE_NOANSWER:
05169       return AST_CAUSE_NO_ANSWER;
05170    case OO_REASON_UNKNOWN: 
05171    case OO_REASON_INVALIDMESSAGE:
05172    case OO_REASON_TRANSPORTFAILURE:
05173       return AST_CAUSE_FAILURE;
05174    case OO_REASON_REMOTE_CLEARED:
05175       return AST_CAUSE_NORMAL;
05176    default:
05177       return AST_CAUSE_NORMAL;
05178    }
05179    /* Never reached */
05180    return 0;
05181 }

int ooh323_convertAsteriskCapToH323Cap ( struct ast_format format  ) 

Definition at line 4451 of file chan_ooh323.c.

References ast_format_alaw, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g723, ast_format_g726, ast_format_g726_aal2, ast_format_g729, ast_format_get_name(), ast_format_gsm, ast_format_h263, ast_format_speex, ast_format_ulaw, ast_log, and LOG_NOTICE.

Referenced by configure_local_rtp(), and ooh323_set_rtp_peer().

04452 {
04453    if (ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
04454       return OO_G711ULAW64K;
04455    } else if (ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
04456       return OO_G711ALAW64K;
04457    } else if (ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) {
04458       return OO_GSMFULLRATE;
04459    } else if (ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) {
04460       return OO_SPEEX;
04461    } else if (ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
04462       return OO_G729A;
04463    } else if (ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) {
04464       return OO_G726;
04465    } else if (ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) {
04466       return OO_G726AAL2;
04467    } else if (ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
04468       return OO_G7231;
04469    } else if (ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) {
04470       return OO_H263VIDEO;
04471    } else {
04472       ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_format_get_name(format));
04473       return -1;
04474    }
04475 }

void ooh323_delete_peer ( struct ooh323_peer peer  ) 

Definition at line 2285 of file chan_ooh323.c.

References ao2_cleanup, ast_free, ast_mutex_lock, ast_mutex_unlock, ast_verb, ooh323_peer::cap, ooh323_peer::e164, ooh323_peer::email, gH323Debug, ooh323_peer::h323id, ast_peer_list::lock, ooh323_peer::next, NULL, peerl, ast_peer_list::peers, and ooh323_peer::url.

Referenced by build_peer().

02286 {
02287    struct ooh323_peer *prev = NULL, *cur = NULL;
02288 
02289    if (gH323Debug)
02290       ast_verb(0, "---   ooh323_delete_peer\n");
02291 
02292    if (peer) { 
02293       cur = peerl.peers;
02294       ast_mutex_lock(&peerl.lock);
02295       while(cur) {
02296          if(cur==peer) break;
02297          prev = cur;
02298          cur = cur->next;
02299       }
02300 
02301       if (cur) {
02302          if(prev)
02303             prev->next = cur->next;
02304          else
02305             peerl.peers = cur->next;
02306          }
02307       ast_mutex_unlock(&peerl.lock);
02308 
02309       ast_free(peer->h323id);
02310       ast_free(peer->email);
02311       ast_free(peer->url);
02312       ast_free(peer->e164);
02313 
02314       ao2_cleanup(peer->cap);
02315       ast_free(peer);
02316    }  
02317 
02318    if (gH323Debug)
02319       ast_verb(0, "+++   ooh323_delete_peer\n");
02320 
02321 }

int ooh323_destroy ( struct ooh323_pvt p  ) 

Definition at line 4063 of file chan_ooh323.c.

References ao2_cleanup, ast_channel_name(), ast_channel_tech_pvt_set(), ast_channel_trylock, ast_channel_unlock, ast_debug, ast_dsp_free(), ast_free, ast_module_unref, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_destroy(), ast_test_flag, ast_udptl_destroy(), ast_verb, ooh323_pvt::callerid_name, DEADLOCK_AVOIDANCE, find_user(), gH323Debug, H323_OUTGOING, iflist, ooh323_user::inUse, ooh323_user::lock, ooh323_pvt::next, NULL, and ooh323_pvt::username.

Referenced by do_monitor(), ooh323_request(), and unload_module().

04064 {
04065    /* NOTE: Assumes iflock already acquired */
04066    struct ooh323_pvt *prev = NULL, *cur = NULL;
04067    struct ooh323_user *user = NULL;
04068 
04069    if (gH323Debug) {
04070       ast_verb(0, "---   ooh323_destroy \n");
04071 
04072       if (p)
04073          ast_verb(0, " Destroying %s\n", p->username);
04074    }
04075 
04076    cur = iflist;
04077    while (cur) {
04078       if (cur == p) { break; }
04079       prev = cur;
04080       cur = cur->next;
04081    }
04082 
04083    if (cur) {
04084       ast_mutex_lock(&cur->lock);
04085       if (prev)
04086          prev->next = cur->next;
04087       else
04088          iflist = cur->next;
04089 
04090       if (cur->callToken) {
04091          if (gH323Debug) 
04092             ast_verb(0, " Destroying %s\n", cur->callToken);
04093          ast_free(cur->callToken);
04094          cur->callToken = 0;
04095       }
04096 
04097       if (cur->username) {
04098          ast_free(cur->username);
04099          cur->username = 0;
04100       }
04101 
04102       if (cur->host) {
04103          ast_free(cur->host);
04104          cur->host = 0;
04105       }
04106 
04107       if (cur->callerid_name) {
04108          ast_free(cur->callerid_name);
04109          cur->callerid_name = 0;
04110       }
04111       
04112       if (cur->callerid_num) {
04113          ast_free(cur->callerid_num);
04114          cur->callerid_num = 0;
04115       }
04116 
04117       if (cur->rtp) {
04118          ast_rtp_instance_destroy(cur->rtp);
04119          cur->rtp = NULL;
04120       }
04121 
04122       if (cur->udptl) {
04123          ast_udptl_destroy(cur->udptl);
04124          cur->udptl = NULL;
04125       }
04126    
04127       /* Unlink us from the owner if we have one */
04128       if (cur->owner) {
04129                while(ast_channel_trylock(cur->owner)) {
04130                      ast_debug(1, "Failed to grab lock, trying again\n");
04131             DEADLOCK_AVOIDANCE(&cur->lock);
04132                }           
04133          ast_debug(1, "Detaching from %s\n", ast_channel_name(cur->owner));
04134          ast_channel_tech_pvt_set(cur->owner, NULL);
04135          ast_channel_unlock(cur->owner);
04136          cur->owner = NULL;
04137          ast_module_unref(myself);
04138       }
04139   
04140       if (cur->vad) {
04141          ast_dsp_free(cur->vad);
04142          cur->vad = NULL;
04143       }
04144 
04145 /* decrement user/peer count */
04146 
04147       if(!ast_test_flag(cur, H323_OUTGOING)) {
04148     if (cur->neighbor.user) {
04149      user = find_user(p->callerid_name, cur->neighbor.user);
04150      if(user && user->inUse > 0) {
04151       ast_mutex_lock(&user->lock);
04152       user->inUse--;
04153       ast_mutex_unlock(&user->lock);
04154      }
04155      ast_free(cur->neighbor.user);
04156     }
04157       } else {
04158 /* outgoing limit decrement here !!! */
04159       }
04160 
04161       ast_mutex_unlock(&cur->lock);
04162       ast_mutex_destroy(&cur->lock);
04163       ao2_cleanup(cur->writeformat);
04164       ao2_cleanup(cur->readformat);
04165       ao2_cleanup(cur->cap);
04166       ast_free(cur);
04167    }
04168 
04169    if (gH323Debug)
04170       ast_verb(0, "+++   ooh323_destroy\n");
04171 
04172    return 0;
04173 }

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

Definition at line 879 of file chan_ooh323.c.

References ast_channel_tech_pvt(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_dtmf_begin(), ast_verb, ooh323_pvt::callToken, ooh323_pvt::dtmfmode, gH323Debug, H323_DTMF_CISCO, H323_DTMF_H245ALPHANUMERIC, H323_DTMF_H245SIGNAL, H323_DTMF_INBAND, H323_DTMF_Q931, H323_DTMF_RFC2833, ooh323_pvt::lock, LOG_ERROR, and ooh323_pvt::rtp.

00880 {
00881    char dtmf[2];
00882    struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
00883    int res = 0;
00884    
00885    if (gH323Debug)
00886       ast_verb(0, "---   ooh323_digit_begin\n");
00887 
00888    if (!p) {
00889       ast_log(LOG_ERROR, "No private structure for call\n");
00890       return -1;
00891    }
00892    ast_mutex_lock(&p->lock);
00893 
00894    if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) {
00895       ast_rtp_instance_dtmf_begin(p->rtp, digit);
00896    } else if (((p->dtmfmode & H323_DTMF_Q931) ||
00897                    (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ||
00898                    (p->dtmfmode & H323_DTMF_H245SIGNAL))) {
00899       dtmf[0] = digit;
00900       dtmf[1] = '\0';
00901       ooSendDTMFDigit(p->callToken, dtmf);
00902    } else if (p->dtmfmode & H323_DTMF_INBAND) {
00903       res = -1; // tell Asterisk to generate inband indications
00904    }
00905    ast_mutex_unlock(&p->lock);
00906 
00907    if (gH323Debug) {
00908       ast_verb(0, "+++   ooh323_digit_begin, res = %d\n", res);
00909    }
00910    return res;
00911 }

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

Definition at line 913 of file chan_ooh323.c.

References ast_channel_tech_pvt(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_dtmf_end(), ast_verb, ooh323_pvt::dtmfmode, gH323Debug, H323_DTMF_CISCO, H323_DTMF_INBAND, H323_DTMF_RFC2833, ooh323_pvt::lock, LOG_ERROR, and ooh323_pvt::rtp.

00914 {
00915    struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
00916    int res = 0;
00917 
00918    if (gH323Debug)
00919       ast_verb(0, "---   ooh323_digit_end\n");
00920 
00921    if (!p) {
00922       ast_log(LOG_ERROR, "No private structure for call\n");
00923       return -1;
00924    }
00925    ast_mutex_lock(&p->lock);
00926    if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) {
00927       ast_rtp_instance_dtmf_end(p->rtp, digit);
00928    } else if(p->dtmfmode & H323_DTMF_INBAND) {
00929       res = -1; // tell Asterisk to stop inband indications
00930    }
00931 
00932    ast_mutex_unlock(&p->lock);
00933 
00934    if (gH323Debug) {
00935       ast_verb(0, "+++   ooh323_digit_end, res = %d\n", res);
00936    }
00937    return res;
00938 }

static int ooh323_do_reload ( void   )  [static]

Definition at line 2659 of file chan_ooh323.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verb, ooh323_peer::e164, ooh323_peer::email, gAliasList, gGatekeeper, gH323Debug, gH323ep, gRasGkMode, ooh323_peer::h323id, ast_peer_list::lock, ooh323_peer::next, NULL, peerl, ast_peer_list::peers, reload_config(), and ooh323_peer::url.

Referenced by do_monitor().

02660 {
02661    struct ooAliases * pNewAlias = NULL;
02662    struct ooh323_peer *peer = NULL;
02663 
02664    if (gH323Debug) {
02665       ast_verb(0, "---   ooh323_do_reload\n");
02666    }
02667 
02668    /* Gatekeeper */
02669    if (gH323ep.gkClient) {
02670       ooGkClientDestroy();
02671    }
02672 
02673       reload_config(1);
02674 
02675    /* Gatekeeper */
02676    if (gRasGkMode == RasUseSpecificGatekeeper || 
02677       gRasGkMode == RasDiscoverGatekeeper) {
02678       ooGkClientInit(gRasGkMode, (gRasGkMode == RasUseSpecificGatekeeper) ? 
02679                         gGatekeeper : 0, 0);
02680       ooGkClientStart(gH323ep.gkClient);
02681    }
02682 
02683    /* Set aliases if any */
02684    if (gH323Debug) {
02685       ast_verb(0, "updating local aliases\n");
02686    }
02687 
02688    for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) {
02689       switch (pNewAlias->type) {
02690       case T_H225AliasAddress_h323_ID:
02691          ooH323EpAddAliasH323ID(pNewAlias->value);
02692          break;
02693       case T_H225AliasAddress_dialedDigits:  
02694          ooH323EpAddAliasDialedDigits(pNewAlias->value);
02695          break;
02696       case T_H225AliasAddress_email_ID:   
02697          ooH323EpAddAliasEmailID(pNewAlias->value);
02698          break;
02699       default:
02700                   ;
02701       }
02702    }
02703 
02704    ast_mutex_lock(&peerl.lock);
02705    peer = peerl.peers;
02706    while (peer) {
02707       if(peer->h323id) {
02708          ooH323EpAddAliasH323ID(peer->h323id);
02709       }
02710       if(peer->email) {
02711          ooH323EpAddAliasEmailID(peer->email);
02712       }
02713       if(peer->e164) {
02714          ooH323EpAddAliasDialedDigits(peer->e164);
02715       }
02716             if(peer->url) {
02717          ooH323EpAddAliasURLID(peer->url);
02718       }
02719       peer = peer->next;
02720    }
02721    ast_mutex_unlock(&peerl.lock);
02722 
02723    if (gH323Debug) {
02724       ast_verb(0, "+++   ooh323_do_reload\n");
02725    }
02726 
02727    return 0;
02728 }

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

Definition at line 1479 of file chan_ooh323.c.

References ast_channel_tech_pvt(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_verb, gH323Debug, ooh323_pvt::lock, LOG_WARNING, and ooh323_pvt::owner.

01480 {
01481    struct ooh323_pvt *p = ast_channel_tech_pvt(newchan);
01482 
01483    if (!p) return -1;
01484 
01485    if (gH323Debug)
01486       ast_verb(0, "--- ooh323c ooh323_fixup\n");
01487 
01488    ast_mutex_lock(&p->lock);
01489    if (p->owner != oldchan) {
01490       ast_log(LOG_WARNING, "Old channel wasn't %p but was %p\n", oldchan, p->owner);
01491       ast_mutex_unlock(&p->lock);
01492       return -1;
01493    }
01494 
01495    if (p->owner == oldchan) {
01496       p->owner = newchan;
01497    } else {
01498       p->owner = oldchan;
01499    }
01500 
01501    ast_mutex_unlock(&p->lock);
01502 
01503    if (gH323Debug)
01504       ast_verb(0, "+++ ooh323c ooh323_fixup \n");
01505 
01506    return 0;
01507 }

static void ooh323_get_codec ( struct ast_channel chan,
struct ast_format_cap result 
) [static]

Definition at line 4365 of file chan_ooh323.c.

References ast_channel_name(), ast_channel_nativeformats(), ast_channel_tech_pvt(), ast_format_cap_append_from_cap(), ast_format_cap_count(), AST_MEDIA_TYPE_UNKNOWN, ast_verb, ooh323_pvt::cap, and gH323Debug.

04366 {
04367    struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
04368    if (gH323Debug) {
04369       ast_verb(0, "+++ ooh323  get_codec, %s\n", ast_channel_name(chan));
04370    }
04371 
04372    if (p) {
04373       if (ast_format_cap_count(ast_channel_nativeformats(chan))) {
04374          ast_format_cap_append_from_cap(result, ast_channel_nativeformats(chan), AST_MEDIA_TYPE_UNKNOWN);
04375       } else if (ast_format_cap_count(p->cap)) {
04376          ast_format_cap_append_from_cap(result, p->cap, AST_MEDIA_TYPE_UNKNOWN);
04377       }
04378    }
04379 
04380    if (gH323Debug) {
04381       ast_verb(0, "--- ooh323  get_codec, %s\n", ast_channel_name(chan));
04382    }
04383 }

static enum ast_rtp_glue_result ooh323_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  rtp 
) [static]

Definition at line 4387 of file chan_ooh323.c.

References ao2_ref, ast_channel_name(), ast_channel_tech_pvt(), AST_JB_FORCED, AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, AST_RTP_GLUE_RESULT_REMOTE, ast_rtp_instance_get_remote_address, ast_sockaddr_port, ast_sockaddr_stringify_addr(), AST_STATE_UP, ast_test_flag, ast_verb, ooh323_pvt::directrtp, ooh323_pvt::earlydirect, gH323Debug, global_jbconf, NULL, and ooh323_pvt::rtp.

04388 {
04389    struct ooh323_pvt *p = NULL;
04390    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
04391    struct ast_sockaddr tmp;
04392 
04393    if (gH323Debug) {
04394       ast_verb(0, "+++ ooh323  get_rtp_peer \n");
04395    }
04396 
04397    if (!(p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan)))
04398       return AST_RTP_GLUE_RESULT_FORBID;
04399 
04400    if (!(p->rtp)) {
04401       return AST_RTP_GLUE_RESULT_FORBID;
04402    }
04403 
04404    *rtp = p->rtp ? ao2_ref(p->rtp, +1), p->rtp : NULL;
04405 
04406    /* there must be checking of directmedia setting */
04407 
04408    if ((ast_channel_state(chan) != AST_STATE_UP && !p->earlydirect) || !p->directrtp) {
04409       res = AST_RTP_GLUE_RESULT_LOCAL;
04410    } else {
04411       res = AST_RTP_GLUE_RESULT_REMOTE;
04412    }
04413 
04414    if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) {
04415       res = AST_RTP_GLUE_RESULT_FORBID;
04416    }
04417 
04418    ast_rtp_instance_get_remote_address(*rtp, &tmp);
04419    if (gH323Debug) {
04420       ast_verb(0, "ooh323_get_rtp_peer  %s -> %s:%d, %u\n", ast_channel_name(chan), ast_sockaddr_stringify_addr(&tmp),
04421                   ast_sockaddr_port(&tmp), res);
04422    }
04423    if (gH323Debug) {
04424       ast_verb(0, "--- ooh323  get_rtp_peer, res = %d\n", (int) res);
04425    }
04426 
04427    return res;
04428 }

static enum ast_rtp_glue_result ooh323_get_vrtp_peer ( struct ast_channel chan,
struct ast_rtp_instance **  rtp 
) [static]

Definition at line 4430 of file chan_ooh323.c.

References ao2_ref, ast_channel_tech_pvt(), AST_RTP_GLUE_RESULT_FORBID, AST_RTP_GLUE_RESULT_LOCAL, NULL, ooh323_pvt::rtp, and ooh323_pvt::vrtp.

04431 {
04432    struct ooh323_pvt *p = NULL;
04433    enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
04434 
04435    if (!(p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan)))
04436       return AST_RTP_GLUE_RESULT_FORBID;
04437 
04438    if (!(p->rtp)) {
04439       return AST_RTP_GLUE_RESULT_FORBID;
04440    }
04441 
04442    *rtp = p->vrtp ? ao2_ref(p->vrtp, +1), p->vrtp : NULL;
04443 
04444    /* there must check of supporting video per call */
04445 
04446    res = AST_RTP_GLUE_RESULT_FORBID;
04447 
04448    return res;
04449 }

static int ooh323_hangup ( struct ast_channel ast  )  [static]

Definition at line 1038 of file chan_ooh323.c.

References AST_CAUSE_CALL_REJECTED, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_REQUESTED_CHAN_UNAVAIL, AST_CAUSE_USER_BUSY, ast_channel_hangupcause(), ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), ast_debug, ast_module_unref, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verb, ooh323_pvt::callToken, gH323Debug, H323_ALREADYGONE, H323_NEEDDESTROY, ooh323_pvt::lock, NULL, ooh323_convert_hangupcause_asteriskToH323(), ooh323_pvt::owner, pbx_builtin_getvar_helper(), usecnt, usecnt_lock, and ooh323_pvt::username.

01039 {
01040    struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
01041       int q931cause = AST_CAUSE_NORMAL_CLEARING;
01042 
01043    if (gH323Debug)
01044       ast_verb(0, "---   ooh323_hangup\n");
01045 
01046    if (p) {
01047       ast_mutex_lock(&p->lock);
01048 
01049         if (ast_channel_hangupcause(ast)) {
01050                 q931cause = ast_channel_hangupcause(ast);
01051         } else {
01052                 const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS");
01053                 if (cause) {
01054                         if (!strcmp(cause, "CONGESTION")) {
01055                                 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
01056                         } else if (!strcmp(cause, "BUSY")) {
01057                                 q931cause = AST_CAUSE_USER_BUSY;
01058                         } else if (!strcmp(cause, "CHANISUNVAIL")) {
01059                                 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
01060                         } else if (!strcmp(cause, "NOANSWER")) {
01061                                 q931cause = AST_CAUSE_NO_ANSWER;
01062                         } else if (!strcmp(cause, "CANCEL")) {
01063                                 q931cause = AST_CAUSE_CALL_REJECTED;
01064                         }
01065                 }
01066         }
01067 
01068 
01069 
01070       if (gH323Debug)
01071          ast_verb(0, "    hanging %s with cause: %d\n", p->username, q931cause);
01072       ast_channel_tech_pvt_set(ast, NULL); 
01073       if (!ast_test_flag(p, H323_ALREADYGONE)) {
01074                ooHangCall(p->callToken, 
01075             ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause);
01076          ast_set_flag(p, H323_ALREADYGONE);
01077          /* ast_mutex_unlock(&p->lock); */
01078             } else 
01079          ast_set_flag(p, H323_NEEDDESTROY);
01080       /* detach channel here */
01081       if (p->owner) {
01082          ast_channel_tech_pvt_set(p->owner, NULL);
01083          p->owner = NULL;
01084          ast_module_unref(myself);
01085       }
01086 
01087       ast_mutex_unlock(&p->lock);
01088       ast_mutex_lock(&usecnt_lock);
01089       usecnt--;
01090       ast_mutex_unlock(&usecnt_lock);
01091 
01092       /* Notify the module monitors that use count for resource has changed */
01093       ast_update_use_count();
01094      
01095    } else {
01096       ast_debug(1, "No call to hangup\n" );
01097    }
01098    
01099    if (gH323Debug)
01100       ast_verb(0, "+++   ooh323_hangup\n");
01101 
01102   return 0;
01103 }

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

Definition at line 1232 of file chan_ooh323.c.

References ooh323_pvt::alertsent, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_USER_BUSY, ast_channel_connected(), ast_channel_tech_pvt(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, ast_debug, ast_free, ast_log, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_queue_control_data(), ast_rtp_instance_change_source(), ast_rtp_instance_update_source(), ast_sockaddr_isnull(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdup, ast_strlen_zero, AST_T38_NEGOTIATED, AST_T38_RATE_14400, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_PARMS, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, ast_udptl_get_far_max_ifp(), ast_verb, ooh323_pvt::callToken, ooh323_pvt::chmodepend, ooh323_pvt::faxmode, gH323Debug, H323_ALREADYGONE, ooh323_pvt::lock, LOG_ERROR, LOG_WARNING, ast_control_t38_parameters::max_ifp, name, NULL, ooh323_pvt::owner, ooh323_pvt::progsent, ast_control_t38_parameters::rate, ooh323_pvt::redirip, ast_control_t38_parameters::request_response, ooh323_pvt::rtp, T38_ENABLED, ooh323_pvt::t38support, and ooh323_pvt::udptl.

01233 {
01234 
01235    struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
01236    char *callToken = (char *)NULL;
01237    int res = -1;
01238 
01239    if (!p) return -1;
01240 
01241    ast_mutex_lock(&p->lock);
01242    callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
01243    ast_mutex_unlock(&p->lock);
01244 
01245    if (!callToken) {
01246       if (gH323Debug)
01247          ast_verb(0, "  ooh323_indicate - No callToken\n");
01248       return -1;
01249    }
01250 
01251    if (!ast_sockaddr_isnull(&p->redirip)) {
01252       res = 0;
01253    }
01254 
01255    if (gH323Debug) {
01256       ast_verb(0, "----- ooh323_indicate %d on call %s\n", condition, callToken);
01257    }
01258     
01259       ast_mutex_lock(&p->lock);
01260    switch (condition) {
01261    case AST_CONTROL_INCOMPLETE:
01262       /* While h323 does support overlapped dialing, this channel driver does not
01263        * at this time.  Treat a response of Incomplete as if it were congestion.
01264        */
01265    case AST_CONTROL_CONGESTION:
01266       if (!ast_test_flag(p, H323_ALREADYGONE)) {
01267          ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION);
01268       }
01269       break;
01270    case AST_CONTROL_BUSY:
01271       if (!ast_test_flag(p, H323_ALREADYGONE)) {
01272          ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY);
01273       }
01274       break;
01275    case AST_CONTROL_HOLD:
01276       ast_moh_start(ast, data, NULL);
01277       break;
01278    case AST_CONTROL_UNHOLD:
01279       ast_moh_stop(ast);
01280       break;
01281    case AST_CONTROL_PROGRESS:
01282       if (ast_channel_state(ast) != AST_STATE_UP) {
01283             if (!p->progsent) {
01284                if (gH323Debug) {
01285                ast_debug(1, "Sending manual progress for %s, res = %u\n", callToken,
01286                         ooManualProgress(callToken)); 
01287             } else {
01288                   ooManualProgress(callToken);
01289             }
01290                p->progsent = 1;
01291             }
01292       }
01293        break;
01294       case AST_CONTROL_RINGING:
01295       if (ast_channel_state(ast) == AST_STATE_RING || ast_channel_state(ast) == AST_STATE_RINGING) {
01296          if (!p->alertsent) {
01297             if (gH323Debug) {
01298                ast_debug(1, "Sending manual ringback for %s, res = %u\n",
01299                   callToken,
01300                   ooManualRingback(callToken));
01301             } else {
01302                ooManualRingback(callToken);
01303             }
01304             p->alertsent = 1;
01305          }
01306          p->alertsent = 1;
01307       }
01308     break;
01309    case AST_CONTROL_SRCUPDATE:
01310       if (p->rtp) {
01311          ast_rtp_instance_update_source(p->rtp);
01312       }
01313       break;
01314    case AST_CONTROL_SRCCHANGE:
01315       if (p->rtp) {
01316          ast_rtp_instance_change_source(p->rtp);
01317       }
01318       break;
01319    case AST_CONTROL_CONNECTED_LINE:
01320       if (!ast_channel_connected(ast)->id.name.valid
01321          || ast_strlen_zero(ast_channel_connected(ast)->id.name.str)) {
01322          break;
01323       }
01324       if (gH323Debug) {
01325          ast_debug(1, "Sending connected line info for %s (%s)\n",
01326             callToken, ast_channel_connected(ast)->id.name.str);
01327       }
01328       ooSetANI(callToken, ast_channel_connected(ast)->id.name.str);
01329       break;
01330 
01331       case AST_CONTROL_T38_PARAMETERS:
01332       if (p->t38support != T38_ENABLED) {
01333          struct ast_control_t38_parameters parameters = { .request_response = 0 };
01334          parameters.request_response = AST_T38_REFUSED;
01335          ast_queue_control_data(ast, AST_CONTROL_T38_PARAMETERS,
01336                    &parameters, sizeof(parameters));
01337          break;
01338       }
01339       if (datalen != sizeof(struct ast_control_t38_parameters)) {
01340          ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. "
01341                   "Expected %d, got %d\n",
01342             (int)sizeof(enum ast_control_t38), (int)datalen);
01343       } else {
01344          const struct ast_control_t38_parameters *parameters = data;
01345          struct ast_control_t38_parameters our_parameters;
01346          enum ast_control_t38 message = parameters->request_response;
01347          switch (message) {
01348 
01349          case AST_T38_NEGOTIATED:
01350             if (p->faxmode) {
01351                res = 0;
01352                break;
01353             }
01354          case AST_T38_REQUEST_NEGOTIATE:
01355 
01356             if (p->faxmode) {
01357                /* T.38 already negotiated */
01358                our_parameters.request_response = AST_T38_NEGOTIATED;
01359                our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
01360                our_parameters.rate = AST_T38_RATE_14400;
01361                ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
01362             } else if (!p->chmodepend) {
01363                p->chmodepend = 1;
01364                ooRequestChangeMode(p->callToken, 1);
01365                res = 0;
01366             }
01367             break;
01368 
01369          case AST_T38_REQUEST_TERMINATE:
01370 
01371             if (!p->faxmode) {
01372                /* T.38 already terminated */
01373                our_parameters.request_response = AST_T38_TERMINATED;
01374                ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
01375             } else if (!p->chmodepend) {
01376                p->chmodepend = 1;
01377                ooRequestChangeMode(p->callToken, 0);
01378                res = 0;
01379             }
01380             break;
01381 
01382          case AST_T38_REQUEST_PARMS:
01383             our_parameters.request_response = AST_T38_REQUEST_PARMS;
01384             our_parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
01385             our_parameters.rate = AST_T38_RATE_14400;
01386             ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &our_parameters, sizeof(our_parameters));
01387             res = AST_T38_REQUEST_PARMS;
01388             break;
01389 
01390          default:
01391             ;
01392 
01393          }
01394 
01395       }
01396       break;
01397    case AST_CONTROL_PROCEEDING:
01398    case AST_CONTROL_PVT_CAUSE_CODE:
01399    case AST_CONTROL_MASQUERADE_NOTIFY:
01400    case -1:
01401       break;
01402    default:
01403       ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n",
01404                            condition, callToken);
01405    }
01406 
01407       ast_mutex_unlock(&p->lock);
01408 
01409    if (gH323Debug) {
01410       ast_verb(0, "++++  ooh323_indicate %d on %s is %d\n", condition, callToken, res);
01411    }
01412 
01413       ast_free(callToken);
01414    return res;
01415 }

static struct ast_channel* ooh323_new ( struct ooh323_pvt i,
int  state,
const char *  host,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor 
) [static, read]

Definition at line 359 of file chan_ooh323.c.

References ooh323_pvt::accountcode, ooh323_pvt::amaflags, ao2_cleanup, ao2_ref, AST_ADSI_UNAVAILABLE, ast_channel_adsicpe_set(), ast_channel_alloc, ast_channel_amaflags_set(), ast_channel_context_set(), ast_channel_exten_set(), ast_channel_name(), ast_channel_nativeformats_set(), ast_channel_priority_set(), ast_channel_rings_set(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unlock, ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_faxmode(), ast_dsp_set_features(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format(), ast_hangup(), ast_jb_configure(), ast_log, ast_module_ref, ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), ast_publish_channel_state(), ast_set_read_format(), ast_set_write_format(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero, ast_test_flag, ast_update_use_count(), ast_verb, ooh323_pvt::caller_dialedDigits, ooh323_pvt::caller_email, ooh323_pvt::caller_h323id, ooh323_pvt::caller_url, ooh323_pvt::callerid_name, ooh323_pvt::callerid_num, callnumber, ooh323_pvt::cap, ooh323_pvt::context, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FAXMODE_DETECT_CED, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, ooh323_pvt::dtmfmode, ooh323_pvt::exten, ooh323_pvt::faxdetect, FAXDETECT_CNG, gH323Debug, global_jbconf, H323_DTMF_INBAND, H323_DTMF_INBANDRELAX, H323_OUTGOING, ooh323_pvt::lock, LOG_WARNING, NULL, ooh323c_cn_lock, ooh323_pvt::owner, pbx_builtin_setvar_helper(), usecnt, usecnt_lock, and ooh323_pvt::vad.

Referenced by ooh323_onReceivedSetup(), and ooh323_request().

00362 {
00363    struct ast_format_cap *caps = NULL;
00364    struct ast_channel *ch = NULL;
00365    struct ast_format *tmpfmt = NULL;
00366    int features = 0;
00367 
00368    if (gH323Debug) {
00369       ast_verb(0, "---   ooh323_new - %s\n", host);
00370    }
00371 
00372    caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
00373 
00374    /* Don't hold a h323 pvt lock while we allocate a channel */
00375    ast_mutex_unlock(&i->lock);
00376       ast_mutex_lock(&ooh323c_cn_lock);
00377       ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name, 
00378             i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags,
00379             "OOH323/%s-%ld", host, callnumber);
00380       callnumber++;
00381       ast_mutex_unlock(&ooh323c_cn_lock);
00382    
00383    ast_mutex_lock(&i->lock);
00384 
00385    if (ch && caps) {
00386       ast_channel_tech_set(ch, &ooh323_tech);
00387 
00388       if (cap) {
00389          tmpfmt = ast_format_cap_get_format(cap, 0);
00390       }
00391       if (!tmpfmt) {
00392          tmpfmt = ast_format_cap_get_format(i->cap, 0);
00393       }
00394 
00395       ast_format_cap_append(caps, tmpfmt, 0);
00396       ast_channel_nativeformats_set(ch, caps);
00397       ao2_ref(caps, -1);
00398 
00399       ast_channel_set_rawwriteformat(ch, tmpfmt);
00400       ast_channel_set_rawreadformat(ch, tmpfmt);
00401       ast_set_write_format(ch, tmpfmt);
00402       ast_set_read_format(ch, tmpfmt);
00403       ao2_ref(tmpfmt, -1);
00404 
00405       ast_jb_configure(ch, &global_jbconf);
00406 
00407       if (state == AST_STATE_RING)
00408          ast_channel_rings_set(ch, 1);
00409 
00410       ast_channel_adsicpe_set(ch, AST_ADSI_UNAVAILABLE);
00411       ast_channel_tech_pvt_set(ch, i);
00412       i->owner = ch;
00413       ast_module_ref(myself);
00414 
00415       /* Allocate dsp for in-band DTMF support */
00416       if ((i->dtmfmode & H323_DTMF_INBAND) || (i->faxdetect & FAXDETECT_CNG)) {
00417          i->vad = ast_dsp_new();
00418       }
00419 
00420       /* inband DTMF*/
00421       if (i->dtmfmode & H323_DTMF_INBAND) {
00422          features |= DSP_FEATURE_DIGIT_DETECT;
00423          if (i->dtmfmode & H323_DTMF_INBANDRELAX) {
00424             ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
00425          }
00426       }
00427 
00428       /* fax detection*/
00429       if (i->faxdetect & FAXDETECT_CNG) {
00430          features |= DSP_FEATURE_FAX_DETECT;
00431          ast_dsp_set_faxmode(i->vad,
00432                DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED);
00433       }
00434 
00435       if (features) {
00436          ast_dsp_set_features(i->vad, features);
00437       }
00438 
00439       ast_mutex_lock(&usecnt_lock);
00440       usecnt++;
00441       ast_mutex_unlock(&usecnt_lock);
00442 
00443       /* Notify the module monitors that use count for resource has changed*/
00444       ast_update_use_count();
00445 
00446       ast_channel_context_set(ch, i->context);
00447       ast_channel_exten_set(ch, i->exten);
00448 
00449       ast_channel_priority_set(ch, 1);
00450 
00451             if(!ast_test_flag(i, H323_OUTGOING)) {
00452       
00453          if (!ast_strlen_zero(i->caller_h323id)) {
00454             pbx_builtin_setvar_helper(ch, "_CALLER_H323ID", i->caller_h323id);
00455 
00456          }
00457          if (!ast_strlen_zero(i->caller_dialedDigits)) {
00458             pbx_builtin_setvar_helper(ch, "_CALLER_H323DIALEDDIGITS", 
00459             i->caller_dialedDigits);
00460          }
00461          if (!ast_strlen_zero(i->caller_email)) {
00462             pbx_builtin_setvar_helper(ch, "_CALLER_H323EMAIL", 
00463             i->caller_email);
00464          }
00465          if (!ast_strlen_zero(i->caller_url)) {
00466             pbx_builtin_setvar_helper(ch, "_CALLER_H323URL", i->caller_url);
00467          }
00468       }
00469 
00470       if (!ast_strlen_zero(i->accountcode))
00471          ast_channel_accountcode_set(ch, i->accountcode);
00472       
00473       if (i->amaflags)
00474          ast_channel_amaflags_set(ch, i->amaflags);
00475 
00476       ast_setstate(ch, state);
00477       if (state != AST_STATE_DOWN) {
00478                if (ast_pbx_start(ch)) {
00479             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(ch));
00480                      ast_channel_unlock(ch);
00481             ast_hangup(ch);
00482             ch = NULL;
00483          } 
00484       }
00485 
00486       if (ch) {
00487          ast_publish_channel_state(ch);
00488 
00489       }
00490    } else {
00491       ao2_cleanup(caps);
00492       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00493    }
00494 
00495 
00496       if(ch)   ast_channel_unlock(ch);
00497 
00498    if (gH323Debug) {
00499       ast_verb(0, "+++   h323_new\n");
00500    }
00501 
00502    return ch;
00503 }

int ooh323_onReceivedDigit ( OOH323CallData *  call,
const char *  digit 
)

Callback for sending digits from H.323 up to asterisk

Definition at line 1755 of file chan_ooh323.c.

References ast_channel_trylock, ast_channel_unlock, ast_debug, AST_FRAME_DTMF, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_queue_frame(), ast_frame::data, ast_frame::datalen, DEADLOCK_AVOIDANCE, find_call, ast_frame::frametype, ast_frame_subclass::integer, ooh323_pvt::lock, LOG_ERROR, ast_frame::mallocd, NULL, ast_frame::offset, ooh323_pvt::owner, ast_frame::ptr, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by load_module().

01756 {
01757    struct ooh323_pvt *p = NULL;
01758    struct ast_frame f;
01759    int res;
01760 
01761    ast_debug(1, "Received Digit: %c\n", digit[0]);
01762    p = find_call(call);
01763    if (!p) {
01764       ast_log(LOG_ERROR, "Failed to find a matching call.\n");
01765       return -1;
01766    }
01767    if (!p->owner) {
01768       ast_log(LOG_ERROR, "Channel has no owner\n");
01769       return -1;
01770    }
01771    ast_mutex_lock(&p->lock);
01772    memset(&f, 0, sizeof(f));
01773    f.frametype = AST_FRAME_DTMF;
01774    f.subclass.integer = digit[0];
01775    f.datalen = 0;
01776    f.samples = 800;
01777    f.offset = 0;
01778    f.data.ptr = NULL;
01779    f.mallocd = 0;
01780    f.src = "SEND_DIGIT";
01781 
01782    while (p->owner && ast_channel_trylock(p->owner)) {
01783       ast_debug(1, "Failed to grab lock, trying again\n");
01784       DEADLOCK_AVOIDANCE(&p->lock);
01785    }
01786    if (!p->owner) {
01787       ast_mutex_unlock(&p->lock);
01788       ast_log(LOG_ERROR, "Channel has no owner\n");
01789       return 0;
01790    }
01791    res = ast_queue_frame(p->owner, &f);
01792       ast_channel_unlock(p->owner);
01793       ast_mutex_unlock(&p->lock);
01794    return res;
01795 }

int ooh323_onReceivedSetup ( ooCallData *  call,
Q931Message *  pmsg 
)

Definition at line 1797 of file chan_ooh323.c.

References ooh323_user::accountcode, ooh323_pvt::accountcode, ooh323_user::amaflags, ooh323_pvt::amaflags, ooh323_user::aniasdni, ooh323_pvt::aniasdni, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, ast_clear_flag, ast_copy_string(), ast_format_cap_append_from_cap(), ast_log, AST_MEDIA_TYPE_UNKNOWN, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, AST_STATE_RING, ast_strdup, ast_strlen_zero, ast_verb, c, ooh323_pvt::callee_dialedDigits, ooh323_pvt::callee_email, ooh323_pvt::callee_h323id, ooh323_pvt::caller_dialedDigits, ooh323_pvt::caller_email, ooh323_pvt::caller_h323id, ooh323_pvt::caller_url, ooh323_pvt::callerid_name, ooh323_pvt::callerid_num, ooh323_user::cap, ooh323_pvt::cap, configure_local_rtp(), ooh323_user::context, ooh323_pvt::context, ooh323_user::directrtp, ooh323_pvt::directrtp, ooh323_user::dtmfcodec, ooh323_pvt::dtmfcodec, ooh323_user::dtmfmode, ooh323_pvt::dtmfmode, ooh323_user::earlydirect, ooh323_pvt::earlydirect, ooh323_pvt::exten, ooh323_user::faststart, ooh323_pvt::faststart, ooh323_user::faxdetect, ooh323_pvt::faxdetect, find_user(), ooh323_pvt::flags, ooh323_user::g729onlyA, ooh323_pvt::g729onlyA, gDirectRTP, gEarlyDirect, gH323Debug, ooh323_user::h245tunneling, ooh323_pvt::h245tunneling, H323_DISABLEGK, H323_NEEDDESTROY, H323_OUTGOING, ooh323_user::incominglimit, ooh323_user::inUse, ooh323_user::lock, ooh323_pvt::lock, LOG_ERROR, ooh323_user::mIP, ooh323_user::mUseIP, ooh323_user::name, ooh323_user::nat, ooh323_pvt::nat, ooh323_pvt::neighbor, NULL, ooh323_alloc(), ooh323_convert_hangupcause_asteriskToH323(), ooh323_new(), ooh323c_set_capability_for_call(), ooh323_pvt::rtdrcount, ooh323_user::rtdrcount, ooh323_pvt::rtdrinterval, ooh323_user::rtdrinterval, ooh323_pvt::rtpmask, ooh323_user::rtpmask, ooh323_pvt::rtpmaskstr, ooh323_user::rtpmaskstr, ooh323_user::rtptimeout, ooh323_pvt::rtptimeout, ooh323_user::t38support, ooh323_pvt::t38support, update_our_aliases(), ooh323_pvt::user, and ooh323_pvt::username.

Referenced by load_module().

01798 {
01799    struct ooh323_pvt *p = NULL;
01800    struct ooh323_user *user = NULL;
01801       struct ast_channel *c = NULL;
01802    ooAliases *alias = NULL;
01803    char *at = NULL;
01804    char number [OO_MAX_NUMBER_LENGTH];
01805 
01806    if (gH323Debug)
01807       ast_verb(0, "---   ooh323_onReceivedSetup %s\n", call->callToken);
01808 
01809 
01810    if (!(p = ooh323_alloc(call->callReference, call->callToken))) {
01811       ast_log(LOG_ERROR, "Failed to create a new call.\n");
01812       return -1;
01813    }
01814    ast_mutex_lock(&p->lock);
01815    ast_clear_flag(p, H323_OUTGOING);
01816   
01817 
01818    if (call->remoteDisplayName) {
01819       p->callerid_name = ast_strdup(call->remoteDisplayName);
01820    }
01821 
01822    if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) {
01823       p->callerid_num = ast_strdup(number);
01824    }
01825 
01826    if (call->remoteAliases) {
01827       for (alias = call->remoteAliases; alias; alias = alias->next) {
01828          if (alias->type == T_H225AliasAddress_h323_ID) {
01829             if (!p->callerid_name) {
01830                p->callerid_name = ast_strdup(alias->value);
01831             }
01832             ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id));
01833             }
01834          else if(alias->type == T_H225AliasAddress_dialedDigits)
01835          {
01836             if(!p->callerid_num)
01837                p->callerid_num = ast_strdup(alias->value);
01838             ast_copy_string(p->caller_dialedDigits, alias->value, 
01839                                              sizeof(p->caller_dialedDigits));
01840          }
01841          else if(alias->type == T_H225AliasAddress_email_ID)
01842          {
01843             ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email));
01844          }
01845          else if(alias->type == T_H225AliasAddress_url_ID)
01846          {
01847             ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url));
01848          }
01849       }
01850    }
01851 
01852    number[0] = '\0';
01853       if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) {
01854             ast_copy_string(p->exten, number, sizeof(p->exten));
01855       } else {
01856       update_our_aliases(call, p);
01857       if (!ast_strlen_zero(p->callee_dialedDigits)) {
01858                ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten));
01859             } else if(!ast_strlen_zero(p->callee_h323id)) {
01860          ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten));
01861             } else if(!ast_strlen_zero(p->callee_email)) {
01862          ast_copy_string(p->exten, p->callee_email, sizeof(p->exten));
01863          if ((at = strchr(p->exten, '@'))) {
01864             *at = '\0';
01865          }
01866       }
01867    }
01868 
01869    /* if no extension found, set to default 's' */
01870    if (ast_strlen_zero(p->exten)) {
01871             p->exten[0]='s';
01872             p->exten[1]='\0';
01873    }
01874 
01875          user = find_user(p->callerid_name, call->remoteIP);
01876          if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) {
01877       ast_mutex_lock(&user->lock);
01878       p->username = ast_strdup(user->name);
01879       p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) :
01880                     ast_strdup(user->name);
01881       ast_copy_string(p->context, user->context, sizeof(p->context));
01882       ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
01883       p->amaflags = user->amaflags;
01884       ast_format_cap_append_from_cap(p->cap, user->cap, AST_MEDIA_TYPE_UNKNOWN);
01885       p->g729onlyA = user->g729onlyA;
01886       p->dtmfmode |= user->dtmfmode;
01887       p->dtmfcodec = user->dtmfcodec;
01888       p->faxdetect = user->faxdetect;
01889       p->t38support = user->t38support;
01890       p->rtptimeout = user->rtptimeout;
01891       p->nat = user->nat;
01892       p->h245tunneling = user->h245tunneling;
01893       p->faststart = user->faststart;
01894       p->directrtp = user->directrtp;
01895       p->earlydirect = user->earlydirect;
01896 
01897       if (p->faststart)
01898                OO_SETFLAG(call->flags, OO_M_FASTSTART);
01899       else
01900          OO_CLRFLAG(call->flags, OO_M_FASTSTART);
01901       /* if we disable h245tun for this user then we clear flag */
01902       /* in any other case we don't must touch this */
01903       /* ie if we receive setup without h245tun but enabled
01904                      we can't enable it per call */
01905       if (!p->h245tunneling)
01906          OO_CLRFLAG(call->flags, OO_M_TUNNELING);
01907 
01908       if (user->rtpmask && user->rtpmaskstr[0]) {
01909          p->rtpmask = user->rtpmask;
01910          ast_copy_string(p->rtpmaskstr, user->rtpmaskstr, 
01911                       sizeof(p->rtpmaskstr));
01912       }
01913       if (user->rtdrcount > 0 && user->rtdrinterval > 0) {
01914          p->rtdrcount = user->rtdrcount;
01915          p->rtdrinterval = user->rtdrinterval;
01916       }
01917 
01918       p->aniasdni = user->aniasdni;
01919 
01920       if (user->incominglimit) user->inUse++;
01921       ast_mutex_unlock(&user->lock);
01922    } else {
01923     if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
01924       p->username = ast_strdup(call->remoteIP);
01925       p->directrtp = gDirectRTP;
01926       p->earlydirect = gEarlyDirect;
01927    } else {
01928      ast_mutex_unlock(&p->lock);
01929      ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
01930      if (!user) {
01931       ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED);
01932       call->callEndReason = OO_REASON_REMOTE_REJECTED;
01933      }
01934      else {
01935       ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
01936       call->callEndReason = OO_REASON_REMOTE_REJECTED;
01937      }
01938      ast_set_flag(p, H323_NEEDDESTROY);
01939      return -1;
01940     }
01941    }
01942 
01943    ooh323c_set_capability_for_call(call, p->cap, p->dtmfmode, p->dtmfcodec,
01944                 p->t38support, p->g729onlyA);
01945 /* Incoming call */
01946    c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL, NULL);
01947    if(!c) {
01948       ast_mutex_unlock(&p->lock);
01949       ast_log(LOG_ERROR, "Could not create ast_channel\n");
01950          return -1;
01951    }
01952 
01953    if (p->aniasdni) {
01954       ooCallSetCallerId(call, p->exten);
01955    }
01956    if (!configure_local_rtp(p, call)) {
01957       ast_mutex_unlock(&p->lock);
01958       ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
01959       return -1;
01960    }
01961 
01962    ast_mutex_unlock(&p->lock);
01963 
01964    if (gH323Debug)
01965       ast_verb(0, "+++   ooh323_onReceivedSetup - Determined context %s, "
01966                   "extension %s\n", p->context, p->exten);
01967 
01968    return OO_OK;
01969 }

static int ooh323_queryoption ( struct ast_channel ast,
int  option,
void *  data,
int *  datalen 
) [static]

Definition at line 1417 of file chan_ooh323.c.

References ast_channel_name(), ast_channel_tech_pvt(), ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_DIGIT_DETECT, AST_OPTION_T38_STATE, ast_verb, ooh323_pvt::chmodepend, ooh323_pvt::faxmode, gH323Debug, ooh323_pvt::lock, LOG_ERROR, T38_DISABLED, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, ooh323_pvt::t38support, and ooh323_pvt::vad.

01418 {
01419 
01420    struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(ast);
01421    int res = -1;
01422    enum ast_t38_state state = T38_STATE_UNAVAILABLE;
01423    char* cp;
01424 
01425    if (!p) return -1;
01426 
01427    ast_mutex_lock(&p->lock);
01428 
01429    if (gH323Debug)
01430       ast_verb(0, "----- ooh323_queryoption %d on channel %s\n", option, ast_channel_name(ast));
01431     
01432    switch (option) {
01433 
01434       case AST_OPTION_T38_STATE:
01435 
01436          if (*datalen != sizeof(enum ast_t38_state)) {
01437             ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option."
01438             " Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
01439             break;
01440          }
01441 
01442          if (p->t38support != T38_DISABLED) {
01443             if (p->faxmode) {
01444                state = (p->chmodepend) ? T38_STATE_NEGOTIATING : T38_STATE_NEGOTIATED;
01445             } else {
01446                state = T38_STATE_UNKNOWN;
01447             }
01448          }
01449 
01450          *((enum ast_t38_state *) data) = state;
01451          res = 0;
01452          break;
01453 
01454 
01455       case AST_OPTION_DIGIT_DETECT:
01456 
01457          cp = (char *) data;
01458          *cp = p->vad ? 1 : 0;
01459          ast_debug(1, "Reporting digit detection %sabled on %s\n",
01460                       *cp ? "en" : "dis", ast_channel_name(ast));
01461 
01462          res = 0;
01463          break;
01464 
01465       default: ;
01466 
01467    }
01468 
01469    if (gH323Debug)
01470       ast_verb(0, "+++++ ooh323_queryoption %d on channel %s\n", option, ast_channel_name(ast));
01471     
01472       ast_mutex_unlock(&p->lock);
01473 
01474    return res;
01475 }

static struct ast_frame * ooh323_read ( struct ast_channel ast  )  [static, read]

Definition at line 1146 of file chan_ooh323.c.

References ast_channel_tech_pvt(), AST_FRAME_NULL, ast_mutex_lock, ast_mutex_unlock, ooh323_pvt::lock, ooh323_rtp_read(), and ooh323_pvt::rtp.

01147 {
01148    struct ast_frame *fr;
01149    static struct ast_frame null_frame = { AST_FRAME_NULL, };
01150    struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
01151 
01152    if (!p) return &null_frame;
01153 
01154    ast_mutex_lock(&p->lock);
01155    if (p->rtp)
01156       fr = ooh323_rtp_read(ast, p);
01157    else
01158       fr = &null_frame;
01159    /* time(&p->lastrtprx); */
01160    ast_mutex_unlock(&p->lock);
01161    return fr;
01162 }

static struct ast_channel * ooh323_request ( const char *  type,
struct ast_format_cap cap,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor,
const char *  data,
int *  cause 
) [static, read]

Definition at line 575 of file chan_ooh323.c.

References ooh323_peer::accountcode, ooh323_pvt::accountcode, ooh323_peer::amaflags, ooh323_pvt::amaflags, ast_calloc, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_copy_string(), ast_format_cap_append_from_cap(), ast_format_cap_get_names(), ast_format_cap_has_type(), ast_log, AST_MAX_EXTENSION, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, AST_STATE_DOWN, ast_str_alloca, ast_strdup, ast_verb, ooh323_pvt::callToken, ooh323_peer::cap, ooh323_pvt::cap, ooh323_peer::directrtp, ooh323_pvt::directrtp, ooh323_peer::dtmfcodec, ooh323_pvt::dtmfcodec, ooh323_peer::dtmfmode, ooh323_pvt::dtmfmode, ooh323_peer::earlydirect, ooh323_pvt::earlydirect, ext, ooh323_pvt::exten, ooh323_peer::faststart, ooh323_pvt::faststart, ooh323_peer::faxdetect, ooh323_pvt::faxdetect, find_peer(), g729onlyA, ooh323_peer::g729onlyA, ooh323_pvt::g729onlyA, gDirectRTP, gDTMFCodec, gDTMFMode, gEarlyDirect, gFastStart, gFAXdetect, gH323Debug, gH323ep, gNat, gRasGkMode, gRTDRCount, gRTDRInterval, gRTPTimeout, gT38Support, gTunneling, ooh323_peer::h245tunneling, ooh323_pvt::h245tunneling, H323_OUTGOING, ooh323_pvt::host, iflock, ooh323_peer::ip, ooh323_pvt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ooh323_peer::name, ooh323_peer::nat, ooh323_pvt::nat, NULL, ooh323_alloc(), ooh323_destroy(), ooh323_new(), ooh323_pvt::port, ooh323_peer::port, restart_monitor(), ooh323_peer::rtdrcount, ooh323_pvt::rtdrcount, ooh323_pvt::rtdrinterval, ooh323_peer::rtdrinterval, ooh323_pvt::rtp, ooh323_pvt::rtpcond, ooh323_pvt::rtpmask, ooh323_peer::rtpmask, ooh323_pvt::rtpmaskstr, ooh323_peer::rtpmaskstr, ooh323_peer::rtptimeout, ooh323_pvt::rtptimeout, ooh323_peer::t38support, ooh323_pvt::t38support, tmp(), and ooh323_pvt::username.

00578 {
00579    struct ast_str *codec_buf = ast_str_alloca(64);
00580    struct ast_channel *chan = NULL;
00581    struct ooh323_pvt *p = NULL;
00582    struct ooh323_peer *peer = NULL;
00583    char *dest = NULL; 
00584    char *ext = NULL;
00585    char tmp[256];
00586    int port = 0;
00587 
00588    if (gH323Debug) {
00589       ast_verb(0, "---   ooh323_request - data %s format %s\n", data, ast_format_cap_get_names(cap, &codec_buf));
00590    }
00591 
00592    if (!(ast_format_cap_has_type(cap, AST_MEDIA_TYPE_AUDIO))) {
00593       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf));
00594       return NULL;
00595    }
00596 
00597    p = ooh323_alloc(0,0); /* Initial callRef is zero */
00598 
00599    if (!p) {
00600       ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", data);
00601       return NULL;
00602    }
00603    ast_mutex_lock(&p->lock);
00604 
00605    /* This is an outgoing call, since ooh323_request is called */
00606    ast_set_flag(p, H323_OUTGOING);
00607 
00608 
00609       ast_copy_string(tmp, data, sizeof(tmp));
00610 
00611    dest = strchr(tmp, '/');
00612 
00613    if (dest) {  
00614       *dest = '\0';
00615       dest++;
00616       ext = dest;
00617       dest = tmp;
00618    } else if ((dest = strchr(tmp, '@'))) {
00619       *dest = '\0';
00620       dest++;
00621       ext = tmp;
00622    } else {
00623       dest = tmp;
00624       ext = NULL;
00625    }
00626 
00627 #if 0
00628    if ((sport = strchr(dest, ':'))) {
00629       *sport = '\0';
00630       sport++;
00631       port = atoi(sport);
00632    }
00633 #endif
00634 
00635    if (dest) {
00636       peer = find_peer(dest, port);
00637    } else{
00638       ast_mutex_lock(&iflock);
00639       ast_mutex_unlock(&p->lock);
00640       ooh323_destroy(p);
00641       ast_mutex_unlock(&iflock);
00642       ast_log(LOG_ERROR, "Destination format is not supported\n");
00643       *cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
00644       return NULL;
00645    }
00646 
00647    if (peer) {
00648       p->username = ast_strdup(peer->name);
00649       p->host = ast_strdup(peer->ip);
00650       p->port = peer->port;
00651       /* Disable gk as we are going to call a known peer*/
00652       /* OO_SETFLAG(p->flags, H323_DISABLEGK); */
00653 
00654       if (ext)
00655          ast_copy_string(p->exten, ext, sizeof(p->exten));
00656 
00657       ast_format_cap_append_from_cap(p->cap, peer->cap, AST_MEDIA_TYPE_UNKNOWN);
00658       p->g729onlyA = peer->g729onlyA;
00659       p->dtmfmode |= peer->dtmfmode;
00660       p->dtmfcodec  = peer->dtmfcodec;
00661       p->faxdetect = peer->faxdetect;
00662       p->t38support = peer->t38support;
00663       p->rtptimeout = peer->rtptimeout;
00664       p->nat = peer->nat;
00665       p->faststart = peer->faststart;
00666       p->h245tunneling = peer->h245tunneling;
00667       p->directrtp = peer->directrtp;
00668       p->earlydirect = peer->earlydirect;
00669       if (peer->rtpmask && peer->rtpmaskstr[0]) {
00670          p->rtpmask = peer->rtpmask;
00671          ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
00672       }
00673 
00674       if (peer->rtdrinterval) {
00675          p->rtdrinterval = peer->rtdrinterval;
00676          p->rtdrcount = peer->rtdrcount;
00677       }
00678 
00679       ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode));
00680       p->amaflags = peer->amaflags;
00681    } else {
00682       if (gRasGkMode ==  RasNoGatekeeper) {
00683          /* no gk and no peer */
00684          ast_log(LOG_ERROR, "Call to undefined peer %s", dest);
00685          ast_mutex_lock(&iflock);
00686          ast_mutex_unlock(&p->lock);
00687          ooh323_destroy(p);
00688          ast_mutex_unlock(&iflock);
00689          return NULL;
00690       } else if (!gH323ep.gkClient || (gH323ep.gkClient && gH323ep.gkClient->state != GkClientRegistered)) {
00691          ast_log(LOG_ERROR, "Gatekeeper client is configured but not registered\n");
00692          *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
00693          return NULL;
00694       }
00695       p->g729onlyA = g729onlyA;
00696       p->dtmfmode = gDTMFMode;
00697       p->dtmfcodec = gDTMFCodec;
00698       p->faxdetect = gFAXdetect;
00699       p->t38support = gT38Support;
00700       p->rtptimeout = gRTPTimeout;
00701       p->nat = gNat;
00702       ast_format_cap_append_from_cap(p->cap, gCap, AST_MEDIA_TYPE_UNKNOWN);
00703       p->rtdrinterval = gRTDRInterval;
00704       p->rtdrcount = gRTDRCount;
00705       p->faststart = gFastStart;
00706       p->h245tunneling = gTunneling;
00707       p->directrtp = gDirectRTP;
00708       p->earlydirect = gEarlyDirect;
00709 
00710       p->username = ast_strdup(dest);
00711 
00712       p->host = ast_strdup(dest);
00713       if (port > 0) {
00714          p->port = port;
00715       }
00716       if (ext) {
00717          ast_copy_string(p->exten, ext, sizeof(p->exten));
00718       }
00719    }
00720 
00721 
00722    chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
00723              assignedids, requestor);
00724    
00725    ast_mutex_unlock(&p->lock);
00726 
00727    if (!chan) {
00728       ast_mutex_lock(&iflock);
00729       ooh323_destroy(p);
00730       ast_mutex_unlock(&iflock);
00731       } else {
00732             ast_mutex_lock(&p->lock);
00733             p->callToken = (char*)ast_calloc(1, AST_MAX_EXTENSION);
00734             if(!p->callToken) {
00735                ast_mutex_unlock(&p->lock);
00736                ast_mutex_lock(&iflock);
00737                ooh323_destroy(p);
00738                ast_mutex_unlock(&iflock);
00739                ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");
00740                return NULL;
00741             }
00742 
00743       ast_cond_init(&p->rtpcond, NULL);
00744             ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
00745       if (!p->rtp) {
00746          ast_cond_wait(&p->rtpcond, &p->lock);
00747       }
00748       ast_mutex_unlock(&p->lock);
00749       ast_cond_destroy(&p->rtpcond);
00750    }
00751 
00752    restart_monitor();
00753    if (gH323Debug)
00754       ast_verb(0, "+++   ooh323_request\n");
00755 
00756    return chan;
00757 
00758 }

struct ast_frame* ooh323_rtp_read ( struct ast_channel ast,
struct ooh323_pvt p 
) [read]

Definition at line 4923 of file chan_ooh323.c.

References ao2_ref, ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_fdno(), ast_channel_macrocontext(), ast_channel_name(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_writeformat(), ast_debug, ast_dsp_process(), ast_exists_extension(), ast_format_alaw, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_iscompatible_format(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), ast_format_slin, ast_format_ulaw, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frdup(), ast_frfree, ast_log, ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_udptl_read(), ast_verb, ooh323_pvt::callToken, ooh323_pvt::chmodepend, ast_frame::datalen, ooh323_pvt::dtmfmode, f, ooh323_pvt::faxdetect, FAXDETECT_CNG, ooh323_pvt::faxdetected, ooh323_pvt::faxmode, ast_frame_subclass::format, ast_frame::frametype, gH323Debug, H323_DTMF_INBAND, ast_party_caller::id, ast_frame_subclass::integer, ooh323_pvt::lastrtprx, LOG_NOTICE, NULL, ast_party_id::number, ooh323_pvt::owner, pbx_builtin_setvar_helper(), ooh323_pvt::rtp, S_COR, S_OR, ast_party_number::str, ast_frame::subclass, T38_DISABLED, ooh323_pvt::t38support, ooh323_pvt::udptl, ooh323_pvt::vad, ast_party_number::valid, and ooh323_pvt::vrtp.

Referenced by ooh323_read().

04924 {
04925    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04926    struct ast_frame *f;
04927    struct ast_frame *dfr = NULL;
04928    static struct ast_frame null_frame = { AST_FRAME_NULL, };
04929    switch (ast_channel_fdno(ast)) {
04930    case 0:
04931       f = ast_rtp_instance_read(p->rtp, 0);  /* RTP Audio */
04932       p->lastrtprx = time(NULL);
04933       break;
04934    case 1:
04935       f = ast_rtp_instance_read(p->rtp, 1);  /* RTCP Control Channel */
04936       break;
04937    case 2:
04938       f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */
04939       p->lastrtprx = time(NULL);
04940       break;
04941    case 3:
04942       f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */
04943       break;
04944    case 5:
04945       f = ast_udptl_read(p->udptl);    /* UDPTL t.38 data */
04946       if (gH323Debug) {
04947           ast_debug(1, "Got UDPTL %u/%d len %d for %s\n",
04948             f->frametype, f->subclass.integer, f->datalen, ast_channel_name(ast));
04949       }
04950       p->lastrtprx = time(NULL);
04951       break;
04952 
04953    default:
04954       f = &null_frame;
04955    }
04956 
04957    if (f && p->owner && !p->faxmode && (f->frametype == AST_FRAME_VOICE)) {
04958       /* We already hold the channel lock */
04959       if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(p->owner), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
04960          struct ast_format_cap *caps;
04961 
04962          ast_debug(1, "Oooh, voice format changed to %s\n", ast_format_get_name(f->subclass.format));
04963 
04964          caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
04965          if (caps) {
04966             ast_format_cap_append(caps, f->subclass.format, 0);
04967             ast_channel_nativeformats_set(p->owner, caps);
04968             ao2_ref(caps, -1);
04969          }
04970          ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
04971          ast_set_write_format(p->owner, ast_channel_writeformat(p->owner));
04972       }
04973       if (((p->dtmfmode & H323_DTMF_INBAND) || (p->faxdetect & FAXDETECT_CNG)) && p->vad &&
04974          ((ast_format_cmp(f->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) ||
04975          (ast_format_cmp(f->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) ||
04976          (ast_format_cmp(f->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL))) {
04977          dfr = ast_frdup(f);
04978          dfr = ast_dsp_process(p->owner, p->vad, dfr);
04979       }
04980    } else {
04981       return f;
04982    }
04983 
04984    /* process INBAND DTMF*/
04985    if (dfr && (dfr->frametype == AST_FRAME_DTMF) && ((dfr->subclass.integer == 'f') || (dfr->subclass.integer == 'e'))) {
04986       ast_debug(1, "* Detected FAX Tone %s\n", (dfr->subclass.integer == 'e') ? "CED" : "CNG");
04987       /* Switch to T.38 ON CED*/
04988       if (!p->faxmode && !p->chmodepend && (dfr->subclass.integer == 'e') && (p->t38support != T38_DISABLED)) {
04989          if (gH323Debug)
04990             ast_verb(0, "request to change %s to t.38 because fax ced\n", p->callToken);
04991          p->chmodepend = 1;
04992          p->faxdetected = 1;
04993          ooRequestChangeMode(p->callToken, 1);
04994       } else if ((dfr->subclass.integer == 'f') && !p->faxdetected) {
04995          const char *target_context = S_OR(ast_channel_macrocontext(p->owner), ast_channel_context(p->owner));
04996          if ((strcmp(ast_channel_exten(p->owner), "fax")) &&
04997              (ast_exists_extension(p->owner, target_context, "fax", 1,
04998                   S_COR(ast_channel_caller(p->owner)->id.number.valid, ast_channel_caller(p->owner)->id.number.str, NULL)))) {
04999             ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n", ast_channel_name(p->owner));
05000             pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", ast_channel_exten(p->owner));
05001             if (ast_async_goto(p->owner, target_context, "fax", 1)) {
05002                ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(p->owner),target_context);
05003             }
05004             p->faxdetected = 1;
05005             if (dfr) {
05006                ast_frfree(dfr);
05007             }
05008             return &ast_null_frame;
05009          }
05010       }
05011    } else if (dfr && dfr->frametype == AST_FRAME_DTMF) {
05012       ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
05013       ast_frfree(f);
05014       return dfr;
05015    }
05016 
05017    if (dfr) {
05018       ast_frfree(dfr);
05019    }
05020    return f;
05021 }

void ooh323_set_read_format ( ooCallData *  call,
struct ast_format fmt 
)

Definition at line 1582 of file chan_ooh323.c.

References ao2_ref, ao2_replace, ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_trylock, ast_channel_unlock, ast_debug, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_get_name(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_set_read_format(), ast_verb, DEADLOCK_AVOIDANCE, find_call, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, ooh323_pvt::owner, and ooh323_pvt::readformat.

01583 {
01584    struct ooh323_pvt *p = NULL;
01585 
01586    if (gH323Debug)
01587       ast_verb(0, "---   ooh323_update_readformat %s\n", 
01588             ast_format_get_name(fmt));
01589    
01590    p = find_call(call);
01591    if (!p) {
01592       ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
01593       return;
01594    }
01595 
01596    ast_mutex_lock(&p->lock);
01597 
01598    ao2_replace(p->readformat, fmt);
01599 
01600    if (p->owner) {
01601       struct ast_format_cap *caps;
01602 
01603       caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
01604       if (!caps) {
01605          ast_log(LOG_ERROR, "Could not allocate capabilities structure\n");
01606          return;
01607       }
01608 
01609       while (p->owner && ast_channel_trylock(p->owner)) {
01610          ast_debug(1,"Failed to grab lock, trying again\n");
01611          DEADLOCK_AVOIDANCE(&p->lock);
01612       }
01613       if (!p->owner) {
01614          ast_mutex_unlock(&p->lock);
01615          ast_log(LOG_ERROR, "Channel has no owner\n");
01616          ao2_ref(caps, -1);
01617          return;
01618       }
01619 
01620       if (gH323Debug) {
01621          ast_verb(0, "Readformat before update %s\n", 
01622            ast_format_get_name(ast_channel_readformat(p->owner)));
01623       }
01624       ast_format_cap_append(caps, fmt, 0);
01625       ast_channel_nativeformats_set(p->owner, caps);
01626       ao2_ref(caps, -1);
01627       ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
01628       ast_channel_unlock(p->owner);
01629       } else
01630       ast_log(LOG_ERROR, "No owner found\n");
01631 
01632    ast_mutex_unlock(&p->lock);
01633 
01634    if (gH323Debug)
01635       ast_verb(0, "+++   ooh323_update_readformat\n");
01636 }

static int ooh323_set_rtp_peer ( struct ast_channel chan,
struct ast_rtp_instance rtp,
struct ast_rtp_instance vrtp,
struct ast_rtp_instance trtp,
const struct ast_format_cap codecs,
int  nat_active 
) [static]

Definition at line 4477 of file chan_ooh323.c.

References ast_channel_name(), ast_channel_tech_pvt(), ast_channel_writeformat(), ast_free, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_get_and_cmp_remote_address, ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strdup, ast_verb, ooh323_pvt::callToken, gH323Debug, ooh323_pvt::lock, LOG_ERROR, LOG_WARNING, NULL, ooh323_convertAsteriskCapToH323Cap(), and ooh323_pvt::redirip.

04479 {
04480    /* XXX Deal with Video */
04481    struct ooh323_pvt *p;
04482    int changed = 0;
04483    char *callToken = NULL;
04484 
04485    if (gH323Debug) {
04486       ast_verb(0, "---   ooh323_set_peer - %s\n", ast_channel_name(chan));
04487    }
04488 
04489    if (ooh323_convertAsteriskCapToH323Cap(ast_channel_writeformat(chan)) < 0) {
04490       ast_log(LOG_WARNING, "Unknown format.\n");
04491       return -1;
04492    }
04493    p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
04494    if (!p) {
04495       ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
04496       return -1;
04497    }
04498 
04499    ast_mutex_lock(&p->lock);
04500 
04501    if (rtp) {
04502       changed |= ast_rtp_instance_get_and_cmp_remote_address(rtp, &p->redirip);
04503    } else if (!ast_sockaddr_isnull(&p->redirip)) {
04504       changed = 1;
04505       memset(&p->redirip, 0, sizeof(p->redirip));
04506    }
04507 
04508    callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
04509 
04510    if (!callToken) {
04511       if (gH323Debug) {
04512          ast_verb(0, "  set_rtp_peer - No callToken\n");
04513       }
04514       ast_mutex_unlock(&p->lock);
04515       return -1;
04516    }
04517 
04518 
04519    if (changed) {
04520       if (!ast_sockaddr_isnull(&p->redirip)) {
04521          if (gH323Debug) {
04522             ast_verb(0, "ooh323_set_rtp_peer  %s -> %s:%d\n", ast_channel_name(chan), ast_sockaddr_stringify_addr(&p->redirip),
04523                      ast_sockaddr_port(&p->redirip));
04524          }
04525          ooUpdateLogChannels(callToken, ast_sockaddr_stringify_addr(&p->redirip),
04526                      ast_sockaddr_port(&p->redirip));
04527       } else {
04528          if (gH323Debug) {
04529             ast_verb(0, "ooh323_set_rtp_peer  return back to local\n");
04530          }
04531          ooUpdateLogChannels(callToken, "0.0.0.0" , 0);
04532       }
04533    }
04534 
04535    ast_mutex_unlock(&p->lock);
04536    ast_free(callToken);
04537    return 0;
04538 
04539 }

void ooh323_set_write_format ( ooCallData *  call,
struct ast_format fmt,
int  txframes 
)

Definition at line 1510 of file chan_ooh323.c.

References ao2_ref, ao2_replace, ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_trylock, ast_channel_unlock, ast_channel_writeformat(), ast_debug, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_names(), ast_format_cap_set_framing(), ast_format_get_name(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_codecs_payloads_set_rtpmap_type(), ast_rtp_instance_get_codecs(), ast_set_read_format(), ast_set_write_format(), ast_str_alloca, ast_verb, DEADLOCK_AVOIDANCE, ooh323_pvt::dtmfcodec, ooh323_pvt::dtmfmode, find_call, gH323Debug, H323_DTMF_CISCO, H323_DTMF_RFC2833, ooh323_pvt::lock, LOG_ERROR, NULL, ooh323_pvt::owner, ooh323_pvt::rtp, and ooh323_pvt::writeformat.

Referenced by ooh323c_start_transmit_channel().

01511 {
01512    struct ooh323_pvt *p = NULL;
01513 
01514    if (gH323Debug)
01515       ast_verb(0, "---   ooh323_update_writeformat %s/%d\n", 
01516             ast_format_get_name(fmt), txframes);
01517    
01518    p = find_call(call);
01519    if (!p) {
01520       ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
01521       return;
01522    }
01523 
01524    ast_mutex_lock(&p->lock);
01525 
01526    ao2_replace(p->writeformat, fmt);
01527 
01528    if (p->owner) {
01529       struct ast_format_cap *caps;
01530 
01531       caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
01532       if (!caps) {
01533          ast_log(LOG_ERROR, "Could not allocate capabilities structure\n");
01534          return;
01535       }
01536 
01537       while (p->owner && ast_channel_trylock(p->owner)) {
01538          ast_debug(1,"Failed to grab lock, trying again\n");
01539          DEADLOCK_AVOIDANCE(&p->lock);
01540       }
01541       if (!p->owner) {
01542          ast_mutex_unlock(&p->lock);
01543          ast_log(LOG_ERROR, "Channel has no owner\n");
01544          ao2_ref(caps, -1);
01545          return;
01546       }
01547       if (gH323Debug) {
01548          struct ast_str *codec_buf = ast_str_alloca(64);
01549          ast_verb(0, "Writeformat before update %s/%s\n", 
01550            ast_format_get_name(ast_channel_writeformat(p->owner)),
01551            ast_format_cap_get_names(ast_channel_nativeformats(p->owner), &codec_buf));
01552       }
01553 
01554       if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
01555          ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
01556              p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
01557       }
01558       if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
01559          ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
01560              p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
01561       }
01562 
01563       if (txframes) {
01564          ast_format_cap_set_framing(caps, txframes);
01565       }
01566       ast_format_cap_append(caps, fmt, 0);
01567       ast_channel_nativeformats_set(p->owner, caps);
01568       ao2_ref(caps, -1);
01569       ast_set_write_format(p->owner, ast_channel_writeformat(p->owner));
01570       ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
01571       ast_channel_unlock(p->owner);
01572       } else
01573       ast_log(LOG_ERROR, "No owner found\n");
01574 
01575 
01576    ast_mutex_unlock(&p->lock);
01577 
01578    if (gH323Debug)
01579       ast_verb(0, "+++   ooh323_update_writeformat\n");
01580 }

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

Definition at line 1164 of file chan_ooh323.c.

References ast_channel_name(), ast_channel_nativeformats(), ast_channel_readformat(), ast_channel_tech_pvt(), ast_channel_writeformat(), ast_debug, ast_format_cap_count(), ast_format_cap_get_names(), ast_format_cap_iscompatible_format(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_VOICE, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_write(), ast_set_write_format(), ast_str_alloca, ast_test_flag, ast_udptl_write(), ooh323_pvt::callToken, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, H323_OUTGOING, ast_frame_subclass::integer, ooh323_pvt::lastrtptx, ooh323_pvt::lock, LOG_WARNING, NULL, ooh323_pvt::progsent, ooh323_pvt::rtp, ast_frame::subclass, and ooh323_pvt::udptl.

01165 {
01166    struct ooh323_pvt *p = ast_channel_tech_pvt(ast);
01167    int res = 0;
01168 
01169    if (p) {
01170       ast_mutex_lock(&p->lock);
01171 
01172       p->lastrtptx = time(NULL);
01173 
01174       if (f->frametype == AST_FRAME_MODEM) {
01175          ast_debug(1, "Send UDPTL %u/%d len %d for %s\n",
01176             f->frametype, f->subclass.integer, f->datalen, ast_channel_name(ast));
01177          if (p->udptl)
01178             res = ast_udptl_write(p->udptl, f);
01179          ast_mutex_unlock(&p->lock);
01180          return res;
01181       }
01182 
01183    
01184       if (f->frametype == AST_FRAME_VOICE) {
01185 /* sending progress for first */
01186          if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent &&
01187                p->callToken) {
01188             ooManualProgress(p->callToken);
01189             p->progsent = 1;
01190          }
01191 
01192 
01193          if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
01194             if (ast_format_cap_count(ast_channel_nativeformats(ast))) {
01195                struct ast_str *codec_buf = ast_str_alloca(64);
01196                ast_log(LOG_WARNING,
01197                      "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
01198                      ast_format_get_name(f->subclass.format),
01199                      ast_format_cap_get_names(ast_channel_nativeformats(ast), &codec_buf),
01200                      ast_format_get_name(ast_channel_readformat(ast)),
01201                      ast_format_get_name(ast_channel_writeformat(ast)));
01202 
01203                ast_set_write_format(ast, f->subclass.format);
01204             } else {
01205                /* ast_set_write_format(ast, f->subclass);
01206                ast->nativeformats = f->subclass; */
01207             }
01208          ast_mutex_unlock(&p->lock);
01209          return 0;
01210          }
01211 
01212       if (p->rtp)
01213          res = ast_rtp_instance_write(p->rtp, f);
01214 
01215       ast_mutex_unlock(&p->lock);
01216 
01217       } else if (f->frametype == AST_FRAME_IMAGE) {
01218          ast_mutex_unlock(&p->lock);
01219          return 0;
01220       } else {
01221          ast_log(LOG_WARNING, "Can't send %u type frames with OOH323 write\n", 
01222                             f->frametype);
01223          ast_mutex_unlock(&p->lock);
01224          return 0;
01225       }
01226 
01227    }
01228 
01229    return res;
01230 }

static int reload_config ( int  reload  ) 

Definition at line 2767 of file chan_ooh323.c.

References ast_calloc, ast_category_browse(), ast_channel_string2amaflag(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_false(), ast_format_cap_append, ast_format_cap_remove_by_type(), ast_format_cap_update_by_allow_disallow(), ast_format_ulaw, ast_free, ast_jb_read_conf(), ast_log, AST_MEDIA_TYPE_UNKNOWN, ast_mutex_lock, ast_mutex_unlock, ast_parse_arg(), ast_sockaddr_is_ipv6(), ast_strdup, ast_strdupa, ast_strlen_zero, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, bindaddr, buf, build_peer(), build_user(), config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_CONTEXT, DEFAULT_H323ACCNT, DEFAULT_H323ID, DEFAULT_LOGFILE, delete_peers(), delete_users(), FALSE, FAXDETECT_CNG, FAXDETECT_T38, format, g729onlyA, gAccountcode, gAliasList, gAMAFLAGS, gANIasDNI, gBeMaster, gCallerID, gContext, gDirectRTP, gDTMFCodec, gDTMFMode, gEarlyDirect, gFastStart, gFAXdetect, gGatekeeper, gH323Debug, gIncomingLimit, gIP, gIsGateway, global_jbconf, gLogFile, gMediaWaitForConnect, gNat, gOutgoingLimit, gPort, gRasGkMode, gRTDRCount, gRTDRInterval, gRTPTimeout, gT38Support, gTOS, gTRCLVL, gTunneling, H323_DTMF_CISCO, H323_DTMF_H245ALPHANUMERIC, H323_DTMF_H245SIGNAL, H323_DTMF_INBAND, H323_DTMF_INBANDRELAX, H323_DTMF_Q931, H323_DTMF_RFC2833, ast_variable::lineno, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manufacturer, ooh323_config::mTCPPortEnd, ooh323_config::mTCPPortStart, ast_variable::name, ooh323_user::next, ooh323_peer::next, ast_variable::next, NULL, ooconfig, PARSE_ADDR, peerl, ast_peer_list::peers, RESULT_SUCCESS, strsep(), t35countrycode, t35extensions, T38_DISABLED, T38_ENABLED, T38_FAXGW, tmp(), userl, ast_user_list::users, v6mode, ast_variable::value, vendor, and version.

Referenced by acl_change_stasis_cb(), do_monitor(), handle_cli_iax2_reload(), handle_cli_misdn_reload(), load_module(), ooh323_do_reload(), reload(), and sip_do_reload().

02768 {
02769    int format;
02770    struct ooAliases  *pNewAlias = NULL, *cur, *prev;
02771    struct ast_config *cfg;
02772    struct ast_variable *v;
02773    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
02774    struct ooh323_user *user = NULL;
02775    struct ooh323_peer *peer = NULL;
02776    char *cat;
02777    const char *utype;
02778 
02779    if (gH323Debug)
02780       ast_verb(0, "---   reload_config\n");
02781 
02782    cfg =