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