Sun Aug 6 15:05:50 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

chan_h323.c File Reference

This file is part of the chan_h323 driver for Asterisk. More...

#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/dsp.h"
#include "asterisk/causes.h"
#include "h323/chan_h323.h"

Include dependency graph for chan_h323.c:

Go to the source code of this file.

Data Structures

struct  rtpPayloadType

Functions

static void __oh323_destroy (struct oh323_pvt *pvt)
static struct ast_channel__oh323_new (struct oh323_pvt *pvt, int state, const char *host)
static void __oh323_update_info (struct ast_channel *c, struct oh323_pvt *pvt)
static int answer_call (unsigned call_reference, const char *token)
 AST_MUTEX_DEFINE_STATIC (h323_reload_lock)
 AST_MUTEX_DEFINE_STATIC (caplock)
 AST_MUTEX_DEFINE_STATIC (monlock)
 AST_MUTEX_DEFINE_STATIC (usecnt_lock)
 AST_MUTEX_DEFINE_STATIC (iflock)
static struct oh323_alias * build_alias (char *name, struct ast_variable *v)
static struct oh323_peer * build_peer (char *name, struct ast_variable *v)
static struct oh323_user * build_user (char *name, struct ast_variable *v)
void chan_ringing (unsigned call_reference, const char *token)
static void cleanup_call_details (call_details_t *cd)
static void cleanup_connection (unsigned call_reference, const char *call_token)
void connection_made (unsigned call_reference, const char *token)
static char * convertcap (int cap)
static int create_addr (struct oh323_pvt *pvt, char *opeer)
void delete_aliases (void)
void delete_users (void)
char * description ()
 Provides a description of the module.
static void * do_monitor (void *data)
rtp_info * external_rtp_create (unsigned call_reference, const char *token)
oh323_alias * find_alias (const char *source_aliases)
static struct oh323_pvtfind_call_locked (int call_reference, const char *token)
oh323_peer * find_peer (const char *peer, struct sockaddr_in *sin)
oh323_user * find_user (const call_details_t *cd)
static int h323_do_debug (int fd, int argc, char *argv[])
static int h323_do_reload (void)
static int h323_do_trace (int fd, int argc, char *argv[])
static int h323_ep_hangup (int fd, int argc, char *argv[])
static int h323_gk_cycle (int fd, int argc, char *argv[])
static int h323_no_debug (int fd, int argc, char *argv[])
static int h323_no_trace (int fd, int argc, char *argv[])
static int h323_reload (int fd, int argc, char *argv[])
static int h323_tokens_show (int fd, int argc, char *argv[])
static void hangup_connection (unsigned int call_reference, const char *token, int cause)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module ()
 Initialize the module.
static struct oh323_pvtoh323_alloc (int callid)
static int oh323_answer (struct ast_channel *c)
static int oh323_call (struct ast_channel *c, char *dest, int timeout)
static void oh323_destroy (struct oh323_pvt *pvt)
static int oh323_digit (struct ast_channel *c, char digit)
static int oh323_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static struct ast_rtpoh323_get_rtp_peer (struct ast_channel *chan)
static struct ast_rtpoh323_get_vrtp_peer (struct ast_channel *chan)
static int oh323_hangup (struct ast_channel *c)
static int oh323_indicate (struct ast_channel *c, int condition)
static struct ast_frameoh323_read (struct ast_channel *c)
static struct ast_channeloh323_request (const char *type, int format, void *data, int *cause)
static struct ast_frameoh323_rtp_read (struct oh323_pvt *pvt)
static int oh323_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
static void oh323_update_info (struct ast_channel *c)
static int oh323_write (struct ast_channel *c, struct ast_frame *frame)
int progress (unsigned call_reference, const char *token, int inband)
void prune_peers (void)
int reload (void)
 Reload stuff.
int reload_config (void)
static int restart_monitor (void)
int send_digit (unsigned call_reference, char digit, const char *token)
void set_dtmf_payload (unsigned call_reference, const char *token, int payload)
static void set_local_capabilities (unsigned call_reference, const char *token)
call_options_t * setup_incoming_call (call_details_t *cd)
int setup_outgoing_call (call_details_t *cd)
void setup_rtp_connection (unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
int unload_module ()
 Cleanup all module structures, sockets, etc.
static int update_common_options (struct ast_variable *v, struct call_options *options)
static int update_state (struct oh323_pvt *pvt, int state, int signal)
int usecount ()
 Provides a usecount.

Variables

static struct ast_alias_list aliasl
static struct sockaddr_in bindaddr
static struct ast_cli_entry cli_debug
static struct ast_cli_entry cli_gk_cycle
static struct ast_cli_entry cli_h323_reload
static struct ast_cli_entry cli_hangup_call
static struct ast_cli_entry cli_no_debug
static struct ast_cli_entry cli_no_trace
static struct ast_cli_entry cli_show_codecs
static struct ast_cli_entry cli_show_tokens
static struct ast_cli_entry cli_trace
static const char config [] = "h323.conf"
static char debug_usage []
static char default_context [AST_MAX_CONTEXT] = "default"
static const char desc [] = "The NuFone Network's Open H.323 Channel Driver"
static char gatekeeper [100]
static int gatekeeper_disable = 1
static int gatekeeper_discover = 0
static int gkroute = 0
static call_options_t global_options
static char h323_reload_usage []
static int h323_reloading = 0
static int h323_signalling_port = 1720
int h323debug
oh323_pvtiflist
static struct io_contextio
static pthread_t monitor_thread = AST_PTHREADT_NULL
static char no_debug_usage []
static char no_trace_usage []
static struct ast_rtp_protocol oh323_rtp
static const struct ast_channel_tech oh323_tech
answer_call_cb on_answer_call
chan_ringing_cb on_chan_ringing
clear_con_cb on_connection_cleared
con_established_cb on_connection_established
on_rtp_cb on_external_rtp_create
hangup_cb on_hangup
setup_incoming_cb on_incoming_call
setup_outbound_cb on_outgoing_call
progress_cb on_progress
send_digit_cb on_send_digit
rfc2833_cb on_set_rfc2833_payload
setcapabilities_cb on_setcapabilities
start_rtp_cb on_start_rtp_channel
static struct ast_peer_list peerl
static struct sched_contextsched
static char secret [50]
static char show_codec_usage []
static char show_cycle_usage []
static char show_hangup_usage []
static char show_tokens_usage []
static const char tdesc [] = "The NuFone Network's Open H.323 Channel Driver"
static int tos = 0
static char trace_usage []
static const char type [] = "H323"
static unsigned int unique = 0
static int usecnt = 0
static int userbyalias = 1
static struct ast_user_list userl
static int usingGk = 0


Detailed Description

This file is part of the chan_h323 driver for Asterisk.

See also

Definition in file chan_h323.c.


Function Documentation

static void __oh323_destroy struct oh323_pvt pvt  )  [static]
 

Definition at line 299 of file chan_h323.c.

References ast_dsp_free(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), oh323_pvt::cd, cleanup_call_details(), free, iflist, oh323_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, oh323_pvt::next, oh323_pvt::owner, oh323_pvt::rtp, ast_channel::tech_pvt, and oh323_pvt::vad.

Referenced by do_monitor(), and oh323_destroy().

00300 {
00301    struct oh323_pvt *cur, *prev = NULL;
00302    
00303    if (pvt->rtp) {
00304       ast_rtp_destroy(pvt->rtp);
00305    }
00306    
00307    /* Free dsp used for in-band DTMF detection */
00308    if (pvt->vad) {
00309       ast_dsp_free(pvt->vad);
00310    }
00311    cleanup_call_details(&pvt->cd);
00312 
00313    /* Unlink us from the owner if we have one */
00314    if (pvt->owner) {
00315       ast_mutex_lock(&pvt->owner->lock);
00316       ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name);
00317       pvt->owner->tech_pvt = NULL;
00318       ast_mutex_unlock(&pvt->owner->lock);
00319    }
00320    cur = iflist;
00321    while(cur) {
00322       if (cur == pvt) {
00323          if (prev)
00324             prev->next = cur->next;
00325          else
00326             iflist = cur->next;
00327          break;
00328       }
00329       prev = cur;
00330       cur = cur->next;
00331    }
00332    if (!cur) {
00333       ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
00334    } else {
00335       ast_mutex_destroy(&pvt->lock);
00336       free(pvt);
00337    }
00338 }

static struct ast_channel* __oh323_new struct oh323_pvt pvt,
int  state,
const char *  host
[static]
 

Definition at line 721 of file chan_h323.c.

References ast_channel::accountcode, oh323_pvt::accountcode, ast_channel::amaflags, oh323_pvt::amaflags, ast_best_codec(), ast_channel_alloc(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtp_fd(), ast_set_callerid(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_update_use_count(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_dnid, oh323_pvt::cid_name, oh323_pvt::cid_num, ast_callerid::cid_rdnis, oh323_pvt::context, ast_channel::context, DSP_FEATURE_DTMF_DETECT, oh323_pvt::exten, ast_channel::exten, ast_channel::fds, fmt, global_options, oh323_pvt::lock, LOG_WARNING, ast_channel::name, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_pvt::options, oh323_pvt::owner, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, oh323_pvt::rdnis, ast_channel::readformat, ast_channel::rings, oh323_pvt::rtp, strdup, ast_channel::tech, ast_channel::tech_pvt, type, ast_channel::type, usecnt, usecnt_lock, oh323_pvt::vad, and ast_channel::writeformat.

Referenced by answer_call(), and oh323_request().

00722 {
00723    struct ast_channel *ch;
00724    int fmt;
00725    
00726    /* Don't hold a oh323_pvt lock while we allocate a chanel */
00727    ast_mutex_unlock(&pvt->lock);
00728    ch = ast_channel_alloc(1);
00729    /* Update usage counter */
00730    ast_mutex_lock(&usecnt_lock);
00731    usecnt++;
00732    ast_mutex_unlock(&usecnt_lock);
00733    ast_update_use_count();
00734    ast_mutex_lock(&pvt->lock);
00735    if (ch) {
00736       ch->tech = &oh323_tech;
00737       snprintf(ch->name, sizeof(ch->name), "H323/%s", host);
00738       ch->nativeformats = pvt->options.capability;
00739       if (!ch->nativeformats) {
00740          ch->nativeformats = global_options.capability;
00741       }
00742       pvt->nativeformats = ch->nativeformats;
00743       fmt = ast_best_codec(ch->nativeformats);
00744       ch->type = type;
00745       ch->fds[0] = ast_rtp_fd(pvt->rtp);
00746       if (state == AST_STATE_RING) {
00747          ch->rings = 1;
00748       }
00749       ch->writeformat = fmt;
00750       ch->rawwriteformat = fmt;
00751       ch->readformat = fmt;
00752       ch->rawreadformat = fmt;
00753       /* Allocate dsp for in-band DTMF support */
00754       if (pvt->options.dtmfmode & H323_DTMF_INBAND) {
00755          pvt->vad = ast_dsp_new();
00756          ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT);
00757          }
00758       /* Register channel functions. */
00759       ch->tech_pvt = pvt;
00760       /*  Set the owner of this channel */
00761       pvt->owner = ch;
00762       
00763       strncpy(ch->context, pvt->context, sizeof(ch->context) - 1);
00764       strncpy(ch->exten, pvt->exten, sizeof(ch->exten) - 1);      
00765       ch->priority = 1;
00766       if (!ast_strlen_zero(pvt->accountcode)) {
00767          strncpy(ch->accountcode, pvt->accountcode, sizeof(ch->accountcode) - 1);
00768       }
00769       if (pvt->amaflags) {
00770          ch->amaflags = pvt->amaflags;
00771       }
00772 
00773       /*
00774        * If cid_num and cdi.call_source_e164 are both null, then
00775        * ast_set_callerid will do the right thing and leave the
00776        * cid_num and cid_ani for the channel alone.
00777        */
00778       ast_set_callerid(ch,
00779          !ast_strlen_zero(pvt->cid_num) ? pvt->cid_num : pvt->cd.call_source_e164,
00780          pvt->cid_name,
00781          !ast_strlen_zero(pvt->cid_num) ? pvt->cid_num : pvt->cd.call_source_e164);
00782 
00783       if (!ast_strlen_zero(pvt->rdnis)) {
00784          ch->cid.cid_rdnis = strdup(pvt->rdnis);
00785       }
00786       if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
00787          ch->cid.cid_dnid = strdup(pvt->exten);
00788       }
00789       ast_setstate(ch, state);
00790       if (state != AST_STATE_DOWN) {
00791          if (ast_pbx_start(ch)) {
00792             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
00793             ast_hangup(ch);
00794             ch = NULL;
00795          }
00796       }
00797    } else  {
00798       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00799    }
00800    return ch;
00801 }

static void __oh323_update_info struct ast_channel c,
struct oh323_pvt pvt
[static]
 

Definition at line 227 of file chan_h323.c.

References ast_channel::_softhangup, ast_log(), ast_queue_control(), ast_queue_hangup(), ast_set_read_format(), ast_set_write_format(), ast_setstate(), AST_SOFTHANGUP_DEV, h323debug, oh323_pvt::hangupcause, ast_channel::hangupcause, LOG_DEBUG, ast_channel::name, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_pvt::needhangup, oh323_pvt::newcontrol, oh323_pvt::newstate, ast_channel::readformat, and ast_channel::writeformat.

Referenced by oh323_read(), oh323_update_info(), and oh323_write().

00228 {
00229    if (c->nativeformats != pvt->nativeformats) {
00230       if (h323debug)
00231          ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name);
00232       c->nativeformats = pvt->nativeformats;
00233       ast_set_read_format(c, c->readformat);
00234       ast_set_write_format(c, c->writeformat);
00235    }
00236    if (pvt->needhangup) {
00237       if (h323debug)
00238          ast_log(LOG_DEBUG, "Process pending hangup for %s\n", c->name);
00239       c->_softhangup |= AST_SOFTHANGUP_DEV;
00240       c->hangupcause = pvt->hangupcause;
00241       ast_queue_hangup(c);
00242       pvt->needhangup = 0;
00243       pvt->newstate = pvt->newcontrol = -1;
00244    }
00245    if (pvt->newstate >= 0) {
00246       ast_setstate(c, pvt->newstate);
00247       pvt->newstate = -1;
00248    }
00249    if (pvt->newcontrol >= 0) {
00250       ast_queue_control(c, pvt->newcontrol);
00251       pvt->newcontrol = -1;
00252    }
00253 }

static int answer_call unsigned  call_reference,
const char *  token
[static]
 

Call-back function to start PBX when OpenH323 ready to serve incoming call

Returns 1 on success

Definition at line 1393 of file chan_h323.c.

References __oh323_new(), ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, oh323_pvt::cd, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, and LOG_ERROR.

Referenced by load_module().

01394 {
01395    struct oh323_pvt *pvt;
01396    struct ast_channel *c = NULL;
01397 
01398    if (h323debug)
01399       ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token);
01400 
01401    /* Find the call or allocate a private structure if call not found */
01402    pvt = find_call_locked(call_reference, token); 
01403    if (!pvt) {
01404       ast_log(LOG_ERROR, "Something is wrong: answer_call\n");
01405       return 0;
01406    }
01407    /* allocate a channel and tell asterisk about it */
01408    c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token);
01409 
01410    /* And release when done */
01411    ast_mutex_unlock(&pvt->lock);
01412    if (!c) {
01413       ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n");
01414       return 0;
01415    }
01416    return 1;
01417 }

AST_MUTEX_DEFINE_STATIC h323_reload_lock   ) 
 

AST_MUTEX_DEFINE_STATIC caplock   ) 
 

AST_MUTEX_DEFINE_STATIC monlock   ) 
 

AST_MUTEX_DEFINE_STATIC usecnt_lock   ) 
 

AST_MUTEX_DEFINE_STATIC iflock   ) 
 

Protect the interface list (oh323_pvt)

static struct oh323_alias* build_alias char *  name,
struct ast_variable v
[static]
 

Definition at line 1854 of file chan_h323.c.

References ast_log(), LOG_WARNING, malloc, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by reload_config().

01855 {
01856    struct oh323_alias *alias;
01857 
01858    alias = (struct oh323_alias *)malloc(sizeof(struct oh323_alias));
01859    if (alias) {
01860       memset(alias, 0, sizeof(struct oh323_alias));
01861       strncpy(alias->name, name, sizeof(alias->name) - 1);
01862       while (v) {
01863          if (!strcasecmp(v->name, "e164")) {
01864             strncpy(alias->e164,  v->value, sizeof(alias->e164) - 1);
01865          } else if (!strcasecmp(v->name, "prefix")) {
01866             strncpy(alias->prefix,  v->value, sizeof(alias->prefix) - 1);
01867          } else if (!strcasecmp(v->name, "context")) {
01868             strncpy(alias->context,  v->value, sizeof(alias->context) - 1);
01869          } else if (!strcasecmp(v->name, "secret")) {
01870             strncpy(alias->secret,  v->value, sizeof(alias->secret) - 1);
01871          } else {
01872             if (strcasecmp(v->value, "h323")) {    
01873                ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->value);
01874             }
01875          }
01876          v = v->next;
01877       }
01878    }
01879    return alias;
01880 }

static struct oh323_peer* build_peer char *  name,
struct ast_variable v
[static]
 

Definition at line 1930 of file chan_h323.c.

References ast_get_ip(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), free, global_options, h323_signalling_port, ast_peer_list::lock, LOG_ERROR, malloc, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, update_common_options(), and ast_variable::value.

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

01931 {
01932    struct oh323_peer *peer;
01933    struct oh323_peer *prev;
01934    struct ast_ha *oldha = NULL;
01935    int found=0;
01936 
01937    prev = NULL;
01938    ast_mutex_lock(&peerl.lock);
01939    peer = peerl.peers;
01940 
01941    while(peer) {
01942       if (!strcasecmp(peer->name, name)) {   
01943          break;
01944       }
01945       prev = peer;
01946       peer = peer->next;
01947    }
01948 
01949    if (peer) {
01950       found++;
01951       /* Already in the list, remove it and it will be added back (or FREE'd) */
01952       if (prev) {
01953          prev->next = peer->next;
01954       } else {
01955          peerl.peers = peer->next;
01956       }
01957       ast_mutex_unlock(&peerl.lock);
01958    } else {
01959       ast_mutex_unlock(&peerl.lock);
01960       peer = (struct oh323_peer*)malloc(sizeof(struct oh323_peer));
01961       if (peer)
01962          memset(peer, 0, sizeof(struct oh323_peer));
01963    }
01964    if (peer) {
01965       if (!found) {
01966          strncpy(peer->name, name, sizeof(peer->name) - 1);
01967          peer->addr.sin_port = htons(h323_signalling_port);
01968          peer->addr.sin_family = AF_INET;
01969       }
01970       oldha = peer->ha;
01971       peer->ha = NULL;
01972       peer->addr.sin_family = AF_INET;
01973       memcpy(&peer->options, &global_options, sizeof(peer->options));
01974 
01975       while(v) {
01976          if (!update_common_options(v, &peer->options)) {
01977             /* dummy */
01978          } else if (!strcasecmp(v->name, "host")) {
01979             if (!strcasecmp(v->value, "dynamic")) {
01980                ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");
01981                free(peer);
01982                return NULL;
01983             }
01984             if (ast_get_ip(&peer->addr, v->value)) {
01985                   ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
01986                   free(peer);
01987                   return NULL;
01988             }
01989          } else if (!strcasecmp(v->name, "port")) {
01990             peer->addr.sin_port = htons(atoi(v->value));
01991          }
01992          v=v->next;
01993       }
01994    }
01995    return peer;
01996 }

static struct oh323_user* build_user char *  name,
struct ast_variable v
[static]
 

Definition at line 1882 of file chan_h323.c.

References ast_cdr_amaflags2int(), ast_get_ip(), ast_log(), default_context, format, free, global_options, ast_variable::lineno, LOG_ERROR, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, update_common_options(), user, and ast_variable::value.

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

01883 {
01884    struct oh323_user *user;
01885    int format;
01886 
01887    user = (struct oh323_user *)malloc(sizeof(struct oh323_user));
01888    if (user) {
01889       memset(user, 0, sizeof(struct oh323_user));
01890       strncpy(user->name, name, sizeof(user->name) - 1);
01891       memcpy(&user->options, &global_options, sizeof(user->options));
01892       /* Set default context */
01893       strncpy(user->context, default_context, sizeof(user->context) - 1);
01894       while(v) {
01895          if (!strcasecmp(v->name, "context")) {
01896             strncpy(user->context, v->value, sizeof(user->context) - 1);
01897          } else if (!update_common_options(v, &user->options)) {
01898             /* dummy */
01899          } else if (!strcasecmp(v->name, "secret")) {
01900             strncpy(user->secret, v->value, sizeof(user->secret) - 1);
01901          } else if (!strcasecmp(v->name, "callerid")) {
01902             strncpy(user->callerid, v->value, sizeof(user->callerid) - 1);
01903          } else if (!strcasecmp(v->name, "accountcode")) {
01904             strncpy(user->accountcode, v->value, sizeof(user->accountcode) - 1);
01905          } else if (!strcasecmp(v->name, "host")) {
01906             if (!strcasecmp(v->value, "dynamic")) {
01907                ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
01908                free(user);
01909                return NULL;
01910             } else if (ast_get_ip(&user->addr, v->value)) {
01911                free(user);
01912                return NULL;
01913             } 
01914             /* Let us know we need to use ip authentication */
01915             user->host = 1;
01916          } else if (!strcasecmp(v->name, "amaflags")) {
01917             format = ast_cdr_amaflags2int(v->value);
01918             if (format < 0) {
01919                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
01920             } else {
01921                user->amaflags = format;
01922             }
01923          }
01924          v = v->next;
01925       }
01926    }
01927    return user;
01928 }

void chan_ringing unsigned  call_reference,
const char *  token
 

Call-back function to signal asterisk that the channel is ringing Returns nothing

Definition at line 1436 of file chan_h323.c.

References AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, find_call_locked(), h323debug, ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state().

Referenced by load_module().

01437 {
01438    struct oh323_pvt *pvt;
01439 
01440    if (h323debug)
01441       ast_log(LOG_DEBUG, "Ringing on %s\n", token);
01442 
01443    pvt = find_call_locked(call_reference, token); 
01444    if (!pvt) {
01445       ast_log(LOG_ERROR, "Something is wrong: ringing\n");
01446       return;
01447    }
01448    if (!pvt->owner) {
01449       ast_mutex_unlock(&pvt->lock);
01450       ast_log(LOG_ERROR, "Channel has no owner\n");
01451       return;
01452    }
01453    if (update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING))
01454       ast_mutex_unlock(&pvt->owner->lock);
01455    ast_mutex_unlock(&pvt->lock);
01456    return;
01457 }

static void cleanup_call_details call_details_t *  cd  )  [static]
 

Definition at line 267 of file chan_h323.c.

References free.

Referenced by __oh323_destroy(), cleanup_connection(), and setup_outgoing_call().

00268 {
00269         if (cd->call_token) {
00270                 free(cd->call_token);
00271                 cd->call_token = NULL;
00272         }
00273         if (cd->call_source_aliases) {
00274                 free(cd->call_source_aliases);
00275                 cd->call_source_aliases = NULL;
00276         }
00277         if (cd->call_dest_alias) {
00278                 free(cd->call_dest_alias);
00279                 cd->call_dest_alias = NULL;
00280    }
00281         if (cd->call_source_name) { 
00282                 free(cd->call_source_name);
00283                 cd->call_source_name = NULL;
00284         }
00285         if (cd->call_source_e164) {
00286                 free(cd->call_source_e164);
00287                 cd->call_source_e164 = NULL;
00288         }
00289         if (cd->call_dest_e164) {
00290                 free(cd->call_dest_e164);
00291                 cd->call_dest_e164 = NULL;
00292         }
00293         if (cd->sourceIp) {
00294                 free(cd->sourceIp);
00295                 cd->sourceIp = NULL;
00296         }
00297 }

static void cleanup_connection unsigned  call_reference,
const char *  call_token
[static]
 

Call-back function to cleanup communication Returns nothing,

Definition at line 1463 of file chan_h323.c.

References ast_channel::_softhangup, oh323_pvt::alreadygone, ast_dsp_free(), ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_rtp_destroy(), AST_SOFTHANGUP_DEV, oh323_pvt::cd, cleanup_call_details(), find_call_locked(), h323debug, oh323_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, oh323_pvt::owner, oh323_pvt::rtp, and oh323_pvt::vad.

Referenced by load_module().

01464 {  
01465    struct oh323_pvt *pvt;
01466 
01467    ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token);
01468    
01469    while (1) {
01470       pvt = find_call_locked(call_reference, call_token); 
01471       if (!pvt) {
01472          if (h323debug)
01473             ast_log(LOG_DEBUG, "No connection for %s\n", call_token);
01474          return;
01475       }
01476       if (!pvt->owner || !ast_mutex_trylock(&pvt->owner->lock))
01477          break;
01478 #if 1
01479 #ifdef DEBUG_THREADS
01480       ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s, locked at %ld/%d by %s (%s:%d)\n", call_token, pvt->owner->lock.thread, pvt->owner->lock.reentrancy, pvt->owner->lock.func, pvt->owner->lock.file, pvt->owner->lock.lineno);
01481 #else
01482       ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token);
01483 #endif
01484 #endif
01485       ast_mutex_unlock(&pvt->lock);
01486       usleep(1);
01487    }
01488    if (pvt->rtp) {
01489       /* Immediately stop RTP */
01490       ast_rtp_destroy(pvt->rtp);
01491       pvt->rtp = NULL;
01492    }
01493    /* Free dsp used for in-band DTMF detection */
01494    if (pvt->vad) {
01495       ast_dsp_free(pvt->vad);
01496       pvt->vad = NULL;
01497    }
01498    cleanup_call_details(&pvt->cd);
01499    pvt->alreadygone = 1;
01500    /* Send hangup */ 
01501    if (pvt->owner) {
01502       pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
01503       ast_queue_hangup(pvt->owner);
01504       ast_mutex_unlock(&pvt->owner->lock);
01505    }
01506    ast_mutex_unlock(&pvt->lock);
01507    if (h323debug)
01508       ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token);
01509    return;  
01510 }

void connection_made unsigned  call_reference,
const char *  token
 

Call-back function to signal asterisk that the channel has been answered Returns nothing

Definition at line 1235 of file chan_h323.c.

References AST_CONTROL_ANSWER, ast_log(), ast_mutex_unlock(), AST_STATE_UP, find_call_locked(), h323debug, ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::outgoing, oh323_pvt::owner, and update_state().

Referenced by load_module().

01236 {
01237    struct oh323_pvt *pvt;
01238 
01239    if (h323debug)
01240       ast_log(LOG_DEBUG, "Call %s answered\n", token);
01241 
01242    pvt = find_call_locked(call_reference, token); 
01243    if (!pvt) {
01244       ast_log(LOG_ERROR, "Something is wrong: connection\n");
01245       return;
01246    }
01247 
01248    /* Inform asterisk about remote party connected only on outgoing calls */
01249    if (!pvt->outgoing) {
01250       ast_mutex_unlock(&pvt->lock);
01251       return;
01252    }
01253    if (update_state(pvt, AST_STATE_UP, AST_CONTROL_ANSWER))
01254       ast_mutex_unlock(&pvt->owner->lock);
01255    ast_mutex_unlock(&pvt->lock);
01256    return;
01257 }

static char* convertcap int  cap  )  [static]
 

Definition at line 2258 of file chan_h323.c.

References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), and LOG_NOTICE.

Referenced by oh323_set_rtp_peer().

02259 {
02260    switch (cap) {
02261    case AST_FORMAT_G723_1:
02262       return "G.723";
02263    case AST_FORMAT_GSM:
02264       return "GSM";
02265    case AST_FORMAT_ULAW:
02266       return "ULAW";
02267    case AST_FORMAT_ALAW:
02268       return "ALAW";
02269    case AST_FORMAT_ADPCM:
02270       return "G.728";
02271    case AST_FORMAT_G729A:
02272       return "G.729";
02273    case AST_FORMAT_SPEEX:
02274       return "SPEEX";
02275    case AST_FORMAT_ILBC:
02276       return "ILBC";
02277    default:
02278       ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap);
02279       return NULL;
02280    }
02281 }

static int create_addr struct oh323_pvt pvt,
char *  opeer
[static]
 

Definition at line 949 of file chan_h323.c.

References ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setnat(), find_peer(), global_options, h323_signalling_port, hp, ast_peer_list::lock, LOG_DEBUG, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_pvt::options, peerl, portno, oh323_pvt::rtp, and oh323_pvt::sa.

Referenced by cache_get_callno_locked(), iax2_call(), iax2_provision(), iax2_request(), oh323_request(), sip_notify(), sip_request_call(), and transmit_register().

00950 {
00951    struct hostent *hp;
00952    struct ast_hostent ahp;
00953    struct oh323_peer *p;
00954    int portno;
00955    int found = 0;
00956    char *port;
00957    char *hostn;
00958    char peer[256] = "";
00959 
00960    strncpy(peer, opeer, sizeof(peer) - 1);
00961    port = strchr(peer, ':');
00962    if (port) {
00963       *port = '\0';
00964       port++;
00965    }
00966    pvt->sa.sin_family = AF_INET;
00967    ast_mutex_lock(&peerl.lock);
00968    p = find_peer(peer, NULL);
00969    if (p) {
00970       found++;
00971       memcpy(&pvt->options, &p->options, sizeof(pvt->options));
00972       if (pvt->rtp) {
00973          ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
00974          ast_rtp_setnat(pvt->rtp, pvt->options.nat);
00975       }
00976       if (pvt->options.dtmfmode) {
00977          if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
00978             pvt->nonCodecCapability |= AST_RTP_DTMF;
00979          } else {
00980             pvt->nonCodecCapability &= ~AST_RTP_DTMF;
00981          }
00982       }
00983       if (p->addr.sin_addr.s_addr) {
00984          pvt->sa.sin_addr = p->addr.sin_addr;   
00985          pvt->sa.sin_port = p->addr.sin_port;   
00986       } 
00987    }
00988    ast_mutex_unlock(&peerl.lock);
00989    if (!p && !found) {
00990       hostn = peer;
00991       if (port) {
00992          portno = atoi(port);
00993       } else {
00994          portno = h323_signalling_port;
00995       }     
00996       hp = ast_gethostbyname(hostn, &ahp);
00997       if (hp) {
00998          memcpy(&pvt->options, &global_options, sizeof(pvt->options));
00999          memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
01000          pvt->sa.sin_port = htons(portno);
01001          return 0;   
01002       } else {
01003          ast_log(LOG_WARNING, "No such host: %s\n", peer);
01004          return -1;
01005       }
01006    } else if (!p) {
01007       return -1;
01008    } else { 
01009       return 0;
01010    }
01011 }

void delete_aliases void   ) 
 

Definition at line 2174 of file chan_h323.c.

References ast_alias_list::aliases, aliasl, ast_mutex_lock(), ast_mutex_unlock(), free, and ast_alias_list::lock.

Referenced by h323_do_reload(), and unload_module().

02175 {
02176    struct oh323_alias *alias, *aliaslast;
02177       
02178    /* Delete all users */
02179    ast_mutex_lock(&aliasl.lock);
02180    for (alias=aliasl.aliases;alias;) {
02181       aliaslast = alias;
02182       alias=alias->next;
02183       free(aliaslast);
02184    }
02185    aliasl.aliases=NULL;
02186    ast_mutex_unlock(&aliasl.lock);
02187 }

void delete_users void   ) 
 

Definition at line 2151 of file chan_h323.c.

References ast_mutex_lock(), ast_mutex_unlock(), free, ast_peer_list::lock, ast_user_list::lock, peerl, ast_peer_list::peers, user, userl, and ast_user_list::users.

Referenced by __unload_module(), h323_do_reload(), and unload_module().

02152 {
02153    struct oh323_user *user, *userlast;
02154    struct oh323_peer *peer;
02155    
02156    /* Delete all users */
02157    ast_mutex_lock(&userl.lock);
02158    for (user=userl.users;user;) {
02159       userlast = user;
02160       user=user->next;
02161       free(userlast);
02162    }
02163    userl.users=NULL;
02164    ast_mutex_unlock(&userl.lock);
02165    ast_mutex_lock(&peerl.lock);
02166    for (peer=peerl.peers;peer;) {
02167       /* Assume all will be deleted, and we'll find out for sure later */
02168       peer->delme = 1;
02169       peer = peer->next;
02170    }
02171    ast_mutex_unlock(&peerl.lock);
02172 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 2462 of file chan_h323.c.

References desc.

02463 {
02464    return (char *) desc;
02465 }

static void* do_monitor void *  data  )  [static]
 

Definition at line 1575 of file chan_h323.c.

References __oh323_destroy(), ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_verbose(), h323_do_reload(), h323_reloading, iflist, oh323_pvt::needdestroy, oh323_pvt::next, option_verbose, and VERBOSE_PREFIX_1.

Referenced by restart_monitor().

01576 {
01577    int res;
01578    int reloading;
01579    struct oh323_pvt *oh323 = NULL;
01580    
01581    for(;;) {
01582       /* Check for a reload request */
01583       ast_mutex_lock(&h323_reload_lock);
01584       reloading = h323_reloading;
01585       h323_reloading = 0;
01586       ast_mutex_unlock(&h323_reload_lock);
01587       if (reloading) {
01588          if (option_verbose > 0) {
01589             ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n");
01590          }
01591          h323_do_reload();
01592       }
01593       /* Check for interfaces needing to be killed */
01594       ast_mutex_lock(&iflock);
01595 restartsearch:    
01596       oh323 = iflist;
01597       while(oh323) {
01598          if (oh323->needdestroy) {
01599             __oh323_destroy(oh323);
01600             goto restartsearch;
01601          }
01602          oh323 = oh323->next;
01603       }
01604       ast_mutex_unlock(&iflock);
01605       pthread_testcancel();
01606       /* Wait for sched or io */
01607       res = ast_sched_wait(sched);
01608       if ((res < 0) || (res > 1000)) {
01609          res = 1000;
01610       }
01611       res = ast_io_wait(io, res);
01612       pthread_testcancel();
01613       ast_mutex_lock(&monlock);
01614       if (res >= 0) {
01615          ast_sched_runq(sched);
01616       }
01617       ast_mutex_unlock(&monlock);
01618    }
01619    /* Never reached */
01620    return NULL;
01621 }

struct rtp_info* external_rtp_create unsigned  call_reference,
const char *  token
 

Callback function used to inform the H.323 stack of the local rtp ip/port details

Returns the local RTP information

Definition at line 1140 of file chan_h323.c.

References ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_rtp_get_us(), find_call_locked(), free, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, malloc, and oh323_pvt::rtp.

Referenced by load_module().

01141 {  
01142    struct oh323_pvt *pvt;
01143    struct sockaddr_in us;
01144    struct rtp_info *info;
01145 
01146    info = (struct rtp_info *)malloc(sizeof(struct rtp_info));
01147    if (!info) {
01148       ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n");
01149       return NULL;
01150    }
01151    pvt = find_call_locked(call_reference, token); 
01152    if (!pvt) {
01153       free(info);
01154       ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference);
01155       return NULL;
01156    }
01157    /* figure out our local RTP port and tell the H.323 stack about it */
01158    ast_rtp_get_us(pvt->rtp, &us);
01159    ast_mutex_unlock(&pvt->lock);
01160 
01161    ast_inet_ntoa(info->addr, sizeof(info->addr), us.sin_addr);
01162    info->port = ntohs(us.sin_port);
01163    if (h323debug)
01164       ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port);
01165    return info;
01166 }

struct oh323_alias* find_alias const char *  source_aliases  ) 
 

Find a call by alias

Definition at line 1091 of file chan_h323.c.

References ast_alias_list::aliases, and aliasl.

Referenced by __get_header(), and setup_incoming_call().

01092 {
01093    struct oh323_alias *a;
01094 
01095    a = aliasl.aliases;
01096    while(a) {
01097       if (!strcasecmp(a->name, source_aliases)) {
01098          break;
01099       }
01100       a = a->next;
01101    }
01102    return a;
01103 }

static struct oh323_pvt* find_call_locked int  call_reference,
const char *  token
[static]
 

Definition at line 847 of file chan_h323.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::cd, iflist, oh323_pvt::lock, LOG_WARNING, oh323_pvt::needdestroy, and oh323_pvt::next.

Referenced by answer_call(), chan_ringing(), cleanup_connection(), connection_made(), external_rtp_create(), hangup_connection(), progress(), send_digit(), set_dtmf_payload(), set_local_capabilities(), and setup_rtp_connection().

00848 {  
00849    struct oh323_pvt *pvt;
00850 
00851    ast_mutex_lock(&iflock);
00852    pvt = iflist; 
00853    while(pvt) {
00854       if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) {
00855          /* Found the call */             
00856          if ((token != NULL) && (!strcmp(pvt->cd.call_token, token))) {
00857             ast_mutex_lock(&pvt->lock);
00858             ast_mutex_unlock(&iflock);
00859             return pvt;
00860          } else if (token == NULL) {
00861             ast_log(LOG_WARNING, "Call Token is NULL\n");
00862             ast_mutex_lock(&pvt->lock);
00863             ast_mutex_unlock(&iflock);
00864             return pvt;
00865          }
00866       }
00867       pvt = pvt->next; 
00868    }
00869    ast_mutex_unlock(&iflock);
00870    return NULL;
00871 }

struct oh323_peer* find_peer const char *  peer,
struct sockaddr_in *  sin
 

Definition at line 916 of file chan_h323.c.

References ast_inet_ntoa(), ast_log(), inaddrcmp(), LOG_DEBUG, peerl, and ast_peer_list::peers.

Referenced by _sip_show_peer(), check_user_full(), create_addr(), dundi_encrypt(), function_iaxpeer(), function_sippeer(), handle_command_response(), iax2_devicestate(), iax2_prune_realtime(), iax2_show_peer(), register_verify(), registry_authrequest(), sip_devicestate(), sip_do_debug_peer(), update_call_counter(), and update_registry().

00917 {
00918    struct oh323_peer *p = NULL;
00919          static char iabuf[INET_ADDRSTRLEN];
00920 
00921    p = peerl.peers;
00922    if (peer) {
00923       while(p) {
00924          if (!strcasecmp(p->name, peer)) {
00925             ast_log(LOG_DEBUG, "Found peer %s by name\n", peer);
00926             break;
00927          }
00928          p = p->next;
00929       }
00930    } else {
00931       /* find by sin */
00932       if (sin) {
00933          while (p) {
00934             if ((!inaddrcmp(&p->addr, sin)) || 
00935                (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
00936                ast_log(LOG_DEBUG, "Found peer %s/%s by addr\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr));
00937                break;
00938             }
00939             p = p->next;
00940          }
00941       }  
00942    }
00943    if (!p) {
00944       ast_log(LOG_DEBUG, "Could not find peer %s by name or address\n", peer);
00945    }
00946    return p;
00947 }

struct oh323_user* find_user const call_details_t *  cd  ) 
 

Definition at line 893 of file chan_h323.c.

References ast_inet_ntoa(), userbyalias, userl, and ast_user_list::users.

Referenced by admin_exec(), advanced_options(), check_user_full(), forward_message(), leave_voicemail(), setup_incoming_call(), sip_show_user(), update_call_counter(), vm_authenticate(), vm_box_exists(), and vm_execmain().

00894 {
00895    struct oh323_user *u;
00896    char iabuf[INET_ADDRSTRLEN];
00897    u = userl.users;
00898    if (userbyalias) {
00899       while(u) {
00900          if (!strcasecmp(u->name, cd->call_source_aliases)) {
00901             break;
00902          }
00903          u = u->next;
00904       }
00905    } else {
00906       while(u) {
00907          if (!strcasecmp(cd->sourceIp, ast_inet_ntoa(iabuf, sizeof(iabuf), u->addr.sin_addr))) {
00908             break;
00909          }
00910          u = u->next;
00911       }
00912    }
00913    return u;
00914 }

static int h323_do_debug int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1677 of file chan_h323.c.

References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01678 {
01679    if (argc != 2) {
01680       return RESULT_SHOWUSAGE;
01681    }
01682    h323debug = 1;
01683    ast_cli(fd, "H323 debug enabled\n");
01684    return RESULT_SUCCESS;
01685 }

static int h323_do_reload void   )  [static]
 

Definition at line 2225 of file chan_h323.c.

References delete_aliases(), delete_users(), prune_peers(), reload_config(), and restart_monitor().

Referenced by do_monitor().

02226 {
02227    delete_users();
02228    delete_aliases();
02229    prune_peers();
02230    reload_config();
02231    restart_monitor();
02232    return 0;
02233 }

static int h323_do_trace int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1657 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01658 {
01659    if (argc != 3) {
01660       return RESULT_SHOWUSAGE;
01661    }
01662    h323_debug(1, atoi(argv[2]));
01663    ast_cli(fd, "H.323 trace set to level %s\n", argv[2]);
01664    return RESULT_SUCCESS;
01665 }

static int h323_ep_hangup int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1715 of file chan_h323.c.

References ast_verbose(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and VERBOSE_PREFIX_3.

01716 {
01717         if (argc != 3) {
01718                 return RESULT_SHOWUSAGE;
01719    }
01720    if (h323_soft_hangup(argv[2])) {
01721       ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]);
01722    } else { 
01723       ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]);
01724    }
01725    return RESULT_SUCCESS;
01726 }

static int h323_gk_cycle int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1697 of file chan_h323.c.

References ast_log(), gatekeeper, gatekeeper_disable, gatekeeper_discover, LOG_ERROR, RESULT_SHOWUSAGE, RESULT_SUCCESS, and secret.

01698 {
01699 #if 0
01700    if (argc != 3) {
01701       return RESULT_SHOWUSAGE;
01702    }  
01703    h323_gk_urq();
01704    
01705    /* Possibly register with a GK */
01706    if (!gatekeeper_disable) {
01707       if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
01708          ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
01709       }
01710    }
01711 #endif
01712    return RESULT_SUCCESS;
01713 }

static int h323_no_debug int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1687 of file chan_h323.c.

References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01688 {
01689    if (argc != 3) {
01690       return RESULT_SHOWUSAGE;
01691    }
01692    h323debug = 0;
01693    ast_cli(fd, "H323 Debug disabled\n");
01694    return RESULT_SUCCESS;
01695 }

static int h323_no_trace int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1667 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01668 {
01669    if (argc != 3) {
01670       return RESULT_SHOWUSAGE;
01671    }
01672    h323_debug(0,0);
01673    ast_cli(fd, "H.323 trace disabled\n");
01674    return RESULT_SUCCESS;
01675 }

static int h323_reload int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 2212 of file chan_h323.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), h323_reloading, and restart_monitor().

Referenced by reload().

02213 {
02214    ast_mutex_lock(&h323_reload_lock);
02215    if (h323_reloading) {
02216       ast_verbose("Previous H.323 reload not yet done\n");
02217    } else {
02218       h323_reloading = 1;
02219    }
02220    ast_mutex_unlock(&h323_reload_lock);
02221    restart_monitor();
02222    return 0;
02223 }

static int h323_tokens_show int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1728 of file chan_h323.c.

References RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01729 {
01730         if (argc != 3) {
01731                 return RESULT_SHOWUSAGE;
01732    }
01733    h323_show_tokens();
01734    return RESULT_SUCCESS;
01735 }

static void hangup_connection unsigned int  call_reference,
const char *  token,
int  cause
[static]
 

Definition at line 1512 of file chan_h323.c.

References ast_channel::_softhangup, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), AST_SOFTHANGUP_DEV, find_call_locked(), oh323_pvt::hangupcause, ast_channel::hangupcause, oh323_pvt::lock, ast_channel::lock, LOG_DEBUG, oh323_pvt::needhangup, and oh323_pvt::owner.

Referenced by load_module().

01513 {
01514    struct oh323_pvt *pvt;
01515 
01516    ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause);
01517    
01518    pvt = find_call_locked(call_reference, token); 
01519    if (!pvt) {
01520       return;
01521    }
01522    if (pvt->owner && !ast_mutex_trylock(&pvt->owner->lock)) {
01523       pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV;
01524       pvt->owner->hangupcause = pvt->hangupcause = cause;
01525       ast_queue_hangup(pvt->owner);
01526       ast_mutex_unlock(&pvt->owner->lock);
01527    }
01528    else {
01529       pvt->needhangup = 1;
01530       pvt->hangupcause = cause;
01531       ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token);
01532    }
01533    ast_mutex_unlock(&pvt->lock);
01534 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 2467 of file chan_h323.c.

References ASTERISK_GPL_KEY.

02468 {
02469    return ASTERISK_GPL_KEY;
02470 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 2315 of file chan_h323.c.

References aliasl, answer_call(), ast_channel_register(), ast_cli_register(), ast_log(), ast_mutex_init(), ast_rtp_proto_register(), bindaddr, chan_ringing(), cleanup_connection(), connection_made(), external_rtp_create(), gatekeeper, gatekeeper_disable, gatekeeper_discover, h323_signalling_port, hangup_connection(), io_context_create(), ast_alias_list::lock, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_WARNING, peerl, reload_config(), restart_monitor(), sched_context_create(), secret, send_digit(), set_dtmf_payload(), set_local_capabilities(), setup_incoming_call(), setup_outgoing_call(), setup_rtp_connection(), type, and userl.

02316 {
02317    int res;
02318    ast_mutex_init(&userl.lock);
02319    ast_mutex_init(&peerl.lock);
02320    ast_mutex_init(&aliasl.lock);
02321    sched = sched_context_create();
02322    if (!sched) {
02323       ast_log(LOG_WARNING, "Unable to create schedule context\n");
02324    }
02325    io = io_context_create();
02326    if (!io) {
02327       ast_log(LOG_WARNING, "Unable to create I/O context\n");
02328    }
02329    res = reload_config();
02330    if (res) {
02331       return 0;
02332    } else {
02333       /* Make sure we can register our channel type */
02334       if (ast_channel_register(&oh323_tech)) {
02335          ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
02336          h323_end_process();
02337          return -1;
02338       }
02339       ast_cli_register(&cli_debug);
02340       ast_cli_register(&cli_no_debug);
02341       ast_cli_register(&cli_trace);
02342       ast_cli_register(&cli_no_trace);
02343       ast_cli_register(&cli_show_codecs);
02344       ast_cli_register(&cli_gk_cycle);
02345       ast_cli_register(&cli_hangup_call);
02346       ast_cli_register(&cli_show_tokens);
02347       ast_cli_register(&cli_h323_reload);
02348 
02349       ast_rtp_proto_register(&oh323_rtp);
02350 
02351       /* Register our callback functions */
02352       h323_callback_register(setup_incoming_call, 
02353                   setup_outgoing_call,                    
02354                   external_rtp_create, 
02355                   setup_rtp_connection, 
02356                   cleanup_connection, 
02357                   chan_ringing,
02358                   connection_made, 
02359                   send_digit,
02360                   answer_call,
02361                   progress,
02362                   set_dtmf_payload,
02363                   hangup_connection,
02364                   set_local_capabilities);
02365       /* start the h.323 listener */
02366       if (h323_start_listener(h323_signalling_port, bindaddr)) {
02367          ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
02368          return -1;
02369       }
02370       /* Possibly register with a GK */
02371       if (!gatekeeper_disable) {
02372          if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
02373             ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
02374             return 0;
02375          }
02376       }
02377       /* And start the monitor for the first time */
02378       restart_monitor();
02379    }
02380    return res;
02381 }

static struct oh323_pvt* oh323_alloc int  callid  )  [static]
 

Definition at line 803 of file chan_h323.c.

References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_settos(), bindaddr, oh323_pvt::cd, oh323_pvt::context, default_context, free, global_options, iflist, oh323_pvt::lock, LOG_ERROR, LOG_WARNING, malloc, oh323_pvt::newcontrol, oh323_pvt::newstate, oh323_pvt::next, oh323_pvt::nonCodecCapability, oh323_pvt::options, oh323_pvt::rtp, and tos.

Referenced by oh323_request(), and setup_incoming_call().

00804 {
00805    struct oh323_pvt *pvt;
00806 
00807    pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt));
00808    if (!pvt) {
00809       ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");
00810       return NULL;
00811    }
00812    memset(pvt, 0, sizeof(struct oh323_pvt));
00813    pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0,bindaddr.sin_addr);
00814    if (!pvt->rtp) {
00815       ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
00816       free(pvt);
00817       return NULL;
00818    }
00819    ast_rtp_settos(pvt->rtp, tos);
00820    ast_mutex_init(&pvt->lock);
00821    /* Ensure the call token is allocated */
00822    if ((pvt->cd).call_token == NULL) {
00823       (pvt->cd).call_token = (char *)malloc(128);
00824    }
00825    if (!pvt->cd.call_token) {
00826       ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");
00827       return NULL;
00828    }
00829    memset((char *)(pvt->cd).call_token, 0, 128);
00830    pvt->cd.call_reference = callid;
00831    memcpy(&pvt->options, &global_options, sizeof(pvt->options));
00832    if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
00833       pvt->nonCodecCapability |= AST_RTP_DTMF;
00834    } else {
00835       pvt->nonCodecCapability &= ~AST_RTP_DTMF;
00836    }
00837    strncpy(pvt->context, default_context, sizeof(pvt->context) - 1);
00838    pvt->newstate = pvt->newcontrol = -1;
00839    /* Add to interface list */
00840    ast_mutex_lock(&iflock);
00841    pvt->next = iflist;
00842    iflist = pvt;
00843    ast_mutex_unlock(&iflock);
00844    return pvt;
00845 }

static int oh323_answer struct ast_channel c  )  [static]
 

Definition at line 442 of file chan_h323.c.

References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, oh323_pvt::cd, free, h323debug, oh323_pvt::lock, LOG_DEBUG, ast_channel::name, oh323_update_info(), strdup, and ast_channel::tech_pvt.

00443 {
00444    int res;
00445    struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00446    char *token;
00447 
00448    if (h323debug)
00449       ast_log(LOG_DEBUG, "Answering on %s\n", c->name);
00450 
00451    ast_mutex_lock(&pvt->lock);
00452    token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00453    ast_mutex_unlock(&pvt->lock);
00454    res = h323_answering_call(token, 0);
00455    if (token)
00456       free(token);
00457 
00458    oh323_update_info(c);
00459    if (c->_state != AST_STATE_UP) {
00460       ast_setstate(c, AST_STATE_UP);
00461    }
00462    return res;
00463 }

static int oh323_call struct ast_channel c,
char *  dest,
int  timeout
[static]
 

Make a call over the specified channel to the specified destination. Returns -1 on error, 0 on success.

Definition at line 388 of file chan_h323.c.

References ast_channel::_state, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, AST_STATE_RESERVED, ast_strlen_zero(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, oh323_pvt::exten, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, oh323_update_info(), oh323_pvt::options, oh323_pvt::outgoing, oh323_pvt::sa, ast_channel::tech_pvt, and usingGk.

00389 {  
00390    int res = 0;
00391    struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
00392    char addr[INET_ADDRSTRLEN];
00393    char called_addr[1024];
00394 
00395    if (h323debug) {
00396       ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name);
00397    }
00398    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
00399       ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name);
00400       return -1;
00401    }
00402    ast_mutex_lock(&pvt->lock);
00403    if (usingGk) {
00404       if (ast_strlen_zero(pvt->exten)) {
00405          strncpy(called_addr, dest, sizeof(called_addr));
00406       } else {
00407          snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest);
00408       }
00409    } else {
00410       ast_inet_ntoa(addr, sizeof(addr), pvt->sa.sin_addr);
00411       res = htons(pvt->sa.sin_port);
00412       if (ast_strlen_zero(pvt->exten)) {
00413          snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res);
00414       } else {
00415          snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res);
00416       }
00417    }
00418    /* make sure null terminated */
00419    called_addr[sizeof(called_addr) - 1] = '\0'; 
00420 
00421    if (c->cid.cid_num) {
00422       strncpy(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num));
00423    }
00424    if (c->cid.cid_name) {
00425       strncpy(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name));
00426    }
00427 
00428    /* indicate that this is an outgoing call */
00429    pvt->outgoing = 1;
00430 
00431    ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec);
00432    ast_mutex_unlock(&pvt->lock);
00433    res = h323_make_call(called_addr, &(pvt->cd), &pvt->options);
00434    if (res) {
00435       ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name);
00436       return -1;
00437    }
00438    oh323_update_info(c);
00439    return 0;
00440 }

static void oh323_destroy struct oh323_pvt pvt  )  [static]
 

Definition at line 340 of file chan_h323.c.

References __oh323_destroy(), ast_mutex_lock(), and ast_mutex_unlock().

Referenced by oh323_request().

00341 {
00342    ast_mutex_lock(&iflock);
00343    __oh323_destroy(pvt);
00344    ast_mutex_unlock(&iflock);
00345 }

static int oh323_digit struct ast_channel c,
char  digit
[static]
 

Send (play) the specified digit to the channel.

Definition at line 351 of file chan_h323.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit(), oh323_pvt::cd, free, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, ast_channel::name, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, and ast_channel::tech_pvt.

00352 {
00353    struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00354    char *token;
00355 
00356    if (!pvt) {
00357       ast_log(LOG_ERROR, "No private structure?! This is bad\n");
00358       return -1;
00359    }
00360    ast_mutex_lock(&pvt->lock);
00361    if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833)) {
00362       /* out-of-band DTMF */
00363       if (h323debug) {
00364          ast_log(LOG_DEBUG, "Sending out-of-band digit %c on %s\n", digit, c->name);
00365       }
00366       ast_rtp_senddigit(pvt->rtp, digit);
00367    } else {
00368       /* in-band DTMF */
00369       if (h323debug) {
00370          ast_log(LOG_DEBUG, "Sending inband digit %c on %s\n", digit, c->name);
00371       }
00372       token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00373       h323_send_tone(token, digit);
00374       if (token) {
00375          free(token);
00376       }
00377    }
00378    ast_mutex_unlock(&pvt->lock);
00379    oh323_update_info(c);
00380    return 0;
00381 }

static int oh323_fixup struct ast_channel oldchan,
struct ast_channel newchan
[static]
 

Definition at line 706 of file chan_h323.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, LOG_WARNING, oh323_pvt::owner, and ast_channel::tech_pvt.

00707 {
00708    struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt;
00709 
00710    ast_mutex_lock(&pvt->lock);
00711    if (pvt->owner != oldchan) {
00712       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);
00713       return -1;
00714    }
00715    pvt->owner = newchan;
00716    ast_mutex_unlock(&pvt->lock);
00717    return 0;
00718 }

static struct ast_rtp* oh323_get_rtp_peer struct ast_channel chan  )  [static]
 

Definition at line 2243 of file chan_h323.c.

References oh323_pvt::options, oh323_pvt::rtp, and ast_channel::tech_pvt.

02244 {
02245    struct oh323_pvt *pvt;
02246    pvt = (struct oh323_pvt *) chan->tech_pvt;
02247    if (pvt && pvt->rtp && pvt->options.bridge) {
02248       return pvt->rtp;
02249    }
02250    return NULL;
02251 }

static struct ast_rtp* oh323_get_vrtp_peer struct ast_channel chan  )  [static]
 

Definition at line 2253 of file chan_h323.c.

02254 {
02255    return NULL;
02256 }

static int oh323_hangup struct ast_channel c  )  [static]
 

Definition at line 465 of file chan_h323.c.

References ast_channel::_state, oh323_pvt::alreadygone, 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_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_UP, ast_update_use_count(), oh323_pvt::cd, free, h323debug, oh323_pvt::hangupcause, ast_channel::hangupcause, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, oh323_pvt::needdestroy, oh323_pvt::owner, pbx_builtin_getvar_helper(), strdup, ast_channel::tech_pvt, usecnt, and usecnt_lock.

00466 {
00467    struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00468    int needcancel = 0;
00469    int q931cause = AST_CAUSE_NORMAL_CLEARING;
00470    char *call_token;
00471 
00472 
00473    if (h323debug)
00474       ast_log(LOG_DEBUG, "Hanging up call %s\n", c->name);
00475 
00476    if (!c->tech_pvt) {
00477       ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
00478       return 0;
00479    }
00480    ast_mutex_lock(&pvt->lock);
00481    /* Determine how to disconnect */
00482    if (pvt->owner != c) {
00483       ast_log(LOG_WARNING, "Huh?  We aren't the owner?\n");
00484       ast_mutex_unlock(&pvt->lock);
00485       return 0;
00486    }
00487    if (!c || (c->_state != AST_STATE_UP)) {
00488       needcancel = 1;
00489    }
00490    
00491    pvt->owner = NULL;
00492    c->tech_pvt = NULL;
00493 
00494    if (c->hangupcause) {
00495       q931cause = c->hangupcause;
00496    } else {
00497       char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS");
00498       if (cause) {
00499          if (!strcmp(cause, "CONGESTION")) {
00500             q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
00501          } else if (!strcmp(cause, "BUSY")) {
00502             q931cause = AST_CAUSE_USER_BUSY;
00503          } else if (!strcmp(cause, "CHANISUNVAIL")) {
00504             q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
00505          } else if (!strcmp(cause, "NOANSWER")) {
00506             q931cause = AST_CAUSE_NO_ANSWER;
00507          } else if (!strcmp(cause, "CANCEL")) {
00508             q931cause = AST_CAUSE_CALL_REJECTED;
00509          }
00510       }
00511    }
00512 
00513    /* Start the process if it's not already started */
00514    if (!pvt->alreadygone && !pvt->hangupcause) {
00515       call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL;
00516       if (call_token) {
00517          /* Release lock to eliminate deadlock */
00518          ast_mutex_unlock(&pvt->lock);
00519          if (h323_clear_call(call_token, q931cause)) { 
00520             ast_log(LOG_DEBUG, "ClearCall failed.\n");
00521          }
00522          free(call_token);
00523          ast_mutex_lock(&pvt->lock);
00524       }
00525    } 
00526    pvt->needdestroy = 1;
00527 
00528    /* Update usage counter */
00529    ast_mutex_lock(&usecnt_lock);
00530    usecnt--;
00531    if (usecnt < 0) {
00532       ast_log(LOG_WARNING, "Usecnt < 0\n");
00533    }
00534    ast_mutex_unlock(&usecnt_lock);
00535    ast_mutex_unlock(&pvt->lock);
00536    ast_update_use_count();
00537    return 0;
00538 }

static int oh323_indicate struct ast_channel c,
int  condition
[static]
 

Definition at line 630 of file chan_h323.c.

References ast_channel::_state, oh323_pvt::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, oh323_pvt::cd, free, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_update_info(), strdup, and ast_channel::tech_pvt.

00631 {
00632 
00633    struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00634    char *token = (char *)NULL;
00635 
00636    ast_mutex_lock(&pvt->lock);
00637    token = (pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL);
00638    ast_mutex_unlock(&pvt->lock);
00639 
00640    if (h323debug)
00641       ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token);
00642 
00643    switch(condition) {
00644    case AST_CONTROL_RINGING:
00645       if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) {
00646          h323_send_alerting(token);
00647          break;
00648       }
00649       if (token)
00650          free(token);
00651       return -1;
00652    case AST_CONTROL_PROGRESS:
00653       if (c->_state != AST_STATE_UP) {
00654          h323_send_progress(token);
00655          break;
00656       }
00657       if (token)
00658          free(token);
00659       return -1;
00660 
00661    case AST_CONTROL_BUSY:
00662       if (c->_state != AST_STATE_UP) {
00663          h323_answering_call(token, 1);
00664          ast_mutex_lock(&pvt->lock);
00665          pvt->alreadygone = 1;
00666          ast_mutex_unlock(&pvt->lock);
00667          ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);         
00668          break;
00669       }
00670       if (token)
00671          free(token);
00672       return -1;
00673    case AST_CONTROL_CONGESTION:
00674       if (c->_state != AST_STATE_UP) {
00675          h323_answering_call(token, 1);
00676          ast_mutex_lock(&pvt->lock);
00677          pvt->alreadygone = 1;
00678          ast_mutex_unlock(&pvt->lock);
00679          ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
00680          break;
00681       }
00682       if (token)
00683          free(token);
00684       return -1;
00685    case AST_CONTROL_PROCEEDING:
00686    case -1:
00687       if (token)
00688          free(token);
00689       return -1;
00690    default:
00691       ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n", condition, token);
00692       if (token)
00693          free(token);
00694       return -1;
00695    }
00696 
00697    if (h323debug)
00698       ast_log(LOG_DEBUG, "OH323: Indicated %d on %s\n", condition, token);
00699    if (token)
00700       free(token);
00701    oh323_update_info(c);
00702 
00703    return -1;
00704 }

static struct ast_frame * oh323_read struct ast_channel c  )  [static]
 

Definition at line 590 of file chan_h323.c.

References __oh323_update_info(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, oh323_rtp_read(), and ast_channel::tech_pvt.

00591 {
00592    struct ast_frame *fr;
00593    struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
00594    ast_mutex_lock(&pvt->lock);
00595    __oh323_update_info(c, pvt);
00596    fr = oh323_rtp_read(pvt);
00597    ast_mutex_unlock(&pvt->lock);
00598    return fr;
00599 }

static struct ast_channel * oh323_request const char *  type,
int  format,
void *  data,
int *  cause
[static]
 

Definition at line 1012 of file chan_h323.c.

References __oh323_new(), AST_FORMAT_MAX_AUDIO, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setnat(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), create_addr(), oh323_pvt::exten, global_options, host, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_alloc(), oh323_destroy(), oh323_pvt::options, restart_monitor(), oh323_pvt::rtp, unique, and usingGk.

01013 {
01014    int oldformat;
01015    struct oh323_pvt *pvt;
01016    struct ast_channel *tmpc = NULL;
01017    char *dest = (char *)data;
01018    char *ext, *host;
01019    char *h323id = NULL;
01020    char tmp[256], tmp1[256];
01021    
01022    ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data);
01023    pvt = oh323_alloc(0);
01024    if (!pvt) {
01025       ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
01026       return NULL;
01027    }  
01028    oldformat = format;
01029    format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);
01030    if (!format) {
01031       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
01032       return NULL;
01033    }
01034    strncpy(tmp, dest, sizeof(tmp) - 1);   
01035    host = strchr(tmp, '@');
01036    if (host) {
01037       *host = '\0';
01038       host++;
01039       ext = tmp;
01040    } else {
01041       host = tmp;
01042       ext = NULL;
01043    }
01044    strtok_r(host, "/", &(h323id));     
01045    if (!ast_strlen_zero(h323id)) {
01046       h323_set_id(h323id);
01047    }
01048    if (ext) {
01049       strncpy(pvt->exten, ext, sizeof(pvt->exten) - 1);
01050    }
01051    ast_log(LOG_DEBUG, "Extension: %s Host: %s\n",  pvt->exten, host);
01052    if (!usingGk) {
01053       if (create_addr(pvt, host)) {
01054          oh323_destroy(pvt);
01055          return NULL;
01056       }
01057    }
01058    else {
01059       memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01060       if (pvt->rtp) {
01061          ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat);
01062          ast_rtp_setnat(pvt->rtp, pvt->options.nat);
01063       }
01064       if (pvt->options.dtmfmode) {
01065          if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
01066             pvt->nonCodecCapability |= AST_RTP_DTMF;
01067          } else {
01068             pvt->nonCodecCapability &= ~AST_RTP_DTMF;
01069          }
01070       }
01071    }
01072 
01073    ast_mutex_lock(&caplock);
01074    /* Generate unique channel identifier */
01075    snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique);
01076    tmp1[sizeof(tmp1)-1] = '\0';
01077    ast_mutex_unlock(&caplock);
01078 
01079    ast_mutex_lock(&pvt->lock);
01080    tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1);
01081    ast_mutex_unlock(&pvt->lock);
01082    if (!tmpc) {
01083       oh323_destroy(pvt);
01084    }
01085    ast_update_use_count();
01086    restart_monitor();
01087    return tmpc;
01088 }

static struct ast_frame* oh323_rtp_read struct oh323_pvt pvt  )  [static]
 

Definition at line 540 of file chan_h323.c.

References ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_read(), ast_rtp_setnat(), ast_set_read_format(), ast_set_write_format(), ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_pvt::options, oh323_pvt::owner, ast_channel::readformat, oh323_pvt::rtp, ast_frame::subclass, oh323_pvt::vad, and ast_channel::writeformat.

Referenced by oh323_read().

00541 {
00542    /* Retrieve audio/etc from channel.  Assumes pvt->lock is already held. */
00543    struct ast_frame *f;
00544    static struct ast_frame null_frame = { AST_FRAME_NULL, };
00545 
00546    /* Only apply it for the first packet, we just need the correct ip/port */
00547    if (pvt->options.nat) {
00548       ast_rtp_setnat(pvt->rtp, pvt->options.nat);
00549       pvt->options.nat = 0;
00550    }
00551 
00552    f = ast_rtp_read(pvt->rtp);
00553    /* Don't send RFC2833 if we're not supposed to */
00554    if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) {
00555       return &null_frame;
00556    }
00557    if (pvt->owner) {
00558       /* We already hold the channel lock */
00559       if (f->frametype == AST_FRAME_VOICE) {
00560          if (f->subclass != pvt->owner->nativeformats) {
00561             /* Try to avoid deadlock */
00562             if (ast_mutex_trylock(&pvt->owner->lock)) {
00563                ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
00564                return &null_frame;
00565             }
00566             ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass);
00567             pvt->owner->nativeformats = f->subclass;
00568             pvt->nativeformats = f->subclass;
00569             ast_set_read_format(pvt->owner, pvt->owner->readformat);
00570             ast_set_write_format(pvt->owner, pvt->owner->writeformat);
00571             ast_mutex_unlock(&pvt->owner->lock);
00572          }  
00573          /* Do in-band DTMF detection */
00574          if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) {
00575             if (!ast_mutex_trylock(&pvt->owner->lock)) {
00576                f = ast_dsp_process(pvt->owner,pvt->vad,f);
00577                ast_mutex_unlock(&pvt->owner->lock);
00578             }
00579             else
00580                ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
00581             if (f &&(f->frametype == AST_FRAME_DTMF)) {
00582                ast_log(LOG_DEBUG, "Received in-band digit %c.\n", f->subclass);
00583             }
00584          }
00585       }
00586    }
00587    return f;
00588 }

static int oh323_set_rtp_peer struct ast_channel chan,
struct ast_rtp rtp,
struct ast_rtp vrtp,
int  codecs,
int  nat_active
[static]
 

Definition at line 2283 of file chan_h323.c.

References ast_inet_ntoa(), ast_log(), ast_rtp_get_peer(), ast_rtp_get_us(), oh323_pvt::cd, convertcap(), LOG_ERROR, ast_channel::tech_pvt, and ast_channel::writeformat.

02284 {
02285    /* XXX Deal with Video */
02286    struct oh323_pvt *pvt;
02287    struct sockaddr_in them;
02288    struct sockaddr_in us;
02289    char *mode;
02290    char iabuf[INET_ADDRSTRLEN];
02291 
02292    if (!rtp) {
02293       return 0;
02294    }
02295 
02296    mode = convertcap(chan->writeformat); 
02297    pvt = (struct oh323_pvt *) chan->tech_pvt;
02298    if (!pvt) {
02299       ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
02300       return -1;
02301    }
02302    ast_rtp_get_peer(rtp, &them); 
02303    ast_rtp_get_us(rtp, &us);
02304    h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(iabuf, sizeof(iabuf), them.sin_addr), mode);
02305    return 0;
02306 }

static void oh323_update_info struct ast_channel c  )  [static]
 

Definition at line 256 of file chan_h323.c.

References __oh323_update_info(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, and ast_channel::tech_pvt.

Referenced by oh323_answer(), oh323_call(), oh323_digit(), and oh323_indicate().

00257 {
00258    struct oh323_pvt *pvt = c->tech_pvt;
00259 
00260    if (pvt) {
00261       ast_mutex_lock(&pvt->lock);
00262       __oh323_update_info(c, pvt);
00263       ast_mutex_unlock(&pvt->lock);
00264    }
00265 }

static int oh323_write struct ast_channel c,
struct ast_frame frame
[static]
 

Definition at line 601 of file chan_h323.c.

References __oh323_update_info(), AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_frame::frametype, oh323_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, oh323_pvt::rtp, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat.

00602 {
00603    struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
00604    int res = 0;
00605    if (frame->frametype != AST_FRAME_VOICE) {
00606       if (frame->frametype == AST_FRAME_IMAGE) {
00607          return 0;
00608       } else {
00609          ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype);
00610          return 0;
00611       }
00612    } else {
00613       if (!(frame->subclass & c->nativeformats)) {
00614          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n",
00615             frame->subclass, c->nativeformats, c->readformat, c->writeformat);
00616          return 0;
00617       }
00618    }
00619    if (pvt) {
00620       ast_mutex_lock(&pvt->lock);
00621       if (pvt->rtp) {
00622          res =  ast_rtp_write(pvt->rtp, frame);
00623       }
00624       __oh323_update_info(c, pvt);
00625       ast_mutex_unlock(&pvt->lock);
00626    }
00627    return res;
00628 }

int progress unsigned  call_reference,
const char *  token,
int  inband
 

Definition at line 1259 of file chan_h323.c.

References AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), find_call_locked(), ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state().

01260 {
01261    struct oh323_pvt *pvt;
01262 
01263    ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated"));
01264 
01265    pvt = find_call_locked(call_reference, token);
01266    if (!pvt) {
01267       ast_log(LOG_ERROR, "Private structure not found in progress.\n");
01268       return -1;
01269    }
01270    if (!pvt->owner) {
01271       ast_mutex_unlock(&pvt->lock);
01272       ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n");
01273       return -1;
01274    }
01275    if (update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING)))
01276       ast_mutex_unlock(&pvt->owner->lock);
01277    ast_mutex_unlock(&pvt->lock);
01278 
01279    return 0;
01280 }

static void prune_peers void   ) 
 

Definition at line 2189 of file chan_h323.c.

References ast_mutex_lock(), ast_mutex_unlock(), free, ast_peer_list::lock, peerl, and ast_peer_list::peers.

Referenced by expire_registry(), h323_do_reload(), set_config(), and unload_module().

02190 {
02191    /* Prune peers who still are supposed to be deleted */
02192    struct oh323_peer *peer, *peerlast, *peernext;
02193    ast_mutex_lock(&peerl.lock);
02194    peerlast = NULL;
02195    for (peer=peerl.peers;peer;) {
02196       peernext = peer->next;
02197       if (peer->delme) {
02198          free(peer);
02199          if (peerlast) {
02200             peerlast->next = peernext;
02201          } else {
02202             peerl.peers = peernext;
02203          }
02204       } else {
02205          peerlast = peer;
02206       }
02207       peer = peernext;
02208    }
02209    ast_mutex_unlock(&peerl.lock);
02210 }

int reload void   ) 
 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 2235 of file chan_h323.c.

References h323_reload().

02236 {
02237    return h323_reload(0, 0, NULL);
02238 }

static int reload_config void   ) 
 

Definition at line 1998 of file chan_h323.c.

References ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), bindaddr, build_alias(), build_peer(), build_user(), cfg, config, default_context, format, gatekeeper, gatekeeper_disable, gatekeeper_discover, gkroute, global_options, h323_signalling_port, h323debug, hp, IPTOS_MINCOST, ast_variable::lineno, ast_user_list::lock, ast_peer_list::lock, ast_alias_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, secret, tos, update_common_options(), user, userbyalias, userl, ast_user_list::users, usingGk, ast_variable::value, and VERBOSE_PREFIX_2.

Referenced by h323_do_reload(), iax2_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), and reload().

01999 {  
02000    int format;
02001    struct ast_config *cfg;
02002    struct ast_variable *v;
02003    struct oh323_peer *peer   = NULL;
02004    struct oh323_user *user   = NULL;
02005    struct oh323_alias *alias = NULL;
02006    struct ast_hostent ahp; struct hostent *hp;
02007    char *cat;
02008       char *utype;
02009    
02010    cfg = ast_config_load(config);
02011 
02012    /* We *must* have a config file otherwise stop immediately */
02013    if (!cfg) {
02014       ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
02015       return 1;
02016    }
02017    
02018        /* fire up the H.323 Endpoint */       
02019    if (!h323_end_point_exist()) {
02020           h323_end_point_create();        
02021    }
02022    h323debug = 0;
02023    memset(&bindaddr, 0, sizeof(bindaddr));
02024    memset(&global_options, 0, sizeof(global_options));
02025    global_options.dtmfcodec = 101;
02026    global_options.dtmfmode = H323_DTMF_RFC2833;
02027    global_options.capability = ~0;  /* All capabilities */
02028    global_options.bridge = 1;    /* Do native bridging by default */
02029    v = ast_variable_browse(cfg, "general");
02030    while(v) {
02031       /* Create the interface list */
02032       if (!strcasecmp(v->name, "port")) {
02033          h323_signalling_port = (int)strtol(v->value, NULL, 10);
02034       } else if (!strcasecmp(v->name, "bindaddr")) {
02035          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
02036             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
02037          } else {
02038             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
02039          }
02040       } else if (!strcasecmp(v->name, "tos")) {
02041          if (sscanf(v->value, "%d", &format)) {
02042             tos = format & 0xff;
02043          } else if (!strcasecmp(v->value, "lowdelay")) {
02044             tos = IPTOS_LOWDELAY;
02045          } else if (!strcasecmp(v->value, "throughput")) {
02046             tos = IPTOS_THROUGHPUT;
02047          } else if (!strcasecmp(v->value, "reliability")) {
02048             tos = IPTOS_RELIABILITY;
02049          } else if (!strcasecmp(v->value, "mincost")) {
02050             tos = IPTOS_MINCOST;
02051          } else if (!strcasecmp(v->value, "none")) {
02052             tos = 0;
02053          } else {
02054             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
02055          }
02056       } else if (!strcasecmp(v->name, "gatekeeper")) {
02057          if (!strcasecmp(v->value, "DISABLE")) {
02058             gatekeeper_disable = 1;
02059             usingGk = 0;
02060          } else if (!strcasecmp(v->value, "DISCOVER")) {
02061             gatekeeper_disable = 0;
02062             gatekeeper_discover = 1;
02063             usingGk = 1;
02064          } else {
02065             gatekeeper_disable = 0;
02066             usingGk = 1;
02067             strncpy(gatekeeper, v->value, sizeof(gatekeeper) - 1);
02068          }
02069       } else if (!strcasecmp(v->name, "secret")) {
02070          strncpy(secret, v->value, sizeof(secret) - 1);
02071       } else if (!strcasecmp(v->name, "AllowGKRouted")) {
02072          gkroute = ast_true(v->value);
02073       } else if (!strcasecmp(v->name, "context")) {
02074          strncpy(default_context, v->value, sizeof(default_context) - 1);
02075          ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context);   
02076       } else if (!strcasecmp(v->name, "UserByAlias")) {
02077          userbyalias = ast_true(v->value);
02078       } else if (!update_common_options(v, &global_options)) {
02079          /* dummy */
02080       }
02081       v = v->next;   
02082    }
02083    
02084    cat = ast_category_browse(cfg, NULL);
02085    while(cat) {
02086       if (strcasecmp(cat, "general")) {
02087          utype = ast_variable_retrieve(cfg, cat, "type");
02088          if (utype) {
02089             if (!strcasecmp(utype, "user")) {
02090                user = build_user(cat, ast_variable_browse(cfg, cat));
02091                if (user) {
02092                   ast_mutex_lock(&userl.lock);
02093                   user->next = userl.users;
02094                   userl.users = user;
02095                   ast_mutex_unlock(&userl.lock);
02096                }
02097             }  else if (!strcasecmp(utype, "peer")) {
02098                peer = build_peer(cat, ast_variable_browse(cfg, cat));
02099                if (peer) {
02100                   ast_mutex_lock(&peerl.lock);
02101                   peer->next = peerl.peers;
02102                   peerl.peers = peer;
02103                   ast_mutex_unlock(&peerl.lock);
02104                }
02105             }  else if (!strcasecmp(utype, "friend")) {
02106                user = build_user(cat, ast_variable_browse(cfg, cat));
02107                peer = build_peer(cat, ast_variable_browse(cfg, cat));
02108                if (user) {
02109                   ast_mutex_lock(&userl.lock);
02110                   user->next = userl.users;
02111                   userl.users = user;
02112                   ast_mutex_unlock(&userl.lock);
02113                }
02114                if (peer) {
02115                   ast_mutex_lock(&peerl.lock);
02116                   peer->next = peerl.peers;
02117                   peerl.peers = peer;
02118                   ast_mutex_unlock(&peerl.lock);
02119                }
02120             }  else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) {
02121                alias = build_alias(cat, ast_variable_browse(cfg, cat));
02122                if (alias) {
02123                   ast_mutex_lock(&aliasl.lock);
02124                   alias->next = aliasl.aliases;
02125                   aliasl.aliases = alias;
02126                   ast_mutex_unlock(&aliasl.lock);
02127                }
02128             } else {
02129                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
02130             }
02131          } else {
02132             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
02133          }
02134       }
02135       cat = ast_category_browse(cfg, cat);
02136    }
02137    ast_config_destroy(cfg);
02138 
02139    /* Register our H.323 aliases if any*/
02140    while (alias) {      
02141       if (h323_set_alias(alias)) {
02142          ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name);
02143          return -1;
02144       }  
02145       alias = alias->next;
02146    }
02147 
02148    return 0;
02149 }

static int restart_monitor void   )  [static]
 

Definition at line 1623 of file chan_h323.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread.

Referenced by h323_do_reload(), h323_reload(), load_module(), mgcp_reload(), mgcp_request(), modem_hangup(), modem_request(), oh323_request(), phone_hangup(), phone_request(), reload(), setup_zap(), sip_reload(), sip_request_call(), skinny_request(), vpb_hangup(), vpb_request(), zt_hangup(), and zt_request().

01624 {
01625    pthread_attr_t attr;
01626    /* If we're supposed to be stopped -- stay stopped */
01627    if (monitor_thread == AST_PTHREADT_STOP) {
01628       return 0;
01629    }
01630    if (ast_mutex_lock(&monlock)) {
01631       ast_log(LOG_WARNING, "Unable to lock monitor\n");
01632       return -1;
01633    }
01634    if (monitor_thread == pthread_self()) {
01635       ast_mutex_unlock(&monlock);
01636       ast_log(LOG_WARNING, "Cannot kill myself\n");
01637       return -1;
01638    }
01639    if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) {
01640       /* Wake up the thread */
01641       pthread_kill(monitor_thread, SIGURG);
01642    } else { 
01643       pthread_attr_init(&attr);
01644                 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01645                 /* Start a new monitor */
01646                 if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
01647                         ast_mutex_unlock(&monlock);
01648                         ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
01649                         return -1;
01650                 }
01651 
01652    }
01653    ast_mutex_unlock(&monlock);
01654    return 0;
01655 }

int send_digit unsigned  call_reference,
char  digit,
const char *  token
 

Callback for sending digits from H.323 up to asterisk

Definition at line 1109 of file chan_h323.c.

References AST_FRAME_DTMF, ast_log(), ast_mutex_unlock(), ast_queue_frame(), find_call_locked(), oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, and oh323_pvt::owner.

Referenced by load_module().

01110 {
01111    struct oh323_pvt *pvt;
01112    struct ast_frame f;
01113    int res;
01114 
01115    ast_log(LOG_DEBUG, "Received Digit: %c\n", digit);
01116    pvt = find_call_locked(call_reference, token); 
01117    if (!pvt) {
01118       ast_log(LOG_ERROR, "Private structure not found in send_digit.\n");
01119       return -1;
01120    }
01121    memset(&f, 0, sizeof(f));
01122    f.frametype = AST_FRAME_DTMF;
01123    f.subclass = digit;
01124    f.datalen = 0;
01125    f.samples = 800;
01126    f.offset = 0;
01127    f.data = NULL;
01128    f.mallocd = 0;
01129    f.src = "SEND_DIGIT";   
01130    res = ast_queue_frame(pvt->owner, &f);
01131    ast_mutex_unlock(&pvt->lock);
01132    return res;
01133 }

void set_dtmf_payload unsigned  call_reference,
const char *  token,
int  payload
 

Definition at line 1536 of file chan_h323.c.

References ast_log(), ast_mutex_unlock(), ast_rtp_set_rtpmap_type(), find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, and oh323_pvt::rtp.

Referenced by load_module().

01537 {
01538    struct oh323_pvt *pvt;
01539 
01540    if (h323debug)
01541       ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token);
01542 
01543    pvt = find_call_locked(call_reference, token);
01544    if (!pvt) {
01545       return;
01546    }
01547    if (pvt->rtp) {
01548       ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event");
01549    }
01550    ast_mutex_unlock(&pvt->lock);
01551    if (h323debug)
01552       ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload);
01553 }

static void set_local_capabilities unsigned  call_reference,
const char *  token
[static]
 

Definition at line 1555 of file chan_h323.c.

References ast_log(), ast_mutex_unlock(), capability, dtmfmode, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, and oh323_pvt::options.

Referenced by load_module().

01556 {
01557    struct oh323_pvt *pvt;
01558    int capability, dtmfmode;
01559 
01560    if (h323debug)
01561       ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token);
01562 
01563    pvt = find_call_locked(call_reference, token);
01564    if (!pvt)
01565       return;
01566    capability = pvt->options.capability;
01567    dtmfmode = pvt->options.dtmfmode;
01568    ast_mutex_unlock(&pvt->lock);
01569    h323_set_capabilities(token, capability, dtmfmode);
01570 
01571    if (h323debug)
01572       ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token);
01573 }

call_options_t* setup_incoming_call call_details_t *  cd  ) 
 

Call-back function for incoming calls

Returns 1 on success

Definition at line 1287 of file chan_h323.c.

References oh323_pvt::accountcode, oh323_pvt::amaflags, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_verbose(), oh323_pvt::cd, oh323_pvt::context, default_context, oh323_pvt::exten, find_alias(), find_user(), gatekeeper, gkroute, global_options, h323debug, LOG_DEBUG, LOG_ERROR, oh323_alloc(), oh323_pvt::options, user, usingGk, and VERBOSE_PREFIX_3.

Referenced by load_module().

01288 {
01289    struct oh323_pvt *pvt;
01290    struct oh323_user *user = NULL;
01291    struct oh323_alias *alias = NULL;
01292    char iabuf[INET_ADDRSTRLEN];
01293 
01294    if (h323debug)
01295       ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token);
01296 
01297    /* allocate the call*/
01298    pvt = oh323_alloc(cd->call_reference);
01299 
01300    if (!pvt) {
01301       ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
01302       return NULL;
01303    }
01304 
01305    /* Populate the call details in the private structure */
01306    memcpy(&pvt->cd, cd, sizeof(pvt->cd));
01307    memcpy(&pvt->options, &global_options, sizeof(pvt->options));
01308 
01309    if (h323debug) {
01310       ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n");
01311       ast_verbose(VERBOSE_PREFIX_3 "\tCall token:  [%s]\n", pvt->cd.call_token);
01312       ast_verbose(VERBOSE_PREFIX_3 "\tCalling party name:  [%s]\n", pvt->cd.call_source_name);
01313       ast_verbose(VERBOSE_PREFIX_3 "\tCalling party number:  [%s]\n", pvt->cd.call_source_e164);
01314       ast_verbose(VERBOSE_PREFIX_3 "\tCalled party name:  [%s]\n", pvt->cd.call_dest_alias);
01315       ast_verbose(VERBOSE_PREFIX_3 "\tCalled party number:  [%s]\n", pvt->cd.call_dest_e164);
01316    }
01317 
01318    /* Decide if we are allowing Gatekeeper routed calls*/
01319    if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk)) {
01320       if (!ast_strlen_zero(cd->call_dest_e164)) {
01321          strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1);
01322          strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); 
01323       } else {
01324          alias = find_alias(cd->call_dest_alias);
01325          if (!alias) {
01326             ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias);
01327             return NULL;
01328          }
01329          strncpy(pvt->exten, alias->name, sizeof(pvt->exten) - 1);
01330          strncpy(pvt->context, alias->context, sizeof(pvt->context) - 1);
01331       }
01332    } else {
01333       /* Either this call is not from the Gatekeeper 
01334          or we are not allowing gk routed calls */
01335       user  = find_user(cd);
01336       if (!user) {
01337          if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
01338             strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1);
01339          } else {
01340             strncpy(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten) - 1);
01341          }
01342          if (ast_strlen_zero(default_context)) {
01343             ast_log(LOG_ERROR, "Call from '%s' rejected due to no default context\n", pvt->cd.call_source_aliases);
01344             return NULL;
01345          }
01346          strncpy(pvt->context, default_context, sizeof(pvt->context) - 1);
01347          ast_log(LOG_DEBUG, "Sending %s to context [%s]\n", cd->call_source_aliases, pvt->context);
01348          /* XXX: Is it really required??? */
01349 #if 0
01350          memset(&pvt->options, 0, sizeof(pvt->options));
01351 #endif
01352       } else {
01353          if (user->host) {
01354             if (strcasecmp(cd->sourceIp, ast_inet_ntoa(iabuf, sizeof(iabuf), user->addr.sin_addr))) {
01355                if (ast_strlen_zero(user->context)) {
01356                   if (ast_strlen_zero(default_context)) {
01357                      ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp);
01358                               return NULL;
01359                   }
01360                   strncpy(pvt->context, default_context, sizeof(pvt->context) - 1);
01361                } else {
01362                   strncpy(pvt->context, user->context, sizeof(pvt->context) - 1);
01363                }
01364                pvt->exten[0] = 'i';
01365                pvt->exten[1] = '\0';
01366                ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp);
01367                return NULL;   /* XXX: Hmmm... Why to setup context if we drop connection immediately??? */
01368             }
01369          }
01370          strncpy(pvt->context, user->context, sizeof(pvt->context) - 1);
01371          memcpy(&pvt->options, &user->options, sizeof(pvt->options));
01372          if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
01373             strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1);
01374          } else {
01375             strncpy(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten) - 1);
01376          }
01377          if (!ast_strlen_zero(user->accountcode)) {
01378             strncpy(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode) - 1);
01379          } 
01380          if (user->amaflags) {
01381             pvt->amaflags = user->amaflags;
01382          } 
01383       } 
01384    }
01385    return &pvt->options;
01386 }

int setup_outgoing_call call_details_t *  cd  ) 
 

Call-back function to establish an outgoing H.323 call

Returns 1 on success

Definition at line 1424 of file chan_h323.c.

References cleanup_call_details().

Referenced by load_module().

01425 {
01426    /* Use argument here or free it immediately */
01427    cleanup_call_details(cd);
01428 
01429    return 1;
01430 }

void setup_rtp_connection unsigned  call_reference,
const char *  remoteIp,
int  remotePort,
const char *  token,
int  pt
 

Call-back function passing remote ip/port information from H.323 to asterisk

Returns nothing

Definition at line 1181 of file chan_h323.c.

References oh323_pvt::alreadygone, AST_CONTROL_PROGRESS, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control(), ast_rtp_lookup_pt(), ast_rtp_set_peer(), ast_set_read_format(), ast_set_write_format(), rtpPayloadType::code, find_call_locked(), h323debug, ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, ast_channel::nativeformats, oh323_pvt::nativeformats, oh323_pvt::newcontrol, oh323_pvt::options, oh323_pvt::owner, ast_channel::readformat, oh323_pvt::rtp, and ast_channel::writeformat.

Referenced by load_module().

01182 {
01183    struct oh323_pvt *pvt;
01184    struct sockaddr_in them;
01185    struct rtpPayloadType rtptype;
01186 
01187    if (h323debug)
01188       ast_log(LOG_DEBUG, "Setting up RTP connection for %s\n", token);
01189 
01190    /* Find the call or allocate a private structure if call not found */
01191    pvt = find_call_locked(call_reference, token); 
01192    if (!pvt) {
01193       ast_log(LOG_ERROR, "Something is wrong: rtp\n");
01194       return;
01195    }
01196    if (pvt->alreadygone) {
01197       ast_mutex_unlock(&pvt->lock);
01198       return;
01199    }
01200    rtptype = ast_rtp_lookup_pt(pvt->rtp, pt);
01201    pvt->nativeformats = rtptype.code;
01202    if (pvt->owner && !ast_mutex_trylock(&pvt->owner->lock)) {
01203       pvt->owner->nativeformats = pvt->nativeformats;
01204       ast_set_read_format(pvt->owner, pvt->owner->readformat);
01205       ast_set_write_format(pvt->owner, pvt->owner->writeformat);
01206       if (pvt->options.progress_audio)
01207          ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
01208       ast_mutex_unlock(&pvt->owner->lock);
01209    }
01210    else {
01211       if (pvt->options.progress_audio)
01212          pvt->newcontrol = AST_CONTROL_PROGRESS;
01213       if (h323debug)
01214          ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token);
01215    }
01216 
01217    them.sin_family = AF_INET;
01218    /* only works for IPv4 */
01219    them.sin_addr.s_addr = inet_addr(remoteIp); 
01220    them.sin_port = htons(remotePort);
01221    ast_rtp_set_peer(pvt->rtp, &them);
01222 
01223    ast_mutex_unlock(&pvt->lock);
01224 
01225    if (h323debug)
01226       ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token);
01227 
01228    return;
01229 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 2383 of file chan_h323.c.

References aliasl, ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, delete_aliases(), delete_users(), free, iflist, io_context_destroy(), ast_peer_list::lock, ast_user_list::lock, ast_alias_list::lock, oh323_pvt::lock, LOG_WARNING, monitor_thread, oh323_pvt::next, oh323_pvt::owner, peerl, prune_peers(), sched_context_destroy(), and userl.

02384 {
02385    struct oh323_pvt *p, *pl;
02386 
02387    /* unregister commands */
02388    ast_cli_unregister(&cli_debug);
02389    ast_cli_unregister(&cli_no_debug);
02390    ast_cli_unregister(&cli_trace);
02391    ast_cli_unregister(&cli_no_trace);   
02392    ast_cli_unregister(&cli_show_codecs);
02393    ast_cli_unregister(&cli_gk_cycle);
02394    ast_cli_unregister(&cli_hangup_call);
02395    ast_cli_unregister(&cli_show_tokens);
02396    ast_cli_unregister(&cli_h323_reload);
02397    ast_rtp_proto_unregister(&oh323_rtp);
02398    ast_channel_unregister(&oh323_tech);
02399       
02400    if (!ast_mutex_lock(&iflock)) {
02401       /* hangup all interfaces if they have an owner */
02402       p = iflist;
02403       while(p) {
02404          if (p->owner) {
02405             ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
02406          }
02407          p = p->next;
02408       }
02409       iflist = NULL;
02410       ast_mutex_unlock(&iflock);
02411    } else {
02412       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
02413       return -1;
02414    }
02415    if (!ast_mutex_lock(&monlock)) {
02416       if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
02417          /* this causes a seg, anyone know why? */
02418          pthread_cancel(monitor_thread);
02419          pthread_kill(monitor_thread, SIGURG);
02420          pthread_join(monitor_thread, NULL);
02421       }
02422       monitor_thread = AST_PTHREADT_STOP;
02423       ast_mutex_unlock(&monlock);
02424    } else {
02425       ast_log(LOG_WARNING, "Unable to lock the monitor\n");
02426       return -1;
02427    }
02428    if (!ast_mutex_lock(&iflock)) {
02429       /* destroy all the interfaces and free their memory */
02430       p = iflist;
02431       while(p) {
02432          pl = p;
02433          p = p->next;
02434          /* free associated memory */
02435          ast_mutex_destroy(&pl->lock);
02436          free(pl);
02437       }
02438       iflist = NULL;
02439       ast_mutex_unlock(&iflock);
02440    } else {
02441       ast_log(LOG_WARNING, "Unable to lock the interface list\n");
02442       return -1;
02443    }
02444    h323_gk_urq();
02445    h323_end_process();
02446    io_context_destroy(io);
02447    sched_context_destroy(sched);
02448    delete_users();
02449    delete_aliases();
02450    prune_peers();
02451    ast_mutex_destroy(&aliasl.lock);
02452    ast_mutex_destroy(&userl.lock);
02453    ast_mutex_destroy(&peerl.lock);
02454    return 0; 
02455 } 

static int update_common_options struct ast_variable v,
struct call_options *  options
[static]
 

Definition at line 1790 of file chan_h323.c.

References ast_getformatbyname(), ast_log(), ast_true(), format, ast_variable::lineno, LOG_WARNING, ast_variable::name, and ast_variable::value.

Referenced by build_peer(), build_user(), and reload_config().

01791 {
01792    unsigned int format;
01793    int tmp;
01794 
01795    if (!strcasecmp(v->name, "allow")) {
01796       format = ast_getformatbyname(v->value);
01797       if (format < 1) 
01798          ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
01799       else
01800          options->capability |= format;
01801    } else if (!strcasecmp(v->name, "disallow")) {
01802       format = ast_getformatbyname(v->value);
01803       if (format < 1) 
01804          ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
01805       else
01806          options->capability &= ~format;
01807    } else if (!strcasecmp(v->name, "dtmfmode")) {
01808       if (!strcasecmp(v->value, "inband")) {
01809          options->dtmfmode = H323_DTMF_INBAND;
01810       } else if (!strcasecmp(v->value, "rfc2833")) {
01811          options->dtmfmode = H323_DTMF_RFC2833;
01812       } else {
01813          ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
01814          options->dtmfmode = H323_DTMF_RFC2833;
01815       }
01816    } else if (!strcasecmp(v->name, "dtmfcodec")) {
01817       tmp = atoi(v->value);
01818       if (tmp < 96)
01819          ast_log(LOG_WARNING, "Invalid global dtmfcodec value %s\n", v->value);
01820       else
01821          options->dtmfcodec = tmp;
01822    } else if (!strcasecmp(v->name, "bridge")) {
01823       options->bridge = ast_true(v->value);
01824    } else if (!strcasecmp(v->name, "nat")) {
01825       options->nat = ast_true(v->value);
01826    } else if (!strcasecmp(v->name, "noFastStart")) {
01827       options->noFastStart = ast_true(v->value);
01828    } else if (!strcasecmp(v->name, "noH245Tunneling")) {
01829       options->noH245Tunneling = ast_true(v->value);
01830    } else if (!strcasecmp(v->name, "noSilenceSuppression")) {
01831       options->noSilenceSuppression = ast_true(v->value);
01832    } else if (!strcasecmp(v->name, "progress_setup")) {
01833       tmp = atoi(v->value);
01834       if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {
01835          ast_log(LOG_WARNING, "Invalid value %d for progress_setup at line %d, assuming 0\n", tmp, v->lineno);
01836          tmp = 0;
01837       }
01838       options->progress_setup = tmp;
01839    } else if (!strcasecmp(v->name, "progress_alert")) {
01840       tmp = atoi(v->value);
01841       if ((tmp != 0) && (tmp != 8)) {
01842          ast_log(LOG_WARNING, "Invalud value %d for progress_alert at line %d, assuming 0\n", tmp, v->lineno);
01843          tmp = 0;
01844       }
01845       options->progress_alert = tmp;
01846    } else if (!strcasecmp(v->name, "progress_audio")) {
01847       options->progress_audio = ast_true(v->value);
01848    } else
01849       return 1;
01850 
01851    return 0;
01852 }

static int update_state struct oh323_pvt pvt,
int  state,
int  signal
[static]
 

Definition at line 873 of file chan_h323.c.

References ast_mutex_trylock(), ast_queue_control(), ast_setstate(), ast_channel::lock, oh323_pvt::newcontrol, oh323_pvt::newstate, and oh323_pvt::owner.

Referenced by chan_ringing(), connection_made(), and progress().

00874 {
00875    if (!pvt)
00876       return 0;
00877    if (pvt->owner && !ast_mutex_trylock(&pvt->owner->lock)) {
00878       if (state >= 0)
00879          ast_setstate(pvt->owner, state);
00880       if (signal >= 0)
00881          ast_queue_control(pvt->owner, signal);
00882       return 1;
00883    }
00884    else {
00885       if (state >= 0)
00886          pvt->newstate = state;
00887       if (signal >= 0)
00888          pvt->newcontrol = signal;
00889       return 0;
00890    }
00891 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 2457 of file chan_h323.c.

References usecnt.

02458 {
02459    return usecnt;
02460 }


Variable Documentation

struct ast_alias_list aliasl [static]
 

Referenced by delete_aliases(), find_alias(), load_module(), reload_config(), and unload_module().

struct sockaddr_in bindaddr [static]
 

Definition at line 107 of file chan_h323.c.

Referenced by load_module(), oh323_alloc(), reload_config(), sip_show_settings(), and start_rtp().

struct ast_cli_entry cli_debug [static]
 

Initial value:

   { { "h.323", "debug", NULL }, h323_do_debug, "Enable H.323 debug", debug_usage }

Definition at line 1777 of file chan_h323.c.

struct ast_cli_entry cli_gk_cycle [static]
 

Initial value:

   { { "h.323", "gk", "cycle", NULL }, h323_gk_cycle, "Manually re-register with the Gatekeper", show_cycle_usage }

Definition at line 1783 of file chan_h323.c.

struct ast_cli_entry cli_h323_reload [static]
 

Initial value:

   { { "h.323", "reload", NULL }, h323_reload, "Reload H.323 configuration", h323_reload_usage }

Definition at line 2240 of file chan_h323.c.

struct ast_cli_entry cli_hangup_call [static]
 

Initial value:

   { { "h.323", "hangup", NULL }, h323_ep_hangup, "Manually try to hang up a call", show_hangup_usage }

Definition at line 1785 of file chan_h323.c.

struct ast_cli_entry cli_no_debug [static]
 

Initial value:

   { { "h.323", "no", "debug", NULL }, h323_no_debug, "Disable H.323 debug", no_debug_usage }

Definition at line 1779 of file chan_h323.c.

struct ast_cli_entry cli_no_trace [static]
 

Initial value:

   { { "h.323", "no", "trace", NULL }, h323_no_trace, "Disable H.323 Stack Tracing", no_trace_usage }

Definition at line 1775 of file chan_h323.c.

struct ast_cli_entry cli_show_codecs [static]
 

Initial value:

   { { "h.323", "show", "codecs", NULL }, h323_show_codec, "Show enabled codecs", show_codec_usage }

Definition at line 1781 of file chan_h323.c.

struct ast_cli_entry cli_show_tokens [static]
 

Initial value:

   { { "h.323", "show", "tokens", NULL }, h323_tokens_show, "Show all active call tokens", show_tokens_usage }

Definition at line 1787 of file chan_h323.c.

struct ast_cli_entry cli_trace [static]
 

Initial value:

   { { "h.323", "trace", NULL }, h323_do_trace, "Enable H.323 Stack Tracing", trace_usage }

Definition at line 1773 of file chan_h323.c.

const char config[] = "h323.conf" [static]
 

Definition at line 105 of file chan_h323.c.

char debug_usage[] [static]
 

Initial value:

 
"Usage: h.323 debug\n"
"       Enables H.323 debug output\n"

Definition at line 1745 of file chan_h323.c.

char default_context[AST_MAX_CONTEXT] = "default" [static]
 

Definition at line 106 of file chan_h323.c.

Referenced by build_peer(), build_user(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), oh323_alloc(), reload_config(), setup_incoming_call(), sip_alloc(), sip_show_settings(), and temp_peer().

const char desc[] = "The NuFone Network's Open H.323 Channel Driver" [static]
 

Definition at line 103 of file chan_h323.c.

char gatekeeper[100] [static]
 

Definition at line 111 of file chan_h323.c.

Referenced by h323_gk_cycle(), load_module(), reload_config(), and setup_incoming_call().

int gatekeeper_disable = 1 [static]
 

Definition at line 112 of file chan_h323.c.

Referenced by h323_gk_cycle(), load_module(), and reload_config().

int gatekeeper_discover = 0 [static]
 

Definition at line 113 of file chan_h323.c.

Referenced by h323_gk_cycle(), load_module(), and reload_config().

int gkroute = 0 [static]
 

Definition at line 115 of file chan_h323.c.

Referenced by reload_config(), and setup_incoming_call().

call_options_t global_options [static]
 

Definition at line 122 of file chan_h323.c.

Referenced by __oh323_new(), build_peer(), build_user(), create_addr(), oh323_alloc(), oh323_request(), reload_config(), and setup_incoming_call().

char h323_reload_usage[] [static]
 

Initial value:

"Usage: h323 reload\n"
"       Reloads H.323 configuration from sip.conf\n"

Definition at line 1769 of file chan_h323.c.

int h323_reloading = 0 [static]
 

Definition at line 188 of file chan_h323.c.

Referenced by do_monitor(), and h323_reload().

int h323_signalling_port = 1720 [static]
 

H.323 configuration values

Definition at line 110 of file chan_h323.c.

Referenced by build_peer(), create_addr(), load_module(), and reload_config().

int h323debug
 

Definition at line 99 of file chan_h323.c.

Referenced by __oh323_update_info(), answer_call(), chan_ringing(), cleanup_connection(), connection_made(), external_rtp_create(), h323_do_debug(), h323_no_debug(), oh323_answer(), oh323_call(), oh323_digit(), oh323_hangup(), oh323_indicate(), reload_config(), set_dtmf_payload(), set_local_capabilities(), setup_incoming_call(), and setup_rtp_connection().

struct oh323_pvt * iflist
 

Private structure of a OpenH323 channel

Referenced by __oh323_destroy(), __sip_destroy(), __sip_show_channels(), __unload_module(), action_zapshowchannels(), chandup(), complete_sipch(), destroy_channel(), do_monitor(), find_call(), find_call_locked(), find_channel(), get_sip_pvt_byid_locked(), handle_request_subscribe(), load_module(), mkintf(), oh323_alloc(), phone_request(), sip_alloc(), sip_show_channel(), sip_show_history(), unload_module(), vpb_request(), zap_destroy_channel(), zap_restart(), zap_show_channel(), zap_show_channels(), zt_hangup(), and zt_request().

struct io_context* io [static]
 

Definition at line 170 of file chan_h323.c.

pthread_t monitor_thread = AST_PTHREADT_NULL [static]
 

Definition at line 192 of file chan_h323.c.

Referenced by __unload_module(), reload_config(), restart_monitor(), and unload_module().

char no_debug_usage[] [static]
 

Initial value:

 
"Usage: h.323 no debug\n"
"       Disables H.323 debug output\n"

Definition at line 1749 of file chan_h323.c.

char no_trace_usage[] [static]
 

Initial value:

 
"Usage: h.323 no trace\n"
"       Disables H.323 stack tracing for debugging purposes\n"

Definition at line 1741 of file chan_h323.c.

struct ast_rtp_protocol oh323_rtp [static]
 

Definition at line 2308 of file chan_h323.c.

const struct ast_channel_tech oh323_tech [static]
 

Definition at line 206 of file chan_h323.c.

answer_call_cb on_answer_call
 

Definition at line 92 of file chan_h323.c.

chan_ringing_cb on_chan_ringing
 

Definition at line 89 of file chan_h323.c.

clear_con_cb on_connection_cleared
 

Definition at line 91 of file chan_h323.c.

con_established_cb on_connection_established
 

Definition at line 90 of file chan_h323.c.

on_rtp_cb on_external_rtp_create
 

Definition at line 85 of file chan_h323.c.

hangup_cb on_hangup
 

Definition at line 95 of file chan_h323.c.

setup_incoming_cb on_incoming_call
 

Definition at line 87 of file chan_h323.c.

setup_outbound_cb on_outgoing_call
 

Definition at line 88 of file chan_h323.c.

progress_cb on_progress
 

Definition at line 93 of file chan_h323.c.

send_digit_cb on_send_digit
 

Definition at line 84 of file chan_h323.c.

rfc2833_cb on_set_rfc2833_payload
 

Definition at line 94 of file chan_h323.c.

setcapabilities_cb on_setcapabilities
 

Definition at line 96 of file chan_h323.c.

start_rtp_cb on_start_rtp_channel
 

Definition at line 86 of file chan_h323.c.

struct ast_peer_list peerl [static]
 

Referenced by __iax2_show_peers(), _sip_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), complete_sip_peer(), create_addr(), delete_users(), do_monitor(), expire_register(), find_peer(), iax2_getpeername(), iax2_getpeertrunk(), iax2_show_registry(), load_module(), prune_peers(), realtime_peer(), register_verify(), reload_config(), set_config(), sip_poke_all_peers(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), timing_read(), and unload_module().

struct sched_context* sched [static]
 

Asterisk RTP stuff

Definition at line 169 of file chan_h323.c.

char secret[50] [static]
 

Definition at line 119 of file chan_h323.c.

Referenced by add_realm_authentication(), authenticate_verify(), build_reply_digest(), cache_get_callno_locked(), check_access(), decrypt_frame(), h323_gk_cycle(), iax2_call(), iax2_register(), load_module(), register_verify(), reload_config(), and sip_register().

char show_codec_usage[] [static]
 

Initial value:

 
"Usage: h.323 show codec\n"
"       Shows all enabled codecs\n"

Definition at line 1753 of file chan_h323.c.

char show_cycle_usage[] [static]
 

Initial value:

 
"Usage: h.323 gk cycle\n"
"       Manually re-register with the Gatekeper (Currently Disabled)\n"

Definition at line 1757 of file chan_h323.c.

char show_hangup_usage[] [static]
 

Initial value:

 
"Usage: h.323 hangup <token>\n"
"       Manually try to hang up call identified by <token>\n"

Definition at line 1761 of file chan_h323.c.

char show_tokens_usage[] [static]
 

Initial value:

 
"Usage: h.323 show tokens\n"
"       Print out all active call tokens\n"

Definition at line 1765 of file chan_h323.c.

const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver" [static]
 

Definition at line 104 of file chan_h323.c.

int tos = 0 [static]
 

Definition at line 118 of file chan_h323.c.

Referenced by load_module(), oh323_alloc(), reload_config(), set_config(), sip_alloc(), and sip_show_settings().

char trace_usage[] [static]
 

Initial value:

 
"Usage: h.323 trace <level num>\n"
"       Enables H.323 stack tracing for debugging purposes\n"

Definition at line 1737 of file chan_h323.c.

const char type[] = "H323" [static]
 

Variables required by Asterisk

Definition at line 102 of file chan_h323.c.

unsigned int unique = 0 [static]
 

Definition at line 120 of file chan_h323.c.

Referenced by oh323_request().

int usecnt = 0 [static]
 

Usage counter and associated lock

Definition at line 176 of file chan_h323.c.

int userbyalias = 1 [static]
 

Definition at line 117 of file chan_h323.c.

Referenced by find_user(), and reload_config().

struct ast_user_list userl [static]
 

Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), complete_sip_user(), delete_users(), find_user(), iax2_destroy(), iax2_predestroy(), iax2_show_users(), load_module(), prune_users(), realtime_user(), reload_config(), set_config(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), sip_show_users(), and unload_module().

int usingGk = 0 [static]
 

Definition at line 114 of file chan_h323.c.

Referenced by oh323_call(), oh323_request(), reload_config(), and setup_incoming_call().


Generated on Sun Aug 6 15:05:53 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.2