#include "asterisk.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"
Include dependency graph for chan_h323.c:
Go to the source code of this file.
Data Structures | |
struct | ast_alias_list |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | oh323_pvt |
struct | rtpPayloadType |
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 int | answer_call (unsigned call_reference, const char *token) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"The NuFone Network's OpenH323 Channel Driver",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (h323_reload_lock) | |
AST_MUTEX_DEFINE_STATIC (caplock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
static struct oh323_alias * | build_alias (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
static struct oh323_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
static struct oh323_user * | build_user (char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
static void | chan_ringing (unsigned call_reference, const char *token) |
static void | cleanup_call_details (call_details_t *cd) |
static void | cleanup_connection (unsigned call_reference, const char *call_token) |
static void | connection_made (unsigned call_reference, const char *token) |
static char * | convertcap (int cap) |
static int | create_addr (struct oh323_pvt *pvt, char *opeer) |
static void | delete_aliases (void) |
static void | delete_users (void) |
static void * | do_monitor (void *data) |
static struct rtp_info * | external_rtp_create (unsigned call_reference, const char *token) |
static struct oh323_alias * | find_alias (const char *source_aliases, int realtime) |
static struct oh323_pvt * | find_call_locked (int call_reference, const char *token) |
static struct oh323_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
static struct oh323_user * | find_user (const call_details_t *cd, int realtime) |
static int | h323_do_debug (int fd, int argc, char *argv[]) |
static int | h323_do_reload (void) |
static int | h323_do_trace (int fd, int argc, char *argv[]) |
static int | h323_ep_hangup (int fd, int argc, char *argv[]) |
static int | h323_gk_cycle (int fd, int argc, char *argv[]) |
static int | h323_no_debug (int fd, int argc, char *argv[]) |
static int | h323_no_trace (int fd, int argc, char *argv[]) |
static int | h323_reload (int fd, int argc, char *argv[]) |
static int | h323_tokens_show (int fd, int argc, char *argv[]) |
static void | hangup_connection (unsigned int call_reference, const char *token, int cause) |
static enum ast_module_load_result | load_module (void) |
static int | oh323_addrcmp (struct sockaddr_in addr, struct sockaddr_in *sin) |
static int | oh323_addrcmp_str (struct in_addr inaddr, char *addr) |
static struct oh323_pvt * | oh323_alloc (int callid) |
static int | oh323_answer (struct ast_channel *c) |
static int | oh323_call (struct ast_channel *c, char *dest, int timeout) |
static void | oh323_destroy (struct oh323_pvt *pvt) |
static void | oh323_destroy_alias (struct oh323_alias *alias) |
static void | oh323_destroy_peer (struct oh323_peer *peer) |
static void | oh323_destroy_user (struct oh323_user *user) |
static int | oh323_digit_begin (struct ast_channel *c, char digit) |
static int | oh323_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | oh323_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static enum ast_rtp_get_result | oh323_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
static enum ast_rtp_get_result | oh323_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
static int | oh323_hangup (struct ast_channel *c) |
static int | oh323_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static struct ast_frame * | oh323_read (struct ast_channel *c) |
static struct ast_channel * | oh323_request (const char *type, int format, void *data, int *cause) |
static struct ast_frame * | oh323_rtp_read (struct oh323_pvt *pvt) |
static int | oh323_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
static int | oh323_simulate_dtmf_end (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 int | acceptAnonymous = 1 |
static struct ast_alias_list | aliasl |
static struct sockaddr_in | bindaddr |
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 char | h323_reload_usage [] |
static int | h323_reloading = 0 |
static int | h323_signalling_port = 1720 |
int | h323debug |
oh323_pvt * | iflist |
static struct io_context * | io |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
static char | no_debug_usage [] |
static char | no_trace_usage [] |
static struct ast_rtp_protocol | oh323_rtp |
static struct ast_channel_tech | oh323_tech |
answer_call_cb | on_answer_call |
chan_ringing_cb | on_chan_ringing |
clear_con_cb | on_connection_cleared |
con_established_cb | on_connection_established |
on_rtp_cb | on_external_rtp_create |
hangup_cb | on_hangup |
setup_incoming_cb | on_incoming_call |
setup_outbound_cb | on_outgoing_call |
progress_cb | on_progress |
receive_digit_cb | on_receive_digit |
rfc2833_cb | on_set_rfc2833_payload |
setcapabilities_cb | on_setcapabilities |
setpeercapabilities_cb | on_setpeercapabilities |
start_rtp_cb | on_start_rtp_channel |
static struct ast_peer_list | peerl |
static struct sched_context * | sched |
static char | secret [50] |
static char | show_cycle_usage [] |
static char | show_hangup_usage [] |
static char | show_tokens_usage [] |
static const char | tdesc [] = "The NuFone Network's Open H.323 Channel Driver" |
static int | tos = 0 |
static char | trace_usage [] |
static unsigned int | unique = 0 |
static int | userbyalias = 1 |
static struct ast_user_list | userl |
Definition in file chan_h323.c.
#define 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 451 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, oh323_pvt::next, oh323_pvt::owner, oh323_pvt::rtp, sched, ast_channel::tech_pvt, and oh323_pvt::vad.
Referenced by do_monitor(), and oh323_destroy().
00452 { 00453 struct oh323_pvt *cur, *prev = NULL; 00454 00455 if (pvt->DTMFsched >= 0) { 00456 ast_sched_del(sched, pvt->DTMFsched); 00457 pvt->DTMFsched = -1; 00458 } 00459 00460 if (pvt->rtp) { 00461 ast_rtp_destroy(pvt->rtp); 00462 } 00463 00464 /* Free dsp used for in-band DTMF detection */ 00465 if (pvt->vad) { 00466 ast_dsp_free(pvt->vad); 00467 } 00468 cleanup_call_details(&pvt->cd); 00469 00470 /* Unlink us from the owner if we have one */ 00471 if (pvt->owner) { 00472 ast_channel_lock(pvt->owner); 00473 if (h323debug) 00474 ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name); 00475 pvt->owner->tech_pvt = NULL; 00476 ast_channel_unlock(pvt->owner); 00477 } 00478 cur = iflist; 00479 while(cur) { 00480 if (cur == pvt) { 00481 if (prev) 00482 prev->next = cur->next; 00483 else 00484 iflist = cur->next; 00485 break; 00486 } 00487 prev = cur; 00488 cur = cur->next; 00489 } 00490 if (!cur) { 00491 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur); 00492 } else { 00493 ast_mutex_unlock(&pvt->lock); 00494 ast_mutex_destroy(&pvt->lock); 00495 free(pvt); 00496 } 00497 }
static struct ast_channel* __oh323_new | ( | struct oh323_pvt * | pvt, | |
int | state, | |||
const char * | host | |||
) | [static] |
Definition at line 999 of file chan_h323.c.
References accountcode, oh323_pvt::accountcode, ast_channel::amaflags, oh323_pvt::amaflags, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_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, ast_callerid::cid_name, cid_name, ast_callerid::cid_num, 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, fmt, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_WARNING, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_tech, oh323_pvt::options, oh323_pvt::owner, pbx_builtin_setvar_helper(), ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, redirectingreason2str(), ast_channel::rings, oh323_pvt::rtp, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, oh323_pvt::vad, and ast_channel::writeformat.
Referenced by answer_call(), and oh323_request().
01000 { 01001 struct ast_channel *ch; 01002 char *cid_num, *cid_name; 01003 int fmt; 01004 01005 if (!ast_strlen_zero(pvt->options.cid_num)) 01006 cid_num = pvt->options.cid_num; 01007 else 01008 cid_num = pvt->cd.call_source_e164; 01009 01010 if (!ast_strlen_zero(pvt->options.cid_name)) 01011 cid_name = pvt->options.cid_name; 01012 else 01013 cid_name = pvt->cd.call_source_name; 01014 01015 /* Don't hold a oh323_pvt lock while we allocate a chanel */ 01016 ast_mutex_unlock(&pvt->lock); 01017 ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host); 01018 /* Update usage counter */ 01019 ast_module_ref(ast_module_info->self); 01020 ast_mutex_lock(&pvt->lock); 01021 if (ch) { 01022 ch->tech = &oh323_tech; 01023 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability)) 01024 fmt = global_options.capability; 01025 ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/; 01026 pvt->nativeformats = ch->nativeformats; 01027 fmt = ast_best_codec(ch->nativeformats); 01028 ch->writeformat = fmt; 01029 ch->rawwriteformat = fmt; 01030 ch->readformat = fmt; 01031 ch->rawreadformat = fmt; 01032 #if 0 01033 ch->fds[0] = ast_rtp_fd(pvt->rtp); 01034 ch->fds[1] = ast_rtcp_fd(pvt->rtp); 01035 #endif 01036 #ifdef VIDEO_SUPPORT 01037 if (pvt->vrtp) { 01038 ch->fds[2] = ast_rtp_fd(pvt->vrtp); 01039 ch->fds[3] = ast_rtcp_fd(pvt->vrtp); 01040 } 01041 #endif 01042 #ifdef T38_SUPPORT 01043 if (pvt->udptl) { 01044 ch->fds[4] = ast_udptl_fd(pvt->udptl); 01045 } 01046 #endif 01047 if (state == AST_STATE_RING) { 01048 ch->rings = 1; 01049 } 01050 /* Allocate dsp for in-band DTMF support */ 01051 if (pvt->options.dtmfmode & H323_DTMF_INBAND) { 01052 pvt->vad = ast_dsp_new(); 01053 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT); 01054 } 01055 /* Register channel functions. */ 01056 ch->tech_pvt = pvt; 01057 /* Set the owner of this channel */ 01058 pvt->owner = ch; 01059 01060 ast_copy_string(ch->context, pvt->context, sizeof(ch->context)); 01061 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten)); 01062 ch->priority = 1; 01063 if (!ast_strlen_zero(pvt->accountcode)) { 01064 ast_string_field_set(ch, accountcode, pvt->accountcode); 01065 } 01066 if (pvt->amaflags) { 01067 ch->amaflags = pvt->amaflags; 01068 } 01069 01070 /* Don't use ast_set_callerid() here because it will 01071 * generate a needless NewCallerID event */ 01072 ch->cid.cid_num = ast_strdup(cid_num); 01073 ch->cid.cid_ani = ast_strdup(cid_num); 01074 ch->cid.cid_name = ast_strdup(cid_name); 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 953 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, ast_find_ourip(), ast_jb_configure(), ast_log(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), ast_rtcp_fd(), ast_rtp_codec_setpref(), ast_rtp_fd(), ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpmap_type(), ast_rtp_setnat(), ast_rtp_settos(), oh323_pvt::dtmf_pt, ast_channel::fds, global_jbconf, io, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, oh323_pvt::options, oh323_pvt::owner, oh323_pvt::peer_prefs, oh323_pvt::peercapability, oh323_pvt::rtp, sched, and oh323_pvt::update_rtp_info.
Referenced by external_rtp_create(), and setup_rtp_connection().
00954 { 00955 struct in_addr our_addr; 00956 00957 if (pvt->rtp) 00958 return 0; 00959 00960 if (ast_find_ourip(&our_addr, bindaddr)) { 00961 ast_mutex_unlock(&pvt->lock); 00962 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n"); 00963 return -1; 00964 } 00965 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr); 00966 if (!pvt->rtp) { 00967 ast_mutex_unlock(&pvt->lock); 00968 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); 00969 return -1; 00970 } 00971 if (h323debug) 00972 ast_log(LOG_DEBUG, "Created RTP channel\n"); 00973 00974 ast_rtp_settos(pvt->rtp, tos); 00975 00976 if (h323debug) 00977 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat); 00978 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00979 00980 if (pvt->dtmf_pt > 0) 00981 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0); 00982 00983 if (pvt->peercapability) 00984 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 00985 00986 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 00987 ast_jb_configure(pvt->owner, &global_jbconf); 00988 pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp); 00989 pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp); 00990 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00991 ast_channel_unlock(pvt->owner); 00992 } else 00993 pvt->update_rtp_info = 1; 00994 00995 return 0; 00996 }
static void __oh323_update_info | ( | struct ast_channel * | c, | |
struct oh323_pvt * | pvt | |||
) | [static] |
Definition at line 338 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, 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().
00339 { 00340 if (c->nativeformats != pvt->nativeformats) { 00341 if (h323debug) 00342 ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name); 00343 c->nativeformats = pvt->nativeformats; 00344 ast_set_read_format(c, c->readformat); 00345 ast_set_write_format(c, c->writeformat); 00346 } 00347 if (pvt->needhangup) { 00348 if (h323debug) 00349 ast_log(LOG_DEBUG, "Process pending hangup for %s\n", c->name); 00350 c->_softhangup |= AST_SOFTHANGUP_DEV; 00351 c->hangupcause = pvt->hangupcause; 00352 ast_queue_hangup(c); 00353 pvt->needhangup = 0; 00354 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1; 00355 } 00356 if (pvt->newstate >= 0) { 00357 ast_setstate(c, pvt->newstate); 00358 pvt->newstate = -1; 00359 } 00360 if (pvt->newcontrol >= 0) { 00361 ast_queue_control(c, pvt->newcontrol); 00362 pvt->newcontrol = -1; 00363 } 00364 if (pvt->newdigit >= 0) { 00365 struct ast_frame f = { 00366 .frametype = AST_FRAME_DTMF_END, 00367 .subclass = pvt->newdigit, 00368 .samples = pvt->newduration * 8, 00369 .len = pvt->newduration, 00370 .src = "UPDATE_INFO", 00371 }; 00372 if (pvt->newdigit == ' ') { /* signalUpdate message */ 00373 f.subclass = pvt->curDTMF; 00374 if (pvt->DTMFsched >= 0) { 00375 ast_sched_del(sched, pvt->DTMFsched); 00376 pvt->DTMFsched = -1; 00377 } 00378 } else { /* Regular input or signal message */ 00379 if (pvt->newduration) { /* This is a signal, signalUpdate follows */ 00380 f.frametype = AST_FRAME_DTMF_BEGIN; 00381 if (pvt->DTMFsched >= 0) 00382 ast_sched_del(sched, pvt->DTMFsched); 00383 pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt); 00384 if (h323debug) 00385 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched); 00386 } 00387 pvt->curDTMF = pvt->newdigit; 00388 } 00389 ast_queue_frame(c, &f); 00390 pvt->newdigit = -1; 00391 } 00392 if (pvt->update_rtp_info > 0) { 00393 if (pvt->rtp) { 00394 ast_jb_configure(c, &global_jbconf); 00395 c->fds[0] = ast_rtp_fd(pvt->rtp); 00396 c->fds[1] = ast_rtcp_fd(pvt->rtp); 00397 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00398 } 00399 pvt->update_rtp_info = -1; 00400 } 00401 }
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 2175 of file chan_h323.c.
References __oh323_new(), AST_CAUSE_UNALLOCATED, 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().
02176 { 02177 struct oh323_pvt *pvt; 02178 struct ast_channel *c = NULL; 02179 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten; 02180 char tmp_exten[sizeof(pvt->exten)]; 02181 02182 if (h323debug) 02183 ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token); 02184 02185 /* Find the call or allocate a private structure if call not found */ 02186 pvt = find_call_locked(call_reference, token); 02187 if (!pvt) { 02188 ast_log(LOG_ERROR, "Something is wrong: answer_call\n"); 02189 return 0; 02190 } 02191 /* Check if requested extension@context pair exists in the dialplan */ 02192 ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten)); 02193 02194 /* Try to find best extension in specified context */ 02195 if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) { 02196 if (tmp_exten[0] == 's') 02197 try_exten = ext_s; 02198 else if (tmp_exten[0] == 'i') 02199 try_exten = ext_i; 02200 else 02201 try_exten = ext_original; 02202 } else 02203 try_exten = ext_original; 02204 do { 02205 if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL)) 02206 break; 02207 switch (try_exten) { 02208 case ext_original: 02209 tmp_exten[0] = 's'; 02210 tmp_exten[1] = '\0'; 02211 try_exten = ext_s; 02212 break; 02213 case ext_s: 02214 tmp_exten[0] = 'i'; 02215 try_exten = ext_i; 02216 break; 02217 case ext_i: 02218 try_exten = ext_notexists; 02219 break; 02220 default: 02221 break; 02222 } 02223 } while (try_exten != ext_notexists); 02224 02225 /* Drop the call if we don't have <exten>, s and i extensions */ 02226 if (try_exten == ext_notexists) { 02227 ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context); 02228 ast_mutex_unlock(&pvt->lock); 02229 h323_clear_call(token, AST_CAUSE_UNALLOCATED); 02230 return 0; 02231 } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) { 02232 if (h323debug) 02233 ast_log(LOG_DEBUG, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context); 02234 ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten)); 02235 } 02236 02237 /* allocate a channel and tell asterisk about it */ 02238 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token); 02239 02240 /* And release when done */ 02241 ast_mutex_unlock(&pvt->lock); 02242 if (!c) { 02243 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n"); 02244 return 0; 02245 } 02246 return 1; 02247 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"The NuFone Network's OpenH323 Channel Driver" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | h323_reload_lock | ) |
AST_MUTEX_DEFINE_STATIC | ( | caplock | ) |
AST_MUTEX_DEFINE_STATIC | ( | monlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | iflock | ) |
Protect the interface list (oh323_pvt)
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_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 1441 of file chan_h323.c.
References ast_append_ha(), ast_free_ha(), ast_get_ip(), ast_log(), 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 realtime_peer(), and set_config().
01442 { 01443 struct oh323_peer *peer; 01444 struct ast_ha *oldha; 01445 int found = 0; 01446 01447 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 01448 01449 if (peer) 01450 found++; 01451 else { 01452 if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer)))) 01453 return NULL; 01454 ASTOBJ_INIT(peer); 01455 } 01456 oldha = peer->ha; 01457 peer->ha = NULL; 01458 memcpy(&peer->options, &global_options, sizeof(peer->options)); 01459 peer->addr.sin_port = htons(h323_signalling_port); 01460 peer->addr.sin_family = AF_INET; 01461 if (!found && name) 01462 ast_copy_string(peer->name, name, sizeof(peer->name)); 01463 01464 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01465 if (peer->chanvars) { 01466 ast_variables_destroy(peer->chanvars); 01467 peer->chanvars = NULL; 01468 } 01469 #endif 01470 /* Default settings for mailbox */ 01471 peer->mailbox[0] = '\0'; 01472 01473 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01474 if (!update_common_options(v, &peer->options)) 01475 continue; 01476 if (!strcasecmp(v->name, "host")) { 01477 if (!strcasecmp(v->value, "dynamic")) { 01478 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n"); 01479 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01480 return NULL; 01481 } 01482 if (ast_get_ip(&peer->addr, v->value)) { 01483 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value); 01484 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01485 return NULL; 01486 } 01487 } else if (!strcasecmp(v->name, "port")) { 01488 peer->addr.sin_port = htons(atoi(v->value)); 01489 } else if (!strcasecmp(v->name, "permit") || 01490 !strcasecmp(v->name, "deny")) { 01491 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 01492 } else if (!strcasecmp(v->name, "mailbox")) { 01493 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 01494 } 01495 } 01496 ASTOBJ_UNMARK(peer); 01497 ast_free_ha(oldha); 01498 return peer; 01499 }
static struct oh323_user* build_user | ( | char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static] |
Definition at line 1335 of file chan_h323.c.
References ast_append_ha(), ast_cdr_amaflags2int(), 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 realtime_user(), reload_config(), and set_config().
01336 { 01337 struct oh323_user *user; 01338 struct ast_ha *oldha; 01339 int found = 0; 01340 int format; 01341 01342 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp); 01343 01344 if (user) 01345 found++; 01346 else { 01347 if (!(user = (struct oh323_user *)calloc(1, sizeof(*user)))) 01348 return NULL; 01349 ASTOBJ_INIT(user); 01350 } 01351 oldha = user->ha; 01352 user->ha = (struct ast_ha *)NULL; 01353 memcpy(&user->options, &global_options, sizeof(user->options)); 01354 /* Set default context */ 01355 ast_copy_string(user->context, default_context, sizeof(user->context)); 01356 if (user && !found) 01357 ast_copy_string(user->name, name, sizeof(user->name)); 01358 01359 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01360 if (user->chanvars) { 01361 ast_variables_destroy(user->chanvars); 01362 user->chanvars = NULL; 01363 } 01364 #endif 01365 01366 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01367 if (!update_common_options(v, &user->options)) 01368 continue; 01369 if (!strcasecmp(v->name, "context")) { 01370 ast_copy_string(user->context, v->value, sizeof(user->context)); 01371 } else if (!strcasecmp(v->name, "secret")) { 01372 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 01373 } else if (!strcasecmp(v->name, "accountcode")) { 01374 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 01375 } else if (!strcasecmp(v->name, "host")) { 01376 if (!strcasecmp(v->value, "dynamic")) { 01377 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n"); 01378 ASTOBJ_UNREF(user, oh323_destroy_user); 01379 return NULL; 01380 } else if (ast_get_ip(&user->addr, v->value)) { 01381 ASTOBJ_UNREF(user, oh323_destroy_user); 01382 return NULL; 01383 } 01384 /* Let us know we need to use ip authentication */ 01385 user->host = 1; 01386 } else if (!strcasecmp(v->name, "amaflags")) { 01387 format = ast_cdr_amaflags2int(v->value); 01388 if (format < 0) { 01389 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 01390 } else { 01391 user->amaflags = format; 01392 } 01393 } else if (!strcasecmp(v->name, "permit") || 01394 !strcasecmp(v->name, "deny")) { 01395 user->ha = ast_append_ha(v->name, v->value, user->ha); 01396 } 01397 } 01398 ASTOBJ_UNMARK(user); 01399 ast_free_ha(oldha); 01400 return user; 01401 }
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 2266 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().
02267 { 02268 struct oh323_pvt *pvt; 02269 02270 if (h323debug) 02271 ast_log(LOG_DEBUG, "Ringing on %s\n", token); 02272 02273 pvt = find_call_locked(call_reference, token); 02274 if (!pvt) { 02275 ast_log(LOG_ERROR, "Something is wrong: ringing\n"); 02276 return; 02277 } 02278 if (!pvt->owner) { 02279 ast_mutex_unlock(&pvt->lock); 02280 ast_log(LOG_ERROR, "Channel has no owner\n"); 02281 return; 02282 } 02283 update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING); 02284 ast_mutex_unlock(&pvt->lock); 02285 return; 02286 }
static void cleanup_call_details | ( | call_details_t * | cd | ) | [static] |
Definition at line 415 of file chan_h323.c.
References free.
Referenced by __oh323_destroy(), cleanup_connection(), setup_incoming_call(), and setup_outgoing_call().
00416 { 00417 if (cd->call_token) { 00418 free(cd->call_token); 00419 cd->call_token = NULL; 00420 } 00421 if (cd->call_source_aliases) { 00422 free(cd->call_source_aliases); 00423 cd->call_source_aliases = NULL; 00424 } 00425 if (cd->call_dest_alias) { 00426 free(cd->call_dest_alias); 00427 cd->call_dest_alias = NULL; 00428 } 00429 if (cd->call_source_name) { 00430 free(cd->call_source_name); 00431 cd->call_source_name = NULL; 00432 } 00433 if (cd->call_source_e164) { 00434 free(cd->call_source_e164); 00435 cd->call_source_e164 = NULL; 00436 } 00437 if (cd->call_dest_e164) { 00438 free(cd->call_dest_e164); 00439 cd->call_dest_e164 = NULL; 00440 } 00441 if (cd->sourceIp) { 00442 free(cd->sourceIp); 00443 cd->sourceIp = NULL; 00444 } 00445 if (cd->redirect_number) { 00446 free(cd->redirect_number); 00447 cd->redirect_number = NULL; 00448 } 00449 }
static void cleanup_connection | ( | unsigned | call_reference, | |
const char * | call_token | |||
) | [static] |
Call-back function to cleanup communication Returns nothing,
Definition at line 2292 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().
02293 { 02294 struct oh323_pvt *pvt; 02295 02296 if (h323debug) 02297 ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token); 02298 02299 while (1) { 02300 pvt = find_call_locked(call_reference, call_token); 02301 if (!pvt) { 02302 if (h323debug) 02303 ast_log(LOG_DEBUG, "No connection for %s\n", call_token); 02304 return; 02305 } 02306 if (!pvt->owner || !ast_channel_trylock(pvt->owner)) 02307 break; 02308 #if 1 02309 #ifdef DEBUG_THREADS 02310 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]); 02311 #else 02312 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token); 02313 #endif 02314 #endif 02315 ast_mutex_unlock(&pvt->lock); 02316 usleep(1); 02317 } 02318 if (pvt->rtp) { 02319 /* Immediately stop RTP */ 02320 ast_rtp_destroy(pvt->rtp); 02321 pvt->rtp = NULL; 02322 } 02323 /* Free dsp used for in-band DTMF detection */ 02324 if (pvt->vad) { 02325 ast_dsp_free(pvt->vad); 02326 pvt->vad = NULL; 02327 } 02328 cleanup_call_details(&pvt->cd); 02329 pvt->alreadygone = 1; 02330 /* Send hangup */ 02331 if (pvt->owner) { 02332 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02333 ast_queue_hangup(pvt->owner); 02334 ast_channel_unlock(pvt->owner); 02335 } 02336 ast_mutex_unlock(&pvt->lock); 02337 if (h323debug) 02338 ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token); 02339 return; 02340 }
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 2000 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().
02001 { 02002 struct oh323_pvt *pvt; 02003 02004 if (h323debug) 02005 ast_log(LOG_DEBUG, "Call %s answered\n", token); 02006 02007 pvt = find_call_locked(call_reference, token); 02008 if (!pvt) { 02009 ast_log(LOG_ERROR, "Something is wrong: connection\n"); 02010 return; 02011 } 02012 02013 /* Inform asterisk about remote party connected only on outgoing calls */ 02014 if (!pvt->outgoing) { 02015 ast_mutex_unlock(&pvt->lock); 02016 return; 02017 } 02018 /* Do not send ANSWER message more than once */ 02019 if (!pvt->connection_established) { 02020 pvt->connection_established = 1; 02021 update_state(pvt, -1, AST_CONTROL_ANSWER); 02022 } 02023 ast_mutex_unlock(&pvt->lock); 02024 return; 02025 }
static char* convertcap | ( | int | cap | ) | [static] |
Definition at line 3029 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().
03030 { 03031 switch (cap) { 03032 case AST_FORMAT_G723_1: 03033 return "G.723"; 03034 case AST_FORMAT_GSM: 03035 return "GSM"; 03036 case AST_FORMAT_ULAW: 03037 return "ULAW"; 03038 case AST_FORMAT_ALAW: 03039 return "ALAW"; 03040 case AST_FORMAT_G722: 03041 return "G.722"; 03042 case AST_FORMAT_ADPCM: 03043 return "G.728"; 03044 case AST_FORMAT_G729A: 03045 return "G.729"; 03046 case AST_FORMAT_SPEEX: 03047 return "SPEEX"; 03048 case AST_FORMAT_ILBC: 03049 return "ILBC"; 03050 default: 03051 ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap); 03052 return NULL; 03053 } 03054 }
static int create_addr | ( | struct oh323_pvt * | pvt, | |
char * | opeer | |||
) | [static] |
Definition at line 1597 of file chan_h323.c.
References ahp, 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().
01598 { 01599 struct hostent *hp; 01600 struct ast_hostent ahp; 01601 struct oh323_peer *p; 01602 int portno; 01603 int found = 0; 01604 char *port; 01605 char *hostn; 01606 char peer[256] = ""; 01607 01608 ast_copy_string(peer, opeer, sizeof(peer)); 01609 port = strchr(peer, ':'); 01610 if (port) { 01611 *port = '\0'; 01612 port++; 01613 } 01614 pvt->sa.sin_family = AF_INET; 01615 p = find_peer(peer, NULL, 1); 01616 if (p) { 01617 found++; 01618 memcpy(&pvt->options, &p->options, sizeof(pvt->options)); 01619 pvt->jointcapability = pvt->options.capability; 01620 if (pvt->options.dtmfmode) { 01621 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01622 pvt->nonCodecCapability |= AST_RTP_DTMF; 01623 } else { 01624 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01625 } 01626 } 01627 if (p->addr.sin_addr.s_addr) { 01628 pvt->sa.sin_addr = p->addr.sin_addr; 01629 pvt->sa.sin_port = p->addr.sin_port; 01630 } 01631 ASTOBJ_UNREF(p, oh323_destroy_peer); 01632 } 01633 if (!p && !found) { 01634 hostn = peer; 01635 if (port) { 01636 portno = atoi(port); 01637 } else { 01638 portno = h323_signalling_port; 01639 } 01640 hp = ast_gethostbyname(hostn, &ahp); 01641 if (hp) { 01642 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 01643 pvt->sa.sin_port = htons(portno); 01644 /* Look peer by address */ 01645 p = find_peer(NULL, &pvt->sa, 1); 01646 memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options)); 01647 pvt->jointcapability = pvt->options.capability; 01648 if (p) { 01649 ASTOBJ_UNREF(p, oh323_destroy_peer); 01650 } 01651 if (pvt->options.dtmfmode) { 01652 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01653 pvt->nonCodecCapability |= AST_RTP_DTMF; 01654 } else { 01655 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01656 } 01657 } 01658 return 0; 01659 } else { 01660 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01661 return -1; 01662 } 01663 } else if (!found) { 01664 return -1; 01665 } else { 01666 return 0; 01667 } 01668 }
static void delete_aliases | ( | void | ) | [static] |
Definition at line 2949 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 h323_do_reload().
02950 { 02951 int pruned = 0; 02952 02953 /* Delete all aliases */ 02954 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 02955 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 02956 ASTOBJ_RDLOCK(iterator); 02957 ASTOBJ_MARK(iterator); 02958 ++pruned; 02959 ASTOBJ_UNLOCK(iterator); 02960 } while (0) ); 02961 if (pruned) { 02962 ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias); 02963 } 02964 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 02965 }
static void delete_users | ( | void | ) | [static] |
Definition at line 2923 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(), h323_do_reload(), and reload_config().
02924 { 02925 int pruned = 0; 02926 02927 /* Delete all users */ 02928 ASTOBJ_CONTAINER_WRLOCK(&userl); 02929 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 02930 ASTOBJ_RDLOCK(iterator); 02931 ASTOBJ_MARK(iterator); 02932 ++pruned; 02933 ASTOBJ_UNLOCK(iterator); 02934 } while (0) ); 02935 if (pruned) { 02936 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user); 02937 } 02938 ASTOBJ_CONTAINER_UNLOCK(&userl); 02939 02940 ASTOBJ_CONTAINER_WRLOCK(&peerl); 02941 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 02942 ASTOBJ_RDLOCK(iterator); 02943 ASTOBJ_MARK(iterator); 02944 ASTOBJ_UNLOCK(iterator); 02945 } while (0) ); 02946 ASTOBJ_CONTAINER_UNLOCK(&peerl); 02947 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 2443 of file chan_h323.c.
References __oh323_destroy(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_verbose(), h323_do_reload(), h323_reloading, iflist, oh323_pvt::lock, oh323_pvt::needdestroy, oh323_pvt::next, option_verbose, and VERBOSE_PREFIX_1.
Referenced by restart_monitor().
02444 { 02445 int res; 02446 int reloading; 02447 struct oh323_pvt *oh323 = NULL; 02448 02449 for(;;) { 02450 /* Check for a reload request */ 02451 ast_mutex_lock(&h323_reload_lock); 02452 reloading = h323_reloading; 02453 h323_reloading = 0; 02454 ast_mutex_unlock(&h323_reload_lock); 02455 if (reloading) { 02456 if (option_verbose > 0) { 02457 ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n"); 02458 } 02459 h323_do_reload(); 02460 } 02461 /* Check for interfaces needing to be killed */ 02462 if (!ast_mutex_trylock(&iflock)) { 02463 #if 1 02464 do { 02465 for (oh323 = iflist; oh323; oh323 = oh323->next) { 02466 if (!ast_mutex_trylock(&oh323->lock)) { 02467 if (oh323->needdestroy) { 02468 __oh323_destroy(oh323); 02469 break; 02470 } 02471 ast_mutex_unlock(&oh323->lock); 02472 } 02473 } 02474 } while (/*oh323*/ 0); 02475 #else 02476 restartsearch: 02477 oh323 = iflist; 02478 while(oh323) { 02479 if (!ast_mutex_trylock(&oh323->lock)) { 02480 if (oh323->needdestroy) { 02481 __oh323_destroy(oh323); 02482 goto restartsearch; 02483 } 02484 ast_mutex_unlock(&oh323->lock); 02485 oh323 = oh323->next; 02486 } 02487 } 02488 #endif 02489 ast_mutex_unlock(&iflock); 02490 } else 02491 oh323 = (struct oh323_pvt *)1; /* Force fast loop */ 02492 pthread_testcancel(); 02493 /* Wait for sched or io */ 02494 res = ast_sched_wait(sched); 02495 if ((res < 0) || (res > 1000)) { 02496 res = 1000; 02497 } 02498 /* Do not wait if some channel(s) is destroyed, probably, more available too */ 02499 if (oh323) 02500 res = 1; 02501 res = ast_io_wait(io, res); 02502 pthread_testcancel(); 02503 ast_mutex_lock(&monlock); 02504 if (res >= 0) { 02505 ast_sched_runq(sched); 02506 } 02507 ast_mutex_unlock(&monlock); 02508 } 02509 /* Never reached */ 02510 return NULL; 02511 }
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 1846 of file chan_h323.c.
References __oh323_rtp_create(), 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().
01847 { 01848 struct oh323_pvt *pvt; 01849 struct sockaddr_in us; 01850 struct rtp_info *info; 01851 01852 info = (struct rtp_info *)malloc(sizeof(struct rtp_info)); 01853 if (!info) { 01854 ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n"); 01855 return NULL; 01856 } 01857 pvt = find_call_locked(call_reference, token); 01858 if (!pvt) { 01859 free(info); 01860 ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference); 01861 return NULL; 01862 } 01863 if (!pvt->rtp) 01864 __oh323_rtp_create(pvt); 01865 if (!pvt->rtp) { 01866 ast_mutex_unlock(&pvt->lock); 01867 free(info); 01868 ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference); 01869 return NULL; 01870 } 01871 /* figure out our local RTP port and tell the H.323 stack about it */ 01872 ast_rtp_get_us(pvt->rtp, &us); 01873 ast_mutex_unlock(&pvt->lock); 01874 01875 ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr)); 01876 info->port = ntohs(us.sin_port); 01877 if (h323debug) 01878 ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port); 01879 return info; 01880 }
static struct oh323_alias* find_alias | ( | const char * | source_aliases, | |
int | realtime | |||
) | [static] |
Find a call by alias
Definition at line 1758 of file chan_h323.c.
References aliasl, ASTOBJ_CONTAINER_FIND, and realtime_alias().
Referenced by __get_header(), add_header(), and setup_incoming_call().
01759 { 01760 struct oh323_alias *a; 01761 01762 a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases); 01763 01764 if (!a && realtime) 01765 a = realtime_alias(source_aliases); 01766 01767 return a; 01768 }
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, 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) && (!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 1579 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(), sip_devicestate(), sip_do_debug_peer(), sip_peer_hold(), update_call_counter(), and update_registry().
01580 { 01581 struct oh323_peer *p; 01582 01583 if (peer) 01584 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 01585 else 01586 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp); 01587 01588 if (!p && realtime) 01589 p = realtime_peer(peer, sin); 01590 01591 if (!p && h323debug) 01592 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>")); 01593 01594 return p; 01595 }
static struct oh323_user* find_user | ( | const call_details_t * | cd, | |
int | realtime | |||
) | [static] |
Definition at line 1549 of file chan_h323.c.
References ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, h323debug, LOG_DEBUG, oh323_addrcmp_str(), realtime_user(), userbyalias, and userl.
Referenced by admin_exec(), advanced_options(), check_user_full(), forward_message(), leave_voicemail(), setup_incoming_call(), sip_show_user(), update_call_counter(), vm_authenticate(), vm_box_exists(), and vm_execmain().
01550 { 01551 struct oh323_user *u; 01552 01553 if (userbyalias) 01554 u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases); 01555 else 01556 u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str); 01557 01558 if (!u && realtime) 01559 u = realtime_user(cd); 01560 01561 if (!u && h323debug) 01562 ast_log(LOG_DEBUG, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp); 01563 01564 return u; 01565 }
static int h323_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2570 of file chan_h323.c.
References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02571 { 02572 if (argc < 2 || argc > 3) { 02573 return RESULT_SHOWUSAGE; 02574 } 02575 h323debug = 1; 02576 ast_cli(fd, "H.323 debug enabled\n"); 02577 return RESULT_SUCCESS; 02578 }
static int h323_do_reload | ( | void | ) | [static] |
Definition at line 2986 of file chan_h323.c.
References delete_aliases(), delete_users(), prune_peers(), and reload_config().
Referenced by do_monitor().
02987 { 02988 delete_users(); 02989 delete_aliases(); 02990 prune_peers(); 02991 reload_config(1); 02992 return 0; 02993 }
static int h323_do_trace | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2550 of file chan_h323.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02551 { 02552 if (argc != 4) { 02553 return RESULT_SHOWUSAGE; 02554 } 02555 h323_debug(1, atoi(argv[3])); 02556 ast_cli(fd, "H.323 trace set to level %s\n", argv[2]); 02557 return RESULT_SUCCESS; 02558 }
static int h323_ep_hangup | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2606 of file chan_h323.c.
References ast_verbose(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and VERBOSE_PREFIX_3.
02607 { 02608 if (argc != 3) { 02609 return RESULT_SHOWUSAGE; 02610 } 02611 if (h323_soft_hangup(argv[2])) { 02612 ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]); 02613 } else { 02614 ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]); 02615 } 02616 return RESULT_SUCCESS; 02617 }
static int h323_gk_cycle | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2590 of file chan_h323.c.
References ast_log(), gatekeeper, gatekeeper_disable, gatekeeper_discover, LOG_ERROR, RESULT_SHOWUSAGE, RESULT_SUCCESS, and secret.
02591 { 02592 if (argc != 3) { 02593 return RESULT_SHOWUSAGE; 02594 } 02595 h323_gk_urq(); 02596 02597 /* Possibly register with a GK */ 02598 if (!gatekeeper_disable) { 02599 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 02600 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 02601 } 02602 } 02603 return RESULT_SUCCESS; 02604 }
static int h323_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2580 of file chan_h323.c.
References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02581 { 02582 if (argc < 3 || argc > 4) { 02583 return RESULT_SHOWUSAGE; 02584 } 02585 h323debug = 0; 02586 ast_cli(fd, "H.323 debug disabled\n"); 02587 return RESULT_SUCCESS; 02588 }
static int h323_no_trace | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2560 of file chan_h323.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02561 { 02562 if (argc < 3 || argc > 4) { 02563 return RESULT_SHOWUSAGE; 02564 } 02565 h323_debug(0,0); 02566 ast_cli(fd, "H.323 trace disabled\n"); 02567 return RESULT_SUCCESS; 02568 }
static int h323_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2973 of file chan_h323.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), h323_reloading, and restart_monitor().
Referenced by reload().
02974 { 02975 ast_mutex_lock(&h323_reload_lock); 02976 if (h323_reloading) { 02977 ast_verbose("Previous H.323 reload not yet done\n"); 02978 } else { 02979 h323_reloading = 1; 02980 } 02981 ast_mutex_unlock(&h323_reload_lock); 02982 restart_monitor(); 02983 return 0; 02984 }
static int h323_tokens_show | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2619 of file chan_h323.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02620 { 02621 if (argc != 3) { 02622 return RESULT_SHOWUSAGE; 02623 } 02624 h323_show_tokens(); 02625 return RESULT_SUCCESS; 02626 }
static void hangup_connection | ( | unsigned int | call_reference, | |
const char * | token, | |||
int | cause | |||
) | [static] |
Definition at line 2342 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().
02343 { 02344 struct oh323_pvt *pvt; 02345 02346 if (h323debug) { 02347 ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause); 02348 } 02349 02350 pvt = find_call_locked(call_reference, token); 02351 if (!pvt) { 02352 if (h323debug) { 02353 ast_log(LOG_DEBUG, "Connection to %s already cleared\n", token); 02354 } 02355 return; 02356 } 02357 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 02358 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02359 pvt->owner->hangupcause = pvt->hangupcause = cause; 02360 ast_queue_hangup(pvt->owner); 02361 ast_channel_unlock(pvt->owner); 02362 } 02363 else { 02364 pvt->needhangup = 1; 02365 pvt->hangupcause = cause; 02366 if (h323debug) 02367 ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token); 02368 } 02369 ast_mutex_unlock(&pvt->lock); 02370 }
static enum ast_module_load_result load_module | ( | void | ) | [static] |
Definition at line 3089 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.
03090 { 03091 int res; 03092 03093 h323debug = 0; 03094 sched = sched_context_create(); 03095 if (!sched) { 03096 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 03097 return AST_MODULE_LOAD_FAILURE; 03098 } 03099 io = io_context_create(); 03100 if (!io) { 03101 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 03102 return AST_MODULE_LOAD_FAILURE; 03103 } 03104 ast_cli_register(&cli_h323_reload); 03105 ASTOBJ_CONTAINER_INIT(&userl); 03106 ASTOBJ_CONTAINER_INIT(&peerl); 03107 ASTOBJ_CONTAINER_INIT(&aliasl); 03108 res = reload_config(0); 03109 if (res) { 03110 /* No config entry */ 03111 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n"); 03112 ast_cli_unregister(&cli_h323_reload); 03113 io_context_destroy(io); 03114 io = NULL; 03115 sched_context_destroy(sched); 03116 sched = NULL; 03117 ASTOBJ_CONTAINER_DESTROY(&userl); 03118 ASTOBJ_CONTAINER_DESTROY(&peerl); 03119 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03120 return AST_MODULE_LOAD_DECLINE; 03121 } else { 03122 /* Make sure we can register our channel type */ 03123 if (ast_channel_register(&oh323_tech)) { 03124 ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n"); 03125 ast_cli_unregister(&cli_h323_reload); 03126 h323_end_process(); 03127 io_context_destroy(io); 03128 sched_context_destroy(sched); 03129 03130 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03131 ASTOBJ_CONTAINER_DESTROY(&userl); 03132 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03133 ASTOBJ_CONTAINER_DESTROY(&peerl); 03134 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03135 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03136 03137 return AST_MODULE_LOAD_FAILURE; 03138 } 03139 ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03140 03141 ast_rtp_proto_register(&oh323_rtp); 03142 03143 /* Register our callback functions */ 03144 h323_callback_register(setup_incoming_call, 03145 setup_outgoing_call, 03146 external_rtp_create, 03147 setup_rtp_connection, 03148 cleanup_connection, 03149 chan_ringing, 03150 connection_made, 03151 receive_digit, 03152 answer_call, 03153 progress, 03154 set_dtmf_payload, 03155 hangup_connection, 03156 set_local_capabilities, 03157 set_peer_capabilities); 03158 /* start the h.323 listener */ 03159 if (h323_start_listener(h323_signalling_port, bindaddr)) { 03160 ast_log(LOG_ERROR, "Unable to create H323 listener.\n"); 03161 ast_rtp_proto_unregister(&oh323_rtp); 03162 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03163 ast_cli_unregister(&cli_h323_reload); 03164 h323_end_process(); 03165 io_context_destroy(io); 03166 sched_context_destroy(sched); 03167 03168 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03169 ASTOBJ_CONTAINER_DESTROY(&userl); 03170 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03171 ASTOBJ_CONTAINER_DESTROY(&peerl); 03172 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03173 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03174 03175 return AST_MODULE_LOAD_FAILURE; 03176 } 03177 /* Possibly register with a GK */ 03178 if (!gatekeeper_disable) { 03179 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 03180 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 03181 gatekeeper_disable = 1; 03182 res = AST_MODULE_LOAD_SUCCESS; 03183 } 03184 } 03185 /* And start the monitor for the first time */ 03186 restart_monitor(); 03187 } 03188 return res; 03189 }
static int oh323_addrcmp | ( | struct sockaddr_in | addr, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 1567 of file chan_h323.c.
References inaddrcmp().
Referenced by find_peer().
01568 { 01569 int res; 01570 01571 if (!sin) 01572 res = -1; 01573 else 01574 res = inaddrcmp(&addr , sin); 01575 01576 return res; 01577 }
static int oh323_addrcmp_str | ( | struct in_addr | inaddr, | |
char * | addr | |||
) | [static] |
Definition at line 1544 of file chan_h323.c.
References ast_inet_ntoa().
Referenced by find_user().
01545 { 01546 return strcmp(ast_inet_ntoa(inaddr), addr); 01547 }
static struct oh323_pvt* oh323_alloc | ( | int | callid | ) | [static] |
Definition at line 1101 of file chan_h323.c.
References 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, 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 667 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, oh323_update_info(), strdup, and ast_channel::tech_pvt.
00668 { 00669 int res; 00670 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00671 char *token; 00672 00673 if (h323debug) 00674 ast_log(LOG_DEBUG, "Answering on %s\n", c->name); 00675 00676 ast_mutex_lock(&pvt->lock); 00677 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00678 ast_mutex_unlock(&pvt->lock); 00679 res = h323_answering_call(token, 0); 00680 if (token) 00681 free(token); 00682 00683 oh323_update_info(c); 00684 if (c->_state != AST_STATE_UP) { 00685 ast_setstate(c, AST_STATE_UP); 00686 } 00687 return res; 00688 }
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 588 of file chan_h323.c.
References ast_channel::_state, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, AST_STATE_RESERVED, ast_strlen_zero(), 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, 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.
00589 { 00590 int res = 0; 00591 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00592 const char *addr; 00593 char called_addr[1024]; 00594 00595 if (h323debug) { 00596 ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name); 00597 } 00598 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 00599 ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name); 00600 return -1; 00601 } 00602 ast_mutex_lock(&pvt->lock); 00603 if (!gatekeeper_disable) { 00604 if (ast_strlen_zero(pvt->exten)) { 00605 ast_copy_string(called_addr, dest, sizeof(called_addr)); 00606 } else { 00607 snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest); 00608 } 00609 } else { 00610 res = htons(pvt->sa.sin_port); 00611 addr = ast_inet_ntoa(pvt->sa.sin_addr); 00612 if (ast_strlen_zero(pvt->exten)) { 00613 snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res); 00614 } else { 00615 snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res); 00616 } 00617 } 00618 /* make sure null terminated */ 00619 called_addr[sizeof(called_addr) - 1] = '\0'; 00620 00621 if (c->cid.cid_num) 00622 ast_copy_string(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num)); 00623 00624 if (c->cid.cid_name) 00625 ast_copy_string(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name)); 00626 00627 if (c->cid.cid_rdnis) { 00628 ast_copy_string(pvt->options.cid_rdnis, c->cid.cid_rdnis, sizeof(pvt->options.cid_rdnis)); 00629 } 00630 00631 pvt->options.presentation = c->cid.cid_pres; 00632 pvt->options.type_of_number = c->cid.cid_ton; 00633 00634 if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) { 00635 if (!strcasecmp(addr, "UNKNOWN")) 00636 pvt->options.redirect_reason = 0; 00637 else if (!strcasecmp(addr, "BUSY")) 00638 pvt->options.redirect_reason = 1; 00639 else if (!strcasecmp(addr, "NO_REPLY")) 00640 pvt->options.redirect_reason = 2; 00641 else if (!strcasecmp(addr, "UNCONDITIONAL")) 00642 pvt->options.redirect_reason = 15; 00643 else 00644 pvt->options.redirect_reason = -1; 00645 } else 00646 pvt->options.redirect_reason = -1; 00647 00648 pvt->options.transfer_capability = c->transfercapability; 00649 00650 /* indicate that this is an outgoing call */ 00651 pvt->outgoing = 1; 00652 00653 if (option_verbose > 2) 00654 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability)); 00655 if (h323debug) 00656 ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec); 00657 ast_mutex_unlock(&pvt->lock); 00658 res = h323_make_call(called_addr, &(pvt->cd), &pvt->options); 00659 if (res) { 00660 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name); 00661 return -1; 00662 } 00663 oh323_update_info(c); 00664 return 0; 00665 }
static void oh323_destroy | ( | struct oh323_pvt * | pvt | ) | [static] |
Definition at line 499 of file chan_h323.c.
References __oh323_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, LOG_DEBUG, and oh323_pvt::owner.
Referenced by oh323_request(), and setup_incoming_call().
00500 { 00501 if (h323debug) { 00502 ast_log(LOG_DEBUG, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>")); 00503 } 00504 ast_mutex_lock(&iflock); 00505 ast_mutex_lock(&pvt->lock); 00506 __oh323_destroy(pvt); 00507 ast_mutex_unlock(&iflock); 00508 }
static void oh323_destroy_alias | ( | struct oh323_alias * | alias | ) | [static] |
Definition at line 283 of file chan_h323.c.
References ast_log(), free, and LOG_DEBUG.
Referenced by delete_aliases(), load_module(), and unload_module().
00284 { 00285 if (h323debug) 00286 ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name); 00287 free(alias); 00288 }
static void oh323_destroy_peer | ( | struct oh323_peer * | peer | ) | [static] |
Definition at line 298 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(), and unload_module().
00299 { 00300 if (h323debug) 00301 ast_log(LOG_DEBUG, "Destroying peer '%s'\n", peer->name); 00302 ast_free_ha(peer->ha); 00303 free(peer); 00304 }
static void oh323_destroy_user | ( | struct oh323_user * | user | ) | [static] |
Definition at line 290 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().
00291 { 00292 if (h323debug) 00293 ast_log(LOG_DEBUG, "Destroying user '%s'\n", user->name); 00294 ast_free_ha(user->ha); 00295 free(user); 00296 }
static int oh323_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 510 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, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, ast_channel::tech_pvt, and oh323_pvt::txDtmfDigit.
00511 { 00512 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00513 char *token; 00514 00515 if (!pvt) { 00516 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00517 return -1; 00518 } 00519 ast_mutex_lock(&pvt->lock); 00520 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) { 00521 /* out-of-band DTMF */ 00522 if (h323debug) { 00523 ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name); 00524 } 00525 ast_rtp_senddigit_begin(pvt->rtp, digit); 00526 ast_mutex_unlock(&pvt->lock); 00527 } else if (pvt->txDtmfDigit != digit) { 00528 /* in-band DTMF */ 00529 if (h323debug) { 00530 ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name); 00531 } 00532 pvt->txDtmfDigit = digit; 00533 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00534 ast_mutex_unlock(&pvt->lock); 00535 h323_send_tone(token, digit); 00536 if (token) { 00537 free(token); 00538 } 00539 } else 00540 ast_mutex_unlock(&pvt->lock); 00541 oh323_update_info(c); 00542 return 0; 00543 }
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 549 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, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, ast_channel::tech_pvt, and oh323_pvt::txDtmfDigit.
00550 { 00551 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00552 char *token; 00553 00554 if (!pvt) { 00555 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00556 return -1; 00557 } 00558 ast_mutex_lock(&pvt->lock); 00559 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) { 00560 /* out-of-band DTMF */ 00561 if (h323debug) { 00562 ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, c->name, duration); 00563 } 00564 ast_rtp_senddigit_end(pvt->rtp, digit); 00565 ast_mutex_unlock(&pvt->lock); 00566 } else { 00567 /* in-band DTMF */ 00568 if (h323debug) { 00569 ast_log(LOG_DTMF, "End sending inband digit %c on %s, duration %d\n", digit, c->name, duration); 00570 } 00571 pvt->txDtmfDigit = ' '; 00572 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00573 ast_mutex_unlock(&pvt->lock); 00574 h323_send_tone(token, ' '); 00575 if (token) { 00576 free(token); 00577 } 00578 } 00579 oh323_update_info(c); 00580 return 0; 00581 }
static int oh323_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 939 of file chan_h323.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, LOG_WARNING, oh323_pvt::owner, and ast_channel::tech_pvt.
00940 { 00941 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt; 00942 00943 ast_mutex_lock(&pvt->lock); 00944 if (pvt->owner != oldchan) { 00945 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner); 00946 return -1; 00947 } 00948 pvt->owner = newchan; 00949 ast_mutex_unlock(&pvt->lock); 00950 return 0; 00951 }
static enum ast_rtp_get_result oh323_get_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 3006 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.
03007 { 03008 struct oh323_pvt *pvt; 03009 enum ast_rtp_get_result res = AST_RTP_GET_FAILED; 03010 03011 if (!(pvt = (struct oh323_pvt *)chan->tech_pvt)) 03012 return res; 03013 03014 ast_mutex_lock(&pvt->lock); 03015 if (pvt->rtp && pvt->options.bridge) { 03016 *rtp = pvt->rtp; 03017 res = AST_RTP_TRY_NATIVE; 03018 } 03019 ast_mutex_unlock(&pvt->lock); 03020 03021 return res; 03022 }
static enum ast_rtp_get_result oh323_get_vrtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 3024 of file chan_h323.c.
References AST_RTP_GET_FAILED.
03025 { 03026 return AST_RTP_GET_FAILED; 03027 }
static int oh323_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 690 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, oh323_pvt::needdestroy, oh323_pvt::owner, pbx_builtin_getvar_helper(), strdup, and ast_channel::tech_pvt.
00691 { 00692 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00693 int q931cause = AST_CAUSE_NORMAL_CLEARING; 00694 char *call_token; 00695 00696 00697 if (h323debug) 00698 ast_log(LOG_DEBUG, "Hanging up and scheduling destroy of call %s\n", c->name); 00699 00700 if (!c->tech_pvt) { 00701 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 00702 return 0; 00703 } 00704 ast_mutex_lock(&pvt->lock); 00705 /* Determine how to disconnect */ 00706 if (pvt->owner != c) { 00707 ast_log(LOG_WARNING, "Huh? We aren't the owner?\n"); 00708 ast_mutex_unlock(&pvt->lock); 00709 return 0; 00710 } 00711 00712 pvt->owner = NULL; 00713 c->tech_pvt = NULL; 00714 00715 if (c->hangupcause) { 00716 q931cause = c->hangupcause; 00717 } else { 00718 const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 00719 if (cause) { 00720 if (!strcmp(cause, "CONGESTION")) { 00721 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 00722 } else if (!strcmp(cause, "BUSY")) { 00723 q931cause = AST_CAUSE_USER_BUSY; 00724 } else if (!strcmp(cause, "CHANISUNVAIL")) { 00725 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; 00726 } else if (!strcmp(cause, "NOANSWER")) { 00727 q931cause = AST_CAUSE_NO_ANSWER; 00728 } else if (!strcmp(cause, "CANCEL")) { 00729 q931cause = AST_CAUSE_CALL_REJECTED; 00730 } 00731 } 00732 } 00733 00734 /* Start the process if it's not already started */ 00735 if (!pvt->alreadygone && !pvt->hangupcause) { 00736 call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00737 if (call_token) { 00738 /* Release lock to eliminate deadlock */ 00739 ast_mutex_unlock(&pvt->lock); 00740 if (h323_clear_call(call_token, q931cause)) { 00741 ast_log(LOG_WARNING, "ClearCall failed.\n"); 00742 } 00743 free(call_token); 00744 ast_mutex_lock(&pvt->lock); 00745 } 00746 } 00747 pvt->needdestroy = 1; 00748 ast_mutex_unlock(&pvt->lock); 00749 00750 /* Update usage counter */ 00751 ast_module_unref(ast_module_info->self); 00752 00753 return 0; 00754 }
static int oh323_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 865 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_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, oh323_pvt::cd, free, oh323_pvt::got_progress, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_update_info(), strdup, and ast_channel::tech_pvt.
00866 { 00867 00868 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00869 char *token = (char *)NULL; 00870 int res = -1; 00871 int got_progress; 00872 00873 ast_mutex_lock(&pvt->lock); 00874 token = (pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL); 00875 got_progress = pvt->got_progress; 00876 if (condition == AST_CONTROL_PROGRESS) 00877 pvt->got_progress = 1; 00878 else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION)) 00879 pvt->alreadygone = 1; 00880 ast_mutex_unlock(&pvt->lock); 00881 00882 if (h323debug) 00883 ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token); 00884 00885 switch(condition) { 00886 case AST_CONTROL_RINGING: 00887 if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) { 00888 h323_send_alerting(token); 00889 res = (got_progress ? 0 : -1); /* Do not simulate any audio tones if we got PROGRESS message */ 00890 } 00891 break; 00892 case AST_CONTROL_PROGRESS: 00893 if (c->_state != AST_STATE_UP) { 00894 /* Do not send PROGRESS message more than once */ 00895 if (!got_progress) 00896 h323_send_progress(token); 00897 res = 0; 00898 } 00899 break; 00900 case AST_CONTROL_BUSY: 00901 if (c->_state != AST_STATE_UP) { 00902 h323_answering_call(token, 1); 00903 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00904 res = 0; 00905 } 00906 break; 00907 case AST_CONTROL_CONGESTION: 00908 if (c->_state != AST_STATE_UP) { 00909 h323_answering_call(token, 1); 00910 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00911 res = 0; 00912 } 00913 break; 00914 case AST_CONTROL_HOLD: 00915 ast_moh_start(c, data, NULL); 00916 res = 0; 00917 break; 00918 case AST_CONTROL_UNHOLD: 00919 ast_moh_stop(c); 00920 res = 0; 00921 break; 00922 case AST_CONTROL_PROCEEDING: 00923 case -1: 00924 break; 00925 default: 00926 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token); 00927 break; 00928 } 00929 00930 if (h323debug) 00931 ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res); 00932 if (token) 00933 free(token); 00934 oh323_update_info(c); 00935 00936 return res; 00937 }
static struct ast_frame * oh323_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 812 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, oh323_rtp_read(), oh323_pvt::rtp, and ast_channel::tech_pvt.
00813 { 00814 struct ast_frame *fr; 00815 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00816 ast_mutex_lock(&pvt->lock); 00817 __oh323_update_info(c, pvt); 00818 switch(c->fdno) { 00819 case 0: 00820 fr = oh323_rtp_read(pvt); 00821 break; 00822 case 1: 00823 if (pvt->rtp) 00824 fr = ast_rtcp_read(pvt->rtp); 00825 else 00826 fr = &ast_null_frame; 00827 break; 00828 default: 00829 ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name); 00830 fr = &ast_null_frame; 00831 break; 00832 } 00833 ast_mutex_unlock(&pvt->lock); 00834 return fr; 00835 }
static struct ast_channel * oh323_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 1669 of file chan_h323.c.
References __oh323_new(), AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INCOMPATIBLE_DESTINATION, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, 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(), 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.
01670 { 01671 int oldformat; 01672 struct oh323_pvt *pvt; 01673 struct ast_channel *tmpc = NULL; 01674 char *dest = (char *)data; 01675 char *ext, *host; 01676 char *h323id = NULL; 01677 char tmp[256], tmp1[256]; 01678 01679 if (h323debug) 01680 ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data); 01681 01682 pvt = oh323_alloc(0); 01683 if (!pvt) { 01684 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data); 01685 return NULL; 01686 } 01687 oldformat = format; 01688 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 01689 if (!format) { 01690 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 01691 oh323_destroy(pvt); 01692 if (cause) 01693 *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 01694 return NULL; 01695 } 01696 ast_copy_string(tmp, dest, sizeof(tmp)); 01697 host = strchr(tmp, '@'); 01698 if (host) { 01699 *host = '\0'; 01700 host++; 01701 ext = tmp; 01702 } else { 01703 ext = strrchr(tmp, '/'); 01704 if (ext) 01705 *ext++ = '\0'; 01706 host = tmp; 01707 } 01708 strtok_r(host, "/", &(h323id)); 01709 if (!ast_strlen_zero(h323id)) { 01710 h323_set_id(h323id); 01711 } 01712 if (ext) { 01713 ast_copy_string(pvt->exten, ext, sizeof(pvt->exten)); 01714 } 01715 if (h323debug) 01716 ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host); 01717 01718 if (gatekeeper_disable) { 01719 if (create_addr(pvt, host)) { 01720 oh323_destroy(pvt); 01721 if (cause) 01722 *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01723 return NULL; 01724 } 01725 } 01726 else { 01727 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01728 pvt->jointcapability = pvt->options.capability; 01729 if (pvt->options.dtmfmode) { 01730 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01731 pvt->nonCodecCapability |= AST_RTP_DTMF; 01732 } else { 01733 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01734 } 01735 } 01736 } 01737 01738 ast_mutex_lock(&caplock); 01739 /* Generate unique channel identifier */ 01740 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique); 01741 tmp1[sizeof(tmp1)-1] = '\0'; 01742 ast_mutex_unlock(&caplock); 01743 01744 ast_mutex_lock(&pvt->lock); 01745 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1); 01746 ast_mutex_unlock(&pvt->lock); 01747 if (!tmpc) { 01748 oh323_destroy(pvt); 01749 if (cause) 01750 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 01751 } 01752 ast_update_use_count(); 01753 restart_monitor(); 01754 return tmpc; 01755 }
Definition at line 756 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().
00757 { 00758 /* Retrieve audio/etc from channel. Assumes pvt->lock is already held. */ 00759 struct ast_frame *f; 00760 00761 /* Only apply it for the first packet, we just need the correct ip/port */ 00762 if (pvt->options.nat) { 00763 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00764 pvt->options.nat = 0; 00765 } 00766 00767 f = ast_rtp_read(pvt->rtp); 00768 /* Don't send RFC2833 if we're not supposed to */ 00769 if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) { 00770 return &ast_null_frame; 00771 } 00772 if (pvt->owner) { 00773 /* We already hold the channel lock */ 00774 if (f->frametype == AST_FRAME_VOICE) { 00775 if (f->subclass != pvt->owner->nativeformats) { 00776 /* Try to avoid deadlock */ 00777 if (ast_channel_trylock(pvt->owner)) { 00778 ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n"); 00779 return &ast_null_frame; 00780 } 00781 if (h323debug) 00782 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 00783 pvt->owner->nativeformats = f->subclass; 00784 pvt->nativeformats = f->subclass; 00785 ast_set_read_format(pvt->owner, pvt->owner->readformat); 00786 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 00787 ast_channel_unlock(pvt->owner); 00788 } 00789 /* Do in-band DTMF detection */ 00790 if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) { 00791 if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) { 00792 if (!ast_channel_trylock(pvt->owner)) { 00793 f = ast_dsp_process(pvt->owner, pvt->vad, f); 00794 ast_channel_unlock(pvt->owner); 00795 } 00796 else 00797 ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n"); 00798 } else if (pvt->nativeformats && !pvt->noInbandDtmf) { 00799 ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass)); 00800 pvt->noInbandDtmf = 1; 00801 } 00802 if (f &&(f->frametype == AST_FRAME_DTMF)) { 00803 if (h323debug) 00804 ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass); 00805 } 00806 } 00807 } 00808 } 00809 return f; 00810 }
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 3056 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.
03057 { 03058 /* XXX Deal with Video */ 03059 struct oh323_pvt *pvt; 03060 struct sockaddr_in them; 03061 struct sockaddr_in us; 03062 char *mode; 03063 03064 if (!rtp) { 03065 return 0; 03066 } 03067 03068 mode = convertcap(chan->writeformat); 03069 pvt = (struct oh323_pvt *) chan->tech_pvt; 03070 if (!pvt) { 03071 ast_log(LOG_ERROR, "No Private Structure, this is bad\n"); 03072 return -1; 03073 } 03074 ast_rtp_get_peer(rtp, &them); 03075 ast_rtp_get_us(rtp, &us); 03076 #if 0 /* Native bridge still isn't ready */ 03077 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode); 03078 #endif 03079 return 0; 03080 }
static int oh323_simulate_dtmf_end | ( | void * | data | ) | [static] |
Definition at line 306 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(), oh323_pvt::curDTMF, oh323_pvt::DTMFsched, f, oh323_pvt::lock, and oh323_pvt::owner.
Referenced by __oh323_update_info(), and receive_digit().
00307 { 00308 struct oh323_pvt *pvt = data; 00309 00310 if (pvt) { 00311 ast_mutex_lock(&pvt->lock); 00312 /* Don't hold pvt lock while trying to lock the channel */ 00313 while(pvt->owner && ast_channel_trylock(pvt->owner)) { 00314 ast_mutex_unlock(&pvt->lock); 00315 usleep(1); 00316 ast_mutex_lock(&pvt->lock); 00317 } 00318 00319 if (pvt->owner) { 00320 struct ast_frame f = { 00321 .frametype = AST_FRAME_DTMF_END, 00322 .subclass = pvt->curDTMF, 00323 .samples = 0, 00324 .src = "SIMULATE_DTMF_END", 00325 }; 00326 ast_queue_frame(pvt->owner, &f); 00327 ast_channel_unlock(pvt->owner); 00328 } 00329 00330 pvt->DTMFsched = -1; 00331 ast_mutex_unlock(&pvt->lock); 00332 } 00333 00334 return 0; 00335 }
static void oh323_update_info | ( | struct ast_channel * | c | ) | [static] |
Definition at line 404 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().
00405 { 00406 struct oh323_pvt *pvt = c->tech_pvt; 00407 00408 if (pvt) { 00409 ast_mutex_lock(&pvt->lock); 00410 __oh323_update_info(c, pvt); 00411 ast_mutex_unlock(&pvt->lock); 00412 } 00413 }
static int oh323_write | ( | struct ast_channel * | c, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 837 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.
00838 { 00839 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00840 int res = 0; 00841 if (frame->frametype != AST_FRAME_VOICE) { 00842 if (frame->frametype == AST_FRAME_IMAGE) { 00843 return 0; 00844 } else { 00845 ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype); 00846 return 0; 00847 } 00848 } else { 00849 if (!(frame->subclass & c->nativeformats)) { 00850 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 00851 frame->subclass, c->nativeformats, c->readformat, c->writeformat); 00852 return 0; 00853 } 00854 } 00855 if (pvt) { 00856 ast_mutex_lock(&pvt->lock); 00857 if (pvt->rtp && !pvt->recvonly) 00858 res = ast_rtp_write(pvt->rtp, frame); 00859 __oh323_update_info(c, pvt); 00860 ast_mutex_unlock(&pvt->lock); 00861 } 00862 return res; 00863 }
static int progress | ( | unsigned | call_reference, | |
const char * | token, | |||
int | inband | |||
) | [static] |
Definition at line 2027 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().
02028 { 02029 struct oh323_pvt *pvt; 02030 02031 if (h323debug) 02032 ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated")); 02033 02034 pvt = find_call_locked(call_reference, token); 02035 if (!pvt) { 02036 ast_log(LOG_ERROR, "Private structure not found in progress.\n"); 02037 return -1; 02038 } 02039 if (!pvt->owner) { 02040 ast_mutex_unlock(&pvt->lock); 02041 ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n"); 02042 return -1; 02043 } 02044 update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING)); 02045 ast_mutex_unlock(&pvt->lock); 02046 02047 return 0; 02048 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 2967 of file chan_h323.c.
References ASTOBJ_CONTAINER_PRUNE_MARKED, oh323_destroy_peer(), and peerl.
Referenced by __expire_registry(), h323_do_reload(), reload_config(), and set_config().
02968 { 02969 /* Prune peers who still are supposed to be deleted */ 02970 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer); 02971 }
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 1501 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().
01502 { 01503 struct oh323_peer *peer; 01504 struct ast_variable *var; 01505 struct ast_variable *tmp; 01506 const char *addr; 01507 01508 /* First check on peer name */ 01509 if (peername) 01510 var = ast_load_realtime("h323", "name", peername, addr = NULL); 01511 else if (sin) /* Then check on IP address for dynamic peers */ 01512 var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), NULL); 01513 else 01514 return NULL; 01515 01516 if (!var) 01517 return NULL; 01518 01519 for (tmp = var; tmp; tmp = tmp->next) { 01520 /* If this is type=user, then skip this object. */ 01521 if (!strcasecmp(tmp->name, "type") && 01522 !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) { 01523 ast_variables_destroy(var); 01524 return NULL; 01525 } else if (!peername && !strcasecmp(tmp->name, "name")) { 01526 peername = tmp->value; 01527 } 01528 } 01529 01530 if (!peername) { /* Did not find peer in realtime */ 01531 ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr); 01532 ast_variables_destroy(var); 01533 return NULL; 01534 } 01535 01536 /* Peer found in realtime, now build it in memory */ 01537 peer = build_peer(peername, var, NULL, 1); 01538 01539 ast_variables_destroy(var); 01540 01541 return peer; 01542 }
static struct oh323_user* realtime_user | ( | const call_details_t * | cd | ) | [static] |
Definition at line 1403 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().
01404 { 01405 struct ast_variable *var, *tmp; 01406 struct oh323_user *user; 01407 char *username; 01408 01409 if (userbyalias) 01410 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL); 01411 else { 01412 username = (char *)NULL; 01413 var = ast_load_realtime("h323", "host", cd->sourceIp, NULL); 01414 } 01415 01416 if (!var) 01417 return NULL; 01418 01419 for (tmp = var; tmp; tmp = tmp->next) { 01420 if (!strcasecmp(tmp->name, "type") && 01421 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) { 01422 ast_variables_destroy(var); 01423 return NULL; 01424 } else if (!username && !strcasecmp(tmp->name, "name")) 01425 username = tmp->value; 01426 } 01427 01428 if (!username) { 01429 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp); 01430 ast_variables_destroy(var); 01431 return NULL; 01432 } 01433 01434 user = build_user(username, var, NULL, 1); 01435 01436 ast_variables_destroy(var); 01437 01438 return user; 01439 }
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 1774 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().
01775 { 01776 struct oh323_pvt *pvt; 01777 int res; 01778 01779 pvt = find_call_locked(call_reference, token); 01780 if (!pvt) { 01781 ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token); 01782 return -1; 01783 } 01784 if (h323debug) 01785 ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token); 01786 01787 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01788 if (digit == '!') 01789 res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH); 01790 else { 01791 struct ast_frame f = { 01792 .frametype = AST_FRAME_DTMF_END, 01793 .subclass = digit, 01794 .samples = duration * 8, 01795 .len = duration, 01796 .src = "SEND_DIGIT", 01797 }; 01798 if (digit == ' ') { /* signalUpdate message */ 01799 f.subclass = pvt->curDTMF; 01800 if (pvt->DTMFsched >= 0) { 01801 ast_sched_del(sched, pvt->DTMFsched); 01802 pvt->DTMFsched = -1; 01803 } 01804 } else { /* Regular input or signal message */ 01805 if (pvt->DTMFsched >= 0) { 01806 /* We still don't send DTMF END from previous event, send it now */ 01807 ast_sched_del(sched, pvt->DTMFsched); 01808 pvt->DTMFsched = -1; 01809 f.subclass = pvt->curDTMF; 01810 f.samples = f.len = 0; 01811 ast_queue_frame(pvt->owner, &f); 01812 /* Restore values */ 01813 f.subclass = digit; 01814 f.samples = duration * 8; 01815 f.len = duration; 01816 } 01817 if (duration) { /* This is a signal, signalUpdate follows */ 01818 f.frametype = AST_FRAME_DTMF_BEGIN; 01819 pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt); 01820 if (h323debug) 01821 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched); 01822 } 01823 pvt->curDTMF = digit; 01824 } 01825 res = ast_queue_frame(pvt->owner, &f); 01826 } 01827 ast_channel_unlock(pvt->owner); 01828 } else { 01829 if (digit == '!') 01830 pvt->newcontrol = AST_CONTROL_FLASH; 01831 else { 01832 pvt->newduration = duration; 01833 pvt->newdigit = digit; 01834 } 01835 res = 0; 01836 } 01837 ast_mutex_unlock(&pvt->lock); 01838 return res; 01839 }
static const char* redirectingreason2str | ( | int | redirectingreason | ) | [static] |
Definition at line 267 of file chan_h323.c.
Referenced by __oh323_new().
00268 { 00269 switch (redirectingreason) { 00270 case 0: 00271 return "UNKNOWN"; 00272 case 1: 00273 return "BUSY"; 00274 case 2: 00275 return "NO_REPLY"; 00276 case 0xF: 00277 return "UNCONDITIONAL"; 00278 default: 00279 return "NOREDIRECT"; 00280 } 00281 }
static int reload | ( | void | ) | [static] |
Definition at line 2995 of file chan_h323.c.
References h323_reload().
02996 { 02997 return h323_reload(0, 0, NULL); 02998 }
static int reload_config | ( | int | is_reload | ) | [static] |
Definition at line 2715 of file chan_h323.c.
References acceptAnonymous, ahp, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_jb_read_conf(), ast_log(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, bindaddr, build_user(), config, default_context, default_jbconf, 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_user(), tos, userbyalias, userl, and ast_variable::value.
Referenced by h323_do_reload(), iax2_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), misdn_reload(), and reload().
02716 { 02717 int format; 02718 struct ast_config *cfg, *ucfg; 02719 struct ast_variable *v; 02720 struct oh323_peer *peer = NULL; 02721 struct oh323_user *user = NULL; 02722 struct oh323_alias *alias = NULL; 02723 struct ast_hostent ahp; struct hostent *hp; 02724 char *cat; 02725 const char *utype; 02726 int is_user, is_peer, is_alias; 02727 char _gatekeeper[100]; 02728 int gk_discover, gk_disable, gk_changed; 02729 02730 cfg = ast_config_load(config); 02731 02732 /* We *must* have a config file otherwise stop immediately */ 02733 if (!cfg) { 02734 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02735 return 1; 02736 } 02737 02738 /* fire up the H.323 Endpoint */ 02739 if (!h323_end_point_exist()) { 02740 h323_end_point_create(); 02741 } 02742 ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper)); 02743 gk_discover = gatekeeper_discover; 02744 gk_disable = gatekeeper_disable; 02745 memset(&bindaddr, 0, sizeof(bindaddr)); 02746 memset(&global_options, 0, sizeof(global_options)); 02747 global_options.fastStart = 1; 02748 global_options.h245Tunneling = 1; 02749 global_options.dtmfcodec = 101; 02750 global_options.dtmfmode = H323_DTMF_RFC2833; 02751 global_options.capability = GLOBAL_CAPABILITY; 02752 global_options.bridge = 1; /* Do native bridging by default */ 02753 strcpy(default_context, "default"); 02754 h323_signalling_port = 1720; 02755 gatekeeper_disable = 1; 02756 gatekeeper_discover = 0; 02757 gkroute = 0; 02758 userbyalias = 1; 02759 acceptAnonymous = 1; 02760 tos = 0; 02761 02762 /* Copy the default jb config over global_jbconf */ 02763 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 02764 02765 /* Load configuration from users.conf */ 02766 ucfg = ast_config_load("users.conf"); 02767 if (ucfg) { 02768 struct ast_variable *gen; 02769 int genhas_h323; 02770 const char *has_h323; 02771 02772 genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323")); 02773 gen = ast_variable_browse(ucfg, "general"); 02774 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) { 02775 if (strcasecmp(cat, "general")) { 02776 has_h323 = ast_variable_retrieve(ucfg, cat, "hash323"); 02777 if (ast_true(has_h323) || (!has_h323 && genhas_h323)) { 02778 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 02779 if (user) { 02780 ASTOBJ_CONTAINER_LINK(&userl, user); 02781 ASTOBJ_UNREF(user, oh323_destroy_user); 02782 } 02783 } 02784 } 02785 } 02786 ast_config_destroy(ucfg); 02787 } 02788 02789 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 02790 /* handle jb conf */ 02791 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 02792 continue; 02793 /* Create the interface list */ 02794 if (!strcasecmp(v->name, "port")) { 02795 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02796 } else if (!strcasecmp(v->name, "bindaddr")) { 02797 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02798 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02799 } else { 02800 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02801 } 02802 } else if (!strcasecmp(v->name, "tos")) { 02803 if (sscanf(v->value, "%d", &format)) { 02804 tos = format & 0xff; 02805 } else if (!strcasecmp(v->value, "lowdelay")) { 02806 tos = IPTOS_LOWDELAY; 02807 } else if (!strcasecmp(v->value, "throughput")) { 02808 tos = IPTOS_THROUGHPUT; 02809 } else if (!strcasecmp(v->value, "reliability")) { 02810 tos = IPTOS_RELIABILITY; 02811 } else if (!strcasecmp(v->value, "mincost")) { 02812 tos = IPTOS_MINCOST; 02813 } else if (!strcasecmp(v->value, "none")) { 02814 tos = 0; 02815 } else { 02816 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02817 } 02818 } else if (!strcasecmp(v->name, "gatekeeper")) { 02819 if (!strcasecmp(v->value, "DISABLE")) { 02820 gatekeeper_disable = 1; 02821 } else if (!strcasecmp(v->value, "DISCOVER")) { 02822 gatekeeper_disable = 0; 02823 gatekeeper_discover = 1; 02824 } else { 02825 gatekeeper_disable = 0; 02826 ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper)); 02827 } 02828 } else if (!strcasecmp(v->name, "secret")) { 02829 ast_copy_string(secret, v->value, sizeof(secret)); 02830 } else if (!strcasecmp(v->name, "AllowGKRouted")) { 02831 gkroute = ast_true(v->value); 02832 } else if (!strcasecmp(v->name, "context")) { 02833 ast_copy_string(default_context, v->value, sizeof(default_context)); 02834 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context); 02835 } else if (!strcasecmp(v->name, "UserByAlias")) { 02836 userbyalias = ast_true(v->value); 02837 } else if (!strcasecmp(v->name, "AcceptAnonymous")) { 02838 acceptAnonymous = ast_true(v->value); 02839 } else if (!update_common_options(v, &global_options)) { 02840 /* dummy */ 02841 } 02842 } 02843 02844 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) { 02845 if (strcasecmp(cat, "general")) { 02846 utype = ast_variable_retrieve(cfg, cat, "type"); 02847 if (utype) { 02848 is_user = is_peer = is_alias = 0; 02849 if (!strcasecmp(utype, "user")) 02850 is_user = 1; 02851 else if (!strcasecmp(utype, "peer")) 02852 is_peer = 1; 02853 else if (!strcasecmp(utype, "friend")) 02854 is_user = is_peer = 1; 02855 else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) 02856 is_alias = 1; 02857 else { 02858 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config); 02859 continue; 02860 } 02861 if (is_user) { 02862 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 02863 if (user) { 02864 ASTOBJ_CONTAINER_LINK(&userl, user); 02865 ASTOBJ_UNREF(user, oh323_destroy_user); 02866 } 02867 } 02868 if (is_peer) { 02869 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 02870 if (peer) { 02871 ASTOBJ_CONTAINER_LINK(&peerl, peer); 02872 ASTOBJ_UNREF(peer, oh323_destroy_peer); 02873 } 02874 } 02875 if (is_alias) { 02876 alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0); 02877 if (alias) { 02878 ASTOBJ_CONTAINER_LINK(&aliasl, alias); 02879 ASTOBJ_UNREF(alias, oh323_destroy_alias); 02880 } 02881 } 02882 } else { 02883 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 02884 } 02885 } 02886 } 02887 ast_config_destroy(cfg); 02888 02889 /* Register our H.323 aliases if any*/ 02890 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 02891 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 02892 ASTOBJ_RDLOCK(iterator); 02893 if (h323_set_alias(iterator)) { 02894 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name); 02895 ASTOBJ_UNLOCK(iterator); 02896 continue; 02897 } 02898 ASTOBJ_UNLOCK(iterator); 02899 } while (0) ); 02900 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 02901 02902 /* Don't touch GK if nothing changed because URQ will drop all existing calls */ 02903 gk_changed = 0; 02904 if (gatekeeper_disable != gk_disable) 02905 gk_changed = is_reload; 02906 else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover)) 02907 gk_changed = is_reload; 02908 else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0)) 02909 gk_changed = is_reload; 02910 if (gk_changed) { 02911 if(!gk_disable) 02912 h323_gk_urq(); 02913 if (!gatekeeper_disable) { 02914 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 02915 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 02916 gatekeeper_disable = 1; 02917 } 02918 } 02919 } 02920 return 0; 02921 }
static int restart_monitor | ( | void | ) | [static] |
Definition at line 2513 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, and monitor_thread.
Referenced by h323_reload(), load_module(), mgcp_reload(), mgcp_request(), oh323_request(), phone_hangup(), phone_request(), setup_zap(), sip_reload(), sip_request_call(), skinny_request(), zt_hangup(), and zt_request().
02514 { 02515 pthread_attr_t attr; 02516 /* If we're supposed to be stopped -- stay stopped */ 02517 if (ast_mutex_lock(&monlock)) { 02518 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 02519 return -1; 02520 } 02521 if (monitor_thread == AST_PTHREADT_STOP) { 02522 ast_mutex_unlock(&monlock); 02523 return 0; 02524 } 02525 if (monitor_thread == pthread_self()) { 02526 ast_mutex_unlock(&monlock); 02527 ast_log(LOG_WARNING, "Cannot kill myself\n"); 02528 return -1; 02529 } 02530 if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) { 02531 /* Wake up the thread */ 02532 pthread_kill(monitor_thread, SIGURG); 02533 } else { 02534 pthread_attr_init(&attr); 02535 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02536 /* Start a new monitor */ 02537 if (ast_pthread_create_background(&monitor_thread, &attr, do_monitor, NULL) < 0) { 02538 monitor_thread = AST_PTHREADT_NULL; 02539 ast_mutex_unlock(&monlock); 02540 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 02541 pthread_attr_destroy(&attr); 02542 return -1; 02543 } 02544 pthread_attr_destroy(&attr); 02545 } 02546 ast_mutex_unlock(&monlock); 02547 return 0; 02548 }
static void set_dtmf_payload | ( | unsigned | call_reference, | |
const char * | token, | |||
int | payload | |||
) | [static] |
Definition at line 2372 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().
02373 { 02374 struct oh323_pvt *pvt; 02375 02376 if (h323debug) 02377 ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token); 02378 02379 pvt = find_call_locked(call_reference, token); 02380 if (!pvt) { 02381 return; 02382 } 02383 if (pvt->rtp) { 02384 ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event", 0); 02385 } 02386 pvt->dtmf_pt = payload; 02387 ast_mutex_unlock(&pvt->lock); 02388 if (h323debug) 02389 ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload); 02390 }
static void set_local_capabilities | ( | unsigned | call_reference, | |
const char * | token | |||
) | [static] |
Definition at line 2420 of file chan_h323.c.
References ast_log(), ast_mutex_unlock(), capability, dtmfmode, find_call_locked(), h323debug, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, oh323_pvt::options, oh323_pvt::pref_codec, and prefs.
Referenced by load_module().
02421 { 02422 struct oh323_pvt *pvt; 02423 int capability, dtmfmode, pref_codec; 02424 struct ast_codec_pref prefs; 02425 02426 if (h323debug) 02427 ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token); 02428 02429 pvt = find_call_locked(call_reference, token); 02430 if (!pvt) 02431 return; 02432 capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability; 02433 dtmfmode = pvt->options.dtmfmode; 02434 prefs = pvt->options.prefs; 02435 pref_codec = pvt->pref_codec; 02436 ast_mutex_unlock(&pvt->lock); 02437 h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec); 02438 02439 if (h323debug) 02440 ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token); 02441 }
static void set_peer_capabilities | ( | unsigned | call_reference, | |
const char * | token, | |||
int | capabilities, | |||
struct ast_codec_pref * | prefs | |||
) | [static] |
Definition at line 2392 of file chan_h323.c.
References ast_getformatname(), ast_log(), ast_mutex_unlock(), ast_rtp_codec_setpref(), find_call_locked(), ast_codec_pref::framing, h323debug, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, oh323_pvt::options, ast_codec_pref::order, oh323_pvt::peer_prefs, oh323_pvt::peercapability, prefs, and oh323_pvt::rtp.
Referenced by load_module().
02393 { 02394 struct oh323_pvt *pvt; 02395 02396 if (h323debug) 02397 ast_log(LOG_DEBUG, "Got remote capabilities from connection %s\n", token); 02398 02399 pvt = find_call_locked(call_reference, token); 02400 if (!pvt) 02401 return; 02402 pvt->peercapability = capabilities; 02403 pvt->jointcapability = pvt->options.capability & capabilities; 02404 if (prefs) { 02405 memcpy(&pvt->peer_prefs, prefs, sizeof(pvt->peer_prefs)); 02406 if (h323debug) { 02407 int i; 02408 for (i = 0; i < 32; ++i) { 02409 if (!prefs->order[i]) 02410 break; 02411 ast_log(LOG_DEBUG, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]); 02412 } 02413 } 02414 if (pvt->rtp) 02415 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 02416 } 02417 ast_mutex_unlock(&pvt->lock); 02418 }
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 2055 of file chan_h323.c.
References acceptAnonymous, oh323_pvt::accountcode, oh323_pvt::amaflags, 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().
02056 { 02057 struct oh323_pvt *pvt; 02058 struct oh323_user *user = NULL; 02059 struct oh323_alias *alias = NULL; 02060 02061 if (h323debug) 02062 ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token); 02063 02064 /* allocate the call*/ 02065 pvt = oh323_alloc(cd->call_reference); 02066 02067 if (!pvt) { 02068 ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n"); 02069 cleanup_call_details(cd); 02070 return NULL; 02071 } 02072 02073 /* Populate the call details in the private structure */ 02074 memcpy(&pvt->cd, cd, sizeof(pvt->cd)); 02075 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 02076 pvt->jointcapability = pvt->options.capability; 02077 02078 if (h323debug) { 02079 ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n"); 02080 ast_verbose(VERBOSE_PREFIX_3 " \tCall token: [%s]\n", pvt->cd.call_token); 02081 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party name: [%s]\n", pvt->cd.call_source_name); 02082 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party number: [%s]\n", pvt->cd.call_source_e164); 02083 ast_verbose(VERBOSE_PREFIX_3 " \tCalled party name: [%s]\n", pvt->cd.call_dest_alias); 02084 ast_verbose(VERBOSE_PREFIX_3 " \tCalled party number: [%s]\n", pvt->cd.call_dest_e164); 02085 if (pvt->cd.redirect_reason >= 0) 02086 ast_verbose(VERBOSE_PREFIX_3 " \tRedirecting party number: [%s] (reason %d)\n", pvt->cd.redirect_number, pvt->cd.redirect_reason); 02087 ast_verbose(VERBOSE_PREFIX_3 " \tCalling party IP: [%s]\n", pvt->cd.sourceIp); 02088 } 02089 02090 /* Decide if we are allowing Gatekeeper routed calls*/ 02091 if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) { 02092 if (!ast_strlen_zero(cd->call_dest_e164)) { 02093 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02094 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02095 } else { 02096 alias = find_alias(cd->call_dest_alias, 1); 02097 if (!alias) { 02098 ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias); 02099 oh323_destroy(pvt); 02100 return NULL; 02101 } 02102 ast_copy_string(pvt->exten, alias->name, sizeof(pvt->exten)); 02103 ast_copy_string(pvt->context, alias->context, sizeof(pvt->context)); 02104 } 02105 } else { 02106 /* Either this call is not from the Gatekeeper 02107 or we are not allowing gk routed calls */ 02108 user = find_user(cd, 1); 02109 if (!user) { 02110 if (!acceptAnonymous) { 02111 ast_log(LOG_NOTICE, "Anonymous call from '%s@%s' rejected\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp); 02112 oh323_destroy(pvt); 02113 return NULL; 02114 } 02115 if (ast_strlen_zero(default_context)) { 02116 ast_log(LOG_ERROR, "Call from '%s@%s' rejected due to no default context\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp); 02117 oh323_destroy(pvt); 02118 return NULL; 02119 } 02120 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02121 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { 02122 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02123 } else { 02124 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten)); 02125 } 02126 if (h323debug) 02127 ast_log(LOG_DEBUG, "Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->context, pvt->exten); 02128 } else { 02129 if (user->host) { 02130 if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) { 02131 if (ast_strlen_zero(user->context)) { 02132 if (ast_strlen_zero(default_context)) { 02133 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp); 02134 oh323_destroy(pvt); 02135 ASTOBJ_UNREF(user, oh323_destroy_user); 02136 return NULL; 02137 } 02138 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 02139 } else { 02140 ast_copy_string(pvt->context, user->context, sizeof(pvt->context)); 02141 } 02142 pvt->exten[0] = 'i'; 02143 pvt->exten[1] = '\0'; 02144 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp); 02145 oh323_destroy(pvt); 02146 ASTOBJ_UNREF(user, oh323_destroy_user); 02147 return NULL; /* XXX: Hmmm... Why to setup context if we drop connection immediately??? */ 02148 } 02149 } 02150 ast_copy_string(pvt->context, user->context, sizeof(pvt->context)); 02151 memcpy(&pvt->options, &user->options, sizeof(pvt->options)); 02152 pvt->jointcapability = pvt->options.capability; 02153 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { 02154 ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten)); 02155 } else { 02156 ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten)); 02157 } 02158 if (!ast_strlen_zero(user->accountcode)) { 02159 ast_copy_string(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode)); 02160 } 02161 if (user->amaflags) { 02162 pvt->amaflags = user->amaflags; 02163 } 02164 ASTOBJ_UNREF(user, oh323_destroy_user); 02165 } 02166 } 02167 return &pvt->options; 02168 }
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 2254 of file chan_h323.c.
References cleanup_call_details().
Referenced by load_module().
02255 { 02256 /* Use argument here or free it immediately */ 02257 cleanup_call_details(cd); 02258 02259 return 1; 02260 }
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 1895 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().
01896 { 01897 struct oh323_pvt *pvt; 01898 struct sockaddr_in them; 01899 struct rtpPayloadType rtptype; 01900 int nativeformats_changed; 01901 enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE; 01902 01903 if (h323debug) 01904 ast_log(LOG_DEBUG, "Setting up RTP connection for %s\n", token); 01905 01906 /* Find the call or allocate a private structure if call not found */ 01907 pvt = find_call_locked(call_reference, token); 01908 if (!pvt) { 01909 ast_log(LOG_ERROR, "Something is wrong: rtp\n"); 01910 return; 01911 } 01912 if (pvt->alreadygone) { 01913 ast_mutex_unlock(&pvt->lock); 01914 return; 01915 } 01916 01917 if (!pvt->rtp) 01918 __oh323_rtp_create(pvt); 01919 01920 them.sin_family = AF_INET; 01921 /* only works for IPv4 */ 01922 them.sin_addr.s_addr = inet_addr(remoteIp); 01923 them.sin_port = htons(remotePort); 01924 01925 if (them.sin_addr.s_addr) { 01926 ast_rtp_set_peer(pvt->rtp, &them); 01927 if (pvt->recvonly) { 01928 pvt->recvonly = 0; 01929 rtp_change = NEED_UNHOLD; 01930 } 01931 } else { 01932 ast_rtp_stop(pvt->rtp); 01933 if (!pvt->recvonly) { 01934 pvt->recvonly = 1; 01935 rtp_change = NEED_HOLD; 01936 } 01937 } 01938 01939 /* Change native format to reflect information taken from OLC/OLCAck */ 01940 nativeformats_changed = 0; 01941 if (pt != 128 && pvt->rtp) { /* Payload type is invalid, so try to use previously decided */ 01942 rtptype = ast_rtp_lookup_pt(pvt->rtp, pt); 01943 if (h323debug) 01944 ast_log(LOG_DEBUG, "Native format is set to %d from %d by RTP payload type %d\n", rtptype.code, pvt->nativeformats, pt); 01945 if (pvt->nativeformats != rtptype.code) { 01946 pvt->nativeformats = rtptype.code; 01947 nativeformats_changed = 1; 01948 } 01949 } else if (h323debug) 01950 ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n"); 01951 01952 /* Don't try to lock the channel if nothing changed */ 01953 if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) { 01954 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01955 /* Re-build translation path only if native format(s) has been changed */ 01956 if (pvt->owner->nativeformats != pvt->nativeformats) { 01957 if (h323debug) 01958 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); 01959 pvt->owner->nativeformats = pvt->nativeformats; 01960 ast_set_read_format(pvt->owner, pvt->owner->readformat); 01961 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 01962 } 01963 if (pvt->options.progress_audio) 01964 ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS); 01965 switch (rtp_change) { 01966 case NEED_HOLD: 01967 ast_queue_control(pvt->owner, AST_CONTROL_HOLD); 01968 break; 01969 case NEED_UNHOLD: 01970 ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD); 01971 break; 01972 default: 01973 break; 01974 } 01975 ast_channel_unlock(pvt->owner); 01976 } 01977 else { 01978 if (pvt->options.progress_audio) 01979 pvt->newcontrol = AST_CONTROL_PROGRESS; 01980 else if (rtp_change == NEED_HOLD) 01981 pvt->newcontrol = AST_CONTROL_HOLD; 01982 else if (rtp_change == NEED_UNHOLD) 01983 pvt->newcontrol = AST_CONTROL_UNHOLD; 01984 if (h323debug) 01985 ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token); 01986 } 01987 } 01988 ast_mutex_unlock(&pvt->lock); 01989 01990 if (h323debug) 01991 ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token); 01992 01993 return; 01994 }
static int unload_module | ( | void | ) | [static] |
Definition at line 3191 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, io, io_context_destroy(), oh323_pvt::lock, LOG_WARNING, monitor_thread, 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.
03192 { 03193 struct oh323_pvt *p, *pl; 03194 03195 /* unregister commands */ 03196 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03197 ast_cli_unregister(&cli_h323_reload); 03198 03199 ast_channel_unregister(&oh323_tech); 03200 ast_rtp_proto_unregister(&oh323_rtp); 03201 03202 if (!ast_mutex_lock(&iflock)) { 03203 /* hangup all interfaces if they have an owner */ 03204 p = iflist; 03205 while(p) { 03206 if (p->owner) { 03207 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 03208 } 03209 p = p->next; 03210 } 03211 iflist = NULL; 03212 ast_mutex_unlock(&iflock); 03213 } else { 03214 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 03215 return -1; 03216 } 03217 if (!ast_mutex_lock(&monlock)) { 03218 if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 03219 /* this causes a seg, anyone know why? */ 03220 if (monitor_thread != pthread_self()) 03221 pthread_cancel(monitor_thread); 03222 pthread_kill(monitor_thread, SIGURG); 03223 pthread_join(monitor_thread, NULL); 03224 } 03225 monitor_thread = AST_PTHREADT_STOP; 03226 ast_mutex_unlock(&monlock); 03227 } else { 03228 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03229 return -1; 03230 } 03231 if (!ast_mutex_lock(&iflock)) { 03232 /* destroy all the interfaces and free their memory */ 03233 p = iflist; 03234 while(p) { 03235 pl = p; 03236 p = p->next; 03237 /* free associated memory */ 03238 ast_mutex_destroy(&pl->lock); 03239 free(pl); 03240 } 03241 iflist = NULL; 03242 ast_mutex_unlock(&iflock); 03243 } else { 03244 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 03245 return -1; 03246 } 03247 if (!gatekeeper_disable) 03248 h323_gk_urq(); 03249 h323_end_process(); 03250 if (io) 03251 io_context_destroy(io); 03252 if (sched) 03253 sched_context_destroy(sched); 03254 03255 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03256 ASTOBJ_CONTAINER_DESTROY(&userl); 03257 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03258 ASTOBJ_CONTAINER_DESTROY(&peerl); 03259 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03260 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03261 03262 return 0; 03263 }
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_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, "disallow")) { 01262 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0); 01263 } else if (!strcasecmp(v->name, "dtmfmode")) { 01264 if (!strcasecmp(v->value, "inband")) { 01265 options->dtmfmode = H323_DTMF_INBAND; 01266 } else if (!strcasecmp(v->value, "rfc2833")) { 01267 options->dtmfmode = H323_DTMF_RFC2833; 01268 } else { 01269 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value); 01270 options->dtmfmode = H323_DTMF_RFC2833; 01271 } 01272 } else if (!strcasecmp(v->name, "dtmfcodec")) { 01273 tmp = atoi(v->value); 01274 if (tmp < 96) 01275 ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno); 01276 else 01277 options->dtmfcodec = tmp; 01278 } else if (!strcasecmp(v->name, "bridge")) { 01279 options->bridge = ast_true(v->value); 01280 } else if (!strcasecmp(v->name, "nat")) { 01281 options->nat = ast_true(v->value); 01282 } else if (!strcasecmp(v->name, "noFastStart")) { 01283 DEPRECATED(v, "fastStart"); 01284 options->fastStart = !ast_true(v->value); 01285 } else if (!strcasecmp(v->name, "fastStart")) { 01286 options->fastStart = ast_true(v->value); 01287 } else if (!strcasecmp(v->name, "noH245Tunneling")) { 01288 DEPRECATED(v, "h245Tunneling"); 01289 options->h245Tunneling = !ast_true(v->value); 01290 } else if (!strcasecmp(v->name, "h245Tunneling")) { 01291 options->h245Tunneling = ast_true(v->value); 01292 } else if (!strcasecmp(v->name, "noSilenceSuppression")) { 01293 DEPRECATED(v, "silenceSuppression"); 01294 options->silenceSuppression = !ast_true(v->value); 01295 } else if (!strcasecmp(v->name, "silenceSuppression")) { 01296 options->silenceSuppression = ast_true(v->value); 01297 } else if (!strcasecmp(v->name, "progress_setup")) { 01298 tmp = atoi(v->value); 01299 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) { 01300 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno); 01301 tmp = 0; 01302 } 01303 options->progress_setup = tmp; 01304 } else if (!strcasecmp(v->name, "progress_alert")) { 01305 tmp = atoi(v->value); 01306 if ((tmp != 0) && (tmp != 1) && (tmp != 8)) { 01307 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno); 01308 tmp = 0; 01309 } 01310 options->progress_alert = tmp; 01311 } else if (!strcasecmp(v->name, "progress_audio")) { 01312 options->progress_audio = ast_true(v->value); 01313 } else if (!strcasecmp(v->name, "callerid")) { 01314 ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num)); 01315 } else if (!strcasecmp(v->name, "fullname")) { 01316 ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name)); 01317 } else if (!strcasecmp(v->name, "cid_number")) { 01318 ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num)); 01319 } else if (!strcasecmp(v->name, "tunneling")) { 01320 if (!strcasecmp(v->value, "none")) 01321 options->tunnelOptions = 0; 01322 else if (!strcasecmp(v->value, "cisco")) 01323 options->tunnelOptions |= H323_TUNNEL_CISCO; 01324 else if (!strcasecmp(v->value, "qsig")) 01325 options->tunnelOptions |= H323_TUNNEL_QSIG; 01326 else 01327 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno); 01328 } else 01329 return 1; 01330 01331 return 0; 01332 }
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 }
int acceptAnonymous = 1 [static] |
Definition at line 150 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().
struct sockaddr_in bindaddr [static] |
Definition at line 138 of file chan_h323.c.
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 2670 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 2680 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 2665 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 2660 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 3000 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 2675 of file chan_h323.c.
const char config[] = "h323.conf" [static] |
Definition at line 136 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 2636 of file chan_h323.c.
char default_context[AST_MAX_CONTEXT] = "default" [static] |
Definition at line 137 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 125 of file chan_h323.c.
char gatekeeper[100] [static] |
Definition at line 144 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 145 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 146 of file chan_h323.c.
Referenced by h323_gk_cycle(), load_module(), and reload_config().
int gkroute = 0 [static] |
Definition at line 147 of file chan_h323.c.
Referenced by reload_config(), and setup_incoming_call().
struct ast_jb_conf global_jbconf [static] |
Definition at line 132 of file chan_h323.c.
call_options_t global_options [static] |
Definition at line 155 of file chan_h323.c.
Referenced by build_peer(), build_user(), create_addr(), oh323_request(), reload_config(), and setup_incoming_call().
char h323_reload_usage[] [static] |
Initial value:
"Usage: h323 reload\n" " Reloads H.323 configuration from h323.conf\n"
Definition at line 2656 of file chan_h323.c.
int h323_reloading = 0 [static] |
int h323_signalling_port = 1720 [static] |
H.323 configuration values
Definition at line 143 of file chan_h323.c.
Referenced by build_peer(), create_addr(), load_module(), and reload_config().
int h323debug |
Definition at line 122 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().
Private structure of a OpenH323 channel
Referenced by __oh323_destroy(), __sip_destroy(), __sip_show_channels(), __unload_module(), action_zapshowchannels(), chandup(), complete_sipch(), destroy_channel(), do_monitor(), find_call(), find_call_locked(), find_channel(), get_sip_pvt_byid_locked(), handle_request_subscribe(), load_module(), mkintf(), oh323_alloc(), phone_request(), sip_alloc(), sip_show_channel(), sip_show_history(), unload_module(), zap_destroy_channel_bynum(), zap_restart(), zap_show_channel(), zap_show_channels(), zt_hangup(), and zt_request().
struct io_context* io [static] |
Definition at line 213 of file chan_h323.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
Definition at line 231 of file chan_h323.c.
Referenced by load_module(), reload_config(), restart_monitor(), stop_monitor(), and unload_module().
char no_debug_usage[] [static] |
Initial value:
"Usage: h.323 debug off\n" " Disables H.323 debug output\n"
Definition at line 2640 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 2632 of file chan_h323.c.
struct ast_rtp_protocol oh323_rtp [static] |
struct ast_channel_tech oh323_tech [static] |
Definition at line 246 of file chan_h323.c.
Referenced by __oh323_new(), load_module(), and unload_module().
answer_call_cb on_answer_call |
Definition at line 114 of file chan_h323.c.
chan_ringing_cb on_chan_ringing |
Definition at line 111 of file chan_h323.c.
clear_con_cb on_connection_cleared |
Definition at line 113 of file chan_h323.c.
con_established_cb on_connection_established |
Definition at line 112 of file chan_h323.c.
on_rtp_cb on_external_rtp_create |
Definition at line 107 of file chan_h323.c.
hangup_cb on_hangup |
Definition at line 117 of file chan_h323.c.
setup_incoming_cb on_incoming_call |
Definition at line 109 of file chan_h323.c.
setup_outbound_cb on_outgoing_call |
Definition at line 110 of file chan_h323.c.
progress_cb on_progress |
Definition at line 115 of file chan_h323.c.
receive_digit_cb on_receive_digit |
Definition at line 106 of file chan_h323.c.
rfc2833_cb on_set_rfc2833_payload |
Definition at line 116 of file chan_h323.c.
setcapabilities_cb on_setcapabilities |
Definition at line 118 of file chan_h323.c.
setpeercapabilities_cb on_setpeercapabilities |
Definition at line 119 of file chan_h323.c.
start_rtp_cb on_start_rtp_channel |
Definition at line 108 of file chan_h323.c.
struct ast_peer_list peerl [static] |
struct sched_context* sched [static] |
Asterisk RTP stuff
Definition at line 212 of file chan_h323.c.
char secret[50] [static] |
Definition at line 152 of file chan_h323.c.
Referenced by add_realm_authentication(), aji_act_hook(), build_reply_digest(), h323_gk_cycle(), load_module(), read_agent_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 2644 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 2648 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 2652 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 135 of file chan_h323.c.
int tos = 0 [static] |
Definition at line 151 of file chan_h323.c.
Referenced by load_module(), reload_config(), and set_config().
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 2628 of file chan_h323.c.
unsigned int unique = 0 [static] |
int userbyalias = 1 [static] |
Definition at line 149 of file chan_h323.c.
Referenced by find_user(), realtime_user(), and reload_config().
struct ast_user_list userl [static] |