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