#include "asterisk.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/musiconhold.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/dsp.h"
#include "asterisk/causes.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/astobj.h"
#include "h323/chan_h323.h"
Go to the source code of this file.
Data Structures | |
struct | ast_alias_list |
struct | ast_peer_list |
The peer list: Peers and Friends. More... | |
struct | ast_user_list |
The user list: Users and friends. More... | |
struct | oh323_pvt |
struct | rtpPayloadType |
Structure representing a RTP session. 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 (const void *data) |
static void | oh323_update_info (struct ast_channel *c) |
static int | oh323_write (struct ast_channel *c, struct ast_frame *frame) |
static int | progress (unsigned call_reference, const char *token, int inband) |
static void | prune_peers (void) |
static struct oh323_alias * | realtime_alias (const char *alias) |
static struct oh323_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static struct oh323_user * | realtime_user (const call_details_t *cd) |
static int | receive_digit (unsigned call_reference, char digit, const char *token, int duration) |
static const char * | redirectingreason2str (int redirectingreason) |
static int | reload (void) |
static int | reload_config (int is_reload) |
static int | restart_monitor (void) |
static void | set_dtmf_payload (unsigned call_reference, const char *token, int payload) |
static void | set_local_capabilities (unsigned call_reference, const char *token) |
static void | set_peer_capabilities (unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs) |
static call_options_t * | setup_incoming_call (call_details_t *cd) |
static int | setup_outgoing_call (call_details_t *cd) |
static void | setup_rtp_connection (unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt) |
static int | unload_module (void) |
static int | update_common_options (struct ast_variable *v, struct call_options *options) |
static int | update_state (struct oh323_pvt *pvt, int state, int signal) |
Variables | |
static 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 |
struct 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 450 of file chan_h323.c.
References ast_channel_lock, ast_channel_unlock, ast_dsp_free(), ast_log(), ast_mutex_destroy(), ast_mutex_unlock(), ast_rtp_destroy(), AST_SCHED_DEL, oh323_pvt::cd, cleanup_call_details(), oh323_pvt::DTMFsched, free, iflist, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_pvt::next, oh323_pvt::owner, oh323_pvt::rtp, ast_channel::tech_pvt, and oh323_pvt::vad.
Referenced by do_monitor(), and oh323_destroy().
00451 { 00452 struct oh323_pvt *cur, *prev = NULL; 00453 00454 AST_SCHED_DEL(sched, pvt->DTMFsched); 00455 00456 if (pvt->rtp) { 00457 ast_rtp_destroy(pvt->rtp); 00458 } 00459 00460 /* Free dsp used for in-band DTMF detection */ 00461 if (pvt->vad) { 00462 ast_dsp_free(pvt->vad); 00463 } 00464 cleanup_call_details(&pvt->cd); 00465 00466 /* Unlink us from the owner if we have one */ 00467 if (pvt->owner) { 00468 ast_channel_lock(pvt->owner); 00469 if (h323debug) 00470 ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name); 00471 pvt->owner->tech_pvt = NULL; 00472 ast_channel_unlock(pvt->owner); 00473 } 00474 cur = iflist; 00475 while(cur) { 00476 if (cur == pvt) { 00477 if (prev) 00478 prev->next = cur->next; 00479 else 00480 iflist = cur->next; 00481 break; 00482 } 00483 prev = cur; 00484 cur = cur->next; 00485 } 00486 if (!cur) { 00487 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur); 00488 } else { 00489 ast_mutex_unlock(&pvt->lock); 00490 ast_mutex_destroy(&pvt->lock); 00491 free(pvt); 00492 } 00493 }
static struct ast_channel* __oh323_new | ( | struct oh323_pvt * | pvt, | |
int | state, | |||
const char * | host | |||
) | [static, read] |
Definition at line 1003 of file chan_h323.c.
References accountcode, oh323_pvt::accountcode, ast_channel::amaflags, oh323_pvt::amaflags, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_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_pvt::options, oh323_pvt::owner, pbx_builtin_setvar_helper(), ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, redirectingreason2str(), ast_channel::rings, oh323_pvt::rtp, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, oh323_pvt::vad, and ast_channel::writeformat.
Referenced by answer_call(), and oh323_request().
01004 { 01005 struct ast_channel *ch; 01006 char *cid_num, *cid_name; 01007 int fmt; 01008 01009 if (!ast_strlen_zero(pvt->options.cid_num)) 01010 cid_num = pvt->options.cid_num; 01011 else 01012 cid_num = pvt->cd.call_source_e164; 01013 01014 if (!ast_strlen_zero(pvt->options.cid_name)) 01015 cid_name = pvt->options.cid_name; 01016 else 01017 cid_name = pvt->cd.call_source_name; 01018 01019 /* Don't hold a oh323_pvt lock while we allocate a chanel */ 01020 ast_mutex_unlock(&pvt->lock); 01021 ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host); 01022 /* Update usage counter */ 01023 ast_module_ref(ast_module_info->self); 01024 ast_mutex_lock(&pvt->lock); 01025 if (ch) { 01026 ch->tech = &oh323_tech; 01027 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability)) 01028 fmt = global_options.capability; 01029 ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/; 01030 pvt->nativeformats = ch->nativeformats; 01031 fmt = ast_best_codec(ch->nativeformats); 01032 ch->writeformat = fmt; 01033 ch->rawwriteformat = fmt; 01034 ch->readformat = fmt; 01035 ch->rawreadformat = fmt; 01036 #if 0 01037 ch->fds[0] = ast_rtp_fd(pvt->rtp); 01038 ch->fds[1] = ast_rtcp_fd(pvt->rtp); 01039 #endif 01040 #ifdef VIDEO_SUPPORT 01041 if (pvt->vrtp) { 01042 ch->fds[2] = ast_rtp_fd(pvt->vrtp); 01043 ch->fds[3] = ast_rtcp_fd(pvt->vrtp); 01044 } 01045 #endif 01046 #ifdef T38_SUPPORT 01047 if (pvt->udptl) { 01048 ch->fds[4] = ast_udptl_fd(pvt->udptl); 01049 } 01050 #endif 01051 if (state == AST_STATE_RING) { 01052 ch->rings = 1; 01053 } 01054 /* Allocate dsp for in-band DTMF support */ 01055 if (pvt->options.dtmfmode & H323_DTMF_INBAND) { 01056 pvt->vad = ast_dsp_new(); 01057 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT); 01058 } 01059 /* Register channel functions. */ 01060 ch->tech_pvt = pvt; 01061 /* Set the owner of this channel */ 01062 pvt->owner = ch; 01063 01064 ast_copy_string(ch->context, pvt->context, sizeof(ch->context)); 01065 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten)); 01066 ch->priority = 1; 01067 if (!ast_strlen_zero(pvt->accountcode)) { 01068 ast_string_field_set(ch, accountcode, pvt->accountcode); 01069 } 01070 if (pvt->amaflags) { 01071 ch->amaflags = pvt->amaflags; 01072 } 01073 01074 /* Don't use ast_set_callerid() here because it will 01075 * generate a needless NewCallerID event */ 01076 ch->cid.cid_ani = ast_strdup(cid_num); 01077 01078 if (pvt->cd.redirect_reason >= 0) { 01079 ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number); 01080 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason)); 01081 } 01082 ch->cid.cid_pres = pvt->cd.presentation; 01083 ch->cid.cid_ton = pvt->cd.type_of_number; 01084 01085 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) { 01086 ch->cid.cid_dnid = strdup(pvt->exten); 01087 } 01088 if (pvt->cd.transfer_capability >= 0) 01089 ch->transfercapability = pvt->cd.transfer_capability; 01090 if (state != AST_STATE_DOWN) { 01091 if (ast_pbx_start(ch)) { 01092 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name); 01093 ast_hangup(ch); 01094 ch = NULL; 01095 } 01096 } 01097 } else { 01098 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 01099 } 01100 return ch; 01101 }
static int __oh323_rtp_create | ( | struct oh323_pvt * | pvt | ) | [static] |
Definition at line 957 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, ast_find_ourip(), ast_jb_configure(), ast_log(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), ast_rtcp_fd(), ast_rtp_codec_setpref(), ast_rtp_fd(), ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpmap_type(), ast_rtp_setnat(), ast_rtp_settos(), bindaddr, oh323_pvt::dtmf_pt, errno, ast_channel::fds, global_jbconf, 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, and oh323_pvt::update_rtp_info.
Referenced by external_rtp_create(), and setup_rtp_connection().
00958 { 00959 struct in_addr our_addr; 00960 00961 if (pvt->rtp) 00962 return 0; 00963 00964 if (ast_find_ourip(&our_addr, bindaddr)) { 00965 ast_mutex_unlock(&pvt->lock); 00966 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n"); 00967 return -1; 00968 } 00969 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr); 00970 if (!pvt->rtp) { 00971 ast_mutex_unlock(&pvt->lock); 00972 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); 00973 return -1; 00974 } 00975 if (h323debug) 00976 ast_log(LOG_DEBUG, "Created RTP channel\n"); 00977 00978 ast_rtp_settos(pvt->rtp, tos); 00979 00980 if (h323debug) 00981 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat); 00982 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00983 00984 if (pvt->dtmf_pt > 0) 00985 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt, "audio", "telephone-event", 0); 00986 00987 if (pvt->peercapability) 00988 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 00989 00990 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 00991 ast_jb_configure(pvt->owner, &global_jbconf); 00992 pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp); 00993 pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp); 00994 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00995 ast_channel_unlock(pvt->owner); 00996 } else 00997 pvt->update_rtp_info = 1; 00998 00999 return 0; 01000 }
static void __oh323_update_info | ( | struct ast_channel * | c, | |
struct oh323_pvt * | pvt | |||
) | [static] |
Definition at line 339 of file chan_h323.c.
References ast_channel::_softhangup, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_jb_configure(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_rtcp_fd(), ast_rtp_fd(), ast_sched_add(), AST_SCHED_DEL, ast_set_read_format(), ast_set_write_format(), ast_setstate(), AST_SOFTHANGUP_DEV, oh323_pvt::curDTMF, oh323_pvt::DTMFsched, ast_channel::fds, ast_frame::frametype, 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, ast_frame::subclass, oh323_pvt::update_rtp_info, and ast_channel::writeformat.
Referenced by oh323_read(), oh323_update_info(), and oh323_write().
00340 { 00341 if (c->nativeformats != pvt->nativeformats) { 00342 if (h323debug) 00343 ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name); 00344 c->nativeformats = pvt->nativeformats; 00345 ast_set_read_format(c, c->readformat); 00346 ast_set_write_format(c, c->writeformat); 00347 } 00348 if (pvt->needhangup) { 00349 if (h323debug) 00350 ast_log(LOG_DEBUG, "Process pending hangup for %s\n", c->name); 00351 c->_softhangup |= AST_SOFTHANGUP_DEV; 00352 c->hangupcause = pvt->hangupcause; 00353 ast_queue_hangup(c); 00354 pvt->needhangup = 0; 00355 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1; 00356 } 00357 if (pvt->newstate >= 0) { 00358 ast_setstate(c, pvt->newstate); 00359 pvt->newstate = -1; 00360 } 00361 if (pvt->newcontrol >= 0) { 00362 ast_queue_control(c, pvt->newcontrol); 00363 pvt->newcontrol = -1; 00364 } 00365 if (pvt->newdigit >= 0) { 00366 struct ast_frame f = { 00367 .frametype = AST_FRAME_DTMF_END, 00368 .subclass = pvt->newdigit, 00369 .samples = pvt->newduration * 8, 00370 .len = pvt->newduration, 00371 .src = "UPDATE_INFO", 00372 }; 00373 if (pvt->newdigit == ' ') { /* signalUpdate message */ 00374 f.subclass = pvt->curDTMF; 00375 if (pvt->DTMFsched >= 0) { 00376 AST_SCHED_DEL(sched, pvt->DTMFsched); 00377 } 00378 } else { /* Regular input or signal message */ 00379 if (pvt->newduration) { /* This is a signal, signalUpdate follows */ 00380 f.frametype = AST_FRAME_DTMF_BEGIN; 00381 AST_SCHED_DEL(sched, pvt->DTMFsched); 00382 pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt); 00383 if (h323debug) 00384 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched); 00385 } 00386 pvt->curDTMF = pvt->newdigit; 00387 } 00388 ast_queue_frame(c, &f); 00389 pvt->newdigit = -1; 00390 } 00391 if (pvt->update_rtp_info > 0) { 00392 if (pvt->rtp) { 00393 ast_jb_configure(c, &global_jbconf); 00394 c->fds[0] = ast_rtp_fd(pvt->rtp); 00395 c->fds[1] = ast_rtcp_fd(pvt->rtp); 00396 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00397 } 00398 pvt->update_rtp_info = -1; 00399 } 00400 }
static 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(), 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, read] |
Definition at line 1194 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.
Referenced by realtime_alias(), and reload_config().
01195 { 01196 struct oh323_alias *alias; 01197 int found = 0; 01198 01199 alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp); 01200 01201 if (alias) 01202 found++; 01203 else { 01204 if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias)))) 01205 return NULL; 01206 ASTOBJ_INIT(alias); 01207 } 01208 if (!found && name) 01209 ast_copy_string(alias->name, name, sizeof(alias->name)); 01210 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01211 if (!strcasecmp(v->name, "e164")) { 01212 ast_copy_string(alias->e164, v->value, sizeof(alias->e164)); 01213 } else if (!strcasecmp(v->name, "prefix")) { 01214 ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix)); 01215 } else if (!strcasecmp(v->name, "context")) { 01216 ast_copy_string(alias->context, v->value, sizeof(alias->context)); 01217 } else if (!strcasecmp(v->name, "secret")) { 01218 ast_copy_string(alias->secret, v->value, sizeof(alias->secret)); 01219 } else { 01220 if (strcasecmp(v->value, "h323")) { 01221 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name); 01222 } 01223 } 01224 } 01225 ASTOBJ_UNMARK(alias); 01226 return alias; 01227 }
static struct oh323_peer* build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static, read] |
Definition at line 1443 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, 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().
01444 { 01445 struct oh323_peer *peer; 01446 struct ast_ha *oldha; 01447 int found = 0; 01448 01449 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 01450 01451 if (peer) 01452 found++; 01453 else { 01454 if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer)))) 01455 return NULL; 01456 ASTOBJ_INIT(peer); 01457 } 01458 oldha = peer->ha; 01459 peer->ha = NULL; 01460 memcpy(&peer->options, &global_options, sizeof(peer->options)); 01461 peer->addr.sin_port = htons(h323_signalling_port); 01462 peer->addr.sin_family = AF_INET; 01463 if (!found && name) 01464 ast_copy_string(peer->name, name, sizeof(peer->name)); 01465 01466 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01467 if (peer->chanvars) { 01468 ast_variables_destroy(peer->chanvars); 01469 peer->chanvars = NULL; 01470 } 01471 #endif 01472 /* Default settings for mailbox */ 01473 peer->mailbox[0] = '\0'; 01474 01475 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01476 if (!update_common_options(v, &peer->options)) 01477 continue; 01478 if (!strcasecmp(v->name, "host")) { 01479 if (!strcasecmp(v->value, "dynamic")) { 01480 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n"); 01481 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01482 return NULL; 01483 } 01484 if (ast_get_ip(&peer->addr, v->value)) { 01485 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value); 01486 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01487 return NULL; 01488 } 01489 } else if (!strcasecmp(v->name, "port")) { 01490 peer->addr.sin_port = htons(atoi(v->value)); 01491 } else if (!strcasecmp(v->name, "permit") || 01492 !strcasecmp(v->name, "deny")) { 01493 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 01494 } else if (!strcasecmp(v->name, "mailbox")) { 01495 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 01496 } 01497 } 01498 ASTOBJ_UNMARK(peer); 01499 ast_free_ha(oldha); 01500 return peer; 01501 }
static struct oh323_user* build_user | ( | char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | realtime | |||
) | [static, read] |
Definition at line 1337 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, format, 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().
01338 { 01339 struct oh323_user *user; 01340 struct ast_ha *oldha; 01341 int found = 0; 01342 int format; 01343 01344 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp); 01345 01346 if (user) 01347 found++; 01348 else { 01349 if (!(user = (struct oh323_user *)calloc(1, sizeof(*user)))) 01350 return NULL; 01351 ASTOBJ_INIT(user); 01352 } 01353 oldha = user->ha; 01354 user->ha = (struct ast_ha *)NULL; 01355 memcpy(&user->options, &global_options, sizeof(user->options)); 01356 /* Set default context */ 01357 ast_copy_string(user->context, default_context, sizeof(user->context)); 01358 if (user && !found) 01359 ast_copy_string(user->name, name, sizeof(user->name)); 01360 01361 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01362 if (user->chanvars) { 01363 ast_variables_destroy(user->chanvars); 01364 user->chanvars = NULL; 01365 } 01366 #endif 01367 01368 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01369 if (!update_common_options(v, &user->options)) 01370 continue; 01371 if (!strcasecmp(v->name, "context")) { 01372 ast_copy_string(user->context, v->value, sizeof(user->context)); 01373 } else if (!strcasecmp(v->name, "secret")) { 01374 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 01375 } else if (!strcasecmp(v->name, "accountcode")) { 01376 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 01377 } else if (!strcasecmp(v->name, "host")) { 01378 if (!strcasecmp(v->value, "dynamic")) { 01379 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n"); 01380 ASTOBJ_UNREF(user, oh323_destroy_user); 01381 return NULL; 01382 } else if (ast_get_ip(&user->addr, v->value)) { 01383 ASTOBJ_UNREF(user, oh323_destroy_user); 01384 return NULL; 01385 } 01386 /* Let us know we need to use ip authentication */ 01387 user->host = 1; 01388 } else if (!strcasecmp(v->name, "amaflags")) { 01389 format = ast_cdr_amaflags2int(v->value); 01390 if (format < 0) { 01391 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 01392 } else { 01393 user->amaflags = format; 01394 } 01395 } else if (!strcasecmp(v->name, "permit") || 01396 !strcasecmp(v->name, "deny")) { 01397 user->ha = ast_append_ha(v->name, v->value, user->ha); 01398 } 01399 } 01400 ASTOBJ_UNMARK(user); 01401 ast_free_ha(oldha); 01402 return user; 01403 }
static void chan_ringing | ( | unsigned | call_reference, | |
const char * | token | |||
) | [static] |
Call-back function to signal asterisk that the channel is ringing Returns nothing
Definition at line 2264 of file chan_h323.c.
References AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, find_call_locked(), oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state().
Referenced by load_module().
02265 { 02266 struct oh323_pvt *pvt; 02267 02268 if (h323debug) 02269 ast_log(LOG_DEBUG, "Ringing on %s\n", token); 02270 02271 pvt = find_call_locked(call_reference, token); 02272 if (!pvt) { 02273 ast_log(LOG_ERROR, "Something is wrong: ringing\n"); 02274 return; 02275 } 02276 if (!pvt->owner) { 02277 ast_mutex_unlock(&pvt->lock); 02278 ast_log(LOG_ERROR, "Channel has no owner\n"); 02279 return; 02280 } 02281 update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING); 02282 ast_mutex_unlock(&pvt->lock); 02283 return; 02284 }
static void cleanup_call_details | ( | call_details_t * | cd | ) | [static] |
Definition at line 414 of file chan_h323.c.
References free.
Referenced by __oh323_destroy(), cleanup_connection(), setup_incoming_call(), and setup_outgoing_call().
00415 { 00416 if (cd->call_token) { 00417 free(cd->call_token); 00418 cd->call_token = NULL; 00419 } 00420 if (cd->call_source_aliases) { 00421 free(cd->call_source_aliases); 00422 cd->call_source_aliases = NULL; 00423 } 00424 if (cd->call_dest_alias) { 00425 free(cd->call_dest_alias); 00426 cd->call_dest_alias = NULL; 00427 } 00428 if (cd->call_source_name) { 00429 free(cd->call_source_name); 00430 cd->call_source_name = NULL; 00431 } 00432 if (cd->call_source_e164) { 00433 free(cd->call_source_e164); 00434 cd->call_source_e164 = NULL; 00435 } 00436 if (cd->call_dest_e164) { 00437 free(cd->call_dest_e164); 00438 cd->call_dest_e164 = NULL; 00439 } 00440 if (cd->sourceIp) { 00441 free(cd->sourceIp); 00442 cd->sourceIp = NULL; 00443 } 00444 if (cd->redirect_number) { 00445 free(cd->redirect_number); 00446 cd->redirect_number = NULL; 00447 } 00448 }
static void cleanup_connection | ( | unsigned | call_reference, | |
const char * | call_token | |||
) | [static] |
Call-back function to cleanup communication Returns nothing,
Definition at line 2290 of file chan_h323.c.
References ast_channel::_softhangup, oh323_pvt::alreadygone, ast_channel_trylock, ast_channel_unlock, ast_dsp_free(), ast_log(), ast_mutex_unlock(), ast_queue_hangup(), ast_rtp_destroy(), AST_SOFTHANGUP_DEV, oh323_pvt::cd, cleanup_call_details(), find_call_locked(), 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(), 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 3039 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().
03040 { 03041 switch (cap) { 03042 case AST_FORMAT_G723_1: 03043 return "G.723"; 03044 case AST_FORMAT_GSM: 03045 return "GSM"; 03046 case AST_FORMAT_ULAW: 03047 return "ULAW"; 03048 case AST_FORMAT_ALAW: 03049 return "ALAW"; 03050 case AST_FORMAT_G722: 03051 return "G.722"; 03052 case AST_FORMAT_ADPCM: 03053 return "G.728"; 03054 case AST_FORMAT_G729A: 03055 return "G.729"; 03056 case AST_FORMAT_SPEEX: 03057 return "SPEEX"; 03058 case AST_FORMAT_ILBC: 03059 return "ILBC"; 03060 default: 03061 ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap); 03062 return NULL; 03063 } 03064 }
static int create_addr | ( | struct oh323_pvt * | pvt, | |
char * | opeer | |||
) | [static] |
Definition at line 1599 of file chan_h323.c.
References ast_gethostbyname(), ast_log(), AST_RTP_DTMF, ASTOBJ_UNREF, find_peer(), hp, oh323_pvt::jointcapability, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_destroy_peer(), oh323_pvt::options, portno, and oh323_pvt::sa.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_provision(), iax2_request(), oh323_request(), sip_notify(), sip_request_call(), and transmit_register().
01600 { 01601 struct hostent *hp; 01602 struct ast_hostent ahp; 01603 struct oh323_peer *p; 01604 int portno; 01605 int found = 0; 01606 char *port; 01607 char *hostn; 01608 char peer[256] = ""; 01609 01610 ast_copy_string(peer, opeer, sizeof(peer)); 01611 port = strchr(peer, ':'); 01612 if (port) { 01613 *port = '\0'; 01614 port++; 01615 } 01616 pvt->sa.sin_family = AF_INET; 01617 p = find_peer(peer, NULL, 1); 01618 if (p) { 01619 found++; 01620 memcpy(&pvt->options, &p->options, sizeof(pvt->options)); 01621 pvt->jointcapability = pvt->options.capability; 01622 if (pvt->options.dtmfmode) { 01623 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01624 pvt->nonCodecCapability |= AST_RTP_DTMF; 01625 } else { 01626 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01627 } 01628 } 01629 if (p->addr.sin_addr.s_addr) { 01630 pvt->sa.sin_addr = p->addr.sin_addr; 01631 pvt->sa.sin_port = p->addr.sin_port; 01632 } 01633 ASTOBJ_UNREF(p, oh323_destroy_peer); 01634 } 01635 if (!p && !found) { 01636 hostn = peer; 01637 if (port) { 01638 portno = atoi(port); 01639 } else { 01640 portno = h323_signalling_port; 01641 } 01642 hp = ast_gethostbyname(hostn, &ahp); 01643 if (hp) { 01644 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 01645 pvt->sa.sin_port = htons(portno); 01646 /* Look peer by address */ 01647 p = find_peer(NULL, &pvt->sa, 1); 01648 memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options)); 01649 pvt->jointcapability = pvt->options.capability; 01650 if (p) { 01651 ASTOBJ_UNREF(p, oh323_destroy_peer); 01652 } 01653 if (pvt->options.dtmfmode) { 01654 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01655 pvt->nonCodecCapability |= AST_RTP_DTMF; 01656 } else { 01657 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01658 } 01659 } 01660 return 0; 01661 } else { 01662 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01663 return -1; 01664 } 01665 } else if (!found) { 01666 return -1; 01667 } else { 01668 return 0; 01669 } 01670 }
static void delete_aliases | ( | void | ) | [static] |
Definition at line 2739 of file chan_h323.c.
References aliasl, ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and oh323_destroy_alias().
Referenced by reload_config().
02740 { 02741 int pruned = 0; 02742 02743 /* Delete all aliases */ 02744 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 02745 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 02746 ASTOBJ_RDLOCK(iterator); 02747 ASTOBJ_MARK(iterator); 02748 ++pruned; 02749 ASTOBJ_UNLOCK(iterator); 02750 } while (0) ); 02751 if (pruned) { 02752 ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias); 02753 } 02754 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 02755 }
static void delete_users | ( | void | ) | [static] |
Definition at line 2713 of file chan_h323.c.
References ASTOBJ_CONTAINER_PRUNE_MARKED, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, oh323_destroy_user(), peerl, and userl.
Referenced by __unload_module(), reload_config(), and set_config_destroy().
02714 { 02715 int pruned = 0; 02716 02717 /* Delete all users */ 02718 ASTOBJ_CONTAINER_WRLOCK(&userl); 02719 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 02720 ASTOBJ_RDLOCK(iterator); 02721 ASTOBJ_MARK(iterator); 02722 ++pruned; 02723 ASTOBJ_UNLOCK(iterator); 02724 } while (0) ); 02725 if (pruned) { 02726 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user); 02727 } 02728 ASTOBJ_CONTAINER_UNLOCK(&userl); 02729 02730 ASTOBJ_CONTAINER_WRLOCK(&peerl); 02731 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 02732 ASTOBJ_RDLOCK(iterator); 02733 ASTOBJ_MARK(iterator); 02734 ASTOBJ_UNLOCK(iterator); 02735 } while (0) ); 02736 ASTOBJ_CONTAINER_UNLOCK(&peerl); 02737 }
static void* do_monitor | ( | void * | data | ) | [static] |
Definition at line 2441 of file chan_h323.c.
References __oh323_destroy(), ast_io_wait(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_verbose(), h323_do_reload(), 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, read] |
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, 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, read] |
Find a call by alias
Definition at line 1760 of file chan_h323.c.
References aliasl, ASTOBJ_CONTAINER_FIND, and realtime_alias().
Referenced by __get_header(), add_header(), and setup_incoming_call().
01761 { 01762 struct oh323_alias *a; 01763 01764 a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases); 01765 01766 if (!a && realtime) 01767 a = realtime_alias(source_aliases); 01768 01769 return a; 01770 }
static struct oh323_pvt* find_call_locked | ( | int | call_reference, | |
const char * | token | |||
) | [static, read] |
Definition at line 1147 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().
01148 { 01149 struct oh323_pvt *pvt; 01150 01151 ast_mutex_lock(&iflock); 01152 pvt = iflist; 01153 while(pvt) { 01154 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) { 01155 /* Found the call */ 01156 if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) { 01157 ast_mutex_lock(&pvt->lock); 01158 ast_mutex_unlock(&iflock); 01159 return pvt; 01160 } else if (token == NULL) { 01161 ast_log(LOG_WARNING, "Call Token is NULL\n"); 01162 ast_mutex_lock(&pvt->lock); 01163 ast_mutex_unlock(&iflock); 01164 return pvt; 01165 } 01166 } 01167 pvt = pvt->next; 01168 } 01169 ast_mutex_unlock(&iflock); 01170 return NULL; 01171 }
static struct oh323_peer* find_peer | ( | const char * | peer, | |
struct sockaddr_in * | sin, | |||
int | realtime | |||
) | [static, read] |
Definition at line 1581 of file chan_h323.c.
References ast_inet_ntoa(), ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, LOG_DEBUG, oh323_addrcmp(), peerl, and realtime_peer().
Referenced by _sip_show_peer(), check_user_full(), create_addr(), dundi_encrypt(), function_iaxpeer(), function_sippeer(), handle_command_response(), iax2_devicestate(), iax2_prune_realtime(), iax2_show_peer(), register_verify(), registry_authrequest(), set_config(), sip_devicestate(), sip_do_debug_peer(), sip_peer_hold(), update_call_counter(), and update_registry().
01582 { 01583 struct oh323_peer *p; 01584 01585 if (peer) 01586 p = ASTOBJ_CONTAINER_FIND(&peerl, peer); 01587 else 01588 p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp); 01589 01590 if (!p && realtime) 01591 p = realtime_peer(peer, sin); 01592 01593 if (!p && h323debug) 01594 ast_log(LOG_DEBUG, "Could not find peer by name %s or address %s\n", (peer ? peer : "<NONE>"), (sin ? ast_inet_ntoa(sin->sin_addr) : "<NONE>")); 01595 01596 return p; 01597 }
static struct oh323_user* find_user | ( | const call_details_t * | cd, | |
int | realtime | |||
) | [static, read] |
Definition at line 1551 of file chan_h323.c.
References ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, LOG_DEBUG, oh323_addrcmp_str(), realtime_user(), and userl.
Referenced by admin_exec(), advanced_options(), check_user_full(), forward_message(), leave_voicemail(), setup_incoming_call(), sip_show_user(), update_call_counter(), vm_authenticate(), vm_box_exists(), and vm_execmain().
01552 { 01553 struct oh323_user *u; 01554 01555 if (userbyalias) 01556 u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases); 01557 else 01558 u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str); 01559 01560 if (!u && realtime) 01561 u = realtime_user(cd); 01562 01563 if (!u && h323debug) 01564 ast_log(LOG_DEBUG, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp); 01565 01566 return u; 01567 }
static int h323_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2568 of file chan_h323.c.
References ast_cli(), 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 2995 of file chan_h323.c.
References reload_config().
Referenced by do_monitor().
02996 { 02997 reload_config(1); 02998 return 0; 02999 }
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(), LOG_ERROR, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
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(), 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 2982 of file chan_h323.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), and restart_monitor().
Referenced by reload().
02983 { 02984 ast_mutex_lock(&h323_reload_lock); 02985 if (h323_reloading) { 02986 ast_verbose("Previous H.323 reload not yet done\n"); 02987 } else { 02988 h323_reloading = 1; 02989 } 02990 ast_mutex_unlock(&h323_reload_lock); 02991 restart_monitor(); 02992 return 0; 02993 }
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(), 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 3099 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(), connection_made(), external_rtp_create(), hangup_connection(), io_context_create(), io_context_destroy(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, oh323_destroy_alias(), oh323_destroy_peer(), oh323_destroy_user(), peerl, receive_digit(), reload_config(), restart_monitor(), sched_context_create(), sched_context_destroy(), set_dtmf_payload(), set_local_capabilities(), set_peer_capabilities(), setup_incoming_call(), setup_outgoing_call(), setup_rtp_connection(), and userl.
03100 { 03101 int res; 03102 03103 h323debug = 0; 03104 sched = sched_context_create(); 03105 if (!sched) { 03106 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 03107 return AST_MODULE_LOAD_FAILURE; 03108 } 03109 io = io_context_create(); 03110 if (!io) { 03111 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 03112 return AST_MODULE_LOAD_FAILURE; 03113 } 03114 ast_cli_register(&cli_h323_reload); 03115 ASTOBJ_CONTAINER_INIT(&userl); 03116 ASTOBJ_CONTAINER_INIT(&peerl); 03117 ASTOBJ_CONTAINER_INIT(&aliasl); 03118 res = reload_config(0); 03119 if (res) { 03120 /* No config entry */ 03121 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n"); 03122 ast_cli_unregister(&cli_h323_reload); 03123 io_context_destroy(io); 03124 io = NULL; 03125 sched_context_destroy(sched); 03126 sched = NULL; 03127 ASTOBJ_CONTAINER_DESTROY(&userl); 03128 ASTOBJ_CONTAINER_DESTROY(&peerl); 03129 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03130 return AST_MODULE_LOAD_DECLINE; 03131 } else { 03132 /* Make sure we can register our channel type */ 03133 if (ast_channel_register(&oh323_tech)) { 03134 ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n"); 03135 ast_cli_unregister(&cli_h323_reload); 03136 h323_end_process(); 03137 io_context_destroy(io); 03138 sched_context_destroy(sched); 03139 03140 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03141 ASTOBJ_CONTAINER_DESTROY(&userl); 03142 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03143 ASTOBJ_CONTAINER_DESTROY(&peerl); 03144 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03145 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03146 03147 return AST_MODULE_LOAD_FAILURE; 03148 } 03149 ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03150 03151 ast_rtp_proto_register(&oh323_rtp); 03152 03153 /* Register our callback functions */ 03154 h323_callback_register(setup_incoming_call, 03155 setup_outgoing_call, 03156 external_rtp_create, 03157 setup_rtp_connection, 03158 cleanup_connection, 03159 chan_ringing, 03160 connection_made, 03161 receive_digit, 03162 answer_call, 03163 progress, 03164 set_dtmf_payload, 03165 hangup_connection, 03166 set_local_capabilities, 03167 set_peer_capabilities); 03168 /* start the h.323 listener */ 03169 if (h323_start_listener(h323_signalling_port, bindaddr)) { 03170 ast_log(LOG_ERROR, "Unable to create H323 listener.\n"); 03171 ast_rtp_proto_unregister(&oh323_rtp); 03172 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03173 ast_cli_unregister(&cli_h323_reload); 03174 h323_end_process(); 03175 io_context_destroy(io); 03176 sched_context_destroy(sched); 03177 03178 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03179 ASTOBJ_CONTAINER_DESTROY(&userl); 03180 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03181 ASTOBJ_CONTAINER_DESTROY(&peerl); 03182 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03183 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03184 03185 return AST_MODULE_LOAD_FAILURE; 03186 } 03187 /* Possibly register with a GK */ 03188 if (!gatekeeper_disable) { 03189 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 03190 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 03191 gatekeeper_disable = 1; 03192 res = AST_MODULE_LOAD_SUCCESS; 03193 } 03194 } 03195 /* And start the monitor for the first time */ 03196 restart_monitor(); 03197 } 03198 return res; 03199 }
static int oh323_addrcmp | ( | struct sockaddr_in | addr, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 1569 of file chan_h323.c.
References inaddrcmp().
Referenced by find_peer().
01570 { 01571 int res; 01572 01573 if (!sin) 01574 res = -1; 01575 else 01576 res = inaddrcmp(&addr , sin); 01577 01578 return res; 01579 }
static int oh323_addrcmp_str | ( | struct in_addr | inaddr, | |
char * | addr | |||
) | [static] |
Definition at line 1546 of file chan_h323.c.
References ast_inet_ntoa().
Referenced by find_user().
01547 { 01548 return strcmp(ast_inet_ntoa(inaddr), addr); 01549 }
static struct oh323_pvt* oh323_alloc | ( | int | callid | ) | [static, read] |
Definition at line 1103 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().
01104 { 01105 struct oh323_pvt *pvt; 01106 01107 pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt)); 01108 if (!pvt) { 01109 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n"); 01110 return NULL; 01111 } 01112 memset(pvt, 0, sizeof(struct oh323_pvt)); 01113 pvt->cd.redirect_reason = -1; 01114 pvt->cd.transfer_capability = -1; 01115 /* Ensure the call token is allocated for outgoing call */ 01116 if (!callid) { 01117 if ((pvt->cd).call_token == NULL) { 01118 (pvt->cd).call_token = (char *)malloc(128); 01119 } 01120 if (!pvt->cd.call_token) { 01121 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n"); 01122 ast_rtp_destroy(pvt->rtp); 01123 free(pvt); 01124 return NULL; 01125 } 01126 memset((char *)(pvt->cd).call_token, 0, 128); 01127 pvt->cd.call_reference = callid; 01128 } 01129 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01130 pvt->jointcapability = pvt->options.capability; 01131 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01132 pvt->nonCodecCapability |= AST_RTP_DTMF; 01133 } else { 01134 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01135 } 01136 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 01137 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1; 01138 ast_mutex_init(&pvt->lock); 01139 /* Add to interface list */ 01140 ast_mutex_lock(&iflock); 01141 pvt->next = iflist; 01142 iflist = pvt; 01143 ast_mutex_unlock(&iflock); 01144 return pvt; 01145 }
static int oh323_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 663 of file chan_h323.c.
References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, oh323_pvt::cd, free, oh323_pvt::lock, LOG_DEBUG, oh323_update_info(), strdup, and ast_channel::tech_pvt.
00664 { 00665 int res; 00666 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00667 char *token; 00668 00669 if (h323debug) 00670 ast_log(LOG_DEBUG, "Answering on %s\n", c->name); 00671 00672 ast_mutex_lock(&pvt->lock); 00673 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00674 ast_mutex_unlock(&pvt->lock); 00675 res = h323_answering_call(token, 0); 00676 if (token) 00677 free(token); 00678 00679 oh323_update_info(c); 00680 if (c->_state != AST_STATE_UP) { 00681 ast_setstate(c, AST_STATE_UP); 00682 } 00683 return res; 00684 }
static int oh323_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Make a call over the specified channel to the specified destination. Returns -1 on error, 0 on success.
Definition at line 584 of file chan_h323.c.
References ast_channel::_state, ast_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.
00585 { 00586 int res = 0; 00587 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00588 const char *addr; 00589 char called_addr[1024]; 00590 00591 if (h323debug) { 00592 ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name); 00593 } 00594 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 00595 ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name); 00596 return -1; 00597 } 00598 ast_mutex_lock(&pvt->lock); 00599 if (!gatekeeper_disable) { 00600 if (ast_strlen_zero(pvt->exten)) { 00601 ast_copy_string(called_addr, dest, sizeof(called_addr)); 00602 } else { 00603 snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest); 00604 } 00605 } else { 00606 res = htons(pvt->sa.sin_port); 00607 addr = ast_inet_ntoa(pvt->sa.sin_addr); 00608 if (ast_strlen_zero(pvt->exten)) { 00609 snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res); 00610 } else { 00611 snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res); 00612 } 00613 } 00614 /* make sure null terminated */ 00615 called_addr[sizeof(called_addr) - 1] = '\0'; 00616 00617 if (c->cid.cid_num) 00618 ast_copy_string(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num)); 00619 00620 if (c->cid.cid_name) 00621 ast_copy_string(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name)); 00622 00623 if (c->cid.cid_rdnis) { 00624 ast_copy_string(pvt->options.cid_rdnis, c->cid.cid_rdnis, sizeof(pvt->options.cid_rdnis)); 00625 } 00626 00627 pvt->options.presentation = c->cid.cid_pres; 00628 pvt->options.type_of_number = c->cid.cid_ton; 00629 00630 if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) { 00631 if (!strcasecmp(addr, "UNKNOWN")) 00632 pvt->options.redirect_reason = 0; 00633 else if (!strcasecmp(addr, "BUSY")) 00634 pvt->options.redirect_reason = 1; 00635 else if (!strcasecmp(addr, "NO_REPLY")) 00636 pvt->options.redirect_reason = 2; 00637 else if (!strcasecmp(addr, "UNCONDITIONAL")) 00638 pvt->options.redirect_reason = 15; 00639 else 00640 pvt->options.redirect_reason = -1; 00641 } else 00642 pvt->options.redirect_reason = -1; 00643 00644 pvt->options.transfer_capability = c->transfercapability; 00645 00646 /* indicate that this is an outgoing call */ 00647 pvt->outgoing = 1; 00648 00649 if (option_verbose > 2) 00650 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability)); 00651 if (h323debug) 00652 ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec); 00653 ast_mutex_unlock(&pvt->lock); 00654 res = h323_make_call(called_addr, &(pvt->cd), &pvt->options); 00655 if (res) { 00656 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name); 00657 return -1; 00658 } 00659 oh323_update_info(c); 00660 return 0; 00661 }
static void oh323_destroy | ( | struct oh323_pvt * | pvt | ) | [static] |
Definition at line 495 of file chan_h323.c.
References __oh323_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, LOG_DEBUG, and oh323_pvt::owner.
Referenced by oh323_request(), and setup_incoming_call().
00496 { 00497 if (h323debug) { 00498 ast_log(LOG_DEBUG, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>")); 00499 } 00500 ast_mutex_lock(&iflock); 00501 ast_mutex_lock(&pvt->lock); 00502 __oh323_destroy(pvt); 00503 ast_mutex_unlock(&iflock); 00504 }
static void oh323_destroy_alias | ( | struct oh323_alias * | alias | ) | [static] |
Definition at line 284 of file chan_h323.c.
References ast_log(), free, and LOG_DEBUG.
Referenced by delete_aliases(), load_module(), reload_config(), and unload_module().
00285 { 00286 if (h323debug) 00287 ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name); 00288 free(alias); 00289 }
static void oh323_destroy_peer | ( | struct oh323_peer * | peer | ) | [static] |
Definition at line 299 of file chan_h323.c.
References ast_free_ha(), ast_log(), free, and LOG_DEBUG.
Referenced by build_peer(), create_addr(), load_module(), prune_peers(), reload_config(), and unload_module().
00300 { 00301 if (h323debug) 00302 ast_log(LOG_DEBUG, "Destroying peer '%s'\n", peer->name); 00303 ast_free_ha(peer->ha); 00304 free(peer); 00305 }
static void oh323_destroy_user | ( | struct oh323_user * | user | ) | [static] |
Definition at line 291 of file chan_h323.c.
References ast_free_ha(), ast_log(), free, and LOG_DEBUG.
Referenced by build_user(), delete_users(), load_module(), reload_config(), setup_incoming_call(), and unload_module().
00292 { 00293 if (h323debug) 00294 ast_log(LOG_DEBUG, "Destroying user '%s'\n", user->name); 00295 ast_free_ha(user->ha); 00296 free(user); 00297 }
static int oh323_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 506 of file chan_h323.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_begin(), oh323_pvt::cd, oh323_pvt::dtmf_pt, free, oh323_pvt::lock, LOG_DTMF, LOG_ERROR, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, ast_channel::tech_pvt, and oh323_pvt::txDtmfDigit.
00507 { 00508 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00509 char *token; 00510 00511 if (!pvt) { 00512 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00513 return -1; 00514 } 00515 ast_mutex_lock(&pvt->lock); 00516 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) { 00517 /* out-of-band DTMF */ 00518 if (h323debug) { 00519 ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name); 00520 } 00521 ast_rtp_senddigit_begin(pvt->rtp, digit); 00522 ast_mutex_unlock(&pvt->lock); 00523 } else if (pvt->txDtmfDigit != digit) { 00524 /* in-band DTMF */ 00525 if (h323debug) { 00526 ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name); 00527 } 00528 pvt->txDtmfDigit = digit; 00529 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00530 ast_mutex_unlock(&pvt->lock); 00531 h323_send_tone(token, digit); 00532 if (token) { 00533 free(token); 00534 } 00535 } else 00536 ast_mutex_unlock(&pvt->lock); 00537 oh323_update_info(c); 00538 return 0; 00539 }
static int oh323_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Send (play) the specified digit to the channel.
Definition at line 545 of file chan_h323.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_end(), oh323_pvt::cd, oh323_pvt::dtmf_pt, free, oh323_pvt::lock, LOG_DTMF, LOG_ERROR, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, ast_channel::tech_pvt, and oh323_pvt::txDtmfDigit.
00546 { 00547 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00548 char *token; 00549 00550 if (!pvt) { 00551 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00552 return -1; 00553 } 00554 ast_mutex_lock(&pvt->lock); 00555 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && (pvt->dtmf_pt > 0)) { 00556 /* out-of-band DTMF */ 00557 if (h323debug) { 00558 ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, c->name, duration); 00559 } 00560 ast_rtp_senddigit_end(pvt->rtp, digit); 00561 ast_mutex_unlock(&pvt->lock); 00562 } else { 00563 /* in-band DTMF */ 00564 if (h323debug) { 00565 ast_log(LOG_DTMF, "End sending inband digit %c on %s, duration %d\n", digit, c->name, duration); 00566 } 00567 pvt->txDtmfDigit = ' '; 00568 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00569 ast_mutex_unlock(&pvt->lock); 00570 h323_send_tone(token, ' '); 00571 if (token) { 00572 free(token); 00573 } 00574 } 00575 oh323_update_info(c); 00576 return 0; 00577 }
static int oh323_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 943 of file chan_h323.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, LOG_WARNING, oh323_pvt::owner, and ast_channel::tech_pvt.
00944 { 00945 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt; 00946 00947 ast_mutex_lock(&pvt->lock); 00948 if (pvt->owner != oldchan) { 00949 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner); 00950 return -1; 00951 } 00952 pvt->owner = newchan; 00953 ast_mutex_unlock(&pvt->lock); 00954 return 0; 00955 }
static enum ast_rtp_get_result oh323_get_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 3016 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.
03017 { 03018 struct oh323_pvt *pvt; 03019 enum ast_rtp_get_result res = AST_RTP_GET_FAILED; 03020 03021 if (!(pvt = (struct oh323_pvt *)chan->tech_pvt)) 03022 return res; 03023 03024 ast_mutex_lock(&pvt->lock); 03025 if (pvt->rtp && pvt->options.bridge) { 03026 *rtp = pvt->rtp; 03027 res = AST_RTP_TRY_NATIVE; 03028 } 03029 ast_mutex_unlock(&pvt->lock); 03030 03031 return res; 03032 }
static enum ast_rtp_get_result oh323_get_vrtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp ** | rtp | |||
) | [static] |
Definition at line 3034 of file chan_h323.c.
References AST_RTP_GET_FAILED.
03035 { 03036 return AST_RTP_GET_FAILED; 03037 }
static int oh323_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 686 of file chan_h323.c.
References oh323_pvt::alreadygone, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, AST_CAUSE_NORMAL_CLEARING, AST_CAUSE_REQUESTED_CHAN_UNAVAIL, AST_CAUSE_USER_BUSY, ast_log(), ast_module_unref(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::cd, free, oh323_pvt::hangupcause, ast_channel::hangupcause, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_pvt::needdestroy, oh323_pvt::owner, pbx_builtin_getvar_helper(), strdup, and ast_channel::tech_pvt.
00687 { 00688 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00689 int q931cause = AST_CAUSE_NORMAL_CLEARING; 00690 char *call_token; 00691 00692 00693 if (h323debug) 00694 ast_log(LOG_DEBUG, "Hanging up and scheduling destroy of call %s\n", c->name); 00695 00696 if (!c->tech_pvt) { 00697 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 00698 return 0; 00699 } 00700 ast_mutex_lock(&pvt->lock); 00701 /* Determine how to disconnect */ 00702 if (pvt->owner != c) { 00703 ast_log(LOG_WARNING, "Huh? We aren't the owner?\n"); 00704 ast_mutex_unlock(&pvt->lock); 00705 return 0; 00706 } 00707 00708 pvt->owner = NULL; 00709 c->tech_pvt = NULL; 00710 00711 if (c->hangupcause) { 00712 q931cause = c->hangupcause; 00713 } else { 00714 const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 00715 if (cause) { 00716 if (!strcmp(cause, "CONGESTION")) { 00717 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 00718 } else if (!strcmp(cause, "BUSY")) { 00719 q931cause = AST_CAUSE_USER_BUSY; 00720 } else if (!strcmp(cause, "CHANISUNVAIL")) { 00721 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; 00722 } else if (!strcmp(cause, "NOANSWER")) { 00723 q931cause = AST_CAUSE_NO_ANSWER; 00724 } else if (!strcmp(cause, "CANCEL")) { 00725 q931cause = AST_CAUSE_CALL_REJECTED; 00726 } 00727 } 00728 } 00729 00730 /* Start the process if it's not already started */ 00731 if (!pvt->alreadygone && !pvt->hangupcause) { 00732 call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00733 if (call_token) { 00734 /* Release lock to eliminate deadlock */ 00735 ast_mutex_unlock(&pvt->lock); 00736 if (h323_clear_call(call_token, q931cause)) { 00737 ast_log(LOG_WARNING, "ClearCall failed.\n"); 00738 } 00739 free(call_token); 00740 ast_mutex_lock(&pvt->lock); 00741 } 00742 } 00743 pvt->needdestroy = 1; 00744 ast_mutex_unlock(&pvt->lock); 00745 00746 /* Update usage counter */ 00747 ast_module_unref(ast_module_info->self); 00748 00749 return 0; 00750 }
static int oh323_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 861 of file chan_h323.c.
References ast_channel::_state, oh323_pvt::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_change_source(), ast_rtp_update_source(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, oh323_pvt::cd, free, oh323_pvt::got_progress, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_update_info(), oh323_pvt::rtp, strdup, and ast_channel::tech_pvt.
00862 { 00863 00864 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00865 char *token = (char *)NULL; 00866 int res = -1; 00867 int got_progress; 00868 00869 ast_mutex_lock(&pvt->lock); 00870 token = (pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL); 00871 got_progress = pvt->got_progress; 00872 if (condition == AST_CONTROL_PROGRESS) 00873 pvt->got_progress = 1; 00874 else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION)) 00875 pvt->alreadygone = 1; 00876 ast_mutex_unlock(&pvt->lock); 00877 00878 if (h323debug) 00879 ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token); 00880 00881 switch(condition) { 00882 case AST_CONTROL_RINGING: 00883 if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) { 00884 h323_send_alerting(token); 00885 res = (got_progress ? 0 : -1); /* Do not simulate any audio tones if we got PROGRESS message */ 00886 } 00887 break; 00888 case AST_CONTROL_PROGRESS: 00889 if (c->_state != AST_STATE_UP) { 00890 /* Do not send PROGRESS message more than once */ 00891 if (!got_progress) 00892 h323_send_progress(token); 00893 res = 0; 00894 } 00895 break; 00896 case AST_CONTROL_BUSY: 00897 if (c->_state != AST_STATE_UP) { 00898 h323_answering_call(token, 1); 00899 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00900 res = 0; 00901 } 00902 break; 00903 case AST_CONTROL_CONGESTION: 00904 if (c->_state != AST_STATE_UP) { 00905 h323_answering_call(token, 1); 00906 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00907 res = 0; 00908 } 00909 break; 00910 case AST_CONTROL_HOLD: 00911 ast_moh_start(c, data, NULL); 00912 res = 0; 00913 break; 00914 case AST_CONTROL_UNHOLD: 00915 ast_moh_stop(c); 00916 res = 0; 00917 break; 00918 case AST_CONTROL_SRCUPDATE: 00919 ast_rtp_update_source(pvt->rtp); 00920 res = 0; 00921 break; 00922 case AST_CONTROL_SRCCHANGE: 00923 ast_rtp_change_source(pvt->rtp); 00924 res = 0; 00925 break; 00926 case AST_CONTROL_PROCEEDING: 00927 case -1: 00928 break; 00929 default: 00930 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token); 00931 break; 00932 } 00933 00934 if (h323debug) 00935 ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res); 00936 if (token) 00937 free(token); 00938 oh323_update_info(c); 00939 00940 return res; 00941 }
static struct ast_frame * oh323_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 808 of file chan_h323.c.
References __oh323_update_info(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_null_frame, ast_rtcp_read(), ast_channel::fdno, oh323_pvt::lock, LOG_ERROR, oh323_rtp_read(), oh323_pvt::rtp, and ast_channel::tech_pvt.
00809 { 00810 struct ast_frame *fr; 00811 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00812 ast_mutex_lock(&pvt->lock); 00813 __oh323_update_info(c, pvt); 00814 switch(c->fdno) { 00815 case 0: 00816 fr = oh323_rtp_read(pvt); 00817 break; 00818 case 1: 00819 if (pvt->rtp) 00820 fr = ast_rtcp_read(pvt->rtp); 00821 else 00822 fr = &ast_null_frame; 00823 break; 00824 default: 00825 ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name); 00826 fr = &ast_null_frame; 00827 break; 00828 } 00829 ast_mutex_unlock(&pvt->lock); 00830 return fr; 00831 }
static struct ast_channel * oh323_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static, read] |
Definition at line 1671 of file chan_h323.c.
References __oh323_new(), AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INCOMPATIBLE_DESTINATION, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_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, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_alloc(), oh323_destroy(), oh323_pvt::options, and restart_monitor().
01672 { 01673 int oldformat; 01674 struct oh323_pvt *pvt; 01675 struct ast_channel *tmpc = NULL; 01676 char *dest = (char *)data; 01677 char *ext, *host; 01678 char *h323id = NULL; 01679 char tmp[256], tmp1[256]; 01680 01681 if (h323debug) 01682 ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data); 01683 01684 pvt = oh323_alloc(0); 01685 if (!pvt) { 01686 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data); 01687 return NULL; 01688 } 01689 oldformat = format; 01690 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 01691 if (!format) { 01692 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 01693 oh323_destroy(pvt); 01694 if (cause) 01695 *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 01696 return NULL; 01697 } 01698 ast_copy_string(tmp, dest, sizeof(tmp)); 01699 host = strchr(tmp, '@'); 01700 if (host) { 01701 *host = '\0'; 01702 host++; 01703 ext = tmp; 01704 } else { 01705 ext = strrchr(tmp, '/'); 01706 if (ext) 01707 *ext++ = '\0'; 01708 host = tmp; 01709 } 01710 strtok_r(host, "/", &(h323id)); 01711 if (!ast_strlen_zero(h323id)) { 01712 h323_set_id(h323id); 01713 } 01714 if (ext) { 01715 ast_copy_string(pvt->exten, ext, sizeof(pvt->exten)); 01716 } 01717 if (h323debug) 01718 ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host); 01719 01720 if (gatekeeper_disable) { 01721 if (create_addr(pvt, host)) { 01722 oh323_destroy(pvt); 01723 if (cause) 01724 *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01725 return NULL; 01726 } 01727 } 01728 else { 01729 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01730 pvt->jointcapability = pvt->options.capability; 01731 if (pvt->options.dtmfmode) { 01732 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01733 pvt->nonCodecCapability |= AST_RTP_DTMF; 01734 } else { 01735 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01736 } 01737 } 01738 } 01739 01740 ast_mutex_lock(&caplock); 01741 /* Generate unique channel identifier */ 01742 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique); 01743 tmp1[sizeof(tmp1)-1] = '\0'; 01744 ast_mutex_unlock(&caplock); 01745 01746 ast_mutex_lock(&pvt->lock); 01747 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1); 01748 ast_mutex_unlock(&pvt->lock); 01749 if (!tmpc) { 01750 oh323_destroy(pvt); 01751 if (cause) 01752 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 01753 } 01754 ast_update_use_count(); 01755 restart_monitor(); 01756 return tmpc; 01757 }
Definition at line 752 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, ast_dsp_process(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtp_read(), ast_rtp_setnat(), ast_set_read_format(), ast_set_write_format(), f, ast_frame::frametype, 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, ast_frame::subclass, oh323_pvt::vad, and ast_channel::writeformat.
Referenced by oh323_read().
00753 { 00754 /* Retrieve audio/etc from channel. Assumes pvt->lock is already held. */ 00755 struct ast_frame *f; 00756 00757 /* Only apply it for the first packet, we just need the correct ip/port */ 00758 if (pvt->options.nat) { 00759 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00760 pvt->options.nat = 0; 00761 } 00762 00763 f = ast_rtp_read(pvt->rtp); 00764 /* Don't send RFC2833 if we're not supposed to */ 00765 if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) { 00766 return &ast_null_frame; 00767 } 00768 if (pvt->owner) { 00769 /* We already hold the channel lock */ 00770 if (f->frametype == AST_FRAME_VOICE) { 00771 if (f->subclass != pvt->owner->nativeformats) { 00772 /* Try to avoid deadlock */ 00773 if (ast_channel_trylock(pvt->owner)) { 00774 ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n"); 00775 return &ast_null_frame; 00776 } 00777 if (h323debug) 00778 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 00779 pvt->owner->nativeformats = f->subclass; 00780 pvt->nativeformats = f->subclass; 00781 ast_set_read_format(pvt->owner, pvt->owner->readformat); 00782 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 00783 ast_channel_unlock(pvt->owner); 00784 } 00785 /* Do in-band DTMF detection */ 00786 if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) { 00787 if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) { 00788 if (!ast_channel_trylock(pvt->owner)) { 00789 f = ast_dsp_process(pvt->owner, pvt->vad, f); 00790 ast_channel_unlock(pvt->owner); 00791 } 00792 else 00793 ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n"); 00794 } else if (pvt->nativeformats && !pvt->noInbandDtmf) { 00795 ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass)); 00796 pvt->noInbandDtmf = 1; 00797 } 00798 if (f &&(f->frametype == AST_FRAME_DTMF)) { 00799 if (h323debug) 00800 ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass); 00801 } 00802 } 00803 } 00804 } 00805 return f; 00806 }
static int oh323_set_rtp_peer | ( | struct ast_channel * | chan, | |
struct ast_rtp * | rtp, | |||
struct ast_rtp * | vrtp, | |||
int | codecs, | |||
int | nat_active | |||
) | [static] |
Definition at line 3066 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, ast_channel::tech_pvt, and ast_channel::writeformat.
03067 { 03068 /* XXX Deal with Video */ 03069 struct oh323_pvt *pvt; 03070 struct sockaddr_in them; 03071 struct sockaddr_in us; 03072 char *mode; 03073 03074 if (!rtp) { 03075 return 0; 03076 } 03077 03078 mode = convertcap(chan->writeformat); 03079 pvt = (struct oh323_pvt *) chan->tech_pvt; 03080 if (!pvt) { 03081 ast_log(LOG_ERROR, "No Private Structure, this is bad\n"); 03082 return -1; 03083 } 03084 ast_rtp_get_peer(rtp, &them); 03085 ast_rtp_get_us(rtp, &us); 03086 #if 0 /* Native bridge still isn't ready */ 03087 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode); 03088 #endif 03089 return 0; 03090 }
static int oh323_simulate_dtmf_end | ( | const void * | data | ) | [static] |
Definition at line 307 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, AST_FRAME_DTMF_END, ast_mutex_lock(), ast_mutex_unlock(), ast_queue_frame(), oh323_pvt::curDTMF, oh323_pvt::DTMFsched, ast_frame::frametype, oh323_pvt::lock, and oh323_pvt::owner.
Referenced by __oh323_update_info(), and receive_digit().
00308 { 00309 struct oh323_pvt *pvt = (struct oh323_pvt *)data; 00310 00311 if (pvt) { 00312 ast_mutex_lock(&pvt->lock); 00313 /* Don't hold pvt lock while trying to lock the channel */ 00314 while(pvt->owner && ast_channel_trylock(pvt->owner)) { 00315 ast_mutex_unlock(&pvt->lock); 00316 usleep(1); 00317 ast_mutex_lock(&pvt->lock); 00318 } 00319 00320 if (pvt->owner) { 00321 struct ast_frame f = { 00322 .frametype = AST_FRAME_DTMF_END, 00323 .subclass = pvt->curDTMF, 00324 .samples = 0, 00325 .src = "SIMULATE_DTMF_END", 00326 }; 00327 ast_queue_frame(pvt->owner, &f); 00328 ast_channel_unlock(pvt->owner); 00329 } 00330 00331 pvt->DTMFsched = -1; 00332 ast_mutex_unlock(&pvt->lock); 00333 } 00334 00335 return 0; 00336 }
static void oh323_update_info | ( | struct ast_channel * | c | ) | [static] |
Definition at line 403 of file chan_h323.c.
References __oh323_update_info(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, and ast_channel::tech_pvt.
Referenced by oh323_answer(), oh323_call(), oh323_digit_begin(), oh323_digit_end(), and oh323_indicate().
00404 { 00405 struct oh323_pvt *pvt = c->tech_pvt; 00406 00407 if (pvt) { 00408 ast_mutex_lock(&pvt->lock); 00409 __oh323_update_info(c, pvt); 00410 ast_mutex_unlock(&pvt->lock); 00411 } 00412 }
static int oh323_write | ( | struct ast_channel * | c, | |
struct ast_frame * | frame | |||
) | [static] |
Definition at line 833 of file chan_h323.c.
References __oh323_update_info(), AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_frame::frametype, oh323_pvt::lock, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, oh323_pvt::recvonly, oh323_pvt::rtp, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat.
00834 { 00835 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00836 int res = 0; 00837 if (frame->frametype != AST_FRAME_VOICE) { 00838 if (frame->frametype == AST_FRAME_IMAGE) { 00839 return 0; 00840 } else { 00841 ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype); 00842 return 0; 00843 } 00844 } else { 00845 if (!(frame->subclass & c->nativeformats)) { 00846 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 00847 frame->subclass, c->nativeformats, c->readformat, c->writeformat); 00848 return 0; 00849 } 00850 } 00851 if (pvt) { 00852 ast_mutex_lock(&pvt->lock); 00853 if (pvt->rtp && !pvt->recvonly) 00854 res = ast_rtp_write(pvt->rtp, frame); 00855 __oh323_update_info(c, pvt); 00856 ast_mutex_unlock(&pvt->lock); 00857 } 00858 return res; 00859 }
static int progress | ( | unsigned | call_reference, | |
const char * | token, | |||
int | inband | |||
) | [static] |
Definition at line 2025 of file chan_h323.c.
References AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), find_call_locked(), 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 2757 of file chan_h323.c.
References ASTOBJ_CONTAINER_PRUNE_MARKED, oh323_destroy_peer(), and peerl.
Referenced by reload_config(), set_config(), and unload_module().
02758 { 02759 /* Prune peers who still are supposed to be deleted */ 02760 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer); 02761 }
static struct oh323_alias* realtime_alias | ( | const char * | alias | ) | [static, read] |
Definition at line 1229 of file chan_h323.c.
References ast_load_realtime(), ast_variables_destroy(), build_alias(), ast_variable::name, ast_variable::next, ast_variable::value, and var.
Referenced by find_alias().
01230 { 01231 struct ast_variable *var, *tmp; 01232 struct oh323_alias *a; 01233 01234 var = ast_load_realtime("h323", "name", alias, NULL); 01235 01236 if (!var) 01237 return NULL; 01238 01239 for (tmp = var; tmp; tmp = tmp->next) { 01240 if (!strcasecmp(tmp->name, "type") && 01241 !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) { 01242 ast_variables_destroy(var); 01243 return NULL; 01244 } 01245 } 01246 01247 a = build_alias(alias, var, NULL, 1); 01248 01249 ast_variables_destroy(var); 01250 01251 return a; 01252 }
static struct oh323_peer* realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 1503 of file chan_h323.c.
References ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_variables_destroy(), build_peer(), LOG_WARNING, ast_variable::name, ast_variable::next, ast_variable::value, and var.
Referenced by authenticate_reply(), find_peer(), and iax2_getpeername().
01504 { 01505 struct oh323_peer *peer; 01506 struct ast_variable *var; 01507 struct ast_variable *tmp; 01508 const char *addr; 01509 01510 /* First check on peer name */ 01511 if (peername) 01512 var = ast_load_realtime("h323", "name", peername, addr = NULL); 01513 else if (sin) /* Then check on IP address for dynamic peers */ 01514 var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), NULL); 01515 else 01516 return NULL; 01517 01518 if (!var) 01519 return NULL; 01520 01521 for (tmp = var; tmp; tmp = tmp->next) { 01522 /* If this is type=user, then skip this object. */ 01523 if (!strcasecmp(tmp->name, "type") && 01524 !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) { 01525 ast_variables_destroy(var); 01526 return NULL; 01527 } else if (!peername && !strcasecmp(tmp->name, "name")) { 01528 peername = tmp->value; 01529 } 01530 } 01531 01532 if (!peername) { /* Did not find peer in realtime */ 01533 ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr); 01534 ast_variables_destroy(var); 01535 return NULL; 01536 } 01537 01538 /* Peer found in realtime, now build it in memory */ 01539 peer = build_peer(peername, var, NULL, 1); 01540 01541 ast_variables_destroy(var); 01542 01543 return peer; 01544 }
static struct oh323_user* realtime_user | ( | const call_details_t * | cd | ) | [static, read] |
Definition at line 1405 of file chan_h323.c.
References ast_load_realtime(), ast_log(), ast_variables_destroy(), build_user(), LOG_WARNING, ast_variable::name, ast_variable::next, username, ast_variable::value, and var.
Referenced by check_access(), and find_user().
01406 { 01407 struct ast_variable *var, *tmp; 01408 struct oh323_user *user; 01409 char *username; 01410 01411 if (userbyalias) 01412 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL); 01413 else { 01414 username = (char *)NULL; 01415 var = ast_load_realtime("h323", "host", cd->sourceIp, NULL); 01416 } 01417 01418 if (!var) 01419 return NULL; 01420 01421 for (tmp = var; tmp; tmp = tmp->next) { 01422 if (!strcasecmp(tmp->name, "type") && 01423 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) { 01424 ast_variables_destroy(var); 01425 return NULL; 01426 } else if (!username && !strcasecmp(tmp->name, "name")) 01427 username = tmp->value; 01428 } 01429 01430 if (!username) { 01431 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp); 01432 ast_variables_destroy(var); 01433 return NULL; 01434 } 01435 01436 user = build_user(username, var, NULL, 1); 01437 01438 ast_variables_destroy(var); 01439 01440 return user; 01441 }
static int receive_digit | ( | unsigned | call_reference, | |
char | digit, | |||
const char * | token, | |||
int | duration | |||
) | [static] |
Callback for sending digits from H.323 up to asterisk
Definition at line 1776 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, AST_CONTROL_FLASH, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_log(), ast_mutex_unlock(), ast_queue_control(), ast_queue_frame(), ast_sched_add(), AST_SCHED_DEL, oh323_pvt::curDTMF, oh323_pvt::DTMFsched, find_call_locked(), ast_frame::frametype, ast_frame::len, oh323_pvt::lock, LOG_DTMF, LOG_ERROR, oh323_pvt::newcontrol, oh323_pvt::newdigit, oh323_pvt::newduration, oh323_simulate_dtmf_end(), oh323_pvt::owner, ast_frame::samples, and ast_frame::subclass.
Referenced by load_module().
01777 { 01778 struct oh323_pvt *pvt; 01779 int res; 01780 01781 pvt = find_call_locked(call_reference, token); 01782 if (!pvt) { 01783 ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token); 01784 return -1; 01785 } 01786 if (h323debug) 01787 ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token); 01788 01789 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01790 if (digit == '!') 01791 res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH); 01792 else { 01793 struct ast_frame f = { 01794 .frametype = AST_FRAME_DTMF_END, 01795 .subclass = digit, 01796 .samples = duration * 8, 01797 .len = duration, 01798 .src = "SEND_DIGIT", 01799 }; 01800 if (digit == ' ') { /* signalUpdate message */ 01801 f.subclass = pvt->curDTMF; 01802 AST_SCHED_DEL(sched, pvt->DTMFsched); 01803 } else { /* Regular input or signal message */ 01804 if (pvt->DTMFsched >= 0) { 01805 /* We still don't send DTMF END from previous event, send it now */ 01806 AST_SCHED_DEL(sched, pvt->DTMFsched); 01807 f.subclass = pvt->curDTMF; 01808 f.samples = f.len = 0; 01809 ast_queue_frame(pvt->owner, &f); 01810 /* Restore values */ 01811 f.subclass = digit; 01812 f.samples = duration * 8; 01813 f.len = duration; 01814 } 01815 if (duration) { /* This is a signal, signalUpdate follows */ 01816 f.frametype = AST_FRAME_DTMF_BEGIN; 01817 pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt); 01818 if (h323debug) 01819 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched); 01820 } 01821 pvt->curDTMF = digit; 01822 } 01823 res = ast_queue_frame(pvt->owner, &f); 01824 } 01825 ast_channel_unlock(pvt->owner); 01826 } else { 01827 if (digit == '!') 01828 pvt->newcontrol = AST_CONTROL_FLASH; 01829 else { 01830 pvt->newduration = duration; 01831 pvt->newdigit = digit; 01832 } 01833 res = 0; 01834 } 01835 ast_mutex_unlock(&pvt->lock); 01836 return res; 01837 }
static const char* redirectingreason2str | ( | int | redirectingreason | ) | [static] |
Definition at line 268 of file chan_h323.c.
Referenced by __oh323_new().
00269 { 00270 switch (redirectingreason) { 00271 case 0: 00272 return "UNKNOWN"; 00273 case 1: 00274 return "BUSY"; 00275 case 2: 00276 return "NO_REPLY"; 00277 case 0xF: 00278 return "UNCONDITIONAL"; 00279 default: 00280 return "NOREDIRECT"; 00281 } 00282 }
static int reload | ( | void | ) | [static] |
Definition at line 3001 of file chan_h323.c.
References ast_log(), h323_reload(), and LOG_NOTICE.
03002 { 03003 if (!sched || !io) { 03004 ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n"); 03005 return 0; 03006 } 03007 return h323_reload(0, 0, NULL); 03008 }
static int reload_config | ( | int | is_reload | ) | [static] |
Definition at line 2763 of file chan_h323.c.
References aliasl, 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(), ast_verbose(), ASTOBJ_CONTAINER_LINK, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_UNLOCK, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, ASTOBJ_UNREF, bindaddr, build_alias(), build_peer(), build_user(), delete_aliases(), delete_users(), format, gen, GLOBAL_CAPABILITY, global_jbconf, hp, IPTOS_MINCOST, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, oh323_destroy_alias(), oh323_destroy_peer(), oh323_destroy_user(), peerl, prune_peers(), update_common_options(), userl, ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by h323_do_reload(), iax2_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), misdn_reload(), reload(), and sip_do_reload().
02764 { 02765 int format; 02766 struct ast_config *cfg, *ucfg; 02767 struct ast_variable *v; 02768 struct oh323_peer *peer = NULL; 02769 struct oh323_user *user = NULL; 02770 struct oh323_alias *alias = NULL; 02771 struct ast_hostent ahp; struct hostent *hp; 02772 char *cat; 02773 const char *utype; 02774 int is_user, is_peer, is_alias; 02775 char _gatekeeper[100]; 02776 int gk_discover, gk_disable, gk_changed; 02777 02778 cfg = ast_config_load(config); 02779 02780 /* We *must* have a config file otherwise stop immediately */ 02781 if (!cfg) { 02782 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02783 return 1; 02784 } 02785 02786 if (is_reload) { 02787 delete_users(); 02788 delete_aliases(); 02789 prune_peers(); 02790 } 02791 02792 /* fire up the H.323 Endpoint */ 02793 if (!h323_end_point_exist()) { 02794 h323_end_point_create(); 02795 } 02796 ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper)); 02797 gk_discover = gatekeeper_discover; 02798 gk_disable = gatekeeper_disable; 02799 memset(&bindaddr, 0, sizeof(bindaddr)); 02800 memset(&global_options, 0, sizeof(global_options)); 02801 global_options.fastStart = 1; 02802 global_options.h245Tunneling = 1; 02803 global_options.dtmfcodec = 101; 02804 global_options.dtmfmode = H323_DTMF_RFC2833; 02805 global_options.capability = GLOBAL_CAPABILITY; 02806 global_options.bridge = 1; /* Do native bridging by default */ 02807 strcpy(default_context, "default"); 02808 h323_signalling_port = 1720; 02809 gatekeeper_disable = 1; 02810 gatekeeper_discover = 0; 02811 gkroute = 0; 02812 userbyalias = 1; 02813 acceptAnonymous = 1; 02814 tos = 0; 02815 02816 /* Copy the default jb config over global_jbconf */ 02817 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 02818 02819 /* Load configuration from users.conf */ 02820 ucfg = ast_config_load("users.conf"); 02821 if (ucfg) { 02822 struct ast_variable *gen; 02823 int genhas_h323; 02824 const char *has_h323; 02825 02826 genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323")); 02827 gen = ast_variable_browse(ucfg, "general"); 02828 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) { 02829 if (strcasecmp(cat, "general")) { 02830 has_h323 = ast_variable_retrieve(ucfg, cat, "hash323"); 02831 if (ast_true(has_h323) || (!has_h323 && genhas_h323)) { 02832 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 02833 if (user) { 02834 ASTOBJ_CONTAINER_LINK(&userl, user); 02835 ASTOBJ_UNREF(user, oh323_destroy_user); 02836 } 02837 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 02838 if (peer) { 02839 ASTOBJ_CONTAINER_LINK(&peerl, peer); 02840 ASTOBJ_UNREF(peer, oh323_destroy_peer); 02841 } 02842 } 02843 } 02844 } 02845 ast_config_destroy(ucfg); 02846 } 02847 02848 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 02849 /* handle jb conf */ 02850 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 02851 continue; 02852 /* Create the interface list */ 02853 if (!strcasecmp(v->name, "port")) { 02854 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02855 } else if (!strcasecmp(v->name, "bindaddr")) { 02856 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02857 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02858 } else { 02859 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02860 } 02861 } else if (!strcasecmp(v->name, "tos")) { 02862 if (sscanf(v->value, "%d", &format)) { 02863 tos = format & 0xff; 02864 } else if (!strcasecmp(v->value, "lowdelay")) { 02865 tos = IPTOS_LOWDELAY; 02866 } else if (!strcasecmp(v->value, "throughput")) { 02867 tos = IPTOS_THROUGHPUT; 02868 } else if (!strcasecmp(v->value, "reliability")) { 02869 tos = IPTOS_RELIABILITY; 02870 } else if (!strcasecmp(v->value, "mincost")) { 02871 tos = IPTOS_MINCOST; 02872 } else if (!strcasecmp(v->value, "none")) { 02873 tos = 0; 02874 } else { 02875 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02876 } 02877 } else if (!strcasecmp(v->name, "gatekeeper")) { 02878 if (!strcasecmp(v->value, "DISABLE")) { 02879 gatekeeper_disable = 1; 02880 } else if (!strcasecmp(v->value, "DISCOVER")) { 02881 gatekeeper_disable = 0; 02882 gatekeeper_discover = 1; 02883 } else { 02884 gatekeeper_disable = 0; 02885 ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper)); 02886 } 02887 } else if (!strcasecmp(v->name, "secret")) { 02888 ast_copy_string(secret, v->value, sizeof(secret)); 02889 } else if (!strcasecmp(v->name, "AllowGKRouted")) { 02890 gkroute = ast_true(v->value); 02891 } else if (!strcasecmp(v->name, "context")) { 02892 ast_copy_string(default_context, v->value, sizeof(default_context)); 02893 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context); 02894 } else if (!strcasecmp(v->name, "UserByAlias")) { 02895 userbyalias = ast_true(v->value); 02896 } else if (!strcasecmp(v->name, "AcceptAnonymous")) { 02897 acceptAnonymous = ast_true(v->value); 02898 } else if (!update_common_options(v, &global_options)) { 02899 /* dummy */ 02900 } 02901 } 02902 02903 for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) { 02904 if (strcasecmp(cat, "general")) { 02905 utype = ast_variable_retrieve(cfg, cat, "type"); 02906 if (utype) { 02907 is_user = is_peer = is_alias = 0; 02908 if (!strcasecmp(utype, "user")) 02909 is_user = 1; 02910 else if (!strcasecmp(utype, "peer")) 02911 is_peer = 1; 02912 else if (!strcasecmp(utype, "friend")) 02913 is_user = is_peer = 1; 02914 else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) 02915 is_alias = 1; 02916 else { 02917 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config); 02918 continue; 02919 } 02920 if (is_user) { 02921 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 02922 if (user) { 02923 ASTOBJ_CONTAINER_LINK(&userl, user); 02924 ASTOBJ_UNREF(user, oh323_destroy_user); 02925 } 02926 } 02927 if (is_peer) { 02928 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 02929 if (peer) { 02930 ASTOBJ_CONTAINER_LINK(&peerl, peer); 02931 ASTOBJ_UNREF(peer, oh323_destroy_peer); 02932 } 02933 } 02934 if (is_alias) { 02935 alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0); 02936 if (alias) { 02937 ASTOBJ_CONTAINER_LINK(&aliasl, alias); 02938 ASTOBJ_UNREF(alias, oh323_destroy_alias); 02939 } 02940 } 02941 } else { 02942 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 02943 } 02944 } 02945 } 02946 ast_config_destroy(cfg); 02947 02948 /* Register our H.323 aliases if any*/ 02949 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 02950 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 02951 ASTOBJ_RDLOCK(iterator); 02952 if (h323_set_alias(iterator)) { 02953 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name); 02954 ASTOBJ_UNLOCK(iterator); 02955 continue; 02956 } 02957 ASTOBJ_UNLOCK(iterator); 02958 } while (0) ); 02959 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 02960 02961 /* Don't touch GK if nothing changed because URQ will drop all existing calls */ 02962 gk_changed = 0; 02963 if (gatekeeper_disable != gk_disable) 02964 gk_changed = is_reload; 02965 else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover)) 02966 gk_changed = is_reload; 02967 else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0)) 02968 gk_changed = is_reload; 02969 if (gk_changed) { 02970 if(!gk_disable) 02971 h323_gk_urq(); 02972 if (!gatekeeper_disable) { 02973 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 02974 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 02975 gatekeeper_disable = 1; 02976 } 02977 } 02978 } 02979 return 0; 02980 }
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, and LOG_WARNING.
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(), 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(), oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, oh323_pvt::options, and oh323_pvt::pref_codec.
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, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, oh323_pvt::options, ast_codec_pref::order, oh323_pvt::peer_prefs, oh323_pvt::peercapability, 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 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, oh323_pvt::exten, find_alias(), find_user(), 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(), 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 3201 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, free, iflist, io_context_destroy(), oh323_pvt::lock, LOG_WARNING, oh323_pvt::next, oh323_destroy_alias(), oh323_destroy_peer(), oh323_destroy_user(), oh323_pvt::owner, peerl, sched_context_destroy(), and userl.
03202 { 03203 struct oh323_pvt *p, *pl; 03204 03205 /* unregister commands */ 03206 ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry)); 03207 ast_cli_unregister(&cli_h323_reload); 03208 03209 ast_channel_unregister(&oh323_tech); 03210 ast_rtp_proto_unregister(&oh323_rtp); 03211 03212 if (!ast_mutex_lock(&iflock)) { 03213 /* hangup all interfaces if they have an owner */ 03214 p = iflist; 03215 while(p) { 03216 if (p->owner) { 03217 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 03218 } 03219 p = p->next; 03220 } 03221 iflist = NULL; 03222 ast_mutex_unlock(&iflock); 03223 } else { 03224 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 03225 return -1; 03226 } 03227 if (!ast_mutex_lock(&monlock)) { 03228 if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) { 03229 /* this causes a seg, anyone know why? */ 03230 if (monitor_thread != pthread_self()) 03231 pthread_cancel(monitor_thread); 03232 pthread_kill(monitor_thread, SIGURG); 03233 pthread_join(monitor_thread, NULL); 03234 } 03235 monitor_thread = AST_PTHREADT_STOP; 03236 ast_mutex_unlock(&monlock); 03237 } else { 03238 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 03239 return -1; 03240 } 03241 if (!ast_mutex_lock(&iflock)) { 03242 /* destroy all the interfaces and free their memory */ 03243 p = iflist; 03244 while(p) { 03245 pl = p; 03246 p = p->next; 03247 /* free associated memory */ 03248 ast_mutex_destroy(&pl->lock); 03249 free(pl); 03250 } 03251 iflist = NULL; 03252 ast_mutex_unlock(&iflock); 03253 } else { 03254 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 03255 return -1; 03256 } 03257 if (!gatekeeper_disable) 03258 h323_gk_urq(); 03259 h323_end_process(); 03260 if (io) 03261 io_context_destroy(io); 03262 if (sched) 03263 sched_context_destroy(sched); 03264 03265 ASTOBJ_CONTAINER_DESTROYALL(&userl, oh323_destroy_user); 03266 ASTOBJ_CONTAINER_DESTROY(&userl); 03267 ASTOBJ_CONTAINER_DESTROYALL(&peerl, oh323_destroy_peer); 03268 ASTOBJ_CONTAINER_DESTROY(&peerl); 03269 ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias); 03270 ASTOBJ_CONTAINER_DESTROY(&aliasl); 03271 03272 return 0; 03273 }
static int update_common_options | ( | struct ast_variable * | v, | |
struct call_options * | options | |||
) | [static] |
Definition at line 1257 of file chan_h323.c.
References ast_callerid_split(), ast_log(), ast_parse_allow_disallow(), ast_true(), DEPRECATED, ast_variable::lineno, LOG_WARNING, ast_variable::name, and ast_variable::value.
Referenced by build_peer(), build_user(), and reload_config().
01258 { 01259 int tmp; 01260 01261 if (!strcasecmp(v->name, "allow")) { 01262 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1); 01263 } else if (!strcasecmp(v->name, "disallow")) { 01264 ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0); 01265 } else if (!strcasecmp(v->name, "dtmfmode")) { 01266 if (!strcasecmp(v->value, "inband")) { 01267 options->dtmfmode = H323_DTMF_INBAND; 01268 } else if (!strcasecmp(v->value, "rfc2833")) { 01269 options->dtmfmode = H323_DTMF_RFC2833; 01270 } else { 01271 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value); 01272 options->dtmfmode = H323_DTMF_RFC2833; 01273 } 01274 } else if (!strcasecmp(v->name, "dtmfcodec")) { 01275 tmp = atoi(v->value); 01276 if (tmp < 96) 01277 ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno); 01278 else 01279 options->dtmfcodec = tmp; 01280 } else if (!strcasecmp(v->name, "bridge")) { 01281 options->bridge = ast_true(v->value); 01282 } else if (!strcasecmp(v->name, "nat")) { 01283 options->nat = ast_true(v->value); 01284 } else if (!strcasecmp(v->name, "noFastStart")) { 01285 DEPRECATED(v, "fastStart"); 01286 options->fastStart = !ast_true(v->value); 01287 } else if (!strcasecmp(v->name, "fastStart")) { 01288 options->fastStart = ast_true(v->value); 01289 } else if (!strcasecmp(v->name, "noH245Tunneling")) { 01290 DEPRECATED(v, "h245Tunneling"); 01291 options->h245Tunneling = !ast_true(v->value); 01292 } else if (!strcasecmp(v->name, "h245Tunneling")) { 01293 options->h245Tunneling = ast_true(v->value); 01294 } else if (!strcasecmp(v->name, "noSilenceSuppression")) { 01295 DEPRECATED(v, "silenceSuppression"); 01296 options->silenceSuppression = !ast_true(v->value); 01297 } else if (!strcasecmp(v->name, "silenceSuppression")) { 01298 options->silenceSuppression = ast_true(v->value); 01299 } else if (!strcasecmp(v->name, "progress_setup")) { 01300 tmp = atoi(v->value); 01301 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) { 01302 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno); 01303 tmp = 0; 01304 } 01305 options->progress_setup = tmp; 01306 } else if (!strcasecmp(v->name, "progress_alert")) { 01307 tmp = atoi(v->value); 01308 if ((tmp != 0) && (tmp != 1) && (tmp != 8)) { 01309 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno); 01310 tmp = 0; 01311 } 01312 options->progress_alert = tmp; 01313 } else if (!strcasecmp(v->name, "progress_audio")) { 01314 options->progress_audio = ast_true(v->value); 01315 } else if (!strcasecmp(v->name, "callerid")) { 01316 ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num)); 01317 } else if (!strcasecmp(v->name, "fullname")) { 01318 ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name)); 01319 } else if (!strcasecmp(v->name, "cid_number")) { 01320 ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num)); 01321 } else if (!strcasecmp(v->name, "tunneling")) { 01322 if (!strcasecmp(v->value, "none")) 01323 options->tunnelOptions = 0; 01324 else if (!strcasecmp(v->value, "cisco")) 01325 options->tunnelOptions |= H323_TUNNEL_CISCO; 01326 else if (!strcasecmp(v->value, "qsig")) 01327 options->tunnelOptions |= H323_TUNNEL_QSIG; 01328 else 01329 ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno); 01330 } else 01331 return 1; 01332 01333 return 0; 01334 }
static int update_state | ( | struct oh323_pvt * | pvt, | |
int | state, | |||
int | signal | |||
) | [static] |
Definition at line 1173 of file chan_h323.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_control(), ast_setstate(), oh323_pvt::newcontrol, oh323_pvt::newstate, and oh323_pvt::owner.
Referenced by chan_ringing(), connection_made(), and progress().
01174 { 01175 if (!pvt) 01176 return 0; 01177 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01178 if (state >= 0) 01179 ast_setstate(pvt->owner, state); 01180 if (signal >= 0) 01181 ast_queue_control(pvt->owner, signal); 01182 ast_channel_unlock(pvt->owner); 01183 return 1; 01184 } 01185 else { 01186 if (state >= 0) 01187 pvt->newstate = state; 01188 if (signal >= 0) 01189 pvt->newcontrol = signal; 01190 return 0; 01191 } 01192 }
int acceptAnonymous = 1 [static] |
Definition at line 151 of file chan_h323.c.
struct ast_alias_list aliasl [static] |
Referenced by build_alias(), delete_aliases(), find_alias(), load_module(), reload_config(), and unload_module().
struct sockaddr_in bindaddr [static] |
Definition at line 139 of file chan_h323.c.
struct ast_cli_entry cli_h323[] [static] |
Definition at line 2683 of file chan_h323.c.
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 3010 of file chan_h323.c.
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 137 of file chan_h323.c.
char debug_usage[] [static] |
Initial value:
"Usage: h.323 debug\n" " Enables H.323 debug output\n"
Definition at line 2634 of file chan_h323.c.
char default_context[AST_MAX_CONTEXT] = "default" [static] |
Definition at line 138 of file chan_h323.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration - by default, jb is disabled
Definition at line 126 of file chan_h323.c.
char gatekeeper[100] [static] |
Definition at line 145 of file chan_h323.c.
int gatekeeper_disable = 1 [static] |
Definition at line 146 of file chan_h323.c.
int gatekeeper_discover = 0 [static] |
Definition at line 147 of file chan_h323.c.
int gkroute = 0 [static] |
Definition at line 148 of file chan_h323.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 133 of file chan_h323.c.
call_options_t global_options [static] |
Definition at line 156 of file chan_h323.c.
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] |
Definition at line 228 of file chan_h323.c.
int h323_signalling_port = 1720 [static] |
H.323 configuration values
Definition at line 144 of file chan_h323.c.
int h323debug |
Definition at line 123 of file chan_h323.c.
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 214 of file chan_h323.c.
pthread_t monitor_thread = AST_PTHREADT_NULL [static] |
Definition at line 232 of file chan_h323.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: h.323 debug off\n" " Disables H.323 debug output\n"
Definition at line 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] |
Definition at line 3092 of file chan_h323.c.
struct ast_channel_tech oh323_tech [static] |
Definition at line 247 of file chan_h323.c.
answer_call_cb on_answer_call |
Definition at line 115 of file chan_h323.c.
chan_ringing_cb on_chan_ringing |
Definition at line 112 of file chan_h323.c.
clear_con_cb on_connection_cleared |
Definition at line 114 of file chan_h323.c.
con_established_cb on_connection_established |
Definition at line 113 of file chan_h323.c.
on_rtp_cb on_external_rtp_create |
Definition at line 108 of file chan_h323.c.
hangup_cb on_hangup |
Definition at line 118 of file chan_h323.c.
setup_incoming_cb on_incoming_call |
Definition at line 110 of file chan_h323.c.
setup_outbound_cb on_outgoing_call |
Definition at line 111 of file chan_h323.c.
progress_cb on_progress |
Definition at line 116 of file chan_h323.c.
receive_digit_cb on_receive_digit |
Definition at line 107 of file chan_h323.c.
rfc2833_cb on_set_rfc2833_payload |
Definition at line 117 of file chan_h323.c.
setcapabilities_cb on_setcapabilities |
Definition at line 119 of file chan_h323.c.
setpeercapabilities_cb on_setpeercapabilities |
Definition at line 120 of file chan_h323.c.
start_rtp_cb on_start_rtp_channel |
Definition at line 109 of file chan_h323.c.
struct ast_peer_list peerl [static] |
Referenced by _sip_show_peers(), build_peer(), complete_sip_peer(), delete_users(), do_monitor(), expire_register(), find_peer(), load_module(), prune_peers(), realtime_peer(), register_verify(), reload_config(), sip_do_reload(), sip_poke_all_peers(), sip_prune_realtime(), sip_show_inuse(), sip_show_objects(), and unload_module().
struct sched_context* sched [static] |
Asterisk RTP stuff
Definition at line 213 of file chan_h323.c.
char secret[50] [static] |
Definition at line 153 of file chan_h323.c.
Referenced by add_realm_authentication(), aji_act_hook(), build_reply_digest(), load_module(), read_agent_config(), reload_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 136 of file chan_h323.c.
int tos = 0 [static] |
Definition at line 152 of file chan_h323.c.
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] |
Definition at line 154 of file chan_h323.c.
int userbyalias = 1 [static] |
Definition at line 150 of file chan_h323.c.
struct ast_user_list userl [static] |