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