Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:04 2007

Asterisk developer's documentation :: Codename Pineapple


chan_h323.c File Reference


Detailed Description

This file is part of the chan_h323 driver for Asterisk.

Author:
Jeremy McNamara
See also

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_pvtfind_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_pvtoh323_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_frameoh323_read (struct ast_channel *c)
static struct ast_channeloh323_request (const char *type, int format, void *data, int *cause)
static struct ast_frameoh323_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_pvtiflist
static struct io_contextio
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_contextsched
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


Define Documentation

#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)
 

Definition at line 141 of file chan_h323.c.

Referenced by reload_config().


Function Documentation

static void __oh323_destroy struct oh323_pvt pvt  )  [static]
 

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 }

static struct ast_channel* __oh323_new struct oh323_pvt pvt,
int  state,
const char *  host
[static]
 

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 }

static int __oh323_rtp_create struct oh323_pvt pvt  )  [static]
 

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 }

static void __oh323_update_info struct ast_channel c,
struct oh323_pvt pvt
[static]
 

Definition at line 339 of file chan_h323.c.

References ast_channel::_softhangup, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_jb_configure(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup(), ast_rtcp_fd(), ast_rtp_fd(), ast_sched_add(), ast_sched_del(), ast_set_read_format(), ast_set_write_format(), ast_setstate(), AST_SOFTHANGUP_DEV, oh323_pvt::curDTMF, oh323_pvt::DTMFsched, ast_channel::fds, ast_frame::frametype, global_jbconf, oh323_pvt::hangupcause, ast_channel::hangupcause, LOG_DEBUG, LOG_DTMF, oh323_pvt::nativeformats, ast_channel::nativeformats, oh323_pvt::needhangup, oh323_pvt::newcontrol, oh323_pvt::newdigit, oh323_pvt::newduration, oh323_pvt::newstate, oh323_simulate_dtmf_end(), oh323_pvt::owner, ast_channel::readformat, oh323_pvt::rtp, sched, ast_frame::subclass, oh323_pvt::update_rtp_info, and ast_channel::writeformat.

Referenced by oh323_read(), oh323_update_info(), and oh323_write().

00340 {
00341    if (c->nativeformats != pvt->nativeformats) {
00342       if (h323debug)
00343          ast_log(LOG_DEBUG, "Preparing %s for new native format\n", c->name);
00344       c->nativeformats = pvt->nativeformats;
00345       ast_set_read_format(c, c->readformat);
00346       ast_set_write_format(c, c->writeformat);
00347    }
00348    if (pvt->needhangup) {
00349       if (h323debug)
00350          ast_log(LOG_DEBUG, "Process pending hangup for %s\n", c->name);
00351       c->_softhangup |= AST_SOFTHANGUP_DEV;
00352       c->hangupcause = pvt->hangupcause;
00353       ast_queue_hangup(c);
00354       pvt->needhangup = 0;
00355       pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1;
00356    }
00357    if (pvt->newstate >= 0) {
00358       ast_setstate(c, pvt->newstate);
00359       pvt->newstate = -1;
00360    }
00361    if (pvt->newcontrol >= 0) {
00362       ast_queue_control(c, pvt->newcontrol);
00363       pvt->newcontrol = -1;
00364    }
00365    if (pvt->newdigit >= 0) {
00366       struct ast_frame f = {
00367          .frametype = AST_FRAME_DTMF_END,
00368          .subclass = pvt->newdigit,
00369          .samples = pvt->newduration * 8,
00370          .src = "UPDATE_INFO",
00371       };
00372       if (pvt->newdigit == ' ') {      /* signalUpdate message */
00373          f.subclass = pvt->curDTMF;
00374          if (pvt->DTMFsched >= 0) {
00375             ast_sched_del(sched, pvt->DTMFsched);
00376             pvt->DTMFsched = -1;
00377          }
00378       } else {                /* Regular input or signal message */
00379          if (pvt->newduration) {    /* This is a signal, signalUpdate follows */
00380             f.frametype = AST_FRAME_DTMF_BEGIN;
00381             if (pvt->DTMFsched >= 0)
00382                ast_sched_del(sched, pvt->DTMFsched);
00383             pvt->DTMFsched = ast_sched_add(sched, pvt->newduration, oh323_simulate_dtmf_end, pvt);
00384             if (h323debug)
00385                ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched);
00386          }
00387          pvt->curDTMF = pvt->newdigit;
00388       }
00389       ast_queue_frame(c, &f);
00390       pvt->newdigit = -1;
00391    }
00392    if (pvt->update_rtp_info > 0) {
00393       if (pvt->rtp) {
00394          ast_jb_configure(c, &global_jbconf);
00395          c->fds[0] = ast_rtp_fd(pvt->rtp);
00396          c->fds[1] = ast_rtcp_fd(pvt->rtp);
00397          ast_queue_frame(pvt->owner, &ast_null_frame);   /* Tell Asterisk to apply changes */
00398       }
00399       pvt->update_rtp_info = -1;
00400    }
00401 }

static int answer_call unsigned  call_reference,
const char *  token
[static]
 

Call-back function to start PBX when OpenH323 ready to serve incoming call

Returns 1 on success

Definition at line 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 }

AST_MODULE_INFO ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
"The NuFone Network's OpenH323 Channel Driver"  ,
load = load_module,
unload = unload_module,
reload = reload
 

AST_MUTEX_DEFINE_STATIC h323_reload_lock   ) 
 

AST_MUTEX_DEFINE_STATIC caplock   ) 
 

AST_MUTEX_DEFINE_STATIC monlock   ) 
 

AST_MUTEX_DEFINE_STATIC iflock   ) 
 

Protect the interface list (oh323_pvt)

static struct oh323_alias* build_alias const char *  name,
struct ast_variable v,
struct ast_variable alt,
int  realtime
[static]