#include "asterisk.h"
#include <sys/types.h>
#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/lock.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/musiconhold.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 "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/astobj.h"
#include "h323/chan_h323.h"
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 |
Structure representing a RTP session.The value of each payload format mapping:. More... | |
Defines | |
#define | DEPRECATED(_v, _new_opt) ast_log(LOG_WARNING, "Option %s found at line %d has beed deprecated. Use %s instead.\n", (_v)->name, (_v)->lineno, (_new_opt)) |
#define | GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_H261) |
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 int | __oh323_rtp_create (struct oh323_pvt *pvt) |
static void | __oh323_update_info (struct ast_channel *c, struct oh323_pvt *pvt) |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | answer_call (unsigned call_reference, const char *token) |
static struct oh323_alias * | build_alias (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
static struct oh323_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
static struct oh323_user * | build_user (char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
static 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) |
static void | connection_made (unsigned call_reference, const char *token) |
static char * | convertcap (int cap) |
static int | create_addr (struct oh323_pvt *pvt, char *opeer) |
static void | delete_aliases (void) |
static void | delete_users (void) |
static void * | do_monitor (void *data) |
static struct rtp_info * | external_rtp_create (unsigned call_reference, const char *token) |
static struct oh323_alias * | find_alias (const char *source_aliases, int realtime) |
static struct oh323_pvt * | find_call_locked (int call_reference, const char *token) |
static struct oh323_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
static struct oh323_user * | find_user (const call_details_t *cd, int realtime) |
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 int | h323_version_show (int fd, int argc, char *argv[]) |
static void | hangup_connection (unsigned int call_reference, const char *token, int cause) |
static enum ast_module_load_result | load_module (void) |
static int | oh323_addrcmp (struct sockaddr_in addr, struct sockaddr_in *sin) |
static int | oh323_addrcmp_str (struct in_addr inaddr, char *addr) |
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 void | oh323_destroy_alias (struct oh323_alias *alias) |
static void | oh323_destroy_peer (struct oh323_peer *peer) |
static void | oh323_destroy_user (struct oh323_user *user) |
static int | oh323_digit_begin (struct ast_channel *c, char digit) |
static int | oh323_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | oh323_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static enum ast_rtp_get_result | oh323_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
static enum ast_rtp_get_result | oh323_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
static int | oh323_hangup (struct ast_channel *c) |
static int | oh323_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
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 int | oh323_simulate_dtmf_end (const void *data) |
static void | oh323_update_info (struct ast_channel *c) |
static int | oh323_write (struct ast_channel *c, struct ast_frame *frame) |
static int | progress (unsigned call_reference, const char *token, int inband) |
static void | prune_peers (void) |
static struct oh323_alias * | realtime_alias (const char *alias) |
static struct oh323_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static struct oh323_user * | realtime_user (const call_details_t *cd) |
static int | receive_digit (unsigned call_reference, char digit, const char *token, int duration) |
static const char * | redirectingreason2str (int redirectingreason) |
static int | reload (void) |
static int | reload_config (int is_reload) |
static int | restart_monitor (void) |
static void | set_dtmf_payload (unsigned call_reference, const char *token, int payload) |
static void | set_local_capabilities (unsigned call_reference, const char *token) |
static void | set_peer_capabilities (unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs) |
static call_options_t * | setup_incoming_call (call_details_t *cd) |
static int | setup_outgoing_call (call_details_t *cd) |
static void | setup_rtp_connection (unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt) |
static int | unload_module (void) |
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) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "The NuFone Network's OpenH323 Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } |
static int | acceptAnonymous = 1 |
static struct ast_alias_list | aliasl |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static struct sockaddr_in | bindaddr |
static ast_mutex_t | caplock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static struct ast_cli_entry | cli_h323 [] |
static struct ast_cli_entry | cli_h323_debug_deprecated |
static struct ast_cli_entry | cli_h323_gk_cycle_deprecated |
static struct ast_cli_entry | cli_h323_no_debug_deprecated |
static struct ast_cli_entry | cli_h323_no_trace_deprecated |
static struct ast_cli_entry | cli_h323_reload |
static struct ast_cli_entry | cli_h323_trace_deprecated |
static const char | config [] = "h323.conf" |
static char | debug_usage [] |
static char | default_context [AST_MAX_CONTEXT] = "default" |
static struct ast_jb_conf | default_jbconf |
static char | gatekeeper [100] |
static int | gatekeeper_disable = 1 |
static int | gatekeeper_discover = 0 |
static int | gkroute = 0 |
static struct ast_jb_conf | global_jbconf |
static call_options_t | global_options |
static ast_mutex_t | h323_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static char | h323_reload_usage [] |
static int | h323_reloading = 0 |
static int | h323_signalling_port = 1720 |
int | h323debug |
oh323_pvt * | iflist |
static ast_mutex_t | iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static struct io_context * | io |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
static ast_mutex_t | monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
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 |
receive_digit_cb | on_receive_digit |
rfc2833_cb | on_set_rfc2833_payload |
setcapabilities_cb | on_setcapabilities |
setpeercapabilities_cb | on_setpeercapabilities |
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_cycle_usage [] |
static char | show_hangup_usage [] |
static char | show_tokens_usage [] |
static char | show_version_usage [] |
static const char | tdesc [] = "The NuFone Network's Open H.323 Channel Driver" |
static int | tos = 0 |
static char | trace_usage [] |
static unsigned int | unique = 0 |
static int | userbyalias = 1 |
static struct ast_user_list | userl |
Definition in file chan_h323.c.
#define DEPRECATED | ( | _v, | |||
_new_opt | ) | ast_log(LOG_WARNING, "Option %s found at line %d has beed deprecated. Use %s instead.\n", (_v)->name, (_v)->lineno, (_new_opt)) |
#define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_H261) |
static void __oh323_destroy | ( | struct oh323_pvt * | pvt | ) | [static] |
Definition at line 450 of file chan_h323.c.
References ast_channel_lock, ast_channel_unlock, ast_dsp_free(), ast_log(), ast_mutex_destroy(), ast_mutex_unlock(), ast_rtp_destroy(), AST_SCHED_DEL, oh323_pvt::cd, cleanup_call_details(), oh323_pvt::DTMFsched, free, iflist, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, oh323_pvt::next, dahdi_pvt::next, oh323_pvt::owner, oh323_pvt::rtp, sched, ast_channel::tech_pvt, and oh323_pvt::vad.
Referenced by do_monitor(), and oh323_destroy().
00451 { 00452 struct oh323_pvt *cur, *prev = NULL; 00453 00454 AST_SCHED_DEL(sched, pvt->DTMFsched); 00455 00456 if (pvt->rtp) { 00457 ast_rtp_destroy(pvt->rtp); 00458 } 00459 00460 /* Free dsp used for in-band DTMF detection */ 00461 if (pvt->vad) { 00462 ast_dsp_free(pvt->vad); 00463 } 00464 cleanup_call_details(&pvt->cd); 00465 00466 /* Unlink us from the owner if we have one */ 00467 if (pvt->owner) { 00468 ast_channel_lock(pvt->owner); 00469 if (h323debug) 00470 ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name); 00471 pvt->owner->tech_pvt = NULL; 00472 ast_channel_unlock(pvt->owner); 00473 } 00474 cur = iflist; 00475 while(cur) { 00476 if (cur == pvt) { 00477 if (prev) 00478 prev->next = cur->next; 00479 else 00480 iflist = cur->next; 00481 break; 00482 } 00483 prev = cur; 00484 cur = cur->next; 00485 } 00486 if (!cur) { 00487 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur); 00488 } else { 00489 ast_mutex_unlock(&pvt->lock); 00490 ast_mutex_destroy(&pvt->lock); 00491 free(pvt); 00492 } 00493 }
static struct ast_channel* __oh323_new | ( | struct oh323_pvt * | pvt, | |
int | state, | |||
const char * | host | |||
) | [static] |
Definition at line 1003 of file chan_h323.c.
References accountcode, oh323_pvt::accountcode, ast_channel::amaflags, oh323_pvt::amaflags, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_copy_string(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_udptl_fd(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, cid_name, cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_ton, ast_channel::context, oh323_pvt::context, DSP_FEATURE_DTMF_DETECT, ast_channel::exten, oh323_pvt::exten, ast_channel::fds, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_WARNING, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_tech, oh323_pvt::options, oh323_pvt::owner, pbx_builtin_setvar_helper(), ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, redirectingreason2str(), ast_channel::rings, oh323_pvt::rtp, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, oh323_pvt::vad, and ast_channel::writeformat.
Referenced by answer_call(), and oh323_request().
01004 { 01005 struct ast_channel *ch; 01006 char *cid_num, *cid_name; 01007 int fmt; 01008 01009 if (!ast_strlen_zero(pvt->options.cid_num)) 01010 cid_num = pvt->options.cid_num; 01011 else 01012 cid_num = pvt->cd.call_source_e164; 01013 01014 if (!ast_strlen_zero(pvt->options.cid_name)) 01015 cid_name = pvt->options.cid_name; 01016 else 01017 cid_name = pvt->cd.call_source_name; 01018 01019 /* Don't hold a oh323_pvt lock while we allocate a chanel */ 01020 ast_mutex_unlock(&pvt->lock); 01021 ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host); 01022 /* Update usage counter */ 01023 ast_module_ref(ast_module_info->self); 01024 ast_mutex_lock(&pvt->lock); 01025 if (ch) { 01026 ch->tech = &oh323_tech; 01027 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability)) 01028 fmt = global_options.capability; 01029 ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/; 01030 pvt->nativeformats = ch->nativeformats; 01031 fmt = ast_best_codec(ch->nativeformats); 01032 ch->writeformat = fmt; 01033 ch->rawwriteformat = fmt; 01034 ch->readformat = fmt; 01035 ch->rawreadformat = fmt; 01036 #if 0 01037 ch->fds[0] = ast_rtp_fd(pvt->rtp); 01038 ch->fds[1] = ast_rtcp_fd(pvt->rtp); 01039 #endif 01040 #ifdef VIDEO_SUPPORT 01041 if (pvt->vrtp) { 01042 ch->fds[2] = ast_rtp_fd(pvt->vrtp); 01043 ch->fds[3] = ast_rtcp_fd(pvt->vrtp); 01044 } 01045 #endif 01046 #ifdef T38_SUPPORT 01047 if (pvt->udptl) { 01048 ch->fds[4] = ast_udptl_fd(pvt->udptl); 01049 } 01050 #endif 01051 if (state == AST_STATE_RING) { 01052 ch->rings = 1; 01053 } 01054 /* Allocate dsp for in-band DTMF support */ 01055 if (pvt->options.dtmfmode & H323_DTMF_INBAND) { 01056 pvt->vad = ast_dsp_new(); 01057 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT); 01058 } 01059 /* Register channel functions. */ 01060 ch->tech_pvt = pvt; 01061 /* Set the owner of this channel */ 01062 pvt->owner = ch; 01063 01064 ast_copy_string(ch->context, pvt->context, sizeof(ch->context)); 01065 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten)); 01066 ch->priority = 1; 01067 if (!ast_strlen_zero(pvt->accountcode)) { 01068 ast_string_field_set(ch, accountcode, pvt->accountcode); 01069 } 01070 if (pvt->amaflags) { 01071 ch->amaflags = pvt->amaflags; 01072 } 01073 01074 /* Don't use ast_set_callerid() here because it will 01075 * generate a needless NewCallerID event */ 01076 ch->cid.cid_ani = ast_strdup(cid_num); 01077 01078 if (pvt->cd.redirect_reason >= 0) { 01079 ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number); 01080 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason)); 01081 } 01082 ch->cid.cid_pres = pvt->cd.presentation; 01083 ch->cid.cid_ton = pvt->cd.type_of_number; 01084 01085 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) { 01086 ch->cid.cid_dnid = strdup(pvt->exten); 01087 } 01088 if (pvt->cd.transfer_capability >= 0) 01089 ch->transfercapability = pvt->cd.transfer_capability; 01090 if (state != AST_STATE_DOWN) { 01091 if (ast_pbx_start(ch)) { 01092 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name); 01093 ast_hangup(ch); 01094 ch = NULL; 01095 } 01096 } 01097 } else { 01098 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 01099 } 01100 return ch; 01101 }
static int __oh323_rtp_create | ( | struct oh323_pvt * | pvt | ) | [static] |
Definition at line 957 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, ast_find_ourip(), ast_jb_configure(), ast_log(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), ast_rtcp_fd(), ast_rtp_codec_setpref(), ast_rtp_fd(), ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpmap_type(), ast_rtp_setnat(), ast_rtp_settos(), oh323_pvt::dtmf_pt, errno, ast_channel::fds, global_jbconf, io, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, oh323_pvt::options, oh323_pvt::owner, oh323_pvt::peer_prefs, oh323_pvt::peercapability, oh323_pvt::rtp, sched, and oh323_pvt::update_rtp_info.
Referenced by external_rtp_create(), and setup_rtp_connection().
00958 { 00959 struct in_addr our_addr; 00960 00961 if (pvt->rtp) 00962 return 0; 00963 00964 if (ast_find_ourip(&our_addr, bindaddr)) { 00965 ast_mutex_unlock(&pvt->lock); 00966 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n"); 00967 return -1; 00968 } 00969 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr); 00970 if (!pvt->rtp) { 00971 ast_mutex_unlock(&pvt->lock); 00972 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); 00973 return -1; 00974 } 00975 if (h323debug) 00976 ast_log(LOG_DEBUG, "Created RTP channel\n"); 00977 00978 ast_rtp_settos(pvt->rtp, tos); 00979 00980 if (h323debug) 00981 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat); 00982 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00983 00984 if (pvt->dtmf_pt > 0) 00985 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0); 00986 00987 if (pvt->peercapability) 00988 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 00989 00990 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 00991 ast_jb_configure(pvt->owner, &global_jbconf); 00992 pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp); 00993 pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp); 00994 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00995 ast_channel_unlock(pvt->owner); 00996 } else 00997 pvt->update_rtp_info = 1; 00998 00999 return 0; 01000 }
static void __oh323_update_info | ( | struct ast_channel * | c, | |
struct oh323_pvt * | pvt | |||
) | [static] |
Definition at line 339 of file chan_h323.c.
References ast_channel::_softhangup, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_jb_configure(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_rtcp_fd(), ast_rtp_fd(), ast_sched_add(), AST_SCHED_DEL, ast_set_read_format(), ast_set_write_format(), ast_setstate(), AST_SOFTHANGUP_DEV, oh323_pvt::curDTMF, oh323_pvt::DTMFsched, f, ast_channel::fds, global_jbconf, oh323_pvt::hangupcause, ast_channel::hangupcause, LOG_DEBUG, LOG_DTMF, ast_channel::name, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_pvt::needhangup, oh323_pvt::newcontrol, oh323_pvt::newdigit, oh323_pvt::newduration, oh323_pvt::newstate, oh323_simulate_dtmf_end(), oh323_pvt::owner, ast_channel::readformat, oh323_pvt::rtp, sched, oh323_pvt::update_rtp_info, and ast_channel::writeformat.
Referenced by oh323_read(), oh323_update_info(), and oh323_write().
00340 { 00341 if (c->nativeformats != pvt->nativeformats) { 00342 if (h323debug) 00343 ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name); 00344 c->nativeformats = pvt->nativeformats; 00345 ast_set_read_format(c, c->readformat); 00346 ast_set_write_format(c, c->writeformat); 00347 } 00348 if (pvt->needhangup) { 00349 if (h323debug) 00350 ast_log(LOG_DEBUG, "Process pending hangup for %s\n", c->name); 00351 c->_softhangup |= AST_SOFTHANGUP_DEV; 00352 c->hangupcause = pvt->hangupcause; 00353 ast_queue_hangup(c); 00354 pvt->needhangup = 0; 00355 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1; 00356 } 00357 if (pvt->newstate >= 0) { 00358 ast_setstate(c, pvt->newstate); 00359 pvt->newstate = -1; 00360 } 00361 if (pvt->newcontrol >= 0) { 00362 ast_queue_control(c, pvt->newcontrol); 00363 pvt->newcontrol = -1; 00364 } 00365 if (pvt->newdigit >= 0) { 00366 struct ast_frame f = { 00367 .frametype = AST_FRAME_DTMF_END, 00368 .subclass = pvt->newdigit, 00369 .samples = pvt->newduration * 8, 00370 .len = pvt->newduration, 00371 .src = "UPDATE_INFO", 00372 }; 00373 if (pvt->newdigit == ' ') { /* signalUpdate message */ 00374 f.subclass = pvt->curDTMF; 00375 if (pvt->DTMFsched >= 0) { 00376 AST_SCHED_DEL(sched, pvt->DTMFsched); 00377 } 00378 } else { /* Regular input or signal message */ 00379 if (pvt->newduration) { /* This is a signal, signalUpdate follows */ 00380 f.frametype = AST_FRAME_DTMF_BEGIN; 00381 AST_SCHED_DEL(sched, pvt->DTMFsched); 00382 pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt); 00383 if (h323debug) 00384 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched); 00385 } 00386 pvt->curDTMF = pvt->newdigit; 00387 } 00388 ast_queue_frame(c, &f); 00389 pvt->newdigit = -1; 00390 } 00391 if (pvt->update_rtp_info > 0) { 00392 if (pvt->rtp) { 00393 ast_jb_configure(c, &global_jbconf); 00394 c->fds[0] = ast_rtp_fd(pvt->rtp); 00395 c->fds[1] = ast_rtcp_fd(pvt->rtp); 00396 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00397 } 00398 pvt->update_rtp_info = -1; 00399 } 00400 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 3312 of file chan_h323.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 3312 of file chan_h323.c.
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 2179 of file chan_h323.c.
References __oh323_new(), AST_CAUSE_UNALLOCATED, ast_copy_string(), ast_exists_extension(), ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, oh323_pvt::cd, oh323_pvt::context, oh323_pvt::exten, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, and LOG_NOTICE.
Referenced by load_module().
02180 { 02181 struct oh323_pvt *pvt; 02182 struct ast_channel *c = NULL; 02183 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten; 02184 char tmp_exten[sizeof(pvt->exten)]; 02185 02186 if (h323debug) 02187 ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token); 02188 02189 /* Find the call or allocate a private structure if call not found */ 02190 pvt = find_call_locked(call_reference, token); 02191 if (!pvt) { 02192 ast_log(LOG_ERROR, "Something is wrong: answer_call\n"); 02193 return 0; 02194 } 02195 /* Check if requested extension@context pair exists in the dialplan */ 02196 ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten)); 02197 02198 /* Try to find best extension in specified context */ 02199 if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) { 02200 if (tmp_exten[0] == 's') 02201 try_exten = ext_s; 02202 else if (tmp_exten[0] == 'i') 02203 try_exten = ext_i; 02204 else 02205 try_exten = ext_original; 02206 } else 02207 try_exten = ext_original; 02208 do { 02209 if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL)) 02210 break; 02211 switch (try_exten) { 02212 case ext_original: 02213 tmp_exten[0] = 's'; 02214 tmp_exten[1] = '\0'; 02215 try_exten = ext_s; 02216 break; 02217 case ext_s: 02218 tmp_exten[0] = 'i'; 02219 try_exten = ext_i; 02220 break; 02221 case ext_i: 02222 try_exten = ext_notexists; 02223 break; 02224 default: 02225 break; 02226 } 02227 } while (try_exten != ext_notexists); 02228 02229 /* Drop the call if we don't have <exten>, s and i extensions */ 02230 if (try_exten == ext_notexists) { 02231 ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context); 02232 ast_mutex_unlock(&pvt->lock); 02233 h323_clear_call(token, AST_CAUSE_UNALLOCATED); 02234 return 0; 02235 } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) { 02236 if (h323debug) 02237 ast_log(LOG_DEBUG, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context); 02238 ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten)); 02239 } 02240 02241 /* allocate a channel and tell asterisk about it */ 02242 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token); 02243 02244 /* And release when done */ 02245 ast_mutex_unlock(&pvt->lock); 02246 if (!c) { 02247 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n"); 02248 return 0; 02249 } 02250 return 1; 02251 }
static struct oh323_alias* build_alias | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Definition at line 1194 of file chan_h323.c.
References aliasl, ast_copy_string(), ast_log(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_INIT, ASTOBJ_UNMARK, calloc, LOG_WARNING, ast_variable::name, ast_variable::next, and ast_variable::value.
01195 { 01196 struct oh323_alias *alias; 01197 int found = 0; 01198 01199 alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp); 01200 01201 if (alias) 01202 found++; 01203 else { 01204 if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias)))) 01205 return NULL; 01206 ASTOBJ_INIT(alias); 01207 } 01208 if (!found && name) 01209 ast_copy_string(alias->name, name, sizeof(alias->name)); 01210 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01211 if (!strcasecmp(v->name, "e164")) { 01212 ast_copy_string(alias->e164, v->value, sizeof(alias->e164)); 01213 } else if (!strcasecmp(v->name, "prefix")) { 01214 ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix)); 01215 } else if (!strcasecmp(v->name, "context")) { 01216 ast_copy_string(alias->context, v->value, sizeof(alias->context)); 01217 } else if (!strcasecmp(v->name, "secret")) { 01218 ast_copy_string(alias->secret, v->value, sizeof(alias->secret)); 01219 } else { 01220 if (strcasecmp(v->value, "h323")) { 01221 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name); 01222 } 01223 } 01224 } 01225 ASTOBJ_UNMARK(alias); 01226 return alias; 01227 }
static struct oh323_peer* build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Definition at line 1445 of file chan_h323.c.
References ast_append_ha(), ast_copy_string(), ast_free_ha(), ast_get_ip(), ast_log(), ast_strlen_zero(), ast_true(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, calloc, global_options, h323_signalling_port, LOG_ERROR, ast_variable::name, ast_variable::next, oh323_destroy_peer(), peerl, update_common_options(), and ast_variable::value.
Referenced by reload_config(), and set_config().
01446 { 01447 struct oh323_peer *peer; 01448 struct ast_ha *oldha; 01449 int found = 0; 01450 01451 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 01452 01453 if (peer) 01454 found++; 01455 else { 01456 if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer)))) 01457 return NULL; 01458 ASTOBJ_INIT(peer); 01459 } 01460 oldha = peer->ha; 01461 peer->ha = NULL; 01462 memcpy(&peer->options, &global_options, sizeof(peer->options)); 01463 peer->addr.sin_port = htons(h323_signalling_port); 01464 peer->addr.sin_family = AF_INET; 01465 if (!found && name) 01466 ast_copy_string(peer->name, name, sizeof(peer->name)); 01467 01468 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01469 if (peer->chanvars) { 01470 ast_variables_destroy(peer->chanvars); 01471 peer->chanvars = NULL; 01472 } 01473 #endif 01474 /* Default settings for mailbox */ 01475 peer->mailbox[0] = '\0'; 01476 01477 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01478 if (!update_common_options(v, &peer->options)) 01479 continue; 01480 if (!strcasecmp(v->name, "host")) { 01481 if (!strcasecmp(v->value, "dynamic")) { 01482 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n"); 01483 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01484 return NULL; 01485 } 01486 if (ast_get_ip(&peer->addr, v->value)) { 01487 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value); 01488 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01489 return NULL; 01490 } 01491 } else if (!strcasecmp(v->name, "port")) { 01492 peer->addr.sin_port = htons(atoi(v->value)); 01493 } else if (!strcasecmp(v->name, "permit") || 01494 !strcasecmp(v->name, "deny")) { 01495 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 01496 } else if (!strcasecmp(v->name, "mailbox")) { 01497 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 01498 } else if (!strcasecmp(v->name, "hasvoicemail")) { 01499 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 01500 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 01501 } 01502 } 01503 } 01504 ASTOBJ_UNMARK(peer); 01505 ast_free_ha(oldha); 01506 return peer; 01507 }
static struct oh323_user* build_user | ( | char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Definition at line 1339 of file chan_h323.c.
References ast_append_ha(), ast_cdr_amaflags2int(), ast_copy_string(), ast_free_ha(), ast_get_ip(), ast_log(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_INIT, ASTOBJ_UNMARK, ASTOBJ_UNREF, calloc, default_context, format, global_options, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, oh323_destroy_user(), update_common_options(), userl, and ast_variable::value.
Referenced by reload_config(), and set_config().
01340 { 01341 struct oh323_user *user; 01342 struct ast_ha *oldha; 01343 int found = 0; 01344 int format; 01345 01346 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp); 01347 01348 if (user) 01349 found++; 01350 else { 01351 if (!(user = (struct oh323_user *)calloc(1, sizeof(*user)))) 01352 return NULL; 01353 ASTOBJ_INIT(user); 01354 } 01355 oldha = user->ha; 01356 user->ha = (struct ast_ha *)NULL; 01357 memcpy(&user->options, &global_options, sizeof(user->options)); 01358 /* Set default context */ 01359 ast_copy_string(user->context, default_context, sizeof(user->context)); 01360 if (user && !found) 01361 ast_copy_string(user->name, name, sizeof(user->name)); 01362 01363 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01364 if (user->chanvars) { 01365 ast_variables_destroy(user->chanvars); 01366 user->chanvars = NULL; 01367 } 01368 #endif 01369 01370 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01371 if (!update_common_options(v, &user->options)) 01372 continue; 01373 if (!strcasecmp(v->name, "context")) { 01374 ast_copy_string(user->context, v->value, sizeof(user->context)); 01375 } else if (!strcasecmp(v->name, "secret")) { 01376 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 01377 } else if (!strcasecmp(v->name, "accountcode")) { 01378 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 01379 } else if (!strcasecmp(v->name, "host")) { 01380 if (!strcasecmp(v->value, "dynamic")) { 01381 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n"); 01382 ASTOBJ_UNREF(user, oh323_destroy_user); 01383 return NULL; 01384 } else if (ast_get_ip(&user->addr, v->value)) { 01385 ASTOBJ_UNREF(user, oh323_destroy_user); 01386 return NULL; 01387 } 01388 /* Let us know we need to use ip authentication */ 01389 user->host = 1; 01390 } else if (!strcasecmp(v->name, "amaflags")) { 01391 format = ast_cdr_amaflags2int(v->value); 01392 if (format < 0) { 01393 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 01394 } else { 01395 user->amaflags = format; 01396 } 01397 } else if (!strcasecmp(v->name, "permit") || 01398 !strcasecmp(v->name, "deny")) { 01399 user->ha = ast_append_ha(v->name, v->value, user->ha); 01400 } 01401 } 01402 ASTOBJ_UNMARK(user); 01403 ast_free_ha(oldha); 01404 return user; 01405 }
static void chan_ringing | ( | unsigned | call_reference, | |
const char * | token | |||
) | [static] |
Call-back function to signal asterisk that the channel is ringing Returns nothing
Definition at line 2270 of file chan_h323.c.
References AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state().
Referenced by load_module().
02271 { 02272 struct oh323_pvt *pvt; 02273 02274 if (h323debug) 02275 ast_log(LOG_DEBUG, "Ringing on %s\n", token); 02276 02277 pvt = find_call_locked(call_reference, token); 02278 if (!pvt) { 02279 ast_log(LOG_ERROR, "Something is wrong: ringing\n"); 02280 return; 02281 } 02282 if (!pvt->owner) { 02283 ast_mutex_unlock(&pvt->lock); 02284 ast_log(LOG_ERROR, "Channel has no owner\n"); 02285 return; 02286 } 02287 update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING); 02288 ast_mutex_unlock(&pvt->lock); 02289 return; 02290 }
static void cleanup_call_details | ( | call_details_t * | cd | ) | [static] |
Definition at line 414 of file chan_h323.c.
References free.
Referenced by __oh323_destroy(), cleanup_connection(), setup_incoming_call(), and setup_outgoing_call().
00415 { 00416 if (cd->call_token) { 00417 free(cd->call_token); 00418 cd->call_token = NULL; 00419 } 00420 if (cd->call_source_aliases) { 00421 free(cd->call_source_aliases); 00422 cd->call_source_aliases = NULL; 00423 } 00424 if (cd->call_dest_alias) { 00425 free(cd->call_dest_alias); 00426 cd->call_dest_alias = NULL; 00427 } 00428 if (cd->call_source_name) { 00429 free(cd->call_source_name); 00430 cd->call_source_name = NULL; 00431 } 00432 if (cd->call_source_e164) { 00433 free(cd->call_source_e164); 00434 cd->call_source_e164 = NULL; 00435 } 00436 if (cd->call_dest_e164) { 00437 free(cd->call_dest_e164); 00438 cd->call_dest_e164 = NULL; 00439 } 00440 if (cd->sourceIp) { 00441 free(cd->sourceIp); 00442 cd->sourceIp = NULL; 00443 } 00444 if (cd->redirect_number) { 00445 free(cd->redirect_number); 00446 cd->redirect_number = NULL; 00447 } 00448 }
static void cleanup_connection | ( | unsigned | call_reference, | |
const char * | call_token | |||
) | [static] |
Call-back function to cleanup communication Returns nothing,
Definition at line 2296 of file chan_h323.c.
References ast_channel::_softhangup, oh323_pvt::alreadygone, ast_channel_trylock, ast_channel_unlock, ast_dsp_free(), ast_log(), ast_mutex_unlock(), ast_queue_hangup(), ast_rtp_destroy(), AST_SOFTHANGUP_DEV, oh323_pvt::cd, cleanup_call_details(), find_call_locked(), h323debug, oh323_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, oh323_pvt::owner, oh323_pvt::rtp, and oh323_pvt::vad.
Referenced by load_module().
02297 { 02298 struct oh323_pvt *pvt; 02299 02300 if (h323debug) 02301 ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token); 02302 02303 while (1) { 02304 pvt = find_call_locked(call_reference, call_token); 02305 if (!pvt) { 02306 if (h323debug) 02307 ast_log(LOG_DEBUG, "No connection for %s\n", call_token); 02308 return; 02309 } 02310 if (!pvt->owner || !ast_channel_trylock(pvt->owner)) 02311 break; 02312 #if 1 02313 #ifdef DEBUG_THREADS 02314 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[0], pvt->owner->lock.reentrancy, pvt->owner->lock.func[0], pvt->owner->lock.file[0], pvt->owner->lock.lineno[0]); 02315 #else 02316 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token); 02317 #endif 02318 #endif 02319 ast_mutex_unlock(&pvt->lock); 02320 usleep(1); 02321 } 02322 if (pvt->rtp) { 02323 /* Immediately stop RTP */ 02324 ast_rtp_destroy(pvt->rtp); 02325 pvt->rtp = NULL; 02326 } 02327 /* Free dsp used for in-band DTMF detection */ 02328 if (pvt->vad) { 02329 ast_dsp_free(pvt->vad); 02330 pvt->vad = NULL; 02331 } 02332 cleanup_call_details(&pvt->cd); 02333 pvt->alreadygone = 1; 02334 /* Send hangup */ 02335 if (pvt->owner) { 02336 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02337 ast_queue_hangup(pvt->owner); 02338 ast_channel_unlock(pvt->owner); 02339 } 02340 ast_mutex_unlock(&pvt->lock); 02341 if (h323debug) 02342 ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token); 02343 return; 02344 }
static void connection_made | ( | unsigned | call_reference, | |
const char * | token | |||
) | [static] |
Call-back function to signal asterisk that the channel has been answered Returns nothing
Definition at line 2004 of file chan_h323.c.
References AST_CONTROL_ANSWER, ast_log(), ast_mutex_unlock(), oh323_pvt::connection_established, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::outgoing, and update_state().
Referenced by load_module().
02005 { 02006 struct oh323_pvt *pvt; 02007 02008 if (h323debug) 02009 ast_log(LOG_DEBUG, "Call %s answered\n", token); 02010 02011 pvt = find_call_locked(call_reference, token); 02012 if (!pvt) { 02013 ast_log(LOG_ERROR, "Something is wrong: connection\n"); 02014 return; 02015 } 02016 02017 /* Inform asterisk about remote party connected only on outgoing calls */ 02018 if (!pvt->outgoing) { 02019 ast_mutex_unlock(&pvt->lock); 02020 return; 02021 } 02022 /* Do not send ANSWER message more than once */ 02023 if (!pvt->connection_established) { 02024 pvt->connection_established = 1; 02025 update_state(pvt, -1, AST_CONTROL_ANSWER); 02026 } 02027 ast_mutex_unlock(&pvt->lock); 02028 return; 02029 }
static char* convertcap | ( | int | cap | ) | [static] |
Definition at line 3072 of file chan_h323.c.
References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G722, 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().
03073 { 03074 switch (cap) { 03075 case AST_FORMAT_G723_1: 03076 return "G.723"; 03077 case AST_FORMAT_GSM: 03078 return "GSM"; 03079 case AST_FORMAT_ULAW: 03080 return "ULAW"; 03081 case AST_FORMAT_ALAW: 03082 return "ALAW"; 03083 case AST_FORMAT_G722: 03084 return "G.722"; 03085 case AST_FORMAT_ADPCM: 03086 return "G.728"; 03087 case AST_FORMAT_G729A: 03088 return "G.729"; 03089 case AST_FORMAT_SPEEX: 03090 return "SPEEX"; 03091 case AST_FORMAT_ILBC: 03092 return "ILBC"; 03093 default: 03094 ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap); 03095 return NULL; 03096 } 03097 }
static int create_addr | ( | struct oh323_pvt * | pvt, | |
char * | opeer | |||
) | [static] |
Definition at line 1605 of file chan_h323.c.
References ahp, ast_copy_string(), ast_gethostbyname(), ast_log(), AST_RTP_DTMF, ASTOBJ_UNREF, find_peer(), global_options, h323_signalling_port, hp, oh323_pvt::jointcapability, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_destroy_peer(), oh323_pvt::options, portno, 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().
01606 { 01607 struct hostent *hp; 01608 struct ast_hostent ahp; 01609 struct oh323_peer *p; 01610 int portno; 01611 int found = 0; 01612 char *port; 01613 char *hostn; 01614 char peer[256] = ""; 01615 01616 ast_copy_string(peer, opeer, sizeof(peer)); 01617 port = strchr(peer, ':'); 01618 if (port) { 01619 *port = '\0'; 01620 port++; 01621 } 01622 pvt->sa.sin_family = AF_INET; 01623 p = find_peer(peer, NULL, 1); 01624 if (p) { 01625 found++; 01626 memcpy(&pvt->options, &p->options, sizeof(pvt->options)); 01627 pvt->jointcapability = pvt->options.capability; 01628 if (pvt->options.dtmfmode) { 01629 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01630 pvt->nonCodecCapability |= AST_RTP_DTMF; 01631 } else { 01632 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01633 } 01634 } 01635 if (p->addr.sin_addr.s_addr) { 01636 pvt->sa.sin_addr = p->addr.sin_addr; 01637 pvt->sa.sin_port = p->addr.sin_port; 01638 } 01639 ASTOBJ_UNREF(p, oh323_destroy_peer); 01640 } 01641 if (!p && !found) { 01642 hostn = peer; 01643 if (port) { 01644 portno = atoi(port); 01645 } else { 01646 portno = h323_signalling_port; 01647 } 01648 hp = ast_gethostbyname(hostn, &ahp); 01649 if (hp) { 01650 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 01651 pvt->sa.sin_port = htons(portno); 01652 /* Look peer by address */ 01653 p = find_peer(NULL, &pvt->sa, 1); 01654 memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options)); 01655 pvt->jointcapability = pvt->options.capability; 01656 if (p) { 01657 ASTOBJ_UNREF(p, oh323_destroy_peer); 01658 } 01659 if (pvt->options.dtmfmode) { 01660 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01661 pvt->nonCodecCapability |= AST_RTP_DTMF; 01662 } else { 01663 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01664 } 01665 } 01666 return 0; 01667 } else { 01668 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01669 return -1; 01670 } 01671 } else if (!found) { 01672 return -1; 01673 } else { 01674 return 0; 01675 } 01676 }
static void delete_aliases | ( | void | ) | [static] |
Definition at line 2771 of file chan_h323.c.
References aliasl, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and oh323_destroy_alias().
Referenced by reload_config().
02772 { 02773 int pruned = 0; 02774 02775 /* Delete all aliases */ 02776 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 02777 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 02778 ASTOBJ_RDLOCK(iterator); 02779 ASTOBJ_MARK(iterator); 02780 ++pruned; 02781 ASTOBJ_UNLOCK(iterator); 02782 } while (0) ); 02783 if (pruned) { 02784 ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias); 02785 } 02786 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 02787 }
static void delete_users | ( | void | ) | [static] |
Definition at line 2745 of file chan_h323.c.
References ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, oh323_destroy_user(), peerl, and userl.
Referenced by __unload_module(), reload_config(), and set_config_destroy().
02746 { 02747 int pruned = 0; 02748 02749 /* Delete all users */ 02750 ASTOBJ_CONTAINER_WRLOCK(&userl); 02751 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 02752 ASTOBJ_RDLOCK(iterator); 02753 ASTOBJ_MARK(iterator); 02754 ++pruned; 02755 ASTOBJ_UNLOCK(iterator); 02756 } while (0) ); 02757 if (pruned) { 02758 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user); 02759 } 02760 ASTOBJ_CONTAINER_UNLOCK(&userl); 02761 02762 ASTOBJ_CONTAINER_WRLOCK(&peerl); 02763 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 02764 ASTOBJ_RDLOCK(iterator); 02765 ASTOBJ_MARK(iterator); 02766 ASTOBJ_UNLOCK(iterator); 02767 } while (0) ); 02768 ASTOBJ_CONTAINER_UNLOCK(&peerl); 02769 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 2461 of file chan_h323.c.
References __oh323_destroy(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_verbose(), h323_do_reload(), h323_reload_lock, h323_reloading, iflist, iflock, oh323_pvt::lock, oh323_pvt::needdestroy, oh323_pvt::next, option_verbose, and VERBOSE_PREFIX_1.
02462 { 02463 int res; 02464 int reloading; 02465 struct oh323_pvt *oh323 = NULL; 02466 02467 for(;;) { 02468 /* Check for a reload request */ 02469 ast_mutex_lock(&h323_reload_lock); 02470 reloading = h323_reloading; 02471 h323_reloading = 0; 02472 ast_mutex_unlock(&h323_reload_lock); 02473 if (reloading) { 02474 if (option_verbose > 0) { 02475 ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n"); 02476 } 02477 h323_do_reload(); 02478 } 02479 /* Check for interfaces needing to be killed */ 02480 if (!ast_mutex_trylock(&iflock)) { 02481 #if 1 02482 do { 02483 for (oh323 = iflist; oh323; oh323 = oh323->next) { 02484 if (!ast_mutex_trylock(&oh323->lock)) { 02485 if (oh323->needdestroy) { 02486 __oh323_destroy(oh323); 02487 break; 02488 } 02489 ast_mutex_unlock(&oh323->lock); 02490 } 02491 } 02492 } while (/*oh323*/ 0); 02493 #else 02494 restartsearch: 02495 oh323 = iflist; 02496 while(oh323) { 02497 if (!ast_mutex_trylock(&oh323->lock)) { 02498 if (oh323->needdestroy) { 02499 __oh323_destroy(oh323); 02500 goto restartsearch; 02501 } 02502 ast_mutex_unlock(&oh323->lock); 02503 oh323 = oh323->next; 02504 } 02505 } 02506 #endif 02507 ast_mutex_unlock(&iflock); 02508 } else 02509 oh323 = (struct oh323_pvt *)1; /* Force fast loop */ 02510 pthread_testcancel(); 02511 /* Wait for sched or io */ 02512 res = ast_sched_wait(sched); 02513 if ((res < 0) || (res > 1000)) { 02514 res = 1000; 02515 } 02516 /* Do not wait if some channel(s) is destroyed, probably, more available too */ 02517 if (oh323) 02518 res = 1; 02519 res = ast_io_wait(io, res); 02520 pthread_testcancel(); 02521 ast_mutex_lock(&monlock); 02522 if (res >= 0) { 02523 ast_sched_runq(sched); 02524 } 02525 ast_mutex_unlock(&monlock); 02526 } 02527 /* Never reached */ 02528 return NULL; 02529 }
static struct rtp_info* external_rtp_create | ( | unsigned | call_reference, | |
const char * | token | |||
) | [static] |
Callback function used to inform the H.323 stack of the local rtp ip/port details
Returns the local RTP information
Definition at line 1850 of file chan_h323.c.
References __oh323_rtp_create(), ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_rtp_get_us(), find_call_locked(), free, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, malloc, and oh323_pvt::rtp.
Referenced by load_module().
01851 { 01852 struct oh323_pvt *pvt; 01853 struct sockaddr_in us; 01854 struct rtp_info *info; 01855 01856 info = (struct rtp_info *)malloc(sizeof(struct rtp_info)); 01857 if (!info) { 01858 ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n"); 01859 return NULL; 01860 } 01861 pvt = find_call_locked(call_reference, token); 01862 if (!pvt) { 01863 free(info); 01864 ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference); 01865 return NULL; 01866 } 01867 if (!pvt->rtp) 01868 __oh323_rtp_create(pvt); 01869 if (!pvt->rtp) { 01870 ast_mutex_unlock(&pvt->lock); 01871 free(info); 01872 ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference); 01873 return NULL; 01874 } 01875 /* figure out our local RTP port and tell the H.323 stack about it */ 01876 ast_rtp_get_us(pvt->rtp, &us); 01877 ast_mutex_unlock(&pvt->lock); 01878 01879 ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr)); 01880 info->port = ntohs(us.sin_port); 01881 if (h323debug) 01882 ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port); 01883 return info; 01884 }
static struct oh323_alias* find_alias | ( | const char * | source_aliases, | |
int | realtime | |||
) | [static] |
Find a call by alias
Definition at line 1766 of file chan_h323.c.
References aliasl, ASTOBJ_CONTAINER_FIND, and realtime_alias().
Referenced by __get_header(), add_header(), and setup_incoming_call().
01767 { 01768 struct oh323_alias *a; 01769 01770 a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases); 01771 01772 if (!a && realtime) 01773 a = realtime_alias(source_aliases); 01774 01775 return a; 01776 }
static struct oh323_pvt* find_call_locked | ( | int | call_reference, | |
const char * | token | |||
) | [static] |
Definition at line 1147 of file chan_h323.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::cd, iflist, iflock, 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(), receive_digit(), set_dtmf_payload(), set_local_capabilities(), set_peer_capabilities(), and setup_rtp_connection().
01148 { 01149 struct oh323_pvt *pvt; 01150 01151 ast_mutex_lock(&iflock); 01152 pvt = iflist; 01153 while(pvt) { 01154 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) { 01155 /* Found the call */ 01156 if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) { 01157 ast_mutex_lock(&pvt->lock); 01158 ast_mutex_unlock(&iflock); 01159 return pvt; 01160 } else if (token == NULL) { 01161 ast_log(LOG_WARNING, "Call Token is NULL\n"); 01162 ast_mutex_lock(&pvt->lock); 01163 ast_mutex_unlock(&iflock); 01164 return pvt; 01165 } 01166 } 01167 pvt = pvt->next; 01168 } 01169 ast_mutex_unlock(&iflock); 01170 return NULL; 01171 }
static struct oh323_peer* find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [static] |
Definition at line 1587 of file chan_h323.c.
References ast_inet_ntoa(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, h323debug, LOG_DEBUG, oh323_addrcmp(), peerl, and realtime_peer().
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(), set_config(), sip_devicestate(), sip_do_debug_peer(), sip_peer_hold(), update_call_counter(), and update_registry().
01588 { 01589 struct oh323_peer *p; 01590 01591 if (peer) 01592 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 01593 else 01594 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp); 01595 01596 if (!p && realtime) 01597 p = realtime_peer(peer, sin); 01598 01599 if (!p && h323debug) 01600 ast_log(LOG_DEBUG, "Could not find peer by name %s or address %s\n", (peer ? peer : "<NONE>"), (sin ? ast_inet_ntoa(sin->sin_addr) : "<NONE>")); 01601 01602 return p; 01603 }
static struct oh323_user* find_user | ( | const call_details_t * | cd, | |
int | realtime | |||
) | [static] |
Definition at line 1557 of file chan_h323.c.
References ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, h323debug, LOG_DEBUG, oh323_addrcmp_str(), realtime_user(), userbyalias, and userl.
Referenced by admin_exec(), advanced_options(), calltoken_required(), check_user_full(), forward_message(), iax2_prune_realtime(), leave_voicemail(), requirecalltoken_mark_auto(), setup_incoming_call(), sip_show_user(), update_call_counter(), vm_authenticate(), vm_box_exists(), and vm_execmain().
01558 { 01559 struct oh323_user *u; 01560 01561 if (userbyalias) 01562 u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases); 01563 else 01564 u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str); 01565 01566 if (!u && realtime) 01567 u = realtime_user(cd); 01568 01569 if (!u && h323debug) 01570 ast_log(LOG_DEBUG, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp); 01571 01572 return u; 01573 }
static int h323_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2583 of file chan_h323.c.
References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02584 { 02585 if (argc < 2 || argc > 3) { 02586 return RESULT_SHOWUSAGE; 02587 } 02588 h323debug = 1; 02589 ast_cli(fd, "H.323 debug enabled\n"); 02590 return RESULT_SUCCESS; 02591 }
static int h323_do_reload | ( | void | ) | [static] |
Definition at line 3028 of file chan_h323.c.
References reload_config().
Referenced by do_monitor().
03029 { 03030 reload_config(1); 03031 return 0; 03032 }
static int h323_do_trace | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2563 of file chan_h323.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02564 { 02565 if (argc != 4) { 02566 return RESULT_SHOWUSAGE; 02567 } 02568 h323_debug(1, atoi(argv[3])); 02569 ast_cli(fd, "H.323 trace set to level %s\n", argv[2]); 02570 return RESULT_SUCCESS; 02571 }
static int h323_ep_hangup | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2619 of file chan_h323.c.
References ast_verbose(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and VERBOSE_PREFIX_3.
02620 { 02621 if (argc != 3) { 02622 return RESULT_SHOWUSAGE; 02623 } 02624 if (h323_soft_hangup(argv[2])) { 02625 ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]); 02626 } else { 02627 ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]); 02628 } 02629 return RESULT_SUCCESS; 02630 }
static int h323_gk_cycle | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2603 of file chan_h323.c.
References ast_log(), gatekeeper, gatekeeper_disable, gatekeeper_discover, LOG_ERROR, RESULT_SHOWUSAGE, RESULT_SUCCESS, and secret.
02604 { 02605 if (argc != 3) { 02606 return RESULT_SHOWUSAGE; 02607 } 02608 h323_gk_urq(); 02609 02610 /* Possibly register with a GK */ 02611 if (!gatekeeper_disable) { 02612 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 02613 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 02614 } 02615 } 02616 return RESULT_SUCCESS; 02617 }
static int h323_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2593 of file chan_h323.c.
References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02594 { 02595 if (argc < 3 || argc > 4) { 02596 return RESULT_SHOWUSAGE; 02597 } 02598 h323debug = 0; 02599 ast_cli(fd, "H.323 debug disabled\n"); 02600 return RESULT_SUCCESS; 02601 }
static int h323_no_trace | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2573 of file chan_h323.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02574 { 02575 if (argc < 3 || argc > 4) { 02576 return RESULT_SHOWUSAGE; 02577 } 02578 h323_debug(0,0); 02579 ast_cli(fd, "H.323 trace disabled\n"); 02580 return RESULT_SUCCESS; 02581 }
static int h323_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3015 of file chan_h323.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), h323_reload_lock, h323_reloading, and restart_monitor().
Referenced by reload().
03016 { 03017 ast_mutex_lock(&h323_reload_lock); 03018 if (h323_reloading) { 03019 ast_verbose("Previous H.323 reload not yet done\n"); 03020 } else { 03021 h323_reloading = 1; 03022 } 03023 ast_mutex_unlock(&h323_reload_lock); 03024 restart_monitor(); 03025 return 0; 03026 }
static int h323_tokens_show | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2632 of file chan_h323.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02633 { 02634 if (argc != 3) { 02635 return RESULT_SHOWUSAGE; 02636 } 02637 h323_show_tokens(); 02638 return RESULT_SUCCESS; 02639 }
static int h323_version_show | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2641 of file chan_h323.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02642 { 02643 if (argc != 3) { 02644 return RESULT_SHOWUSAGE; 02645 } 02646 h323_show_version(); 02647 return RESULT_SUCCESS; 02648 }
static void hangup_connection | ( | unsigned int | call_reference, | |
const char * | token, | |||
int | cause | |||
) | [static] |
Definition at line 2346 of file chan_h323.c.
References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, ast_log(), ast_mutex_unlock(), ast_queue_hangup(), AST_SOFTHANGUP_DEV, find_call_locked(), h323debug, oh323_pvt::hangupcause, ast_channel::hangupcause, oh323_pvt::lock, LOG_DEBUG, oh323_pvt::needhangup, and oh323_pvt::owner.
Referenced by load_module().
02347 { 02348 struct oh323_pvt *pvt; 02349 02350 if (h323debug) { 02351 ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause); 02352 } 02353 02354 pvt = find_call_locked(call_reference, token); 02355 if (!pvt) { 02356 if (h323debug) { 02357 ast_log(LOG_DEBUG, "Connection to %s already cleared\n", token); 02358 } 02359 return; 02360 } 02361 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 02362 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02363 pvt->owner->hangupcause = pvt->hangupcause = cause; 02364 ast_queue_hangup(pvt->owner); 02365 ast_channel_unlock(pvt->owner); 02366 } 02367 else { 02368 pvt->needhangup = 1; 02369 pvt->hangupcause = cause; 02370 if (h323debug) 02371 ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token); 02372 } 02373 ast_mutex_unlock(&pvt->lock); 02374 }
static enum ast_module_load_result load_module | ( | void | ) | [static] |
Definition at line 3132 of file chan_h323.c.
References aliasl, answer_call(), ast_channel_register(), ast_cli_register(), ast_cli_register_multiple(), ast_cli_unregister(), ast_cli_unregister_multiple(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_rtp_proto_register(), ast_rtp_proto_unregister(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, ASTOBJ_CONTAINER_INIT, bindaddr, chan_ringing(), cleanup_connection(), cli_h323, cli_h323_reload, connection_made(), external_rtp_create(), gatekeeper, gatekeeper_disable, gatekeeper_discover, h323_signalling_port, h323debug, hangup_connection(), io, io_context_create(), io_context_destroy(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, oh323_destroy_alias(), oh323_destroy_peer(), oh323_destroy_user(), oh323_rtp, oh323_tech, peerl, receive_digit(), reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), secret, set_dtmf_payload(), set_local_capabilities(), set_peer_capabilities(), setup_incoming_call(), setup_outgoing_call(), setup_rtp_connection(), and userl.
03133 { 03134 int res; 03135 03136 h323debug = 0; 03137 sched = sched_context_create(); 03138 if (!sched) { 03139 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 03140 return AST_MODULE_LOAD_FAILURE; 03141 } 03142 io = io_context_create(); 03143 if (!io) { 03144 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 03145 return AST_MODULE_LOAD_FAILURE; 03146 } 03147 ast_cli_register(&cli_h323_reload); 03148 ASTOBJ_CONTAINER_INIT(&userl); 03149 ASTOBJ_CONTAINER_INIT(&peerl); 03150 ASTOBJ_CONTAINER_INIT(&aliasl); 03151 res = reload_config(0); 03152 if (res) { 03153 /* No config entry */ 03154 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n"); 03155 ast_cli_unregister(&cli_h323_reload); 03156 io_context_destroy(io); 03157 io = NULL; 03158 sched_context_destroy(sched); 03159 sched = NULL; 03160 ASTOBJ_CONTAINER_DESTROY(&userl); 03161 ASTOBJ_CONTAINER_DESTROY(&peerl); 03162 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03163 return AST_MODULE_LOAD_DECLINE; 03164 } else { 03165 /* Make sure we can register our channel type */ 03166 if (ast_channel_register(&oh323_tech)) { 03167 ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n"); 03168 ast_cli_unregister(&cli_h323_reload); 03169 h323_end_process(); 03170 io_context_destroy(io); 03171 sched_context_destroy(sched); 03172 03173 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03174 ASTOBJ_CONTAINER_DESTROY(&userl); 03175 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03176 ASTOBJ_CONTAINER_DESTROY(&peerl); 03177 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03178 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03179 03180 return AST_MODULE_LOAD_FAILURE; 03181 } 03182 ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03183 03184 ast_rtp_proto_register(&oh323_rtp); 03185 03186 /* Register our callback functions */ 03187 h323_callback_register(setup_incoming_call, 03188 setup_outgoing_call, 03189 external_rtp_create, 03190 setup_rtp_connection, 03191 cleanup_connection, 03192 chan_ringing, 03193 connection_made, 03194 receive_digit, 03195 answer_call, 03196 progress, 03197 set_dtmf_payload, 03198 hangup_connection, 03199 set_local_capabilities, 03200 set_peer_capabilities); 03201 /* start the h.323 listener */ 03202 if (h323_start_listener(h323_signalling_port, bindaddr)) { 03203 ast_log(LOG_ERROR, "Unable to create H323 listener.\n"); 03204 ast_rtp_proto_unregister(&oh323_rtp); 03205 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03206 ast_cli_unregister(&cli_h323_reload); 03207 h323_end_process(); 03208 io_context_destroy(io); 03209 sched_context_destroy(sched); 03210 03211 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03212 ASTOBJ_CONTAINER_DESTROY(&userl); 03213 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03214 ASTOBJ_CONTAINER_DESTROY(&peerl); 03215 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03216 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03217 03218 return AST_MODULE_LOAD_DECLINE; 03219 } 03220 /* Possibly register with a GK */ 03221 if (!gatekeeper_disable) { 03222 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 03223 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 03224 gatekeeper_disable = 1; 03225 res = AST_MODULE_LOAD_SUCCESS; 03226 } 03227 } 03228 /* And start the monitor for the first time */ 03229 restart_monitor(); 03230 } 03231 return res; 03232 }
static int oh323_addrcmp | ( | struct sockaddr_in | addr, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 1575 of file chan_h323.c.
References inaddrcmp().
Referenced by find_peer().
01576 { 01577 int res; 01578 01579 if (!sin) 01580 res = -1; 01581 else 01582 res = inaddrcmp(&addr , sin); 01583 01584 return res; 01585 }
static int oh323_addrcmp_str | ( | struct in_addr | inaddr, | |
char * | addr | |||
) | [static] |
Definition at line 1552 of file chan_h323.c.
References ast_inet_ntoa().
Referenced by find_user().
01553 { 01554 return strcmp(ast_inet_ntoa(inaddr), addr); 01555 }
static struct oh323_pvt* oh323_alloc | ( | int | callid | ) | [static] |
Definition at line 1103 of file chan_h323.c.
References ast_copy_string(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), AST_RTP_DTMF, oh323_pvt::cd, oh323_pvt::context, oh323_pvt::DTMFsched, free, iflist, iflock, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_ERROR, malloc, oh323_pvt::newcontrol, oh323_pvt::newdigit, oh323_pvt::newstate, oh323_pvt::next, oh323_pvt::nonCodecCapability, oh323_pvt::options, oh323_pvt::rtp, and oh323_pvt::update_rtp_info.
Referenced by oh323_request(), and setup_incoming_call().
01104 { 01105 struct oh323_pvt *pvt; 01106 01107 pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt)); 01108 if (!pvt) { 01109 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n"); 01110 return NULL; 01111 } 01112 memset(pvt, 0, sizeof(struct oh323_pvt)); 01113 pvt->cd.redirect_reason = -1; 01114 pvt->cd.transfer_capability = -1; 01115 /* Ensure the call token is allocated for outgoing call */ 01116 if (!callid) { 01117 if ((pvt->cd).call_token == NULL) { 01118 (pvt->cd).call_token = (char *)malloc(128); 01119 } 01120 if (!pvt->cd.call_token) { 01121 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n"); 01122 ast_rtp_destroy(pvt->rtp); 01123 free(pvt); 01124 return NULL; 01125 } 01126 memset((char *)(pvt->cd).call_token, 0, 128); 01127 pvt->cd.call_reference = callid; 01128 } 01129 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01130 pvt->jointcapability = pvt->options.capability; 01131 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01132 pvt->nonCodecCapability |= AST_RTP_DTMF; 01133 } else { 01134 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01135 } 01136 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 01137 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1; 01138 ast_mutex_init(&pvt->lock); 01139 /* Add to interface list */ 01140 ast_mutex_lock(&iflock); 01141 pvt->next = iflist; 01142 iflist = pvt; 01143 ast_mutex_unlock(&iflock); 01144 return pvt; 01145 }
static int oh323_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 663 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.
00664 { 00665 int res; 00666 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00667 char *token; 00668 00669 if (h323debug) 00670 ast_log(LOG_DEBUG, "Answering on %s\n", c->name); 00671 00672 ast_mutex_lock(&pvt->lock); 00673 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00674 ast_mutex_unlock(&pvt->lock); 00675 res = h323_answering_call(token, 0); 00676 if (token) 00677 free(token); 00678 00679 oh323_update_info(c); 00680 if (c->_state != AST_STATE_UP) { 00681 ast_setstate(c, AST_STATE_UP); 00682 } 00683 return res; 00684 }
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 584 of file chan_h323.c.
References ast_channel::_state, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, AST_STATE_RESERVED, ast_strlen_zero(), ast_transfercapability2str(), ast_verbose(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_ton, oh323_pvt::exten, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, oh323_update_info(), option_verbose, oh323_pvt::options, oh323_pvt::outgoing, pbx_builtin_getvar_helper(), oh323_pvt::sa, ast_channel::tech_pvt, ast_channel::transfercapability, and VERBOSE_PREFIX_3.
00585 { 00586 int res = 0; 00587 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00588 const char *addr; 00589 char called_addr[1024]; 00590 00591 if (h323debug) { 00592 ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name); 00593 } 00594 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 00595 ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name); 00596 return -1; 00597 } 00598 ast_mutex_lock(&pvt->lock); 00599 if (!gatekeeper_disable) { 00600 if (ast_strlen_zero(pvt->exten)) { 00601 ast_copy_string(called_addr, dest, sizeof(called_addr)); 00602 } else { 00603 snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest); 00604 } 00605 } else { 00606 res = htons(pvt->sa.sin_port); 00607 addr = ast_inet_ntoa(pvt->sa.sin_addr); 00608 if (ast_strlen_zero(pvt->exten)) { 00609 snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res); 00610 } else { 00611 snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res); 00612 } 00613 } 00614 /* make sure null terminated */ 00615 called_addr[sizeof(called_addr) - 1] = '\0'; 00616 00617 if (c->cid.cid_num) 00618 ast_copy_string(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num)); 00619 00620 if (c->cid.cid_name) 00621 ast_copy_string(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name)); 00622 00623 if (c->cid.cid_rdnis) { 00624 ast_copy_string(pvt->options.cid_rdnis, c->cid.cid_rdnis, sizeof(pvt->options.cid_rdnis)); 00625 } 00626 00627 pvt->options.presentation = c->cid.cid_pres; 00628 pvt->options.type_of_number = c->cid.cid_ton; 00629 00630 if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) { 00631 if (!strcasecmp(addr, "UNKNOWN")) 00632 pvt->options.redirect_reason = 0; 00633 else if (!strcasecmp(addr, "BUSY")) 00634 pvt->options.redirect_reason = 1; 00635 else if (!strcasecmp(addr, "NO_REPLY")) 00636 pvt->options.redirect_reason = 2; 00637 else if (!strcasecmp(addr, "UNCONDITIONAL")) 00638 pvt->options.redirect_reason = 15; 00639 else 00640 pvt->options.redirect_reason = -1; 00641 } else 00642 pvt->options.redirect_reason = -1; 00643 00644 pvt->options.transfer_capability = c->transfercapability; 00645 00646 /* indicate that this is an outgoing call */ 00647 pvt->outgoing = 1; 00648 00649 if (option_verbose > 2) 00650 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability)); 00651 if (h323debug) 00652 ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec); 00653 ast_mutex_unlock(&pvt->lock); 00654 res = h323_make_call(called_addr, &(pvt->cd), &pvt->options); 00655 if (res) { 00656 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name); 00657 return -1; 00658 } 00659 oh323_update_info(c); 00660 return 0; 00661 }
static void oh323_destroy | ( | struct oh323_pvt * | pvt | ) | [static] |
Definition at line 495 of file chan_h323.c.
References __oh323_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iflock, oh323_pvt::lock, LOG_DEBUG, ast_channel::name, and oh323_pvt::owner.
Referenced by oh323_request(), and setup_incoming_call().
00496 { 00497 if (h323debug) { 00498 ast_log(LOG_DEBUG, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>")); 00499 } 00500 ast_mutex_lock(&iflock); 00501 ast_mutex_lock(&pvt->lock); 00502 __oh323_destroy(pvt); 00503 ast_mutex_unlock(&iflock); 00504 }
static void oh323_destroy_alias | ( | struct oh323_alias * | alias | ) | [static] |
Definition at line 286 of file chan_h323.c.
References ast_log(), free, and LOG_DEBUG.
Referenced by delete_aliases(), load_module(), and unload_module().
00287 { 00288 if (h323debug) 00289 ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name); 00290 free(alias); 00291 }
static void oh323_destroy_peer | ( | struct oh323_peer * | peer | ) | [static] |
Definition at line 301 of file chan_h323.c.
References ast_free_ha(), ast_log(), free, and LOG_DEBUG.
Referenced by build_peer(), create_addr(), load_module(), prune_peers(), reload_config(), and unload_module().
00302 { 00303 if (h323debug) 00304 ast_log(LOG_DEBUG, "Destroying peer '%s'\n", peer->name); 00305 ast_free_ha(peer->ha); 00306 free(peer); 00307 }
static void oh323_destroy_user | ( | struct oh323_user * | user | ) | [static] |
Definition at line 293 of file chan_h323.c.
References ast_free_ha(), ast_log(), free, and LOG_DEBUG.
Referenced by build_user(), delete_users(), load_module(), reload_config(), setup_incoming_call(), and unload_module().
00294 { 00295 if (h323debug) 00296 ast_log(LOG_DEBUG, "Destroying user '%s'\n", user->name); 00297 ast_free_ha(user->ha); 00298 free(user); 00299 }
static int oh323_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 506 of file chan_h323.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_begin(), oh323_pvt::cd, oh323_pvt::dtmf_pt, free, oh323_pvt::lock, LOG_DTMF, LOG_ERROR, ast_channel::name, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, ast_channel::tech_pvt, and oh323_pvt::txDtmfDigit.
00507 { 00508 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00509 char *token; 00510 00511 if (!pvt) { 00512 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00513 return -1; 00514 } 00515 ast_mutex_lock(&pvt->lock); 00516 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) { 00517 /* out-of-band DTMF */ 00518 if (h323debug) { 00519 ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name); 00520 } 00521 ast_rtp_senddigit_begin(pvt->rtp, digit); 00522 ast_mutex_unlock(&pvt->lock); 00523 } else if (pvt->txDtmfDigit != digit) { 00524 /* in-band DTMF */ 00525 if (h323debug) { 00526 ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name); 00527 } 00528 pvt->txDtmfDigit = digit; 00529 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00530 ast_mutex_unlock(&pvt->lock); 00531 h323_send_tone(token, digit); 00532 if (token) { 00533 free(token); 00534 } 00535 } else 00536 ast_mutex_unlock(&pvt->lock); 00537 oh323_update_info(c); 00538 return 0; 00539 }
static int oh323_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Send (play) the specified digit to the channel.
Definition at line 545 of file chan_h323.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end(), oh323_pvt::cd, oh323_pvt::dtmf_pt, free, oh323_pvt::lock, LOG_DTMF, LOG_ERROR, ast_channel::name, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, ast_channel::tech_pvt, and oh323_pvt::txDtmfDigit.
00546 { 00547 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00548 char *token; 00549 00550 if (!pvt) { 00551 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00552 return -1; 00553 } 00554 ast_mutex_lock(&pvt->lock); 00555 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) { 00556 /* out-of-band DTMF */ 00557 if (h323debug) { 00558 ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, c->name, duration); 00559 } 00560 ast_rtp_senddigit_end(pvt->rtp, digit); 00561 ast_mutex_unlock(&pvt->lock); 00562 } else { 00563 /* in-band DTMF */ 00564 if (h323debug) { 00565 ast_log(LOG_DTMF, "End sending inband digit %c on %s, duration %d\n", digit, c->name, duration); 00566 } 00567 pvt->txDtmfDigit = ' '; 00568 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00569 ast_mutex_unlock(&pvt->lock); 00570 h323_send_tone(token, ' '); 00571 if (token) { 00572 free(token); 00573 } 00574 } 00575 oh323_update_info(c); 00576 return 0; 00577 }
static int oh323_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 943 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.
00944 { 00945 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt; 00946 00947 ast_mutex_lock(&pvt->lock); 00948 if (pvt->owner != oldchan) { 00949 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner); 00950 return -1; 00951 } 00952 pvt->owner = newchan; 00953 ast_mutex_unlock(&pvt->lock); 00954 return 0; 00955 }
static enum ast_rtp_get_result oh323_get_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 3049 of file chan_h323.c.
References ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, oh323_pvt::lock, oh323_pvt::options, oh323_pvt::rtp, and ast_channel::tech_pvt.
03050 { 03051 struct oh323_pvt *pvt; 03052 enum ast_rtp_get_result res = AST_RTP_GET_FAILED; 03053 03054 if (!(pvt = (struct oh323_pvt *)chan->tech_pvt)) 03055 return res; 03056 03057 ast_mutex_lock(&pvt->lock); 03058 if (pvt->rtp && pvt->options.bridge) { 03059 *rtp = pvt->rtp; 03060 res = AST_RTP_TRY_NATIVE; 03061 } 03062 ast_mutex_unlock(&pvt->lock); 03063 03064 return res; 03065 }
static enum ast_rtp_get_result oh323_get_vrtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 3067 of file chan_h323.c.
References AST_RTP_GET_FAILED.
03068 { 03069 return AST_RTP_GET_FAILED; 03070 }
static int oh323_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 686 of file chan_h323.c.
References 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_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), 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, and ast_channel::tech_pvt.
00687 { 00688 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00689 int q931cause = AST_CAUSE_NORMAL_CLEARING; 00690 char *call_token; 00691 00692 00693 if (h323debug) 00694 ast_log(LOG_DEBUG, "Hanging up and scheduling destroy of call %s\n", c->name); 00695 00696 if (!c->tech_pvt) { 00697 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 00698 return 0; 00699 } 00700 ast_mutex_lock(&pvt->lock); 00701 /* Determine how to disconnect */ 00702 if (pvt->owner != c) { 00703 ast_log(LOG_WARNING, "Huh? We aren't the owner?\n"); 00704 ast_mutex_unlock(&pvt->lock); 00705 return 0; 00706 } 00707 00708 pvt->owner = NULL; 00709 c->tech_pvt = NULL; 00710 00711 if (c->hangupcause) { 00712 q931cause = c->hangupcause; 00713 } else { 00714 const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 00715 if (cause) { 00716 if (!strcmp(cause, "CONGESTION")) { 00717 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 00718 } else if (!strcmp(cause, "BUSY")) { 00719 q931cause = AST_CAUSE_USER_BUSY; 00720 } else if (!strcmp(cause, "CHANISUNVAIL")) { 00721 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; 00722 } else if (!strcmp(cause, "NOANSWER")) { 00723 q931cause = AST_CAUSE_NO_ANSWER; 00724 } else if (!strcmp(cause, "CANCEL")) { 00725 q931cause = AST_CAUSE_CALL_REJECTED; 00726 } 00727 } 00728 } 00729 00730 /* Start the process if it's not already started */ 00731 if (!pvt->alreadygone && !pvt->hangupcause) { 00732 call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00733 if (call_token) { 00734 /* Release lock to eliminate deadlock */ 00735 ast_mutex_unlock(&pvt->lock); 00736 if (h323_clear_call(call_token, q931cause)) { 00737 ast_log(LOG_WARNING, "ClearCall failed.\n"); 00738 } 00739 free(call_token); 00740 ast_mutex_lock(&pvt->lock); 00741 } 00742 } 00743 pvt->needdestroy = 1; 00744 ast_mutex_unlock(&pvt->lock); 00745 00746 /* Update usage counter */ 00747 ast_module_unref(ast_module_info->self); 00748 00749 return 0; 00750 }
static int oh323_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 861 of file chan_h323.c.
References ast_channel::_state, oh323_pvt::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_change_source(), ast_rtp_new_source(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, oh323_pvt::cd, free, oh323_pvt::got_progress, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_update_info(), oh323_pvt::rtp, strdup, and ast_channel::tech_pvt.
00862 { 00863 00864 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00865 char *token = (char *)NULL; 00866 int res = -1; 00867 int got_progress; 00868 00869 ast_mutex_lock(&pvt->lock); 00870 token = (pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL); 00871 got_progress = pvt->got_progress; 00872 if (condition == AST_CONTROL_PROGRESS) 00873 pvt->got_progress = 1; 00874 else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION)) 00875 pvt->alreadygone = 1; 00876 ast_mutex_unlock(&pvt->lock); 00877 00878 if (h323debug) 00879 ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token); 00880 00881 switch(condition) { 00882 case AST_CONTROL_RINGING: 00883 if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) { 00884 h323_send_alerting(token); 00885 res = (got_progress ? 0 : -1); /* Do not simulate any audio tones if we got PROGRESS message */ 00886 } 00887 break; 00888 case AST_CONTROL_PROGRESS: 00889 if (c->_state != AST_STATE_UP) { 00890 /* Do not send PROGRESS message more than once */ 00891 if (!got_progress) 00892 h323_send_progress(token); 00893 res = 0; 00894 } 00895 break; 00896 case AST_CONTROL_BUSY: 00897 if (c->_state != AST_STATE_UP) { 00898 h323_answering_call(token, 1); 00899 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00900 res = 0; 00901 } 00902 break; 00903 case AST_CONTROL_CONGESTION: 00904 if (c->_state != AST_STATE_UP) { 00905 h323_answering_call(token, 1); 00906 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00907 res = 0; 00908 } 00909 break; 00910 case AST_CONTROL_HOLD: 00911 ast_moh_start(c, data, NULL); 00912 res = 0; 00913 break; 00914 case AST_CONTROL_UNHOLD: 00915 ast_moh_stop(c); 00916 res = 0; 00917 break; 00918 case AST_CONTROL_SRCUPDATE: 00919 ast_rtp_new_source(pvt->rtp); 00920 res = 0; 00921 break; 00922 case AST_CONTROL_SRCCHANGE: 00923 ast_rtp_change_source(pvt->rtp); 00924 res = 0; 00925 break; 00926 case AST_CONTROL_PROCEEDING: 00927 case -1: 00928 break; 00929 default: 00930 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token); 00931 break; 00932 } 00933 00934 if (h323debug) 00935 ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res); 00936 if (token) 00937 free(token); 00938 oh323_update_info(c); 00939 00940 return res; 00941 }
static struct ast_frame * oh323_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 808 of file chan_h323.c.
References __oh323_update_info(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_rtcp_read(), ast_channel::fdno, oh323_pvt::lock, LOG_ERROR, ast_channel::name, oh323_rtp_read(), oh323_pvt::rtp, and ast_channel::tech_pvt.
00809 { 00810 struct ast_frame *fr; 00811 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00812 ast_mutex_lock(&pvt->lock); 00813 __oh323_update_info(c, pvt); 00814 switch(c->fdno) { 00815 case 0: 00816 fr = oh323_rtp_read(pvt); 00817 break; 00818 case 1: 00819 if (pvt->rtp) 00820 fr = ast_rtcp_read(pvt->rtp); 00821 else 00822 fr = &ast_null_frame; 00823 break; 00824 default: 00825 ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name); 00826 fr = &ast_null_frame; 00827 break; 00828 } 00829 ast_mutex_unlock(&pvt->lock); 00830 return fr; 00831 }
static struct ast_channel * oh323_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 1677 of file chan_h323.c.
References __oh323_new(), AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INCOMPATIBLE_DESTINATION, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, ast_copy_string(), AST_FORMAT_MAX_AUDIO, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), caplock, create_addr(), ext, oh323_pvt::exten, gatekeeper_disable, global_options, h323debug, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_alloc(), oh323_destroy(), oh323_pvt::options, restart_monitor(), and unique.
01678 { 01679 int oldformat; 01680 struct oh323_pvt *pvt; 01681 struct ast_channel *tmpc = NULL; 01682 char *dest = (char *)data; 01683 char *ext, *host; 01684 char *h323id = NULL; 01685 char tmp[256], tmp1[256]; 01686 01687 if (h323debug) 01688 ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data); 01689 01690 pvt = oh323_alloc(0); 01691 if (!pvt) { 01692 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data); 01693 return NULL; 01694 } 01695 oldformat = format; 01696 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 01697 if (!format) { 01698 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 01699 oh323_destroy(pvt); 01700 if (cause) 01701 *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 01702 return NULL; 01703 } 01704 ast_copy_string(tmp, dest, sizeof(tmp)); 01705 host = strchr(tmp, '@'); 01706 if (host) { 01707 *host = '\0'; 01708 host++; 01709 ext = tmp; 01710 } else { 01711 ext = strrchr(tmp, '/'); 01712 if (ext) 01713 *ext++ = '\0'; 01714 host = tmp; 01715 } 01716 strtok_r(host, "/", &(h323id)); 01717 if (!ast_strlen_zero(h323id)) { 01718 h323_set_id(h323id); 01719 } 01720 if (ext) { 01721 ast_copy_string(pvt->exten, ext, sizeof(pvt->exten)); 01722 } 01723 if (h323debug) 01724 ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host); 01725 01726 if (gatekeeper_disable) { 01727 if (create_addr(pvt, host)) { 01728 oh323_destroy(pvt); 01729 if (cause) 01730 *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01731 return NULL; 01732 } 01733 } 01734 else { 01735 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01736 pvt->jointcapability = pvt->options.capability; 01737 if (pvt->options.dtmfmode) { 01738 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01739 pvt->nonCodecCapability |= AST_RTP_DTMF; 01740 } else { 01741 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01742 } 01743 } 01744 } 01745 01746 ast_mutex_lock(&caplock); 01747 /* Generate unique channel identifier */ 01748 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique); 01749 tmp1[sizeof(tmp1)-1] = '\0'; 01750 ast_mutex_unlock(&caplock); 01751 01752 ast_mutex_lock(&pvt->lock); 01753 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1); 01754 ast_mutex_unlock(&pvt->lock); 01755 if (!tmpc) { 01756 oh323_destroy(pvt); 01757 if (cause) 01758 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 01759 } 01760 ast_update_use_count(); 01761 restart_monitor(); 01762 return tmpc; 01763 }
Definition at line 752 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, ast_dsp_process(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtp_read(), ast_rtp_setnat(), ast_set_read_format(), ast_set_write_format(), f, LOG_DEBUG, LOG_DTMF, LOG_NOTICE, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_pvt::noInbandDtmf, oh323_pvt::options, oh323_pvt::owner, ast_channel::readformat, oh323_pvt::rtp, oh323_pvt::vad, and ast_channel::writeformat.
Referenced by oh323_read().
00753 { 00754 /* Retrieve audio/etc from channel. Assumes pvt->lock is already held. */ 00755 struct ast_frame *f; 00756 00757 /* Only apply it for the first packet, we just need the correct ip/port */ 00758 if (pvt->options.nat) { 00759 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00760 pvt->options.nat = 0; 00761 } 00762 00763 f = ast_rtp_read(pvt->rtp); 00764 /* Don't send RFC2833 if we're not supposed to */ 00765 if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) { 00766 return &ast_null_frame; 00767 } 00768 if (pvt->owner) { 00769 /* We already hold the channel lock */ 00770 if (f->frametype == AST_FRAME_VOICE) { 00771 if (f->subclass != pvt->owner->nativeformats) { 00772 /* Try to avoid deadlock */ 00773 if (ast_channel_trylock(pvt->owner)) { 00774 ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n"); 00775 return &ast_null_frame; 00776 } 00777 if (h323debug) 00778 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 00779 pvt->owner->nativeformats = f->subclass; 00780 pvt->nativeformats = f->subclass; 00781 ast_set_read_format(pvt->owner, pvt->owner->readformat); 00782 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 00783 ast_channel_unlock(pvt->owner); 00784 } 00785 /* Do in-band DTMF detection */ 00786 if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) { 00787 if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) { 00788 if (!ast_channel_trylock(pvt->owner)) { 00789 f = ast_dsp_process(pvt->owner, pvt->vad, f); 00790 ast_channel_unlock(pvt->owner); 00791 } 00792 else 00793 ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n"); 00794 } else if (pvt->nativeformats && !pvt->noInbandDtmf) { 00795 ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass)); 00796 pvt->noInbandDtmf = 1; 00797 } 00798 if (f &&(f->frametype == AST_FRAME_DTMF)) { 00799 if (h323debug) 00800 ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass); 00801 } 00802 } 00803 } 00804 } 00805 return f; 00806 }
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 3099 of file chan_h323.c.
References ast_inet_ntoa(), ast_log(), ast_rtp_get_peer(), ast_rtp_get_us(), oh323_pvt::cd, convertcap(), LOG_ERROR, oh323_pvt::rtp, ast_channel::tech_pvt, and ast_channel::writeformat.
03100 { 03101 /* XXX Deal with Video */ 03102 struct oh323_pvt *pvt; 03103 struct sockaddr_in them; 03104 struct sockaddr_in us; 03105 char *mode; 03106 03107 if (!rtp) { 03108 return 0; 03109 } 03110 03111 mode = convertcap(chan->writeformat); 03112 pvt = (struct oh323_pvt *) chan->tech_pvt; 03113 if (!pvt) { 03114 ast_log(LOG_ERROR, "No Private Structure, this is bad\n"); 03115 return -1; 03116 } 03117 ast_rtp_get_peer(rtp, &them); 03118 ast_rtp_get_us(rtp, &us); 03119 #if 0 /* Native bridge still isn't ready */ 03120 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode); 03121 #endif 03122 return 0; 03123 }
static int oh323_simulate_dtmf_end | ( | const void * | data | ) | [static] |
Definition at line 309 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, AST_FRAME_DTMF_END, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, and f.
Referenced by __oh323_update_info(), and receive_digit().
00310 { 00311 struct oh323_pvt *pvt = (struct oh323_pvt *)data; 00312 00313 if (pvt) { 00314 ast_mutex_lock(&pvt->lock); 00315 /* Don't hold pvt lock while trying to lock the channel */ 00316 while (pvt->owner && ast_channel_trylock(pvt->owner)) { 00317 DEADLOCK_AVOIDANCE(&pvt->lock); 00318 } 00319 00320 if (pvt->owner) { 00321 struct ast_frame f = { 00322 .frametype = AST_FRAME_DTMF_END, 00323 .subclass = pvt->curDTMF, 00324 .samples = 0, 00325 .src = "SIMULATE_DTMF_END", 00326 }; 00327 ast_queue_frame(pvt->owner, &f); 00328 ast_channel_unlock(pvt->owner); 00329 } 00330 00331 pvt->DTMFsched = -1; 00332 ast_mutex_unlock(&pvt->lock); 00333 } 00334 00335 return 0; 00336 }
static void oh323_update_info | ( | struct ast_channel * | c | ) | [static] |
Definition at line 403 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_begin(), oh323_digit_end(), and oh323_indicate().
00404 { 00405 struct oh323_pvt *pvt = c->tech_pvt; 00406 00407 if (pvt) { 00408 ast_mutex_lock(&pvt->lock); 00409 __oh323_update_info(c, pvt); 00410 ast_mutex_unlock(&pvt->lock); 00411 } 00412 }
static int oh323_write | ( | struct ast_channel * | c, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 833 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::recvonly, oh323_pvt::rtp, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat.
00834 { 00835 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00836 int res = 0; 00837 if (frame->frametype != AST_FRAME_VOICE) { 00838 if (frame->frametype == AST_FRAME_IMAGE) { 00839 return 0; 00840 } else { 00841 ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype); 00842 return 0; 00843 } 00844 } else { 00845 if (!(frame->subclass & c->nativeformats)) { 00846 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 00847 frame->subclass, c->nativeformats, c->readformat, c->writeformat); 00848 return 0; 00849 } 00850 } 00851 if (pvt) { 00852 ast_mutex_lock(&pvt->lock); 00853 if (pvt->rtp && !pvt->recvonly) 00854 res = ast_rtp_write(pvt->rtp, frame); 00855 __oh323_update_info(c, pvt); 00856 ast_mutex_unlock(&pvt->lock); 00857 } 00858 return res; 00859 }
static int progress | ( | unsigned | call_reference, | |
const char * | token, | |||
int | inband | |||
) | [static] |
Definition at line 2031 of file chan_h323.c.
References AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state().
02032 { 02033 struct oh323_pvt *pvt; 02034 02035 if (h323debug) 02036 ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated")); 02037 02038 pvt = find_call_locked(call_reference, token); 02039 if (!pvt) { 02040 ast_log(LOG_ERROR, "Private structure not found in progress.\n"); 02041 return -1; 02042 } 02043 if (!pvt->owner) { 02044 ast_mutex_unlock(&pvt->lock); 02045 ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n"); 02046 return -1; 02047 } 02048 update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING)); 02049 ast_mutex_unlock(&pvt->lock); 02050 02051 return 0; 02052 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 2789 of file chan_h323.c.
References ASTOBJ_CONTAINER_PRUNE_MARKED, oh323_destroy_peer(), and peerl.
Referenced by iax2_prune_realtime(), reload_config(), set_config(), and unload_module().
02790 { 02791 /* Prune peers who still are supposed to be deleted */ 02792 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer); 02793 }
static struct oh323_alias* realtime_alias | ( | const char * | alias | ) | [static] |
Definition at line 1229 of file chan_h323.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
Referenced by find_alias().
01230 { 01231 struct ast_variable *var, *tmp; 01232 struct oh323_alias *a; 01233 01234 var = ast_load_realtime("h323", "name", alias, NULL); 01235 01236 if (!var) 01237 return NULL; 01238 01239 for (tmp = var; tmp; tmp = tmp->next) { 01240 if (!strcasecmp(tmp->name, "type") && 01241 !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) { 01242 ast_variables_destroy(var); 01243 return NULL; 01244 } 01245 } 01246 01247 a = build_alias(alias, var, NULL, 1); 01248 01249 ast_variables_destroy(var); 01250 01251 return a; 01252 }
static struct oh323_peer* realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 1509 of file chan_h323.c.
References ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
Referenced by authenticate_reply(), calltoken_required(), find_peer(), and iax2_getpeername().
01510 { 01511 struct oh323_peer *peer; 01512 struct ast_variable *var; 01513 struct ast_variable *tmp; 01514 const char *addr; 01515 01516 /* First check on peer name */ 01517 if (peername) 01518 var = ast_load_realtime("h323", "name", peername, addr = NULL); 01519 else if (sin) /* Then check on IP address for dynamic peers */ 01520 var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), NULL); 01521 else 01522 return NULL; 01523 01524 if (!var) 01525 return NULL; 01526 01527 for (tmp = var; tmp; tmp = tmp->next) { 01528 /* If this is type=user, then skip this object. */ 01529 if (!strcasecmp(tmp->name, "type") && 01530 !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) { 01531 ast_variables_destroy(var); 01532 return NULL; 01533 } else if (!peername && !strcasecmp(tmp->name, "name")) { 01534 peername = tmp->value; 01535 } 01536 } 01537 01538 if (!peername) { /* Did not find peer in realtime */ 01539 ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr); 01540 ast_variables_destroy(var); 01541 return NULL; 01542 } 01543 01544 /* Peer found in realtime, now build it in memory */ 01545 peer = build_peer(peername, var, NULL, 1); 01546 01547 ast_variables_destroy(var); 01548 01549 return peer; 01550 }
static struct oh323_user* realtime_user | ( | const call_details_t * | cd | ) | [static] |
Definition at line 1407 of file chan_h323.c.
References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, userbyalias, username, ast_variable::value, and var.
Referenced by calltoken_required(), check_access(), and find_user().
01408 { 01409 struct ast_variable *var, *tmp; 01410 struct oh323_user *user; 01411 char *username; 01412 01413 if (userbyalias) 01414 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL); 01415 else { 01416 username = (char *)NULL; 01417 var = ast_load_realtime("h323", "host", cd->sourceIp, NULL); 01418 } 01419 01420 if (!var) 01421 return NULL; 01422 01423 for (tmp = var; tmp; tmp = tmp->next) { 01424 if (!strcasecmp(tmp->name, "type") && 01425 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) { 01426 ast_variables_destroy(var); 01427 return NULL; 01428 } else if (!username && !strcasecmp(tmp->name, "name")) 01429 username = tmp->value; 01430 } 01431 01432 if (!username) { 01433 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp); 01434 ast_variables_destroy(var); 01435 return NULL; 01436 } 01437 01438 user = build_user(username, var, NULL, 1); 01439 01440 ast_variables_destroy(var); 01441 01442 return user; 01443 }
static int receive_digit | ( | unsigned | call_reference, | |
char | digit, | |||
const char * | token, | |||
int | duration | |||
) | [static] |
Callback for sending digits from H.323 up to asterisk
Definition at line 1782 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, AST_CONTROL_FLASH, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_log(), ast_mutex_unlock(), ast_queue_control(), ast_queue_frame(), ast_sched_add(), AST_SCHED_DEL, oh323_pvt::curDTMF, oh323_pvt::DTMFsched, f, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DTMF, LOG_ERROR, oh323_pvt::newcontrol, oh323_pvt::newdigit, oh323_pvt::newduration, oh323_simulate_dtmf_end(), and oh323_pvt::owner.
Referenced by load_module().
01783 { 01784 struct oh323_pvt *pvt; 01785 int res; 01786 01787 pvt = find_call_locked(call_reference, token); 01788 if (!pvt) { 01789 ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token); 01790 return -1; 01791 } 01792 if (h323debug) 01793 ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token); 01794 01795 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01796 if (digit == '!') 01797 res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH); 01798 else { 01799 struct ast_frame f = { 01800 .frametype = AST_FRAME_DTMF_END, 01801 .subclass = digit, 01802 .samples = duration * 8, 01803 .len = duration, 01804 .src = "SEND_DIGIT", 01805 }; 01806 if (digit == ' ') { /* signalUpdate message */ 01807 f.subclass = pvt->curDTMF; 01808 AST_SCHED_DEL(sched, pvt->DTMFsched); 01809 } else { /* Regular input or signal message */ 01810 if (pvt->DTMFsched >= 0) { 01811 /* We still don't send DTMF END from previous event, send it now */ 01812 AST_SCHED_DEL(sched, pvt->DTMFsched); 01813 f.subclass = pvt->curDTMF; 01814 f.samples = f.len = 0; 01815 ast_queue_frame(pvt->owner, &f); 01816 /* Restore values */ 01817 f.subclass = digit; 01818 f.samples = duration * 8; 01819 f.len = duration; 01820 } 01821 if (duration) { /* This is a signal, signalUpdate follows */ 01822 f.frametype = AST_FRAME_DTMF_BEGIN; 01823 pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt); 01824 if (h323debug) 01825 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched); 01826 } 01827 pvt->curDTMF = digit; 01828 } 01829 res = ast_queue_frame(pvt->owner, &f); 01830 } 01831 ast_channel_unlock(pvt->owner); 01832 } else { 01833 if (digit == '!') 01834 pvt->newcontrol = AST_CONTROL_FLASH; 01835 else { 01836 pvt->newduration = duration; 01837 pvt->newdigit = digit; 01838 } 01839 res = 0; 01840 } 01841 ast_mutex_unlock(&pvt->lock); 01842 return res; 01843 }
static const char* redirectingreason2str | ( | int | redirectingreason | ) | [static] |
Definition at line 270 of file chan_h323.c.
00271 { 00272 switch (redirectingreason) { 00273 case 0: 00274 return "UNKNOWN"; 00275 case 1: 00276 return "BUSY"; 00277 case 2: 00278 return "NO_REPLY"; 00279 case 0xF: 00280 return "UNCONDITIONAL"; 00281 default: 00282 return "NOREDIRECT"; 00283 } 00284 }
static int reload | ( | void | ) | [static] |
Definition at line 3034 of file chan_h323.c.
References ast_log(), h323_reload(), io, and LOG_NOTICE.
03035 { 03036 if (!sched || !io) { 03037 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n"); 03038 return 0; 03039 } 03040 return h323_reload(0, 0, NULL); 03041 }
static int reload_config | ( | int | is_reload | ) | [static] |
Definition at line 2795 of file chan_h323.c.
References acceptAnonymous, ahp, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_copy_string(), ast_gethostbyname(), ast_jb_read_conf(), ast_log(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, bindaddr, build_peer(), build_user(), config, default_context, default_jbconf, delete_aliases(), delete_users(), format, gatekeeper, gatekeeper_disable, gatekeeper_discover, gen, gkroute, GLOBAL_CAPABILITY, global_jbconf, global_options, h323_signalling_port, hp, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, oh323_destroy_peer(), oh323_destroy_user(), peerl, prune_peers(), tos, userbyalias, userl, and ast_variable::value.
Referenced by h323_do_reload(), iax2_reload(), load_module(), mgcp_do_reload(), misdn_reload(), reload(), and sip_do_reload().
02796 { 02797 int format; 02798 struct ast_config *cfg, *ucfg; 02799 struct ast_variable *v; 02800 struct oh323_peer *peer = NULL; 02801 struct oh323_user *user = NULL; 02802 struct oh323_alias *alias = NULL; 02803 struct ast_hostent ahp; struct hostent *hp; 02804 char *cat; 02805 const char *utype; 02806 int is_user, is_peer, is_alias; 02807 char _gatekeeper[100]; 02808 int gk_discover, gk_disable, gk_changed; 02809 02810 cfg = ast_config_load(config); 02811 02812 /* We *must* have a config file otherwise stop immediately */ 02813 if (!cfg) { 02814 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02815 return 1; 02816 } 02817 02818 if (is_reload) { 02819 delete_users(); 02820 delete_aliases(); 02821 prune_peers(); 02822 } 02823 02824 /* fire up the H.323 Endpoint */ 02825 if (!h323_end_point_exist()) { 02826 h323_end_point_create(); 02827 } 02828 ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper)); 02829 gk_discover = gatekeeper_discover; 02830 gk_disable = gatekeeper_disable; 02831 memset(&bindaddr, 0, sizeof(bindaddr)); 02832 memset(&global_options, 0, sizeof(global_options)); 02833 global_options.fastStart = 1; 02834 global_options.h245Tunneling = 1; 02835 global_options.dtmfcodec = 101; 02836 global_options.dtmfmode = H323_DTMF_RFC2833; 02837 global_options.capability = GLOBAL_CAPABILITY; 02838 global_options.bridge = 1; /* Do native bridging by default */ 02839 global_options.autoframing = 0; 02840 strcpy(default_context, "default"); 02841 h323_signalling_port = 1720; 02842 gatekeeper_disable = 1; 02843 gatekeeper_discover = 0; 02844 gkroute = 0; 02845 userbyalias = 1; 02846 acceptAnonymous = 1; 02847 tos = 0; 02848 02849 /* Copy the default jb config over global_jbconf */ 02850 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 02851 02852 /* Load configuration from users.conf */ 02853 ucfg = ast_config_load("users.conf"); 02854 if (ucfg) { 02855 struct ast_variable *gen; 02856 int genhas_h323; 02857 const char *has_h323; 02858 02859 genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323")); 02860 gen = ast_variable_browse(ucfg, "general"); 02861 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) { 02862 if (strcasecmp(cat, "general")) { 02863 has_h323 = ast_variable_retrieve(ucfg, cat, "hash323"); 02864 if (ast_true(has_h323) || (!has_h323 && genhas_h323)) { 02865 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 02866 if (user) { 02867 ASTOBJ_CONTAINER_LINK(&userl, user); 02868 ASTOBJ_UNREF(user, oh323_destroy_user); 02869 } 02870 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 02871 if (peer) { 02872 ASTOBJ_CONTAINER_LINK(&peerl, peer); 02873 ASTOBJ_UNREF(peer, oh323_destroy_peer); 02874 } 02875 } 02876 } 02877 } 02878 ast_config_destroy(ucfg); 02879 } 02880 02881 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 02882 /* handle jb conf */ 02883 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 02884 continue; 02885 /* Create the interface list */ 02886 if (!strcasecmp(v->name, "port")) { 02887 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02888 } else if (!strcasecmp(v->name, "bindaddr")) { 02889 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02890 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02891 } else { 02892 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02893 } 02894 } else if (!strcasecmp(v->name, "tos")) { 02895 if (sscanf(v->value, "%30d", &format)) { 02896 tos = format & 0xff; 02897 } else if (!strcasecmp(v->value, "lowdelay")) { 02898 tos = IPTOS_LOWDELAY; 02899 } else if (!strcasecmp(v->value, "throughput")) { 02900 tos = IPTOS_THROUGHPUT; 02901 } else if (!strcasecmp(v->value, "reliability")) { 02902 tos = IPTOS_RELIABILITY; 02903 } else if (!strcasecmp(v->value, "mincost")) { 02904 tos = IPTOS_MINCOST; 02905 } else if (!strcasecmp(v->value, "none")) { 02906 tos = 0; 02907 } else { 02908 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02909 } 02910 } else if (!strcasecmp(v->name, "gatekeeper")) { 02911 if (!strcasecmp(v->value, "DISABLE")) { 02912 gatekeeper_disable = 1; 02913 } else if (!strcasecmp(v->value, "DISCOVER")) { 02914 gatekeeper_disable = 0; 02915 gatekeeper_discover = 1; 02916 } else { 02917 gatekeeper_disable = 0; 02918 ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper)); 02919 } 02920 } else if (!strcasecmp(v->name, "secret")) { 02921 ast_copy_string(secret, v->value, sizeof(secret)); 02922 } else if (!strcasecmp(v->name, "AllowGKRouted")) { 02923 gkroute = ast_true(v->value); 02924 } else if (!strcasecmp(v->name, "context")) { 02925 ast_copy_string(default_context, v->value, sizeof(default_context)); 02926 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context); 02927 } else if (!strcasecmp(v->name, "UserByAlias")) { 02928 userbyalias = ast_true(v->value); 02929 } else if (!strcasecmp(v->name, "AcceptAnonymous")) { 02930 acceptAnonymous = ast_true(v->value); 02931 } else if (!update_common_options(v, &global_options)) { 02932 /* dummy */ 02933 } 02934 } 02935 02936 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) { 02937 if (strcasecmp(cat, "general")) { 02938 utype = ast_variable_retrieve(cfg, cat, "type"); 02939 if (utype) { 02940 is_user = is_peer = is_alias = 0; 02941 if (!strcasecmp(utype, "user")) 02942 is_user = 1; 02943 else if (!strcasecmp(utype, "peer")) 02944 is_peer = 1; 02945 else if (!strcasecmp(utype, "friend")) 02946 is_user = is_peer = 1; 02947 else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) 02948 is_alias = 1; 02949 else { 02950 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config); 02951 continue; 02952 } 02953 if (is_user) { 02954 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 02955 if (user) { 02956 ASTOBJ_CONTAINER_LINK(&userl, user); 02957 ASTOBJ_UNREF(user, oh323_destroy_user); 02958 } 02959 } 02960 if (is_peer) { 02961 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 02962 if (peer) { 02963 ASTOBJ_CONTAINER_LINK(&peerl, peer); 02964 ASTOBJ_UNREF(peer, oh323_destroy_peer); 02965 } 02966 } 02967 if (is_alias) { 02968 alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0); 02969 if (alias) { 02970 ASTOBJ_CONTAINER_LINK(&aliasl, alias); 02971 ASTOBJ_UNREF(alias, oh323_destroy_alias); 02972 } 02973 } 02974 } else { 02975 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 02976 } 02977 } 02978 } 02979 ast_config_destroy(cfg); 02980 02981 /* Register our H.323 aliases if any*/ 02982 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 02983 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 02984 ASTOBJ_RDLOCK(iterator); 02985 if (h323_set_alias(iterator)) { 02986 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name); 02987 ASTOBJ_UNLOCK(iterator); 02988 continue; 02989 } 02990 ASTOBJ_UNLOCK(iterator); 02991 } while (0) ); 02992 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 02993 02994 /* Don't touch GK if nothing changed because URQ will drop all existing calls */ 02995 gk_changed = 0; 02996 if (gatekeeper_disable != gk_disable) 02997 gk_changed = is_reload; 02998 else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover)) 02999 gk_changed = is_reload; 03000 else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0)) 03001 gk_changed = is_reload; 03002 if (gk_changed) { 03003 if(!gk_disable) 03004 h323_gk_urq(); 03005 if (!gatekeeper_disable) { 03006 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 03007 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 03008 gatekeeper_disable = 1; 03009 } 03010 } 03011 } 03012 return 0; 03013 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 2531 of file chan_h323.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, monitor_thread, and monlock.
02532 { 02533 /* If we're supposed to be stopped -- stay stopped */ 02534 if (ast_mutex_lock(&monlock)) { 02535 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 02536 return -1; 02537 } 02538 if (monitor_thread == AST_PTHREADT_STOP) { 02539 ast_mutex_unlock(&monlock); 02540 return 0; 02541 } 02542 if (monitor_thread == pthread_self()) { 02543 ast_mutex_unlock(&monlock); 02544 ast_log(LOG_WARNING, "Cannot kill myself\n"); 02545 return -1; 02546 } 02547 if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) { 02548 /* Wake up the thread */ 02549 pthread_kill(monitor_thread, SIGURG); 02550 } else { 02551 /* Start a new monitor */ 02552 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 02553 monitor_thread = AST_PTHREADT_NULL; 02554 ast_mutex_unlock(&monlock); 02555 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 02556 return -1; 02557 } 02558 } 02559 ast_mutex_unlock(&monlock); 02560 return 0; 02561 }
static void set_dtmf_payload | ( | unsigned | call_reference, | |
const char * | token, | |||
int | payload | |||
) | [static] |
Definition at line 2376 of file chan_h323.c.
References ast_log(), ast_mutex_unlock(), ast_rtp_set_rtpmap_type(), oh323_pvt::dtmf_pt, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, and oh323_pvt::rtp.
Referenced by load_module().
02377 { 02378 struct oh323_pvt *pvt; 02379 02380 if (h323debug) 02381 ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token); 02382 02383 pvt = find_call_locked(call_reference, token); 02384 if (!pvt) { 02385 return; 02386 } 02387 if (pvt->rtp) { 02388 ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event", 0); 02389 } 02390 pvt->dtmf_pt = payload; 02391 ast_mutex_unlock(&pvt->lock); 02392 if (h323debug) 02393 ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload); 02394 }
static void set_local_capabilities | ( | unsigned | call_reference, | |
const char * | token | |||
) | [static] |
Definition at line 2431 of file chan_h323.c.
References ast_getformatname(), ast_log(), ast_mutex_unlock(), capability, dtmfmode, find_call_locked(), ast_codec_pref::framing, h323debug, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, oh323_pvt::options, ast_codec_pref::order, oh323_pvt::pref_codec, and prefs.
Referenced by load_module().
02432 { 02433 struct oh323_pvt *pvt; 02434 int capability, dtmfmode, pref_codec; 02435 struct ast_codec_pref prefs; 02436 02437 if (h323debug) 02438 ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token); 02439 02440 pvt = find_call_locked(call_reference, token); 02441 if (!pvt) 02442 return; 02443 capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability; 02444 dtmfmode = pvt->options.dtmfmode; 02445 prefs = pvt->options.prefs; 02446 pref_codec = pvt->pref_codec; 02447 ast_mutex_unlock(&pvt->lock); 02448 h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec); 02449 02450 if (h323debug) { 02451 int i; 02452 for (i = 0; i < 32; i++) { 02453 if (!prefs.order[i]) 02454 break; 02455 ast_log(LOG_DEBUG, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(1 << (prefs.order[i]-1)) : "<none>"), prefs.framing[i]); 02456 } 02457 ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token); 02458 } 02459 }
static void set_peer_capabilities | ( | unsigned | call_reference, | |
const char * | token, | |||
int | capabilities, | |||
struct ast_codec_pref * | prefs | |||
) | [static] |
Definition at line 2396 of file chan_h323.c.
References ast_getformatname(), ast_log(), ast_rtp_codec_setpref(), find_call_locked(), ast_codec_pref::framing, h323debug, oh323_pvt::jointcapability, LOG_DEBUG, oh323_pvt::options, ast_codec_pref::order, oh323_pvt::peer_prefs, oh323_pvt::peercapability, prefs, and oh323_pvt::rtp.
Referenced by load_module().
02397 { 02398 struct oh323_pvt *pvt; 02399 02400 if (h323debug) 02401 ast_log(LOG_DEBUG, "Got remote capabilities from connection %s\n", token); 02402 02403 pvt = find_call_locked(call_reference, token); 02404 if (!pvt) 02405 return; 02406 pvt->peercapability = capabilities; 02407 pvt->jointcapability = pvt->options.capability & capabilities; 02408 if (prefs) { 02409 memcpy(&pvt->peer_prefs, prefs, sizeof(pvt->peer_prefs)); 02410 if (h323debug) { 02411 int i; 02412 for (i = 0; i < 32; ++i) { 02413 if (!prefs->order[i]) 02414 break; 02415 ast_log(LOG_DEBUG, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]); 02416 } 02417 } 02418 if (pvt->rtp) { 02419 if (pvt->options.autoframing) { 02420 ast_log(LOG_DEBUG, "Autoframing option set, using peer's packetization settings\n"); 02421 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 02422 } else { 02423 ast_log(LOG_DEBUG, "Autoframing option not set, using ignoring peer's packetization settings\n"); 02424 ast_rtp_codec_setpref(pvt->rtp, &pvt->options.prefs); 02425 } 02426 } 02427 } 02428 ast_mutex_unlock(&pvt->lock); 02429 }
static call_options_t* setup_incoming_call | ( | call_details_t * | cd | ) | [static] |
Call-back function for incoming calls
Returns 1 on success
Definition at line 2059 of file chan_h323.c.
References acceptAnonymous, oh323_pvt::accountcode, oh323_pvt::amaflags, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_verbose(), ASTOBJ_UNREF, oh323_pvt::cd, cleanup_call_details(), oh323_pvt::context, default_context, oh323_pvt::exten, find_alias(), find_user(), gatekeeper, gatekeeper_disable, gkroute, global_options, h323debug, oh323_pvt::jointcapability, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, oh323_alloc(), oh323_destroy(), oh323_destroy_user(), oh323_pvt::options, and VERBOSE_PREFIX_3.
Referenced by load_module().
02060 { 02061 struct oh323_pvt *pvt; 02062 struct oh323_user *user = NULL; 02063 struct oh323_alias *alias = NULL; 02064 02065 if (h323debug) 02066 ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token); 02067 02068 /* allocate the call*/ 02069 pvt = oh323_alloc(cd->call_reference); 02070 02071 if (!pvt) { 02072 ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n"); 02073 cleanup_call_details(cd); 02074 return NULL; 02075 } 02076 02077 /* Populate the call details in the private structure */ 02078 memcpy(&pvt->cd, cd, sizeof(pvt->cd)); 02079 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 02080 pvt->jointcapability = pvt->options.capability; 02081 02082 if (h323debug) { 02083 ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n"); 02084 ast_verbose(VERBOSE_PREFIX_3 " \tCall token: [%s]\n", pvt->cd.call_token); 02085 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party name: [%s]\n", pvt->cd.call_source_name); 02086 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party number: [%s]\n", pvt->cd.call_source_e164); 02087 ast_verbose(VERBOSE_PREFIX_3 " \tCalled party name: [%s]\n", pvt->cd.call_dest_alias); 02088 ast_verbose(VERBOSE_PREFIX_3 " \tCalled party number: [%s]\n", pvt->cd.call_dest_e164); 02089 if (pvt->cd.redirect_reason >= 0) 02090 ast_verbose(VERBOSE_PREFIX_3 " \tRedirecting party number: [%s] (reason %d)\n", pvt->cd.redirect_number, pvt->cd.redirect_reason); 02091 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party IP: [%s]\n", pvt->cd.sourceIp); 02092 } 02093 02094 /* Decide if we are allowing Gatekeeper routed calls*/ 02095 if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) { 02096 if (!ast_strlen_zero(cd->call_dest_e164)) { 02097 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02098 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02099 } else { 02100 alias = find_alias(cd->call_dest_alias, 1); 02101 if (!alias) { 02102 ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias); 02103 oh323_destroy(pvt); 02104 return NULL; 02105 } 02106 ast_copy_string(pvt->exten, alias->name, sizeof(pvt->exten)); 02107 ast_copy_string(pvt->context, alias->context, sizeof(pvt->context)); 02108 } 02109 } else { 02110 /* Either this call is not from the Gatekeeper 02111 or we are not allowing gk routed calls */ 02112 user = find_user(cd, 1); 02113 if (!user) { 02114 if (!acceptAnonymous) { 02115 ast_log(LOG_NOTICE, "Anonymous call from '%s@%s' rejected\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp); 02116 oh323_destroy(pvt); 02117 return NULL; 02118 } 02119 if (ast_strlen_zero(default_context)) { 02120 ast_log(LOG_ERROR, "Call from '%s@%s' rejected due to no default context\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp); 02121 oh323_destroy(pvt); 02122 return NULL; 02123 } 02124 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02125 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { 02126 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02127 } else { 02128 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten)); 02129 } 02130 if (h323debug) 02131 ast_log(LOG_DEBUG, "Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->context, pvt->exten); 02132 } else { 02133 if (user->host) { 02134 if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) { 02135 if (ast_strlen_zero(user->context)) { 02136 if (ast_strlen_zero(default_context)) { 02137 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp); 02138 oh323_destroy(pvt); 02139 ASTOBJ_UNREF(user, oh323_destroy_user); 02140 return NULL; 02141 } 02142 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02143 } else { 02144 ast_copy_string(pvt->context, user->context, sizeof(pvt->context)); 02145 } 02146 pvt->exten[0] = 'i'; 02147 pvt->exten[1] = '\0'; 02148 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp); 02149 oh323_destroy(pvt); 02150 ASTOBJ_UNREF(user, oh323_destroy_user); 02151 return NULL; /* XXX: Hmmm... Why to setup context if we drop connection immediately??? */ 02152 } 02153 } 02154 ast_copy_string(pvt->context, user->context, sizeof(pvt->context)); 02155 memcpy(&pvt->options, &user->options, sizeof(pvt->options)); 02156 pvt->jointcapability = pvt->options.capability; 02157 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { 02158 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02159 } else { 02160 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten)); 02161 } 02162 if (!ast_strlen_zero(user->accountcode)) { 02163 ast_copy_string(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode)); 02164 } 02165 if (user->amaflags) { 02166 pvt->amaflags = user->amaflags; 02167 } 02168 ASTOBJ_UNREF(user, oh323_destroy_user); 02169 } 02170 } 02171 return &pvt->options; 02172 }
static int setup_outgoing_call | ( | call_details_t * | cd | ) | [static] |
Call-back function to establish an outgoing H.323 call
Returns 1 on success
Definition at line 2258 of file chan_h323.c.
References cleanup_call_details().
Referenced by load_module().
02259 { 02260 /* Use argument here or free it immediately */ 02261 cleanup_call_details(cd); 02262 02263 return 1; 02264 }
static void setup_rtp_connection | ( | unsigned | call_reference, | |
const char * | remoteIp, | |||
int | remotePort, | |||
const char * | token, | |||
int | pt | |||
) | [static] |
Call-back function passing remote ip/port information from H.323 to asterisk
Returns nothing
Definition at line 1899 of file chan_h323.c.
References __oh323_rtp_create(), oh323_pvt::alreadygone, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_log(), ast_mutex_unlock(), ast_queue_control(), ast_rtp_lookup_pt(), ast_rtp_set_peer(), ast_rtp_stop(), ast_set_read_format(), ast_set_write_format(), rtpPayloadType::code, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, ast_channel::nativeformats, oh323_pvt::nativeformats, oh323_pvt::newcontrol, oh323_pvt::options, oh323_pvt::owner, ast_channel::readformat, oh323_pvt::recvonly, oh323_pvt::rtp, and ast_channel::writeformat.
Referenced by load_module().
01900 { 01901 struct oh323_pvt *pvt; 01902 struct sockaddr_in them; 01903 struct rtpPayloadType rtptype; 01904 int nativeformats_changed; 01905 enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE; 01906 01907 if (h323debug) 01908 ast_log(LOG_DEBUG, "Setting up RTP connection for %s\n", token); 01909 01910 /* Find the call or allocate a private structure if call not found */ 01911 pvt = find_call_locked(call_reference, token); 01912 if (!pvt) { 01913 ast_log(LOG_ERROR, "Something is wrong: rtp\n"); 01914 return; 01915 } 01916 if (pvt->alreadygone) { 01917 ast_mutex_unlock(&pvt->lock); 01918 return; 01919 } 01920 01921 if (!pvt->rtp) 01922 __oh323_rtp_create(pvt); 01923 01924 them.sin_family = AF_INET; 01925 /* only works for IPv4 */ 01926 them.sin_addr.s_addr = inet_addr(remoteIp); 01927 them.sin_port = htons(remotePort); 01928 01929 if (them.sin_addr.s_addr) { 01930 ast_rtp_set_peer(pvt->rtp, &them); 01931 if (pvt->recvonly) { 01932 pvt->recvonly = 0; 01933 rtp_change = NEED_UNHOLD; 01934 } 01935 } else { 01936 ast_rtp_stop(pvt->rtp); 01937 if (!pvt->recvonly) { 01938 pvt->recvonly = 1; 01939 rtp_change = NEED_HOLD; 01940 } 01941 } 01942 01943 /* Change native format to reflect information taken from OLC/OLCAck */ 01944 nativeformats_changed = 0; 01945 if (pt != 128 && pvt->rtp) { /* Payload type is invalid, so try to use previously decided */ 01946 rtptype = ast_rtp_lookup_pt(pvt->rtp, pt); 01947 if (h323debug) 01948 ast_log(LOG_DEBUG, "Native format is set to %d from %d by RTP payload type %d\n", rtptype.code, pvt->nativeformats, pt); 01949 if (pvt->nativeformats != rtptype.code) { 01950 pvt->nativeformats = rtptype.code; 01951 nativeformats_changed = 1; 01952 } 01953 } else if (h323debug) 01954 ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n"); 01955 01956 /* Don't try to lock the channel if nothing changed */ 01957 if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) { 01958 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01959 /* Re-build translation path only if native format(s) has been changed */ 01960 if (pvt->owner->nativeformats != pvt->nativeformats) { 01961 if (h323debug) 01962 ast_log(LOG_DEBUG, "Native format changed to %d from %d, read format is %d, write format is %d\n", pvt->nativeformats, pvt->owner->nativeformats, pvt->owner->readformat, pvt->owner->writeformat); 01963 pvt->owner->nativeformats = pvt->nativeformats; 01964 ast_set_read_format(pvt->owner, pvt->owner->readformat); 01965 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 01966 } 01967 if (pvt->options.progress_audio) 01968 ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS); 01969 switch (rtp_change) { 01970 case NEED_HOLD: 01971 ast_queue_control(pvt->owner, AST_CONTROL_HOLD); 01972 break; 01973 case NEED_UNHOLD: 01974 ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD); 01975 break; 01976 default: 01977 break; 01978 } 01979 ast_channel_unlock(pvt->owner); 01980 } 01981 else { 01982 if (pvt->options.progress_audio) 01983 pvt->newcontrol = AST_CONTROL_PROGRESS; 01984 else if (rtp_change == NEED_HOLD) 01985 pvt->newcontrol = AST_CONTROL_HOLD; 01986 else if (rtp_change == NEED_UNHOLD) 01987 pvt->newcontrol = AST_CONTROL_UNHOLD; 01988 if (h323debug) 01989 ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token); 01990 } 01991 } 01992 ast_mutex_unlock(&pvt->lock); 01993 01994 if (h323debug) 01995 ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token); 01996 01997 return; 01998 }
static int unload_module | ( | void | ) | [static] |
Definition at line 3234 of file chan_h323.c.
References aliasl, ast_channel_unregister(), ast_cli_unregister(), ast_cli_unregister_multiple(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, cli_h323, cli_h323_reload, free, gatekeeper_disable, iflist, iflock, io, io_context_destroy(), oh323_pvt::lock, LOG_WARNING, monitor_thread, monlock, oh323_pvt::next, oh323_destroy_alias(), oh323_destroy_peer(), oh323_destroy_user(), oh323_rtp, oh323_tech, oh323_pvt::owner, peerl, sched_context_destroy(), and userl.
03235 { 03236 struct oh323_pvt *p, *pl; 03237 03238 /* unregister commands */ 03239 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03240 ast_cli_unregister(&cli_h323_reload); 03241 03242 ast_channel_unregister(&oh323_tech); 03243 ast_rtp_proto_unregister(&oh323_rtp); 03244 03245 if (!ast_mutex_lock(&iflock)) { 03246 /* hangup all interfaces if they have an owner */ 03247 p = iflist; 03248 while(p) { 03249 if (p->owner) { 03250 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 03251 } 03252 p = p->next; 03253 } 03254 iflist = NULL; 03255 ast_mutex_unlock(&iflock); 03256 } else { 03257 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 03258 return -1; 03259 } 03260 if (!ast_mutex_lock(&monlock)) { 03261 if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 03262 if (monitor_thread != pthread_self()) { 03263 pthread_cancel(monitor_thread); 03264 } 03265 pthread_kill(monitor_thread, SIGURG); 03266 pthread_join(monitor_thread, NULL); 03267 } 03268 monitor_thread = AST_PTHREADT_STOP; 03269 ast_mutex_unlock(&monlock); 03270 } else { 03271 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03272 return -1; 03273 } 03274 if (!ast_mutex_lock(&iflock)) { 03275 /* destroy all the interfaces and free their memory */ 03276 p = iflist; 03277 while(p) { 03278 pl = p; 03279 p = p->next; 03280 /* free associated memory */ 03281 ast_mutex_destroy(&pl->lock); 03282 free(pl); 03283 } 03284 iflist = NULL; 03285 ast_mutex_unlock(&iflock); 03286 } else { 03287 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 03288 return -1; 03289 } 03290 if (!gatekeeper_disable) 03291 h323_gk_urq(); 03292 h323_end_process(); 03293 if (io) 03294 io_context_destroy(io); 03295 if (sched) 03296 sched_context_destroy(sched); 03297 03298 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03299 ASTOBJ_CONTAINER_DESTROY(&userl); 03300 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03301 ASTOBJ_CONTAINER_DESTROY(&peerl); 03302 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03303 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03304 03305 return 0; 03306 }
static int update_common_options | ( | struct ast_variable * | v, | |
struct call_options * | options | |||
) | [static] |
Definition at line 1257 of file chan_h323.c.
References ast_callerid_split(), ast_copy_string(), ast_log(), ast_parse_allow_disallow(), ast_true(), DEPRECATED, ast_variable::lineno, LOG_WARNING, ast_variable::name, and ast_variable::value.
Referenced by build_peer(), and build_user().
01258 { 01259 int tmp; 01260 01261 if (!strcasecmp(v->name, "allow")) { 01262 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1); 01263 } else if (!strcasecmp(v->name, "autoframing")) { 01264 options->autoframing = ast_true(v->value); 01265 } else if (!strcasecmp(v->name, "disallow")) { 01266 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0); 01267 } else if (!strcasecmp(v->name, "dtmfmode")) { 01268 if (!strcasecmp(v->value, "inband")) { 01269 options->dtmfmode = H323_DTMF_INBAND; 01270 } else if (!strcasecmp(v->value, "rfc2833")) { 01271 options->dtmfmode = H323_DTMF_RFC2833; 01272 } else { 01273 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value); 01274 options->dtmfmode = H323_DTMF_RFC2833; 01275 } 01276 } else if (!strcasecmp(v->name, "dtmfcodec")) { 01277 tmp = atoi(v->value); 01278 if (tmp < 96) 01279 ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno); 01280 else 01281 options->dtmfcodec = tmp; 01282 } else if (!strcasecmp(v->name, "bridge")) { 01283 options->bridge = ast_true(v->value); 01284 } else if (!strcasecmp(v->name, "nat")) { 01285 options->nat = ast_true(v->value); 01286 } else if (!strcasecmp(v->name, "noFastStart")) { 01287 DEPRECATED(v, "fastStart"); 01288 options->fastStart = !ast_true(v->value); 01289 } else if (!strcasecmp(v->name, "fastStart")) { 01290 options->fastStart = ast_true(v->value); 01291 } else if (!strcasecmp(v->name, "noH245Tunneling")) { 01292 DEPRECATED(v, "h245Tunneling"); 01293 options->h245Tunneling = !ast_true(v->value); 01294 } else if (!strcasecmp(v->name, "h245Tunneling")) { 01295 options->h245Tunneling = ast_true(v->value); 01296 } else if (!strcasecmp(v->name, "noSilenceSuppression")) { 01297 DEPRECATED(v, "silenceSuppression"); 01298 options->silenceSuppression = !ast_true(v->value); 01299 } else if (!strcasecmp(v->name, "silenceSuppression")) { 01300 options->silenceSuppression = ast_true(v->value); 01301 } else if (!strcasecmp(v->name, "progress_setup")) { 01302 tmp = atoi(v->value); 01303 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) { 01304 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno); 01305 tmp = 0; 01306 } 01307 options->progress_setup = tmp; 01308 } else if (!strcasecmp(v->name, "progress_alert")) { 01309 tmp = atoi(v->value); 01310 if ((tmp != 0) && (tmp != 1) && (tmp != 8)) { 01311 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno); 01312 tmp = 0; 01313 } 01314 options->progress_alert = tmp; 01315 } else if (!strcasecmp(v->name, "progress_audio")) { 01316 options->progress_audio = ast_true(v->value); 01317 } else if (!strcasecmp(v->name, "callerid")) { 01318 ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num)); 01319 } else if (!strcasecmp(v->name, "fullname")) { 01320 ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name)); 01321 } else if (!strcasecmp(v->name, "cid_number")) { 01322 ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num)); 01323 } else if (!strcasecmp(v->name, "tunneling")) { 01324 if (!strcasecmp(v->value, "none")) 01325 options->tunnelOptions = 0; 01326 else if (!strcasecmp(v->value, "cisco")) 01327 options->tunnelOptions |= H323_TUNNEL_CISCO; 01328 else if (!strcasecmp(v->value, "qsig")) 01329 options->tunnelOptions |= H323_TUNNEL_QSIG; 01330 else 01331 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno); 01332 } else 01333 return 1; 01334 01335 return 0; 01336 }
static int update_state | ( | struct oh323_pvt * | pvt, | |
int | state, | |||
int | signal | |||
) | [static] |
Definition at line 1173 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_control(), ast_setstate(), oh323_pvt::newcontrol, oh323_pvt::newstate, and oh323_pvt::owner.
Referenced by chan_ringing(), connection_made(), and progress().
01174 { 01175 if (!pvt) 01176 return 0; 01177 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01178 if (state >= 0) 01179 ast_setstate(pvt->owner, state); 01180 if (signal >= 0) 01181 ast_queue_control(pvt->owner, signal); 01182 ast_channel_unlock(pvt->owner); 01183 return 1; 01184 } 01185 else { 01186 if (state >= 0) 01187 pvt->newstate = state; 01188 if (signal >= 0) 01189 pvt->newcontrol = signal; 01190 return 0; 01191 } 01192 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "The NuFone Network's OpenH323 Channel Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 3312 of file chan_h323.c.
int acceptAnonymous = 1 [static] |
Definition at line 153 of file chan_h323.c.
Referenced by reload_config(), and setup_incoming_call().
struct ast_alias_list aliasl [static] |
Referenced by build_alias(), delete_aliases(), find_alias(), load_module(), and unload_module().
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 3312 of file chan_h323.c.
struct sockaddr_in bindaddr [static] |
Definition at line 141 of file chan_h323.c.
ast_mutex_t caplock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct ast_cli_entry cli_h323[] [static] |
struct ast_cli_entry cli_h323_debug_deprecated [static] |
Initial value:
{ { "h.323", "debug", NULL }, h323_do_debug, "Enable H.323 debug", debug_usage }
Definition at line 2696 of file chan_h323.c.
struct ast_cli_entry cli_h323_gk_cycle_deprecated [static] |
Initial value:
{ { "h.323", "gk", "cycle", NULL }, h323_gk_cycle, "Manually re-register with the Gatekeper", show_cycle_usage }
Definition at line 2706 of file chan_h323.c.
struct ast_cli_entry cli_h323_no_debug_deprecated [static] |
Initial value:
{ { "h.323", "no", "debug", NULL }, h323_no_debug, "Disable H.323 debug", no_debug_usage }
Definition at line 2691 of file chan_h323.c.
struct ast_cli_entry cli_h323_no_trace_deprecated [static] |
Initial value:
{ { "h.323", "no", "trace", NULL }, h323_no_trace, "Disable H.323 Stack Tracing", no_trace_usage }
Definition at line 2686 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 3043 of file chan_h323.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_h323_trace_deprecated [static] |
Initial value:
{ { "h.323", "trace", NULL }, h323_do_trace, "Enable H.323 Stack Tracing", trace_usage }
Definition at line 2701 of file chan_h323.c.
const char config[] = "h323.conf" [static] |
Definition at line 139 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 2658 of file chan_h323.c.
char default_context[AST_MAX_CONTEXT] = "default" [static] |
Definition at line 140 of file chan_h323.c.
Referenced by build_user(), reload_config(), and setup_incoming_call().
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 128 of file chan_h323.c.
char gatekeeper[100] [static] |
Definition at line 147 of file chan_h323.c.
Referenced by h323_gk_cycle(), load_module(), reload_config(), and setup_incoming_call().
int gatekeeper_disable = 1 [static] |
Definition at line 148 of file chan_h323.c.
Referenced by h323_gk_cycle(), load_module(), oh323_request(), reload_config(), setup_incoming_call(), and unload_module().
int gatekeeper_discover = 0 [static] |
Definition at line 149 of file chan_h323.c.
Referenced by h323_gk_cycle(), load_module(), and reload_config().
int gkroute = 0 [static] |
Definition at line 150 of file chan_h323.c.
Referenced by reload_config(), and setup_incoming_call().
struct ast_jb_conf global_jbconf [static] |
Definition at line 135 of file chan_h323.c.
call_options_t global_options [static] |
Definition at line 158 of file chan_h323.c.
Referenced by build_peer(), build_user(), create_addr(), oh323_request(), reload_config(), and setup_incoming_call().
ast_mutex_t h323_reload_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
char h323_reload_usage[] [static] |
Initial value:
"Usage: h323 reload\n" " Reloads H.323 configuration from h323.conf\n"
Definition at line 2682 of file chan_h323.c.
int h323_reloading = 0 [static] |
int h323_signalling_port = 1720 [static] |
H.323 configuration values
Definition at line 146 of file chan_h323.c.
Referenced by build_peer(), create_addr(), load_module(), and reload_config().
int h323debug |
Definition at line 125 of file chan_h323.c.
Referenced by answer_call(), chan_ringing(), cleanup_connection(), connection_made(), external_rtp_create(), find_peer(), find_user(), h323_do_debug(), h323_no_debug(), hangup_connection(), load_module(), oh323_request(), progress(), receive_digit(), set_dtmf_payload(), set_local_capabilities(), set_peer_capabilities(), setup_incoming_call(), and setup_rtp_connection().
ast_mutex_t iflock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Protect the interface list (oh323_pvt)
Definition at line 219 of file chan_h323.c.
struct io_context* io [static] |
Definition at line 216 of file chan_h323.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
Definition at line 234 of file chan_h323.c.
ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 223 of file chan_h323.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: h.323 debug off\n" " Disables H.323 debug output\n"
Definition at line 2662 of file chan_h323.c.
char no_trace_usage[] [static] |
Initial value:
"Usage: h.323 trace off\n" " Disables H.323 stack tracing for debugging purposes\n"
Definition at line 2654 of file chan_h323.c.
struct ast_rtp_protocol oh323_rtp [static] |
struct ast_channel_tech oh323_tech [static] |
Definition at line 249 of file chan_h323.c.
Referenced by __oh323_new(), load_module(), and unload_module().
answer_call_cb on_answer_call |
Definition at line 117 of file chan_h323.c.
chan_ringing_cb on_chan_ringing |
Definition at line 114 of file chan_h323.c.
clear_con_cb on_connection_cleared |
Definition at line 116 of file chan_h323.c.
con_established_cb on_connection_established |
Definition at line 115 of file chan_h323.c.
on_rtp_cb on_external_rtp_create |
Definition at line 110 of file chan_h323.c.
hangup_cb on_hangup |
Definition at line 120 of file chan_h323.c.
setup_incoming_cb on_incoming_call |
Definition at line 112 of file chan_h323.c.
setup_outbound_cb on_outgoing_call |
Definition at line 113 of file chan_h323.c.
progress_cb on_progress |
Definition at line 118 of file chan_h323.c.
receive_digit_cb on_receive_digit |
Definition at line 109 of file chan_h323.c.
rfc2833_cb on_set_rfc2833_payload |
Definition at line 119 of file chan_h323.c.
setcapabilities_cb on_setcapabilities |
Definition at line 121 of file chan_h323.c.
setpeercapabilities_cb on_setpeercapabilities |
Definition at line 122 of file chan_h323.c.
start_rtp_cb on_start_rtp_channel |
Definition at line 111 of file chan_h323.c.
struct ast_peer_list peerl [static] |
Referenced by _sip_show_peers(), build_peer(), complete_sip_peer(), delete_users(), do_monitor(), expire_register(), find_peer(), load_module(), prune_peers(), register_verify(), reload_config(), sip_do_reload(), sip_poke_all_peers(), sip_poke_peer_s(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), and unload_module().
struct sched_context* sched [static] |
Asterisk RTP stuff
Definition at line 215 of file chan_h323.c.
char secret[50] [static] |
Definition at line 155 of file chan_h323.c.
Referenced by add_realm_authentication(), aji_act_hook(), authenticate_verify(), build_peer(), build_reply_digest(), build_user(), cache_get_callno_locked(), check_access(), decrypt_frame(), h323_gk_cycle(), iax2_call(), iax2_register(), load_module(), read_agent_config(), register_verify(), set_config(), and sip_register().
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 2666 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 2670 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 2674 of file chan_h323.c.
char show_version_usage[] [static] |
Initial value:
"Usage: h.323 show version\n" " Print the version of the H.323 library in use\n"
Definition at line 2678 of file chan_h323.c.
const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver" [static] |
Variables required by Asterisk
Definition at line 138 of file chan_h323.c.
int tos = 0 [static] |
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 2650 of file chan_h323.c.
unsigned int unique = 0 [static] |
int userbyalias = 1 [static] |
Definition at line 152 of file chan_h323.c.
Referenced by find_user(), realtime_user(), and reload_config().
struct ast_user_list userl [static] |