![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
chan_h323.c File Reference
Definition in file chan_h323.c.
#include "asterisk.h"
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/musiconhold.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/dsp.h"
#include "asterisk/causes.h"
#include "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/astobj.h"
#include "h323/chan_h323.h"
Include dependency graph for chan_h323.c:

Go to the source code of this file.
Data Structures | |
| struct | ast_alias_list |
| struct | ast_peer_list |
| The peer list: Peers and Friends. More... | |
| struct | ast_user_list |
| The user list: Users and friends. More... | |
| struct | oh323_pvt |
| struct | rtpPayloadType |
| Structure representing a RTP session.The value of each payload format mapping:. More... | |
Defines | |
| #define | GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_G726_AAL2 | AST_FORMAT_H261) |
Functions | |
| static void | __oh323_destroy (struct oh323_pvt *pvt) |
| static struct ast_channel * | __oh323_new (struct oh323_pvt *pvt, int state, const char *host) |
| static int | __oh323_rtp_create (struct oh323_pvt *pvt) |
| static void | __oh323_update_info (struct ast_channel *c, struct oh323_pvt *pvt) |
| static int | answer_call (unsigned call_reference, const char *token) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"The NuFone Network's OpenH323 Channel Driver",.load=load_module,.unload=unload_module,.reload=reload,) | |
| AST_MUTEX_DEFINE_STATIC (h323_reload_lock) | |
| AST_MUTEX_DEFINE_STATIC (caplock) | |
| AST_MUTEX_DEFINE_STATIC (monlock) | |
| AST_MUTEX_DEFINE_STATIC (iflock) | |
| static struct oh323_alias * | build_alias (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
| static struct oh323_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
| static struct oh323_user * | build_user (char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
| static void | chan_ringing (unsigned call_reference, const char *token) |
| static void | cleanup_call_details (call_details_t *cd) |
| static void | cleanup_connection (unsigned call_reference, const char *call_token) |
| static void | connection_made (unsigned call_reference, const char *token) |
| static char * | convertcap (int cap) |
| static int | create_addr (struct oh323_pvt *pvt, char *opeer) |
| static void | delete_aliases (void) |
| static void | delete_users (void) |
| static void * | do_monitor (void *data) |
| static struct rtp_info * | external_rtp_create (unsigned call_reference, const char *token) |
| static struct oh323_alias * | find_alias (const char *source_aliases, int realtime) |
| static struct oh323_pvt * | find_call_locked (int call_reference, const char *token) |
| static struct oh323_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
| static struct oh323_user * | find_user (const call_details_t *cd, int realtime) |
| static int | h323_do_debug (int fd, int argc, char *argv[]) |
| static int | h323_do_reload (void) |
| static int | h323_do_trace (int fd, int argc, char *argv[]) |
| static int | h323_ep_hangup (int fd, int argc, char *argv[]) |
| static int | h323_gk_cycle (int fd, int argc, char *argv[]) |
| static int | h323_no_debug (int fd, int argc, char *argv[]) |
| static int | h323_no_trace (int fd, int argc, char *argv[]) |
| static int | h323_reload (int fd, int argc, char *argv[]) |
| static int | h323_tokens_show (int fd, int argc, char *argv[]) |
| static void | hangup_connection (unsigned int call_reference, const char *token, int cause) |
| static enum ast_module_load_result | load_module (void) |
| static int | oh323_addrcmp (struct sockaddr_in addr, struct sockaddr_in *sin) |
| static int | oh323_addrcmp_str (struct in_addr inaddr, char *addr) |
| static struct oh323_pvt * | oh323_alloc (int callid) |
| static int | oh323_answer (struct ast_channel *c) |
| static int | oh323_call (struct ast_channel *c, char *dest, int timeout) |
| static void | oh323_destroy (struct oh323_pvt *pvt) |
| static void | oh323_destroy_alias (struct oh323_alias *alias) |
| static void | oh323_destroy_peer (struct oh323_peer *peer) |
| static void | oh323_destroy_user (struct oh323_user *user) |
| static int | oh323_digit_begin (struct ast_channel *c, char digit) |
| static int | oh323_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
| static int | oh323_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| static enum ast_rtp_get_result | oh323_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
| static enum ast_rtp_get_result | oh323_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
| static int | oh323_hangup (struct ast_channel *c) |
| static int | oh323_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
| static struct ast_frame * | oh323_read (struct ast_channel *c) |
| static struct ast_channel * | oh323_request (const char *type, int format, void *data, int *cause) |
| static struct ast_frame * | oh323_rtp_read (struct oh323_pvt *pvt) |
| static int | oh323_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
| static int | oh323_simulate_dtmf_end (void *data) |
| static void | oh323_update_info (struct ast_channel *c) |
| static int | oh323_write (struct ast_channel *c, struct ast_frame *frame) |
| static int | progress (unsigned call_reference, const char *token, int inband) |
| static void | prune_peers (void) |
| static struct oh323_alias * | realtime_alias (const char *alias) |
| static struct oh323_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
| static struct oh323_user * | realtime_user (const call_details_t *cd) |
| static int | receive_digit (unsigned call_reference, char digit, const char *token, int duration) |
| static const char * | redirectingreason2str (int redirectingreason) |
| static int | reload (void) |
| static int | reload_config (int is_reload) |
| static void | remote_hold (unsigned call_reference, const char *token, int is_hold) |
| static int | restart_monitor (void) |
| Start the channel monitor thread. | |
| static void | set_dtmf_payload (unsigned call_reference, const char *token, int payload, int is_cisco) |
| 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_hangup_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_reload_deprecated |
| static struct ast_cli_entry | cli_h323_show_tokens_deprecated |
| static struct ast_cli_entry | cli_h323_trace_deprecated |
| static const char | config [] = "h323.conf" |
| static char | debug_usage [] |
| static char | default_context [AST_MAX_CONTEXT] = "default" |
| static struct ast_jb_conf | default_jbconf |
| static char | gatekeeper [100] |
| static int | gatekeeper_disable = 1 |
| static int | gatekeeper_discover = 0 |
| static int | gkroute = 0 |
| static struct ast_jb_conf | global_jbconf |
| static call_options_t | global_options |
| static char | h323_reload_usage [] |
| static int | h323_reloading = 0 |
| static int | h323_signalling_port = 1720 |
| int | h323debug |
| oh323_pvt * | iflist |
| static struct io_context * | io |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| static char | no_debug_usage [] |
| static char | no_trace_usage [] |
| static struct ast_rtp_protocol | oh323_rtp |
| static const 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 |
| onhold_cb | on_hold |
| 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 at line 141 of file chan_h323.c. Referenced by reload_config(). |
|
|
Definition at line 451 of file chan_h323.c. References ast_channel_lock, ast_channel_unlock, ast_dsp_free(), ast_log(), ast_mutex_destroy(), ast_mutex_unlock(), ast_rtp_destroy(), ast_sched_del(), oh323_pvt::cd, cleanup_call_details(), oh323_pvt::DTMFsched, free, iflist, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_pvt::next, oh323_pvt::owner, oh323_pvt::rtp, sched, ast_channel::tech_pvt, and oh323_pvt::vad. Referenced by do_monitor(), and oh323_destroy(). 00452 { 00453 struct oh323_pvt *cur, *prev = NULL; 00454 00455 if (pvt->DTMFsched >= 0) { 00456 ast_sched_del(sched, pvt->DTMFsched); 00457 pvt->DTMFsched = -1; 00458 } 00459 00460 if (pvt->rtp) { 00461 ast_rtp_destroy(pvt->rtp); 00462 } 00463 00464 /* Free dsp used for in-band DTMF detection */ 00465 if (pvt->vad) { 00466 ast_dsp_free(pvt->vad); 00467 } 00468 cleanup_call_details(&pvt->cd); 00469 00470 /* Unlink us from the owner if we have one */ 00471 if (pvt->owner) { 00472 ast_channel_lock(pvt->owner); 00473 if (h323debug) 00474 ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name); 00475 pvt->owner->tech_pvt = NULL; 00476 ast_channel_unlock(pvt->owner); 00477 } 00478 cur = iflist; 00479 while(cur) { 00480 if (cur == pvt) { 00481 if (prev) 00482 prev->next = cur->next; 00483 else 00484 iflist = cur->next; 00485 break; 00486 } 00487 prev = cur; 00488 cur = cur->next; 00489 } 00490 if (!cur) { 00491 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur); 00492 } else { 00493 ast_mutex_unlock(&pvt->lock); 00494 ast_mutex_destroy(&pvt->lock); 00495 free(pvt); 00496 } 00497 }
|
|
||||||||||||||||
|
Definition at line 1006 of file chan_h323.c. References accountcode, oh323_pvt::accountcode, ast_channel::amaflags, oh323_pvt::amaflags, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_udptl_fd(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, cid_name, ast_callerid::cid_num, cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_ton, oh323_pvt::context, ast_channel::context, DSP_FEATURE_DTMF_DETECT, oh323_pvt::exten, ast_channel::exten, ast_channel::fds, fmt, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_WARNING, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_tech, oh323_pvt::options, oh323_pvt::owner, pbx_builtin_setvar_helper(), ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, redirectingreason2str(), ast_channel::rings, oh323_pvt::rtp, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, oh323_pvt::vad, and ast_channel::writeformat. Referenced by answer_call(), and oh323_request(). 01007 { 01008 struct ast_channel *ch; 01009 char *cid_num, *cid_name; 01010 int fmt; 01011 01012 if (!ast_strlen_zero(pvt->options.cid_num)) 01013 cid_num = pvt->options.cid_num; 01014 else 01015 cid_num = pvt->cd.call_source_e164; 01016 01017 if (!ast_strlen_zero(pvt->options.cid_name)) 01018 cid_name = pvt->options.cid_name; 01019 else 01020 cid_name = pvt->cd.call_source_name; 01021 01022 /* Don't hold a oh323_pvt lock while we allocate a chanel */ 01023 ast_mutex_unlock(&pvt->lock); 01024 ch = ast_channel_alloc(1, state, cid_num, cid_name, "H323/%s", host); 01025 /* Update usage counter */ 01026 ast_module_ref(ast_module_info->self); 01027 ast_mutex_lock(&pvt->lock); 01028 if (ch) { 01029 ch->tech = &oh323_tech; 01030 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability)) 01031 fmt = global_options.capability; 01032 ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/; 01033 pvt->nativeformats = ch->nativeformats; 01034 fmt = ast_best_codec(ch->nativeformats); 01035 ch->writeformat = fmt; 01036 ch->rawwriteformat = fmt; 01037 ch->readformat = fmt; 01038 ch->rawreadformat = fmt; 01039 #if 0 01040 ch->fds[0] = ast_rtp_fd(pvt->rtp); 01041 ch->fds[1] = ast_rtcp_fd(pvt->rtp); 01042 #endif 01043 #ifdef VIDEO_SUPPORT 01044 if (pvt->vrtp) { 01045 ch->fds[2] = ast_rtp_fd(pvt->vrtp); 01046 ch->fds[3] = ast_rtcp_fd(pvt->vrtp); 01047 } 01048 #endif 01049 #ifdef T38_SUPPORT 01050 if (pvt->udptl) { 01051 ch->fds[4] = ast_udptl_fd(pvt->udptl); 01052 } 01053 #endif 01054 if (state == AST_STATE_RING) { 01055 ch->rings = 1; 01056 } 01057 /* Allocate dsp for in-band DTMF support */ 01058 if (pvt->options.dtmfmode & H323_DTMF_INBAND) { 01059 pvt->vad = ast_dsp_new(); 01060 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT); 01061 } 01062 /* Register channel functions. */ 01063 ch->tech_pvt = pvt; 01064 /* Set the owner of this channel */ 01065 pvt->owner = ch; 01066 01067 ast_copy_string(ch->context, pvt->context, sizeof(ch->context)); 01068 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten)); 01069 ch->priority = 1; 01070 if (!ast_strlen_zero(pvt->accountcode)) { 01071 ast_string_field_set(ch, accountcode, pvt->accountcode); 01072 } 01073 if (pvt->amaflags) { 01074 ch->amaflags = pvt->amaflags; 01075 } 01076 01077 /* Don't use ast_set_callerid() here because it will 01078 * generate a needless NewCallerID event */ 01079 ch->cid.cid_num = ast_strdup(cid_num); 01080 ch->cid.cid_ani = ast_strdup(cid_num); 01081 ch->cid.cid_name = ast_strdup(cid_name); 01082 01083 if (pvt->cd.redirect_reason >= 0) { 01084 ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number); 01085 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason)); 01086 } 01087 ch->cid.cid_pres = pvt->cd.presentation; 01088 ch->cid.cid_ton = pvt->cd.type_of_number; 01089 01090 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) { 01091 ch->cid.cid_dnid = strdup(pvt->exten); 01092 } 01093 if (pvt->cd.transfer_capability >= 0) 01094 ch->transfercapability = pvt->cd.transfer_capability; 01095 if (state != AST_STATE_DOWN) { 01096 if (ast_pbx_start(ch)) { 01097 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name); 01098 ast_hangup(ch); 01099 ch = NULL; 01100 } 01101 } 01102 } else { 01103 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 01104 } 01105 return ch; 01106 }
|
|
|
Definition at line 958 of file chan_h323.c. References ast_channel_trylock, ast_channel_unlock, ast_find_ourip(), ast_jb_configure(), ast_log(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), ast_rtcp_fd(), ast_rtp_codec_setpref(), ast_rtp_fd(), ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpmap_type(), ast_rtp_setnat(), ast_rtp_settos(), oh323_pvt::dtmf_pt, ast_channel::fds, global_jbconf, io, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, oh323_pvt::options, oh323_pvt::owner, oh323_pvt::peer_prefs, oh323_pvt::peercapability, oh323_pvt::rtp, sched, and oh323_pvt::update_rtp_info. Referenced by external_rtp_create(), and setup_rtp_connection(). 00959 { 00960 struct in_addr our_addr; 00961 00962 if (pvt->rtp) 00963 return 0; 00964 00965 if (ast_find_ourip(&our_addr, bindaddr)) { 00966 ast_mutex_unlock(&pvt->lock); 00967 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n"); 00968 return -1; 00969 } 00970 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr); 00971 if (!pvt->rtp) { 00972 ast_mutex_unlock(&pvt->lock); 00973 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); 00974 return -1; 00975 } 00976 if (h323debug) 00977 ast_log(LOG_DEBUG, "Created RTP channel\n"); 00978 00979 ast_rtp_settos(pvt->rtp, tos); 00980 00981 if (h323debug) 00982 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat); 00983 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00984 00985 if (pvt->dtmf_pt[0] > 0) 00986 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt[0], "audio", "telephone-event", 0); 00987 if (pvt->dtmf_pt[1] > 0) 00988 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt[1], "audio", "cisco-telephone-event", 0); 00989 00990 if (pvt->peercapability) 00991 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 00992 00993 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 00994 ast_jb_configure(pvt->owner, &global_jbconf); 00995 pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp); 00996 pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp); 00997 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00998 ast_channel_unlock(pvt->owner); 00999 } else 01000 pvt->update_rtp_info = 1; 01001 01002 return 0; 01003 }
|
|
||||||||||||
|
||||||||||||
|
Call-back function to start PBX when OpenH323 ready to serve incoming call Returns 1 on success Definition at line 2223 of file chan_h323.c. References __oh323_new(), AST_CAUSE_UNALLOCATED, ast_exists_extension(), ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, oh323_pvt::cd, oh323_pvt::context, oh323_pvt::exten, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, and LOG_NOTICE. Referenced by load_module(). 02224 { 02225 struct oh323_pvt *pvt; 02226 struct ast_channel *c = NULL; 02227 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten; 02228 char tmp_exten[sizeof(pvt->exten)]; 02229 02230 if (h323debug) 02231 ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token); 02232 02233 /* Find the call or allocate a private structure if call not found */ 02234 pvt = find_call_locked(call_reference, token); 02235 if (!pvt) { 02236 ast_log(LOG_ERROR, "Something is wrong: answer_call\n"); 02237 return 0; 02238 } 02239 /* Check if requested extension@context pair exists in the dialplan */ 02240 ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten)); 02241 02242 /* Try to find best extension in specified context */ 02243 if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) { 02244 if (tmp_exten[0] == 's') 02245 try_exten = ext_s; 02246 else if (tmp_exten[0] == 'i') 02247 try_exten = ext_i; 02248 else 02249 try_exten = ext_original; 02250 } else 02251 try_exten = ext_original; 02252 do { 02253 if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL)) 02254 break; 02255 switch (try_exten) { 02256 case ext_original: 02257 tmp_exten[0] = 's'; 02258 tmp_exten[1] = '\0'; 02259 try_exten = ext_s; 02260 break; 02261 case ext_s: 02262 tmp_exten[0] = 'i'; 02263 try_exten = ext_i; 02264 break; 02265 case ext_i: 02266 try_exten = ext_notexists; 02267 break; 02268 default: 02269 break; 02270 } 02271 } while (try_exten != ext_notexists); 02272 02273 /* Drop the call if we don't have <exten>, s and i extensions */ 02274 if (try_exten == ext_notexists) { 02275 ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context); 02276 ast_mutex_unlock(&pvt->lock); 02277 h323_clear_call(token, AST_CAUSE_UNALLOCATED); 02278 return 0; 02279 } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) { 02280 if (h323debug) 02281 ast_log(LOG_DEBUG, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context); 02282 ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten)); 02283 } 02284 02285 /* allocate a channel and tell asterisk about it */ 02286 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token); 02287 02288 /* And release when done */ 02289 ast_mutex_unlock(&pvt->lock); 02290 if (!c) { 02291 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n"); 02292 return 0; 02293 } 02294 return 1; 02295 }
|
|
||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
Protect the interface list (oh323_pvt) |
|
||||||||||||||||||||
|
Definition at line 1199 of file chan_h323.c. References aliasl, ast_log(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_INIT, calloc, LOG_WARNING, ast_variable::name, ast_variable::next, and ast_variable::value. 01200 { 01201 struct oh323_alias *alias; 01202 int found = 0; 01203 01204 alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp); 01205 01206 if (alias) 01207 found++; 01208 else { 01209 if (!(alias = (struct oh323_alias *)calloc(1, sizeof(*alias)))) 01210 return NULL; 01211 ASTOBJ_INIT(alias); 01212 } 01213 if (!found && name) 01214 ast_copy_string(alias->name, name, sizeof(alias->name)); 01215 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01216 if (!strcasecmp(v->name, "e164")) { 01217 ast_copy_string(alias->e164, v->value, sizeof(alias->e164)); 01218 } else if (!strcasecmp(v->name, "prefix")) { 01219 ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix)); 01220 } else if (!strcasecmp(v->name, "context")) { 01221 ast_copy_string(alias->context, v->value, sizeof(alias->context)); 01222 } else if (!strcasecmp(v->name, "secret")) { 01223 ast_copy_string(alias->secret, v->value, sizeof(alias->secret)); 01224 } else { 01225 if (strcasecmp(v->value, "h323")) { 01226 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name); 01227 } 01228 } 01229 } 01230 ASTOBJ_UNMARK(alias); 01231 return alias; 01232 }
|
|
||||||||||||||||||||
|
Definition at line 1484 of file chan_h323.c. References ast_append_ha(), ast_get_ip(), ast_log(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_INIT, ASTOBJ_UNREF, calloc, global_options, h323_signalling_port, ast_variable::lineno, LOG_ERROR, ast_variable::name, ast_variable::next, oh323_destroy_peer(), peerl, update_common_options(), and ast_variable::value. Referenced by set_config(). 01485 { 01486 struct oh323_peer *peer; 01487 struct ast_ha *oldha; 01488 int found = 0; 01489 01490 peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp); 01491 01492 if (peer) 01493 found++; 01494 else { 01495 if (!(peer = (struct oh323_peer*)calloc(1, sizeof(*peer)))) 01496 return NULL; 01497 ASTOBJ_INIT(peer); 01498 } 01499 oldha = peer->ha; 01500 peer->ha = NULL; 01501 memcpy(&peer->options, &global_options, sizeof(peer->options)); 01502 peer->options.dtmfmode = 0; 01503 peer->options.holdHandling = 0; 01504 peer->addr.sin_port = htons(h323_signalling_port); 01505 peer->addr.sin_family = AF_INET; 01506 if (!found && name) 01507 ast_copy_string(peer->name, name, sizeof(peer->name)); 01508 01509 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01510 if (peer->chanvars) { 01511 ast_variables_destroy(peer->chanvars); 01512 peer->chanvars = NULL; 01513 } 01514 #endif 01515 /* Default settings for mailbox */ 01516 peer->mailbox[0] = '\0'; 01517 01518 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01519 if (!update_common_options(v, &peer->options)) 01520 continue; 01521 if (!strcasecmp(v->name, "host")) { 01522 if (!strcasecmp(v->value, "dynamic")) { 01523 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n"); 01524 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01525 return NULL; 01526 } 01527 if (ast_get_ip(&peer->addr, v->value)) { 01528 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value); 01529 ASTOBJ_UNREF(peer, oh323_destroy_peer); 01530 return NULL; 01531 } 01532 } else if (!strcasecmp(v->name, "port")) { 01533 peer->addr.sin_port = htons(atoi(v->value)); 01534 } else if (!strcasecmp(v->name, "permit") || 01535 !strcasecmp(v->name, "deny")) { 01536 int ha_error = 0; 01537 01538 peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error); 01539 if (ha_error) 01540 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 01541 } else if (!strcasecmp(v->name, "mailbox")) { 01542 ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox)); 01543 } 01544 } 01545 if (!peer->options.dtmfmode) 01546 peer->options.dtmfmode = global_options.dtmfmode; 01547 if (peer->options.holdHandling == ~0) 01548 peer->options.holdHandling = 0; 01549 else if (!peer->options.holdHandling) 01550 peer->options.holdHandling = global_options.holdHandling; 01551 ASTOBJ_UNMARK(peer); 01552 ast_free_ha(oldha); 01553 return peer; 01554 }
|
|
||||||||||||||||||||
|
Definition at line 1366 of file chan_h323.c. References ast_append_ha(), ast_cdr_amaflags2int(), ast_get_ip(), ast_log(), ast_variables_destroy(), ASTOBJ_CONTAINER_FIND_UNLINK_FULL, ASTOBJ_INIT, ASTOBJ_UNREF, calloc, default_context, format, global_options, ast_variable::lineno, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, oh323_destroy_user(), update_common_options(), userl, and ast_variable::value. Referenced by realtime_user(), reload_config(), and set_config(). 01367 { 01368 struct oh323_user *user; 01369 struct ast_ha *oldha; 01370 int found = 0; 01371 int format; 01372 01373 user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp); 01374 01375 if (user) 01376 found++; 01377 else { 01378 if (!(user = (struct oh323_user *)calloc(1, sizeof(*user)))) 01379 return NULL; 01380 ASTOBJ_INIT(user); 01381 } 01382 oldha = user->ha; 01383 user->ha = (struct ast_ha *)NULL; 01384 memcpy(&user->options, &global_options, sizeof(user->options)); 01385 user->options.dtmfmode = 0; 01386 user->options.holdHandling = 0; 01387 /* Set default context */ 01388 ast_copy_string(user->context, default_context, sizeof(user->context)); 01389 if (user && !found) 01390 ast_copy_string(user->name, name, sizeof(user->name)); 01391 01392 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */ 01393 if (user->chanvars) { 01394 ast_variables_destroy(user->chanvars); 01395 user->chanvars = NULL; 01396 } 01397 #endif 01398 01399 for (; v || ((v = alt) && !(alt = NULL)); v = v->next) { 01400 if (!update_common_options(v, &user->options)) 01401 continue; 01402 if (!strcasecmp(v->name, "context")) { 01403 ast_copy_string(user->context, v->value, sizeof(user->context)); 01404 } else if (!strcasecmp(v->name, "secret")) { 01405 ast_copy_string(user->secret, v->value, sizeof(user->secret)); 01406 } else if (!strcasecmp(v->name, "accountcode")) { 01407 ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode)); 01408 } else if (!strcasecmp(v->name, "host")) { 01409 if (!strcasecmp(v->value, "dynamic")) { 01410 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n"); 01411 ASTOBJ_UNREF(user, oh323_destroy_user); 01412 return NULL; 01413 } else if (ast_get_ip(&user->addr, v->value)) { 01414 ASTOBJ_UNREF(user, oh323_destroy_user); 01415 return NULL; 01416 } 01417 /* Let us know we need to use ip authentication */ 01418 user->host = 1; 01419 } else if (!strcasecmp(v->name, "amaflags")) { 01420 format = ast_cdr_amaflags2int(v->value); 01421 if (format < 0) { 01422 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 01423 } else { 01424 user->amaflags = format; 01425 } 01426 } else if (!strcasecmp(v->name, "permit") || 01427 !strcasecmp(v->name, "deny")) { 01428 int ha_error = 0; 01429 01430 user->ha = ast_append_ha(v->name, v->value, user->ha, &ha_error); 01431 if (ha_error) 01432 ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value); 01433 } 01434 } 01435 if (!user->options.dtmfmode) 01436 user->options.dtmfmode = global_options.dtmfmode; 01437 if (user->options.holdHandling == ~0) 01438 user->options.holdHandling = 0; 01439 else if (!user->options.holdHandling) 01440 user->options.holdHandling = global_options.holdHandling; 01441 ASTOBJ_UNMARK(user); 01442 ast_free_ha(oldha); 01443 return user; 01444 }
|
|
||||||||||||
|
Call-back function to signal asterisk that the channel is ringing Returns nothing Definition at line 2314 of file chan_h323.c. References AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state(). Referenced by load_module(). 02315 { 02316 struct oh323_pvt *pvt; 02317 02318 if (h323debug) 02319 ast_log(LOG_DEBUG, "Ringing on %s\n", token); 02320 02321 pvt = find_call_locked(call_reference, token); 02322 if (!pvt) { 02323 ast_log(LOG_ERROR, "Something is wrong: ringing\n"); 02324 return; 02325 } 02326 if (!pvt->owner) { 02327 ast_mutex_unlock(&pvt->lock); 02328 ast_log(LOG_ERROR, "Channel has no owner\n"); 02329 return; 02330 } 02331 update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING); 02332 ast_mutex_unlock(&pvt->lock); 02333 return; 02334 }
|
|
|
Definition at line 415 of file chan_h323.c. References free. Referenced by __oh323_destroy(), cleanup_connection(), setup_incoming_call(), and setup_outgoing_call(). 00416 { 00417 if (cd->call_token) { 00418 free(cd->call_token); 00419 cd->call_token = NULL; 00420 } 00421 if (cd->call_source_aliases) { 00422 free(cd->call_source_aliases); 00423 cd->call_source_aliases = NULL; 00424 } 00425 if (cd->call_dest_alias) { 00426 free(cd->call_dest_alias); 00427 cd->call_dest_alias = NULL; 00428 } 00429 if (cd->call_source_name) { 00430 free(cd->call_source_name); 00431 cd->call_source_name = NULL; 00432 } 00433 if (cd->call_source_e164) { 00434 free(cd->call_source_e164); 00435 cd->call_source_e164 = NULL; 00436 } 00437 if (cd->call_dest_e164) { 00438 free(cd->call_dest_e164); 00439 cd->call_dest_e164 = NULL; 00440 } 00441 if (cd->sourceIp) { 00442 free(cd->sourceIp); 00443 cd->sourceIp = NULL; 00444 } 00445 if (cd->redirect_number) { 00446 free(cd->redirect_number); 00447 cd->redirect_number = NULL; 00448 } 00449 }
|
|
||||||||||||
|
Call-back function to cleanup communication Returns nothing, Definition at line 2340 of file chan_h323.c. References ast_channel::_softhangup, oh323_pvt::alreadygone, ast_channel_trylock, ast_channel_unlock, ast_dsp_free(), ast_log(), ast_mutex_unlock(), ast_queue_hangup(), ast_rtp_destroy(), AST_SOFTHANGUP_DEV, oh323_pvt::cd, cleanup_call_details(), find_call_locked(), h323debug, oh323_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, oh323_pvt::owner, oh323_pvt::rtp, and oh323_pvt::vad. Referenced by load_module(). 02341 { 02342 struct oh323_pvt *pvt; 02343 02344 if (h323debug) 02345 ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token); 02346 02347 while (1) { 02348 pvt = find_call_locked(call_reference, call_token); 02349 if (!pvt) { 02350 if (h323debug) 02351 ast_log(LOG_DEBUG, "No connection for %s\n", call_token); 02352 return; 02353 } 02354 if (!pvt->owner || !ast_channel_trylock(pvt->owner)) 02355 break; 02356 #if 1 02357 #ifdef DEBUG_THREADS 02358 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]); 02359 #else 02360 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token); 02361 #endif 02362 #endif 02363 ast_mutex_unlock(&pvt->lock); 02364 usleep(1); 02365 } 02366 if (pvt->rtp) { 02367 /* Immediately stop RTP */ 02368 ast_rtp_destroy(pvt->rtp); 02369 pvt->rtp = NULL; 02370 } 02371 /* Free dsp used for in-band DTMF detection */ 02372 if (pvt->vad) { 02373 ast_dsp_free(pvt->vad); 02374 pvt->vad = NULL; 02375 } 02376 cleanup_call_details(&pvt->cd); 02377 pvt->alreadygone = 1; 02378 /* Send hangup */ 02379 if (pvt->owner) { 02380 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02381 ast_queue_hangup(pvt->owner); 02382 ast_channel_unlock(pvt->owner); 02383 } 02384 ast_mutex_unlock(&pvt->lock); 02385 if (h323debug) 02386 ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token); 02387 return; 02388 }
|
|
||||||||||||
|
Call-back function to signal asterisk that the channel has been answered Returns nothing Definition at line 2048 of file chan_h323.c. References AST_CONTROL_ANSWER, ast_log(), ast_mutex_unlock(), oh323_pvt::connection_established, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::outgoing, and update_state(). Referenced by load_module(). 02049 { 02050 struct oh323_pvt *pvt; 02051 02052 if (h323debug) 02053 ast_log(LOG_DEBUG, "Call %s answered\n", token); 02054 02055 pvt = find_call_locked(call_reference, token); 02056 if (!pvt) { 02057 ast_log(LOG_ERROR, "Something is wrong: connection\n"); 02058 return; 02059 } 02060 02061 /* Inform asterisk about remote party connected only on outgoing calls */ 02062 if (!pvt->outgoing) { 02063 ast_mutex_unlock(&pvt->lock); 02064 return; 02065 } 02066 /* Do not send ANSWER message more than once */ 02067 if (!pvt->connection_established) { 02068 pvt->connection_established = 1; 02069 update_state(pvt, -1, AST_CONTROL_ANSWER); 02070 } 02071 ast_mutex_unlock(&pvt->lock); 02072 return; 02073 }
|
|
|
Definition at line 3123 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(). 03124 { 03125 switch (cap) { 03126 case AST_FORMAT_G723_1: 03127 return "G.723"; 03128 case AST_FORMAT_GSM: 03129 return "GSM"; 03130 case AST_FORMAT_ULAW: 03131 return "ULAW"; 03132 case AST_FORMAT_ALAW: 03133 return "ALAW"; 03134 case AST_FORMAT_G722: 03135 return "G.722"; 03136 case AST_FORMAT_ADPCM: 03137 return "G.728"; 03138 case AST_FORMAT_G729A: 03139 return "G.729"; 03140 case AST_FORMAT_SPEEX: 03141 return "SPEEX"; 03142 case AST_FORMAT_ILBC: 03143 return "ILBC"; 03144 default: 03145 ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap); 03146 return NULL; 03147 } 03148 }
|
|
||||||||||||
|
Definition at line 1652 of file chan_h323.c. References ahp, ast_gethostbyname(), ast_log(), AST_RTP_DTMF, ASTOBJ_UNREF, find_peer(), global_options, h323_signalling_port, hp, oh323_pvt::jointcapability, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_destroy_peer(), oh323_pvt::options, and oh323_pvt::sa. Referenced by iax2_call(), iax2_provision(), iax2_request(), oh323_request(), sip_request_call(), and transmit_register(). 01653 { 01654 struct hostent *hp; 01655 struct ast_hostent ahp; 01656 struct oh323_peer *p; 01657 int portno; 01658 int found = 0; 01659 char *port; 01660 char *hostn; 01661 char peer[256] = ""; 01662 01663 ast_copy_string(peer, opeer, sizeof(peer)); 01664 port = strchr(peer, ':'); 01665 if (port) { 01666 *port = '\0'; 01667 port++; 01668 } 01669 pvt->sa.sin_family = AF_INET; 01670 p = find_peer(peer, NULL, 1); 01671 if (p) { 01672 found++; 01673 memcpy(&pvt->options, &p->options, sizeof(pvt->options)); 01674 pvt->jointcapability = pvt->options.capability; 01675 if (pvt->options.dtmfmode) { 01676 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01677 pvt->nonCodecCapability |= AST_RTP_DTMF; 01678 } else { 01679 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01680 } 01681 } 01682 if (p->addr.sin_addr.s_addr) { 01683 pvt->sa.sin_addr = p->addr.sin_addr; 01684 pvt->sa.sin_port = p->addr.sin_port; 01685 } 01686 ASTOBJ_UNREF(p, oh323_destroy_peer); 01687 } 01688 if (!p && !found) { 01689 hostn = peer; 01690 if (port) { 01691 portno = atoi(port); 01692 } else { 01693 portno = h323_signalling_port; 01694 } 01695 hp = ast_gethostbyname(hostn, &ahp); 01696 if (hp) { 01697 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 01698 pvt->sa.sin_port = htons(portno); 01699 /* Look peer by address */ 01700 p = find_peer(NULL, &pvt->sa, 1); 01701 memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options)); 01702 pvt->jointcapability = pvt->options.capability; 01703 if (p) { 01704 ASTOBJ_UNREF(p, oh323_destroy_peer); 01705 } 01706 if (pvt->options.dtmfmode) { 01707 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01708 pvt->nonCodecCapability |= AST_RTP_DTMF; 01709 } else { 01710 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01711 } 01712 } 01713 return 0; 01714 } else { 01715 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01716 return -1; 01717 } 01718 } else if (!found) { 01719 return -1; 01720 } else { 01721 return 0; 01722 } 01723 }
|
|
|
Definition at line 3037 of file chan_h323.c. References aliasl, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, and ASTOBJ_UNLOCK. Referenced by h323_do_reload(). 03038 { 03039 int pruned = 0; 03040 03041 /* Delete all aliases */ 03042 ASTOBJ_CONTAINER_WRLOCK(&aliasl); 03043 ASTOBJ_CONTAINER_TRAVERSE(&aliasl, 1, do { 03044 ASTOBJ_RDLOCK(iterator); 03045 ASTOBJ_MARK(iterator); 03046 ++pruned; 03047 ASTOBJ_UNLOCK(iterator); 03048 } while (0) ); 03049 if (pruned) { 03050 ASTOBJ_CONTAINER_PRUNE_MARKED(&aliasl, oh323_destroy_alias); 03051 } 03052 ASTOBJ_CONTAINER_UNLOCK(&aliasl); 03053 }
|
|
|
Definition at line 3011 of file chan_h323.c. References ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_CONTAINER_WRLOCK, ASTOBJ_MARK, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, and userl. Referenced by __unload_module(), h323_do_reload(), and reload_config(). 03012 { 03013 int pruned = 0; 03014 03015 /* Delete all users */ 03016 ASTOBJ_CONTAINER_WRLOCK(&userl); 03017 ASTOBJ_CONTAINER_TRAVERSE(&userl, 1, do { 03018 ASTOBJ_RDLOCK(iterator); 03019 ASTOBJ_MARK(iterator); 03020 ++pruned; 03021 ASTOBJ_UNLOCK(iterator); 03022 } while (0) ); 03023 if (pruned) { 03024 ASTOBJ_CONTAINER_PRUNE_MARKED(&userl, oh323_destroy_user); 03025 } 03026 ASTOBJ_CONTAINER_UNLOCK(&userl); 03027 03028 ASTOBJ_CONTAINER_WRLOCK(&peerl); 03029 ASTOBJ_CONTAINER_TRAVERSE(&peerl, 1, do { 03030 ASTOBJ_RDLOCK(iterator); 03031 ASTOBJ_MARK(iterator); 03032 ASTOBJ_UNLOCK(iterator); 03033 } while (0) ); 03034 ASTOBJ_CONTAINER_UNLOCK(&peerl); 03035 }
|
|
|
Definition at line 2515 of file chan_h323.c. References __oh323_destroy(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_verbose(), h323_do_reload(), h323_reloading, iflist, oh323_pvt::lock, oh323_pvt::needdestroy, oh323_pvt::next, option_verbose, and VERBOSE_PREFIX_1. Referenced by restart_monitor(). 02516 { 02517 int res; 02518 int reloading; 02519 struct oh323_pvt *oh323 = NULL; 02520 02521 for(;;) { 02522 /* Check for a reload request */ 02523 ast_mutex_lock(&h323_reload_lock); 02524 reloading = h323_reloading; 02525 h323_reloading = 0; 02526 ast_mutex_unlock(&h323_reload_lock); 02527 if (reloading) { 02528 if (option_verbose > 0) { 02529 ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n"); 02530 } 02531 h323_do_reload(); 02532 } 02533 /* Check for interfaces needing to be killed */ 02534 if (!ast_mutex_trylock(&iflock)) { 02535 #if 1 02536 do { 02537 for (oh323 = iflist; oh323; oh323 = oh323->next) { 02538 if (!ast_mutex_trylock(&oh323->lock)) { 02539 if (oh323->needdestroy) { 02540 __oh323_destroy(oh323); 02541 break; 02542 } 02543 ast_mutex_unlock(&oh323->lock); 02544 } 02545 } 02546 } while (/*oh323*/ 0); 02547 #else 02548 restartsearch: 02549 oh323 = iflist; 02550 while(oh323) { 02551 if (!ast_mutex_trylock(&oh323->lock)) { 02552 if (oh323->needdestroy) { 02553 __oh323_destroy(oh323); 02554 goto restartsearch; 02555 } 02556 ast_mutex_unlock(&oh323->lock); 02557 oh323 = oh323->next; 02558 } 02559 } 02560 #endif 02561 ast_mutex_unlock(&iflock); 02562 } else 02563 oh323 = (struct oh323_pvt *)1; /* Force fast loop */ 02564 pthread_testcancel(); 02565 /* Wait for sched or io */ 02566 res = ast_sched_wait(sched); 02567 if ((res < 0) || (res > 1000)) { 02568 res = 1000; 02569 } 02570 /* Do not wait if some channel(s) is destroyed, probably, more available too */ 02571 if (oh323) 02572 res = 1; 02573 res = ast_io_wait(io, res); 02574 pthread_testcancel(); 02575 ast_mutex_lock(&monlock); 02576 if (res >= 0) { 02577 ast_sched_runq(sched); 02578 } 02579 ast_mutex_unlock(&monlock); 02580 } 02581 /* Never reached */ 02582 return NULL; 02583 }
|
|
||||||||||||
|
Callback function used to inform the H.323 stack of the local rtp ip/port details Returns the local RTP information Definition at line 1890 of file chan_h323.c. References __oh323_rtp_create(), ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_rtp_get_us(), find_call_locked(), free, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, malloc, and oh323_pvt::rtp. Referenced by load_module(). 01891 { 01892 struct oh323_pvt *pvt; 01893 struct sockaddr_in us; 01894 struct rtp_info *info; 01895 01896 info = (struct rtp_info *)malloc(sizeof(struct rtp_info)); 01897 if (!info) { 01898 ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n"); 01899 return NULL; 01900 } 01901 pvt = find_call_locked(call_reference, token); 01902 if (!pvt) { 01903 free(info); 01904 ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference); 01905 return NULL; 01906 } 01907 if (!pvt->rtp) 01908 __oh323_rtp_create(pvt); 01909 if (!pvt->rtp) { 01910 ast_mutex_unlock(&pvt->lock); 01911 free(info); 01912 ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference); 01913 return NULL; 01914 } 01915 /* figure out our local RTP port and tell the H.323 stack about it */ 01916 ast_rtp_get_us(pvt->rtp, &us); 01917 ast_mutex_unlock(&pvt->lock); 01918 01919 ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr)); 01920 info->port = ntohs(us.sin_port); 01921 if (h323debug) 01922 ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port); 01923 return info; 01924 }
|
|
||||||||||||
|
Find a call by alias Definition at line 1813 of file chan_h323.c. References aliasl, ASTOBJ_CONTAINER_FIND, and realtime_alias(). Referenced by add_header(), and setup_incoming_call(). 01814 { 01815 struct oh323_alias *a; 01816 01817 a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases); 01818 01819 if (!a && realtime) 01820 a = realtime_alias(source_aliases); 01821 01822 return a; 01823 }
|
|
||||||||||||
|
Definition at line 1152 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(), remote_hold(), set_dtmf_payload(), set_local_capabilities(), set_peer_capabilities(), and setup_rtp_connection(). 01153 { 01154 struct oh323_pvt *pvt; 01155 01156 ast_mutex_lock(&iflock); 01157 pvt = iflist; 01158 while(pvt) { 01159 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) { 01160 /* Found the call */ 01161 if ((token != NULL) && (!strcmp(pvt->cd.call_token, token))) { 01162 ast_mutex_lock(&pvt->lock); 01163 ast_mutex_unlock(&iflock); 01164 return pvt; 01165 } else if (token == NULL) { 01166 ast_log(LOG_WARNING, "Call Token is NULL\n"); 01167 ast_mutex_lock(&pvt->lock); 01168 ast_mutex_unlock(&iflock); 01169 return pvt; 01170 } 01171 } 01172 pvt = pvt->next; 01173 } 01174 ast_mutex_unlock(&iflock); 01175 return NULL; 01176 }
|
|
||||||||||||||||
|
||||||||||||
|
Definition at line 1604 of file chan_h323.c. References ast_log(), ASTOBJ_CONTAINER_FIND, ASTOBJ_CONTAINER_FIND_FULL, h323debug, LOG_DEBUG, oh323_addrcmp_str(), realtime_user(), userbyalias, and userl. Referenced by check_user_ok(), setup_incoming_call(), sip_show_user(), and update_call_counter(). 01605 { 01606 struct oh323_user *u; 01607 01608 if (userbyalias) 01609 u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases); 01610 else 01611 u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str); 01612 01613 if (!u && realtime) 01614 u = realtime_user(cd); 01615 01616 if (!u && h323debug) 01617 ast_log(LOG_DEBUG, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp); 01618 01619 return u; 01620 }
|
|
||||||||||||||||
|
Definition at line 2640 of file chan_h323.c. References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 02641 { 02642 if (argc < 2 || argc > 3) { 02643 return RESULT_SHOWUSAGE; 02644 } 02645 h323debug = 1; 02646 ast_cli(fd, "H.323 debug enabled\n"); 02647 return RESULT_SUCCESS; 02648 }
|
|
|
Definition at line 3074 of file chan_h323.c. References delete_aliases(), delete_users(), prune_peers(), and reload_config(). Referenced by do_monitor(). 03075 { 03076 delete_users(); 03077 delete_aliases(); 03078 prune_peers(); 03079 reload_config(1); 03080 return 0; 03081 }
|
|
||||||||||||||||
|
Definition at line 2620 of file chan_h323.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 02621 { 02622 if (argc != 4) { 02623 return RESULT_SHOWUSAGE; 02624 } 02625 h323_debug(1, atoi(argv[3])); 02626 ast_cli(fd, "H.323 trace set to level %s\n", argv[2]); 02627 return RESULT_SUCCESS; 02628 }
|
|
||||||||||||||||
|
Definition at line 2676 of file chan_h323.c. References ast_verbose(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and VERBOSE_PREFIX_3. 02677 { 02678 if (argc != 3) { 02679 return RESULT_SHOWUSAGE; 02680 } 02681 if (h323_soft_hangup(argv[2])) { 02682 ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]); 02683 } else { 02684 ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]); 02685 } 02686 return RESULT_SUCCESS; 02687 }
|
|
||||||||||||||||
|
Definition at line 2660 of file chan_h323.c. References ast_log(), gatekeeper, gatekeeper_disable, gatekeeper_discover, LOG_ERROR, RESULT_SHOWUSAGE, RESULT_SUCCESS, and secret. 02661 { 02662 if (argc != 3) { 02663 return RESULT_SHOWUSAGE; 02664 } 02665 h323_gk_urq(); 02666 02667 /* Possibly register with a GK */ 02668 if (!gatekeeper_disable) { 02669 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 02670 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 02671 } 02672 } 02673 return RESULT_SUCCESS; 02674 }
|
|
||||||||||||||||
|
Definition at line 2650 of file chan_h323.c. References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 02651 { 02652 if (argc < 3 || argc > 4) { 02653 return RESULT_SHOWUSAGE; 02654 } 02655 h323debug = 0; 02656 ast_cli(fd, "H.323 debug disabled\n"); 02657 return RESULT_SUCCESS; 02658 }
|
|
||||||||||||||||
|
Definition at line 2630 of file chan_h323.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 02631 { 02632 if (argc < 3 || argc > 4) { 02633 return RESULT_SHOWUSAGE; 02634 } 02635 h323_debug(0,0); 02636 ast_cli(fd, "H.323 trace disabled\n"); 02637 return RESULT_SUCCESS; 02638 }
|
|
||||||||||||||||
|
Definition at line 3061 of file chan_h323.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), h323_reloading, and restart_monitor(). Referenced by reload(). 03062 { 03063 ast_mutex_lock(&h323_reload_lock); 03064 if (h323_reloading) { 03065 ast_verbose("Previous H.323 reload not yet done\n"); 03066 } else { 03067 h323_reloading = 1; 03068 } 03069 ast_mutex_unlock(&h323_reload_lock); 03070 restart_monitor(); 03071 return 0; 03072 }
|
|
||||||||||||||||
|
Definition at line 2689 of file chan_h323.c. References RESULT_SHOWUSAGE, and RESULT_SUCCESS. 02690 { 02691 if (argc != 3) { 02692 return RESULT_SHOWUSAGE; 02693 } 02694 h323_show_tokens(); 02695 return RESULT_SUCCESS; 02696 }
|
|
||||||||||||||||
|
Definition at line 2390 of file chan_h323.c. References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, ast_log(), ast_mutex_unlock(), ast_queue_hangup(), AST_SOFTHANGUP_DEV, find_call_locked(), h323debug, oh323_pvt::hangupcause, ast_channel::hangupcause, oh323_pvt::lock, LOG_DEBUG, oh323_pvt::needhangup, and oh323_pvt::owner. Referenced by load_module(). 02391 { 02392 struct oh323_pvt *pvt; 02393 02394 if (h323debug) { 02395 ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause); 02396 } 02397 02398 pvt = find_call_locked(call_reference, token); 02399 if (!pvt) { 02400 if (h323debug) { 02401 ast_log(LOG_DEBUG, "Connection to %s already cleared\n", token); 02402 } 02403 return; 02404 } 02405 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 02406 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02407 pvt->owner->hangupcause = pvt->hangupcause = cause; 02408 ast_queue_hangup(pvt->owner); 02409 ast_channel_unlock(pvt->owner); 02410 } 02411 else { 02412 pvt->needhangup = 1; 02413 pvt->hangupcause = cause; 02414 if (h323debug) 02415 ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token); 02416 } 02417 ast_mutex_unlock(&pvt->lock); 02418 }
|
|
|
||||||||||||
|
Definition at line 1622 of file chan_h323.c. References inaddrcmp(). Referenced by find_peer(). 01623 { 01624 int res; 01625 01626 if (!sin) 01627 res = -1; 01628 else 01629 res = inaddrcmp(&addr , sin); 01630 01631 return res; 01632 }
|
|
||||||||||||
|
Definition at line 1599 of file chan_h323.c. References ast_inet_ntoa(). Referenced by find_user(). 01600 { 01601 return strcmp(ast_inet_ntoa(inaddr), addr); 01602 }
|
|
|
Definition at line 1108 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(). 01109 { 01110 struct oh323_pvt *pvt; 01111 01112 pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt)); 01113 if (!pvt) { 01114 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n"); 01115 return NULL; 01116 } 01117 memset(pvt, 0, sizeof(struct oh323_pvt)); 01118 pvt->cd.redirect_reason = -1; 01119 pvt->cd.transfer_capability = -1; 01120 /* Ensure the call token is allocated for outgoing call */ 01121 if (!callid) { 01122 if ((pvt->cd).call_token == NULL) { 01123 (pvt->cd).call_token = (char *)malloc(128); 01124 } 01125 if (!pvt->cd.call_token) { 01126 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n"); 01127 ast_rtp_destroy(pvt->rtp); 01128 free(pvt); 01129 return NULL; 01130 } 01131 memset((char *)(pvt->cd).call_token, 0, 128); 01132 pvt->cd.call_reference = callid; 01133 } 01134 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01135 pvt->jointcapability = pvt->options.capability; 01136 if (pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO)) { 01137 pvt->nonCodecCapability |= AST_RTP_DTMF; 01138 } else { 01139 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01140 } 01141 ast_copy_string(pvt->context, default_context, sizeof(pvt->context)); 01142 pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1; 01143 ast_mutex_init(&pvt->lock); 01144 /* Add to interface list */ 01145 ast_mutex_lock(&iflock); 01146 pvt->next = iflist; 01147 iflist = pvt; 01148 ast_mutex_unlock(&iflock); 01149 return pvt; 01150 }
|
|
|
Definition at line 669 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. 00670 { 00671 int res; 00672 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00673 char *token; 00674 00675 if (h323debug) 00676 ast_log(LOG_DEBUG, "Answering on %s\n", c->name); 00677 00678 ast_mutex_lock(&pvt->lock); 00679 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00680 ast_mutex_unlock(&pvt->lock); 00681 res = h323_answering_call(token, 0); 00682 if (token) 00683 free(token); 00684 00685 oh323_update_info(c); 00686 if (c->_state != AST_STATE_UP) { 00687 ast_setstate(c, AST_STATE_UP); 00688 } 00689 return res; 00690 }
|
|
||||||||||||||||
|
Make a call over the specified channel to the specified destination. Returns -1 on error, 0 on success. Definition at line 590 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. 00591 { 00592 int res = 0; 00593 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00594 const char *addr; 00595 char called_addr[1024]; 00596 00597 if (h323debug) { 00598 ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name); 00599 } 00600 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 00601 ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name); 00602 return -1; 00603 } 00604 ast_mutex_lock(&pvt->lock); 00605 if (!gatekeeper_disable) { 00606 if (ast_strlen_zero(pvt->exten)) { 00607 ast_copy_string(called_addr, dest, sizeof(called_addr)); 00608 } else { 00609 snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest); 00610 } 00611 } else { 00612 res = htons(pvt->sa.sin_port); 00613 addr = ast_inet_ntoa(pvt->sa.sin_addr); 00614 if (ast_strlen_zero(pvt->exten)) { 00615 snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res); 00616 } else { 00617 snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res); 00618 } 00619 } 00620 /* make sure null terminated */ 00621 called_addr[sizeof(called_addr) - 1] = '\0'; 00622 00623 if (c->cid.cid_num) 00624 ast_copy_string(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num)); 00625 00626 if (c->cid.cid_name) 00627 ast_copy_string(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name)); 00628 00629 if (c->cid.cid_rdnis) { 00630 ast_copy_string(pvt->options.cid_rdnis, c->cid.cid_rdnis, sizeof(pvt->options.cid_rdnis)); 00631 } 00632 00633 pvt->options.presentation = c->cid.cid_pres; 00634 pvt->options.type_of_number = c->cid.cid_ton; 00635 00636 if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) { 00637 if (!strcasecmp(addr, "UNKNOWN")) 00638 pvt->options.redirect_reason = 0; 00639 else if (!strcasecmp(addr, "BUSY")) 00640 pvt->options.redirect_reason = 1; 00641 else if (!strcasecmp(addr, "NO_REPLY")) 00642 pvt->options.redirect_reason = 2; 00643 else if (!strcasecmp(addr, "UNCONDITIONAL")) 00644 pvt->options.redirect_reason = 15; 00645 else 00646 pvt->options.redirect_reason = -1; 00647 } else 00648 pvt->options.redirect_reason = -1; 00649 00650 pvt->options.transfer_capability = c->transfercapability; 00651 00652 /* indicate that this is an outgoing call */ 00653 pvt->outgoing = 1; 00654 00655 if (option_verbose > 2) 00656 ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability)); 00657 if (h323debug) 00658 ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d/%d\n", called_addr, pvt->options.dtmfcodec[0], pvt->options.dtmfcodec[1]); 00659 ast_mutex_unlock(&pvt->lock); 00660 res = h323_make_call(called_addr, &(pvt->cd), &pvt->options); 00661 if (res) { 00662 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name); 00663 return -1; 00664 } 00665 oh323_update_info(c); 00666 return 0; 00667 }
|
|
|
Definition at line 499 of file chan_h323.c. References __oh323_destroy(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, LOG_DEBUG, and oh323_pvt::owner. Referenced by oh323_request(), and setup_incoming_call(). 00500 { 00501 if (h323debug) { 00502 ast_log(LOG_DEBUG, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>")); 00503 } 00504 ast_mutex_lock(&iflock); 00505 ast_mutex_lock(&pvt->lock); 00506 __oh323_destroy(pvt); 00507 ast_mutex_unlock(&iflock); 00508 }
|
|
|
Definition at line 284 of file chan_h323.c. References ast_log(), free, and LOG_DEBUG. Referenced by load_module(), and unload_module(). 00285 { 00286 if (h323debug) 00287 ast_log(LOG_DEBUG, "Destroying alias '%s'\n", alias->name); 00288 free(alias); 00289 }
|
|
|
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(), 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 }
|
|
|
Definition at line 291 of file chan_h323.c. References ast_free_ha(), ast_log(), free, and LOG_DEBUG. Referenced by build_user(), 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 }
|
|
||||||||||||
|
Definition at line 510 of file chan_h323.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit_begin(), oh323_pvt::cd, oh323_pvt::dtmf_pt, free, oh323_pvt::lock, LOG_DTMF, LOG_ERROR, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, ast_channel::tech_pvt, and oh323_pvt::txDtmfDigit. 00511 { 00512 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00513 char *token; 00514 00515 if (!pvt) { 00516 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00517 return -1; 00518 } 00519 ast_mutex_lock(&pvt->lock); 00520 if (pvt->rtp && 00521 (((pvt->options.dtmfmode & H323_DTMF_RFC2833) && pvt->dtmf_pt[0]) 00522 /*|| ((pvt->options.dtmfmode & H323_DTMF_CISCO) && pvt->dtmf_pt[1]))*/)) { 00523 /* out-of-band DTMF */ 00524 if (h323debug) { 00525 ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name); 00526 } 00527 ast_rtp_senddigit_begin(pvt->rtp, digit); 00528 ast_mutex_unlock(&pvt->lock); 00529 } else if (pvt->txDtmfDigit != digit) { 00530 /* in-band DTMF */ 00531 if (h323debug) { 00532 ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name); 00533 } 00534 pvt->txDtmfDigit = digit; 00535 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00536 ast_mutex_unlock(&pvt->lock); 00537 h323_send_tone(token, digit); 00538 if (token) { 00539 free(token); 00540 } 00541 } else 00542 ast_mutex_unlock(&pvt->lock); 00543 oh323_update_info(c); 00544 return 0; 00545 }
|
|
||||||||||||||||
|
Send (play) the specified digit to the channel. Definition at line 551 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. 00552 { 00553 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00554 char *token; 00555 00556 if (!pvt) { 00557 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00558 return -1; 00559 } 00560 ast_mutex_lock(&pvt->lock); 00561 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && ((pvt->dtmf_pt[0] > 0) || (pvt->dtmf_pt[0] > 0))) { 00562 /* out-of-band DTMF */ 00563 if (h323debug) { 00564 ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s\n", digit, c->name); 00565 } 00566 ast_rtp_senddigit_end(pvt->rtp, digit); 00567 ast_mutex_unlock(&pvt->lock); 00568 } else { 00569 /* in-band DTMF */ 00570 if (h323debug) { 00571 ast_log(LOG_DTMF, "End sending inband digit %c on %s\n", digit, c->name); 00572 } 00573 pvt->txDtmfDigit = ' '; 00574 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00575 ast_mutex_unlock(&pvt->lock); 00576 h323_send_tone(token, ' '); 00577 if (token) { 00578 free(token); 00579 } 00580 } 00581 oh323_update_info(c); 00582 return 0; 00583 }
|
|
||||||||||||
|
Definition at line 944 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. 00945 { 00946 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt; 00947 00948 ast_mutex_lock(&pvt->lock); 00949 if (pvt->owner != oldchan) { 00950 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner); 00951 return -1; 00952 } 00953 pvt->owner = newchan; 00954 ast_mutex_unlock(&pvt->lock); 00955 return 0; 00956 }
|
|
||||||||||||
|
Definition at line 3100 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. 03101 { 03102 struct oh323_pvt *pvt; 03103 enum ast_rtp_get_result res = AST_RTP_GET_FAILED; 03104 03105 if (!(pvt = (struct oh323_pvt *)chan->tech_pvt)) 03106 return res; 03107 03108 ast_mutex_lock(&pvt->lock); 03109 if (pvt->rtp && pvt->options.bridge) { 03110 *rtp = pvt->rtp; 03111 res = AST_RTP_TRY_NATIVE; 03112 } 03113 ast_mutex_unlock(&pvt->lock); 03114 03115 return res; 03116 }
|
|
||||||||||||
|
Definition at line 3118 of file chan_h323.c. References AST_RTP_GET_FAILED. 03119 { 03120 return AST_RTP_GET_FAILED; 03121 }
|
|
|
Definition at line 692 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. 00693 { 00694 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00695 int q931cause = AST_CAUSE_NORMAL_CLEARING; 00696 char *call_token; 00697 00698 00699 if (h323debug) 00700 ast_log(LOG_DEBUG, "Hanging up and scheduling destroy of call %s\n", c->name); 00701 00702 if (!c->tech_pvt) { 00703 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 00704 return 0; 00705 } 00706 ast_mutex_lock(&pvt->lock); 00707 /* Determine how to disconnect */ 00708 if (pvt->owner != c) { 00709 ast_log(LOG_WARNING, "Huh? We aren't the owner?\n"); 00710 ast_mutex_unlock(&pvt->lock); 00711 return 0; 00712 } 00713 00714 pvt->owner = NULL; 00715 c->tech_pvt = NULL; 00716 00717 if (c->hangupcause) { 00718 q931cause = c->hangupcause; 00719 } else { 00720 const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 00721 if (cause) { 00722 if (!strcmp(cause, "CONGESTION")) { 00723 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 00724 } else if (!strcmp(cause, "BUSY")) { 00725 q931cause = AST_CAUSE_USER_BUSY; 00726 } else if (!strcmp(cause, "CHANISUNVAIL")) { 00727 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; 00728 } else if (!strcmp(cause, "NOANSWER")) { 00729 q931cause = AST_CAUSE_NO_ANSWER; 00730 } else if (!strcmp(cause, "CANCEL")) { 00731 q931cause = AST_CAUSE_CALL_REJECTED; 00732 } 00733 } 00734 } 00735 00736 /* Start the process if it's not already started */ 00737 if (!pvt->alreadygone && !pvt->hangupcause) { 00738 call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00739 if (call_token) { 00740 /* Release lock to eliminate deadlock */ 00741 ast_mutex_unlock(&pvt->lock); 00742 if (h323_clear_call(call_token, q931cause)) { 00743 ast_log(LOG_WARNING, "ClearCall failed.\n"); 00744 } 00745 free(call_token); 00746 ast_mutex_lock(&pvt->lock); 00747 } 00748 } 00749 pvt->needdestroy = 1; 00750 ast_mutex_unlock(&pvt->lock); 00751 00752 /* Update usage counter */ 00753 ast_module_unref(ast_module_info->self); 00754 00755 return 0; 00756 }
|
|
||||||||||||||||||||
|
Definition at line 867 of file chan_h323.c. References ast_channel::_state, oh323_pvt::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, oh323_pvt::cd, free, oh323_pvt::got_progress, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_update_info(), strdup, and ast_channel::tech_pvt. 00868 { 00869 00870 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00871 char *token = (char *)NULL; 00872 int res = -1; 00873 int got_progress; 00874 00875 ast_mutex_lock(&pvt->lock); 00876 token = (pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL); 00877 got_progress = pvt->got_progress; 00878 if (condition == AST_CONTROL_PROGRESS) 00879 pvt->got_progress = 1; 00880 else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION)) 00881 pvt->alreadygone = 1; 00882 ast_mutex_unlock(&pvt->lock); 00883 00884 if (h323debug) 00885 ast_log(LOG_DEBUG, "OH323: Indicating %d on %s (%s)\n", condition, token, c->name); 00886 00887 switch(condition) { 00888 case AST_CONTROL_RINGING: 00889 if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) { 00890 h323_send_alerting(token); 00891 res = (got_progress ? 0 : -1); /* Do not simulate any audio tones if we got PROGRESS message */ 00892 } 00893 break; 00894 case AST_CONTROL_PROGRESS: 00895 if (c->_state != AST_STATE_UP) { 00896 /* Do not send PROGRESS message more than once */ 00897 if (!got_progress) 00898 h323_send_progress(token); 00899 res = 0; 00900 } 00901 break; 00902 case AST_CONTROL_BUSY: 00903 if (c->_state != AST_STATE_UP) { 00904 h323_answering_call(token, 1); 00905 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00906 res = 0; 00907 } 00908 break; 00909 case AST_CONTROL_CONGESTION: 00910 if (c->_state != AST_STATE_UP) { 00911 h323_answering_call(token, 1); 00912 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00913 res = 0; 00914 } 00915 break; 00916 case AST_CONTROL_HOLD: 00917 h323_hold_call(token, 1); 00918 /* We should start MOH only if remote party isn't provide audio for us */ 00919 ast_moh_start(c, data, NULL); 00920 res = 0; 00921 break; 00922 case AST_CONTROL_UNHOLD: 00923 h323_hold_call(token, 0); 00924 ast_moh_stop(c); 00925 res = 0; 00926 break; 00927 case AST_CONTROL_PROCEEDING: 00928 case -1: 00929 break; 00930 default: 00931 ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token); 00932 break; 00933 } 00934 00935 if (h323debug) 00936 ast_log(LOG_DEBUG, "OH323: Indicated %d on %s, res=%d\n", condition, token, res); 00937 if (token) 00938 free(token); 00939 oh323_update_info(c); 00940 00941 return res; 00942 }
|
|
|
Definition at line 814 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. 00815 { 00816 struct ast_frame *fr; 00817 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00818 ast_mutex_lock(&pvt->lock); 00819 __oh323_update_info(c, pvt); 00820 switch(c->fdno) { 00821 case 0: 00822 fr = oh323_rtp_read(pvt); 00823 break; 00824 case 1: 00825 if (pvt->rtp) 00826 fr = ast_rtcp_read(pvt->rtp); 00827 else 00828 fr = &ast_null_frame; 00829 break; 00830 default: 00831 ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name); 00832 fr = &ast_null_frame; 00833 break; 00834 } 00835 ast_mutex_unlock(&pvt->lock); 00836 return fr; 00837 }
|
|
||||||||||||||||||||
|
Definition at line 1724 of file chan_h323.c. References __oh323_new(), AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_INCOMPATIBLE_DESTINATION, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_FORMAT_MAX_AUDIO, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), create_addr(), ext, oh323_pvt::exten, gatekeeper_disable, global_options, h323debug, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_alloc(), oh323_destroy(), oh323_pvt::options, restart_monitor(), and unique. 01725 { 01726 int oldformat; 01727 struct oh323_pvt *pvt; 01728 struct ast_channel *tmpc = NULL; 01729 char *dest = (char *)data; 01730 char *ext, *host; 01731 char *h323id = NULL; 01732 char tmp[256], tmp1[256]; 01733 01734 if (h323debug) 01735 ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data); 01736 01737 pvt = oh323_alloc(0); 01738 if (!pvt) { 01739 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data); 01740 return NULL; 01741 } 01742 oldformat = format; 01743 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 01744 if (!format) { 01745 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 01746 oh323_destroy(pvt); 01747 if (cause) 01748 *cause = AST_CAUSE_INCOMPATIBLE_DESTINATION; 01749 return NULL; 01750 } 01751 ast_copy_string(tmp, dest, sizeof(tmp)); 01752 host = strchr(tmp, '@'); 01753 if (host) { 01754 *host = '\0'; 01755 host++; 01756 ext = tmp; 01757 } else { 01758 ext = strrchr(tmp, '/'); 01759 if (ext) 01760 *ext++ = '\0'; 01761 host = tmp; 01762 } 01763 strtok_r(host, "/", &(h323id)); 01764 if (!ast_strlen_zero(h323id)) { 01765 h323_set_id(h323id); 01766 } 01767 if (ext) { 01768 ast_copy_string(pvt->exten, ext, sizeof(pvt->exten)); 01769 } 01770 if (h323debug) 01771 ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host); 01772 01773 if (gatekeeper_disable) { 01774 if (create_addr(pvt, host)) { 01775 oh323_destroy(pvt); 01776 if (cause) 01777 *cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 01778 return NULL; 01779 } 01780 } 01781 else { 01782 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01783 pvt->jointcapability = pvt->options.capability; 01784 if (pvt->options.dtmfmode) { 01785 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01786 pvt->nonCodecCapability |= AST_RTP_DTMF; 01787 } else { 01788 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01789 } 01790 } 01791 } 01792 01793 ast_mutex_lock(&caplock); 01794 /* Generate unique channel identifier */ 01795 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique); 01796 tmp1[sizeof(tmp1)-1] = '\0'; 01797 ast_mutex_unlock(&caplock); 01798 01799 ast_mutex_lock(&pvt->lock); 01800 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1); 01801 ast_mutex_unlock(&pvt->lock); 01802 if (!tmpc) { 01803 oh323_destroy(pvt); 01804 if (cause) 01805 *cause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE; 01806 } 01807 ast_update_use_count(); 01808 restart_monitor(); 01809 return tmpc; 01810 }
|
|
|
Definition at line 758 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(), 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(). 00759 { 00760 /* Retrieve audio/etc from channel. Assumes pvt->lock is already held. */ 00761 struct ast_frame *f; 00762 00763 /* Only apply it for the first packet, we just need the correct ip/port */ 00764 if (pvt->options.nat) { 00765 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00766 pvt->options.nat = 0; 00767 } 00768 00769 f = ast_rtp_read(pvt->rtp); 00770 /* Don't send RFC2833 if we're not supposed to */ 00771 if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO))) { 00772 return &ast_null_frame; 00773 } 00774 if (pvt->owner) { 00775 /* We already hold the channel lock */ 00776 if (f->frametype == AST_FRAME_VOICE) { 00777 if (f->subclass != pvt->owner->nativeformats) { 00778 /* Try to avoid deadlock */ 00779 if (ast_channel_trylock(pvt->owner)) { 00780 ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n"); 00781 return &ast_null_frame; 00782 } 00783 if (h323debug) 00784 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 00785 pvt->owner->nativeformats = f->subclass; 00786 pvt->nativeformats = f->subclass; 00787 ast_set_read_format(pvt->owner, pvt->owner->readformat); 00788 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 00789 ast_channel_unlock(pvt->owner); 00790 } 00791 /* Do in-band DTMF detection */ 00792 if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) { 00793 if ((pvt->nativeformats & (AST_FORMAT_SLINEAR | AST_FORMAT_ALAW | AST_FORMAT_ULAW))) { 00794 if (!ast_channel_trylock(pvt->owner)) { 00795 f = ast_dsp_process(pvt->owner, pvt->vad, f); 00796 ast_channel_unlock(pvt->owner); 00797 } 00798 else 00799 ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n"); 00800 } else if (pvt->nativeformats && !pvt->noInbandDtmf) { 00801 ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass)); 00802 pvt->noInbandDtmf = 1; 00803 } 00804 if (f &&(f->frametype == AST_FRAME_DTMF)) { 00805 if (h323debug) 00806 ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass); 00807 } 00808 } 00809 } 00810 } 00811 return f; 00812 }
|
|
||||||||||||||||||||||||
|
Definition at line 3150 of file chan_h323.c. References ast_inet_ntoa(), ast_log(), ast_rtp_get_peer(), ast_rtp_get_us(), oh323_pvt::cd, convertcap(), LOG_ERROR, oh323_pvt::rtp, ast_channel::tech_pvt, and ast_channel::writeformat. 03151 { 03152 /* XXX Deal with Video */ 03153 struct oh323_pvt *pvt; 03154 struct sockaddr_in them; 03155 struct sockaddr_in us; 03156 char *mode; 03157 03158 if (!rtp) { 03159 return 0; 03160 } 03161 03162 mode = convertcap(chan->writeformat); 03163 pvt = (struct oh323_pvt *) chan->tech_pvt; 03164 if (!pvt) { 03165 ast_log(LOG_ERROR, "No Private Structure, this is bad\n"); 03166 return -1; 03167 } 03168 ast_rtp_get_peer(rtp, &them); 03169 ast_rtp_get_us(rtp, &us); 03170 #if 0 /* Native bridge still isn't ready */ 03171 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode); 03172 #endif 03173 return 0; 03174 }
|
|
|
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 = 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 }
|
|
|
Definition at line 404 of file chan_h323.c. References __oh323_update_info(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, and ast_channel::tech_pvt. Referenced by oh323_answer(), oh323_call(), oh323_digit_begin(), oh323_digit_end(), and oh323_indicate(). 00405 { 00406 struct oh323_pvt *pvt = c->tech_pvt; 00407 00408 if (pvt) { 00409 ast_mutex_lock(&pvt->lock); 00410 __oh323_update_info(c, pvt); 00411 ast_mutex_unlock(&pvt->lock); 00412 } 00413 }
|
|
||||||||||||
|
Definition at line 839 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. 00840 { 00841 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00842 int res = 0; 00843 if (frame->frametype != AST_FRAME_VOICE) { 00844 if (frame->frametype == AST_FRAME_IMAGE) { 00845 return 0; 00846 } else { 00847 ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype); 00848 return 0; 00849 } 00850 } else { 00851 if (!(frame->subclass & c->nativeformats)) { 00852 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 00853 frame->subclass, c->nativeformats, c->readformat, c->writeformat); 00854 return 0; 00855 } 00856 } 00857 if (pvt) { 00858 ast_mutex_lock(&pvt->lock); 00859 if (pvt->rtp && !pvt->recvonly) 00860 res = ast_rtp_write(pvt->rtp, frame); 00861 __oh323_update_info(c, pvt); 00862 ast_mutex_unlock(&pvt->lock); 00863 } 00864 return res; 00865 }
|
|
||||||||||||||||
|
Definition at line 2075 of file chan_h323.c. References AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state(). 02076 { 02077 struct oh323_pvt *pvt; 02078 02079 if (h323debug) 02080 ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated")); 02081 02082 pvt = find_call_locked(call_reference, token); 02083 if (!pvt) { 02084 ast_log(LOG_ERROR, "Private structure not found in progress.\n"); 02085 return -1; 02086 } 02087 if (!pvt->owner) { 02088 ast_mutex_unlock(&pvt->lock); 02089 ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n"); 02090 return -1; 02091 } 02092 update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING)); 02093 ast_mutex_unlock(&pvt->lock); 02094 02095 return 0; 02096 }
|
|
|
Definition at line 3055 of file chan_h323.c. References ASTOBJ_CONTAINER_PRUNE_MARKED, oh323_destroy_peer(), and peerl. Referenced by __expire_registry(), h323_do_reload(), reload_config(), and set_config(). 03056 { 03057 /* Prune peers who still are supposed to be deleted */ 03058 ASTOBJ_CONTAINER_PRUNE_MARKED(&peerl, oh323_destroy_peer); 03059 }
|
|
|
Definition at line 1234 of file chan_h323.c. References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var. Referenced by find_alias(). 01235 { 01236 struct ast_variable *var, *tmp; 01237 struct oh323_alias *a; 01238 01239 var = ast_load_realtime("h323", "name", alias, NULL); 01240 01241 if (!var) 01242 return NULL; 01243 01244 for (tmp = var; tmp; tmp = tmp->next) { 01245 if (!strcasecmp(tmp->name, "type") && 01246 !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) { 01247 ast_variables_destroy(var); 01248 return NULL; 01249 } 01250 } 01251 01252 a = build_alias(alias, var, NULL, 1); 01253 01254 ast_variables_destroy(var); 01255 01256 return a; 01257 }
|
|
||||||||||||
|
Definition at line 1556 of file chan_h323.c. References ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, ast_variable::value, and var. Referenced by authenticate_reply(), find_device(), find_peer(), and iax2_getpeername(). 01557 { 01558 struct oh323_peer *peer; 01559 struct ast_variable *var; 01560 struct ast_variable *tmp; 01561 const char *addr; 01562 01563 /* First check on peer name */ 01564 if (peername) 01565 var = ast_load_realtime("h323", "name", peername, addr = NULL); 01566 else if (sin) /* Then check on IP address for dynamic peers */ 01567 var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), NULL); 01568 else 01569 return NULL; 01570 01571 if (!var) 01572 return NULL; 01573 01574 for (tmp = var; tmp; tmp = tmp->next) { 01575 /* If this is type=user, then skip this object. */ 01576 if (!strcasecmp(tmp->name, "type") && 01577 !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) { 01578 ast_variables_destroy(var); 01579 return NULL; 01580 } else if (!peername && !strcasecmp(tmp->name, "name")) { 01581 peername = tmp->value; 01582 } 01583 } 01584 01585 if (!peername) { /* Did not find peer in realtime */ 01586 ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr); 01587 ast_variables_destroy(var); 01588 return NULL; 01589 } 01590 01591 /* Peer found in realtime, now build it in memory */ 01592 peer = build_peer(peername, var, NULL, 1); 01593 01594 ast_variables_destroy(var); 01595 01596 return peer; 01597 }
|
|
|
Definition at line 1446 of file chan_h323.c. References ast_load_realtime(), ast_variables_destroy(), ast_variable::name, ast_variable::next, userbyalias, ast_variable::value, and var. Referenced by check_access(), and find_user(). 01447 { 01448 struct ast_variable *var, *tmp; 01449 struct oh323_user *user; 01450 char *username; 01451 01452 if (userbyalias) 01453 var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, NULL); 01454 else { 01455 username = (char *)NULL; 01456 var = ast_load_realtime("h323", "host", cd->sourceIp, NULL); 01457 } 01458 01459 if (!var) 01460 return NULL; 01461 01462 for (tmp = var; tmp; tmp = tmp->next) { 01463 if (!strcasecmp(tmp->name, "type") && 01464 !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) { 01465 ast_variables_destroy(var); 01466 return NULL; 01467 } else if (!username && !strcasecmp(tmp->name, "name")) 01468 username = tmp->value; 01469 } 01470 01471 if (!username) { 01472 ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp); 01473 ast_variables_destroy(var); 01474 return NULL; 01475 } 01476 01477 user = build_user(username, var, NULL, 1); 01478 01479 ast_variables_destroy(var); 01480 01481 return user; 01482 }
|
|
||||||||||||||||||||
|
Callback for sending digits from H.323 up to asterisk Definition at line 1829 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, h323debug, oh323_pvt::lock, LOG_DTMF, LOG_ERROR, oh323_pvt::newcontrol, oh323_pvt::newdigit, oh323_pvt::newduration, oh323_simulate_dtmf_end(), oh323_pvt::owner, and ast_frame::subclass. Referenced by load_module(). 01830 { 01831 struct oh323_pvt *pvt; 01832 int res; 01833 01834 pvt = find_call_locked(call_reference, token); 01835 if (!pvt) { 01836 ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token); 01837 return -1; 01838 } 01839 if (h323debug) 01840 ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token); 01841 01842 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 01843 if (digit == '!') 01844 res = ast_queue_control(pvt->owner, AST_CONTROL_FLASH); 01845 else { 01846 struct ast_frame f = { 01847 .frametype = AST_FRAME_DTMF_END, 01848 .subclass = digit, 01849 .samples = duration * 8, 01850 .src = "SEND_DIGIT", 01851 }; 01852 if (digit == ' ') { /* signalUpdate message */ 01853 f.subclass = pvt->curDTMF; 01854 if (pvt->DTMFsched >= 0) { 01855 ast_sched_del(sched, pvt->DTMFsched); 01856 pvt->DTMFsched = -1; 01857 } 01858 } else { /* Regular input or signal message */ 01859 if (duration) { /* This is a signal, signalUpdate follows */ 01860 f.frametype = AST_FRAME_DTMF_BEGIN; 01861 if (pvt->DTMFsched >= 0) 01862 ast_sched_del(sched, pvt->DTMFsched); 01863 pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt); 01864 if (h323debug) 01865 ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched); 01866 } 01867 pvt->curDTMF = digit; 01868 } 01869 res = ast_queue_frame(pvt->owner, &f); 01870 } 01871 ast_channel_unlock(pvt->owner); 01872 } else { 01873 if (digit == '!') 01874 pvt->newcontrol = AST_CONTROL_FLASH; 01875 else { 01876 pvt->newduration = duration; 01877 pvt->newdigit = digit; 01878 } 01879 res = 0; 01880 } 01881 ast_mutex_unlock(&pvt->lock); 01882 return res; 01883 }
|
|
|
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 }
|
|
|
Definition at line 3083 of file chan_h323.c. References h323_reload(). 03084 { 03085 return h323_reload(0, 0, NULL); 03086 }
|
|
|
Definition at line 2795 of file chan_h323.c. References acceptAnonymous, ahp, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTOBJ_CONTAINER_LINK, ASTOBJ_UNREF, bindaddr, build_user(), config, default_context, default_jbconf, format, gatekeeper, gatekeeper_disable, gatekeeper_discover, gkroute, GLOBAL_CAPABILITY, global_jbconf, global_options, h323_signalling_port, hp, LOG_NOTICE, oh323_destroy_user(), tos, userbyalias, and userl. Referenced by h323_do_reload(), iax2_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), misdn_reload(), and reload(). 02796 { 02797 int format; 02798 struct ast_config *cfg, *ucfg; 02799 struct ast_variable *v; 02800 struct oh323_peer *peer = NULL; 02801 struct oh323_user *user = NULL; 02802 struct oh323_alias *alias = NULL; 02803 struct ast_hostent ahp; struct hostent *hp; 02804 char *cat; 02805 const char *utype; 02806 int is_user, is_peer, is_alias; 02807 char _gatekeeper[100]; 02808 int gk_discover, gk_disable, gk_changed; 02809 02810 cfg = ast_config_load(config); 02811 02812 /* We *must* have a config file otherwise stop immediately */ 02813 if (!cfg) { 02814 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02815 return 1; 02816 } 02817 02818 /* fire up the H.323 Endpoint */ 02819 if (!h323_end_point_exist()) { 02820 h323_end_point_create(); 02821 } 02822 ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper)); 02823 gk_discover = gatekeeper_discover; 02824 gk_disable = gatekeeper_disable; 02825 memset(&bindaddr, 0, sizeof(bindaddr)); 02826 memset(&global_options, 0, sizeof(global_options)); 02827 global_options.fastStart = 1; 02828 global_options.h245Tunneling = 1; 02829 global_options.dtmfcodec[0] = H323_DTMF_RFC2833_PT; 02830 global_options.dtmfcodec[1] = H323_DTMF_CISCO_PT; 02831 global_options.dtmfmode = 0; 02832 global_options.holdHandling = 0; 02833 global_options.capability = GLOBAL_CAPABILITY; 02834 global_options.bridge = 1; /* Do native bridging by default */ 02835 strcpy(default_context, "default"); 02836 h323_signalling_port = 1720; 02837 gatekeeper_disable = 1; 02838 gatekeeper_discover = 0; 02839 gkroute = 0; 02840 userbyalias = 1; 02841 acceptAnonymous = 1; 02842 tos = 0; 02843 02844 /* Copy the default jb config over global_jbconf */ 02845 memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); 02846 02847 /* Load configuration from users.conf */ 02848 ucfg = ast_config_load("users.conf"); 02849 if (ucfg) { 02850 struct ast_variable *gen; 02851 int genhas_h323; 02852 const char *has_h323; 02853 02854 genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323")); 02855 gen = ast_variable_browse(ucfg, "general"); 02856 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) { 02857 if (strcasecmp(cat, "general")) { 02858 has_h323 = ast_variable_retrieve(ucfg, cat, "hash323"); 02859 if (ast_true(has_h323) || (!has_h323 && genhas_h323)) { 02860 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 02861 if (user) { 02862 ASTOBJ_CONTAINER_LINK(&userl, user); 02863 ASTOBJ_UNREF(user, oh323_destroy_user); 02864 } 02865 } 02866 } 02867 } 02868 ast_config_destroy(ucfg); 02869 } 02870 02871 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) { 02872 /* handle jb conf */ 02873 if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) 02874 continue; 02875 /* Create the interface list */ 02876 if (!strcasecmp(v->name, "port")) { 02877 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02878 } else if (!strcasecmp(v->name, "bindaddr")) { 02879 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02880 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02881 } else { 02882 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02883 } 02884 } else if (!strcasecmp(v->name, "tos")) { 02885 if (sscanf(v->value, "%d", &format)) { 02886 tos = format & 0xff; 02887 } else if (!strcasecmp(v->value, "lowdelay")) { 02888 tos = IPTOS_LOWDELAY; 02889 } else if (!strcasecmp(v->value, "throughput")) { 02890 tos = IPTOS_THROUGHPUT; 02891 } else if (!strcasecmp(v->value, "reliability")) { 02892 tos = IPTOS_RELIABILITY; 02893 } else if (!strcasecmp(v->value, "mincost")) { 02894 tos = IPTOS_MINCOST; 02895 } else if (!strcasecmp(v->value, "none")) { 02896 tos = 0; 02897 } else { 02898 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02899 } 02900 } else if (!strcasecmp(v->name, "gatekeeper")) { 02901 if (!strcasecmp(v->value, "DISABLE")) { 02902 |