Sat Mar 24 23:27:09 2007

Asterisk developer's documentation


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  ast_alias_list
struct  ast_peer_list
 The peer list: Peers and Friends ---. More...
struct  ast_user_list
 The user list: Users and friends ---. More...
struct  oh323_pvt
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)
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_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_update_use_count(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_name, oh323_pvt::cid_name, ast_callerid::cid_num, 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, oh323_pvt::lock, LOG_WARNING, ast_channel::name, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_tech, 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, ast_channel::type, 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       if (!ast_strlen_zero(pvt->cid_num)) {
00773          ch->cid.cid_num = strdup(pvt->cid_num);
00774       } else if (!ast_strlen_zero(pvt->cd.call_source_e164)) {
00775          ch->cid.cid_num = strdup(pvt->cd.call_source_e164);
00776       }
00777       if (!ast_strlen_zero(pvt->cid_name)) {
00778          ch->cid.cid_name = strdup(pvt->cid_name);
00779       } else if (!ast_strlen_zero(pvt->cd.call_source_name)) {
00780          ch->cid.cid_name = strdup(pvt->cd.call_source_name);
00781       }
00782       if (!ast_strlen_zero(pvt->rdnis)) {
00783          ch->cid.cid_rdnis = strdup(pvt->rdnis);
00784       }
00785       if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
00786          ch->cid.cid_dnid = strdup(pvt->exten);
00787       }
00788       ast_setstate(ch, state);
00789       if (state != AST_STATE_DOWN) {
00790          if (ast_pbx_start(ch)) {
00791             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
00792             ast_hangup(ch);
00793             ch = NULL;
00794          }
00795       }
00796    } else  {
00797       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00798    }
00799    return ch;
00800 }

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

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

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

Definition at line 1931 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().

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

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

Definition at line 1883 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().

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

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(), ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state().

Referenced by load_module().

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

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 1464 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(), oh323_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, oh323_pvt::owner, oh323_pvt::rtp, and oh323_pvt::vad.

Referenced by load_module().

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

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 1234 of file chan_h323.c.

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

Referenced by load_module().

01235 {
01236    struct ast_channel *c = NULL;
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 2259 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().

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

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

Definition at line 948 of file chan_h323.c.

References ahp, ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setnat(), find_peer(), 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 iax2_call(), iax2_provision(), iax2_request(), oh323_request(), sip_notify(), sip_request_call(), and transmit_register().

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

void delete_aliases void   ) 
 

Definition at line 2175 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().

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

void delete_users void   ) 
 

Definition at line 2152 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().

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

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 2463 of file chan_h323.c.

References desc.

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

static void* do_monitor void *  data  )  [static]
 

Definition at line 1576 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(), iflist, io, oh323_pvt::needdestroy, oh323_pvt::next, option_verbose, sched, and VERBOSE_PREFIX_1.

Referenced by restart_monitor().

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

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 1139 of file chan_h323.c.

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

Referenced by load_module().

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

struct oh323_alias* find_alias const char *  source_aliases  ) 
 

Find a call by alias

Definition at line 1090 of file chan_h323.c.

References ast_alias_list::aliases, and aliasl.

Referenced by setup_incoming_call().

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

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

Definition at line 846 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().

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

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

Definition at line 915 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().

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

struct oh323_user* find_user const call_details_t *  cd  ) 
 

Definition at line 892 of file chan_h323.c.

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

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

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

Definition at line 1678 of file chan_h323.c.

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

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

static int h323_do_reload void   )  [static]
 

Definition at line 2226 of file chan_h323.c.

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

Referenced by do_monitor().

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

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

Definition at line 1658 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1716 of file chan_h323.c.

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

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

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

Definition at line 1698 of file chan_h323.c.

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

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

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

Definition at line 1688 of file chan_h323.c.

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

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

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

Definition at line 1668 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 2213 of file chan_h323.c.

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

Referenced by reload().

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

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

Definition at line 1729 of file chan_h323.c.

References RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1513 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().

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

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 2468 of file chan_h323.c.

References ASTERISK_GPL_KEY.

02469 {
02470    return ASTERISK_GPL_KEY;
02471 }

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 2316 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(), cli_debug, cli_gk_cycle, cli_h323_reload, cli_hangup_call, cli_no_debug, cli_no_trace, cli_show_codecs, cli_show_tokens, cli_trace, connection_made(), external_rtp_create(), gatekeeper, gatekeeper_disable, gatekeeper_discover, h323_signalling_port, hangup_connection(), io, io_context_create(), ast_alias_list::lock, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_WARNING, oh323_rtp, oh323_tech, 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.

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

static struct oh323_pvt* oh323_alloc int  callid  )  [static]
 

Definition at line 802 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(), oh323_pvt::cd, oh323_pvt::context, free, iflist, io, 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 sched.

Referenced by oh323_request(), and setup_incoming_call().

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

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, 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, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, oh323_update_info(), oh323_pvt::options, oh323_pvt::outgoing, oh323_pvt::sa, and ast_channel::tech_pvt.

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, 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 2244 of file chan_h323.c.

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

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

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

Definition at line 2254 of file chan_h323.c.

02255 {
02256    return NULL;
02257 }

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, 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, 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, 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 1011 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, host, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_alloc(), oh323_destroy(), oh323_pvt::options, restart_monitor(), and oh323_pvt::rtp.

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

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
[static]
 

Definition at line 2284 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, oh323_pvt::rtp, ast_channel::tech_pvt, and ast_channel::writeformat.

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

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 2190 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().

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

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 2236 of file chan_h323.c.

References h323_reload().

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

static int reload_config void   ) 
 

Definition at line 1999 of file chan_h323.c.

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

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

static int restart_monitor void   )  [static]
 

Definition at line 1624 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(), sip_reload(), sip_request_call(), skinny_request(), vpb_hangup(), vpb_request(), and zt_hangup().

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

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

Callback for sending digits from H.323 up to asterisk

Definition at line 1108 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().

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

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

Definition at line 1537 of file chan_h323.c.

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

Referenced by load_module().

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

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

Definition at line 1556 of file chan_h323.c.

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

Referenced by load_module().

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

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, oh323_pvt::exten, find_alias(), find_user(), LOG_DEBUG, LOG_ERROR, oh323_alloc(), oh323_pvt::options, user, 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 1180 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(), 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().

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

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 2384 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, cli_debug, cli_gk_cycle, cli_h323_reload, cli_hangup_call, cli_no_debug, cli_no_trace, cli_show_codecs, cli_show_tokens, cli_trace, delete_aliases(), delete_users(), free, iflist, io, 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_rtp, oh323_tech, oh323_pvt::owner, peerl, prune_peers(), sched_context_destroy(), and userl.

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

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

Definition at line 1791 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().

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

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

Definition at line 872 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().

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

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 2458 of file chan_h323.c.

References usecnt.

02459 {
02460    return usecnt;
02461 }


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 ast_sip_ouraddrfor(), load_module(), reload_config(), sip_alloc(), sip_show_settings(), start_rtp(), and transmit_register().

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 1778 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 1784 of file chan_h323.c.

Referenced by load_module(), and unload_module().

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 2241 of file chan_h323.c.

Referenced by load_module(), and unload_module().

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 1786 of file chan_h323.c.

Referenced by load_module(), and unload_module().

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 1780 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 1776 of file chan_h323.c.

Referenced by load_module(), and unload_module().

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 1782 of file chan_h323.c.

Referenced by load_module(), and unload_module().

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 1788 of file chan_h323.c.

Referenced by load_module(), and unload_module().

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 1774 of file chan_h323.c.

Referenced by load_module(), and unload_module().

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 1746 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(), reload_config(), 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(), and reload_config().

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

call_options_t global_options [static]
 

Definition at line 122 of file chan_h323.c.

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

char h323_reload_usage[] [static]
 

Initial value:

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

Definition at line 1770 of file chan_h323.c.

int h323_reloading = 0 [static]
 

Definition at line 188 of file chan_h323.c.

Referenced by 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(), load_module(), and reload_config().

int h323debug
 

Definition at line 99 of file chan_h323.c.

Referenced by h323_do_debug(), h323_no_debug(), and reload_config().

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(), do_monitor(), find_call(), find_call_locked(), find_channel(), get_sip_pvt_byid_locked(), handle_request_subscribe(), load_module(), mkintf(), modem_request(), 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.

Referenced by ast_expr(), ast_rtp_new(), do_monitor(), load_module(), network_thread(), oh323_alloc(), reload_config(), set_config(), sip_alloc(), start_rtp(), and unload_module().

pthread_t monitor_thread = AST_PTHREADT_NULL [static]
 

Definition at line 192 of file chan_h323.c.

Referenced by 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 1750 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 1742 of file chan_h323.c.

struct ast_rtp_protocol oh323_rtp [static]
 

Definition at line 2309 of file chan_h323.c.

Referenced by load_module(), and unload_module().

const struct ast_channel_tech oh323_tech [static]
 

Definition at line 206 of file chan_h323.c.

Referenced by __oh323_new(), load_module(), and unload_module().

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_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(), 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 1754 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 1758 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 1762 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 1766 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 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 1738 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.

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 reload_config().

struct ast_user_list userl [static]
 

Referenced by build_user(), check_access(), complete_sip_user(), delete_users(), find_user(), iax2_show_users(), load_module(), prune_users(), realtime_user(), reload_config(), set_config(), 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 reload_config().


Generated on Sat Mar 24 23:27:10 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6