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

Go to the source code of this file.
Data Structures | |
| struct | ast_alias_list |
| struct | ast_peer_list |
| The peer list: Peers and Friends. More... | |
| struct | ast_user_list |
| The user list: Users and friends. More... | |
| struct | oh323_pvt |
| struct | rtpPayloadType |
| Structure representing a RTP session.The value of each payload format mapping:. More... | |
Defines | |
| #define | GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_G726_AAL2 | AST_FORMAT_H261) |
Functions | |
| static void | __oh323_destroy (struct oh323_pvt *pvt) |
| static struct ast_channel * | __oh323_new (struct oh323_pvt *pvt, int state, const char *host) |
| static int | __oh323_rtp_create (struct oh323_pvt *pvt) |
| static void | __oh323_update_info (struct ast_channel *c, struct oh323_pvt *pvt) |
| static int | answer_call (unsigned call_reference, const char *token) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"The NuFone Network's OpenH323 Channel Driver",.load=load_module,.unload=unload_module,.reload=reload,) | |
| AST_MUTEX_DEFINE_STATIC (h323_reload_lock) | |
| AST_MUTEX_DEFINE_STATIC (caplock) | |
| AST_MUTEX_DEFINE_STATIC (monlock) | |
| AST_MUTEX_DEFINE_STATIC (iflock) | |
| static struct oh323_alias * | build_alias (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
| static struct oh323_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
| static struct oh323_user * | build_user (char *name, struct ast_variable *v, struct ast_variable *alt, int realtime) |
| static void | chan_ringing (unsigned call_reference, const char *token) |
| static void | cleanup_call_details (call_details_t *cd) |
| static void | cleanup_connection (unsigned call_reference, const char *call_token) |
| static void | connection_made (unsigned call_reference, const char *token) |
| static char * | convertcap (int cap) |
| static int | create_addr (struct oh323_pvt *pvt, char *opeer) |
| static void | delete_aliases (void) |
| static void | delete_users (void) |
| static void * | do_monitor (void *data) |
| static struct rtp_info * | external_rtp_create (unsigned call_reference, const char *token) |
| static struct oh323_alias * | find_alias (const char *source_aliases, int realtime) |
| static struct oh323_pvt * | find_call_locked (int call_reference, const char *token) |
| static struct oh323_peer * | find_peer (const char *peer, struct sockaddr_in *sin, int realtime) |
| static struct oh323_user * | find_user (const call_details_t *cd, int realtime) |
| static int | h323_do_debug (int fd, int argc, char *argv[]) |
| static int | h323_do_reload (void) |
| static int | h323_do_trace (int fd, int argc, char *argv[]) |
| static int | h323_ep_hangup (int fd, int argc, char *argv[]) |
| static int | h323_gk_cycle (int fd, int argc, char *argv[]) |
| static int | h323_no_debug (int fd, int argc, char *argv[]) |
| static int | h323_no_trace (int fd, int argc, char *argv[]) |
| static int | h323_reload (int fd, int argc, char *argv[]) |
| static int | h323_tokens_show (int fd, int argc, char *argv[]) |
| static void | hangup_connection (unsigned int call_reference, const char *token, int cause) |
| static enum ast_module_load_result | load_module (void) |
| static int | oh323_addrcmp (struct sockaddr_in addr, struct sockaddr_in *sin) |
| static int | oh323_addrcmp_str (struct in_addr inaddr, char *addr) |
| static struct oh323_pvt * | oh323_alloc (int callid) |
| static int | oh323_answer (struct ast_channel *c) |
| static int | oh323_call (struct ast_channel *c, char *dest, int timeout) |
| static void | oh323_destroy (struct oh323_pvt *pvt) |
| static void | oh323_destroy_alias (struct oh323_alias *alias) |
| static void | oh323_destroy_peer (struct oh323_peer *peer) |
| static void | oh323_destroy_user (struct oh323_user *user) |
| static int | oh323_digit_begin (struct ast_channel *c, char digit) |
| static int | oh323_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
| static int | oh323_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
| static enum ast_rtp_get_result | oh323_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
| static enum ast_rtp_get_result | oh323_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp) |
| static int | oh323_hangup (struct ast_channel *c) |
| static int | oh323_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
| static struct ast_frame * | oh323_read (struct ast_channel *c) |
| static struct ast_channel * | oh323_request (const char *type, int format, void *data, int *cause) |
| static struct ast_frame * | oh323_rtp_read (struct oh323_pvt *pvt) |
| static int | oh323_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
| static int | oh323_simulate_dtmf_end (void *data) |
| static void | oh323_update_info (struct ast_channel *c) |
| static int | oh323_write (struct ast_channel *c, struct ast_frame *frame) |
| static int | progress (unsigned call_reference, const char *token, int inband) |
| static void | prune_peers (void) |
| static struct oh323_alias * | realtime_alias (const char *alias) |
| static struct oh323_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
| static struct oh323_user * | realtime_user (const call_details_t *cd) |
| static int | receive_digit (unsigned call_reference, char digit, const char *token, int duration) |
| static const char * | redirectingreason2str (int redirectingreason) |
| static int | reload (void) |
| static int | reload_config (int is_reload) |
| static void | remote_hold (unsigned call_reference, const char *token, int is_hold) |
| static int | restart_monitor (void) |
| Start the channel monitor thread. | |
| static void | set_dtmf_payload (unsigned call_reference, const char *token, int payload, int is_cisco) |
| static void | set_local_capabilities (unsigned call_reference, const char *token) |
| static void | set_peer_capabilities (unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs) |
| static call_options_t * | setup_incoming_call (call_details_t *cd) |
| static int | setup_outgoing_call (call_details_t *cd) |
| static void | setup_rtp_connection (unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt) |
| static int | unload_module (void) |
| static int | update_common_options (struct ast_variable *v, struct call_options *options) |
| static int | update_state (struct oh323_pvt *pvt, int state, int signal) |
Variables | |
| static int | acceptAnonymous = 1 |
| static struct ast_alias_list | aliasl |
| static struct sockaddr_in | bindaddr |
| static struct ast_cli_entry | cli_h323 [] |
| static struct ast_cli_entry | cli_h323_debug_deprecated |
| static struct ast_cli_entry | cli_h323_gk_cycle_deprecated |
| static struct ast_cli_entry | cli_h323_hangup_deprecated |
| static struct ast_cli_entry | cli_h323_no_debug_deprecated |
| static struct ast_cli_entry | cli_h323_no_trace_deprecated |
| static struct ast_cli_entry | cli_h323_reload |
| static struct ast_cli_entry | cli_h323_reload_deprecated |
| static struct ast_cli_entry | cli_h323_show_tokens_deprecated |
| static struct ast_cli_entry | cli_h323_trace_deprecated |
| static const char | config [] = "h323.conf" |
| static char | debug_usage [] |
| static char | default_context [AST_MAX_CONTEXT] = "default" |
| static struct ast_jb_conf | default_jbconf |
| static char | gatekeeper [100] |
| static int | gatekeeper_disable = 1 |
| static int | gatekeeper_discover = 0 |
| static int | gkroute = 0 |
| static struct ast_jb_conf | global_jbconf |
| static call_options_t | global_options |
| static char | h323_reload_usage [] |
| static int | h323_reloading = 0 |
| static int | h323_signalling_port = 1720 |
| int | h323debug |
| oh323_pvt * | iflist |
| static struct io_context * | io |
| static pthread_t | monitor_thread = AST_PTHREADT_NULL |
| static char | no_debug_usage [] |
| static char | no_trace_usage [] |
| static struct ast_rtp_protocol | oh323_rtp |
| static const struct ast_channel_tech | oh323_tech |
| answer_call_cb | on_answer_call |
| chan_ringing_cb | on_chan_ringing |
| clear_con_cb | on_connection_cleared |
| con_established_cb | on_connection_established |
| on_rtp_cb | on_external_rtp_create |
| hangup_cb | on_hangup |
| onhold_cb | on_hold |
| setup_incoming_cb | on_incoming_call |
| setup_outbound_cb | on_outgoing_call |
| progress_cb | on_progress |
| receive_digit_cb | on_receive_digit |
| rfc2833_cb | on_set_rfc2833_payload |
| setcapabilities_cb | on_setcapabilities |
| setpeercapabilities_cb | on_setpeercapabilities |
| start_rtp_cb | on_start_rtp_channel |
| static struct ast_peer_list | peerl |
| static struct sched_context * | sched |
| static char | secret [50] |
| static char | show_cycle_usage [] |
| static char | show_hangup_usage [] |
| static char | show_tokens_usage [] |
| static const char | tdesc [] = "The NuFone Network's Open H.323 Channel Driver" |
| static int | tos = 0 |
| static char | trace_usage [] |
| static unsigned int | unique = 0 |
| static int | userbyalias = 1 |
| static struct ast_user_list | userl |
|
|
Definition at line 141 of file chan_h323.c. Referenced by reload_config(). |
|
|
Definition at line 451 of file chan_h323.c. References ast_channel_lock, ast_channel_unlock, ast_dsp_free(), ast_log(), ast_mutex_destroy(), ast_mutex_unlock(), ast_rtp_destroy(), ast_sched_del(), oh323_pvt::cd, cleanup_call_details(), oh323_pvt::DTMFsched, free, iflist, oh323_pvt::lock, LOG_DEBUG, LOG_WARNING, oh323_pvt::next, oh323_pvt::owner, oh323_pvt::rtp, sched, ast_channel::tech_pvt, and oh323_pvt::vad. Referenced by do_monitor(), and oh323_destroy(). 00452 { 00453 struct oh323_pvt *cur, *prev = NULL; 00454 00455 if (pvt->DTMFsched >= 0) { 00456 ast_sched_del(sched, pvt->DTMFsched); 00457 pvt->DTMFsched = -1; 00458 } 00459 00460 if (pvt->rtp) { 00461 ast_rtp_destroy(pvt->rtp); 00462 } 00463 00464 /* Free dsp used for in-band DTMF detection */ 00465 if (pvt->vad) { 00466 ast_dsp_free(pvt->vad); 00467 } 00468 cleanup_call_details(&pvt->cd); 00469 00470 /* Unlink us from the owner if we have one */ 00471 if (pvt->owner) { 00472 ast_channel_lock(pvt->owner); 00473 if (h323debug) 00474 ast_log(LOG_DEBUG, "Detaching from %s\n", pvt->owner->name); 00475 pvt->owner->tech_pvt = NULL; 00476 ast_channel_unlock(pvt->owner); 00477 } 00478 cur = iflist; 00479 while(cur) { 00480 if (cur == pvt) { 00481 if (prev) 00482 prev->next = cur->next; 00483 else 00484 iflist = cur->next; 00485 break; 00486 } 00487 prev = cur; 00488 cur = cur->next; 00489 } 00490 if (!cur) { 00491 ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur); 00492 } else { 00493 ast_mutex_unlock(&pvt->lock); 00494 ast_mutex_destroy(&pvt->lock); 00495 free(pvt); 00496 } 00497 }
|
|
||||||||||||||||
|
Definition at line 1006 of file chan_h323.c. References accountcode, oh323_pvt::accountcode, ast_channel::amaflags, oh323_pvt::amaflags, ast_best_codec(), ast_channel_alloc(), ast_codec_choose(), ast_dsp_new(), ast_dsp_set_features(), ast_hangup(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_udptl_fd(), oh323_pvt::cd, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, cid_name, ast_callerid::cid_num, cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_ton, oh323_pvt::context, ast_channel::context, DSP_FEATURE_DTMF_DETECT, oh323_pvt::exten, ast_channel::exten, ast_channel::fds, fmt, oh323_pvt::jointcapability, oh323_pvt::lock, LOG_WARNING, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_tech, oh323_pvt::options, oh323_pvt::owner, pbx_builtin_setvar_helper(), ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, redirectingreason2str(), ast_channel::rings, oh323_pvt::rtp, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::transfercapability, oh323_pvt::vad, and ast_channel::writeformat. Referenced by answer_call(), and oh323_request(). 01007 { 01008 struct ast_channel *ch; 01009 char *cid_num, *cid_name; 01010 int fmt; 01011 01012 if (!ast_strlen_zero(pvt->options.cid_num)) 01013 cid_num = pvt->options.cid_num; 01014 else 01015 cid_num = pvt->cd.call_source_e164; 01016 01017 if (!ast_strlen_zero(pvt->options.cid_name)) 01018 cid_name = pvt->options.cid_name; 01019 else 01020 cid_name = pvt->cd.call_source_name; 01021 01022 /* Don't hold a oh323_pvt lock while we allocate a chanel */ 01023 ast_mutex_unlock(&pvt->lock); 01024 ch = ast_channel_alloc(1, state, cid_num, cid_name, "H323/%s", host); 01025 /* Update usage counter */ 01026 ast_module_ref(ast_module_info->self); 01027 ast_mutex_lock(&pvt->lock); 01028 if (ch) { 01029 ch->tech = &oh323_tech; 01030 if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability)) 01031 fmt = global_options.capability; 01032 ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/; 01033 pvt->nativeformats = ch->nativeformats; 01034 fmt = ast_best_codec(ch->nativeformats); 01035 ch->writeformat = fmt; 01036 ch->rawwriteformat = fmt; 01037 ch->readformat = fmt; 01038 ch->rawreadformat = fmt; 01039 #if 0 01040 ch->fds[0] = ast_rtp_fd(pvt->rtp); 01041 ch->fds[1] = ast_rtcp_fd(pvt->rtp); 01042 #endif 01043 #ifdef VIDEO_SUPPORT 01044 if (pvt->vrtp) { 01045 ch->fds[2] = ast_rtp_fd(pvt->vrtp); 01046 ch->fds[3] = ast_rtcp_fd(pvt->vrtp); 01047 } 01048 #endif 01049 #ifdef T38_SUPPORT 01050 if (pvt->udptl) { 01051 ch->fds[4] = ast_udptl_fd(pvt->udptl); 01052 } 01053 #endif 01054 if (state == AST_STATE_RING) { 01055 ch->rings = 1; 01056 } 01057 /* Allocate dsp for in-band DTMF support */ 01058 if (pvt->options.dtmfmode & H323_DTMF_INBAND) { 01059 pvt->vad = ast_dsp_new(); 01060 ast_dsp_set_features(pvt->vad, DSP_FEATURE_DTMF_DETECT); 01061 } 01062 /* Register channel functions. */ 01063 ch->tech_pvt = pvt; 01064 /* Set the owner of this channel */ 01065 pvt->owner = ch; 01066 01067 ast_copy_string(ch->context, pvt->context, sizeof(ch->context)); 01068 ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten)); 01069 ch->priority = 1; 01070 if (!ast_strlen_zero(pvt->accountcode)) { 01071 ast_string_field_set(ch, accountcode, pvt->accountcode); 01072 } 01073 if (pvt->amaflags) { 01074 ch->amaflags = pvt->amaflags; 01075 } 01076 01077 /* Don't use ast_set_callerid() here because it will 01078 * generate a needless NewCallerID event */ 01079 ch->cid.cid_num = ast_strdup(cid_num); 01080 ch->cid.cid_ani = ast_strdup(cid_num); 01081 ch->cid.cid_name = ast_strdup(cid_name); 01082 01083 if (pvt->cd.redirect_reason >= 0) { 01084 ch->cid.cid_rdnis = ast_strdup(pvt->cd.redirect_number); 01085 pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason)); 01086 } 01087 ch->cid.cid_pres = pvt->cd.presentation; 01088 ch->cid.cid_ton = pvt->cd.type_of_number; 01089 01090 if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) { 01091 ch->cid.cid_dnid = strdup(pvt->exten); 01092 } 01093 if (pvt->cd.transfer_capability >= 0) 01094 ch->transfercapability = pvt->cd.transfer_capability; 01095 if (state != AST_STATE_DOWN) { 01096 if (ast_pbx_start(ch)) { 01097 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name); 01098 ast_hangup(ch); 01099 ch = NULL; 01100 } 01101 } 01102 } else { 01103 ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); 01104 } 01105 return ch; 01106 }
|
|
|
Definition at line 958 of file chan_h323.c. References ast_channel_trylock, ast_channel_unlock, ast_find_ourip(), ast_jb_configure(), ast_log(), ast_mutex_unlock(), ast_null_frame, ast_queue_frame(), ast_rtcp_fd(), ast_rtp_codec_setpref(), ast_rtp_fd(), ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpmap_type(), ast_rtp_setnat(), ast_rtp_settos(), oh323_pvt::dtmf_pt, ast_channel::fds, global_jbconf, io, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, oh323_pvt::options, oh323_pvt::owner, oh323_pvt::peer_prefs, oh323_pvt::peercapability, oh323_pvt::rtp, sched, and oh323_pvt::update_rtp_info. Referenced by external_rtp_create(), and setup_rtp_connection(). 00959 { 00960 struct in_addr our_addr; 00961 00962 if (pvt->rtp) 00963 return 0; 00964 00965 if (ast_find_ourip(&our_addr, bindaddr)) { 00966 ast_mutex_unlock(&pvt->lock); 00967 ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n"); 00968 return -1; 00969 } 00970 pvt->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, our_addr); 00971 if (!pvt->rtp) { 00972 ast_mutex_unlock(&pvt->lock); 00973 ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno)); 00974 return -1; 00975 } 00976 if (h323debug) 00977 ast_log(LOG_DEBUG, "Created RTP channel\n"); 00978 00979 ast_rtp_settos(pvt->rtp, tos); 00980 00981 if (h323debug) 00982 ast_log(LOG_DEBUG, "Setting NAT on RTP to %d\n", pvt->options.nat); 00983 ast_rtp_setnat(pvt->rtp, pvt->options.nat); 00984 00985 if (pvt->dtmf_pt[0] > 0) 00986 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt[0], "audio", "telephone-event", 0); 00987 if (pvt->dtmf_pt[1] > 0) 00988 ast_rtp_set_rtpmap_type(pvt->rtp, pvt->dtmf_pt[1], "audio", "cisco-telephone-event", 0); 00989 00990 if (pvt->peercapability) 00991 ast_rtp_codec_setpref(pvt->rtp, &pvt->peer_prefs); 00992 00993 if (pvt->owner && !ast_channel_trylock(pvt->owner)) { 00994 ast_jb_configure(pvt->owner, &global_jbconf); 00995 pvt->owner->fds[0] = ast_rtp_fd(pvt->rtp); 00996 pvt->owner->fds[1] = ast_rtcp_fd(pvt->rtp); 00997 ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */ 00998 ast_channel_unlock(pvt->owner); 00999 } else 01000 pvt->update_rtp_info = 1; 01001 01002 return 0; 01003 }
|
|
||||||||||||
|
||||||||||||
|
Call-back function to start PBX when OpenH323 ready to serve incoming call Returns 1 on success Definition at line 2223 of file chan_h323.c. References __oh323_new(), AST_CAUSE_UNALLOCATED, ast_exists_extension(), ast_log(), ast_mutex_unlock(), AST_STATE_RINGING, oh323_pvt::cd, oh323_pvt::context, oh323_pvt::exten, find_call_locked(), h323debug, oh323_pvt::lock, LOG_DEBUG, LOG_ERROR, and LOG_NOTICE. Referenced by load_module(). 02224 { 02225 struct oh323_pvt *pvt; 02226 struct ast_channel *c = NULL; 02227 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten; 02228 char tmp_exten[sizeof(pvt->exten)]; 02229 02230 if (h323debug) 02231 ast_log(LOG_DEBUG, "Preparing Asterisk to answer for %s\n", token); 02232 02233 /* Find the call or allocate a private structure if call not found */ 02234 pvt = find_call_locked(call_reference, token); 02235 if (!pvt) { 02236 ast_log(LOG_ERROR, "Something is wrong: answer_call\n"); 02237 return 0; 02238 } 02239 /* Check if requested extension@context pair exists in the dialplan */ 02240 ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten)); 02241 02242 /* Try to find best extension in specified context */ 02243 if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) { 02244 if (tmp_exten[0] == 's') 02245 try_exten = ext_s; 02246 else if (tmp_exten[0] == 'i') 02247 try_exten = ext_i; 02248 else 02249 try_exten = ext_original; 02250 } else 02251 try_exten = ext_original; 02252 do { 02253 if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL)) 02254 break; 02255 switch (try_exten) { 02256 case ext_original: 02257 tmp_exten[0] = 's'; 02258 tmp_exten[1] = '\0'; 02259 try_exten = ext_s; 02260 break; 02261 case ext_s: 02262 tmp_exten[0] = 'i'; 02263 try_exten = ext_i; 02264 break; 02265 case ext_i: 02266 try_exten = ext_notexists; 02267 break; 02268 default: 02269 break; 02270 } 02271 } while (try_exten != ext_notexists); 02272 02273 /* Drop the call if we don't have <exten>, s and i extensions */ 02274 if (try_exten == ext_notexists) { 02275 ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context); 02276 ast_mutex_unlock(&pvt->lock); 02277 h323_clear_call(token, AST_CAUSE_UNALLOCATED); 02278 return 0; 02279 } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) { 02280 if (h323debug) 02281 ast_log(LOG_DEBUG, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context); 02282 ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten)); 02283 } 02284 02285 /* allocate a channel and tell asterisk about it */ 02286 c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token); 02287 02288 /* And release when done */ 02289 ast_mutex_unlock(&pvt->lock); 02290 if (!c) { 02291 ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n"); 02292 return 0; 02293 } 02294 return 1; 02295 }
|
|
||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
Protect the interface list (oh323_pvt) |
| ||||||||||||||||||||