options are documented in config sample sample config rename to proper name - ooh323.conf To change media address ooh323 send empty TCS if there was completed TCS exchange or send facility forwardedelements with new fast start proposal if not. Then close transmit logical channels and renew TCS exchange. If new fast start proposal is received then ooh323 stack call back channel driver routine to change rtp address in the rtp instance. If empty TCS is received then close transmit logical channels and renew TCS exchange Review: https://reviewboard.asterisk.org/r/1607/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369613 65c4cc65-6c06-0410-ace0-fbb531ad65f3
740 lines
25 KiB
C
740 lines
25 KiB
C
/*
|
|
* Copyright (C) 2004-2005 by Objective Systems, Inc.
|
|
*
|
|
* This software is furnished under an open source license and may be
|
|
* used and copied only in accordance with the terms of this license.
|
|
* The text of the license may generally be found in the root
|
|
* directory of this installation in the COPYING file. It
|
|
* can also be viewed online at the following URL:
|
|
*
|
|
* http://www.obj-sys.com/open/license.html
|
|
*
|
|
* Any redistributions of this file including modified versions must
|
|
* maintain this copyright notice.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "ooh323cDriver.h"
|
|
|
|
#include "asterisk.h"
|
|
#include "asterisk/lock.h"
|
|
|
|
#include "asterisk/pbx.h"
|
|
#include "asterisk/logger.h"
|
|
|
|
#undef AST_BACKGROUND_STACKSIZE
|
|
#define AST_BACKGROUND_STACKSIZE 768 * 1024
|
|
|
|
#define SEC_TO_HOLD_THREAD 24
|
|
|
|
extern struct ast_module *myself;
|
|
extern OOBOOL gH323Debug;
|
|
extern OOH323EndPoint gH323ep;
|
|
/* ooh323c stack thread. */
|
|
static pthread_t ooh323c_thread = AST_PTHREADT_NULL;
|
|
static pthread_t ooh323cmd_thread = AST_PTHREADT_NULL;
|
|
static int grxframes = 240;
|
|
|
|
static int gtxframes = 20;
|
|
|
|
static struct callthread {
|
|
ast_mutex_t lock;
|
|
int thePipe[2];
|
|
OOBOOL inUse;
|
|
ooCallData* call;
|
|
struct callthread *next, *prev;
|
|
} *callThreads = NULL;
|
|
|
|
AST_MUTEX_DEFINE_STATIC(callThreadsLock);
|
|
|
|
|
|
int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel);
|
|
int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel);
|
|
int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel);
|
|
int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel);
|
|
|
|
int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
|
|
int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
|
|
int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
|
|
int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel);
|
|
|
|
void* ooh323c_stack_thread(void* dummy);
|
|
void* ooh323c_cmd_thread(void* dummy);
|
|
void* ooh323c_call_thread(void* dummy);
|
|
int ooh323c_set_aliases(ooAliases * aliases);
|
|
|
|
void* ooh323c_stack_thread(void* dummy)
|
|
{
|
|
|
|
ooMonitorChannels();
|
|
return dummy;
|
|
}
|
|
|
|
void* ooh323c_cmd_thread(void* dummy)
|
|
{
|
|
|
|
ooMonitorCmdChannels();
|
|
return dummy;
|
|
}
|
|
|
|
void* ooh323c_call_thread(void* dummy)
|
|
{
|
|
struct callthread* mycthread = (struct callthread *)dummy;
|
|
struct pollfd pfds[1];
|
|
char c;
|
|
int res = 0;
|
|
|
|
do {
|
|
|
|
ooMonitorCallChannels((ooCallData*)mycthread->call);
|
|
mycthread->call = NULL;
|
|
mycthread->prev = NULL;
|
|
mycthread->inUse = FALSE;
|
|
|
|
ast_mutex_lock(&callThreadsLock);
|
|
mycthread->next = callThreads;
|
|
callThreads = mycthread;
|
|
if (mycthread->next) mycthread->next->prev = mycthread;
|
|
ast_mutex_unlock(&callThreadsLock);
|
|
|
|
pfds[0].fd = mycthread->thePipe[0];
|
|
pfds[0].events = POLLIN;
|
|
ooSocketPoll(pfds, 1, SEC_TO_HOLD_THREAD * 1000);
|
|
if (ooPDRead(pfds, 1, mycthread->thePipe[0]))
|
|
res = read(mycthread->thePipe[0], &c, 1);
|
|
|
|
ast_mutex_lock(&callThreadsLock);
|
|
ast_mutex_lock(&mycthread->lock);
|
|
if (mycthread->prev)
|
|
mycthread->prev->next = mycthread->next;
|
|
else
|
|
callThreads = mycthread->next;
|
|
if (mycthread->next)
|
|
mycthread->next->prev = mycthread->prev;
|
|
ast_mutex_unlock(&mycthread->lock);
|
|
ast_mutex_unlock(&callThreadsLock);
|
|
|
|
} while (mycthread->call != NULL && res >= 0);
|
|
|
|
|
|
ast_mutex_destroy(&mycthread->lock);
|
|
|
|
close(mycthread->thePipe[0]);
|
|
close(mycthread->thePipe[1]);
|
|
free(mycthread);
|
|
ast_module_unref(myself);
|
|
ast_update_use_count();
|
|
return NULL;
|
|
}
|
|
|
|
int ooh323c_start_call_thread(ooCallData *call) {
|
|
char c = 'c';
|
|
struct callthread *cur = callThreads;
|
|
|
|
ast_mutex_lock(&callThreadsLock);
|
|
while (cur != NULL && (cur->inUse || ast_mutex_trylock(&cur->lock))) {
|
|
cur = cur->next;
|
|
}
|
|
ast_mutex_unlock(&callThreadsLock);
|
|
|
|
if (cur != NULL) {
|
|
if (cur->inUse || write(cur->thePipe[1], &c, 1) < 0) {
|
|
ast_mutex_unlock(&cur->lock);
|
|
cur = NULL;
|
|
}
|
|
}
|
|
|
|
/* make new thread */
|
|
if (cur == NULL) {
|
|
if (!(cur = ast_calloc(1, sizeof(struct callthread)))) {
|
|
ast_log(LOG_ERROR, "Unable to allocate thread structure for call %s\n",
|
|
call->callToken);
|
|
return -1;
|
|
}
|
|
|
|
ast_module_ref(myself);
|
|
if ((socketpair(PF_LOCAL, SOCK_STREAM, 0, cur->thePipe)) == -1) {
|
|
ast_log(LOG_ERROR, "Can't create thread pipe for call %s\n", call->callToken);
|
|
free(cur);
|
|
return -1;
|
|
}
|
|
cur->inUse = TRUE;
|
|
cur->call = call;
|
|
|
|
ast_mutex_init(&cur->lock);
|
|
|
|
if (gH323Debug)
|
|
ast_debug(1,"new call thread created for call %s\n", call->callToken);
|
|
|
|
if(ast_pthread_create_detached_background(&call->callThread, NULL, ooh323c_call_thread, cur) < 0)
|
|
{
|
|
ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n",
|
|
call->callToken);
|
|
ast_mutex_destroy(&cur->lock);
|
|
close(cur->thePipe[0]);
|
|
close(cur->thePipe[1]);
|
|
free(cur);
|
|
return -1;
|
|
}
|
|
|
|
} else {
|
|
if (gH323Debug)
|
|
ast_debug(1,"using existing call thread for call %s\n", call->callToken);
|
|
cur->inUse = TRUE;
|
|
cur->call = call;
|
|
ast_mutex_unlock(&cur->lock);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int ooh323c_stop_call_thread(ooCallData *call) {
|
|
if (call->callThread != AST_PTHREADT_NULL) {
|
|
ooStopMonitorCallChannels(call);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ooh323c_start_stack_thread()
|
|
{
|
|
if(ast_pthread_create_background(&ooh323c_thread, NULL, ooh323c_stack_thread, NULL) < 0)
|
|
{
|
|
ast_log(LOG_ERROR, "Unable to start ooh323c thread.\n");
|
|
return -1;
|
|
}
|
|
if(ast_pthread_create_background(&ooh323cmd_thread, NULL, ooh323c_cmd_thread, NULL) < 0)
|
|
{
|
|
ast_log(LOG_ERROR, "Unable to start ooh323cmd thread.\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ooh323c_stop_stack_thread(void)
|
|
{
|
|
if(ooh323c_thread != AST_PTHREADT_NULL)
|
|
{
|
|
ooStopMonitor();
|
|
pthread_join(ooh323c_thread, NULL);
|
|
ooh323c_thread = AST_PTHREADT_NULL;
|
|
pthread_join(ooh323cmd_thread, NULL);
|
|
ooh323cmd_thread = AST_PTHREADT_NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ooh323c_set_capability
|
|
(struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec)
|
|
{
|
|
int ret = 0, x;
|
|
struct ast_format tmpfmt;
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding capabilities to H323 endpoint\n");
|
|
}
|
|
|
|
for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
|
|
{
|
|
if(tmpfmt.id == AST_FORMAT_ULAW)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g711 ulaw capability to H323 endpoint\n");
|
|
}
|
|
ret= ooH323EpAddG711Capability(OO_G711ULAW64K, gtxframes, grxframes,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
}
|
|
if(tmpfmt.id == AST_FORMAT_ALAW)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g711 alaw capability to H323 endpoint\n");
|
|
}
|
|
ret= ooH323EpAddG711Capability(OO_G711ALAW64K, gtxframes, grxframes,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_G729A)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g729A capability to H323 endpoint\n");
|
|
}
|
|
ret = ooH323EpAddG729Capability(OO_G729A, 2, 24,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g729 capability to H323 endpoint\n");
|
|
}
|
|
ret |= ooH323EpAddG729Capability(OO_G729, 2, 24,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g729b capability to H323 endpoint\n");
|
|
}
|
|
ret |= ooH323EpAddG729Capability(OO_G729B, 2, 24,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_G723_1)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g7231 capability to H323 endpoint\n");
|
|
}
|
|
ret = ooH323EpAddG7231Capability(OO_G7231, 1, 1, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_G726)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g726 capability to H323 endpoint\n");
|
|
}
|
|
ret = ooH323EpAddG726Capability(OO_G726, gtxframes, grxframes, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_G726_AAL2)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g726aal2 capability to H323 endpoint\n");
|
|
}
|
|
ret = ooH323EpAddG726Capability(OO_G726AAL2, gtxframes, grxframes, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_H263)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding h263 capability to H323 endpoint\n");
|
|
}
|
|
ret = ooH323EpAddH263VideoCapability(OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_GSM)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding gsm capability to H323 endpoint\n");
|
|
}
|
|
ret = ooH323EpAddGSMCapability(OO_GSMFULLRATE, 4, FALSE, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
#ifdef AST_FORMAT_AMRNB
|
|
if(tmpfmt.id == AST_FORMAT_AMRNB)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding amr nb capability to H323 endpoint\n");
|
|
}
|
|
ret = ooH323EpAddAMRNBCapability(OO_AMRNB, 4, 4, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef AST_FORMAT_SPEEX
|
|
if(tmpfmt.id == AST_FORMAT_SPEEX)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding speex capability to H323 endpoint\n");
|
|
}
|
|
ret = ooH323EpAddSpeexCapability(OO_SPEEX, 4, 4, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
if(dtmf & H323_DTMF_CISCO)
|
|
ret |= ooH323EpEnableDTMFCISCO(0);
|
|
if(dtmf & H323_DTMF_RFC2833)
|
|
ret |= ooH323EpEnableDTMFRFC2833(0);
|
|
else if(dtmf & H323_DTMF_H245ALPHANUMERIC)
|
|
ret |= ooH323EpEnableDTMFH245Alphanumeric();
|
|
else if(dtmf & H323_DTMF_H245SIGNAL)
|
|
ret |= ooH323EpEnableDTMFH245Signal();
|
|
|
|
return ret;
|
|
}
|
|
|
|
int ooh323c_set_capability_for_call
|
|
(ooCallData *call, struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
|
|
int t38support, int g729onlyA)
|
|
{
|
|
int ret = 0, x, txframes;
|
|
struct ast_format tmpfmt;
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding capabilities to call(%s, %s)\n", call->callType,
|
|
call->callToken);
|
|
}
|
|
if(dtmf & H323_DTMF_CISCO || 1)
|
|
ret |= ooCallEnableDTMFCISCO(call,dtmfcodec);
|
|
if(dtmf & H323_DTMF_RFC2833 || 1)
|
|
ret |= ooCallEnableDTMFRFC2833(call,dtmfcodec);
|
|
if(dtmf & H323_DTMF_H245ALPHANUMERIC || 1)
|
|
ret |= ooCallEnableDTMFH245Alphanumeric(call);
|
|
if(dtmf & H323_DTMF_H245SIGNAL || 1)
|
|
ret |= ooCallEnableDTMFH245Signal(call);
|
|
|
|
if (t38support)
|
|
ooCapabilityAddT38Capability(call, OO_T38, OORXANDTX,
|
|
&ooh323c_start_receive_datachannel,
|
|
&ooh323c_start_transmit_datachannel,
|
|
&ooh323c_stop_receive_datachannel,
|
|
&ooh323c_stop_transmit_datachannel,
|
|
0);
|
|
|
|
for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
|
|
{
|
|
if(tmpfmt.id == AST_FORMAT_ULAW)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g711 ulaw capability to call(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
txframes = prefs->framing[x];
|
|
ret= ooCallAddG711Capability(call, OO_G711ULAW64K, txframes,
|
|
txframes, OORXANDTX,
|
|
&ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
}
|
|
if(tmpfmt.id == AST_FORMAT_ALAW)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g711 alaw capability to call(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
txframes = prefs->framing[x];
|
|
ret= ooCallAddG711Capability(call, OO_G711ALAW64K, txframes,
|
|
txframes, OORXANDTX,
|
|
&ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_G726)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g726 capability to call (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
txframes = prefs->framing[x];
|
|
ret = ooCallAddG726Capability(call, OO_G726, txframes, grxframes, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_G726_AAL2)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g726aal2 capability to call (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
txframes = prefs->framing[x];
|
|
ret = ooCallAddG726Capability(call, OO_G726AAL2, txframes, grxframes, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_G729A)
|
|
{
|
|
|
|
txframes = (prefs->framing[x])/10;
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g729A capability to call(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
ret= ooCallAddG729Capability(call, OO_G729A, txframes, txframes,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
if (g729onlyA)
|
|
continue;
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g729 capability to call(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g729B capability to call(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_G723_1)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding g7231 capability to call (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_H263)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding h263 capability to call (%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
|
|
}
|
|
|
|
if(tmpfmt.id == AST_FORMAT_GSM)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding gsm capability to call(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
ret = ooCallAddGSMCapability(call, OO_GSMFULLRATE, 4, FALSE, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
}
|
|
|
|
#ifdef AST_FORMAT_AMRNB
|
|
if(tmpfmt.id == AST_FORMAT_AMRNB)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding AMR capability to call(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
ret = ooCallAddAMRNBCapability(call, OO_AMRNB, 4, 4, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
}
|
|
#endif
|
|
#ifdef AST_FORMAT_SPEEX
|
|
if(tmpfmt.id == AST_FORMAT_SPEEX)
|
|
{
|
|
if (gH323Debug) {
|
|
ast_verb(0, "\tAdding Speex capability to call(%s, %s)\n",
|
|
call->callType, call->callToken);
|
|
}
|
|
ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE,
|
|
OORXANDTX, &ooh323c_start_receive_channel,
|
|
&ooh323c_start_transmit_channel,
|
|
&ooh323c_stop_receive_channel,
|
|
&ooh323c_stop_transmit_channel);
|
|
}
|
|
#endif
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ooh323c_set_aliases(ooAliases * aliases)
|
|
{
|
|
ooAliases *cur = aliases;
|
|
while(cur)
|
|
{
|
|
switch(cur->type)
|
|
{
|
|
case T_H225AliasAddress_dialedDigits:
|
|
ooH323EpAddAliasDialedDigits(cur->value);
|
|
break;
|
|
case T_H225AliasAddress_h323_ID:
|
|
ooH323EpAddAliasH323ID(cur->value);
|
|
break;
|
|
case T_H225AliasAddress_url_ID:
|
|
ooH323EpAddAliasURLID(cur->value);
|
|
break;
|
|
case T_H225AliasAddress_email_ID:
|
|
ooH323EpAddAliasEmailID(cur->value);
|
|
break;
|
|
default:
|
|
ast_debug(1, "Ignoring unknown alias type\n");
|
|
}
|
|
cur = cur->next;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
|
|
{
|
|
struct ast_format tmpfmt;
|
|
convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
|
|
if(tmpfmt.id) {
|
|
/* ooh323_set_read_format(call, fmt); */
|
|
}else{
|
|
ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
|
|
call->callToken);
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
|
|
{
|
|
struct ast_format tmpfmt;
|
|
convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
|
|
if(tmpfmt.id) {
|
|
switch (tmpfmt.id) {
|
|
case AST_FORMAT_ALAW:
|
|
case AST_FORMAT_ULAW:
|
|
ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
|
|
break;
|
|
case AST_FORMAT_G729A:
|
|
ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
|
|
break;
|
|
default:
|
|
ooh323_set_write_format(call, &tmpfmt, 0);
|
|
}
|
|
}else{
|
|
ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
|
|
call->callToken);
|
|
return -1;
|
|
}
|
|
setup_rtp_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
|
|
return 1;
|
|
}
|
|
|
|
int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int ooh323c_stop_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
|
|
{
|
|
close_rtp_connection(call);
|
|
return 1;
|
|
}
|
|
|
|
|
|
int ooh323c_start_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int ooh323c_start_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
|
|
{
|
|
setup_udptl_connection(call, pChannel->remoteIP, pChannel->remoteMediaPort);
|
|
return 1;
|
|
}
|
|
|
|
int ooh323c_stop_receive_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChannel)
|
|
{
|
|
close_udptl_connection(call);
|
|
return 1;
|
|
}
|
|
|
|
struct ast_format *convertH323CapToAsteriskCap(int cap, struct ast_format *result)
|
|
{
|
|
ast_format_clear(result);
|
|
switch(cap)
|
|
{
|
|
case OO_G711ULAW64K:
|
|
return ast_format_set(result, AST_FORMAT_ULAW, 0);
|
|
case OO_G711ALAW64K:
|
|
return ast_format_set(result, AST_FORMAT_ALAW, 0);
|
|
case OO_GSMFULLRATE:
|
|
return ast_format_set(result, AST_FORMAT_GSM, 0);
|
|
|
|
#ifdef AST_FORMAT_AMRNB
|
|
case OO_AMRNB:
|
|
return ast_format_set(result, AST_FORMAT_AMRNB, 0);
|
|
#endif
|
|
#ifdef AST_FORMAT_SPEEX
|
|
case OO_SPEEX:
|
|
return ast_format_set(result, AST_FORMAT_SPEEX, 0);
|
|
#endif
|
|
|
|
case OO_G729:
|
|
return ast_format_set(result, AST_FORMAT_G729A, 0);
|
|
case OO_G729A:
|
|
return ast_format_set(result, AST_FORMAT_G729A, 0);
|
|
case OO_G729B:
|
|
return ast_format_set(result, AST_FORMAT_G729A, 0);
|
|
case OO_G7231:
|
|
return ast_format_set(result, AST_FORMAT_G723_1, 0);
|
|
case OO_G726:
|
|
return ast_format_set(result, AST_FORMAT_G726, 0);
|
|
case OO_G726AAL2:
|
|
return ast_format_set(result, AST_FORMAT_G726_AAL2, 0);
|
|
case OO_H263VIDEO:
|
|
return ast_format_set(result, AST_FORMAT_H263, 0);
|
|
default:
|
|
ast_debug(1, "Cap %d is not supported by driver yet\n", cap);
|
|
return NULL;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|