Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:28 2009

## 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)
struct rtp_info * | external_rtp_create (unsigned call_reference, const char *token)
struct oh323_alias * | find_alias (const char *source_aliases)
static struct oh323_pvt * | find_call_locked (int call_reference, const char *token)
struct oh323_peer * | find_peer (const char *peer, struct sockaddr_in *sin)
struct 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_pvt * | oh323_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_rtp * | oh323_get_rtp_peer (struct ast_channel *chan)
static struct ast_rtp * | oh323_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_frame * | oh323_read (struct ast_channel *c)
static struct ast_channel * | oh323_request (const char *type, int format, void *data, int *cause)
static struct ast_frame * | oh323_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
struct oh323_pvt * | iflist
static struct io_context * | io
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_context * | sched
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
  - Config_h323

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, read]`

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_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, read]`

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

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

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

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

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

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

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

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

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

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

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

Definition at line 946 of file chan_h323.c.

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

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

void delete_users | ( | void |  | ) |

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

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

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 2461 of file chan_h323.c.

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

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, oh323_pvt::needdestroy, oh323_pvt::next, option_verbose, 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 |
| ) |  |  | `[read]`

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 | ) | `[read]`

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, read]`

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 |
| ) |  |  | `[read]`

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(), calltoken_required(), 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(), requirecalltoken_mark_auto(), 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 | ) | `[read]`

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(), calltoken_required(), check_user_full(), forward_message(), leave_voicemail(), requirecalltoken_mark_auto(), 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 1676 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

static int h323_do_reload | ( | void |  | ) | `[static]`

Definition at line 2224 of file chan_h323.c.

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

Referenced by do_monitor().

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

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

Definition at line 1656 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1714 of file chan_h323.c.

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

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

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

Definition at line 1696 of file chan_h323.c.

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

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

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

Definition at line 1686 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 1666 of file chan_h323.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

Definition at line 2211 of file chan_h323.c.

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

Referenced by reload().

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

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

Definition at line 1727 of file chan_h323.c.

References RESULT_SHOWUSAGE, and RESULT_SUCCESS.

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

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

References ASTERISK_GPL_KEY.

    02467 {
    02468    return ASTERISK_GPL_KEY;
    02469 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

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

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

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

static struct oh323_pvt* oh323_alloc | ( | int | callid | ) | `[static, read]`

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(), bindaddr, oh323_pvt::cd, oh323_pvt::context, free, iflist, oh323_pvt::lock, LOG_ERROR, LOG_WARNING, malloc, oh323_pvt::newcontrol, oh323_pvt::newstate, oh323_pvt::next, oh323_pvt::nonCodecCapability, oh323_pvt::options, and oh323_pvt::rtp.

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, read]`

Definition at line 2242 of file chan_h323.c.

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

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

static struct ast_rtp* oh323_get_vrtp_peer | ( | struct ast_channel * | chan | ) | `[static, read]`

Definition at line 2252 of file chan_h323.c.

    02253 {
    02254    return NULL;
    02255 }

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, read]`

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, read]`

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, read]`

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

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

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

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

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

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

References h323_reload().

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

static int reload_config | ( | void |  | ) |

Definition at line 1997 of file chan_h323.c.

References ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_H261, AST_FORMAT_ULAW, ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), bindaddr, build_alias(), build_peer(), build_user(), cfg, format, hp, IPTOS_MINCOST, ast_variable::lineno, ast_alias_list::lock, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, update_common_options(), user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.

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

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

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(), setup_zap(), 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                   pthread_attr_destroy(&attr);
    01646                         ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
    01647                         return -1;
    01648                 }
    01649       pthread_attr_destroy(&attr);
    01650
    01651    }
    01652    ast_mutex_unlock(&monlock);
    01653    return 0;
    01654 }

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(), ast_frame::data, ast_frame::datalen, find_call_locked(), ast_frame::frametype, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, oh323_pvt::owner, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

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

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

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

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

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

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

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

    02457 {
    02458    return usecnt;
    02459 }

## Variable Documentation

struct ast_alias_list aliasl`[static]`

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

struct sockaddr_in bindaddr`[static]`

Definition at line 107 of file chan_h323.c.

Referenced by ast_sip_ouraddrfor(), load_module(), oh323_alloc(), 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 1776 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 1782 of file chan_h323.c.

struct ast_cli_entry cli_h323_reload`[static]`

Initial value:

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

Definition at line 2239 of file chan_h323.c.

struct ast_cli_entry cli_hangup_call`[static]`

Initial value:

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

Definition at line 1784 of file chan_h323.c.

struct ast_cli_entry cli_no_debug`[static]`

Initial value:

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

Definition at line 1778 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 1774 of file chan_h323.c.

struct ast_cli_entry cli_show_codecs`[static]`

Initial value:

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

Definition at line 1780 of file chan_h323.c.

struct ast_cli_entry cli_show_tokens`[static]`

Initial value:

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

Definition at line 1786 of file chan_h323.c.

struct ast_cli_entry cli_trace`[static]`

Initial value:

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

Definition at line 1772 of file chan_h323.c.

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

Definition at line 105 of file chan_h323.c.

char debug_usage[]`[static]`

Initial value:

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

Definition at line 1744 of file chan_h323.c.

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

Definition at line 106 of file chan_h323.c.

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 1768 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(), oh323_alloc(), phone_request(), sip_alloc(), sip_show_channel(), sip_show_history(), unload_module(), vpb_request(), zap_destroy_channel(), zap_show_channel(), zap_show_channels(), zt_hangup(), and zt_request().

struct io_context* io`[static]`

Definition at line 170 of file chan_h323.c.

pthread_t monitor_thread = AST_PTHREADT_NULL`[static]`

Definition at line 192 of file chan_h323.c.

Referenced by unload_module().

char no_debug_usage[]`[static]`

Initial value:

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

Definition at line 1748 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 1740 of file chan_h323.c.

struct ast_rtp_protocol oh323_rtp`[static]`

Definition at line 2307 of file chan_h323.c.

struct ast_channel_tech oh323_tech`[static]`

Definition at line 206 of file chan_h323.c.

answer_call_cb on_answer_call

Definition at line 92 of file chan_h323.c.

chan_ringing_cb on_chan_ringing

Definition at line 89 of file chan_h323.c.

clear_con_cb on_connection_cleared

Definition at line 91 of file chan_h323.c.

con_established_cb on_connection_established

Definition at line 90 of file chan_h323.c.

on_rtp_cb on_external_rtp_create

Definition at line 85 of file chan_h323.c.

hangup_cb on_hangup

Definition at line 95 of file chan_h323.c.

setup_incoming_cb on_incoming_call

Definition at line 87 of file chan_h323.c.

setup_outbound_cb on_outgoing_call

Definition at line 88 of file chan_h323.c.

progress_cb on_progress

Definition at line 93 of file chan_h323.c.

send_digit_cb on_send_digit

Definition at line 84 of file chan_h323.c.

rfc2833_cb on_set_rfc2833_payload

Definition at line 94 of file chan_h323.c.

setcapabilities_cb on_setcapabilities

Definition at line 96 of file chan_h323.c.

start_rtp_cb on_start_rtp_channel

Definition at line 86 of file chan_h323.c.

struct ast_peer_list peerl`[static]`

Referenced by __iax2_show_peers(), __unload_module(), _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(), load_module(), prune_peers(), realtime_peer(), register_verify(), reload_config(), set_config(), sip_do_reload(), 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 1752 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 1756 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 1760 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 1764 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.

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 1736 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 __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), complete_sip_user(), delete_users(), find_user(), iax2_destroy_helper(), iax2_predestroy(), iax2_show_users(), load_module(), prune_users(), realtime_user(), reload_config(), set_config(), sip_do_reload(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), sip_show_users(), and unload_module().

int usingGk = 0`[static]`

Definition at line 114 of file chan_h323.c.