#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 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 = "f450f61f60e761b3aa089ebed76ca8a5" , .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 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, 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 999 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().
01000 { 01001 struct ast_channel *ch; 01002 char *cid_num, *cid_name; 01003 int fmt; 01004 01005 if (!ast_strlen_zero(pvt->options.cid_num)) 01006 cid_num = pvt->options.cid_num; 01007 else 01008 cid_num = pvt->cd.call_source_e164; 01009 01010 if (!ast_strlen_zero(pvt->options.cid_name)) 01011 cid_name = pvt->options.cid_name; 01012 else 01013 cid_name = pvt->cd.call_source_name; 01014 01015 /* Don't hold a oh323_pvt lock while we allocate a chanel */ 01016 ast_mutex_unlock(&pvt->lock); 01017 ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host); 01018 /* Update usage counter */ 01019 ast_module_ref(ast_module_info->self); 01020 ast_mutex_lock(&pvt->lock); 01021 if (ch) { 01022 ch->tech = &oh323_tech; 01023 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability)) 01024 fmt = global_options.capability; 01025 ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/; 01026 pvt->nativeformats = ch->nativeformats; 01027 fmt = ast_best_codec(ch->nativeformats); 01028 ch->writeformat = fmt; 01029 ch->rawwriteformat = fmt; 01030 ch->readformat = fmt; 01031 ch->rawreadformat = fmt; 01032 #if 0 01033 ch->fds[0] = ast_rtp_fd(pvt->rtp); 01034 ch->fds[1] = ast_rtcp_fd(pvt->rtp); 01035 #endif 01036 #ifdef VIDEO_SUPPORT 01037 if (pvt->vrtp) { 01038 ch->fds[2] = ast_rtp_fd(pvt->vrtp); 01039 ch->fds[3] = ast_rtcp_fd(pvt->vrtp); 01040 } 01041 #endif 01042 #ifdef T38_SUPPORT 01043 if (pvt->udptl) { 01044 ch->fds[4] = ast_udptl_fd(pvt->udptl); 01045 } 01046 #endif 01047 if (state == AST_STATE_RING) { 01048 ch->rings = 1; 01049 } 01050 /* Allocate dsp for in-band DTMF support */ 01051 if (pvt->options.dtmfmode & H323_DTMF_INBAND) { 01052 pvt->vad = ast_dsp_new(); 01053 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT); 01054 } 01055 /* Register channel functions. */ 01056 ch->tech_pvt = pvt; 01057 /* Set the owner of this channel */ 01058 pvt->owner = ch; 01059 01060 ast_copy_string(ch->context, pvt->context, sizeof(ch->context)); 01061 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten)); 01062 ch->priority = 1; 01063 if (!ast_strlen_zero(pvt->accountcode)) { 01064 ast_string_field_set(ch, accountcode, pvt->accountcode); 01065 } 01066 if (pvt->amaflags) { 01067 ch->amaflags = pvt->amaflags; 01068 } 01069 01070 /* Don't use ast_set_callerid() here because it will 01071 * generate a needless NewCallerID event */ 01072 ch->cid.cid_ani = ast_strdup(cid_num); 01073 01074 if (pvt->cd.redirect_reason >= 0) { 01075 ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number); 01076 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason)); 01077 } 01078 ch->cid.cid_pres = pvt->cd.presentation; 01079 ch->cid.cid_ton = pvt->cd.type_of_number; 01080 01081 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) { 01082 ch->cid.cid_dnid = strdup(pvt->exten); 01083 } 01084 if (pvt->cd.transfer_capability >= 0) 01085 ch->transfercapability = pvt->cd.transfer_capability; 01086 if (state != AST_STATE_DOWN) { 01087 if (ast_pbx_start(ch)) { 01088 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name); 01089 ast_hangup(ch); 01090 ch = NULL; 01091 } 01092 } 01093 } else { 01094 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 01095 } 01096 return ch; 01097 }
static int __oh323_rtp_create | ( | struct oh323_pvt * | pvt | ) | [static] |
Definition at line 953 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().
00954 { 00955 struct in_addr our_addr; 00956 00957 if (pvt->rtp) 00958 return 0; 00959 00960 if (ast_find_ourip(&our_addr, bindaddr)) { 00961 ast_mutex_unlock(&pvt->lock); 00962 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n"); 00963 return -1; 00964 } 00965 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr); 00966 if (!pvt->rtp) { 00967 ast_mutex_unlock(&pvt->lock); 00968 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); 00969 return -1; 00970 } 00971 if (h323debug) 00972 ast_log(LOG_DEBUG, "Created RTP channel\n"); 00973 00974 ast_rtp_settos(pvt->rtp, tos); 00975 00976 if (h323debug) 00977 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat); 00978 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00979 00980 if (pvt->dtmf_pt > 0) 00981 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0); 00982 00983 if (pvt->peercapability) 00984 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 00985 00986 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 00987 ast_jb_configure(pvt->owner, &global_jbconf); 00988 pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp); 00989 pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp); 00990 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00991 ast_channel_unlock(pvt->owner); 00992 } else 00993 pvt->update_rtp_info = 1; 00994 00995 return 0; 00996 }
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 3274 of file chan_h323.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 3274 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 2173 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().
02174 { 02175 struct oh323_pvt *pvt; 02176 struct ast_channel *c = NULL; 02177 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten; 02178 char tmp_exten[sizeof(pvt->exten)]; 02179 02180 if (h323debug) 02181 ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token); 02182 02183 /* Find the call or allocate a private structure if call not found */ 02184 pvt = find_call_locked(call_reference, token); 02185 if (!pvt) { 02186 ast_log(LOG_ERROR, "Something is wrong: answer_call\n"); 02187 return 0; 02188 } 02189 /* Check if requested extension@context pair exists in the dialplan */ 02190 ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten)); 02191 02192 /* Try to find best extension in specified context */ 02193 if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) { 02194 if (tmp_exten[0] == 's') 02195 try_exten = ext_s; 02196 else if (tmp_exten[0] == 'i') 02197 try_exten = ext_i; 02198 else 02199 try_exten = ext_original; 02200 } else 02201 try_exten = ext_original; 02202 do { 02203 if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL)) 02204 break; 02205 switch (try_exten) { 02206 case ext_original: 02207 tmp_exten[0] = 's'; 02208 tmp_exten[1] = '\0'; 02209 try_exten = ext_s; 02210 break; 02211 case ext_s: 02212 tmp_exten[0] = 'i'; 02213 try_exten = ext_i; 02214 break; 02215 case ext_i: 02216 try_exten = ext_notexists; 02217 break; 02218 default: 02219 break; 02220 } 02221 } while (try_exten != ext_notexists); 02222 02223 /* Drop the call if we don't have <exten>, s and i extensions */ 02224 if (try_exten == ext_notexists) { 02225 ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context); 02226 ast_mutex_unlock(&pvt->lock); 02227 h323_clear_call(token, AST_CAUSE_UNALLOCATED); 02228 return 0; 02229 } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) { 02230 if (h323debug) 02231 ast_log(LOG_DEBUG, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context); 02232 ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten)); 02233 } 02234 02235 /* allocate a channel and tell asterisk about it */ 02236 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token); 02237 02238 /* And release when done */ 02239 ast_mutex_unlock(&pvt->lock); 02240 if (!c) { 02241 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n"); 02242 return 0; 02243 } 02244 return 1; 02245 }
static struct oh323_alias* build_alias | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Definition at line 1190 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.
01191 { 01192 struct oh323_alias *alias; 01193 int found = 0; 01194 01195 alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp); 01196 01197 if (alias) 01198 found++; 01199 else { 01200 if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias)))) 01201 return NULL; 01202 ASTOBJ_INIT(alias); 01203 } 01204 if (!found && name) 01205 ast_copy_string(alias->name, name, sizeof(alias->name)); 01206 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01207 if (!strcasecmp(v->name, "e164")) { 01208 ast_copy_string(alias->e164, v->value, sizeof(alias->e164)); 01209 } else if (!strcasecmp(v->name, "prefix")) { 01210 ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix)); 01211 } else if (!strcasecmp(v->name, "context")) { 01212 ast_copy_string(alias->context, v->value, sizeof(alias->context)); 01213 } else if (!strcasecmp(v->name, "secret")) { 01214 ast_copy_string(alias->secret, v->value, sizeof(alias->secret)); 01215 } else { 01216 if (strcasecmp(v->value, "h323")) { 01217 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name); 01218 } 01219 } 01220 } 01221 ASTOBJ_UNMARK(alias); 01222 return alias; 01223 }
static struct oh323_peer* build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Definition at line 1439 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().
01440 { 01441 struct oh323_peer *peer; 01442 struct ast_ha *oldha; 01443 int found = 0; 01444 01445 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 01446 01447 if (peer) 01448 found++; 01449 else { 01450 if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer)))) 01451 return NULL; 01452 ASTOBJ_INIT(peer); 01453 } 01454 oldha = peer->ha; 01455 peer->ha = NULL; 01456 memcpy(&peer->options, &global_options, sizeof(peer->options)); 01457 peer->addr.sin_port = htons(h323_signalling_port); 01458 peer->addr.sin_family = AF_INET; 01459 if (!found && name) 01460 ast_copy_string(peer->name, name, sizeof(peer->name)); 01461 01462 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01463 if (peer->chanvars) { 01464 ast_variables_destroy(peer->chanvars); 01465 peer->chanvars = NULL; 01466 } 01467 #endif 01468 /* Default settings for mailbox */ 01469 peer->mailbox[0] = '\0'; 01470 01471 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01472 if (!update_common_options(v, &peer->options)) 01473 continue; 01474 if (!strcasecmp(v->name, "host")) { 01475 if (!strcasecmp(v->value, "dynamic")) { 01476 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n"); 01477 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01478 return NULL; 01479 } 01480 if (ast_get_ip(&peer->addr, v->value)) { 01481 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value); 01482 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01483 return NULL; 01484 } 01485 } else if (!strcasecmp(v->name, "port")) { 01486 peer->addr.sin_port = htons(atoi(v->value)); 01487 } else if (!strcasecmp(v->name, "permit") || 01488 !strcasecmp(v->name, "deny")) { 01489 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 01490 } else if (!strcasecmp(v->name, "mailbox")) { 01491 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 01492 } else if (!strcasecmp(v->name, "hasvoicemail")) { 01493 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 01494 ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox)); 01495 } 01496 } 01497 } 01498 ASTOBJ_UNMARK(peer); 01499 ast_free_ha(oldha); 01500 return peer; 01501 }
static struct oh323_user* build_user | ( | char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Definition at line 1333 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().
01334 { 01335 struct oh323_user *user; 01336 struct ast_ha *oldha; 01337 int found = 0; 01338 int format; 01339 01340 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp); 01341 01342 if (user) 01343 found++; 01344 else { 01345 if (!(user = (struct oh323_user *)calloc(1, sizeof(*user)))) 01346 return NULL; 01347 ASTOBJ_INIT(user); 01348 } 01349 oldha = user->ha; 01350 user->ha = (struct ast_ha *)NULL; 01351 memcpy(&user->options, &global_options, sizeof(user->options)); 01352 /* Set default context */ 01353 ast_copy_string(user->context, default_context, sizeof(user->context)); 01354 if (user && !found) 01355 ast_copy_string(user->name, name, sizeof(user->name)); 01356 01357 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01358 if (user->chanvars) { 01359 ast_variables_destroy(user->chanvars); 01360 user->chanvars = NULL; 01361 } 01362 #endif 01363 01364 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01365 if (!update_common_options(v, &user->options)) 01366 continue; 01367 if (!strcasecmp(v->name, "context")) { 01368 ast_copy_string(user->context, v->value, sizeof(user->context)); 01369 } else if (!strcasecmp(v->name, "secret")) { 01370 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 01371 } else if (!strcasecmp(v->name, "accountcode")) { 01372 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 01373 } else if (!strcasecmp(v->name, "host")) { 01374 if (!strcasecmp(v->value, "dynamic")) { 01375 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n"); 01376 ASTOBJ_UNREF(user, oh323_destroy_user); 01377 return NULL; 01378 } else if (ast_get_ip(&user->addr, v->value)) { 01379 ASTOBJ_UNREF(user, oh323_destroy_user); 01380 return NULL; 01381 } 01382 /* Let us know we need to use ip authentication */ 01383 user->host = 1; 01384 } else if (!strcasecmp(v->name, "amaflags")) { 01385 format = ast_cdr_amaflags2int(v->value); 01386 if (format < 0) { 01387 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 01388 } else { 01389 user->amaflags = format; 01390 } 01391 } else if (!strcasecmp(v->name, "permit") || 01392 !strcasecmp(v->name, "deny")) { 01393 user->ha = ast_append_ha(v->name, v->value, user->ha); 01394 } 01395 } 01396 ASTOBJ_UNMARK(user); 01397 ast_free_ha(oldha); 01398 return user; 01399 }
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 2264 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().
02265 { 02266 struct oh323_pvt *pvt; 02267 02268 if (h323debug) 02269 ast_log(LOG_DEBUG, "Ringing on %s\n", token); 02270 02271 pvt = find_call_locked(call_reference, token); 02272 if (!pvt) { 02273 ast_log(LOG_ERROR, "Something is wrong: ringing\n"); 02274 return; 02275 } 02276 if (!pvt->owner) { 02277 ast_mutex_unlock(&pvt->lock); 02278 ast_log(LOG_ERROR, "Channel has no owner\n"); 02279 return; 02280 } 02281 update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING); 02282 ast_mutex_unlock(&pvt->lock); 02283 return; 02284 }
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 2290 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().
02291 { 02292 struct oh323_pvt *pvt; 02293 02294 if (h323debug) 02295 ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token); 02296 02297 while (1) { 02298 pvt = find_call_locked(call_reference, call_token); 02299 if (!pvt) { 02300 if (h323debug) 02301 ast_log(LOG_DEBUG, "No connection for %s\n", call_token); 02302 return; 02303 } 02304 if (!pvt->owner || !ast_channel_trylock(pvt->owner)) 02305 break; 02306 #if 1 02307 #ifdef DEBUG_THREADS 02308 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]); 02309 #else 02310 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token); 02311 #endif 02312 #endif 02313 ast_mutex_unlock(&pvt->lock); 02314 usleep(1); 02315 } 02316 if (pvt->rtp) { 02317 /* Immediately stop RTP */ 02318 ast_rtp_destroy(pvt->rtp); 02319 pvt->rtp = NULL; 02320 } 02321 /* Free dsp used for in-band DTMF detection */ 02322 if (pvt->vad) { 02323 ast_dsp_free(pvt->vad); 02324 pvt->vad = NULL; 02325 } 02326 cleanup_call_details(&pvt->cd); 02327 pvt->alreadygone = 1; 02328 /* Send hangup */ 02329 if (pvt->owner) { 02330 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02331 ast_queue_hangup(pvt->owner); 02332 ast_channel_unlock(pvt->owner); 02333 } 02334 ast_mutex_unlock(&pvt->lock); 02335 if (h323debug) 02336 ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token); 02337 return; 02338 }
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 1998 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().
01999 { 02000 struct oh323_pvt *pvt; 02001 02002 if (h323debug) 02003 ast_log(LOG_DEBUG, "Call %s answered\n", token); 02004 02005 pvt = find_call_locked(call_reference, token); 02006 if (!pvt) { 02007 ast_log(LOG_ERROR, "Something is wrong: connection\n"); 02008 return; 02009 } 02010 02011 /* Inform asterisk about remote party connected only on outgoing calls */ 02012 if (!pvt->outgoing) { 02013 ast_mutex_unlock(&pvt->lock); 02014 return; 02015 } 02016 /* Do not send ANSWER message more than once */ 02017 if (!pvt->connection_established) { 02018 pvt->connection_established = 1; 02019 update_state(pvt, -1, AST_CONTROL_ANSWER); 02020 } 02021 ast_mutex_unlock(&pvt->lock); 02022 return; 02023 }
static char* convertcap | ( | int | cap | ) | [static] |
Definition at line 3034 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().
03035 { 03036 switch (cap) { 03037 case AST_FORMAT_G723_1: 03038 return "G.723"; 03039 case AST_FORMAT_GSM: 03040 return "GSM"; 03041 case AST_FORMAT_ULAW: 03042 return "ULAW"; 03043 case AST_FORMAT_ALAW: 03044 return "ALAW"; 03045 case AST_FORMAT_G722: 03046 return "G.722"; 03047 case AST_FORMAT_ADPCM: 03048 return "G.728"; 03049 case AST_FORMAT_G729A: 03050 return "G.729"; 03051 case AST_FORMAT_SPEEX: 03052 return "SPEEX"; 03053 case AST_FORMAT_ILBC: 03054 return "ILBC"; 03055 default: 03056 ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap); 03057 return NULL; 03058 } 03059 }
static int create_addr | ( | struct oh323_pvt * | pvt, | |
char * | opeer | |||
) | [static] |
Definition at line 1599 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().
01600 { 01601 struct hostent *hp; 01602 struct ast_hostent ahp; 01603 struct oh323_peer *p; 01604 int portno; 01605 int found = 0; 01606 char *port; 01607 char *hostn; 01608 char peer[256] = ""; 01609 01610 ast_copy_string(peer, opeer, sizeof(peer)); 01611 port = strchr(peer, ':'); 01612 if (port) { 01613 *port = '\0'; 01614 port++; 01615 } 01616 pvt->sa.sin_family = AF_INET; 01617 p = find_peer(peer, NULL, 1); 01618 if (p) { 01619 found++; 01620 memcpy(&pvt->options, &p->options, sizeof(pvt->options)); 01621 pvt->jointcapability = pvt->options.capability; 01622 if (pvt->options.dtmfmode) { 01623 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01624 pvt->nonCodecCapability |= AST_RTP_DTMF; 01625 } else { 01626 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01627 } 01628 } 01629 if (p->addr.sin_addr.s_addr) { 01630 pvt->sa.sin_addr = p->addr.sin_addr; 01631 pvt->sa.sin_port = p->addr.sin_port; 01632 } 01633 ASTOBJ_UNREF(p, oh323_destroy_peer); 01634 } 01635 if (!p && !found) { 01636 hostn = peer; 01637 if (port) { 01638 portno = atoi(port); 01639 } else { 01640 portno = h323_signalling_port; 01641 } 01642 hp = ast_gethostbyname(hostn, &ahp); 01643 if (hp) { 01644 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 01645 pvt->sa.sin_port = htons(portno); 01646 /* Look peer by address */ 01647 p = find_peer(NULL, &pvt->sa, 1); 01648 memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options)); 01649 pvt->jointcapability = pvt->options.capability; 01650 if (p) { 01651 ASTOBJ_UNREF(p, oh323_destroy_peer); 01652 } 01653 if (pvt->options.dtmfmode) { 01654 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01655 pvt->nonCodecCapability |= AST_RTP_DTMF; 01656 } else { 01657 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01658 } 01659 } 01660 return 0; 01661 } else { 01662 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01663 return -1; 01664 } 01665 } else if (!found) { 01666 return -1; 01667 } else { 01668 return 0; 01669 } 01670 }
static void delete_aliases | ( | void | ) | [static] |
Definition at line 2734 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().
02735 { 02736 int pruned = 0; 02737 02738 /* Delete all aliases */ 02739 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 02740 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 02741 ASTOBJ_RDLOCK(iterator); 02742 ASTOBJ_MARK(iterator); 02743 ++pruned; 02744 ASTOBJ_UNLOCK(iterator); 02745 } while (0) ); 02746 if (pruned) { 02747 ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias); 02748 } 02749 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 02750 }
static void delete_users | ( | void | ) | [static] |
Definition at line 2708 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().
02709 { 02710 int pruned = 0; 02711 02712 /* Delete all users */ 02713 ASTOBJ_CONTAINER_WRLOCK(&userl); 02714 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 02715 ASTOBJ_RDLOCK(iterator); 02716 ASTOBJ_MARK(iterator); 02717 ++pruned; 02718 ASTOBJ_UNLOCK(iterator); 02719 } while (0) ); 02720 if (pruned) { 02721 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user); 02722 } 02723 ASTOBJ_CONTAINER_UNLOCK(&userl); 02724 02725 ASTOBJ_CONTAINER_WRLOCK(&peerl); 02726 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 02727 ASTOBJ_RDLOCK(iterator); 02728 ASTOBJ_MARK(iterator); 02729 ASTOBJ_UNLOCK(iterator); 02730 } while (0) ); 02731 ASTOBJ_CONTAINER_UNLOCK(&peerl); 02732 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 2441 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.
02442 { 02443 int res; 02444 int reloading; 02445 struct oh323_pvt *oh323 = NULL; 02446 02447 for(;;) { 02448 /* Check for a reload request */ 02449 ast_mutex_lock(&h323_reload_lock); 02450 reloading = h323_reloading; 02451 h323_reloading = 0; 02452 ast_mutex_unlock(&h323_reload_lock); 02453 if (reloading) { 02454 if (option_verbose > 0) { 02455 ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n"); 02456 } 02457 h323_do_reload(); 02458 } 02459 /* Check for interfaces needing to be killed */ 02460 if (!ast_mutex_trylock(&iflock)) { 02461 #if 1 02462 do { 02463 for (oh323 = iflist; oh323; oh323 = oh323->next) { 02464 if (!ast_mutex_trylock(&oh323->lock)) { 02465 if (oh323->needdestroy) { 02466 __oh323_destroy(oh323); 02467 break; 02468 } 02469 ast_mutex_unlock(&oh323->lock); 02470 } 02471 } 02472 } while (/*oh323*/ 0); 02473 #else 02474 restartsearch: 02475 oh323 = iflist; 02476 while(oh323) { 02477 if (!ast_mutex_trylock(&oh323->lock)) { 02478 if (oh323->needdestroy) { 02479 __oh323_destroy(oh323); 02480 goto restartsearch; 02481 } 02482 ast_mutex_unlock(&oh323->lock); 02483 oh323 = oh323->next; 02484 } 02485 } 02486 #endif 02487 ast_mutex_unlock(&iflock); 02488 } else 02489 oh323 = (struct oh323_pvt *)1; /* Force fast loop */ 02490 pthread_testcancel(); 02491 /* Wait for sched or io */ 02492 res = ast_sched_wait(sched); 02493 if ((res < 0) || (res > 1000)) { 02494 res = 1000; 02495 } 02496 /* Do not wait if some channel(s) is destroyed, probably, more available too */ 02497 if (oh323) 02498 res = 1; 02499 res = ast_io_wait(io, res); 02500 pthread_testcancel(); 02501 ast_mutex_lock(&monlock); 02502 if (res >= 0) { 02503 ast_sched_runq(sched); 02504 } 02505 ast_mutex_unlock(&monlock); 02506 } 02507 /* Never reached */ 02508 return NULL; 02509 }
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 1844 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().
01845 { 01846 struct oh323_pvt *pvt; 01847 struct sockaddr_in us; 01848 struct rtp_info *info; 01849 01850 info = (struct rtp_info *)malloc(sizeof(struct rtp_info)); 01851 if (!info) { 01852 ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n"); 01853 return NULL; 01854 } 01855 pvt = find_call_locked(call_reference, token); 01856 if (!pvt) { 01857 free(info); 01858 ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference); 01859 return NULL; 01860 } 01861 if (!pvt->rtp) 01862 __oh323_rtp_create(pvt); 01863 if (!pvt->rtp) { 01864 ast_mutex_unlock(&pvt->lock); 01865 free(info); 01866 ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference); 01867 return NULL; 01868 } 01869 /* figure out our local RTP port and tell the H.323 stack about it */ 01870 ast_rtp_get_us(pvt->rtp, &us); 01871 ast_mutex_unlock(&pvt->lock); 01872 01873 ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr)); 01874 info->port = ntohs(us.sin_port); 01875 if (h323debug) 01876 ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port); 01877 return info; 01878 }
static struct oh323_alias* find_alias | ( | const char * | source_aliases, | |
int | realtime | |||
) | [static] |
Find a call by alias
Definition at line 1760 of file chan_h323.c.
References aliasl, ASTOBJ_CONTAINER_FIND, and realtime_alias().
Referenced by __get_header(), add_header(), and setup_incoming_call().
01761 { 01762 struct oh323_alias *a; 01763 01764 a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases); 01765 01766 if (!a && realtime) 01767 a = realtime_alias(source_aliases); 01768 01769 return a; 01770 }
static struct oh323_pvt* find_call_locked | ( | int | call_reference, | |
const char * | token | |||
) | [static] |
Definition at line 1143 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().
01144 { 01145 struct oh323_pvt *pvt; 01146 01147 ast_mutex_lock(&iflock); 01148 pvt = iflist; 01149 while(pvt) { 01150 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) { 01151 /* Found the call */ 01152 if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) { 01153 ast_mutex_lock(&pvt->lock); 01154 ast_mutex_unlock(&iflock); 01155 return pvt; 01156 } else if (token == NULL) { 01157 ast_log(LOG_WARNING, "Call Token is NULL\n"); 01158 ast_mutex_lock(&pvt->lock); 01159 ast_mutex_unlock(&iflock); 01160 return pvt; 01161 } 01162 } 01163 pvt = pvt->next; 01164 } 01165 ast_mutex_unlock(&iflock); 01166 return NULL; 01167 }
static struct oh323_peer* find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [static] |
Definition at line 1581 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(), 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(), set_config(), sip_devicestate(), sip_do_debug_peer(), sip_peer_hold(), update_call_counter(), and update_registry().
01582 { 01583 struct oh323_peer *p; 01584 01585 if (peer) 01586 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 01587 else 01588 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp); 01589 01590 if (!p && realtime) 01591 p = realtime_peer(peer, sin); 01592 01593 if (!p && h323debug) 01594 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>")); 01595 01596 return p; 01597 }
static struct oh323_user* find_user | ( | const call_details_t * | cd, | |
int | realtime | |||
) | [static] |
Definition at line 1551 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(), check_user_full(), forward_message(), leave_voicemail(), setup_incoming_call(), sip_show_user(), update_call_counter(), vm_authenticate(), vm_box_exists(), and vm_execmain().
01552 { 01553 struct oh323_user *u; 01554 01555 if (userbyalias) 01556 u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases); 01557 else 01558 u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str); 01559 01560 if (!u && realtime) 01561 u = realtime_user(cd); 01562 01563 if (!u && h323debug) 01564 ast_log(LOG_DEBUG, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp); 01565 01566 return u; 01567 }
static int h323_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2563 of file chan_h323.c.
References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02564 { 02565 if (argc < 2 || argc > 3) { 02566 return RESULT_SHOWUSAGE; 02567 } 02568 h323debug = 1; 02569 ast_cli(fd, "H.323 debug enabled\n"); 02570 return RESULT_SUCCESS; 02571 }
static int h323_do_reload | ( | void | ) | [static] |
Definition at line 2990 of file chan_h323.c.
References reload_config().
Referenced by do_monitor().
02991 { 02992 reload_config(1); 02993 return 0; 02994 }
static int h323_do_trace | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2543 of file chan_h323.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02544 { 02545 if (argc != 4) { 02546 return RESULT_SHOWUSAGE; 02547 } 02548 h323_debug(1, atoi(argv[3])); 02549 ast_cli(fd, "H.323 trace set to level %s\n", argv[2]); 02550 return RESULT_SUCCESS; 02551 }
static int h323_ep_hangup | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2599 of file chan_h323.c.
References ast_verbose(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and VERBOSE_PREFIX_3.
02600 { 02601 if (argc != 3) { 02602 return RESULT_SHOWUSAGE; 02603 } 02604 if (h323_soft_hangup(argv[2])) { 02605 ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]); 02606 } else { 02607 ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]); 02608 } 02609 return RESULT_SUCCESS; 02610 }
static int h323_gk_cycle | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2583 of file chan_h323.c.
References ast_log(), gatekeeper, gatekeeper_disable, gatekeeper_discover, LOG_ERROR, RESULT_SHOWUSAGE, RESULT_SUCCESS, and secret.
02584 { 02585 if (argc != 3) { 02586 return RESULT_SHOWUSAGE; 02587 } 02588 h323_gk_urq(); 02589 02590 /* Possibly register with a GK */ 02591 if (!gatekeeper_disable) { 02592 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 02593 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 02594 } 02595 } 02596 return RESULT_SUCCESS; 02597 }
static int h323_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2573 of file chan_h323.c.
References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02574 { 02575 if (argc < 3 || argc > 4) { 02576 return RESULT_SHOWUSAGE; 02577 } 02578 h323debug = 0; 02579 ast_cli(fd, "H.323 debug disabled\n"); 02580 return RESULT_SUCCESS; 02581 }
static int h323_no_trace | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2553 of file chan_h323.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02554 { 02555 if (argc < 3 || argc > 4) { 02556 return RESULT_SHOWUSAGE; 02557 } 02558 h323_debug(0,0); 02559 ast_cli(fd, "H.323 trace disabled\n"); 02560 return RESULT_SUCCESS; 02561 }
static int h323_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2977 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().
02978 { 02979 ast_mutex_lock(&h323_reload_lock); 02980 if (h323_reloading) { 02981 ast_verbose("Previous H.323 reload not yet done\n"); 02982 } else { 02983 h323_reloading = 1; 02984 } 02985 ast_mutex_unlock(&h323_reload_lock); 02986 restart_monitor(); 02987 return 0; 02988 }
static int h323_tokens_show | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2612 of file chan_h323.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02613 { 02614 if (argc != 3) { 02615 return RESULT_SHOWUSAGE; 02616 } 02617 h323_show_tokens(); 02618 return RESULT_SUCCESS; 02619 }
static void hangup_connection | ( | unsigned int | call_reference, | |
const char * | token, | |||
int | cause | |||
) | [static] |
Definition at line 2340 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().
02341 { 02342 struct oh323_pvt *pvt; 02343 02344 if (h323debug) { 02345 ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause); 02346 } 02347 02348 pvt = find_call_locked(call_reference, token); 02349 if (!pvt) { 02350 if (h323debug) { 02351 ast_log(LOG_DEBUG, "Connection to %s already cleared\n", token); 02352 } 02353 return; 02354 } 02355 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 02356 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02357 pvt->owner->hangupcause = pvt->hangupcause = cause; 02358 ast_queue_hangup(pvt->owner); 02359 ast_channel_unlock(pvt->owner); 02360 } 02361 else { 02362 pvt->needhangup = 1; 02363 pvt->hangupcause = cause; 02364 if (h323debug) 02365 ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token); 02366 } 02367 ast_mutex_unlock(&pvt->lock); 02368 }
static enum ast_module_load_result load_module | ( | void | ) | [static] |
Definition at line 3094 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.
03095 { 03096 int res; 03097 03098 h323debug = 0; 03099 sched = sched_context_create(); 03100 if (!sched) { 03101 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 03102 return AST_MODULE_LOAD_FAILURE; 03103 } 03104 io = io_context_create(); 03105 if (!io) { 03106 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 03107 return AST_MODULE_LOAD_FAILURE; 03108 } 03109 ast_cli_register(&cli_h323_reload); 03110 ASTOBJ_CONTAINER_INIT(&userl); 03111 ASTOBJ_CONTAINER_INIT(&peerl); 03112 ASTOBJ_CONTAINER_INIT(&aliasl); 03113 res = reload_config(0); 03114 if (res) { 03115 /* No config entry */ 03116 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n"); 03117 ast_cli_unregister(&cli_h323_reload); 03118 io_context_destroy(io); 03119 io = NULL; 03120 sched_context_destroy(sched); 03121 sched = NULL; 03122 ASTOBJ_CONTAINER_DESTROY(&userl); 03123 ASTOBJ_CONTAINER_DESTROY(&peerl); 03124 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03125 return AST_MODULE_LOAD_DECLINE; 03126 } else { 03127 /* Make sure we can register our channel type */ 03128 if (ast_channel_register(&oh323_tech)) { 03129 ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n"); 03130 ast_cli_unregister(&cli_h323_reload); 03131 h323_end_process(); 03132 io_context_destroy(io); 03133 sched_context_destroy(sched); 03134 03135 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03136 ASTOBJ_CONTAINER_DESTROY(&userl); 03137 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03138 ASTOBJ_CONTAINER_DESTROY(&peerl); 03139 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03140 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03141 03142 return AST_MODULE_LOAD_FAILURE; 03143 } 03144 ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03145 03146 ast_rtp_proto_register(&oh323_rtp); 03147 03148 /* Register our callback functions */ 03149 h323_callback_register(setup_incoming_call, 03150 setup_outgoing_call, 03151 external_rtp_create, 03152 setup_rtp_connection, 03153 cleanup_connection, 03154 chan_ringing, 03155 connection_made, 03156 receive_digit, 03157 answer_call, 03158 progress, 03159 set_dtmf_payload, 03160 hangup_connection, 03161 set_local_capabilities, 03162 set_peer_capabilities); 03163 /* start the h.323 listener */ 03164 if (h323_start_listener(h323_signalling_port, bindaddr)) { 03165 ast_log(LOG_ERROR, "Unable to create H323 listener.\n"); 03166 ast_rtp_proto_unregister(&oh323_rtp); 03167 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 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 /* Possibly register with a GK */ 03183 if (!gatekeeper_disable) { 03184 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 03185 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 03186 gatekeeper_disable = 1; 03187 res = AST_MODULE_LOAD_SUCCESS; 03188 } 03189 } 03190 /* And start the monitor for the first time */ 03191 restart_monitor(); 03192 } 03193 return res; 03194 }
static int oh323_addrcmp | ( | struct sockaddr_in | addr, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 1569 of file chan_h323.c.
References inaddrcmp().
Referenced by find_peer().
01570 { 01571 int res; 01572 01573 if (!sin) 01574 res = -1; 01575 else 01576 res = inaddrcmp(&addr , sin); 01577 01578 return res; 01579 }
static int oh323_addrcmp_str | ( | struct in_addr | inaddr, | |
char * | addr | |||
) | [static] |
Definition at line 1546 of file chan_h323.c.
References ast_inet_ntoa().
Referenced by find_user().
01547 { 01548 return strcmp(ast_inet_ntoa(inaddr), addr); 01549 }
static struct oh323_pvt* oh323_alloc | ( | int | callid | ) | [static] |
Definition at line 1099 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().
01100 { 01101 struct oh323_pvt *pvt; 01102 01103 pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt)); 01104 if (!pvt) { 01105 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n"); 01106 return NULL; 01107 } 01108 memset(pvt, 0, sizeof(struct oh323_pvt)); 01109 pvt->cd.redirect_reason = -1; 01110 pvt->cd.transfer_capability = -1; 01111 /* Ensure the call token is allocated for outgoing call */ 01112 if (!callid) { 01113 if ((pvt->cd).call_token == NULL) { 01114 (pvt->cd).call_token = (char *)malloc(128); 01115 } 01116 if (!pvt->cd.call_token) { 01117 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n"); 01118 ast_rtp_destroy(pvt->rtp); 01119 free(pvt); 01120 return NULL; 01121 } 01122 memset((char *)(pvt->cd).call_token, 0, 128); 01123 pvt->cd.call_reference = callid; 01124 } 01125 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01126 pvt->jointcapability = pvt->options.capability; 01127 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01128 pvt->nonCodecCapability |= AST_RTP_DTMF; 01129 } else { 01130 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01131 } 01132 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 01133 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1; 01134 ast_mutex_init(&pvt->lock); 01135 /* Add to interface list */ 01136 ast_mutex_lock(&iflock); 01137 pvt->next = iflist; 01138 iflist = pvt; 01139 ast_mutex_unlock(&iflock); 01140 return pvt; 01141 }
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 284 of file chan_h323.c.
References ast_log(), free, and LOG_DEBUG.
Referenced by delete_aliases(), load_module(), and unload_module().
00285 { 00286 if (h323debug) 00287 ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name); 00288 free(alias); 00289 }
static void oh323_destroy_peer | ( | struct oh323_peer * | peer | ) | [static] |
Definition at line 299 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().
00300 { 00301 if (h323debug) 00302 ast_log(LOG_DEBUG, "Destroying peer '%s'\n", peer->name); 00303 ast_free_ha(peer->ha); 00304 free(peer); 00305 }
static void oh323_destroy_user | ( | struct oh323_user * | user | ) | [static] |
Definition at line 291 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().
00292 { 00293 if (h323debug) 00294 ast_log(LOG_DEBUG, "Destroying user '%s'\n", user->name); 00295 ast_free_ha(user->ha); 00296 free(user); 00297 }
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 939 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.
00940 { 00941 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt; 00942 00943 ast_mutex_lock(&pvt->lock); 00944 if (pvt->owner != oldchan) { 00945 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner); 00946 return -1; 00947 } 00948 pvt->owner = newchan; 00949 ast_mutex_unlock(&pvt->lock); 00950 return 0; 00951 }
static enum ast_rtp_get_result oh323_get_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 3011 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.
03012 { 03013 struct oh323_pvt *pvt; 03014 enum ast_rtp_get_result res = AST_RTP_GET_FAILED; 03015 03016 if (!(pvt = (struct oh323_pvt *)chan->tech_pvt)) 03017 return res; 03018 03019 ast_mutex_lock(&pvt->lock); 03020 if (pvt->rtp && pvt->options.bridge) { 03021 *rtp = pvt->rtp; 03022 res = AST_RTP_TRY_NATIVE; 03023 } 03024 ast_mutex_unlock(&pvt->lock); 03025 03026 return res; 03027 }
static enum ast_rtp_get_result oh323_get_vrtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 3029 of file chan_h323.c.
References AST_RTP_GET_FAILED.
03030 { 03031 return AST_RTP_GET_FAILED; 03032 }
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_SRCUPDATE, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), 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_PROCEEDING: 00923 case -1: 00924 break; 00925 default: 00926 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token); 00927 break; 00928 } 00929 00930 if (h323debug) 00931 ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res); 00932 if (token) 00933 free(token); 00934 oh323_update_info(c); 00935 00936 return res; 00937 }
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 1671 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.
01672 { 01673 int oldformat; 01674 struct oh323_pvt *pvt; 01675 struct ast_channel *tmpc = NULL; 01676 char *dest = (char *)data; 01677 char *ext, *host; 01678 char *h323id = NULL; 01679 char tmp[256], tmp1[256]; 01680 01681 if (h323debug) 01682 ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data); 01683 01684 pvt = oh323_alloc(0); 01685 if (!pvt) { 01686 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data); 01687 return NULL; 01688 } 01689 oldformat = format; 01690 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 01691 if (!format) { 01692 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 01693 oh323_destroy(pvt); 01694 if (cause) 01695 *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 01696 return NULL; 01697 } 01698 ast_copy_string(tmp, dest, sizeof(tmp)); 01699 host = strchr(tmp, '@'); 01700 if (host) { 01701 *host = '\0'; 01702 host++; 01703 ext = tmp; 01704 } else { 01705 ext = strrchr(tmp, '/'); 01706 if (ext) 01707 *ext++ = '\0'; 01708 host = tmp; 01709 } 01710 strtok_r(host, "/", &(h323id)); 01711 if (!ast_strlen_zero(h323id)) { 01712 h323_set_id(h323id); 01713 } 01714 if (ext) { 01715 ast_copy_string(pvt->exten, ext, sizeof(pvt->exten)); 01716 } 01717 if (h323debug) 01718 ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host); 01719 01720 if (gatekeeper_disable) { 01721 if (create_addr(pvt, host)) { 01722 oh323_destroy(pvt); 01723 if (cause) 01724 *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01725 return NULL; 01726 } 01727 } 01728 else { 01729 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01730 pvt->jointcapability = pvt->options.capability; 01731 if (pvt->options.dtmfmode) { 01732 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01733 pvt->nonCodecCapability |= AST_RTP_DTMF; 01734 } else { 01735 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01736 } 01737 } 01738 } 01739 01740 ast_mutex_lock(&caplock); 01741 /* Generate unique channel identifier */ 01742 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique); 01743 tmp1[sizeof(tmp1)-1] = '\0'; 01744 ast_mutex_unlock(&caplock); 01745 01746 ast_mutex_lock(&pvt->lock); 01747 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1); 01748 ast_mutex_unlock(&pvt->lock); 01749 if (!tmpc) { 01750 oh323_destroy(pvt); 01751 if (cause) 01752 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 01753 } 01754 ast_update_use_count(); 01755 restart_monitor(); 01756 return tmpc; 01757 }
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 3061 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.
03062 { 03063 /* XXX Deal with Video */ 03064 struct oh323_pvt *pvt; 03065 struct sockaddr_in them; 03066 struct sockaddr_in us; 03067 char *mode; 03068 03069 if (!rtp) { 03070 return 0; 03071 } 03072 03073 mode = convertcap(chan->writeformat); 03074 pvt = (struct oh323_pvt *) chan->tech_pvt; 03075 if (!pvt) { 03076 ast_log(LOG_ERROR, "No Private Structure, this is bad\n"); 03077 return -1; 03078 } 03079 ast_rtp_get_peer(rtp, &them); 03080 ast_rtp_get_us(rtp, &us); 03081 #if 0 /* Native bridge still isn't ready */ 03082 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode); 03083 #endif 03084 return 0; 03085 }
static int oh323_simulate_dtmf_end | ( | const void * | data | ) | [static] |
Definition at line 307 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(), and f.
Referenced by __oh323_update_info(), and receive_digit().
00308 { 00309 struct oh323_pvt *pvt = (struct oh323_pvt *)data; 00310 00311 if (pvt) { 00312 ast_mutex_lock(&pvt->lock); 00313 /* Don't hold pvt lock while trying to lock the channel */ 00314 while(pvt->owner && ast_channel_trylock(pvt->owner)) { 00315 ast_mutex_unlock(&pvt->lock); 00316 usleep(1); 00317 ast_mutex_lock(&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 2025 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().
02026 { 02027 struct oh323_pvt *pvt; 02028 02029 if (h323debug) 02030 ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated")); 02031 02032 pvt = find_call_locked(call_reference, token); 02033 if (!pvt) { 02034 ast_log(LOG_ERROR, "Private structure not found in progress.\n"); 02035 return -1; 02036 } 02037 if (!pvt->owner) { 02038 ast_mutex_unlock(&pvt->lock); 02039 ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n"); 02040 return -1; 02041 } 02042 update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING)); 02043 ast_mutex_unlock(&pvt->lock); 02044 02045 return 0; 02046 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 2752 of file chan_h323.c.
References ASTOBJ_CONTAINER_PRUNE_MARKED, oh323_destroy_peer(), and peerl.
Referenced by reload_config(), set_config(), and unload_module().
02753 { 02754 /* Prune peers who still are supposed to be deleted */ 02755 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer); 02756 }
static struct oh323_alias* realtime_alias | ( | const char * | alias | ) | [static] |
Definition at line 1225 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().
01226 { 01227 struct ast_variable *var, *tmp; 01228 struct oh323_alias *a; 01229 01230 var = ast_load_realtime("h323", "name", alias, NULL); 01231 01232 if (!var) 01233 return NULL; 01234 01235 for (tmp = var; tmp; tmp = tmp->next) { 01236 if (!strcasecmp(tmp->name, "type") && 01237 !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) { 01238 ast_variables_destroy(var); 01239 return NULL; 01240 } 01241 } 01242 01243 a = build_alias(alias, var, NULL, 1); 01244 01245 ast_variables_destroy(var); 01246 01247 return a; 01248 }
static struct oh323_peer* realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 1503 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(), find_peer(), and iax2_getpeername().
01504 { 01505 struct oh323_peer *peer; 01506 struct ast_variable *var; 01507 struct ast_variable *tmp; 01508 const char *addr; 01509 01510 /* First check on peer name */ 01511 if (peername) 01512 var = ast_load_realtime("h323", "name", peername, addr = NULL); 01513 else if (sin) /* Then check on IP address for dynamic peers */ 01514 var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), NULL); 01515 else 01516 return NULL; 01517 01518 if (!var) 01519 return NULL; 01520 01521 for (tmp = var; tmp; tmp = tmp->next) { 01522 /* If this is type=user, then skip this object. */ 01523 if (!strcasecmp(tmp->name, "type") && 01524 !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) { 01525 ast_variables_destroy(var); 01526 return NULL; 01527 } else if (!peername && !strcasecmp(tmp->name, "name")) { 01528 peername = tmp->value; 01529 } 01530 } 01531 01532 if (!peername) { /* Did not find peer in realtime */ 01533 ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr); 01534 ast_variables_destroy(var); 01535 return NULL; 01536 } 01537 01538 /* Peer found in realtime, now build it in memory */ 01539 peer = build_peer(peername, var, NULL, 1); 01540 01541 ast_variables_destroy(var); 01542 01543 return peer; 01544 }
static struct oh323_user* realtime_user | ( | const call_details_t * | cd | ) | [static] |
Definition at line 1401 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 check_access(), and find_user().
01402 { 01403 struct ast_variable *var, *tmp; 01404 struct oh323_user *user; 01405 char *username; 01406 01407 if (userbyalias) 01408 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL); 01409 else { 01410 username = (char *)NULL; 01411 var = ast_load_realtime("h323", "host", cd->sourceIp, NULL); 01412 } 01413 01414 if (!var) 01415 return NULL; 01416 01417 for (tmp = var; tmp; tmp = tmp->next) { 01418 if (!strcasecmp(tmp->name, "type") && 01419 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) { 01420 ast_variables_destroy(var); 01421 return NULL; 01422 } else if (!username && !strcasecmp(tmp->name, "name")) 01423 username = tmp->value; 01424 } 01425 01426 if (!username) { 01427 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp); 01428 ast_variables_destroy(var); 01429 return NULL; 01430 } 01431 01432 user = build_user(username, var, NULL, 1); 01433 01434 ast_variables_destroy(var); 01435 01436 return user; 01437 }
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 1776 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().
01777 { 01778 struct oh323_pvt *pvt; 01779 int res; 01780 01781 pvt = find_call_locked(call_reference, token); 01782 if (!pvt) { 01783 ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token); 01784 return -1; 01785 } 01786 if (h323debug) 01787 ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token); 01788 01789 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01790 if (digit == '!') 01791 res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH); 01792 else { 01793 struct ast_frame f = { 01794 .frametype = AST_FRAME_DTMF_END, 01795 .subclass = digit, 01796 .samples = duration * 8, 01797 .len = duration, 01798 .src = "SEND_DIGIT", 01799 }; 01800 if (digit == ' ') { /* signalUpdate message */ 01801 f.subclass = pvt->curDTMF; 01802 AST_SCHED_DEL(sched, pvt->DTMFsched); 01803 } else { /* Regular input or signal message */ 01804 if (pvt->DTMFsched >= 0) { 01805 /* We still don't send DTMF END from previous event, send it now */ 01806 AST_SCHED_DEL(sched, pvt->DTMFsched); 01807 f.subclass = pvt->curDTMF; 01808 f.samples = f.len = 0; 01809 ast_queue_frame(pvt->owner, &f); 01810 /* Restore values */ 01811 f.subclass = digit; 01812 f.samples = duration * 8; 01813 f.len = duration; 01814 } 01815 if (duration) { /* This is a signal, signalUpdate follows */ 01816 f.frametype = AST_FRAME_DTMF_BEGIN; 01817 pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt); 01818 if (h323debug) 01819 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched); 01820 } 01821 pvt->curDTMF = digit; 01822 } 01823 res = ast_queue_frame(pvt->owner, &f); 01824 } 01825 ast_channel_unlock(pvt->owner); 01826 } else { 01827 if (digit == '!') 01828 pvt->newcontrol = AST_CONTROL_FLASH; 01829 else { 01830 pvt->newduration = duration; 01831 pvt->newdigit = digit; 01832 } 01833 res = 0; 01834 } 01835 ast_mutex_unlock(&pvt->lock); 01836 return res; 01837 }
static const char* redirectingreason2str | ( | int | redirectingreason | ) | [static] |
Definition at line 268 of file chan_h323.c.
00269 { 00270 switch (redirectingreason) { 00271 case 0: 00272 return "UNKNOWN"; 00273 case 1: 00274 return "BUSY"; 00275 case 2: 00276 return "NO_REPLY"; 00277 case 0xF: 00278 return "UNCONDITIONAL"; 00279 default: 00280 return "NOREDIRECT"; 00281 } 00282 }
static int reload | ( | void | ) | [static] |
Definition at line 2996 of file chan_h323.c.
References ast_log(), h323_reload(), io, and LOG_NOTICE.
02997 { 02998 if (!sched || !io) { 02999 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n"); 03000 return 0; 03001 } 03002 return h323_reload(0, 0, NULL); 03003 }
static int reload_config | ( | int | is_reload | ) | [static] |
Definition at line 2758 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_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), misdn_reload(), reload(), and sip_do_reload().
02759 { 02760 int format; 02761 struct ast_config *cfg, *ucfg; 02762 struct ast_variable *v; 02763 struct oh323_peer *peer = NULL; 02764 struct oh323_user *user = NULL; 02765 struct oh323_alias *alias = NULL; 02766 struct ast_hostent ahp; struct hostent *hp; 02767 char *cat; 02768 const char *utype; 02769 int is_user, is_peer, is_alias; 02770 char _gatekeeper[100]; 02771 int gk_discover, gk_disable, gk_changed; 02772 02773 cfg = ast_config_load(config); 02774 02775 /* We *must* have a config file otherwise stop immediately */ 02776 if (!cfg) { 02777 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02778 return 1; 02779 } 02780 02781 if (is_reload) { 02782 delete_users(); 02783 delete_aliases(); 02784 prune_peers(); 02785 } 02786 02787 /* fire up the H.323 Endpoint */ 02788 if (!h323_end_point_exist()) { 02789 h323_end_point_create(); 02790 } 02791 ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper)); 02792 gk_discover = gatekeeper_discover; 02793 gk_disable = gatekeeper_disable; 02794 memset(&bindaddr, 0, sizeof(bindaddr)); 02795 memset(&global_options, 0, sizeof(global_options)); 02796 global_options.fastStart = 1; 02797 global_options.h245Tunneling = 1; 02798 global_options.dtmfcodec = 101; 02799 global_options.dtmfmode = H323_DTMF_RFC2833; 02800 global_options.capability = GLOBAL_CAPABILITY; 02801 global_options.bridge = 1; /* Do native bridging by default */ 02802 strcpy(default_context, "default"); 02803 h323_signalling_port = 1720; 02804 gatekeeper_disable = 1; 02805 gatekeeper_discover = 0; 02806 gkroute = 0; 02807 userbyalias = 1; 02808 acceptAnonymous = 1; 02809 tos = 0; 02810 02811 /* Copy the default jb config over global_jbconf */ 02812 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 02813 02814 /* Load configuration from users.conf */ 02815 ucfg = ast_config_load("users.conf"); 02816 if (ucfg) { 02817 struct ast_variable *gen; 02818 int genhas_h323; 02819 const char *has_h323; 02820 02821 genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323")); 02822 gen = ast_variable_browse(ucfg, "general"); 02823 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) { 02824 if (strcasecmp(cat, "general")) { 02825 has_h323 = ast_variable_retrieve(ucfg, cat, "hash323"); 02826 if (ast_true(has_h323) || (!has_h323 && genhas_h323)) { 02827 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 02828 if (user) { 02829 ASTOBJ_CONTAINER_LINK(&userl, user); 02830 ASTOBJ_UNREF(user, oh323_destroy_user); 02831 } 02832 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 02833 if (peer) { 02834 ASTOBJ_CONTAINER_LINK(&peerl, peer); 02835 ASTOBJ_UNREF(peer, oh323_destroy_peer); 02836 } 02837 } 02838 } 02839 } 02840 ast_config_destroy(ucfg); 02841 } 02842 02843 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 02844 /* handle jb conf */ 02845 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 02846 continue; 02847 /* Create the interface list */ 02848 if (!strcasecmp(v->name, "port")) { 02849 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02850 } else if (!strcasecmp(v->name, "bindaddr")) { 02851 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02852 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02853 } else { 02854 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02855 } 02856 } else if (!strcasecmp(v->name, "tos")) { 02857 if (sscanf(v->value, "%d", &format)) { 02858 tos = format & 0xff; 02859 } else if (!strcasecmp(v->value, "lowdelay")) { 02860 tos = IPTOS_LOWDELAY; 02861 } else if (!strcasecmp(v->value, "throughput")) { 02862 tos = IPTOS_THROUGHPUT; 02863 } else if (!strcasecmp(v->value, "reliability")) { 02864 tos = IPTOS_RELIABILITY; 02865 } else if (!strcasecmp(v->value, "mincost")) { 02866 tos = IPTOS_MINCOST; 02867 } else if (!strcasecmp(v->value, "none")) { 02868 tos = 0; 02869 } else { 02870 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02871 } 02872 } else if (!strcasecmp(v->name, "gatekeeper")) { 02873 if (!strcasecmp(v->value, "DISABLE")) { 02874 gatekeeper_disable = 1; 02875 } else if (!strcasecmp(v->value, "DISCOVER")) { 02876 gatekeeper_disable = 0; 02877 gatekeeper_discover = 1; 02878 } else { 02879 gatekeeper_disable = 0; 02880 ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper)); 02881 } 02882 } else if (!strcasecmp(v->name, "secret")) { 02883 ast_copy_string(secret, v->value, sizeof(secret)); 02884 } else if (!strcasecmp(v->name, "AllowGKRouted")) { 02885 gkroute = ast_true(v->value); 02886 } else if (!strcasecmp(v->name, "context")) { 02887 ast_copy_string(default_context, v->value, sizeof(default_context)); 02888 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context); 02889 } else if (!strcasecmp(v->name, "UserByAlias")) { 02890 userbyalias = ast_true(v->value); 02891 } else if (!strcasecmp(v->name, "AcceptAnonymous")) { 02892 acceptAnonymous = ast_true(v->value); 02893 } else if (!update_common_options(v, &global_options)) { 02894 /* dummy */ 02895 } 02896 } 02897 02898 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) { 02899 if (strcasecmp(cat, "general")) { 02900 utype = ast_variable_retrieve(cfg, cat, "type"); 02901 if (utype) { 02902 is_user = is_peer = is_alias = 0; 02903 if (!strcasecmp(utype, "user")) 02904 is_user = 1; 02905 else if (!strcasecmp(utype, "peer")) 02906 is_peer = 1; 02907 else if (!strcasecmp(utype, "friend")) 02908 is_user = is_peer = 1; 02909 else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) 02910 is_alias = 1; 02911 else { 02912 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config); 02913 continue; 02914 } 02915 if (is_user) { 02916 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 02917 if (user) { 02918 ASTOBJ_CONTAINER_LINK(&userl, user); 02919 ASTOBJ_UNREF(user, oh323_destroy_user); 02920 } 02921 } 02922 if (is_peer) { 02923 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 02924 if (peer) { 02925 ASTOBJ_CONTAINER_LINK(&peerl, peer); 02926 ASTOBJ_UNREF(peer, oh323_destroy_peer); 02927 } 02928 } 02929 if (is_alias) { 02930 alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0); 02931 if (alias) { 02932 ASTOBJ_CONTAINER_LINK(&aliasl, alias); 02933 ASTOBJ_UNREF(alias, oh323_destroy_alias); 02934 } 02935 } 02936 } else { 02937 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 02938 } 02939 } 02940 } 02941 ast_config_destroy(cfg); 02942 02943 /* Register our H.323 aliases if any*/ 02944 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 02945 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 02946 ASTOBJ_RDLOCK(iterator); 02947 if (h323_set_alias(iterator)) { 02948 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name); 02949 ASTOBJ_UNLOCK(iterator); 02950 continue; 02951 } 02952 ASTOBJ_UNLOCK(iterator); 02953 } while (0) ); 02954 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 02955 02956 /* Don't touch GK if nothing changed because URQ will drop all existing calls */ 02957 gk_changed = 0; 02958 if (gatekeeper_disable != gk_disable) 02959 gk_changed = is_reload; 02960 else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover)) 02961 gk_changed = is_reload; 02962 else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0)) 02963 gk_changed = is_reload; 02964 if (gk_changed) { 02965 if(!gk_disable) 02966 h323_gk_urq(); 02967 if (!gatekeeper_disable) { 02968 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 02969 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 02970 gatekeeper_disable = 1; 02971 } 02972 } 02973 } 02974 return 0; 02975 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 2511 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.
02512 { 02513 /* If we're supposed to be stopped -- stay stopped */ 02514 if (ast_mutex_lock(&monlock)) { 02515 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 02516 return -1; 02517 } 02518 if (monitor_thread == AST_PTHREADT_STOP) { 02519 ast_mutex_unlock(&monlock); 02520 return 0; 02521 } 02522 if (monitor_thread == pthread_self()) { 02523 ast_mutex_unlock(&monlock); 02524 ast_log(LOG_WARNING, "Cannot kill myself\n"); 02525 return -1; 02526 } 02527 if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) { 02528 /* Wake up the thread */ 02529 pthread_kill(monitor_thread, SIGURG); 02530 } else { 02531 /* Start a new monitor */ 02532 if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) { 02533 monitor_thread = AST_PTHREADT_NULL; 02534 ast_mutex_unlock(&monlock); 02535 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 02536 return -1; 02537 } 02538 } 02539 ast_mutex_unlock(&monlock); 02540 return 0; 02541 }
static void set_dtmf_payload | ( | unsigned | call_reference, | |
const char * | token, | |||
int | payload | |||
) | [static] |
Definition at line 2370 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().
02371 { 02372 struct oh323_pvt *pvt; 02373 02374 if (h323debug) 02375 ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token); 02376 02377 pvt = find_call_locked(call_reference, token); 02378 if (!pvt) { 02379 return; 02380 } 02381 if (pvt->rtp) { 02382 ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event", 0); 02383 } 02384 pvt->dtmf_pt = payload; 02385 ast_mutex_unlock(&pvt->lock); 02386 if (h323debug) 02387 ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload); 02388 }
static void set_local_capabilities | ( | unsigned | call_reference, | |
const char * | token | |||
) | [static] |
Definition at line 2418 of file chan_h323.c.
References ast_log(), ast_mutex_unlock(), capability, dtmfmode, find_call_locked(), h323debug, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, oh323_pvt::options, oh323_pvt::pref_codec, and prefs.
Referenced by load_module().
02419 { 02420 struct oh323_pvt *pvt; 02421 int capability, dtmfmode, pref_codec; 02422 struct ast_codec_pref prefs; 02423 02424 if (h323debug) 02425 ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token); 02426 02427 pvt = find_call_locked(call_reference, token); 02428 if (!pvt) 02429 return; 02430 capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability; 02431 dtmfmode = pvt->options.dtmfmode; 02432 prefs = pvt->options.prefs; 02433 pref_codec = pvt->pref_codec; 02434 ast_mutex_unlock(&pvt->lock); 02435 h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec); 02436 02437 if (h323debug) 02438 ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token); 02439 }
static void set_peer_capabilities | ( | unsigned | call_reference, | |
const char * | token, | |||
int | capabilities, | |||
struct ast_codec_pref * | prefs | |||
) | [static] |
Definition at line 2390 of file chan_h323.c.
References ast_getformatname(), ast_log(), ast_mutex_unlock(), ast_rtp_codec_setpref(), 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::peer_prefs, oh323_pvt::peercapability, prefs, and oh323_pvt::rtp.
Referenced by load_module().
02391 { 02392 struct oh323_pvt *pvt; 02393 02394 if (h323debug) 02395 ast_log(LOG_DEBUG, "Got remote capabilities from connection %s\n", token); 02396 02397 pvt = find_call_locked(call_reference, token); 02398 if (!pvt) 02399 return; 02400 pvt->peercapability = capabilities; 02401 pvt->jointcapability = pvt->options.capability & capabilities; 02402 if (prefs) { 02403 memcpy(&pvt->peer_prefs, prefs, sizeof(pvt->peer_prefs)); 02404 if (h323debug) { 02405 int i; 02406 for (i = 0; i < 32; ++i) { 02407 if (!prefs->order[i]) 02408 break; 02409 ast_log(LOG_DEBUG, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]); 02410 } 02411 } 02412 if (pvt->rtp) 02413 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 02414 } 02415 ast_mutex_unlock(&pvt->lock); 02416 }
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 2053 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().
02054 { 02055 struct oh323_pvt *pvt; 02056 struct oh323_user *user = NULL; 02057 struct oh323_alias *alias = NULL; 02058 02059 if (h323debug) 02060 ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token); 02061 02062 /* allocate the call*/ 02063 pvt = oh323_alloc(cd->call_reference); 02064 02065 if (!pvt) { 02066 ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n"); 02067 cleanup_call_details(cd); 02068 return NULL; 02069 } 02070 02071 /* Populate the call details in the private structure */ 02072 memcpy(&pvt->cd, cd, sizeof(pvt->cd)); 02073 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 02074 pvt->jointcapability = pvt->options.capability; 02075 02076 if (h323debug) { 02077 ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n"); 02078 ast_verbose(VERBOSE_PREFIX_3 " \tCall token: [%s]\n", pvt->cd.call_token); 02079 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party name: [%s]\n", pvt->cd.call_source_name); 02080 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party number: [%s]\n", pvt->cd.call_source_e164); 02081 ast_verbose(VERBOSE_PREFIX_3 " \tCalled party name: [%s]\n", pvt->cd.call_dest_alias); 02082 ast_verbose(VERBOSE_PREFIX_3 " \tCalled party number: [%s]\n", pvt->cd.call_dest_e164); 02083 if (pvt->cd.redirect_reason >= 0) 02084 ast_verbose(VERBOSE_PREFIX_3 " \tRedirecting party number: [%s] (reason %d)\n", pvt->cd.redirect_number, pvt->cd.redirect_reason); 02085 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party IP: [%s]\n", pvt->cd.sourceIp); 02086 } 02087 02088 /* Decide if we are allowing Gatekeeper routed calls*/ 02089 if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) { 02090 if (!ast_strlen_zero(cd->call_dest_e164)) { 02091 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02092 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02093 } else { 02094 alias = find_alias(cd->call_dest_alias, 1); 02095 if (!alias) { 02096 ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias); 02097 oh323_destroy(pvt); 02098 return NULL; 02099 } 02100 ast_copy_string(pvt->exten, alias->name, sizeof(pvt->exten)); 02101 ast_copy_string(pvt->context, alias->context, sizeof(pvt->context)); 02102 } 02103 } else { 02104 /* Either this call is not from the Gatekeeper 02105 or we are not allowing gk routed calls */ 02106 user = find_user(cd, 1); 02107 if (!user) { 02108 if (!acceptAnonymous) { 02109 ast_log(LOG_NOTICE, "Anonymous call from '%s@%s' rejected\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp); 02110 oh323_destroy(pvt); 02111 return NULL; 02112 } 02113 if (ast_strlen_zero(default_context)) { 02114 ast_log(LOG_ERROR, "Call from '%s@%s' rejected due to no default context\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp); 02115 oh323_destroy(pvt); 02116 return NULL; 02117 } 02118 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02119 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { 02120 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02121 } else { 02122 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten)); 02123 } 02124 if (h323debug) 02125 ast_log(LOG_DEBUG, "Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->context, pvt->exten); 02126 } else { 02127 if (user->host) { 02128 if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) { 02129 if (ast_strlen_zero(user->context)) { 02130 if (ast_strlen_zero(default_context)) { 02131 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp); 02132 oh323_destroy(pvt); 02133 ASTOBJ_UNREF(user, oh323_destroy_user); 02134 return NULL; 02135 } 02136 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02137 } else { 02138 ast_copy_string(pvt->context, user->context, sizeof(pvt->context)); 02139 } 02140 pvt->exten[0] = 'i'; 02141 pvt->exten[1] = '\0'; 02142 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp); 02143 oh323_destroy(pvt); 02144 ASTOBJ_UNREF(user, oh323_destroy_user); 02145 return NULL; /* XXX: Hmmm... Why to setup context if we drop connection immediately??? */ 02146 } 02147 } 02148 ast_copy_string(pvt->context, user->context, sizeof(pvt->context)); 02149 memcpy(&pvt->options, &user->options, sizeof(pvt->options)); 02150 pvt->jointcapability = pvt->options.capability; 02151 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { 02152 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02153 } else { 02154 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten)); 02155 } 02156 if (!ast_strlen_zero(user->accountcode)) { 02157 ast_copy_string(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode)); 02158 } 02159 if (user->amaflags) { 02160 pvt->amaflags = user->amaflags; 02161 } 02162 ASTOBJ_UNREF(user, oh323_destroy_user); 02163 } 02164 } 02165 return &pvt->options; 02166 }
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 2252 of file chan_h323.c.
References cleanup_call_details().
Referenced by load_module().
02253 { 02254 /* Use argument here or free it immediately */ 02255 cleanup_call_details(cd); 02256 02257 return 1; 02258 }
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 1893 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().
01894 { 01895 struct oh323_pvt *pvt; 01896 struct sockaddr_in them; 01897 struct rtpPayloadType rtptype; 01898 int nativeformats_changed; 01899 enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE; 01900 01901 if (h323debug) 01902 ast_log(LOG_DEBUG, "Setting up RTP connection for %s\n", token); 01903 01904 /* Find the call or allocate a private structure if call not found */ 01905 pvt = find_call_locked(call_reference, token); 01906 if (!pvt) { 01907 ast_log(LOG_ERROR, "Something is wrong: rtp\n"); 01908 return; 01909 } 01910 if (pvt->alreadygone) { 01911 ast_mutex_unlock(&pvt->lock); 01912 return; 01913 } 01914 01915 if (!pvt->rtp) 01916 __oh323_rtp_create(pvt); 01917 01918 them.sin_family = AF_INET; 01919 /* only works for IPv4 */ 01920 them.sin_addr.s_addr = inet_addr(remoteIp); 01921 them.sin_port = htons(remotePort); 01922 01923 if (them.sin_addr.s_addr) { 01924 ast_rtp_set_peer(pvt->rtp, &them); 01925 if (pvt->recvonly) { 01926 pvt->recvonly = 0; 01927 rtp_change = NEED_UNHOLD; 01928 } 01929 } else { 01930 ast_rtp_stop(pvt->rtp); 01931 if (!pvt->recvonly) { 01932 pvt->recvonly = 1; 01933 rtp_change = NEED_HOLD; 01934 } 01935 } 01936 01937 /* Change native format to reflect information taken from OLC/OLCAck */ 01938 nativeformats_changed = 0; 01939 if (pt != 128 && pvt->rtp) { /* Payload type is invalid, so try to use previously decided */ 01940 rtptype = ast_rtp_lookup_pt(pvt->rtp, pt); 01941 if (h323debug) 01942 ast_log(LOG_DEBUG, "Native format is set to %d from %d by RTP payload type %d\n", rtptype.code, pvt->nativeformats, pt); 01943 if (pvt->nativeformats != rtptype.code) { 01944 pvt->nativeformats = rtptype.code; 01945 nativeformats_changed = 1; 01946 } 01947 } else if (h323debug) 01948 ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n"); 01949 01950 /* Don't try to lock the channel if nothing changed */ 01951 if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) { 01952 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01953 /* Re-build translation path only if native format(s) has been changed */ 01954 if (pvt->owner->nativeformats != pvt->nativeformats) { 01955 if (h323debug) 01956 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); 01957 pvt->owner->nativeformats = pvt->nativeformats; 01958 ast_set_read_format(pvt->owner, pvt->owner->readformat); 01959 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 01960 } 01961 if (pvt->options.progress_audio) 01962 ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS); 01963 switch (rtp_change) { 01964 case NEED_HOLD: 01965 ast_queue_control(pvt->owner, AST_CONTROL_HOLD); 01966 break; 01967 case NEED_UNHOLD: 01968 ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD); 01969 break; 01970 default: 01971 break; 01972 } 01973 ast_channel_unlock(pvt->owner); 01974 } 01975 else { 01976 if (pvt->options.progress_audio) 01977 pvt->newcontrol = AST_CONTROL_PROGRESS; 01978 else if (rtp_change == NEED_HOLD) 01979 pvt->newcontrol = AST_CONTROL_HOLD; 01980 else if (rtp_change == NEED_UNHOLD) 01981 pvt->newcontrol = AST_CONTROL_UNHOLD; 01982 if (h323debug) 01983 ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token); 01984 } 01985 } 01986 ast_mutex_unlock(&pvt->lock); 01987 01988 if (h323debug) 01989 ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token); 01990 01991 return; 01992 }
static int unload_module | ( | void | ) | [static] |
Definition at line 3196 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.
03197 { 03198 struct oh323_pvt *p, *pl; 03199 03200 /* unregister commands */ 03201 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03202 ast_cli_unregister(&cli_h323_reload); 03203 03204 ast_channel_unregister(&oh323_tech); 03205 ast_rtp_proto_unregister(&oh323_rtp); 03206 03207 if (!ast_mutex_lock(&iflock)) { 03208 /* hangup all interfaces if they have an owner */ 03209 p = iflist; 03210 while(p) { 03211 if (p->owner) { 03212 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 03213 } 03214 p = p->next; 03215 } 03216 iflist = NULL; 03217 ast_mutex_unlock(&iflock); 03218 } else { 03219 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 03220 return -1; 03221 } 03222 if (!ast_mutex_lock(&monlock)) { 03223 if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 03224 if (monitor_thread != pthread_self()) { 03225 pthread_cancel(monitor_thread); 03226 } 03227 pthread_kill(monitor_thread, SIGURG); 03228 pthread_join(monitor_thread, NULL); 03229 } 03230 monitor_thread = AST_PTHREADT_STOP; 03231 ast_mutex_unlock(&monlock); 03232 } else { 03233 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03234 return -1; 03235 } 03236 if (!ast_mutex_lock(&iflock)) { 03237 /* destroy all the interfaces and free their memory */ 03238 p = iflist; 03239 while(p) { 03240 pl = p; 03241 p = p->next; 03242 /* free associated memory */ 03243 ast_mutex_destroy(&pl->lock); 03244 free(pl); 03245 } 03246 iflist = NULL; 03247 ast_mutex_unlock(&iflock); 03248 } else { 03249 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 03250 return -1; 03251 } 03252 if (!gatekeeper_disable) 03253 h323_gk_urq(); 03254 h323_end_process(); 03255 if (io) 03256 io_context_destroy(io); 03257 if (sched) 03258 sched_context_destroy(sched); 03259 03260 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03261 ASTOBJ_CONTAINER_DESTROY(&userl); 03262 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03263 ASTOBJ_CONTAINER_DESTROY(&peerl); 03264 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03265 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03266 03267 return 0; 03268 }
static int update_common_options | ( | struct ast_variable * | v, | |
struct call_options * | options | |||
) | [static] |
Definition at line 1253 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().
01254 { 01255 int tmp; 01256 01257 if (!strcasecmp(v->name, "allow")) { 01258 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1); 01259 } else if (!strcasecmp(v->name, "disallow")) { 01260 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0); 01261 } else if (!strcasecmp(v->name, "dtmfmode")) { 01262 if (!strcasecmp(v->value, "inband")) { 01263 options->dtmfmode = H323_DTMF_INBAND; 01264 } else if (!strcasecmp(v->value, "rfc2833")) { 01265 options->dtmfmode = H323_DTMF_RFC2833; 01266 } else { 01267 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value); 01268 options->dtmfmode = H323_DTMF_RFC2833; 01269 } 01270 } else if (!strcasecmp(v->name, "dtmfcodec")) { 01271 tmp = atoi(v->value); 01272 if (tmp < 96) 01273 ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno); 01274 else 01275 options->dtmfcodec = tmp; 01276 } else if (!strcasecmp(v->name, "bridge")) { 01277 options->bridge = ast_true(v->value); 01278 } else if (!strcasecmp(v->name, "nat")) { 01279 options->nat = ast_true(v->value); 01280 } else if (!strcasecmp(v->name, "noFastStart")) { 01281 DEPRECATED(v, "fastStart"); 01282 options->fastStart = !ast_true(v->value); 01283 } else if (!strcasecmp(v->name, "fastStart")) { 01284 options->fastStart = ast_true(v->value); 01285 } else if (!strcasecmp(v->name, "noH245Tunneling")) { 01286 DEPRECATED(v, "h245Tunneling"); 01287 options->h245Tunneling = !ast_true(v->value); 01288 } else if (!strcasecmp(v->name, "h245Tunneling")) { 01289 options->h245Tunneling = ast_true(v->value); 01290 } else if (!strcasecmp(v->name, "noSilenceSuppression")) { 01291 DEPRECATED(v, "silenceSuppression"); 01292 options->silenceSuppression = !ast_true(v->value); 01293 } else if (!strcasecmp(v->name, "silenceSuppression")) { 01294 options->silenceSuppression = ast_true(v->value); 01295 } else if (!strcasecmp(v->name, "progress_setup")) { 01296 tmp = atoi(v->value); 01297 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) { 01298 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno); 01299 tmp = 0; 01300 } 01301 options->progress_setup = tmp; 01302 } else if (!strcasecmp(v->name, "progress_alert")) { 01303 tmp = atoi(v->value); 01304 if ((tmp != 0) && (tmp != 1) && (tmp != 8)) { 01305 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno); 01306 tmp = 0; 01307 } 01308 options->progress_alert = tmp; 01309 } else if (!strcasecmp(v->name, "progress_audio")) { 01310 options->progress_audio = ast_true(v->value); 01311 } else if (!strcasecmp(v->name, "callerid")) { 01312 ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num)); 01313 } else if (!strcasecmp(v->name, "fullname")) { 01314 ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name)); 01315 } else if (!strcasecmp(v->name, "cid_number")) { 01316 ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num)); 01317 } else if (!strcasecmp(v->name, "tunneling")) { 01318 if (!strcasecmp(v->value, "none")) 01319 options->tunnelOptions = 0; 01320 else if (!strcasecmp(v->value, "cisco")) 01321 options->tunnelOptions |= H323_TUNNEL_CISCO; 01322 else if (!strcasecmp(v->value, "qsig")) 01323 options->tunnelOptions |= H323_TUNNEL_QSIG; 01324 else 01325 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno); 01326 } else 01327 return 1; 01328 01329 return 0; 01330 }
static int update_state | ( | struct oh323_pvt * | pvt, | |
int | state, | |||
int | signal | |||
) | [static] |
Definition at line 1169 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().
01170 { 01171 if (!pvt) 01172 return 0; 01173 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01174 if (state >= 0) 01175 ast_setstate(pvt->owner, state); 01176 if (signal >= 0) 01177 ast_queue_control(pvt->owner, signal); 01178 ast_channel_unlock(pvt->owner); 01179 return 1; 01180 } 01181 else { 01182 if (state >= 0) 01183 pvt->newstate = state; 01184 if (signal >= 0) 01185 pvt->newcontrol = signal; 01186 return 0; 01187 } 01188 }
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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 3274 of file chan_h323.c.
int acceptAnonymous = 1 [static] |
Definition at line 151 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 3274 of file chan_h323.c.
struct sockaddr_in bindaddr [static] |
Definition at line 139 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 2663 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 2673 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 2658 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 2653 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 3005 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 2668 of file chan_h323.c.
const char config[] = "h323.conf" [static] |
Definition at line 137 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 2629 of file chan_h323.c.
char default_context[AST_MAX_CONTEXT] = "default" [static] |
Definition at line 138 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 126 of file chan_h323.c.
char gatekeeper[100] [static] |
Definition at line 145 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 146 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 147 of file chan_h323.c.
Referenced by h323_gk_cycle(), load_module(), and reload_config().
int gkroute = 0 [static] |
Definition at line 148 of file chan_h323.c.
Referenced by reload_config(), and setup_incoming_call().
struct ast_jb_conf global_jbconf [static] |
Definition at line 133 of file chan_h323.c.
call_options_t global_options [static] |
Definition at line 156 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 2649 of file chan_h323.c.
int h323_reloading = 0 [static] |
int h323_signalling_port = 1720 [static] |
H.323 configuration values
Definition at line 144 of file chan_h323.c.
Referenced by build_peer(), create_addr(), load_module(), and reload_config().
int h323debug |
Definition at line 123 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 217 of file chan_h323.c.
struct io_context* io [static] |
Definition at line 214 of file chan_h323.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
Definition at line 232 of file chan_h323.c.
ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 221 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 2633 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 2625 of file chan_h323.c.
struct ast_rtp_protocol oh323_rtp [static] |
struct ast_channel_tech oh323_tech [static] |
Definition at line 247 of file chan_h323.c.
Referenced by __oh323_new(), load_module(), and unload_module().
answer_call_cb on_answer_call |
Definition at line 115 of file chan_h323.c.
chan_ringing_cb on_chan_ringing |
Definition at line 112 of file chan_h323.c.
clear_con_cb on_connection_cleared |
Definition at line 114 of file chan_h323.c.
con_established_cb on_connection_established |
Definition at line 113 of file chan_h323.c.
on_rtp_cb on_external_rtp_create |
Definition at line 108 of file chan_h323.c.
hangup_cb on_hangup |
Definition at line 118 of file chan_h323.c.
setup_incoming_cb on_incoming_call |
Definition at line 110 of file chan_h323.c.
setup_outbound_cb on_outgoing_call |
Definition at line 111 of file chan_h323.c.
progress_cb on_progress |
Definition at line 116 of file chan_h323.c.
receive_digit_cb on_receive_digit |
Definition at line 107 of file chan_h323.c.
rfc2833_cb on_set_rfc2833_payload |
Definition at line 117 of file chan_h323.c.
setcapabilities_cb on_setcapabilities |
Definition at line 119 of file chan_h323.c.
setpeercapabilities_cb on_setpeercapabilities |
Definition at line 120 of file chan_h323.c.
start_rtp_cb on_start_rtp_channel |
Definition at line 109 of file chan_h323.c.
struct ast_peer_list peerl [static] |
Referenced by _sip_show_peers(), build_peer(), complete_sip_peer(), delete_users(), expire_register(), find_peer(), load_module(), prune_peers(), register_verify(), reload_config(), sip_do_reload(), sip_poke_all_peers(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), and unload_module().
struct sched_context* sched [static] |
Asterisk RTP stuff
Definition at line 213 of file chan_h323.c.
char secret[50] [static] |
Definition at line 153 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 2637 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 2641 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 2645 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 136 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 2621 of file chan_h323.c.
unsigned int unique = 0 [static] |
int userbyalias = 1 [static] |
Definition at line 150 of file chan_h323.c.
Referenced by find_user(), realtime_user(), and reload_config().
struct ast_user_list userl [static] |