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