chan_ooh323.h File Reference

#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.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 <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/causes.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/stringfields.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
#include "asterisk/udptl.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/format_cache.h"
#include "ootypes.h"
#include "ooUtils.h"
#include "ooCapability.h"
#include "oochannels.h"
#include "ooh323ep.h"
#include "ooh323cDriver.h"
#include "ooCalls.h"
#include "ooq931.h"
#include "ooStackCmds.h"
#include "ooGkClient.h"

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void close_rtp_connection (ooCallData *call)
void close_udptl_connection (ooCallData *call)
int configure_local_rtp (struct ooh323_pvt *p, ooCallData *call)
int delete_peers (void)
int delete_users (void)
struct ooh323_peerfind_peer (const char *name, int port)
struct ooh323_userfind_user (const char *name, const char *ip)
EXTERN char * handle_cli_ooh323_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ooh323_convert_hangupcause_asteriskToH323 (int cause)
int ooh323_convert_hangupcause_h323ToAsterisk (int cause)
int ooh323_convertAsteriskCapToH323Cap (struct ast_format *format)
void ooh323_delete_peer (struct ooh323_peer *peer)
int ooh323_destroy (struct ooh323_pvt *p)
int ooh323_onReceivedDigit (OOH323CallData *call, const char *digit)
int ooh323_onReceivedSetup (ooCallData *call, Q931Message *pmsg)
struct ast_frameooh323_rtp_read (struct ast_channel *ast, struct ooh323_pvt *p)
void ooh323_set_read_format (ooCallData *call, struct ast_format *fmt)
void ooh323_set_write_format (ooCallData *call, struct ast_format *fmt, int txframes)
int reload_config (int reload)
int restart_monitor (void)
 Start the channel monitor thread.
void setup_rtp_connection (ooCallData *call, const char *remoteIp, int remotePort)
void setup_udptl_connection (ooCallData *call, const char *remoteIp, int remotePort)
int update_our_aliases (ooCallData *call, struct ooh323_pvt *p)


Function Documentation

void close_rtp_connection ( ooCallData *  call  ) 

Definition at line 4755 of file chan_ooh323.c.

References ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_stop(), ast_verb, find_call, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, and ooh323_pvt::rtp.

Referenced by ooh323c_stop_transmit_channel().

04756 {
04757    struct ooh323_pvt *p = NULL;
04758 
04759    if(gH323Debug)
04760       ast_verb(0, "---   close_rtp_connection\n");
04761 
04762    p = find_call(call);
04763    if (!p) {
04764       ast_log(LOG_ERROR, "Couldn't find matching call to close rtp "
04765                          "connection\n");
04766       return;
04767    }
04768    ast_mutex_lock(&p->lock);
04769    if (p->rtp) {
04770       ast_rtp_instance_stop(p->rtp);
04771    }
04772    ast_mutex_unlock(&p->lock);
04773 
04774    if(gH323Debug)
04775       ast_verb(0, "+++   close_rtp_connection\n");
04776 
04777    return;
04778 }

void close_udptl_connection ( ooCallData *  call  ) 

Definition at line 4846 of file chan_ooh323.c.

References ast_channel_trylock, ast_channel_unlock, AST_CONTROL_T38_PARAMETERS, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_queue_control_data(), AST_T38_TERMINATED, ast_verb, DEADLOCK_AVOIDANCE, find_call, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, ooh323_pvt::owner, ast_control_t38_parameters::request_response, T38_ENABLED, ooh323_pvt::t38_tx_enable, and ooh323_pvt::t38support.

Referenced by ooh323c_stop_transmit_datachannel().

04847 {
04848    struct ooh323_pvt *p = NULL;
04849 
04850       if(gH323Debug)
04851       ast_verb(0, "---   close_udptl_connection\n");
04852 
04853    p = find_call(call);
04854    if (!p) {
04855             ast_log(LOG_ERROR, "Couldn't find matching call to close udptl "
04856                          "connection\n");
04857       return;
04858    }
04859    ast_mutex_lock(&p->lock);
04860    if (p->owner) {
04861       while (p->owner && ast_channel_trylock(p->owner)) {
04862          ast_debug(1, "Failed to grab lock, trying again\n");
04863          DEADLOCK_AVOIDANCE(&p->lock);
04864       }
04865       if (!p->owner) {
04866          ast_mutex_unlock(&p->lock);
04867          ast_log(LOG_ERROR, "Channel has no owner\n");
04868          return;
04869       }
04870    } else {
04871       ast_mutex_unlock(&p->lock);
04872       ast_log(LOG_ERROR, "Channel has no owner\n");
04873       return;
04874    }
04875 
04876    p->t38_tx_enable = 0;
04877    if (p->t38support == T38_ENABLED) {
04878       struct ast_control_t38_parameters parameters = { .request_response = 0 };
04879       parameters.request_response = AST_T38_TERMINATED;
04880       ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
04881    }
04882 
04883    ast_channel_unlock(p->owner);
04884    ast_mutex_unlock(&p->lock);
04885 
04886       if(gH323Debug)
04887       ast_verb(0, "+++   close_udptl_connection\n");
04888 
04889    return;
04890 }

int configure_local_rtp ( struct ooh323_pvt p,
ooCallData *  call 
)

Definition at line 4544 of file chan_ooh323.c.

References ao2_ref, ast_channel_set_fd(), ast_channel_trylock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_format_cap_count(), ast_format_cap_get_format(), ast_format_cap_get_framing(), ast_log, ast_mutex_unlock, ast_parse_arg(), ast_rtp_codecs_payloads_set_rtpmap_type(), ast_rtp_codecs_set_framing(), ast_rtp_instance_fd(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_local_address(), ast_rtp_instance_new(), ast_rtp_instance_set_prop(), ast_rtp_instance_set_qos(), ast_rtp_instance_set_timeout(), AST_RTP_PROPERTY_DTMF, AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_RTCP, ast_sockaddr_copy(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_udptl_fd(), ast_udptl_get_us(), ast_udptl_new_with_bindaddr(), ast_udptl_set_far_max_datagram(), ast_verb, bindaddr, ooh323_pvt::cap, DEADLOCK_AVOIDANCE, ooh323_pvt::dtmfcodec, ooh323_pvt::dtmfmode, errno, format, gH323Debug, gTOS, H323_DTMF_CISCO, H323_DTMF_RFC2833, ooh323_pvt::lock, LOG_ERROR, LOG_WARNING, ooh323_pvt::nat, NULL, ooh323_convertAsteriskCapToH323Cap(), ooh323_pvt::owner, PARSE_ADDR, ooh323_pvt::rtdrcount, ooh323_pvt::rtdrinterval, ooh323_pvt::rtp, ooh323_pvt::rtptimeout, and ooh323_pvt::udptl.

Referenced by onNewCallCreated(), onOutgoingCall(), and ooh323_onReceivedSetup().

04545 {
04546    char lhost[INET6_ADDRSTRLEN];
04547    unsigned lport = 0;
04548    struct ast_sockaddr tmp;
04549    ooMediaInfo mediaInfo;
04550    int x;
04551 
04552    if (gH323Debug)
04553       ast_verb(0, "---   configure_local_rtp\n");
04554 
04555    memset(&mediaInfo, 0, sizeof(mediaInfo));
04556    if (ast_parse_arg(call->localIP, PARSE_ADDR, &tmp)) {
04557       ast_sockaddr_copy(&tmp, &bindaddr);
04558    }
04559    if (!(p->rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
04560       ast_log(LOG_WARNING, "Unable to create RTP session: %s\n",
04561          strerror(errno));
04562       return 0;
04563    }
04564 
04565    ast_rtp_instance_set_qos(p->rtp, gTOS, 0, "ooh323-rtp");
04566 
04567    if (!(p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &tmp))) {
04568       ast_log(LOG_WARNING, "Unable to create UDPTL session: %s\n",
04569          strerror(errno));
04570       return 0;
04571    }
04572    ast_udptl_set_far_max_datagram(p->udptl, 144);
04573 
04574    if (p->owner) {
04575       while (p->owner && ast_channel_trylock(p->owner)) {
04576          ast_debug(1,"Failed to grab lock, trying again\n");
04577          DEADLOCK_AVOIDANCE(&p->lock);
04578       }
04579       if (!p->owner) {
04580          ast_mutex_unlock(&p->lock);
04581          ast_log(LOG_ERROR, "Channel has no owner\n");
04582          return 0;
04583       }
04584    } else {
04585       ast_log(LOG_ERROR, "Channel has no owner\n");
04586       return 0;
04587    }
04588 
04589    ast_channel_set_fd(p->owner, 0, ast_rtp_instance_fd(p->rtp, 0));
04590    ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1));
04591    ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl));
04592 
04593    ast_channel_unlock(p->owner);
04594 
04595    if (p->rtp) {
04596       if (p->cap) {
04597          ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(p->rtp),
04598             ast_format_cap_get_framing(p->cap));
04599       }
04600       if (p->nat) {
04601          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, 1);
04602       }
04603       if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
04604          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
04605          ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
04606              p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
04607       }
04608       if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
04609          ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
04610          ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
04611              p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
04612       }
04613       /* figure out our local RTP port and tell the H.323 stack about it*/
04614       ast_rtp_instance_get_local_address(p->rtp, &tmp);
04615       ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
04616       lport = ast_sockaddr_port(&tmp);
04617 
04618       if (p->rtptimeout) {
04619          ast_rtp_instance_set_timeout(p->rtp, p->rtptimeout);
04620       }
04621       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1);
04622       
04623    }
04624 
04625    if (p->rtdrcount) {
04626       if (gH323Debug)
04627          ast_verb(0, "Setup RTDR info: %d, %d\n", p->rtdrinterval, p->rtdrcount);
04628       call->rtdrInterval = p->rtdrinterval;
04629       call->rtdrCount = p->rtdrcount;
04630    }
04631 
04632 
04633    ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
04634    mediaInfo.lMediaPort = lport;
04635    mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort + 1;
04636    for (x = 0; x < ast_format_cap_count(p->cap); x++) {
04637       struct ast_format *format = ast_format_cap_get_format(p->cap, x);
04638 
04639       strcpy(mediaInfo.dir, "transmit");
04640       mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(format);
04641       ooAddMediaInfo(call, mediaInfo);
04642       strcpy(mediaInfo.dir, "receive");
04643       ooAddMediaInfo(call, mediaInfo);
04644       if (mediaInfo.cap == OO_G729A) {
04645          strcpy(mediaInfo.dir, "transmit");
04646          mediaInfo.cap = OO_G729;
04647          ooAddMediaInfo(call, mediaInfo);
04648          strcpy(mediaInfo.dir, "receive");
04649          ooAddMediaInfo(call, mediaInfo);
04650 
04651          strcpy(mediaInfo.dir, "transmit");
04652          mediaInfo.cap = OO_G729B;
04653          ooAddMediaInfo(call, mediaInfo);
04654          strcpy(mediaInfo.dir, "receive");
04655          ooAddMediaInfo(call, mediaInfo);
04656       }
04657 
04658       ao2_ref(format, -1);
04659    }
04660 
04661    if (p->udptl) {
04662       ast_udptl_get_us(p->udptl, &tmp);
04663       ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
04664       lport = ast_sockaddr_port(&tmp);
04665       ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
04666       mediaInfo.lMediaPort = lport;
04667       mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
04668       mediaInfo.cap = OO_T38;
04669       strcpy(mediaInfo.dir, "transmit");
04670       ooAddMediaInfo(call, mediaInfo);
04671       strcpy(mediaInfo.dir, "receive");
04672       ooAddMediaInfo(call, mediaInfo);
04673    }
04674 
04675    if (gH323Debug)
04676       ast_verb(0, "+++   configure_local_rtp\n");
04677 
04678    return 1;
04679 }

int delete_peers ( void   ) 

Definition at line 4175 of file chan_ooh323.c.

References ast_free, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_peer_list::lock, ooh323_peer::next, NULL, peerl, and ast_peer_list::peers.

Referenced by reload_config(), and unload_module().

04176 {
04177    struct ooh323_peer *cur = NULL, *prev = NULL;
04178    ast_mutex_lock(&peerl.lock);
04179    cur = peerl.peers;
04180    while (cur) {
04181       prev = cur;
04182       cur = cur->next;
04183 
04184       ast_mutex_destroy(&prev->lock);
04185       ast_free(prev->h323id);
04186       ast_free(prev->email);
04187       ast_free(prev->url);
04188       ast_free(prev->e164);
04189       if(prev->rtpmask) {
04190       ast_mutex_lock(&prev->rtpmask->lock);
04191       prev->rtpmask->inuse--;
04192       ast_mutex_unlock(&prev->rtpmask->lock);
04193       if (prev->rtpmask->inuse == 0) {
04194          regfree(&prev->rtpmask->regex);
04195          ast_mutex_destroy(&prev->rtpmask->lock);
04196          ast_free(prev->rtpmask);
04197             }
04198       }
04199       ast_free(prev);
04200 
04201       if (cur == peerl.peers) {
04202          break;
04203       }
04204    }
04205    peerl.peers = NULL;
04206    ast_mutex_unlock(&peerl.lock);
04207    return 0;
04208 }

int delete_users ( void   ) 

Definition at line 4210 of file chan_ooh323.c.

References ao2_cleanup, ast_free, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_user_list::lock, ooh323_user::next, NULL, userl, and ast_user_list::users.

Referenced by __unload_module(), reload(), reload_config(), set_config_destroy(), and unload_module().

04211 {
04212    struct ooh323_user *cur = NULL, *prev = NULL;
04213    ast_mutex_lock(&userl.lock);
04214    cur = userl.users;
04215    while (cur) {
04216       prev = cur;
04217       cur = cur->next;
04218       ast_mutex_destroy(&prev->lock);
04219 
04220             if(prev->rtpmask) {
04221          ast_mutex_lock(&prev->rtpmask->lock);
04222          prev->rtpmask->inuse--;
04223          ast_mutex_unlock(&prev->rtpmask->lock);
04224          if (prev->rtpmask->inuse == 0) {
04225             regfree(&prev->rtpmask->regex);
04226             ast_mutex_destroy(&prev->rtpmask->lock);
04227             ast_free(prev->rtpmask);
04228                }
04229             }
04230          ao2_cleanup(prev->cap);
04231       ast_free(prev);
04232       if (cur == userl.users) {
04233          break;
04234       }
04235    }
04236    userl.users = NULL;
04237    ast_mutex_unlock(&userl.lock);
04238    return 0;
04239 }

struct ooh323_peer* find_peer ( const char *  name,
int  port 
) [read]

Definition at line 841 of file chan_ooh323.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verb, ooh323_peer::e164, gH323Debug, ooh323_peer::h323id, ooh323_peer::ip, ast_peer_list::lock, ooh323_peer::name, ooh323_peer::next, peerl, and ast_peer_list::peers.

Referenced by ast_iax2_new(), calltoken_required(), create_addr(), dundi_encrypt(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), handle_command_response(), iax2_devicestate(), ooh323_request(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), and update_registry().

00842 {
00843    struct ooh323_peer *peer;
00844 
00845    if (gH323Debug)
00846       ast_verb(0, "---   find_peer \"%s\"\n", name);
00847 
00848 
00849    ast_mutex_lock(&peerl.lock);
00850    for (peer = peerl.peers; peer; peer = peer->next) {
00851       if (gH323Debug) {
00852          ast_verb(0, "     comparing with \"%s\"\n", peer->ip);
00853       }
00854       if (!strcasecmp(peer->name, name))
00855          break;
00856       if (peer->h323id && !strcasecmp(peer->h323id, name))
00857          break;
00858       if (peer->e164 && !strcasecmp(peer->e164, name))
00859          break;
00860       /*
00861       if (!strcmp(peer->ip, name)) {
00862          if (port > 0 && peer->port == port) { break; }
00863          else if (port <= 0) { break; }
00864       }
00865       */
00866    }
00867    ast_mutex_unlock(&peerl.lock);
00868 
00869    if (gH323Debug) {
00870       if (peer) {
00871          ast_verb(0, "     found matching peer\n");
00872       }
00873       ast_verb(0, "+++   find_peer \"%s\"\n", name);
00874    }
00875 
00876    return peer;      
00877 }

struct ooh323_user* find_user ( const char *  name,
const char *  ip 
) [read]

Definition at line 783 of file chan_ooh323.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verb, gH323Debug, ast_user_list::lock, ooh323_user::mIP, ooh323_user::mUseIP, ooh323_user::name, ooh323_user::next, userl, and ast_user_list::users.

Referenced by acf_mailbox_exists(), acf_vm_info(), admin_exec(), advanced_options(), ast_phoneprov_add_extension(), calltoken_required(), forward_message(), handle_cli_iax2_prune_realtime(), leave_voicemail(), msg_create_from_file(), ooh323_destroy(), ooh323_onReceivedSetup(), play_message_by_id(), pp_each_extension_helper(), requirecalltoken_mark_auto(), vm_authenticate(), vm_box_exists(), vm_execmain(), vm_mailbox_snapshot_create(), vm_msg_forward(), vm_msg_move(), vm_msg_play(), and vm_msg_remove().

00784 {
00785    struct ooh323_user *user;
00786 
00787    if (gH323Debug)
00788       ast_verb(0, "---   find_user: %s, %s\n",name,ip);
00789 
00790    ast_mutex_lock(&userl.lock);
00791 
00792    for (user = userl.users; user; user = user->next) {
00793       if (ip && user->mUseIP && !strcmp(user->mIP, ip)) {
00794          break;
00795       }
00796       if (name && !strcmp(user->name, name)) {
00797          break;
00798       }
00799    }
00800 
00801    ast_mutex_unlock(&userl.lock);
00802 
00803    if (gH323Debug)
00804       ast_verb(0, "+++   find_user\n");
00805 
00806    return user;
00807 }

EXTERN char* handle_cli_ooh323_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)

Definition at line 2732 of file chan_ooh323.c.

References ast_cli_args::argc, ast_mutex_lock, ast_mutex_unlock, ast_verb, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, gH323Debug, h323_reload_lock, h323_reloading, NULL, restart_monitor(), and ast_cli_entry::usage.

02733 {
02734 
02735        switch (cmd) {
02736        case CLI_INIT:
02737                e->command = "ooh323 reload";
02738                e->usage =
02739                        "Usage: ooh323 reload\n"
02740                        "                Reload OOH323 config.\n";
02741                return NULL;
02742        case CLI_GENERATE:
02743                return NULL;
02744        }
02745 
02746        if (a->argc != 2)
02747                return CLI_SHOWUSAGE;
02748 
02749    if (gH323Debug)
02750       ast_verb(0, "---   ooh323_reload\n");
02751 
02752    ast_mutex_lock(&h323_reload_lock);
02753    if (h323_reloading) {
02754       ast_verb(0, "Previous OOH323 reload not yet done\n");
02755    } else {
02756       h323_reloading = 1;
02757    }
02758    ast_mutex_unlock(&h323_reload_lock);
02759    restart_monitor();
02760 
02761    if (gH323Debug)
02762       ast_verb(0, "+++   ooh323_reload\n");
02763 
02764    return 0;
02765 }

int ooh323_convert_hangupcause_asteriskToH323 ( int  cause  ) 

Definition at line 5126 of file chan_ooh323.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_FAILURE, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL, and AST_CAUSE_UNALLOCATED.

Referenced by ooh323_hangup(), and ooh323_onReceivedSetup().

05127 {
05128    switch (cause) {
05129    case AST_CAUSE_CALL_REJECTED:
05130       return OO_REASON_REMOTE_REJECTED;
05131    case AST_CAUSE_UNALLOCATED:
05132       return OO_REASON_NOUSER;
05133    case AST_CAUSE_BUSY:
05134       return OO_REASON_REMOTE_BUSY;
05135    case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL:
05136       return OO_REASON_NOCOMMON_CAPABILITIES;
05137    case AST_CAUSE_CONGESTION:
05138       return OO_REASON_REMOTE_BUSY;
05139    case AST_CAUSE_NO_ANSWER:
05140       return OO_REASON_REMOTE_NOANSWER;
05141    case AST_CAUSE_NORMAL:
05142       return OO_REASON_REMOTE_CLEARED;
05143    case AST_CAUSE_FAILURE:
05144    default:
05145       return OO_REASON_UNKNOWN;
05146    }
05147 
05148    return 0;
05149 
05150 
05151 }

int ooh323_convert_hangupcause_h323ToAsterisk ( int  cause  ) 

Definition at line 5153 of file chan_ooh323.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_FAILURE, AST_CAUSE_NO_ANSWER, AST_CAUSE_NORMAL, and AST_CAUSE_UNALLOCATED.

05154 {
05155    switch (cause) {
05156    case OO_REASON_REMOTE_REJECTED:
05157       return AST_CAUSE_CALL_REJECTED;
05158    case OO_REASON_NOUSER: 
05159       return AST_CAUSE_UNALLOCATED;
05160    case OO_REASON_REMOTE_BUSY:
05161    case OO_REASON_LOCAL_BUSY:
05162       return AST_CAUSE_BUSY;
05163    case OO_REASON_NOCOMMON_CAPABILITIES:  /* No codecs approved */
05164       return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05165    case OO_REASON_REMOTE_CONGESTED:
05166    case OO_REASON_LOCAL_CONGESTED:
05167       return AST_CAUSE_CONGESTION;
05168    case OO_REASON_REMOTE_NOANSWER:
05169       return AST_CAUSE_NO_ANSWER;
05170    case OO_REASON_UNKNOWN: 
05171    case OO_REASON_INVALIDMESSAGE:
05172    case OO_REASON_TRANSPORTFAILURE:
05173       return AST_CAUSE_FAILURE;
05174    case OO_REASON_REMOTE_CLEARED:
05175       return AST_CAUSE_NORMAL;
05176    default:
05177       return AST_CAUSE_NORMAL;
05178    }
05179    /* Never reached */
05180    return 0;
05181 }

int ooh323_convertAsteriskCapToH323Cap ( struct ast_format format  ) 

Definition at line 4451 of file chan_ooh323.c.

References ast_format_alaw, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g723, ast_format_g726, ast_format_g726_aal2, ast_format_g729, ast_format_get_name(), ast_format_gsm, ast_format_h263, ast_format_speex, ast_format_ulaw, ast_log, and LOG_NOTICE.

Referenced by configure_local_rtp(), and ooh323_set_rtp_peer().

04452 {
04453    if (ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
04454       return OO_G711ULAW64K;
04455    } else if (ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
04456       return OO_G711ALAW64K;
04457    } else if (ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) {
04458       return OO_GSMFULLRATE;
04459    } else if (ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) {
04460       return OO_SPEEX;
04461    } else if (ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
04462       return OO_G729A;
04463    } else if (ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) {
04464       return OO_G726;
04465    } else if (ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) {
04466       return OO_G726AAL2;
04467    } else if (ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
04468       return OO_G7231;
04469    } else if (ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) {
04470       return OO_H263VIDEO;
04471    } else {
04472       ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_format_get_name(format));
04473       return -1;
04474    }
04475 }

void ooh323_delete_peer ( struct ooh323_peer peer  ) 

Definition at line 2285 of file chan_ooh323.c.

References ao2_cleanup, ast_free, ast_mutex_lock, ast_mutex_unlock, ast_verb, ooh323_peer::cap, ooh323_peer::e164, ooh323_peer::email, gH323Debug, ooh323_peer::h323id, ast_peer_list::lock, ooh323_peer::next, NULL, peerl, ast_peer_list::peers, and ooh323_peer::url.

Referenced by build_peer().

02286 {
02287    struct ooh323_peer *prev = NULL, *cur = NULL;
02288 
02289    if (gH323Debug)
02290       ast_verb(0, "---   ooh323_delete_peer\n");
02291 
02292    if (peer) { 
02293       cur = peerl.peers;
02294       ast_mutex_lock(&peerl.lock);
02295       while(cur) {
02296          if(cur==peer) break;
02297          prev = cur;
02298          cur = cur->next;
02299       }
02300 
02301       if (cur) {
02302          if(prev)
02303             prev->next = cur->next;
02304          else
02305             peerl.peers = cur->next;
02306          }
02307       ast_mutex_unlock(&peerl.lock);
02308 
02309       ast_free(peer->h323id);
02310       ast_free(peer->email);
02311       ast_free(peer->url);
02312       ast_free(peer->e164);
02313 
02314       ao2_cleanup(peer->cap);
02315       ast_free(peer);
02316    }  
02317 
02318    if (gH323Debug)
02319       ast_verb(0, "+++   ooh323_delete_peer\n");
02320 
02321 }

int ooh323_destroy ( struct ooh323_pvt p  ) 

Definition at line 4063 of file chan_ooh323.c.

References ao2_cleanup, ast_channel_name(), ast_channel_tech_pvt_set(), ast_channel_trylock, ast_channel_unlock, ast_debug, ast_dsp_free(), ast_free, ast_module_unref, ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_rtp_instance_destroy(), ast_test_flag, ast_udptl_destroy(), ast_verb, ooh323_pvt::callerid_name, DEADLOCK_AVOIDANCE, find_user(), gH323Debug, H323_OUTGOING, iflist, ooh323_user::inUse, ooh323_user::lock, ooh323_pvt::next, NULL, and ooh323_pvt::username.

Referenced by do_monitor(), ooh323_request(), and unload_module().

04064 {
04065    /* NOTE: Assumes iflock already acquired */
04066    struct ooh323_pvt *prev = NULL, *cur = NULL;
04067    struct ooh323_user *user = NULL;
04068 
04069    if (gH323Debug) {
04070       ast_verb(0, "---   ooh323_destroy \n");
04071 
04072       if (p)
04073          ast_verb(0, " Destroying %s\n", p->username);
04074    }
04075 
04076    cur = iflist;
04077    while (cur) {
04078       if (cur == p) { break; }
04079       prev = cur;
04080       cur = cur->next;
04081    }
04082 
04083    if (cur) {
04084       ast_mutex_lock(&cur->lock);
04085       if (prev)
04086          prev->next = cur->next;
04087       else
04088          iflist = cur->next;
04089 
04090       if (cur->callToken) {
04091          if (gH323Debug) 
04092             ast_verb(0, " Destroying %s\n", cur->callToken);
04093          ast_free(cur->callToken);
04094          cur->callToken = 0;
04095       }
04096 
04097       if (cur->username) {
04098          ast_free(cur->username);
04099          cur->username = 0;
04100       }
04101 
04102       if (cur->host) {
04103          ast_free(cur->host);
04104          cur->host = 0;
04105       }
04106 
04107       if (cur->callerid_name) {
04108          ast_free(cur->callerid_name);
04109          cur->callerid_name = 0;
04110       }
04111       
04112       if (cur->callerid_num) {
04113          ast_free(cur->callerid_num);
04114          cur->callerid_num = 0;
04115       }
04116 
04117       if (cur->rtp) {
04118          ast_rtp_instance_destroy(cur->rtp);
04119          cur->rtp = NULL;
04120       }
04121 
04122       if (cur->udptl) {
04123          ast_udptl_destroy(cur->udptl);
04124          cur->udptl = NULL;
04125       }
04126    
04127       /* Unlink us from the owner if we have one */
04128       if (cur->owner) {
04129                while(ast_channel_trylock(cur->owner)) {
04130                      ast_debug(1, "Failed to grab lock, trying again\n");
04131             DEADLOCK_AVOIDANCE(&cur->lock);
04132                }           
04133          ast_debug(1, "Detaching from %s\n", ast_channel_name(cur->owner));
04134          ast_channel_tech_pvt_set(cur->owner, NULL);
04135          ast_channel_unlock(cur->owner);
04136          cur->owner = NULL;
04137          ast_module_unref(myself);
04138       }
04139   
04140       if (cur->vad) {
04141          ast_dsp_free(cur->vad);
04142          cur->vad = NULL;
04143       }
04144 
04145 /* decrement user/peer count */
04146 
04147       if(!ast_test_flag(cur, H323_OUTGOING)) {
04148     if (cur->neighbor.user) {
04149      user = find_user(p->callerid_name, cur->neighbor.user);
04150      if(user && user->inUse > 0) {
04151       ast_mutex_lock(&user->lock);
04152       user->inUse--;
04153       ast_mutex_unlock(&user->lock);
04154      }
04155      ast_free(cur->neighbor.user);
04156     }
04157       } else {
04158 /* outgoing limit decrement here !!! */
04159       }
04160 
04161       ast_mutex_unlock(&cur->lock);
04162       ast_mutex_destroy(&cur->lock);
04163       ao2_cleanup(cur->writeformat);
04164       ao2_cleanup(cur->readformat);
04165       ao2_cleanup(cur->cap);
04166       ast_free(cur);
04167    }
04168 
04169    if (gH323Debug)
04170       ast_verb(0, "+++   ooh323_destroy\n");
04171 
04172    return 0;
04173 }

int ooh323_onReceivedDigit ( OOH323CallData *  call,
const char *  digit 
)

Callback for sending digits from H.323 up to asterisk

Definition at line 1755 of file chan_ooh323.c.

References ast_channel_trylock, ast_channel_unlock, ast_debug, AST_FRAME_DTMF, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_queue_frame(), ast_frame::data, ast_frame::datalen, DEADLOCK_AVOIDANCE, find_call, ast_frame::frametype, ast_frame_subclass::integer, ooh323_pvt::lock, LOG_ERROR, ast_frame::mallocd, NULL, ast_frame::offset, ooh323_pvt::owner, ast_frame::ptr, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by load_module().

01756 {
01757    struct ooh323_pvt *p = NULL;
01758    struct ast_frame f;
01759    int res;
01760 
01761    ast_debug(1, "Received Digit: %c\n", digit[0]);
01762    p = find_call(call);
01763    if (!p) {
01764       ast_log(LOG_ERROR, "Failed to find a matching call.\n");
01765       return -1;
01766    }
01767    if (!p->owner) {
01768       ast_log(LOG_ERROR, "Channel has no owner\n");
01769       return -1;
01770    }
01771    ast_mutex_lock(&p->lock);
01772    memset(&f, 0, sizeof(f));
01773    f.frametype = AST_FRAME_DTMF;
01774    f.subclass.integer = digit[0];
01775    f.datalen = 0;
01776    f.samples = 800;
01777    f.offset = 0;
01778    f.data.ptr = NULL;
01779    f.mallocd = 0;
01780    f.src = "SEND_DIGIT";
01781 
01782    while (p->owner && ast_channel_trylock(p->owner)) {
01783       ast_debug(1, "Failed to grab lock, trying again\n");
01784       DEADLOCK_AVOIDANCE(&p->lock);
01785    }
01786    if (!p->owner) {
01787       ast_mutex_unlock(&p->lock);
01788       ast_log(LOG_ERROR, "Channel has no owner\n");
01789       return 0;
01790    }
01791    res = ast_queue_frame(p->owner, &f);
01792       ast_channel_unlock(p->owner);
01793       ast_mutex_unlock(&p->lock);
01794    return res;
01795 }

int ooh323_onReceivedSetup ( ooCallData *  call,
Q931Message *  pmsg 
)

Definition at line 1797 of file chan_ooh323.c.

References ooh323_user::accountcode, ooh323_pvt::accountcode, ooh323_user::amaflags, ooh323_pvt::amaflags, ooh323_user::aniasdni, ooh323_pvt::aniasdni, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, ast_clear_flag, ast_copy_string(), ast_format_cap_append_from_cap(), ast_log, AST_MEDIA_TYPE_UNKNOWN, ast_mutex_lock, ast_mutex_unlock, ast_set_flag, AST_STATE_RING, ast_strdup, ast_strlen_zero, ast_verb, c, ooh323_pvt::callee_dialedDigits, ooh323_pvt::callee_email, ooh323_pvt::callee_h323id, ooh323_pvt::caller_dialedDigits, ooh323_pvt::caller_email, ooh323_pvt::caller_h323id, ooh323_pvt::caller_url, ooh323_pvt::callerid_name, ooh323_pvt::callerid_num, ooh323_user::cap, ooh323_pvt::cap, configure_local_rtp(), ooh323_user::context, ooh323_pvt::context, ooh323_user::directrtp, ooh323_pvt::directrtp, ooh323_user::dtmfcodec, ooh323_pvt::dtmfcodec, ooh323_user::dtmfmode, ooh323_pvt::dtmfmode, ooh323_user::earlydirect, ooh323_pvt::earlydirect, ooh323_pvt::exten, ooh323_user::faststart, ooh323_pvt::faststart, ooh323_user::faxdetect, ooh323_pvt::faxdetect, find_user(), ooh323_pvt::flags, ooh323_user::g729onlyA, ooh323_pvt::g729onlyA, gDirectRTP, gEarlyDirect, gH323Debug, ooh323_user::h245tunneling, ooh323_pvt::h245tunneling, H323_DISABLEGK, H323_NEEDDESTROY, H323_OUTGOING, ooh323_user::incominglimit, ooh323_user::inUse, ooh323_user::lock, ooh323_pvt::lock, LOG_ERROR, ooh323_user::mIP, ooh323_user::mUseIP, ooh323_user::name, ooh323_user::nat, ooh323_pvt::nat, ooh323_pvt::neighbor, NULL, ooh323_alloc(), ooh323_convert_hangupcause_asteriskToH323(), ooh323_new(), ooh323c_set_capability_for_call(), ooh323_pvt::rtdrcount, ooh323_user::rtdrcount, ooh323_pvt::rtdrinterval, ooh323_user::rtdrinterval, ooh323_pvt::rtpmask, ooh323_user::rtpmask, ooh323_pvt::rtpmaskstr, ooh323_user::rtpmaskstr, ooh323_user::rtptimeout, ooh323_pvt::rtptimeout, ooh323_user::t38support, ooh323_pvt::t38support, update_our_aliases(), ooh323_pvt::user, and ooh323_pvt::username.

Referenced by load_module().

01798 {
01799    struct ooh323_pvt *p = NULL;
01800    struct ooh323_user *user = NULL;
01801       struct ast_channel *c = NULL;
01802    ooAliases *alias = NULL;
01803    char *at = NULL;
01804    char number [OO_MAX_NUMBER_LENGTH];
01805 
01806    if (gH323Debug)
01807       ast_verb(0, "---   ooh323_onReceivedSetup %s\n", call->callToken);
01808 
01809 
01810    if (!(p = ooh323_alloc(call->callReference, call->callToken))) {
01811       ast_log(LOG_ERROR, "Failed to create a new call.\n");
01812       return -1;
01813    }
01814    ast_mutex_lock(&p->lock);
01815    ast_clear_flag(p, H323_OUTGOING);
01816   
01817 
01818    if (call->remoteDisplayName) {
01819       p->callerid_name = ast_strdup(call->remoteDisplayName);
01820    }
01821 
01822    if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) {
01823       p->callerid_num = ast_strdup(number);
01824    }
01825 
01826    if (call->remoteAliases) {
01827       for (alias = call->remoteAliases; alias; alias = alias->next) {
01828          if (alias->type == T_H225AliasAddress_h323_ID) {
01829             if (!p->callerid_name) {
01830                p->callerid_name = ast_strdup(alias->value);
01831             }
01832             ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id));
01833             }
01834          else if(alias->type == T_H225AliasAddress_dialedDigits)
01835          {
01836             if(!p->callerid_num)
01837                p->callerid_num = ast_strdup(alias->value);
01838             ast_copy_string(p->caller_dialedDigits, alias->value, 
01839                                              sizeof(p->caller_dialedDigits));
01840          }
01841          else if(alias->type == T_H225AliasAddress_email_ID)
01842          {
01843             ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email));
01844          }
01845          else if(alias->type == T_H225AliasAddress_url_ID)
01846          {
01847             ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url));
01848          }
01849       }
01850    }
01851 
01852    number[0] = '\0';
01853       if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) {
01854             ast_copy_string(p->exten, number, sizeof(p->exten));
01855       } else {
01856       update_our_aliases(call, p);
01857       if (!ast_strlen_zero(p->callee_dialedDigits)) {
01858                ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten));
01859             } else if(!ast_strlen_zero(p->callee_h323id)) {
01860          ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten));
01861             } else if(!ast_strlen_zero(p->callee_email)) {
01862          ast_copy_string(p->exten, p->callee_email, sizeof(p->exten));
01863          if ((at = strchr(p->exten, '@'))) {
01864             *at = '\0';
01865          }
01866       }
01867    }
01868 
01869    /* if no extension found, set to default 's' */
01870    if (ast_strlen_zero(p->exten)) {
01871             p->exten[0]='s';
01872             p->exten[1]='\0';
01873    }
01874 
01875          user = find_user(p->callerid_name, call->remoteIP);
01876          if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) {
01877       ast_mutex_lock(&user->lock);
01878       p->username = ast_strdup(user->name);
01879       p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) :
01880                     ast_strdup(user->name);
01881       ast_copy_string(p->context, user->context, sizeof(p->context));
01882       ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
01883       p->amaflags = user->amaflags;
01884       ast_format_cap_append_from_cap(p->cap, user->cap, AST_MEDIA_TYPE_UNKNOWN);
01885       p->g729onlyA = user->g729onlyA;
01886       p->dtmfmode |= user->dtmfmode;
01887       p->dtmfcodec = user->dtmfcodec;
01888       p->faxdetect = user->faxdetect;
01889       p->t38support = user->t38support;
01890       p->rtptimeout = user->rtptimeout;
01891       p->nat = user->nat;
01892       p->h245tunneling = user->h245tunneling;
01893       p->faststart = user->faststart;
01894       p->directrtp = user->directrtp;
01895       p->earlydirect = user->earlydirect;
01896 
01897       if (p->faststart)
01898                OO_SETFLAG(call->flags, OO_M_FASTSTART);
01899       else
01900          OO_CLRFLAG(call->flags, OO_M_FASTSTART);
01901       /* if we disable h245tun for this user then we clear flag */
01902       /* in any other case we don't must touch this */
01903       /* ie if we receive setup without h245tun but enabled
01904                      we can't enable it per call */
01905       if (!p->h245tunneling)
01906          OO_CLRFLAG(call->flags, OO_M_TUNNELING);
01907 
01908       if (user->rtpmask && user->rtpmaskstr[0]) {
01909          p->rtpmask = user->rtpmask;
01910          ast_copy_string(p->rtpmaskstr, user->rtpmaskstr, 
01911                       sizeof(p->rtpmaskstr));
01912       }
01913       if (user->rtdrcount > 0 && user->rtdrinterval > 0) {
01914          p->rtdrcount = user->rtdrcount;
01915          p->rtdrinterval = user->rtdrinterval;
01916       }
01917 
01918       p->aniasdni = user->aniasdni;
01919 
01920       if (user->incominglimit) user->inUse++;
01921       ast_mutex_unlock(&user->lock);
01922    } else {
01923     if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
01924       p->username = ast_strdup(call->remoteIP);
01925       p->directrtp = gDirectRTP;
01926       p->earlydirect = gEarlyDirect;
01927    } else {
01928      ast_mutex_unlock(&p->lock);
01929      ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
01930      if (!user) {
01931       ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED);
01932       call->callEndReason = OO_REASON_REMOTE_REJECTED;
01933      }
01934      else {
01935       ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION);
01936       call->callEndReason = OO_REASON_REMOTE_REJECTED;
01937      }
01938      ast_set_flag(p, H323_NEEDDESTROY);
01939      return -1;
01940     }
01941    }
01942 
01943    ooh323c_set_capability_for_call(call, p->cap, p->dtmfmode, p->dtmfcodec,
01944                 p->t38support, p->g729onlyA);
01945 /* Incoming call */
01946    c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL, NULL);
01947    if(!c) {
01948       ast_mutex_unlock(&p->lock);
01949       ast_log(LOG_ERROR, "Could not create ast_channel\n");
01950          return -1;
01951    }
01952 
01953    if (p->aniasdni) {
01954       ooCallSetCallerId(call, p->exten);
01955    }
01956    if (!configure_local_rtp(p, call)) {
01957       ast_mutex_unlock(&p->lock);
01958       ast_log(LOG_ERROR, "Couldn't create rtp structure\n");
01959       return -1;
01960    }
01961 
01962    ast_mutex_unlock(&p->lock);
01963 
01964    if (gH323Debug)
01965       ast_verb(0, "+++   ooh323_onReceivedSetup - Determined context %s, "
01966                   "extension %s\n", p->context, p->exten);
01967 
01968    return OO_OK;
01969 }

struct ast_frame* ooh323_rtp_read ( struct ast_channel ast,
struct ooh323_pvt p 
) [read]

Definition at line 4923 of file chan_ooh323.c.

References ao2_ref, ast_async_goto(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_fdno(), ast_channel_macrocontext(), ast_channel_name(), ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_writeformat(), ast_debug, ast_dsp_process(), ast_exists_extension(), ast_format_alaw, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_iscompatible_format(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), ast_format_slin, ast_format_ulaw, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frdup(), ast_frfree, ast_log, ast_null_frame, ast_rtp_instance_read(), ast_set_read_format(), ast_set_write_format(), ast_udptl_read(), ast_verb, ooh323_pvt::callToken, ooh323_pvt::chmodepend, ast_frame::datalen, ooh323_pvt::dtmfmode, f, ooh323_pvt::faxdetect, FAXDETECT_CNG, ooh323_pvt::faxdetected, ooh323_pvt::faxmode, ast_frame_subclass::format, ast_frame::frametype, gH323Debug, H323_DTMF_INBAND, ast_party_caller::id, ast_frame_subclass::integer, ooh323_pvt::lastrtprx, LOG_NOTICE, NULL, ast_party_id::number, ooh323_pvt::owner, pbx_builtin_setvar_helper(), ooh323_pvt::rtp, S_COR, S_OR, ast_party_number::str, ast_frame::subclass, T38_DISABLED, ooh323_pvt::t38support, ooh323_pvt::udptl, ooh323_pvt::vad, ast_party_number::valid, and ooh323_pvt::vrtp.

Referenced by ooh323_read().

04924 {
04925    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
04926    struct ast_frame *f;
04927    struct ast_frame *dfr = NULL;
04928    static struct ast_frame null_frame = { AST_FRAME_NULL, };
04929    switch (ast_channel_fdno(ast)) {
04930    case 0:
04931       f = ast_rtp_instance_read(p->rtp, 0);  /* RTP Audio */
04932       p->lastrtprx = time(NULL);
04933       break;
04934    case 1:
04935       f = ast_rtp_instance_read(p->rtp, 1);  /* RTCP Control Channel */
04936       break;
04937    case 2:
04938       f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */
04939       p->lastrtprx = time(NULL);
04940       break;
04941    case 3:
04942       f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */
04943       break;
04944    case 5:
04945       f = ast_udptl_read(p->udptl);    /* UDPTL t.38 data */
04946       if (gH323Debug) {
04947           ast_debug(1, "Got UDPTL %u/%d len %d for %s\n",
04948             f->frametype, f->subclass.integer, f->datalen, ast_channel_name(ast));
04949       }
04950       p->lastrtprx = time(NULL);
04951       break;
04952 
04953    default:
04954       f = &null_frame;
04955    }
04956 
04957    if (f && p->owner && !p->faxmode && (f->frametype == AST_FRAME_VOICE)) {
04958       /* We already hold the channel lock */
04959       if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(p->owner), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
04960          struct ast_format_cap *caps;
04961 
04962          ast_debug(1, "Oooh, voice format changed to %s\n", ast_format_get_name(f->subclass.format));
04963 
04964          caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
04965          if (caps) {
04966             ast_format_cap_append(caps, f->subclass.format, 0);
04967             ast_channel_nativeformats_set(p->owner, caps);
04968             ao2_ref(caps, -1);
04969          }
04970          ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
04971          ast_set_write_format(p->owner, ast_channel_writeformat(p->owner));
04972       }
04973       if (((p->dtmfmode & H323_DTMF_INBAND) || (p->faxdetect & FAXDETECT_CNG)) && p->vad &&
04974          ((ast_format_cmp(f->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) ||
04975          (ast_format_cmp(f->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) ||
04976          (ast_format_cmp(f->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL))) {
04977          dfr = ast_frdup(f);
04978          dfr = ast_dsp_process(p->owner, p->vad, dfr);
04979       }
04980    } else {
04981       return f;
04982    }
04983 
04984    /* process INBAND DTMF*/
04985    if (dfr && (dfr->frametype == AST_FRAME_DTMF) && ((dfr->subclass.integer == 'f') || (dfr->subclass.integer == 'e'))) {
04986       ast_debug(1, "* Detected FAX Tone %s\n", (dfr->subclass.integer == 'e') ? "CED" : "CNG");
04987       /* Switch to T.38 ON CED*/
04988       if (!p->faxmode && !p->chmodepend && (dfr->subclass.integer == 'e') && (p->t38support != T38_DISABLED)) {
04989          if (gH323Debug)
04990             ast_verb(0, "request to change %s to t.38 because fax ced\n", p->callToken);
04991          p->chmodepend = 1;
04992          p->faxdetected = 1;
04993          ooRequestChangeMode(p->callToken, 1);
04994       } else if ((dfr->subclass.integer == 'f') && !p->faxdetected) {
04995          const char *target_context = S_OR(ast_channel_macrocontext(p->owner), ast_channel_context(p->owner));
04996          if ((strcmp(ast_channel_exten(p->owner), "fax")) &&
04997              (ast_exists_extension(p->owner, target_context, "fax", 1,
04998                   S_COR(ast_channel_caller(p->owner)->id.number.valid, ast_channel_caller(p->owner)->id.number.str, NULL)))) {
04999             ast_verb(2, "Redirecting '%s' to fax extension due to CNG detection\n", ast_channel_name(p->owner));
05000             pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", ast_channel_exten(p->owner));
05001             if (ast_async_goto(p->owner, target_context, "fax", 1)) {
05002                ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(p->owner),target_context);
05003             }
05004             p->faxdetected = 1;
05005             if (dfr) {
05006                ast_frfree(dfr);
05007             }
05008             return &ast_null_frame;
05009          }
05010       }
05011    } else if (dfr && dfr->frametype == AST_FRAME_DTMF) {
05012       ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
05013       ast_frfree(f);
05014       return dfr;
05015    }
05016 
05017    if (dfr) {
05018       ast_frfree(dfr);
05019    }
05020    return f;
05021 }

void ooh323_set_read_format ( ooCallData *  call,
struct ast_format fmt 
)

Definition at line 1582 of file chan_ooh323.c.

References ao2_ref, ao2_replace, ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_trylock, ast_channel_unlock, ast_debug, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_get_name(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_set_read_format(), ast_verb, DEADLOCK_AVOIDANCE, find_call, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, ooh323_pvt::owner, and ooh323_pvt::readformat.

01583 {
01584    struct ooh323_pvt *p = NULL;
01585 
01586    if (gH323Debug)
01587       ast_verb(0, "---   ooh323_update_readformat %s\n", 
01588             ast_format_get_name(fmt));
01589    
01590    p = find_call(call);
01591    if (!p) {
01592       ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
01593       return;
01594    }
01595 
01596    ast_mutex_lock(&p->lock);
01597 
01598    ao2_replace(p->readformat, fmt);
01599 
01600    if (p->owner) {
01601       struct ast_format_cap *caps;
01602 
01603       caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
01604       if (!caps) {
01605          ast_log(LOG_ERROR, "Could not allocate capabilities structure\n");
01606          return;
01607       }
01608 
01609       while (p->owner && ast_channel_trylock(p->owner)) {
01610          ast_debug(1,"Failed to grab lock, trying again\n");
01611          DEADLOCK_AVOIDANCE(&p->lock);
01612       }
01613       if (!p->owner) {
01614          ast_mutex_unlock(&p->lock);
01615          ast_log(LOG_ERROR, "Channel has no owner\n");
01616          ao2_ref(caps, -1);
01617          return;
01618       }
01619 
01620       if (gH323Debug) {
01621          ast_verb(0, "Readformat before update %s\n", 
01622            ast_format_get_name(ast_channel_readformat(p->owner)));
01623       }
01624       ast_format_cap_append(caps, fmt, 0);
01625       ast_channel_nativeformats_set(p->owner, caps);
01626       ao2_ref(caps, -1);
01627       ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
01628       ast_channel_unlock(p->owner);
01629       } else
01630       ast_log(LOG_ERROR, "No owner found\n");
01631 
01632    ast_mutex_unlock(&p->lock);
01633 
01634    if (gH323Debug)
01635       ast_verb(0, "+++   ooh323_update_readformat\n");
01636 }

void ooh323_set_write_format ( ooCallData *  call,
struct ast_format fmt,
int  txframes 
)

Definition at line 1510 of file chan_ooh323.c.

References ao2_ref, ao2_replace, ast_channel_nativeformats(), ast_channel_nativeformats_set(), ast_channel_readformat(), ast_channel_trylock, ast_channel_unlock, ast_channel_writeformat(), ast_debug, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_names(), ast_format_cap_set_framing(), ast_format_get_name(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_rtp_codecs_payloads_set_rtpmap_type(), ast_rtp_instance_get_codecs(), ast_set_read_format(), ast_set_write_format(), ast_str_alloca, ast_verb, DEADLOCK_AVOIDANCE, ooh323_pvt::dtmfcodec, ooh323_pvt::dtmfmode, find_call, gH323Debug, H323_DTMF_CISCO, H323_DTMF_RFC2833, ooh323_pvt::lock, LOG_ERROR, NULL, ooh323_pvt::owner, ooh323_pvt::rtp, and ooh323_pvt::writeformat.

Referenced by ooh323c_start_transmit_channel().

01511 {
01512    struct ooh323_pvt *p = NULL;
01513 
01514    if (gH323Debug)
01515       ast_verb(0, "---   ooh323_update_writeformat %s/%d\n", 
01516             ast_format_get_name(fmt), txframes);
01517    
01518    p = find_call(call);
01519    if (!p) {
01520       ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
01521       return;
01522    }
01523 
01524    ast_mutex_lock(&p->lock);
01525 
01526    ao2_replace(p->writeformat, fmt);
01527 
01528    if (p->owner) {
01529       struct ast_format_cap *caps;
01530 
01531       caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
01532       if (!caps) {
01533          ast_log(LOG_ERROR, "Could not allocate capabilities structure\n");
01534          return;
01535       }
01536 
01537       while (p->owner && ast_channel_trylock(p->owner)) {
01538          ast_debug(1,"Failed to grab lock, trying again\n");
01539          DEADLOCK_AVOIDANCE(&p->lock);
01540       }
01541       if (!p->owner) {
01542          ast_mutex_unlock(&p->lock);
01543          ast_log(LOG_ERROR, "Channel has no owner\n");
01544          ao2_ref(caps, -1);
01545          return;
01546       }
01547       if (gH323Debug) {
01548          struct ast_str *codec_buf = ast_str_alloca(64);
01549          ast_verb(0, "Writeformat before update %s/%s\n", 
01550            ast_format_get_name(ast_channel_writeformat(p->owner)),
01551            ast_format_cap_get_names(ast_channel_nativeformats(p->owner), &codec_buf));
01552       }
01553 
01554       if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
01555          ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
01556              p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
01557       }
01558       if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
01559          ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
01560              p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
01561       }
01562 
01563       if (txframes) {
01564          ast_format_cap_set_framing(caps, txframes);
01565       }
01566       ast_format_cap_append(caps, fmt, 0);
01567       ast_channel_nativeformats_set(p->owner, caps);
01568       ao2_ref(caps, -1);
01569       ast_set_write_format(p->owner, ast_channel_writeformat(p->owner));
01570       ast_set_read_format(p->owner, ast_channel_readformat(p->owner));
01571       ast_channel_unlock(p->owner);
01572       } else
01573       ast_log(LOG_ERROR, "No owner found\n");
01574 
01575 
01576    ast_mutex_unlock(&p->lock);
01577 
01578    if (gH323Debug)
01579       ast_verb(0, "+++   ooh323_update_writeformat\n");
01580 }

int reload_config ( int  reload  ) 

Definition at line 2767 of file chan_ooh323.c.

02768 {
02769    int format;
02770    struct ooAliases  *pNewAlias = NULL, *cur, *prev;
02771    struct ast_config *cfg;
02772    struct ast_variable *v;
02773    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
02774    struct ooh323_user *user = NULL;
02775    struct ooh323_peer *peer = NULL;
02776    char *cat;
02777    const char *utype;
02778 
02779    if (gH323Debug)
02780       ast_verb(0, "---   reload_config\n");
02781 
02782    cfg = ast_config_load((char*)config, config_flags);
02783 
02784    /* We *must* have a config file otherwise stop immediately */
02785    if (!cfg) {
02786       ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config);
02787       return 1;
02788    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
02789       return RESULT_SUCCESS;
02790 
02791    if (reload) {
02792       delete_users();
02793       delete_peers();
02794       if (gH323Debug) {
02795          ast_verb(0, "  reload_config - Freeing up alias list\n");
02796       }
02797       cur = gAliasList;
02798       while (cur) {
02799          prev = cur;
02800          cur = cur->next;
02801          ast_free(prev->value);
02802          ast_free(prev);
02803       }
02804       gAliasList = NULL;
02805       ooH323EpClearAllAliases();
02806    }
02807 
02808    /* Inintialize everything to default */
02809    strcpy(gLogFile, DEFAULT_LOGFILE);
02810    gPort = 1720;
02811    gIP[0] = '\0';
02812    strcpy(gCallerID, DEFAULT_H323ID);
02813    ast_format_cap_remove_by_type(gCap, AST_MEDIA_TYPE_UNKNOWN);
02814    ast_format_cap_append(gCap, ast_format_ulaw, 0);
02815    gDTMFMode = H323_DTMF_RFC2833;
02816    gDTMFCodec = 101;
02817    gFAXdetect = FAXDETECT_CNG;
02818    gT38Support = T38_FAXGW;
02819    gTRCLVL = OOTRCLVLERR;
02820    gRasGkMode = RasNoGatekeeper;
02821    gGatekeeper[0] = '\0';
02822    gRTPTimeout = 60;
02823    gNat = FALSE;
02824    gRTDRInterval = 0;
02825    gRTDRCount = 0;
02826    strcpy(gAccountcode, DEFAULT_H323ACCNT);
02827    gFastStart = 1;
02828    gTunneling = 1;
02829    gTOS = 0;
02830    strcpy(gContext, DEFAULT_CONTEXT);
02831    gAliasList = NULL;
02832    gMediaWaitForConnect = 0;
02833    ooconfig.mTCPPortStart = 12030;
02834    ooconfig.mTCPPortEnd = 12230;
02835    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
02836 
02837    v = ast_variable_browse(cfg, "general");
02838    while (v) {
02839 
02840       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
02841          v = v->next;
02842          continue;
02843       }
02844    
02845       if (!strcasecmp(v->name, "port")) {
02846          gPort = (int)strtol(v->value, NULL, 10);
02847       } else if (!strcasecmp(v->name, "bindaddr")) {
02848          ast_copy_string(gIP, v->value, sizeof(gIP));
02849          if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
02850             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
02851             ast_config_destroy(cfg);
02852             return 1;
02853          }
02854          if (ast_sockaddr_is_ipv6(&bindaddr)) {
02855             v6mode = 1;
02856          }
02857       } else if (!strcasecmp(v->name, "h225portrange")) {
02858          char* endlimit = 0;
02859                char temp[512];
02860          ast_copy_string(temp, v->value, sizeof(temp));
02861          endlimit = strchr(temp, ',');
02862          if (endlimit) {
02863             *endlimit = '\0';
02864             endlimit++;
02865             ooconfig.mTCPPortStart = atoi(temp);
02866             ooconfig.mTCPPortEnd = atoi(endlimit);
02867 
02868          } else {
02869             ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n");
02870          }
02871       } else if (!strcasecmp(v->name, "gateway")) {
02872          gIsGateway = ast_true(v->value);
02873             } else if (!strcasecmp(v->name, "faststart")) {
02874          gFastStart = ast_true(v->value);
02875          if (gFastStart)
02876             ooH323EpEnableFastStart();
02877          else
02878             ooH323EpDisableFastStart();
02879       } else if (!strcasecmp(v->name, "mediawaitforconnect")) {
02880          gMediaWaitForConnect = ast_true(v->value);
02881          if (gMediaWaitForConnect)
02882             ooH323EpEnableMediaWaitForConnect();
02883          else 
02884             ooH323EpDisableMediaWaitForConnect();
02885       } else if (!strcasecmp(v->name, "h245tunneling")) {
02886          gTunneling = ast_true(v->value);
02887          if (gTunneling)
02888             ooH323EpEnableH245Tunneling();
02889          else
02890             ooH323EpDisableH245Tunneling();
02891       } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
02892          gDirectRTP = ast_true(v->value);
02893          gEarlyDirect = ast_true(v->value);
02894       } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
02895          gEarlyDirect = ast_true(v->value);
02896       } else if (!strcasecmp(v->name, "g729onlyA")) {
02897          g729onlyA = ast_true(v->value);
02898       } else if (!strcasecmp(v->name, "roundtrip")) {
02899          sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval);
02900             } else if (!strcasecmp(v->name, "trybemaster")) {
02901          gBeMaster = ast_true(v->value);
02902          if (gBeMaster)
02903             ooH323EpTryBeMaster(1);
02904          else 
02905             ooH323EpTryBeMaster(0);
02906       } else if (!strcasecmp(v->name, "h323id")) {
02907                pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
02908          if (!pNewAlias) {
02909             ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n");
02910             ast_config_destroy(cfg);
02911             return 1;
02912          }
02913          if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */
02914             ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
02915          }
02916          pNewAlias->type =  T_H225AliasAddress_h323_ID;
02917          pNewAlias->value = ast_strdup(v->value);
02918          pNewAlias->next = gAliasList;
02919          gAliasList = pNewAlias;
02920          pNewAlias = NULL;
02921       } else if (!strcasecmp(v->name, "e164")) {
02922          int valid = 1;
02923          const char *tmp;
02924          for(tmp = v->value; *tmp; tmp++) {
02925             if (!isdigit(*tmp)) {
02926                valid = 0;
02927                break;
02928             }
02929          }
02930          if (valid) {
02931                   pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
02932             if (!pNewAlias) {
02933                ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n");
02934                ast_config_destroy(cfg);
02935                return 1;
02936             }
02937             pNewAlias->type =  T_H225AliasAddress_dialedDigits;
02938             pNewAlias->value = ast_strdup(v->value);
02939             pNewAlias->next = gAliasList;
02940             gAliasList = pNewAlias;
02941             pNewAlias = NULL;
02942          } else {
02943             ast_log(LOG_ERROR, "Invalid e164: %s\n", v->value);
02944          }
02945       } else if (!strcasecmp(v->name, "email")) {
02946                pNewAlias = ast_calloc(1, sizeof(struct ooAliases));
02947          if (!pNewAlias) {
02948             ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n");
02949             ast_config_destroy(cfg);
02950             return 1;
02951          }
02952          pNewAlias->type =  T_H225AliasAddress_email_ID;
02953          pNewAlias->value = ast_strdup(v->value);
02954          pNewAlias->next = gAliasList;
02955          gAliasList = pNewAlias;
02956          pNewAlias = NULL;
02957       } else if (!strcasecmp(v->name, "t35country")) {
02958          t35countrycode = atoi(v->value);
02959       } else if (!strcasecmp(v->name, "t35extensions")) {
02960          t35extensions = atoi(v->value);
02961       } else if (!strcasecmp(v->name, "manufacturer")) {
02962          manufacturer = atoi(v->value);
02963       } else if (!strcasecmp(v->name, "vendorid")) {
02964          ast_copy_string(vendor, v->value, sizeof(vendor));
02965       } else if (!strcasecmp(v->name, "versionid")) {
02966          ast_copy_string(version, v->value, sizeof(version));
02967       } else if (!strcasecmp(v->name, "callerid")) {
02968          ast_copy_string(gCallerID, v->value, sizeof(gCallerID));
02969       } else if (!strcasecmp(v->name, "incominglimit")) {
02970          gIncomingLimit = atoi(v->value);
02971       } else if (!strcasecmp(v->name, "outgoinglimit")) {
02972          gOutgoingLimit = atoi(v->value);
02973       } else if (!strcasecmp(v->name, "gatekeeper")) {
02974          if (!strcasecmp(v->value, "DISABLE")) {
02975             gRasGkMode = RasNoGatekeeper;
02976          } else if (!strcasecmp(v->value, "DISCOVER")) {
02977             gRasGkMode = RasDiscoverGatekeeper;
02978          } else {
02979             gRasGkMode = RasUseSpecificGatekeeper;
02980                      ast_copy_string(gGatekeeper, v->value, sizeof(gGatekeeper));
02981          }
02982       } else if (!strcasecmp(v->name, "logfile")) {
02983                ast_copy_string(gLogFile, v->value, sizeof(gLogFile));
02984       } else if (!strcasecmp(v->name, "context")) {
02985                ast_copy_string(gContext, v->value, sizeof(gContext));
02986                ast_verb(3, "  == Setting default context to %s\n", gContext);
02987       } else if (!strcasecmp(v->name, "nat")) {
02988          gNat = ast_true(v->value);
02989       } else if (!strcasecmp(v->name, "rtptimeout")) {
02990          gRTPTimeout = atoi(v->value);
02991          if (gRTPTimeout < 0)
02992             gRTPTimeout = 60;
02993       } else if (!strcasecmp(v->name, "tos")) {
02994          if (sscanf(v->value, "%30i", &format) == 1)
02995             gTOS = format & 0xff;
02996          else if (!strcasecmp(v->value, "lowdelay"))
02997             gTOS = IPTOS_LOWDELAY;
02998          else if (!strcasecmp(v->value, "throughput"))
02999             gTOS = IPTOS_THROUGHPUT;
03000          else if (!strcasecmp(v->value, "reliability"))
03001             gTOS = IPTOS_RELIABILITY;
03002          else if (!strcasecmp(v->value, "mincost"))
03003             gTOS = IPTOS_MINCOST;
03004          else if (!strcasecmp(v->value, "none"))
03005             gTOS = 0;
03006          else
03007             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be "
03008                                  "'lowdelay', 'throughput', 'reliability', "
03009                                  "'mincost', or 'none'\n", v->lineno);
03010       } else if (!strcasecmp(v->name, "amaflags")) {
03011          gAMAFLAGS = ast_channel_string2amaflag(v->value);
03012       } else if (!strcasecmp(v->name, "accountcode")) {
03013          ast_copy_string(gAccountcode, v->value, sizeof(gAccountcode));
03014       } else if (!strcasecmp(v->name, "disallow")) {
03015          ast_format_cap_update_by_allow_disallow(gCap, v->value, 0);
03016       } else if (!strcasecmp(v->name, "allow")) {
03017          const char* tcodecs = v->value;
03018          if (!strcasecmp(v->value, "all")) {
03019             tcodecs = "ulaw,alaw,g729,g723,gsm";
03020          }
03021          ast_format_cap_update_by_allow_disallow(gCap, tcodecs, 1);
03022       } else if (!strcasecmp(v->name, "dtmfmode")) {
03023          if (!strcasecmp(v->value, "inband"))
03024             gDTMFMode = H323_DTMF_INBAND;
03025          else if (!strcasecmp(v->value, "rfc2833"))
03026             gDTMFMode = H323_DTMF_RFC2833;
03027          else if (!strcasecmp(v->value, "cisco"))
03028             gDTMFMode = H323_DTMF_CISCO;
03029          else if (!strcasecmp(v->value, "q931keypad"))
03030             gDTMFMode = H323_DTMF_Q931;
03031          else if (!strcasecmp(v->value, "h245alphanumeric"))
03032             gDTMFMode = H323_DTMF_H245ALPHANUMERIC;
03033          else if (!strcasecmp(v->value, "h245signal"))
03034             gDTMFMode = H323_DTMF_H245SIGNAL;
03035          else {
03036             ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", 
03037                                                                     v->value);
03038             gDTMFMode = H323_DTMF_RFC2833;
03039          }
03040       } else if (!strcasecmp(v->name, "relaxdtmf")) {
03041          gDTMFMode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0;
03042       } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) {
03043          gDTMFCodec = atoi(v->value);
03044       } else if (!strcasecmp(v->name, "faxdetect")) {
03045          if (ast_true(v->value)) {
03046             gFAXdetect = FAXDETECT_CNG | FAXDETECT_T38;
03047          } else if (ast_false(v->value)) {
03048             gFAXdetect = 0;
03049          } else {
03050             char *buf = ast_strdupa(v->value);
03051             char *word, *next = buf;
03052             gFAXdetect = 0;
03053             while ((word = strsep(&next, ","))) {
03054                if (!strcasecmp(word, "cng")) {
03055                   gFAXdetect |= FAXDETECT_CNG;
03056                } else if (!strcasecmp(word, "t38")) {
03057                   gFAXdetect |= FAXDETECT_T38;
03058                } else {
03059                   ast_log(LOG_WARNING, "Unknown faxdetect mode '%s' on line %d.\n", word, v->lineno);
03060                }
03061             }
03062 
03063          }
03064       } else if (!strcasecmp(v->name, "t38support")) {
03065          if (!strcasecmp(v->value, "disabled"))
03066             gT38Support = T38_DISABLED;
03067          if (!strcasecmp(v->value, "no"))
03068             gT38Support = T38_DISABLED;
03069          else if (!strcasecmp(v->value, "faxgw"))
03070             gT38Support = T38_FAXGW;
03071          else if (!strcasecmp(v->value, "yes"))
03072             gT38Support = T38_ENABLED;
03073       } else if (!strcasecmp(v->name, "tracelevel")) {
03074          gTRCLVL = atoi(v->value);
03075          ooH323EpSetTraceLevel(gTRCLVL);
03076       } else if (!strcasecmp(v->name, "aniasdni")) {
03077          gANIasDNI = ast_true(v->value);
03078       }
03079       v = v->next;
03080    }
03081    
03082    for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
03083       if (strcasecmp(cat, "general")) {
03084          int friend_type = 0;
03085          utype = ast_variable_retrieve(cfg, cat, "type");
03086          if (utype) {
03087             friend_type = strcasecmp(utype, "friend");
03088             if (!strcmp(utype, "user") || 0 == friend_type) {
03089                user = build_user(cat, ast_variable_browse(cfg, cat));
03090                if (user) {
03091                   ast_mutex_lock(&userl.lock);
03092                   user->next = userl.users;
03093                   userl.users = user;
03094                   ast_mutex_unlock(&userl.lock);
03095                } else {
03096                   ast_log(LOG_WARNING, "Failed to build user %s\n", cat);
03097                }
03098             }
03099             if (!strcasecmp(utype, "peer") || 0 == friend_type) {
03100                peer = build_peer(cat, ast_variable_browse(cfg, cat), friend_type);
03101                if (peer) {
03102                   ast_mutex_lock(&peerl.lock);
03103                   peer->next = peerl.peers;
03104                   peerl.peers = peer;
03105                   ast_mutex_unlock(&peerl.lock);
03106                } else {
03107                   ast_log(LOG_WARNING, "Failed to build peer %s\n", cat);
03108                }
03109             }
03110          }
03111       }
03112    }
03113    ast_config_destroy(cfg);
03114 
03115 
03116    /* Determine ip address if neccessary */
03117    if (ast_strlen_zero(gIP)) {
03118       ooGetLocalIPAddress(gIP);
03119       if (!strcmp(gIP, "127.0.0.1") || !strcmp(gIP, "::1")) {
03120          ast_log(LOG_NOTICE, "Failed to determine local ip address. Please "
03121                             "specify it in ooh323.conf. OOH323 Disabled\n");
03122          return 1;
03123       }
03124    }
03125 
03126    if (gH323Debug)
03127       ast_verb(0, "+++   reload_config\n");
03128 
03129    return 0;
03130 
03131 }

int restart_monitor ( void   ) 

Start the channel monitor thread.

Definition at line 4028 of file chan_ooh323.c.

04029 {
04030    pthread_attr_t attr;
04031 
04032    /* If we're supposed to be stopped -- stay stopped */
04033    if (monitor_thread == AST_PTHREADT_STOP)
04034       return 0;
04035    if (ast_mutex_lock(&monlock)) {
04036       ast_log(LOG_WARNING, "Unable to lock monitor\n");
04037       return -1;
04038    }
04039    if (monitor_thread == pthread_self()) {
04040       ast_mutex_unlock(&monlock);
04041       ast_log(LOG_WARNING, "Cannot kill myself\n");
04042       return -1;
04043    }
04044    if (monitor_thread != AST_PTHREADT_NULL) {
04045       /* Wake up the thread */
04046       pthread_kill(monitor_thread, SIGURG);
04047    } else {
04048       pthread_attr_init(&attr);
04049       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04050       /* Start a new monitor */
04051       if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
04052          ast_mutex_unlock(&monlock);
04053          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
04054          return -1;
04055       }
04056    }
04057    ast_mutex_unlock(&monlock);
04058    return 0;
04059 }

void setup_rtp_connection ( ooCallData *  call,
const char *  remoteIp,
int  remotePort 
)

Definition at line 4720 of file chan_ooh323.c.

References ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_g726_aal2, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_parse_arg(), ast_rtp_codecs_payloads_set_rtpmap_type(), ast_rtp_instance_get_codecs(), ast_rtp_instance_set_remote_address, AST_RTP_OPT_G726_NONSTANDARD, ast_sockaddr_set_port, ast_verb, find_call, gH323Debug, ooh323_pvt::lock, LOG_ERROR, NULL, PARSE_ADDR, ooh323_pvt::rtp, and ooh323_pvt::writeformat.

Referenced by ooh323c_start_transmit_channel().

04721 {
04722    struct ooh323_pvt *p = NULL;
04723    struct ast_sockaddr tmp;
04724 
04725    if (gH323Debug)
04726       ast_verb(0, "---   setup_rtp_connection %s:%d\n", remoteIp, remotePort);
04727 
04728    /* Find the call or allocate a private structure if call not found */
04729    p = find_call(call);
04730 
04731    if (!p || !p->rtp) {
04732       ast_log(LOG_ERROR, "Something is wrong: rtp\n");
04733       return;
04734    }
04735 
04736    ast_mutex_lock(&p->lock);
04737 
04738    ast_parse_arg(remoteIp, PARSE_ADDR, &tmp);
04739    ast_sockaddr_set_port(&tmp, remotePort);
04740    ast_rtp_instance_set_remote_address(p->rtp, &tmp);
04741 
04742    if (ast_format_cmp(p->writeformat, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) {
04743                 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, 2,
04744                      "audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD);
04745    }
04746 
04747    ast_mutex_unlock(&p->lock);
04748 
04749    if(gH323Debug)
04750       ast_verb(0, "+++   setup_rtp_connection\n");
04751 
04752    return;
04753 }

void setup_udptl_connection ( ooCallData *  call,
const char *  remoteIp,
int  remotePort 
)

Definition at line 4784 of file chan_ooh323.c.

References ast_channel_name(), ast_channel_trylock, ast_channel_unlock, AST_CONTROL_T38_PARAMETERS, ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_parse_arg(), ast_queue_control_data(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify_host(), AST_T38_NEGOTIATED, AST_T38_RATE_14400, ast_udptl_get_far_max_ifp(), ast_udptl_set_peer(), ast_udptl_set_tag(), ast_verb, DEADLOCK_AVOIDANCE, find_call, gH323Debug, ooh323_pvt::lastTxT38, ooh323_pvt::lock, LOG_ERROR, ast_control_t38_parameters::max_ifp, NULL, ooh323_pvt::owner, PARSE_ADDR, ast_control_t38_parameters::rate, ast_control_t38_parameters::request_response, T38_ENABLED, ooh323_pvt::t38_tx_enable, ooh323_pvt::t38support, and ooh323_pvt::udptl.

Referenced by ooh323c_start_transmit_datachannel().

04786 {
04787    struct ooh323_pvt *p = NULL;
04788    struct ast_sockaddr them;
04789 
04790    if (gH323Debug)
04791       ast_verb(0, "---   setup_udptl_connection\n");
04792 
04793    /* Find the call or allocate a private structure if call not found */
04794    p = find_call(call); 
04795 
04796    if (!p) {
04797       ast_log(LOG_ERROR, "Something is wrong: rtp\n");
04798       return;
04799    }
04800 
04801    ast_mutex_lock(&p->lock);
04802    if (p->owner) {
04803       while (p->owner && ast_channel_trylock(p->owner)) {
04804          ast_debug(1, "Failed to grab lock, trying again\n");
04805          DEADLOCK_AVOIDANCE(&p->lock);
04806       }
04807       if (!p->owner) {
04808          ast_mutex_unlock(&p->lock);
04809          ast_log(LOG_ERROR, "Channel has no owner\n");
04810          return;
04811       }
04812    } else {
04813       ast_mutex_unlock(&p->lock);
04814       ast_log(LOG_ERROR, "Channel has no owner\n");
04815       return;
04816    }
04817 
04818    ast_parse_arg(remoteIp, PARSE_ADDR, &them);
04819    ast_sockaddr_set_port(&them, remotePort);
04820 
04821    ast_udptl_set_peer(p->udptl, &them);
04822    ast_udptl_set_tag(p->udptl, "%s", ast_channel_name(p->owner));
04823    p->t38_tx_enable = 1;
04824    p->lastTxT38 = time(NULL);
04825    if (p->t38support == T38_ENABLED) {
04826       struct ast_control_t38_parameters parameters = { .request_response = 0 };
04827       parameters.request_response = AST_T38_NEGOTIATED;
04828       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
04829       parameters.rate = AST_T38_RATE_14400;
04830       ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
04831    }
04832    if (gH323Debug) {
04833       ast_debug(1, "Receiving UDPTL  %s:%d\n", ast_sockaddr_stringify_host(&them),
04834                      ast_sockaddr_port(&them));
04835    }
04836 
04837    ast_channel_unlock(p->owner);
04838    ast_mutex_unlock(&p->lock);
04839 
04840    if(gH323Debug)
04841       ast_verb(0, "+++   setup_udptl_connection\n");
04842 
04843    return;
04844 }

int update_our_aliases ( ooCallData *  call,
struct ooh323_pvt p 
)

Definition at line 4894 of file chan_ooh323.c.

References ast_copy_string(), ooh323_pvt::callee_dialedDigits, ooh323_pvt::callee_email, ooh323_pvt::callee_h323id, ooh323_pvt::callee_url, and NULL.

Referenced by ooh323_onReceivedSetup().

04895 {
04896    int updated = -1;
04897    ooAliases *psAlias = NULL;
04898    
04899    if (!call->ourAliases)
04900       return updated;
04901    for (psAlias = call->ourAliases; psAlias; psAlias = psAlias->next) {
04902       if (psAlias->type == T_H225AliasAddress_h323_ID) {
04903          ast_copy_string(p->callee_h323id, psAlias->value, sizeof(p->callee_h323id));
04904          updated = 1;
04905       }
04906       if (psAlias->type == T_H225AliasAddress_dialedDigits) {
04907          ast_copy_string(p->callee_dialedDigits, psAlias->value, 
04908                                         sizeof(p->callee_dialedDigits));
04909          updated = 1;
04910       }
04911       if (psAlias->type == T_H225AliasAddress_url_ID) {
04912          ast_copy_string(p->callee_url, psAlias->value, sizeof(p->callee_url));
04913          updated = 1;
04914       }
04915       if (psAlias->type == T_H225AliasAddress_email_ID) {
04916          ast_copy_string(p->callee_email, psAlias->value, sizeof(p->callee_email));
04917          updated = 1;
04918       }
04919    }
04920    return updated;
04921 }


Generated on Thu Apr 16 06:29:47 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6