Fri Sep 29 11:13:14 2006

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, int nat_active)
static void oh323_update_info (struct ast_channel *c)
static int oh323_write (struct ast_channel *c, struct ast_frame *frame)
int progress (unsigned call_reference, const char *token, int inband)
void prune_peers (void)
int reload (void)
 Reload stuff.
int reload_config (void)
static int restart_monitor (void)
int send_digit (unsigned call_reference, char digit, const char *token)
void set_dtmf_payload (unsigned call_reference, const char *token, int payload)
static void set_local_capabilities (unsigned call_reference, const char *token)
call_options_t * setup_incoming_call (call_details_t *cd)
int setup_outgoing_call (call_details_t *cd)
void setup_rtp_connection (unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
int unload_module ()
 Cleanup all module structures, sockets, etc.
static int update_common_options (struct ast_variable *v, struct call_options *options)
static int update_state (struct oh323_pvt *pvt, int state, int signal)
int usecount ()
 Provides a usecount.

Variables

static struct ast_alias_list aliasl
static struct sockaddr_in bindaddr
static struct ast_cli_entry cli_debug
static struct ast_cli_entry cli_gk_cycle
static struct ast_cli_entry cli_h323_reload
static struct ast_cli_entry cli_hangup_call
static struct ast_cli_entry cli_no_debug
static struct ast_cli_entry cli_no_trace
static struct ast_cli_entry cli_show_codecs
static struct ast_cli_entry cli_show_tokens
static struct ast_cli_entry cli_trace
static const char config [] = "h323.conf"
static char debug_usage []
static char default_context [AST_MAX_CONTEXT] = "default"
static const char desc [] = "The NuFone Network's Open H.323 Channel Driver"
static char gatekeeper [100]
static int gatekeeper_disable = 1
static int gatekeeper_discover = 0
static int gkroute = 0
static call_options_t global_options
static char h323_reload_usage []
static int h323_reloading = 0
static int h323_signalling_port = 1720
int h323debug
oh323_pvtiflist
static struct io_contextio
static pthread_t monitor_thread = AST_PTHREADT_NULL
static char no_debug_usage []
static char no_trace_usage []
static struct ast_rtp_protocol oh323_rtp
static 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 
00773       if (!ast_strlen_zero(pvt->cid_num))
00774          ch->cid.cid_num = strdup(pvt->cid_num);
00775       else if (!ast_strlen_zero(pvt->cd.call_source_e164))
00776          ch->cid.cid_num = strdup(pvt->cd.call_source_e164);
00777       if (!ast_strlen_zero(pvt->cid_name))
00778          ch->cid.cid_name = strdup(pvt->cid_name);
00779 
00780       if (!ast_strlen_zero(pvt->rdnis)) {
00781          ch->cid.cid_rdnis = strdup(pvt->rdnis);
00782       }
00783       if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
00784          ch->cid.cid_dnid = strdup(pvt->exten);
00785       }
00786       ast_setstate(ch, state);
00787       if (state != AST_STATE_DOWN) {
00788          if (ast_pbx_start(ch)) {
00789             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
00790             ast_hangup(ch);
00791             ch = NULL;
00792          }
00793       }
00794    } else  {
00795       ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
00796    }
00797    return ch;
00798 }

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

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

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

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

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

Definition at line 1927 of file chan_h323.c.

References ast_get_ip(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), free, 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().

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

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

Definition at line 1879 of file chan_h323.c.

References ast_cdr_amaflags2int(), ast_get_ip(), ast_log(), format, free, 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().

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

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

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

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

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

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

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

static char* convertcap ( int  cap  )  [static]

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

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

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

Definition at line 946 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 cache_get_callno_locked(), iax2_call(), iax2_provision(), iax2_request(), oh323_request(), sip_notify(), sip_request_call(), and transmit_register().

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

void delete_aliases ( void   ) 

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

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

void delete_users ( void   ) 

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

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

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 2459 of file chan_h323.c.

02460 {
02461    return (char *) desc;
02462 }

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

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

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

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

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

struct oh323_alias* find_alias ( const char *  source_aliases  ) 

Find a call by alias

Definition at line 1088 of file chan_h323.c.

References ast_alias_list::aliases, and aliasl.

Referenced by __get_header(), and setup_incoming_call().

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

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

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

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

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

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

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

struct oh323_user* find_user ( const call_details_t *  cd  ) 

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

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

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

Definition at line 1674 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

static int h323_do_reload ( void   )  [static]

Definition at line 2222 of file chan_h323.c.

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

Referenced by do_monitor().

02223 {
02224    delete_users();
02225    delete_aliases();
02226    prune_peers();
02227    reload_config();
02228    restart_monitor();
02229    return 0;
02230 }

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

Definition at line 1654 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1712 of file chan_h323.c.

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

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

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

Definition at line 1694 of file chan_h323.c.

References ast_log(), LOG_ERROR, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1684 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1664 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 2209 of file chan_h323.c.

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

Referenced by reload().

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

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

Definition at line 1725 of file chan_h323.c.

References RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01726 {
01727         if (argc != 3) {
01728                 return RESULT_SHOWUSAGE;
01729    }
01730    h323_show_tokens();
01731    return RESULT_SUCCESS;
01732 }

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

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

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

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

References ASTERISK_GPL_KEY.

02465 {
02466    return ASTERISK_GPL_KEY;
02467 }

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

References aliasl, answer_call(), ast_channel_register(), ast_cli_register(), ast_log(), ast_mutex_init(), ast_rtp_proto_register(), 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(), 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, sched_context_create(), send_digit(), set_dtmf_payload(), set_local_capabilities(), setup_incoming_call(), setup_outgoing_call(), setup_rtp_connection(), and userl.

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

static struct oh323_pvt* oh323_alloc ( int  callid  )  [static]

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

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

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

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

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

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

Definition at line 2250 of file chan_h323.c.

02251 {
02252    return NULL;
02253 }

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 1009 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.

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

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

Definition at line 540 of file chan_h323.c.

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

Referenced by oh323_read().

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

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

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

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

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

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

static void prune_peers ( void   ) 

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

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

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

References h323_reload().

02233 {
02234    return h323_reload(0, 0, NULL);
02235 }

static int reload_config ( void   ) 

Definition at line 1995 of file chan_h323.c.

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

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

static int restart_monitor ( void   )  [static]

Definition at line 1620 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, and LOG_WARNING.

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(), zt_hangup(), and zt_request().

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

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

Callback for sending digits from H.323 up to asterisk

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

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

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

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

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

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

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

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

call_options_t* setup_incoming_call ( call_details_t *  cd  ) 

Call-back function for incoming calls

Returns 1 on success

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

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

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

References cleanup_call_details().

Referenced by load_module().

01422 {
01423    /* Use argument here or free it immediately */
01424    cleanup_call_details(cd);
01425 
01426    return 1;
01427 }

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

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

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 2380 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, oh323_pvt::next, oh323_rtp, oh323_tech, oh323_pvt::owner, peerl, prune_peers(), sched, sched_context_destroy(), and userl.

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

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

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

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

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

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

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

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

02455 {
02456    return usecnt;
02457 }


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 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 1774 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 1780 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 2237 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 1782 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 1776 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 1772 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 1778 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 1784 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 1770 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 1742 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_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.

int gatekeeper_disable = 1 [static]

Definition at line 112 of file chan_h323.c.

int gatekeeper_discover = 0 [static]

Definition at line 113 of file chan_h323.c.

int gkroute = 0 [static]

Definition at line 115 of file chan_h323.c.

call_options_t global_options [static]

Definition at line 122 of file chan_h323.c.

char h323_reload_usage[] [static]

Initial value:

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

Definition at line 1766 of file chan_h323.c.

int h323_reloading = 0 [static]

Definition at line 188 of file chan_h323.c.

int h323_signalling_port = 1720 [static]

H.323 configuration values

Definition at line 110 of file chan_h323.c.

int h323debug

Definition at line 99 of file chan_h323.c.

struct oh323_pvt * iflist

Private structure of a OpenH323 channel

Referenced by __oh323_destroy(), __sip_destroy(), __sip_show_channels(), __unload_module(), action_zapshowchannels(), chandup(), complete_sipch(), destroy_channel(), do_monitor(), find_call(), find_call_locked(), find_channel(), get_sip_pvt_byid_locked(), handle_request_subscribe(), load_module(), mkintf(), 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(), ast_rtp_new_with_bindaddr(), 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 1746 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 1738 of file chan_h323.c.

struct ast_rtp_protocol oh323_rtp [static]

Definition at line 2305 of file chan_h323.c.

Referenced by load_module(), and unload_module().

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_inuse(), sip_show_objects(), timing_read(), and unload_module().

struct sched_context* sched [static]

Asterisk RTP stuff

Definition at line 169 of file chan_h323.c.

char secret[50] [static]

Definition at line 119 of file chan_h323.c.

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

char show_codec_usage[] [static]

Initial value:

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

Definition at line 1750 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 1754 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 1758 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 1762 of file chan_h323.c.

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

Definition at line 104 of file chan_h323.c.

int tos = 0 [static]

Definition at line 118 of file chan_h323.c.

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

struct ast_user_list userl [static]

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

int usingGk = 0 [static]

Definition at line 114 of file chan_h323.c.


Generated on Fri Sep 29 11:13:15 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7