#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.h"
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.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 "h323/chan_h323.h"
Include dependency graph for chan_h323.c:
Go to the source code of this file.
Data Structures | |
struct | rtpPayloadType |
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 void | __oh323_update_info (struct ast_channel *c, struct oh323_pvt *pvt) |
static int | answer_call (unsigned call_reference, const char *token) |
AST_MUTEX_DEFINE_STATIC (h323_reload_lock) | |
AST_MUTEX_DEFINE_STATIC (caplock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
AST_MUTEX_DEFINE_STATIC (iflock) | |
static struct oh323_alias * | build_alias (char *name, struct ast_variable *v) |
static struct oh323_peer * | build_peer (char *name, struct ast_variable *v) |
static struct oh323_user * | build_user (char *name, struct ast_variable *v) |
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) |
void | connection_made (unsigned call_reference, const char *token) |
static char * | convertcap (int cap) |
static int | create_addr (struct oh323_pvt *pvt, char *opeer) |
void | delete_aliases (void) |
void | delete_users (void) |
char * | description () |
Provides a description of the module. | |
static void * | do_monitor (void *data) |
rtp_info * | external_rtp_create (unsigned call_reference, const char *token) |
oh323_alias * | find_alias (const char *source_aliases) |
static struct oh323_pvt * | find_call_locked (int call_reference, const char *token) |
oh323_peer * | find_peer (const char *peer, struct sockaddr_in *sin) |
oh323_user * | find_user (const call_details_t *cd) |
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) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module () |
Initialize the module. | |
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 int | oh323_digit (struct ast_channel *c, char digit) |
static int | oh323_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static struct ast_rtp * | oh323_get_rtp_peer (struct ast_channel *chan) |
static struct ast_rtp * | oh323_get_vrtp_peer (struct ast_channel *chan) |
static int | oh323_hangup (struct ast_channel *c) |
static int | oh323_indicate (struct ast_channel *c, int condition) |
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 void | oh323_update_info (struct ast_channel *c) |
static int | oh323_write (struct ast_channel *c, struct ast_frame *frame) |
int | progress (unsigned call_reference, const char *token, int inband) |
void | prune_peers (void) |
int | reload (void) |
Reload stuff. | |
int | reload_config (void) |
static int | restart_monitor (void) |
int | send_digit (unsigned call_reference, char digit, const char *token) |
void | set_dtmf_payload (unsigned call_reference, const char *token, int payload) |
static void | set_local_capabilities (unsigned call_reference, const char *token) |
call_options_t * | setup_incoming_call (call_details_t *cd) |
int | setup_outgoing_call (call_details_t *cd) |
void | setup_rtp_connection (unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
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) |
int | usecount () |
Provides a usecount. | |
Variables | |
static struct ast_alias_list | aliasl |
static struct sockaddr_in | bindaddr |
static struct ast_cli_entry | cli_debug |
static struct ast_cli_entry | cli_gk_cycle |
static struct ast_cli_entry | cli_h323_reload |
static struct ast_cli_entry | cli_hangup_call |
static struct ast_cli_entry | cli_no_debug |
static struct ast_cli_entry | cli_no_trace |
static struct ast_cli_entry | cli_show_codecs |
static struct ast_cli_entry | cli_show_tokens |
static struct ast_cli_entry | cli_trace |
static const char | config [] = "h323.conf" |
static char | debug_usage [] |
static char | default_context [AST_MAX_CONTEXT] = "default" |
static const char | desc [] = "The NuFone Network's Open H.323 Channel Driver" |
static char | gatekeeper [100] |
static int | gatekeeper_disable = 1 |
static int | gatekeeper_discover = 0 |
static int | gkroute = 0 |
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 |
setup_incoming_cb | on_incoming_call |
setup_outbound_cb | on_outgoing_call |
progress_cb | on_progress |
send_digit_cb | on_send_digit |
rfc2833_cb | on_set_rfc2833_payload |
setcapabilities_cb | on_setcapabilities |
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_codec_usage [] |
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 const char | type [] = "H323" |
static unsigned int | unique = 0 |
static int | usecnt = 0 |
static int | userbyalias = 1 |
static struct ast_user_list | userl |
static int | usingGk = 0 |
Definition in file chan_h323.c.
|
Definition at line 299 of file chan_h323.c. References ast_dsp_free(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), oh323_pvt::cd, cleanup_call_details(), free, iflist, oh323_pvt::lock, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, oh323_pvt::next, oh323_pvt::owner, oh323_pvt::rtp, ast_channel::tech_pvt, and oh323_pvt::vad. Referenced by do_monitor(), and oh323_destroy(). 00300 { 00301 struct oh323_pvt *cur, *prev = NULL; 00302 00303 if (pvt->rtp) { 00304 ast_rtp_destroy(pvt->rtp); 00305 } 00306 00307 /* Free dsp used for in-band DTMF detection */ 00308 if (pvt->vad) { 00309 ast_dsp_free(pvt->vad); 00310 } 00311 cleanup_call_details(&pvt->cd); 00312 00313 /* Unlink us from the owner if we have one */ 00314 if (pvt->owner) { 00315 ast_mutex_lock(&pvt->owner->lock); 00316 ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name); 00317 pvt->owner->tech_pvt = NULL; 00318 ast_mutex_unlock(&pvt->owner->lock); 00319 } 00320 cur = iflist; 00321 while(cur) { 00322 if (cur == pvt) { 00323 if (prev) 00324 prev->next = cur->next; 00325 else 00326 iflist = cur->next; 00327 break; 00328 } 00329 prev = cur; 00330 cur = cur->next; 00331 } 00332 if (!cur) { 00333 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur); 00334 } else { 00335 ast_mutex_destroy(&pvt->lock); 00336 free(pvt); 00337 } 00338 }
|
|
Definition at line 721 of file chan_h323.c. References ast_channel::accountcode, oh323_pvt::accountcode, ast_channel::amaflags, oh323_pvt::amaflags, ast_best_codec(), ast_channel_alloc(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtp_fd(), ast_set_callerid(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RING, ast_strlen_zero(), ast_update_use_count(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_dnid, oh323_pvt::cid_name, oh323_pvt::cid_num, ast_callerid::cid_rdnis, oh323_pvt::context, ast_channel::context, DSP_FEATURE_DTMF_DETECT, oh323_pvt::exten, ast_channel::exten, ast_channel::fds, fmt, global_options, oh323_pvt::lock, LOG_WARNING, ast_channel::name, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_pvt::options, oh323_pvt::owner, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, oh323_pvt::rdnis, ast_channel::readformat, ast_channel::rings, oh323_pvt::rtp, strdup, ast_channel::tech, ast_channel::tech_pvt, type, ast_channel::type, usecnt, usecnt_lock, oh323_pvt::vad, and ast_channel::writeformat. Referenced by answer_call(), and oh323_request(). 00722 { 00723 struct ast_channel *ch; 00724 int fmt; 00725 00726 /* Don't hold a oh323_pvt lock while we allocate a chanel */ 00727 ast_mutex_unlock(&pvt->lock); 00728 ch = ast_channel_alloc(1); 00729 /* Update usage counter */ 00730 ast_mutex_lock(&usecnt_lock); 00731 usecnt++; 00732 ast_mutex_unlock(&usecnt_lock); 00733 ast_update_use_count(); 00734 ast_mutex_lock(&pvt->lock); 00735 if (ch) { 00736 ch->tech = &oh323_tech; 00737 snprintf(ch->name, sizeof(ch->name), "H323/%s", host); 00738 ch->nativeformats = pvt->options.capability; 00739 if (!ch->nativeformats) { 00740 ch->nativeformats = global_options.capability; 00741 } 00742 pvt->nativeformats = ch->nativeformats; 00743 fmt = ast_best_codec(ch->nativeformats); 00744 ch->type = type; 00745 ch->fds[0] = ast_rtp_fd(pvt->rtp); 00746 if (state == AST_STATE_RING) { 00747 ch->rings = 1; 00748 } 00749 ch->writeformat = fmt; 00750 ch->rawwriteformat = fmt; 00751 ch->readformat = fmt; 00752 ch->rawreadformat = fmt; 00753 /* Allocate dsp for in-band DTMF support */ 00754 if (pvt->options.dtmfmode & H323_DTMF_INBAND) { 00755 pvt->vad = ast_dsp_new(); 00756 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT); 00757 } 00758 /* Register channel functions. */ 00759 ch->tech_pvt = pvt; 00760 /* Set the owner of this channel */ 00761 pvt->owner = ch; 00762 00763 strncpy(ch->context, pvt->context, sizeof(ch->context) - 1); 00764 strncpy(ch->exten, pvt->exten, sizeof(ch->exten) - 1); 00765 ch->priority = 1; 00766 if (!ast_strlen_zero(pvt->accountcode)) { 00767 strncpy(ch->accountcode, pvt->accountcode, sizeof(ch->accountcode) - 1); 00768 } 00769 if (pvt->amaflags) { 00770 ch->amaflags = pvt->amaflags; 00771 } 00772 00773 /* 00774 * If cid_num and cdi.call_source_e164 are both null, then 00775 * ast_set_callerid will do the right thing and leave the 00776 * cid_num and cid_ani for the channel alone. 00777 */ 00778 ast_set_callerid(ch, 00779 !ast_strlen_zero(pvt->cid_num) ? pvt->cid_num : pvt->cd.call_source_e164, 00780 pvt->cid_name, 00781 !ast_strlen_zero(pvt->cid_num) ? pvt->cid_num : pvt->cd.call_source_e164); 00782 00783 if (!ast_strlen_zero(pvt->rdnis)) { 00784 ch->cid.cid_rdnis = strdup(pvt->rdnis); 00785 } 00786 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) { 00787 ch->cid.cid_dnid = strdup(pvt->exten); 00788 } 00789 ast_setstate(ch, state); 00790 if (state != AST_STATE_DOWN) { 00791 if (ast_pbx_start(ch)) { 00792 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name); 00793 ast_hangup(ch); 00794 ch = NULL; 00795 } 00796 } 00797 } else { 00798 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 00799 } 00800 return ch; 00801 }
|
|
|
Call-back function to start PBX when OpenH323 ready to serve incoming call Returns 1 on success Definition at line 1393 of file chan_h323.c. References __oh323_new(), ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, oh323_pvt::cd, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, and LOG_ERROR. Referenced by load_module(). 01394 { 01395 struct oh323_pvt *pvt; 01396 struct ast_channel *c = NULL; 01397 01398 if (h323debug) 01399 ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token); 01400 01401 /* Find the call or allocate a private structure if call not found */ 01402 pvt = find_call_locked(call_reference, token); 01403 if (!pvt) { 01404 ast_log(LOG_ERROR, "Something is wrong: answer_call\n"); 01405 return 0; 01406 } 01407 /* allocate a channel and tell asterisk about it */ 01408 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token); 01409 01410 /* And release when done */ 01411 ast_mutex_unlock(&pvt->lock); 01412 if (!c) { 01413 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n"); 01414 return 0; 01415 } 01416 return 1; 01417 }
|
|
|
|
|
|
|
|
|
|
Protect the interface list (oh323_pvt) |
|
Definition at line 1854 of file chan_h323.c. References ast_log(), LOG_WARNING, malloc, ast_variable::name, ast_variable::next, and ast_variable::value. Referenced by reload_config(). 01855 { 01856 struct oh323_alias *alias; 01857 01858 alias = (struct oh323_alias *)malloc(sizeof(struct oh323_alias)); 01859 if (alias) { 01860 memset(alias, 0, sizeof(struct oh323_alias)); 01861 strncpy(alias->name, name, sizeof(alias->name) - 1); 01862 while (v) { 01863 if (!strcasecmp(v->name, "e164")) { 01864 strncpy(alias->e164, v->value, sizeof(alias->e164) - 1); 01865 } else if (!strcasecmp(v->name, "prefix")) { 01866 strncpy(alias->prefix, v->value, sizeof(alias->prefix) - 1); 01867 } else if (!strcasecmp(v->name, "context")) { 01868 strncpy(alias->context, v->value, sizeof(alias->context) - 1); 01869 } else if (!strcasecmp(v->name, "secret")) { 01870 strncpy(alias->secret, v->value, sizeof(alias->secret) - 1); 01871 } else { 01872 if (strcasecmp(v->value, "h323")) { 01873 ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->value); 01874 } 01875 } 01876 v = v->next; 01877 } 01878 } 01879 return alias; 01880 }
|
|
Definition at line 1930 of file chan_h323.c. References ast_get_ip(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), free, global_options, h323_signalling_port, ast_peer_list::lock, LOG_ERROR, malloc, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, update_common_options(), and ast_variable::value. Referenced by realtime_peer(), reload_config(), and set_config(). 01931 { 01932 struct oh323_peer *peer; 01933 struct oh323_peer *prev; 01934 struct ast_ha *oldha = NULL; 01935 int found=0; 01936 01937 prev = NULL; 01938 ast_mutex_lock(&peerl.lock); 01939 peer = peerl.peers; 01940 01941 while(peer) { 01942 if (!strcasecmp(peer->name, name)) { 01943 break; 01944 } 01945 prev = peer; 01946 peer = peer->next; 01947 } 01948 01949 if (peer) { 01950 found++; 01951 /* Already in the list, remove it and it will be added back (or FREE'd) */ 01952 if (prev) { 01953 prev->next = peer->next; 01954 } else { 01955 peerl.peers = peer->next; 01956 } 01957 ast_mutex_unlock(&peerl.lock); 01958 } else { 01959 ast_mutex_unlock(&peerl.lock); 01960 peer = (struct oh323_peer*)malloc(sizeof(struct oh323_peer)); 01961 if (peer) 01962 memset(peer, 0, sizeof(struct oh323_peer)); 01963 } 01964 if (peer) { 01965 if (!found) { 01966 strncpy(peer->name, name, sizeof(peer->name) - 1); 01967 peer->addr.sin_port = htons(h323_signalling_port); 01968 peer->addr.sin_family = AF_INET; 01969 } 01970 oldha = peer->ha; 01971 peer->ha = NULL; 01972 peer->addr.sin_family = AF_INET; 01973 memcpy(&peer->options, &global_options, sizeof(peer->options)); 01974 01975 while(v) { 01976 if (!update_common_options(v, &peer->options)) { 01977 /* dummy */ 01978 } else if (!strcasecmp(v->name, "host")) { 01979 if (!strcasecmp(v->value, "dynamic")) { 01980 ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n"); 01981 free(peer); 01982 return NULL; 01983 } 01984 if (ast_get_ip(&peer->addr, v->value)) { 01985 ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value); 01986 free(peer); 01987 return NULL; 01988 } 01989 } else if (!strcasecmp(v->name, "port")) { 01990 peer->addr.sin_port = htons(atoi(v->value)); 01991 } 01992 v=v->next; 01993 } 01994 } 01995 return peer; 01996 }
|
|
Definition at line 1882 of file chan_h323.c. References ast_cdr_amaflags2int(), ast_get_ip(), ast_log(), default_context, format, free, global_options, ast_variable::lineno, LOG_ERROR, LOG_WARNING, malloc, ast_variable::name, ast_variable::next, update_common_options(), user, and ast_variable::value. Referenced by realtime_user(), reload_config(), and set_config(). 01883 { 01884 struct oh323_user *user; 01885 int format; 01886 01887 user = (struct oh323_user *)malloc(sizeof(struct oh323_user)); 01888 if (user) { 01889 memset(user, 0, sizeof(struct oh323_user)); 01890 strncpy(user->name, name, sizeof(user->name) - 1); 01891 memcpy(&user->options, &global_options, sizeof(user->options)); 01892 /* Set default context */ 01893 strncpy(user->context, default_context, sizeof(user->context) - 1); 01894 while(v) { 01895 if (!strcasecmp(v->name, "context")) { 01896 strncpy(user->context, v->value, sizeof(user->context) - 1); 01897 } else if (!update_common_options(v, &user->options)) { 01898 /* dummy */ 01899 } else if (!strcasecmp(v->name, "secret")) { 01900 strncpy(user->secret, v->value, sizeof(user->secret) - 1); 01901 } else if (!strcasecmp(v->name, "callerid")) { 01902 strncpy(user->callerid, v->value, sizeof(user->callerid) - 1); 01903 } else if (!strcasecmp(v->name, "accountcode")) { 01904 strncpy(user->accountcode, v->value, sizeof(user->accountcode) - 1); 01905 } else if (!strcasecmp(v->name, "host")) { 01906 if (!strcasecmp(v->value, "dynamic")) { 01907 ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n"); 01908 free(user); 01909 return NULL; 01910 } else if (ast_get_ip(&user->addr, v->value)) { 01911 free(user); 01912 return NULL; 01913 } 01914 /* Let us know we need to use ip authentication */ 01915 user->host = 1; 01916 } else if (!strcasecmp(v->name, "amaflags")) { 01917 format = ast_cdr_amaflags2int(v->value); 01918 if (format < 0) { 01919 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 01920 } else { 01921 user->amaflags = format; 01922 } 01923 } 01924 v = v->next; 01925 } 01926 } 01927 return user; 01928 }
|
|
Call-back function to signal asterisk that the channel is ringing Returns nothing Definition at line 1436 of file chan_h323.c. References AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, find_call_locked(), h323debug, ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state(). Referenced by load_module(). 01437 { 01438 struct oh323_pvt *pvt; 01439 01440 if (h323debug) 01441 ast_log(LOG_DEBUG, "Ringing on %s\n", token); 01442 01443 pvt = find_call_locked(call_reference, token); 01444 if (!pvt) { 01445 ast_log(LOG_ERROR, "Something is wrong: ringing\n"); 01446 return; 01447 } 01448 if (!pvt->owner) { 01449 ast_mutex_unlock(&pvt->lock); 01450 ast_log(LOG_ERROR, "Channel has no owner\n"); 01451 return; 01452 } 01453 if (update_state(pvt, AST_STATE_RINGING, AST_CONTROL_RINGING)) 01454 ast_mutex_unlock(&pvt->owner->lock); 01455 ast_mutex_unlock(&pvt->lock); 01456 return; 01457 }
|
|
Definition at line 267 of file chan_h323.c. References free. Referenced by __oh323_destroy(), cleanup_connection(), and setup_outgoing_call(). 00268 { 00269 if (cd->call_token) { 00270 free(cd->call_token); 00271 cd->call_token = NULL; 00272 } 00273 if (cd->call_source_aliases) { 00274 free(cd->call_source_aliases); 00275 cd->call_source_aliases = NULL; 00276 } 00277 if (cd->call_dest_alias) { 00278 free(cd->call_dest_alias); 00279 cd->call_dest_alias = NULL; 00280 } 00281 if (cd->call_source_name) { 00282 free(cd->call_source_name); 00283 cd->call_source_name = NULL; 00284 } 00285 if (cd->call_source_e164) { 00286 free(cd->call_source_e164); 00287 cd->call_source_e164 = NULL; 00288 } 00289 if (cd->call_dest_e164) { 00290 free(cd->call_dest_e164); 00291 cd->call_dest_e164 = NULL; 00292 } 00293 if (cd->sourceIp) { 00294 free(cd->sourceIp); 00295 cd->sourceIp = NULL; 00296 } 00297 }
|
|
Call-back function to cleanup communication Returns nothing, Definition at line 1463 of file chan_h323.c. References ast_channel::_softhangup, oh323_pvt::alreadygone, ast_dsp_free(), ast_log(), ast_mutex_trylock(), 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(). 01464 { 01465 struct oh323_pvt *pvt; 01466 01467 ast_log(LOG_DEBUG, "Cleaning connection to %s\n", call_token); 01468 01469 while (1) { 01470 pvt = find_call_locked(call_reference, call_token); 01471 if (!pvt) { 01472 if (h323debug) 01473 ast_log(LOG_DEBUG, "No connection for %s\n", call_token); 01474 return; 01475 } 01476 if (!pvt->owner || !ast_mutex_trylock(&pvt->owner->lock)) 01477 break; 01478 #if 1 01479 #ifdef DEBUG_THREADS 01480 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, pvt->owner->lock.reentrancy, pvt->owner->lock.func, pvt->owner->lock.file, pvt->owner->lock.lineno); 01481 #else 01482 ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token); 01483 #endif 01484 #endif 01485 ast_mutex_unlock(&pvt->lock); 01486 usleep(1); 01487 } 01488 if (pvt->rtp) { 01489 /* Immediately stop RTP */ 01490 ast_rtp_destroy(pvt->rtp); 01491 pvt->rtp = NULL; 01492 } 01493 /* Free dsp used for in-band DTMF detection */ 01494 if (pvt->vad) { 01495 ast_dsp_free(pvt->vad); 01496 pvt->vad = NULL; 01497 } 01498 cleanup_call_details(&pvt->cd); 01499 pvt->alreadygone = 1; 01500 /* Send hangup */ 01501 if (pvt->owner) { 01502 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 01503 ast_queue_hangup(pvt->owner); 01504 ast_mutex_unlock(&pvt->owner->lock); 01505 } 01506 ast_mutex_unlock(&pvt->lock); 01507 if (h323debug) 01508 ast_log(LOG_DEBUG, "Connection to %s cleaned\n", call_token); 01509 return; 01510 }
|
|
Call-back function to signal asterisk that the channel has been answered Returns nothing Definition at line 1235 of file chan_h323.c. References AST_CONTROL_ANSWER, ast_log(), ast_mutex_unlock(), AST_STATE_UP, find_call_locked(), h323debug, ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::outgoing, oh323_pvt::owner, and update_state(). Referenced by load_module(). 01236 { 01237 struct oh323_pvt *pvt; 01238 01239 if (h323debug) 01240 ast_log(LOG_DEBUG, "Call %s answered\n", token); 01241 01242 pvt = find_call_locked(call_reference, token); 01243 if (!pvt) { 01244 ast_log(LOG_ERROR, "Something is wrong: connection\n"); 01245 return; 01246 } 01247 01248 /* Inform asterisk about remote party connected only on outgoing calls */ 01249 if (!pvt->outgoing) { 01250 ast_mutex_unlock(&pvt->lock); 01251 return; 01252 } 01253 if (update_state(pvt, AST_STATE_UP, AST_CONTROL_ANSWER)) 01254 ast_mutex_unlock(&pvt->owner->lock); 01255 ast_mutex_unlock(&pvt->lock); 01256 return; 01257 }
|
|
Definition at line 2258 of file chan_h323.c. References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, 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(). 02259 { 02260 switch (cap) { 02261 case AST_FORMAT_G723_1: 02262 return "G.723"; 02263 case AST_FORMAT_GSM: 02264 return "GSM"; 02265 case AST_FORMAT_ULAW: 02266 return "ULAW"; 02267 case AST_FORMAT_ALAW: 02268 return "ALAW"; 02269 case AST_FORMAT_ADPCM: 02270 return "G.728"; 02271 case AST_FORMAT_G729A: 02272 return "G.729"; 02273 case AST_FORMAT_SPEEX: 02274 return "SPEEX"; 02275 case AST_FORMAT_ILBC: 02276 return "ILBC"; 02277 default: 02278 ast_log(LOG_NOTICE, "Don't know how to deal with mode %d\n", cap); 02279 return NULL; 02280 } 02281 }
|
|
Definition at line 949 of file chan_h323.c. References ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setnat(), find_peer(), global_options, h323_signalling_port, hp, ast_peer_list::lock, LOG_DEBUG, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_pvt::options, peerl, portno, oh323_pvt::rtp, and oh323_pvt::sa. Referenced by cache_get_callno_locked(), iax2_call(), iax2_provision(), iax2_request(), oh323_request(), sip_notify(), sip_request_call(), and transmit_register(). 00950 { 00951 struct hostent *hp; 00952 struct ast_hostent ahp; 00953 struct oh323_peer *p; 00954 int portno; 00955 int found = 0; 00956 char *port; 00957 char *hostn; 00958 char peer[256] = ""; 00959 00960 strncpy(peer, opeer, sizeof(peer) - 1); 00961 port = strchr(peer, ':'); 00962 if (port) { 00963 *port = '\0'; 00964 port++; 00965 } 00966 pvt->sa.sin_family = AF_INET; 00967 ast_mutex_lock(&peerl.lock); 00968 p = find_peer(peer, NULL); 00969 if (p) { 00970 found++; 00971 memcpy(&pvt->options, &p->options, sizeof(pvt->options)); 00972 if (pvt->rtp) { 00973 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat); 00974 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00975 } 00976 if (pvt->options.dtmfmode) { 00977 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 00978 pvt->nonCodecCapability |= AST_RTP_DTMF; 00979 } else { 00980 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 00981 } 00982 } 00983 if (p->addr.sin_addr.s_addr) { 00984 pvt->sa.sin_addr = p->addr.sin_addr; 00985 pvt->sa.sin_port = p->addr.sin_port; 00986 } 00987 } 00988 ast_mutex_unlock(&peerl.lock); 00989 if (!p && !found) { 00990 hostn = peer; 00991 if (port) { 00992 portno = atoi(port); 00993 } else { 00994 portno = h323_signalling_port; 00995 } 00996 hp = ast_gethostbyname(hostn, &ahp); 00997 if (hp) { 00998 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 00999 memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr)); 01000 pvt->sa.sin_port = htons(portno); 01001 return 0; 01002 } else { 01003 ast_log(LOG_WARNING, "No such host: %s\n", peer); 01004 return -1; 01005 } 01006 } else if (!p) { 01007 return -1; 01008 } else { 01009 return 0; 01010 } 01011 }
|
|
Definition at line 2174 of file chan_h323.c. References ast_alias_list::aliases, aliasl, ast_mutex_lock(), ast_mutex_unlock(), free, and ast_alias_list::lock. Referenced by h323_do_reload(), and unload_module(). 02175 { 02176 struct oh323_alias *alias, *aliaslast; 02177 02178 /* Delete all users */ 02179 ast_mutex_lock(&aliasl.lock); 02180 for (alias=aliasl.aliases;alias;) { 02181 aliaslast = alias; 02182 alias=alias->next; 02183 free(aliaslast); 02184 } 02185 aliasl.aliases=NULL; 02186 ast_mutex_unlock(&aliasl.lock); 02187 }
|
|
Definition at line 2151 of file chan_h323.c. References ast_mutex_lock(), ast_mutex_unlock(), free, ast_peer_list::lock, ast_user_list::lock, peerl, ast_peer_list::peers, user, userl, and ast_user_list::users. Referenced by __unload_module(), h323_do_reload(), and unload_module(). 02152 { 02153 struct oh323_user *user, *userlast; 02154 struct oh323_peer *peer; 02155 02156 /* Delete all users */ 02157 ast_mutex_lock(&userl.lock); 02158 for (user=userl.users;user;) { 02159 userlast = user; 02160 user=user->next; 02161 free(userlast); 02162 } 02163 userl.users=NULL; 02164 ast_mutex_unlock(&userl.lock); 02165 ast_mutex_lock(&peerl.lock); 02166 for (peer=peerl.peers;peer;) { 02167 /* Assume all will be deleted, and we'll find out for sure later */ 02168 peer->delme = 1; 02169 peer = peer->next; 02170 } 02171 ast_mutex_unlock(&peerl.lock); 02172 }
|
|
Provides a description of the module.
Definition at line 2462 of file chan_h323.c. References desc. 02463 { 02464 return (char *) desc; 02465 }
|
|
Definition at line 1575 of file chan_h323.c. References __oh323_destroy(), ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_verbose(), h323_do_reload(), h323_reloading, iflist, oh323_pvt::needdestroy, oh323_pvt::next, option_verbose, and VERBOSE_PREFIX_1. Referenced by restart_monitor(). 01576 { 01577 int res; 01578 int reloading; 01579 struct oh323_pvt *oh323 = NULL; 01580 01581 for(;;) { 01582 /* Check for a reload request */ 01583 ast_mutex_lock(&h323_reload_lock); 01584 reloading = h323_reloading; 01585 h323_reloading = 0; 01586 ast_mutex_unlock(&h323_reload_lock); 01587 if (reloading) { 01588 if (option_verbose > 0) { 01589 ast_verbose(VERBOSE_PREFIX_1 "Reloading H.323\n"); 01590 } 01591 h323_do_reload(); 01592 } 01593 /* Check for interfaces needing to be killed */ 01594 ast_mutex_lock(&iflock); 01595 restartsearch: 01596 oh323 = iflist; 01597 while(oh323) { 01598 if (oh323->needdestroy) { 01599 __oh323_destroy(oh323); 01600 goto restartsearch; 01601 } 01602 oh323 = oh323->next; 01603 } 01604 ast_mutex_unlock(&iflock); 01605 pthread_testcancel(); 01606 /* Wait for sched or io */ 01607 res = ast_sched_wait(sched); 01608 if ((res < 0) || (res > 1000)) { 01609 res = 1000; 01610 } 01611 res = ast_io_wait(io, res); 01612 pthread_testcancel(); 01613 ast_mutex_lock(&monlock); 01614 if (res >= 0) { 01615 ast_sched_runq(sched); 01616 } 01617 ast_mutex_unlock(&monlock); 01618 } 01619 /* Never reached */ 01620 return NULL; 01621 }
|
|
Callback function used to inform the H.323 stack of the local rtp ip/port details Returns the local RTP information Definition at line 1140 of file chan_h323.c. References 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(). 01141 { 01142 struct oh323_pvt *pvt; 01143 struct sockaddr_in us; 01144 struct rtp_info *info; 01145 01146 info = (struct rtp_info *)malloc(sizeof(struct rtp_info)); 01147 if (!info) { 01148 ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n"); 01149 return NULL; 01150 } 01151 pvt = find_call_locked(call_reference, token); 01152 if (!pvt) { 01153 free(info); 01154 ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference); 01155 return NULL; 01156 } 01157 /* figure out our local RTP port and tell the H.323 stack about it */ 01158 ast_rtp_get_us(pvt->rtp, &us); 01159 ast_mutex_unlock(&pvt->lock); 01160 01161 ast_inet_ntoa(info->addr, sizeof(info->addr), us.sin_addr); 01162 info->port = ntohs(us.sin_port); 01163 if (h323debug) 01164 ast_log(LOG_DEBUG, "Sending RTP 'US' %s:%d\n", info->addr, info->port); 01165 return info; 01166 }
|
|
Find a call by alias Definition at line 1091 of file chan_h323.c. References ast_alias_list::aliases, and aliasl. Referenced by __get_header(), and setup_incoming_call(). 01092 { 01093 struct oh323_alias *a; 01094 01095 a = aliasl.aliases; 01096 while(a) { 01097 if (!strcasecmp(a->name, source_aliases)) { 01098 break; 01099 } 01100 a = a->next; 01101 } 01102 return a; 01103 }
|
|
Definition at line 847 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(), send_digit(), set_dtmf_payload(), set_local_capabilities(), and setup_rtp_connection(). 00848 { 00849 struct oh323_pvt *pvt; 00850 00851 ast_mutex_lock(&iflock); 00852 pvt = iflist; 00853 while(pvt) { 00854 if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) { 00855 /* Found the call */ 00856 if ((token != NULL) && (!strcmp(pvt->cd.call_token, token))) { 00857 ast_mutex_lock(&pvt->lock); 00858 ast_mutex_unlock(&iflock); 00859 return pvt; 00860 } else if (token == NULL) { 00861 ast_log(LOG_WARNING, "Call Token is NULL\n"); 00862 ast_mutex_lock(&pvt->lock); 00863 ast_mutex_unlock(&iflock); 00864 return pvt; 00865 } 00866 } 00867 pvt = pvt->next; 00868 } 00869 ast_mutex_unlock(&iflock); 00870 return NULL; 00871 }
|
|
Definition at line 916 of file chan_h323.c. References ast_inet_ntoa(), ast_log(), inaddrcmp(), LOG_DEBUG, peerl, and ast_peer_list::peers. Referenced by _sip_show_peer(), check_user_full(), create_addr(), dundi_encrypt(), function_iaxpeer(), function_sippeer(), handle_command_response(), iax2_devicestate(), iax2_prune_realtime(), iax2_show_peer(), register_verify(), registry_authrequest(), sip_devicestate(), sip_do_debug_peer(), update_call_counter(), and update_registry(). 00917 { 00918 struct oh323_peer *p = NULL; 00919 static char iabuf[INET_ADDRSTRLEN]; 00920 00921 p = peerl.peers; 00922 if (peer) { 00923 while(p) { 00924 if (!strcasecmp(p->name, peer)) { 00925 ast_log(LOG_DEBUG, "Found peer %s by name\n", peer); 00926 break; 00927 } 00928 p = p->next; 00929 } 00930 } else { 00931 /* find by sin */ 00932 if (sin) { 00933 while (p) { 00934 if ((!inaddrcmp(&p->addr, sin)) || 00935 (p->addr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 00936 ast_log(LOG_DEBUG, "Found peer %s/%s by addr\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), p->addr.sin_addr)); 00937 break; 00938 } 00939 p = p->next; 00940 } 00941 } 00942 } 00943 if (!p) { 00944 ast_log(LOG_DEBUG, "Could not find peer %s by name or address\n", peer); 00945 } 00946 return p; 00947 }
|
|
Definition at line 893 of file chan_h323.c. References ast_inet_ntoa(), userbyalias, userl, and ast_user_list::users. 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(). 00894 { 00895 struct oh323_user *u; 00896 char iabuf[INET_ADDRSTRLEN]; 00897 u = userl.users; 00898 if (userbyalias) { 00899 while(u) { 00900 if (!strcasecmp(u->name, cd->call_source_aliases)) { 00901 break; 00902 } 00903 u = u->next; 00904 } 00905 } else { 00906 while(u) { 00907 if (!strcasecmp(cd->sourceIp, ast_inet_ntoa(iabuf, sizeof(iabuf), u->addr.sin_addr))) { 00908 break; 00909 } 00910 u = u->next; 00911 } 00912 } 00913 return u; 00914 }
|
|
Definition at line 1677 of file chan_h323.c. References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01678 { 01679 if (argc != 2) { 01680 return RESULT_SHOWUSAGE; 01681 } 01682 h323debug = 1; 01683 ast_cli(fd, "H323 debug enabled\n"); 01684 return RESULT_SUCCESS; 01685 }
|
|
Definition at line 2225 of file chan_h323.c. References delete_aliases(), delete_users(), prune_peers(), reload_config(), and restart_monitor(). Referenced by do_monitor(). 02226 { 02227 delete_users(); 02228 delete_aliases(); 02229 prune_peers(); 02230 reload_config(); 02231 restart_monitor(); 02232 return 0; 02233 }
|
|
Definition at line 1657 of file chan_h323.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01658 { 01659 if (argc != 3) { 01660 return RESULT_SHOWUSAGE; 01661 } 01662 h323_debug(1, atoi(argv[2])); 01663 ast_cli(fd, "H.323 trace set to level %s\n", argv[2]); 01664 return RESULT_SUCCESS; 01665 }
|
|
Definition at line 1715 of file chan_h323.c. References ast_verbose(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and VERBOSE_PREFIX_3. 01716 { 01717 if (argc != 3) { 01718 return RESULT_SHOWUSAGE; 01719 } 01720 if (h323_soft_hangup(argv[2])) { 01721 ast_verbose(VERBOSE_PREFIX_3 "Hangup succeeded on %s\n", argv[2]); 01722 } else { 01723 ast_verbose(VERBOSE_PREFIX_3 "Hangup failed for %s\n", argv[2]); 01724 } 01725 return RESULT_SUCCESS; 01726 }
|
|
Definition at line 1697 of file chan_h323.c. References ast_log(), gatekeeper, gatekeeper_disable, gatekeeper_discover, LOG_ERROR, RESULT_SHOWUSAGE, RESULT_SUCCESS, and secret. 01698 { 01699 #if 0 01700 if (argc != 3) { 01701 return RESULT_SHOWUSAGE; 01702 } 01703 h323_gk_urq(); 01704 01705 /* Possibly register with a GK */ 01706 if (!gatekeeper_disable) { 01707 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 01708 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 01709 } 01710 } 01711 #endif 01712 return RESULT_SUCCESS; 01713 }
|
|
Definition at line 1687 of file chan_h323.c. References ast_cli(), h323debug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01688 { 01689 if (argc != 3) { 01690 return RESULT_SHOWUSAGE; 01691 } 01692 h323debug = 0; 01693 ast_cli(fd, "H323 Debug disabled\n"); 01694 return RESULT_SUCCESS; 01695 }
|
|
Definition at line 1667 of file chan_h323.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01668 { 01669 if (argc != 3) { 01670 return RESULT_SHOWUSAGE; 01671 } 01672 h323_debug(0,0); 01673 ast_cli(fd, "H.323 trace disabled\n"); 01674 return RESULT_SUCCESS; 01675 }
|
|
Definition at line 2212 of file chan_h323.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), h323_reloading, and restart_monitor(). Referenced by reload(). 02213 { 02214 ast_mutex_lock(&h323_reload_lock); 02215 if (h323_reloading) { 02216 ast_verbose("Previous H.323 reload not yet done\n"); 02217 } else { 02218 h323_reloading = 1; 02219 } 02220 ast_mutex_unlock(&h323_reload_lock); 02221 restart_monitor(); 02222 return 0; 02223 }
|
|
Definition at line 1728 of file chan_h323.c. References RESULT_SHOWUSAGE, and RESULT_SUCCESS. 01729 { 01730 if (argc != 3) { 01731 return RESULT_SHOWUSAGE; 01732 } 01733 h323_show_tokens(); 01734 return RESULT_SUCCESS; 01735 }
|
|
Definition at line 1512 of file chan_h323.c. References ast_channel::_softhangup, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), AST_SOFTHANGUP_DEV, find_call_locked(), oh323_pvt::hangupcause, ast_channel::hangupcause, oh323_pvt::lock, ast_channel::lock, LOG_DEBUG, oh323_pvt::needhangup, and oh323_pvt::owner. Referenced by load_module(). 01513 { 01514 struct oh323_pvt *pvt; 01515 01516 ast_log(LOG_DEBUG, "Hanging up connection to %s with cause %d\n", token, cause); 01517 01518 pvt = find_call_locked(call_reference, token); 01519 if (!pvt) { 01520 return; 01521 } 01522 if (pvt->owner && !ast_mutex_trylock(&pvt->owner->lock)) { 01523 pvt->owner->_softhangup |= AST_SOFTHANGUP_DEV; 01524 pvt->owner->hangupcause = pvt->hangupcause = cause; 01525 ast_queue_hangup(pvt->owner); 01526 ast_mutex_unlock(&pvt->owner->lock); 01527 } 01528 else { 01529 pvt->needhangup = 1; 01530 pvt->hangupcause = cause; 01531 ast_log(LOG_DEBUG, "Hangup for %s is pending\n", token); 01532 } 01533 ast_mutex_unlock(&pvt->lock); 01534 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 2467 of file chan_h323.c. References ASTERISK_GPL_KEY. 02468 { 02469 return ASTERISK_GPL_KEY; 02470 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 2315 of file chan_h323.c. References aliasl, answer_call(), ast_channel_register(), ast_cli_register(), ast_log(), ast_mutex_init(), ast_rtp_proto_register(), bindaddr, chan_ringing(), cleanup_connection(), connection_made(), external_rtp_create(), gatekeeper, gatekeeper_disable, gatekeeper_discover, h323_signalling_port, hangup_connection(), io_context_create(), ast_alias_list::lock, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_WARNING, peerl, reload_config(), restart_monitor(), sched_context_create(), secret, send_digit(), set_dtmf_payload(), set_local_capabilities(), setup_incoming_call(), setup_outgoing_call(), setup_rtp_connection(), type, and userl. 02316 { 02317 int res; 02318 ast_mutex_init(&userl.lock); 02319 ast_mutex_init(&peerl.lock); 02320 ast_mutex_init(&aliasl.lock); 02321 sched = sched_context_create(); 02322 if (!sched) { 02323 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 02324 } 02325 io = io_context_create(); 02326 if (!io) { 02327 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 02328 } 02329 res = reload_config(); 02330 if (res) { 02331 return 0; 02332 } else { 02333 /* Make sure we can register our channel type */ 02334 if (ast_channel_register(&oh323_tech)) { 02335 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 02336 h323_end_process(); 02337 return -1; 02338 } 02339 ast_cli_register(&cli_debug); 02340 ast_cli_register(&cli_no_debug); 02341 ast_cli_register(&cli_trace); 02342 ast_cli_register(&cli_no_trace); 02343 ast_cli_register(&cli_show_codecs); 02344 ast_cli_register(&cli_gk_cycle); 02345 ast_cli_register(&cli_hangup_call); 02346 ast_cli_register(&cli_show_tokens); 02347 ast_cli_register(&cli_h323_reload); 02348 02349 ast_rtp_proto_register(&oh323_rtp); 02350 02351 /* Register our callback functions */ 02352 h323_callback_register(setup_incoming_call, 02353 setup_outgoing_call, 02354 external_rtp_create, 02355 setup_rtp_connection, 02356 cleanup_connection, 02357 chan_ringing, 02358 connection_made, 02359 send_digit, 02360 answer_call, 02361 progress, 02362 set_dtmf_payload, 02363 hangup_connection, 02364 set_local_capabilities); 02365 /* start the h.323 listener */ 02366 if (h323_start_listener(h323_signalling_port, bindaddr)) { 02367 ast_log(LOG_ERROR, "Unable to create H323 listener.\n"); 02368 return -1; 02369 } 02370 /* Possibly register with a GK */ 02371 if (!gatekeeper_disable) { 02372 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) { 02373 ast_log(LOG_ERROR, "Gatekeeper registration failed.\n"); 02374 return 0; 02375 } 02376 } 02377 /* And start the monitor for the first time */ 02378 restart_monitor(); 02379 } 02380 return res; 02381 }
|
|
Definition at line 803 of file chan_h323.c. References ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_settos(), bindaddr, oh323_pvt::cd, oh323_pvt::context, default_context, free, global_options, iflist, oh323_pvt::lock, LOG_ERROR, LOG_WARNING, malloc, oh323_pvt::newcontrol, oh323_pvt::newstate, oh323_pvt::next, oh323_pvt::nonCodecCapability, oh323_pvt::options, oh323_pvt::rtp, and tos. Referenced by oh323_request(), and setup_incoming_call(). 00804 { 00805 struct oh323_pvt *pvt; 00806 00807 pvt = (struct oh323_pvt *) malloc(sizeof(struct oh323_pvt)); 00808 if (!pvt) { 00809 ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n"); 00810 return NULL; 00811 } 00812 memset(pvt, 0, sizeof(struct oh323_pvt)); 00813 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0,bindaddr.sin_addr); 00814 if (!pvt->rtp) { 00815 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); 00816 free(pvt); 00817 return NULL; 00818 } 00819 ast_rtp_settos(pvt->rtp, tos); 00820 ast_mutex_init(&pvt->lock); 00821 /* Ensure the call token is allocated */ 00822 if ((pvt->cd).call_token == NULL) { 00823 (pvt->cd).call_token = (char *)malloc(128); 00824 } 00825 if (!pvt->cd.call_token) { 00826 ast_log(LOG_ERROR, "Not enough memory to alocate call token\n"); 00827 return NULL; 00828 } 00829 memset((char *)(pvt->cd).call_token, 0, 128); 00830 pvt->cd.call_reference = callid; 00831 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 00832 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 00833 pvt->nonCodecCapability |= AST_RTP_DTMF; 00834 } else { 00835 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 00836 } 00837 strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); 00838 pvt->newstate = pvt->newcontrol = -1; 00839 /* Add to interface list */ 00840 ast_mutex_lock(&iflock); 00841 pvt->next = iflist; 00842 iflist = pvt; 00843 ast_mutex_unlock(&iflock); 00844 return pvt; 00845 }
|
|
Definition at line 442 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, h323debug, oh323_pvt::lock, LOG_DEBUG, ast_channel::name, oh323_update_info(), strdup, and ast_channel::tech_pvt. 00443 { 00444 int res; 00445 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00446 char *token; 00447 00448 if (h323debug) 00449 ast_log(LOG_DEBUG, "Answering on %s\n", c->name); 00450 00451 ast_mutex_lock(&pvt->lock); 00452 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00453 ast_mutex_unlock(&pvt->lock); 00454 res = h323_answering_call(token, 0); 00455 if (token) 00456 free(token); 00457 00458 oh323_update_info(c); 00459 if (c->_state != AST_STATE_UP) { 00460 ast_setstate(c, AST_STATE_UP); 00461 } 00462 return res; 00463 }
|
|
Make a call over the specified channel to the specified destination. Returns -1 on error, 0 on success. Definition at line 388 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(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, oh323_pvt::exten, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_channel::name, oh323_update_info(), oh323_pvt::options, oh323_pvt::outgoing, oh323_pvt::sa, ast_channel::tech_pvt, and usingGk. 00389 { 00390 int res = 0; 00391 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00392 char addr[INET_ADDRSTRLEN]; 00393 char called_addr[1024]; 00394 00395 if (h323debug) { 00396 ast_log(LOG_DEBUG, "Calling to %s on %s\n", dest, c->name); 00397 } 00398 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 00399 ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name); 00400 return -1; 00401 } 00402 ast_mutex_lock(&pvt->lock); 00403 if (usingGk) { 00404 if (ast_strlen_zero(pvt->exten)) { 00405 strncpy(called_addr, dest, sizeof(called_addr)); 00406 } else { 00407 snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest); 00408 } 00409 } else { 00410 ast_inet_ntoa(addr, sizeof(addr), pvt->sa.sin_addr); 00411 res = htons(pvt->sa.sin_port); 00412 if (ast_strlen_zero(pvt->exten)) { 00413 snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res); 00414 } else { 00415 snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res); 00416 } 00417 } 00418 /* make sure null terminated */ 00419 called_addr[sizeof(called_addr) - 1] = '\0'; 00420 00421 if (c->cid.cid_num) { 00422 strncpy(pvt->options.cid_num, c->cid.cid_num, sizeof(pvt->options.cid_num)); 00423 } 00424 if (c->cid.cid_name) { 00425 strncpy(pvt->options.cid_name, c->cid.cid_name, sizeof(pvt->options.cid_name)); 00426 } 00427 00428 /* indicate that this is an outgoing call */ 00429 pvt->outgoing = 1; 00430 00431 ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d\n", called_addr, pvt->options.dtmfcodec); 00432 ast_mutex_unlock(&pvt->lock); 00433 res = h323_make_call(called_addr, &(pvt->cd), &pvt->options); 00434 if (res) { 00435 ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name); 00436 return -1; 00437 } 00438 oh323_update_info(c); 00439 return 0; 00440 }
|
|
Definition at line 340 of file chan_h323.c. References __oh323_destroy(), ast_mutex_lock(), and ast_mutex_unlock(). Referenced by oh323_request(). 00341 { 00342 ast_mutex_lock(&iflock); 00343 __oh323_destroy(pvt); 00344 ast_mutex_unlock(&iflock); 00345 }
|
|
Send (play) the specified digit to the channel. Definition at line 351 of file chan_h323.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_senddigit(), oh323_pvt::cd, free, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, ast_channel::name, oh323_update_info(), oh323_pvt::options, oh323_pvt::rtp, strdup, and ast_channel::tech_pvt. 00352 { 00353 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00354 char *token; 00355 00356 if (!pvt) { 00357 ast_log(LOG_ERROR, "No private structure?! This is bad\n"); 00358 return -1; 00359 } 00360 ast_mutex_lock(&pvt->lock); 00361 if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833)) { 00362 /* out-of-band DTMF */ 00363 if (h323debug) { 00364 ast_log(LOG_DEBUG, "Sending out-of-band digit %c on %s\n", digit, c->name); 00365 } 00366 ast_rtp_senddigit(pvt->rtp, digit); 00367 } else { 00368 /* in-band DTMF */ 00369 if (h323debug) { 00370 ast_log(LOG_DEBUG, "Sending inband digit %c on %s\n", digit, c->name); 00371 } 00372 token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00373 h323_send_tone(token, digit); 00374 if (token) { 00375 free(token); 00376 } 00377 } 00378 ast_mutex_unlock(&pvt->lock); 00379 oh323_update_info(c); 00380 return 0; 00381 }
|
|
Definition at line 706 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. 00707 { 00708 struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt; 00709 00710 ast_mutex_lock(&pvt->lock); 00711 if (pvt->owner != oldchan) { 00712 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner); 00713 return -1; 00714 } 00715 pvt->owner = newchan; 00716 ast_mutex_unlock(&pvt->lock); 00717 return 0; 00718 }
|
|
Definition at line 2243 of file chan_h323.c. References oh323_pvt::options, oh323_pvt::rtp, and ast_channel::tech_pvt. 02244 { 02245 struct oh323_pvt *pvt; 02246 pvt = (struct oh323_pvt *) chan->tech_pvt; 02247 if (pvt && pvt->rtp && pvt->options.bridge) { 02248 return pvt->rtp; 02249 } 02250 return NULL; 02251 }
|
|
Definition at line 2253 of file chan_h323.c. 02254 {
02255 return NULL;
02256 }
|
|
Definition at line 465 of file chan_h323.c. References ast_channel::_state, 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_mutex_lock(), ast_mutex_unlock(), AST_STATE_UP, ast_update_use_count(), oh323_pvt::cd, free, h323debug, oh323_pvt::hangupcause, ast_channel::hangupcause, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, oh323_pvt::needdestroy, oh323_pvt::owner, pbx_builtin_getvar_helper(), strdup, ast_channel::tech_pvt, usecnt, and usecnt_lock. 00466 { 00467 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00468 int needcancel = 0; 00469 int q931cause = AST_CAUSE_NORMAL_CLEARING; 00470 char *call_token; 00471 00472 00473 if (h323debug) 00474 ast_log(LOG_DEBUG, "Hanging up call %s\n", c->name); 00475 00476 if (!c->tech_pvt) { 00477 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); 00478 return 0; 00479 } 00480 ast_mutex_lock(&pvt->lock); 00481 /* Determine how to disconnect */ 00482 if (pvt->owner != c) { 00483 ast_log(LOG_WARNING, "Huh? We aren't the owner?\n"); 00484 ast_mutex_unlock(&pvt->lock); 00485 return 0; 00486 } 00487 if (!c || (c->_state != AST_STATE_UP)) { 00488 needcancel = 1; 00489 } 00490 00491 pvt->owner = NULL; 00492 c->tech_pvt = NULL; 00493 00494 if (c->hangupcause) { 00495 q931cause = c->hangupcause; 00496 } else { 00497 char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS"); 00498 if (cause) { 00499 if (!strcmp(cause, "CONGESTION")) { 00500 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; 00501 } else if (!strcmp(cause, "BUSY")) { 00502 q931cause = AST_CAUSE_USER_BUSY; 00503 } else if (!strcmp(cause, "CHANISUNVAIL")) { 00504 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; 00505 } else if (!strcmp(cause, "NOANSWER")) { 00506 q931cause = AST_CAUSE_NO_ANSWER; 00507 } else if (!strcmp(cause, "CANCEL")) { 00508 q931cause = AST_CAUSE_CALL_REJECTED; 00509 } 00510 } 00511 } 00512 00513 /* Start the process if it's not already started */ 00514 if (!pvt->alreadygone && !pvt->hangupcause) { 00515 call_token = pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL; 00516 if (call_token) { 00517 /* Release lock to eliminate deadlock */ 00518 ast_mutex_unlock(&pvt->lock); 00519 if (h323_clear_call(call_token, q931cause)) { 00520 ast_log(LOG_DEBUG, "ClearCall failed.\n"); 00521 } 00522 free(call_token); 00523 ast_mutex_lock(&pvt->lock); 00524 } 00525 } 00526 pvt->needdestroy = 1; 00527 00528 /* Update usage counter */ 00529 ast_mutex_lock(&usecnt_lock); 00530 usecnt--; 00531 if (usecnt < 0) { 00532 ast_log(LOG_WARNING, "Usecnt < 0\n"); 00533 } 00534 ast_mutex_unlock(&usecnt_lock); 00535 ast_mutex_unlock(&pvt->lock); 00536 ast_update_use_count(); 00537 return 0; 00538 }
|
|
Definition at line 630 of file chan_h323.c. References ast_channel::_state, oh323_pvt::alreadygone, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), 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, h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_update_info(), strdup, and ast_channel::tech_pvt. 00631 { 00632 00633 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00634 char *token = (char *)NULL; 00635 00636 ast_mutex_lock(&pvt->lock); 00637 token = (pvt->cd.call_token ? strdup(pvt->cd.call_token) : NULL); 00638 ast_mutex_unlock(&pvt->lock); 00639 00640 if (h323debug) 00641 ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token); 00642 00643 switch(condition) { 00644 case AST_CONTROL_RINGING: 00645 if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) { 00646 h323_send_alerting(token); 00647 break; 00648 } 00649 if (token) 00650 free(token); 00651 return -1; 00652 case AST_CONTROL_PROGRESS: 00653 if (c->_state != AST_STATE_UP) { 00654 h323_send_progress(token); 00655 break; 00656 } 00657 if (token) 00658 free(token); 00659 return -1; 00660 00661 case AST_CONTROL_BUSY: 00662 if (c->_state != AST_STATE_UP) { 00663 h323_answering_call(token, 1); 00664 ast_mutex_lock(&pvt->lock); 00665 pvt->alreadygone = 1; 00666 ast_mutex_unlock(&pvt->lock); 00667 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00668 break; 00669 } 00670 if (token) 00671 free(token); 00672 return -1; 00673 case AST_CONTROL_CONGESTION: 00674 if (c->_state != AST_STATE_UP) { 00675 h323_answering_call(token, 1); 00676 ast_mutex_lock(&pvt->lock); 00677 pvt->alreadygone = 1; 00678 ast_mutex_unlock(&pvt->lock); 00679 ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV); 00680 break; 00681 } 00682 if (token) 00683 free(token); 00684 return -1; 00685 case AST_CONTROL_PROCEEDING: 00686 case -1: 00687 if (token) 00688 free(token); 00689 return -1; 00690 default: 00691 ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n", condition, token); 00692 if (token) 00693 free(token); 00694 return -1; 00695 } 00696 00697 if (h323debug) 00698 ast_log(LOG_DEBUG, "OH323: Indicated %d on %s\n", condition, token); 00699 if (token) 00700 free(token); 00701 oh323_update_info(c); 00702 00703 return -1; 00704 }
|
|
Definition at line 590 of file chan_h323.c. References __oh323_update_info(), ast_mutex_lock(), ast_mutex_unlock(), oh323_pvt::lock, oh323_rtp_read(), and ast_channel::tech_pvt. 00591 { 00592 struct ast_frame *fr; 00593 struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt; 00594 ast_mutex_lock(&pvt->lock); 00595 __oh323_update_info(c, pvt); 00596 fr = oh323_rtp_read(pvt); 00597 ast_mutex_unlock(&pvt->lock); 00598 return fr; 00599 }
|
|
Definition at line 1012 of file chan_h323.c. References __oh323_new(), AST_FORMAT_MAX_AUDIO, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_DTMF, ast_rtp_setnat(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), create_addr(), oh323_pvt::exten, global_options, host, oh323_pvt::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, oh323_pvt::nonCodecCapability, oh323_alloc(), oh323_destroy(), oh323_pvt::options, restart_monitor(), oh323_pvt::rtp, unique, and usingGk. 01013 { 01014 int oldformat; 01015 struct oh323_pvt *pvt; 01016 struct ast_channel *tmpc = NULL; 01017 char *dest = (char *)data; 01018 char *ext, *host; 01019 char *h323id = NULL; 01020 char tmp[256], tmp1[256]; 01021 01022 ast_log(LOG_DEBUG, "type=%s, format=%d, data=%s.\n", type, format, (char *)data); 01023 pvt = oh323_alloc(0); 01024 if (!pvt) { 01025 ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data); 01026 return NULL; 01027 } 01028 oldformat = format; 01029 format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1); 01030 if (!format) { 01031 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 01032 return NULL; 01033 } 01034 strncpy(tmp, dest, sizeof(tmp) - 1); 01035 host = strchr(tmp, '@'); 01036 if (host) { 01037 *host = '\0'; 01038 host++; 01039 ext = tmp; 01040 } else { 01041 host = tmp; 01042 ext = NULL; 01043 } 01044 strtok_r(host, "/", &(h323id)); 01045 if (!ast_strlen_zero(h323id)) { 01046 h323_set_id(h323id); 01047 } 01048 if (ext) { 01049 strncpy(pvt->exten, ext, sizeof(pvt->exten) - 1); 01050 } 01051 ast_log(LOG_DEBUG, "Extension: %s Host: %s\n", pvt->exten, host); 01052 if (!usingGk) { 01053 if (create_addr(pvt, host)) { 01054 oh323_destroy(pvt); 01055 return NULL; 01056 } 01057 } 01058 else { 01059 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01060 if (pvt->rtp) { 01061 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat); 01062 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 01063 } 01064 if (pvt->options.dtmfmode) { 01065 if (pvt->options.dtmfmode & H323_DTMF_RFC2833) { 01066 pvt->nonCodecCapability |= AST_RTP_DTMF; 01067 } else { 01068 pvt->nonCodecCapability &= ~AST_RTP_DTMF; 01069 } 01070 } 01071 } 01072 01073 ast_mutex_lock(&caplock); 01074 /* Generate unique channel identifier */ 01075 snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique); 01076 tmp1[sizeof(tmp1)-1] = '\0'; 01077 ast_mutex_unlock(&caplock); 01078 01079 ast_mutex_lock(&pvt->lock); 01080 tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1); 01081 ast_mutex_unlock(&pvt->lock); 01082 if (!tmpc) { 01083 oh323_destroy(pvt); 01084 } 01085 ast_update_use_count(); 01086 restart_monitor(); 01087 return tmpc; 01088 }
|
|
Definition at line 540 of file chan_h323.c. References ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_read(), ast_rtp_setnat(), ast_set_read_format(), ast_set_write_format(), ast_frame::frametype, ast_channel::lock, LOG_DEBUG, LOG_NOTICE, oh323_pvt::nativeformats, ast_channel::nativeformats, 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(). 00541 { 00542 /* Retrieve audio/etc from channel. Assumes pvt->lock is already held. */ 00543 struct ast_frame *f; 00544 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 00545 00546 /* Only apply it for the first packet, we just need the correct ip/port */ 00547 if (pvt->options.nat) { 00548 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00549 pvt->options.nat = 0; 00550 } 00551 00552 f = ast_rtp_read(pvt->rtp); 00553 /* Don't send RFC2833 if we're not supposed to */ 00554 if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & H323_DTMF_RFC2833)) { 00555 return &null_frame; 00556 } 00557 if (pvt->owner) { 00558 /* We already hold the channel lock */ 00559 if (f->frametype == AST_FRAME_VOICE) { 00560 if (f->subclass != pvt->owner->nativeformats) { 00561 /* Try to avoid deadlock */ 00562 if (ast_mutex_trylock(&pvt->owner->lock)) { 00563 ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n"); 00564 return &null_frame; 00565 } 00566 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 00567 pvt->owner->nativeformats = f->subclass; 00568 pvt->nativeformats = f->subclass; 00569 ast_set_read_format(pvt->owner, pvt->owner->readformat); 00570 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 00571 ast_mutex_unlock(&pvt->owner->lock); 00572 } 00573 /* Do in-band DTMF detection */ 00574 if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) { 00575 if (!ast_mutex_trylock(&pvt->owner->lock)) { 00576 f = ast_dsp_process(pvt->owner,pvt->vad,f); 00577 ast_mutex_unlock(&pvt->owner->lock); 00578 } 00579 else 00580 ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n"); 00581 if (f &&(f->frametype == AST_FRAME_DTMF)) { 00582 ast_log(LOG_DEBUG, "Received in-band digit %c.\n", f->subclass); 00583 } 00584 } 00585 } 00586 } 00587 return f; 00588 }
|
|
Definition at line 2283 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. 02284 { 02285 /* XXX Deal with Video */ 02286 struct oh323_pvt *pvt; 02287 struct sockaddr_in them; 02288 struct sockaddr_in us; 02289 char *mode; 02290 char iabuf[INET_ADDRSTRLEN]; 02291 02292 if (!rtp) { 02293 return 0; 02294 } 02295 02296 mode = convertcap(chan->writeformat); 02297 pvt = (struct oh323_pvt *) chan->tech_pvt; 02298 if (!pvt) { 02299 ast_log(LOG_ERROR, "No Private Structure, this is bad\n"); 02300 return -1; 02301 } 02302 ast_rtp_get_peer(rtp, &them); 02303 ast_rtp_get_us(rtp, &us); 02304 h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(iabuf, sizeof(iabuf), them.sin_addr), mode); 02305 return 0; 02306 }
|
|
Definition at line 256 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(), and oh323_indicate(). 00257 { 00258 struct oh323_pvt *pvt = c->tech_pvt; 00259 00260 if (pvt) { 00261 ast_mutex_lock(&pvt->lock); 00262 __oh323_update_info(c, pvt); 00263 ast_mutex_unlock(&pvt->lock); 00264 } 00265 }
|
|
Definition at line 601 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::rtp, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat. 00602 { 00603 struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt; 00604 int res = 0; 00605 if (frame->frametype != AST_FRAME_VOICE) { 00606 if (frame->frametype == AST_FRAME_IMAGE) { 00607 return 0; 00608 } else { 00609 ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype); 00610 return 0; 00611 } 00612 } else { 00613 if (!(frame->subclass & c->nativeformats)) { 00614 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 00615 frame->subclass, c->nativeformats, c->readformat, c->writeformat); 00616 return 0; 00617 } 00618 } 00619 if (pvt) { 00620 ast_mutex_lock(&pvt->lock); 00621 if (pvt->rtp) { 00622 res = ast_rtp_write(pvt->rtp, frame); 00623 } 00624 __oh323_update_info(c, pvt); 00625 ast_mutex_unlock(&pvt->lock); 00626 } 00627 return res; 00628 }
|
|
Definition at line 1259 of file chan_h323.c. References AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_log(), ast_mutex_unlock(), find_call_locked(), ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, oh323_pvt::owner, and update_state(). 01260 { 01261 struct oh323_pvt *pvt; 01262 01263 ast_log(LOG_DEBUG, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated")); 01264 01265 pvt = find_call_locked(call_reference, token); 01266 if (!pvt) { 01267 ast_log(LOG_ERROR, "Private structure not found in progress.\n"); 01268 return -1; 01269 } 01270 if (!pvt->owner) { 01271 ast_mutex_unlock(&pvt->lock); 01272 ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n"); 01273 return -1; 01274 } 01275 if (update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING))) 01276 ast_mutex_unlock(&pvt->owner->lock); 01277 ast_mutex_unlock(&pvt->lock); 01278 01279 return 0; 01280 }
|
|
Definition at line 2189 of file chan_h323.c. References ast_mutex_lock(), ast_mutex_unlock(), free, ast_peer_list::lock, peerl, and ast_peer_list::peers. Referenced by expire_registry(), h323_do_reload(), set_config(), and unload_module(). 02190 { 02191 /* Prune peers who still are supposed to be deleted */ 02192 struct oh323_peer *peer, *peerlast, *peernext; 02193 ast_mutex_lock(&peerl.lock); 02194 peerlast = NULL; 02195 for (peer=peerl.peers;peer;) { 02196 peernext = peer->next; 02197 if (peer->delme) { 02198 free(peer); 02199 if (peerlast) { 02200 peerlast->next = peernext; 02201 } else { 02202 peerl.peers = peernext; 02203 } 02204 } else { 02205 peerlast = peer; 02206 } 02207 peer = peernext; 02208 } 02209 ast_mutex_unlock(&peerl.lock); 02210 }
|
|
Reload stuff. This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 2235 of file chan_h323.c. References h323_reload(). 02236 { 02237 return h323_reload(0, 0, NULL); 02238 }
|
|
Definition at line 1998 of file chan_h323.c. References ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), bindaddr, build_alias(), build_peer(), build_user(), cfg, config, default_context, format, gatekeeper, gatekeeper_disable, gatekeeper_discover, gkroute, global_options, h323_signalling_port, h323debug, hp, IPTOS_MINCOST, ast_variable::lineno, ast_user_list::lock, ast_peer_list::lock, ast_alias_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, secret, tos, update_common_options(), user, userbyalias, userl, ast_user_list::users, usingGk, ast_variable::value, and VERBOSE_PREFIX_2. Referenced by h323_do_reload(), iax2_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), and reload(). 01999 { 02000 int format; 02001 struct ast_config *cfg; 02002 struct ast_variable *v; 02003 struct oh323_peer *peer = NULL; 02004 struct oh323_user *user = NULL; 02005 struct oh323_alias *alias = NULL; 02006 struct ast_hostent ahp; struct hostent *hp; 02007 char *cat; 02008 char *utype; 02009 02010 cfg = ast_config_load(config); 02011 02012 /* We *must* have a config file otherwise stop immediately */ 02013 if (!cfg) { 02014 ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config); 02015 return 1; 02016 } 02017 02018 /* fire up the H.323 Endpoint */ 02019 if (!h323_end_point_exist()) { 02020 h323_end_point_create(); 02021 } 02022 h323debug = 0; 02023 memset(&bindaddr, 0, sizeof(bindaddr)); 02024 memset(&global_options, 0, sizeof(global_options)); 02025 global_options.dtmfcodec = 101; 02026 global_options.dtmfmode = H323_DTMF_RFC2833; 02027 global_options.capability = ~0; /* All capabilities */ 02028 global_options.bridge = 1; /* Do native bridging by default */ 02029 v = ast_variable_browse(cfg, "general"); 02030 while(v) { 02031 /* Create the interface list */ 02032 if (!strcasecmp(v->name, "port")) { 02033 h323_signalling_port = (int)strtol(v->value, NULL, 10); 02034 } else if (!strcasecmp(v->name, "bindaddr")) { 02035 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 02036 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 02037 } else { 02038 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 02039 } 02040 } else if (!strcasecmp(v->name, "tos")) { 02041 if (sscanf(v->value, "%d", &format)) { 02042 tos = format & 0xff; 02043 } else if (!strcasecmp(v->value, "lowdelay")) { 02044 tos = IPTOS_LOWDELAY; 02045 } else if (!strcasecmp(v->value, "throughput")) { 02046 tos = IPTOS_THROUGHPUT; 02047 } else if (!strcasecmp(v->value, "reliability")) { 02048 tos = IPTOS_RELIABILITY; 02049 } else if (!strcasecmp(v->value, "mincost")) { 02050 tos = IPTOS_MINCOST; 02051 } else if (!strcasecmp(v->value, "none")) { 02052 tos = 0; 02053 } else { 02054 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 02055 } 02056 } else if (!strcasecmp(v->name, "gatekeeper")) { 02057 if (!strcasecmp(v->value, "DISABLE")) { 02058 gatekeeper_disable = 1; 02059 usingGk = 0; 02060 } else if (!strcasecmp(v->value, "DISCOVER")) { 02061 gatekeeper_disable = 0; 02062 gatekeeper_discover = 1; 02063 usingGk = 1; 02064 } else { 02065 gatekeeper_disable = 0; 02066 usingGk = 1; 02067 strncpy(gatekeeper, v->value, sizeof(gatekeeper) - 1); 02068 } 02069 } else if (!strcasecmp(v->name, "secret")) { 02070 strncpy(secret, v->value, sizeof(secret) - 1); 02071 } else if (!strcasecmp(v->name, "AllowGKRouted")) { 02072 gkroute = ast_true(v->value); 02073 } else if (!strcasecmp(v->name, "context")) { 02074 strncpy(default_context, v->value, sizeof(default_context) - 1); 02075 ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context); 02076 } else if (!strcasecmp(v->name, "UserByAlias")) { 02077 userbyalias = ast_true(v->value); 02078 } else if (!update_common_options(v, &global_options)) { 02079 /* dummy */ 02080 } 02081 v = v->next; 02082 } 02083 02084 cat = ast_category_browse(cfg, NULL); 02085 while(cat) { 02086 if (strcasecmp(cat, "general")) { 02087 utype = ast_variable_retrieve(cfg, cat, "type"); 02088 if (utype) { 02089 if (!strcasecmp(utype, "user")) { 02090 user = build_user(cat, ast_variable_browse(cfg, cat)); 02091 if (user) { 02092 ast_mutex_lock(&userl.lock); 02093 user->next = userl.users; 02094 userl.users = user; 02095 ast_mutex_unlock(&userl.lock); 02096 } 02097 } else if (!strcasecmp(utype, "peer")) { 02098 peer = build_peer(cat, ast_variable_browse(cfg, cat)); 02099 if (peer) { 02100 ast_mutex_lock(&peerl.lock); 02101 peer->next = peerl.peers; 02102 peerl.peers = peer; 02103 ast_mutex_unlock(&peerl.lock); 02104 } 02105 } else if (!strcasecmp(utype, "friend")) { 02106 user = build_user(cat, ast_variable_browse(cfg, cat)); 02107 peer = build_peer(cat, ast_variable_browse(cfg, cat)); 02108 if (user) { 02109 ast_mutex_lock(&userl.lock); 02110 user->next = userl.users; 02111 userl.users = user; 02112 ast_mutex_unlock(&userl.lock); 02113 } 02114 if (peer) { 02115 ast_mutex_lock(&peerl.lock); 02116 peer->next = peerl.peers; 02117 peerl.peers = peer; 02118 ast_mutex_unlock(&peerl.lock); 02119 } 02120 } else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) { 02121 alias = build_alias(cat, ast_variable_browse(cfg, cat)); 02122 if (alias) { 02123 ast_mutex_lock(&aliasl.lock); 02124 alias->next = aliasl.aliases; 02125 aliasl.aliases = alias; 02126 ast_mutex_unlock(&aliasl.lock); 02127 } 02128 } else { 02129 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config); 02130 } 02131 } else { 02132 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 02133 } 02134 } 02135 cat = ast_category_browse(cfg, cat); 02136 } 02137 ast_config_destroy(cfg); 02138 02139 /* Register our H.323 aliases if any*/ 02140 while (alias) { 02141 if (h323_set_alias(alias)) { 02142 ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name); 02143 return -1; 02144 } 02145 alias = alias->next; 02146 } 02147 02148 return 0; 02149 }
|
|
Definition at line 1623 of file chan_h323.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread. Referenced by h323_do_reload(), h323_reload(), load_module(), mgcp_reload(), mgcp_request(), modem_hangup(), modem_request(), oh323_request(), phone_hangup(), phone_request(), reload(), setup_zap(), sip_reload(), sip_request_call(), skinny_request(), vpb_hangup(), vpb_request(), zt_hangup(), and zt_request(). 01624 { 01625 pthread_attr_t attr; 01626 /* If we're supposed to be stopped -- stay stopped */ 01627 if (monitor_thread == AST_PTHREADT_STOP) { 01628 return 0; 01629 } 01630 if (ast_mutex_lock(&monlock)) { 01631 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 01632 return -1; 01633 } 01634 if (monitor_thread == pthread_self()) { 01635 ast_mutex_unlock(&monlock); 01636 ast_log(LOG_WARNING, "Cannot kill myself\n"); 01637 return -1; 01638 } 01639 if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) { 01640 /* Wake up the thread */ 01641 pthread_kill(monitor_thread, SIGURG); 01642 } else { 01643 pthread_attr_init(&attr); 01644 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01645 /* Start a new monitor */ 01646 if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) { 01647 ast_mutex_unlock(&monlock); 01648 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 01649 return -1; 01650 } 01651 01652 } 01653 ast_mutex_unlock(&monlock); 01654 return 0; 01655 }
|
|
Callback for sending digits from H.323 up to asterisk Definition at line 1109 of file chan_h323.c. References AST_FRAME_DTMF, ast_log(), ast_mutex_unlock(), ast_queue_frame(), find_call_locked(), oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, and oh323_pvt::owner. Referenced by load_module(). 01110 { 01111 struct oh323_pvt *pvt; 01112 struct ast_frame f; 01113 int res; 01114 01115 ast_log(LOG_DEBUG, "Received Digit: %c\n", digit); 01116 pvt = find_call_locked(call_reference, token); 01117 if (!pvt) { 01118 ast_log(LOG_ERROR, "Private structure not found in send_digit.\n"); 01119 return -1; 01120 } 01121 memset(&f, 0, sizeof(f)); 01122 f.frametype = AST_FRAME_DTMF; 01123 f.subclass = digit; 01124 f.datalen = 0; 01125 f.samples = 800; 01126 f.offset = 0; 01127 f.data = NULL; 01128 f.mallocd = 0; 01129 f.src = "SEND_DIGIT"; 01130 res = ast_queue_frame(pvt->owner, &f); 01131 ast_mutex_unlock(&pvt->lock); 01132 return res; 01133 }
|
|
Definition at line 1536 of file chan_h323.c. References ast_log(), ast_mutex_unlock(), ast_rtp_set_rtpmap_type(), find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, and oh323_pvt::rtp. Referenced by load_module(). 01537 { 01538 struct oh323_pvt *pvt; 01539 01540 if (h323debug) 01541 ast_log(LOG_DEBUG, "Setting DTMF payload to %d on %s\n", payload, token); 01542 01543 pvt = find_call_locked(call_reference, token); 01544 if (!pvt) { 01545 return; 01546 } 01547 if (pvt->rtp) { 01548 ast_rtp_set_rtpmap_type(pvt->rtp, payload, "audio", "telephone-event"); 01549 } 01550 ast_mutex_unlock(&pvt->lock); 01551 if (h323debug) 01552 ast_log(LOG_DEBUG, "DTMF payload on %s set to %d\n", token, payload); 01553 }
|
|
Definition at line 1555 of file chan_h323.c. References ast_log(), ast_mutex_unlock(), capability, dtmfmode, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, and oh323_pvt::options. Referenced by load_module(). 01556 { 01557 struct oh323_pvt *pvt; 01558 int capability, dtmfmode; 01559 01560 if (h323debug) 01561 ast_log(LOG_DEBUG, "Setting capabilities for connection %s\n", token); 01562 01563 pvt = find_call_locked(call_reference, token); 01564 if (!pvt) 01565 return; 01566 capability = pvt->options.capability; 01567 dtmfmode = pvt->options.dtmfmode; 01568 ast_mutex_unlock(&pvt->lock); 01569 h323_set_capabilities(token, capability, dtmfmode); 01570 01571 if (h323debug) 01572 ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token); 01573 }
|
|
Call-back function for incoming calls Returns 1 on success Definition at line 1287 of file chan_h323.c. References oh323_pvt::accountcode, oh323_pvt::amaflags, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_verbose(), oh323_pvt::cd, oh323_pvt::context, default_context, oh323_pvt::exten, find_alias(), find_user(), gatekeeper, gkroute, global_options, h323debug, LOG_DEBUG, LOG_ERROR, oh323_alloc(), oh323_pvt::options, user, usingGk, and VERBOSE_PREFIX_3. Referenced by load_module(). 01288 { 01289 struct oh323_pvt *pvt; 01290 struct oh323_user *user = NULL; 01291 struct oh323_alias *alias = NULL; 01292 char iabuf[INET_ADDRSTRLEN]; 01293 01294 if (h323debug) 01295 ast_log(LOG_DEBUG, "Setting up incoming call for %s\n", cd->call_token); 01296 01297 /* allocate the call*/ 01298 pvt = oh323_alloc(cd->call_reference); 01299 01300 if (!pvt) { 01301 ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n"); 01302 return NULL; 01303 } 01304 01305 /* Populate the call details in the private structure */ 01306 memcpy(&pvt->cd, cd, sizeof(pvt->cd)); 01307 memcpy(&pvt->options, &global_options, sizeof(pvt->options)); 01308 01309 if (h323debug) { 01310 ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n"); 01311 ast_verbose(VERBOSE_PREFIX_3 "\tCall token: [%s]\n", pvt->cd.call_token); 01312 ast_verbose(VERBOSE_PREFIX_3 "\tCalling party name: [%s]\n", pvt->cd.call_source_name); 01313 ast_verbose(VERBOSE_PREFIX_3 "\tCalling party number: [%s]\n", pvt->cd.call_source_e164); 01314 ast_verbose(VERBOSE_PREFIX_3 "\tCalled party name: [%s]\n", pvt->cd.call_dest_alias); 01315 ast_verbose(VERBOSE_PREFIX_3 "\tCalled party number: [%s]\n", pvt->cd.call_dest_e164); 01316 } 01317 01318 /* Decide if we are allowing Gatekeeper routed calls*/ 01319 if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && (usingGk)) { 01320 if (!ast_strlen_zero(cd->call_dest_e164)) { 01321 strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1); 01322 strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); 01323 } else { 01324 alias = find_alias(cd->call_dest_alias); 01325 if (!alias) { 01326 ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias); 01327 return NULL; 01328 } 01329 strncpy(pvt->exten, alias->name, sizeof(pvt->exten) - 1); 01330 strncpy(pvt->context, alias->context, sizeof(pvt->context) - 1); 01331 } 01332 } else { 01333 /* Either this call is not from the Gatekeeper 01334 or we are not allowing gk routed calls */ 01335 user = find_user(cd); 01336 if (!user) { 01337 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { 01338 strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1); 01339 } else { 01340 strncpy(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten) - 1); 01341 } 01342 if (ast_strlen_zero(default_context)) { 01343 ast_log(LOG_ERROR, "Call from '%s' rejected due to no default context\n", pvt->cd.call_source_aliases); 01344 return NULL; 01345 } 01346 strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); 01347 ast_log(LOG_DEBUG, "Sending %s to context [%s]\n", cd->call_source_aliases, pvt->context); 01348 /* XXX: Is it really required??? */ 01349 #if 0 01350 memset(&pvt->options, 0, sizeof(pvt->options)); 01351 #endif 01352 } else { 01353 if (user->host) { 01354 if (strcasecmp(cd->sourceIp, ast_inet_ntoa(iabuf, sizeof(iabuf), user->addr.sin_addr))) { 01355 if (ast_strlen_zero(user->context)) { 01356 if (ast_strlen_zero(default_context)) { 01357 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp); 01358 return NULL; 01359 } 01360 strncpy(pvt->context, default_context, sizeof(pvt->context) - 1); 01361 } else { 01362 strncpy(pvt->context, user->context, sizeof(pvt->context) - 1); 01363 } 01364 pvt->exten[0] = 'i'; 01365 pvt->exten[1] = '\0'; 01366 ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp); 01367 return NULL; /* XXX: Hmmm... Why to setup context if we drop connection immediately??? */ 01368 } 01369 } 01370 strncpy(pvt->context, user->context, sizeof(pvt->context) - 1); 01371 memcpy(&pvt->options, &user->options, sizeof(pvt->options)); 01372 if (!ast_strlen_zero(pvt->cd.call_dest_e164)) { 01373 strncpy(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten) - 1); 01374 } else { 01375 strncpy(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten) - 1); 01376 } 01377 if (!ast_strlen_zero(user->accountcode)) { 01378 strncpy(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode) - 1); 01379 } 01380 if (user->amaflags) { 01381 pvt->amaflags = user->amaflags; 01382 } 01383 } 01384 } 01385 return &pvt->options; 01386 }
|
|
Call-back function to establish an outgoing H.323 call Returns 1 on success Definition at line 1424 of file chan_h323.c. References cleanup_call_details(). Referenced by load_module(). 01425 { 01426 /* Use argument here or free it immediately */ 01427 cleanup_call_details(cd); 01428 01429 return 1; 01430 }
|
|
Call-back function passing remote ip/port information from H.323 to asterisk Returns nothing Definition at line 1181 of file chan_h323.c. References oh323_pvt::alreadygone, AST_CONTROL_PROGRESS, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control(), ast_rtp_lookup_pt(), ast_rtp_set_peer(), ast_set_read_format(), ast_set_write_format(), rtpPayloadType::code, find_call_locked(), h323debug, ast_channel::lock, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, ast_channel::nativeformats, oh323_pvt::nativeformats, oh323_pvt::newcontrol, oh323_pvt::options, oh323_pvt::owner, ast_channel::readformat, oh323_pvt::rtp, and ast_channel::writeformat. Referenced by load_module(). 01182 { 01183 struct oh323_pvt *pvt; 01184 struct sockaddr_in them; 01185 struct rtpPayloadType rtptype; 01186 01187 if (h323debug) 01188 ast_log(LOG_DEBUG, "Setting up RTP connection for %s\n", token); 01189 01190 /* Find the call or allocate a private structure if call not found */ 01191 pvt = find_call_locked(call_reference, token); 01192 if (!pvt) { 01193 ast_log(LOG_ERROR, "Something is wrong: rtp\n"); 01194 return; 01195 } 01196 if (pvt->alreadygone) { 01197 ast_mutex_unlock(&pvt->lock); 01198 return; 01199 } 01200 rtptype = ast_rtp_lookup_pt(pvt->rtp, pt); 01201 pvt->nativeformats = rtptype.code; 01202 if (pvt->owner && !ast_mutex_trylock(&pvt->owner->lock)) { 01203 pvt->owner->nativeformats = pvt->nativeformats; 01204 ast_set_read_format(pvt->owner, pvt->owner->readformat); 01205 ast_set_write_format(pvt->owner, pvt->owner->writeformat); 01206 if (pvt->options.progress_audio) 01207 ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS); 01208 ast_mutex_unlock(&pvt->owner->lock); 01209 } 01210 else { 01211 if (pvt->options.progress_audio) 01212 pvt->newcontrol = AST_CONTROL_PROGRESS; 01213 if (h323debug) 01214 ast_log(LOG_DEBUG, "RTP connection preparation for %s is pending...\n", token); 01215 } 01216 01217 them.sin_family = AF_INET; 01218 /* only works for IPv4 */ 01219 them.sin_addr.s_addr = inet_addr(remoteIp); 01220 them.sin_port = htons(remotePort); 01221 ast_rtp_set_peer(pvt->rtp, &them); 01222 01223 ast_mutex_unlock(&pvt->lock); 01224 01225 if (h323debug) 01226 ast_log(LOG_DEBUG, "RTP connection prepared for %s\n", token); 01227 01228 return; 01229 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 2383 of file chan_h323.c. References aliasl, ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, delete_aliases(), delete_users(), free, iflist, io_context_destroy(), ast_peer_list::lock, ast_user_list::lock, ast_alias_list::lock, oh323_pvt::lock, LOG_WARNING, monitor_thread, oh323_pvt::next, oh323_pvt::owner, peerl, prune_peers(), sched_context_destroy(), and userl. 02384 { 02385 struct oh323_pvt *p, *pl; 02386 02387 /* unregister commands */ 02388 ast_cli_unregister(&cli_debug); 02389 ast_cli_unregister(&cli_no_debug); 02390 ast_cli_unregister(&cli_trace); 02391 ast_cli_unregister(&cli_no_trace); 02392 ast_cli_unregister(&cli_show_codecs); 02393 ast_cli_unregister(&cli_gk_cycle); 02394 ast_cli_unregister(&cli_hangup_call); 02395 ast_cli_unregister(&cli_show_tokens); 02396 ast_cli_unregister(&cli_h323_reload); 02397 ast_rtp_proto_unregister(&oh323_rtp); 02398 ast_channel_unregister(&oh323_tech); 02399 02400 if (!ast_mutex_lock(&iflock)) { 02401 /* hangup all interfaces if they have an owner */ 02402 p = iflist; 02403 while(p) { 02404 if (p->owner) { 02405 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); 02406 } 02407 p = p->next; 02408 } 02409 iflist = NULL; 02410 ast_mutex_unlock(&iflock); 02411 } else { 02412 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 02413 return -1; 02414 } 02415 if (!ast_mutex_lock(&monlock)) { 02416 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 02417 /* this causes a seg, anyone know why? */ 02418 pthread_cancel(monitor_thread); 02419 pthread_kill(monitor_thread, SIGURG); 02420 pthread_join(monitor_thread, NULL); 02421 } 02422 monitor_thread = AST_PTHREADT_STOP; 02423 ast_mutex_unlock(&monlock); 02424 } else { 02425 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 02426 return -1; 02427 } 02428 if (!ast_mutex_lock(&iflock)) { 02429 /* destroy all the interfaces and free their memory */ 02430 p = iflist; 02431 while(p) { 02432 pl = p; 02433 p = p->next; 02434 /* free associated memory */ 02435 ast_mutex_destroy(&pl->lock); 02436 free(pl); 02437 } 02438 iflist = NULL; 02439 ast_mutex_unlock(&iflock); 02440 } else { 02441 ast_log(LOG_WARNING, "Unable to lock the interface list\n"); 02442 return -1; 02443 } 02444 h323_gk_urq(); 02445 h323_end_process(); 02446 io_context_destroy(io); 02447 sched_context_destroy(sched); 02448 delete_users(); 02449 delete_aliases(); 02450 prune_peers(); 02451 ast_mutex_destroy(&aliasl.lock); 02452 ast_mutex_destroy(&userl.lock); 02453 ast_mutex_destroy(&peerl.lock); 02454 return 0; 02455 }
|
|
Definition at line 1790 of file chan_h323.c. References ast_getformatbyname(), ast_log(), ast_true(), format, ast_variable::lineno, LOG_WARNING, ast_variable::name, and ast_variable::value. Referenced by build_peer(), build_user(), and reload_config(). 01791 { 01792 unsigned int format; 01793 int tmp; 01794 01795 if (!strcasecmp(v->name, "allow")) { 01796 format = ast_getformatbyname(v->value); 01797 if (format < 1) 01798 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value); 01799 else 01800 options->capability |= format; 01801 } else if (!strcasecmp(v->name, "disallow")) { 01802 format = ast_getformatbyname(v->value); 01803 if (format < 1) 01804 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value); 01805 else 01806 options->capability &= ~format; 01807 } else if (!strcasecmp(v->name, "dtmfmode")) { 01808 if (!strcasecmp(v->value, "inband")) { 01809 options->dtmfmode = H323_DTMF_INBAND; 01810 } else if (!strcasecmp(v->value, "rfc2833")) { 01811 options->dtmfmode = H323_DTMF_RFC2833; 01812 } else { 01813 ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value); 01814 options->dtmfmode = H323_DTMF_RFC2833; 01815 } 01816 } else if (!strcasecmp(v->name, "dtmfcodec")) { 01817 tmp = atoi(v->value); 01818 if (tmp < 96) 01819 ast_log(LOG_WARNING, "Invalid global dtmfcodec value %s\n", v->value); 01820 else 01821 options->dtmfcodec = tmp; 01822 } else if (!strcasecmp(v->name, "bridge")) { 01823 options->bridge = ast_true(v->value); 01824 } else if (!strcasecmp(v->name, "nat")) { 01825 options->nat = ast_true(v->value); 01826 } else if (!strcasecmp(v->name, "noFastStart")) { 01827 options->noFastStart = ast_true(v->value); 01828 } else if (!strcasecmp(v->name, "noH245Tunneling")) { 01829 options->noH245Tunneling = ast_true(v->value); 01830 } else if (!strcasecmp(v->name, "noSilenceSuppression")) { 01831 options->noSilenceSuppression = ast_true(v->value); 01832 } else if (!strcasecmp(v->name, "progress_setup")) { 01833 tmp = atoi(v->value); 01834 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) { 01835 ast_log(LOG_WARNING, "Invalid value %d for progress_setup at line %d, assuming 0\n", tmp, v->lineno); 01836 tmp = 0; 01837 } 01838 options->progress_setup = tmp; 01839 } else if (!strcasecmp(v->name, "progress_alert")) { 01840 tmp = atoi(v->value); 01841 if ((tmp != 0) && (tmp != 8)) { 01842 ast_log(LOG_WARNING, "Invalud value %d for progress_alert at line %d, assuming 0\n", tmp, v->lineno); 01843 tmp = 0; 01844 } 01845 options->progress_alert = tmp; 01846 } else if (!strcasecmp(v->name, "progress_audio")) { 01847 options->progress_audio = ast_true(v->value); 01848 } else 01849 return 1; 01850 01851 return 0; 01852 }
|
|
Definition at line 873 of file chan_h323.c. References ast_mutex_trylock(), ast_queue_control(), ast_setstate(), ast_channel::lock, oh323_pvt::newcontrol, oh323_pvt::newstate, and oh323_pvt::owner. Referenced by chan_ringing(), connection_made(), and progress(). 00874 { 00875 if (!pvt) 00876 return 0; 00877 if (pvt->owner && !ast_mutex_trylock(&pvt->owner->lock)) { 00878 if (state >= 0) 00879 ast_setstate(pvt->owner, state); 00880 if (signal >= 0) 00881 ast_queue_control(pvt->owner, signal); 00882 return 1; 00883 } 00884 else { 00885 if (state >= 0) 00886 pvt->newstate = state; 00887 if (signal >= 0) 00888 pvt->newcontrol = signal; 00889 return 0; 00890 } 00891 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 2457 of file chan_h323.c. References usecnt. 02458 { 02459 return usecnt; 02460 }
|
|
Referenced by delete_aliases(), find_alias(), load_module(), reload_config(), and unload_module(). |
|
Definition at line 107 of file chan_h323.c. Referenced by load_module(), oh323_alloc(), reload_config(), sip_show_settings(), and start_rtp(). |
|
Initial value: { { "h.323", "debug", NULL }, h323_do_debug, "Enable H.323 debug", debug_usage } Definition at line 1777 of file chan_h323.c. |
|
Initial value: { { "h.323", "gk", "cycle", NULL }, h323_gk_cycle, "Manually re-register with the Gatekeper", show_cycle_usage } Definition at line 1783 of file chan_h323.c. |
|
Initial value: { { "h.323", "reload", NULL }, h323_reload, "Reload H.323 configuration", h323_reload_usage } Definition at line 2240 of file chan_h323.c. |
|
Initial value: { { "h.323", "hangup", NULL }, h323_ep_hangup, "Manually try to hang up a call", show_hangup_usage } Definition at line 1785 of file chan_h323.c. |
|
Initial value: { { "h.323", "no", "debug", NULL }, h323_no_debug, "Disable H.323 debug", no_debug_usage } Definition at line 1779 of file chan_h323.c. |
|
Initial value: { { "h.323", "no", "trace", NULL }, h323_no_trace, "Disable H.323 Stack Tracing", no_trace_usage } Definition at line 1775 of file chan_h323.c. |
|
Initial value: { { "h.323", "show", "codecs", NULL }, h323_show_codec, "Show enabled codecs", show_codec_usage } Definition at line 1781 of file chan_h323.c. |
|
Initial value: { { "h.323", "show", "tokens", NULL }, h323_tokens_show, "Show all active call tokens", show_tokens_usage } Definition at line 1787 of file chan_h323.c. |
|
Initial value: { { "h.323", "trace", NULL }, h323_do_trace, "Enable H.323 Stack Tracing", trace_usage } Definition at line 1773 of file chan_h323.c. |
|
Definition at line 105 of file chan_h323.c. |
|
Initial value: "Usage: h.323 debug\n" " Enables H.323 debug output\n" Definition at line 1745 of file chan_h323.c. |
|
Definition at line 106 of file chan_h323.c. Referenced by build_peer(), build_user(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_request_subscribe(), oh323_alloc(), reload_config(), setup_incoming_call(), sip_alloc(), sip_show_settings(), and temp_peer(). |
|
Definition at line 103 of file chan_h323.c. |
|
Definition at line 111 of file chan_h323.c. Referenced by h323_gk_cycle(), load_module(), reload_config(), and setup_incoming_call(). |
|
Definition at line 112 of file chan_h323.c. Referenced by h323_gk_cycle(), load_module(), and reload_config(). |
|
Definition at line 113 of file chan_h323.c. Referenced by h323_gk_cycle(), load_module(), and reload_config(). |
|
Definition at line 115 of file chan_h323.c. Referenced by reload_config(), and setup_incoming_call(). |
|
Definition at line 122 of file chan_h323.c. Referenced by __oh323_new(), build_peer(), build_user(), create_addr(), oh323_alloc(), oh323_request(), reload_config(), and setup_incoming_call(). |
|
Initial value: "Usage: h323 reload\n" " Reloads H.323 configuration from sip.conf\n" Definition at line 1769 of file chan_h323.c. |
|
Definition at line 188 of file chan_h323.c. Referenced by do_monitor(), and h323_reload(). |
|
H.323 configuration values Definition at line 110 of file chan_h323.c. Referenced by build_peer(), create_addr(), load_module(), and reload_config(). |
|
Definition at line 99 of file chan_h323.c. Referenced by __oh323_update_info(), answer_call(), chan_ringing(), cleanup_connection(), connection_made(), external_rtp_create(), h323_do_debug(), h323_no_debug(), oh323_answer(), oh323_call(), oh323_digit(), oh323_hangup(), oh323_indicate(), reload_config(), set_dtmf_payload(), set_local_capabilities(), setup_incoming_call(), and setup_rtp_connection(). |
|
Private structure of a OpenH323 channel Referenced by __oh323_destroy(), __sip_destroy(), __sip_show_channels(), __unload_module(), action_zapshowchannels(), chandup(), complete_sipch(), destroy_channel(), do_monitor(), find_call(), find_call_locked(), find_channel(), get_sip_pvt_byid_locked(), handle_request_subscribe(), load_module(), mkintf(), oh323_alloc(), phone_request(), sip_alloc(), sip_show_channel(), sip_show_history(), unload_module(), vpb_request(), zap_destroy_channel(), zap_restart(), zap_show_channel(), zap_show_channels(), zt_hangup(), and zt_request(). |
|
Definition at line 170 of file chan_h323.c. |
|
Definition at line 192 of file chan_h323.c. Referenced by __unload_module(), reload_config(), restart_monitor(), and unload_module(). |
|
Initial value: "Usage: h.323 no debug\n" " Disables H.323 debug output\n" Definition at line 1749 of file chan_h323.c. |
|
Initial value: "Usage: h.323 no trace\n" " Disables H.323 stack tracing for debugging purposes\n" Definition at line 1741 of file chan_h323.c. |
|
Definition at line 2308 of file chan_h323.c. |
|
Definition at line 206 of file chan_h323.c. |
|
Definition at line 92 of file chan_h323.c. |
|
Definition at line 89 of file chan_h323.c. |
|
Definition at line 91 of file chan_h323.c. |
|
Definition at line 90 of file chan_h323.c. |
|
Definition at line 85 of file chan_h323.c. |
|
Definition at line 95 of file chan_h323.c. |
|
Definition at line 87 of file chan_h323.c. |
|
Definition at line 88 of file chan_h323.c. |
|
Definition at line 93 of file chan_h323.c. |
|
Definition at line 84 of file chan_h323.c. |
|
Definition at line 94 of file chan_h323.c. |
|
Definition at line 96 of file chan_h323.c. |
|
Definition at line 86 of file chan_h323.c. |
|
|
Asterisk RTP stuff Definition at line 169 of file chan_h323.c. |
|
Definition at line 119 of file chan_h323.c. Referenced by add_realm_authentication(), authenticate_verify(), build_reply_digest(), cache_get_callno_locked(), check_access(), decrypt_frame(), h323_gk_cycle(), iax2_call(), iax2_register(), load_module(), register_verify(), reload_config(), and sip_register(). |
|
Initial value: "Usage: h.323 show codec\n" " Shows all enabled codecs\n" Definition at line 1753 of file chan_h323.c. |
|
Initial value: "Usage: h.323 gk cycle\n" " Manually re-register with the Gatekeper (Currently Disabled)\n" Definition at line 1757 of file chan_h323.c. |
|
Initial value: "Usage: h.323 hangup <token>\n" " Manually try to hang up call identified by <token>\n" Definition at line 1761 of file chan_h323.c. |
|
Initial value: "Usage: h.323 show tokens\n" " Print out all active call tokens\n" Definition at line 1765 of file chan_h323.c. |
|
Definition at line 104 of file chan_h323.c. |
|
Definition at line 118 of file chan_h323.c. Referenced by load_module(), oh323_alloc(), reload_config(), set_config(), sip_alloc(), and sip_show_settings(). |
|
Initial value: "Usage: h.323 trace <level num>\n" " Enables H.323 stack tracing for debugging purposes\n" Definition at line 1737 of file chan_h323.c. |
|
Variables required by Asterisk Definition at line 102 of file chan_h323.c. |
|
Definition at line 120 of file chan_h323.c. Referenced by oh323_request(). |
|
Usage counter and associated lock Definition at line 176 of file chan_h323.c. |
|
Definition at line 117 of file chan_h323.c. Referenced by find_user(), and reload_config(). |
|
|
Definition at line 114 of file chan_h323.c. Referenced by oh323_call(), oh323_request(), reload_config(), and setup_incoming_call(). |