[asterisk-commits] may: branch may/chan_ooh323_rework r207350 - in /team/may/chan_ooh323_rework/...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat Jul 18 21:50:16 CDT 2009
Author: may
Date: Sat Jul 18 21:50:11 2009
New Revision: 207350
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=207350
Log:
initial t.38 support in transparent audio->t38 mode
now accept request mode, sent req mode ack and work with t38
Modified:
team/may/chan_ooh323_rework/addons/chan_ooh323.c
team/may/chan_ooh323_rework/addons/chan_ooh323.h
team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.c
team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.h
team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.c
team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.h
team/may/chan_ooh323_rework/addons/ooh323c/src/ooh245.c
team/may/chan_ooh323_rework/addons/ooh323c/src/ooh323ep.c
team/may/chan_ooh323_rework/addons/ooh323c/src/ooq931.c
team/may/chan_ooh323_rework/addons/ooh323c/src/ootypes.h
team/may/chan_ooh323_rework/addons/ooh323cDriver.c
Modified: team/may/chan_ooh323_rework/addons/chan_ooh323.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/may/chan_ooh323_rework/addons/chan_ooh323.c?view=diff&rev=207350&r1=207349&r2=207350
==============================================================================
--- team/may/chan_ooh323_rework/addons/chan_ooh323.c (original)
+++ team/may/chan_ooh323_rework/addons/chan_ooh323.c Sat Jul 18 21:50:11 2009
@@ -16,6 +16,8 @@
#include "chan_ooh323.h"
+#include <math.h>
+#include <spandsp.h>
/* Defaults */
#define DEFAULT_CONTEXT "default"
@@ -57,6 +59,9 @@
static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp,
struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, int codecs, int nat_active);
+
+static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan);
+static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
static void ast_ooh323c_exit();
@@ -88,6 +93,14 @@
.update_peer = ooh323_set_rtp_peer,
};
+static struct ast_udptl_protocol ooh323_udptl = {
+ type: "H323",
+ get_udptl_info: ooh323_get_udptl_peer,
+ set_udptl_peer: ooh323_set_udptl_peer,
+};
+
+
+
struct ooh323_user;
/* H.323 channel private structure */
@@ -95,6 +108,15 @@
ast_mutex_t lock; /* Channel private lock */
struct ast_rtp_instance *rtp;
struct ast_rtp_instance *vrtp; /* Placeholder for now */
+
+ struct ast_udptl *udptl;
+ int faxmode;
+ int t38_tx_enable;
+ int t38_init;
+ t38_gateway_state_t t38r_state;
+ struct sockaddr_in udptlredirip;
+ time_t lastTxT38;
+
struct ast_channel *owner; /* Master Channel */
union {
char *user; /* cooperating user/peer */
@@ -209,6 +231,7 @@
int onOutgoingCall(ooCallData *call);
int onCallEstablished(ooCallData *call);
int onCallCleared(ooCallData *call);
+void onModeChanged(ooCallData *call, int t38mode);
static char gLogFile[256] = DEFAULT_LOGFILE;
static int gPort = 1720;
@@ -294,6 +317,7 @@
ast_channel_set_fd(ch, 0, ast_rtp_instance_fd(i->rtp, 0));
ast_channel_set_fd(ch, 1, ast_rtp_instance_fd(i->rtp, 1));
+ ast_channel_set_fd(ch, 5, ast_udptl_fd(i->udptl));
if (state == AST_STATE_RING)
ch->rings = 1;
@@ -413,6 +437,18 @@
}
ast_rtp_instance_set_qos(pvt->rtp, gTOS, 0, "ooh323-rtp");
+
+ if (!(pvt->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, ipAddr))) {
+ ast_log(LOG_WARNING, "Unable to create UDPTL session: %s\n",
+ strerror(errno));
+ ast_mutex_unlock(&pvt->lock);
+ ast_mutex_destroy(&pvt->lock);
+ free(pvt);
+ return NULL;
+ }
+
+ ast_udptl_set_error_correction_scheme(pvt->udptl, UDPTL_ERROR_CORRECTION_NONE);
+ pvt->faxmode = 0;
pvt->call_reference = callref;
if (callToken)
@@ -979,18 +1015,65 @@
struct ooh323_pvt *p = ast->tech_pvt;
int res = 0;
char *callToken = (char *)NULL;
+ int16_t* t38data;
+ int t38samples;
if (p) {
ast_mutex_lock(&p->lock);
+
+ if (f->frametype == AST_FRAME_MODEM) {
+ ast_debug(1, "Send UDPTL %d/%d len %d for %s\n",
+ f->frametype, f->subclass, f->datalen, ast->name);
+ if (p->udptl)
+ res = ast_udptl_write(p->udptl, f);
+ ast_mutex_unlock(&p->lock);
+ return res;
+ }
+
+ if (f->frametype == AST_FRAME_VOICE) {
/* sending progress for first */
- if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent) {
- callToken = (p->callToken ? strdup(p->callToken) : NULL);
- ooManualProgress(callToken);
- p->progsent = 1;
- free(callToken);
- }
- if (f->frametype == AST_FRAME_VOICE) {
+ if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent) {
+ callToken = (p->callToken ? strdup(p->callToken) : NULL);
+ ooManualProgress(callToken);
+ p->progsent = 1;
+ free(callToken);
+ }
+
+
+/* if we are in fax t30-t38 transparent mode */
+
+ if (p->faxmode) {
+ if (f->subclass == AST_FORMAT_SLINEAR) {
+ t38data = f->data.ptr;
+ t38samples = f->samples;
+ } else {
+ t38samples = 0;
+ ast_verbose("Got non-slin frame for %s in fax mode\n",
+ ast->name);
+ ast_set_write_format(ast, AST_FORMAT_SLINEAR);
+ ast_set_read_format(ast, AST_FORMAT_SLINEAR);
+ ast_mutex_unlock(&p->lock);
+ return 0;
+ }
+
+ if (t38samples) {
+ t38_gateway_rx(&p->t38r_state, t38data, t38samples);
+ if (gH323Debug)
+ ast_debug(4, "t38gw_rx %d\n", t38samples);
+ }
+ res = f->samples;
+ time_t ct = time(NULL);
+ /* if (ct - pvt->lastTxT38 > T38TOAUDIOTIMEOUT && !p->chmodepend) {
+ ast_debug(1,"request to change %s to audio because t38 timeout\n", ast->name);
+ h323_mode_change(token,0);
+ pvt->chmodepend = 1;
+ } */
+ ast_mutex_unlock(&p->lock);
+ return res;
+ }
+
+
if (!(f->subclass & ast->nativeformats)) {
if (ast->nativeformats != 0) {
ast_log(LOG_WARNING, "Asked to transmit frame type %d,"
@@ -2763,7 +2846,8 @@
.onCallEstablished = onCallEstablished,
.onCallCleared = onCallCleared,
.openLogicalChannels = NULL,
- .onReceivedDTMF = &ooh323_onReceivedDigit
+ .onReceivedDTMF = &ooh323_onReceivedDigit,
+ .onModeChanged = onModeChanged
};
ast_log(LOG_NOTICE,
@@ -2800,6 +2884,7 @@
return 0;
}
ast_rtp_glue_register(&ooh323_rtp);
+ ast_udptl_proto_register(&ooh323_udptl);
ast_cli_register_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry));
/* fire up the H.323 Endpoint */
@@ -3064,7 +3149,12 @@
if (cur->rtp) {
ast_rtp_instance_destroy(cur->rtp);
- cur->rtp = 0;
+ cur->rtp = NULL;
+ }
+
+ if (cur->udptl) {
+ ast_udptl_destroy(cur->udptl);
+ cur->udptl = NULL;
}
/* Unlink us from the owner if we have one */
@@ -3169,6 +3259,7 @@
/* First, take us out of the channel loop */
ast_cli_unregister_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry));
ast_rtp_glue_unregister(&ooh323_rtp);
+ ast_udptl_proto_unregister(&ooh323_udptl);
ast_channel_unregister(&ooh323_tech);
#if 0
ast_unregister_atexit(&ast_ooh323c_exit);
@@ -3437,6 +3528,16 @@
}
}
+ ast_udptl_get_us(p->udptl, &us);
+ ast_copy_string(mediaInfo.lMediaIP, ast_inet_ntoa(us.sin_addr), sizeof(mediaInfo.lMediaIP));
+ mediaInfo.lMediaPort = ntohs(us.sin_port);
+ mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
+ mediaInfo.cap = OO_T38;
+ strcpy(mediaInfo.dir, "transmit");
+ ooAddMediaInfo(call, mediaInfo);
+ strcpy(mediaInfo.dir, "receive");
+ ooAddMediaInfo(call, mediaInfo);
+
if (gH323Debug)
ast_verbose("+++ configure_local_rtp\n");
@@ -3448,7 +3549,6 @@
{
struct ooh323_pvt *p = NULL;
struct sockaddr_in them;
- char *callToken = (char *)NULL;
if (gH323Debug)
ast_verbose("--- setup_rtp_connection\n");
@@ -3501,6 +3601,103 @@
return;
}
+/*
+ udptl handling functions
+ */
+
+static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan)
+{
+ struct ooh323_pvt *p;
+ struct ast_udptl *udptl = NULL;
+
+ p = chan->tech_pvt;
+ if (!p)
+ return NULL;
+
+ ast_mutex_lock(&p->lock);
+ if (p->udptl)
+ udptl = p->udptl;
+ ast_mutex_unlock(&p->lock);
+ return udptl;
+}
+
+static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl)
+{
+ struct ooh323_pvt *p;
+
+ p = chan->tech_pvt;
+ if (!p)
+ return -1;
+ ast_mutex_lock(&p->lock);
+ if (udptl)
+ ast_udptl_get_peer(udptl, &p->udptlredirip);
+ else
+ memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
+
+ ast_mutex_unlock(&p->lock);
+ return 0;
+}
+
+void setup_udptl_connection(ooCallData *call, const char *remoteIp,
+ int remotePort)
+{
+ struct ooh323_pvt *p = NULL;
+ struct sockaddr_in them;
+
+ if (gH323Debug)
+ ast_verbose("--- setup_udptl_connection\n");
+
+ /* Find the call or allocate a private structure if call not found */
+ p = find_call(call);
+
+ if (!p) {
+ ast_log(LOG_ERROR, "Something is wrong: rtp\n");
+ return;
+ }
+
+ ast_mutex_lock(&p->lock);
+
+ them.sin_family = AF_INET;
+ them.sin_addr.s_addr = inet_addr(remoteIp); /* only works for IPv4 */
+ them.sin_port = htons(remotePort);
+ ast_udptl_set_peer(p->udptl, &them);
+ p->t38_tx_enable = 1;
+ p->lastTxT38 = time(NULL);
+ if (gH323Debug)
+ ast_debug(1, "Receiving UDPTL %s:%d\n", ast_inet_ntoa(them.sin_addr),
+ ntohs(them.sin_port));
+ ast_mutex_unlock(&p->lock);
+
+ if(gH323Debug)
+ ast_verbose("+++ setup_udptl_connection\n");
+
+ return;
+}
+
+void close_udptl_connection(ooCallData *call)
+{
+ struct ooh323_pvt *p = NULL;
+
+ if(gH323Debug)
+ ast_verbose("--- close_udptl_connection\n");
+
+ p = find_call(call);
+ if (!p) {
+ ast_log(LOG_ERROR, "Couldn't find matching call to close udptl "
+ "connection\n");
+ return;
+ }
+ ast_mutex_lock(&p->lock);
+ p->t38_tx_enable = 0;
+ ast_mutex_unlock(&p->lock);
+
+ if(gH323Debug)
+ ast_verbose("+++ close_udptl_connection\n");
+
+ return;
+}
+
+/* end of udptl handling */
int update_our_aliases(ooCallData *call, struct ooh323_pvt *p)
{
@@ -3549,6 +3746,19 @@
case 3:
f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */
break;
+ case 5:
+ f = ast_udptl_read(p->udptl); /* UDPTL t.38 data */
+ if (gH323Debug) ast_debug(1, "Got UDPTL %d/%d len %d for %s\n",
+ f->frametype, f->subclass, f->datalen, ast->name);
+ if (!p->faxmode) p->faxmode = 1;
+ if (p->t38_init) {
+ t38_core_rx_ifp_packet(&p->t38r_state.t38, (uint8_t *)f->data.ptr,
+ f->datalen, 0);
+ p->lastTxT38 = time(NULL);
+ }
+ f = &null_frame;
+ break;
+
default:
f = &null_frame;
}
@@ -3580,6 +3790,189 @@
}
return f;
}
+
+#define MAXT30 240
+
+static int t30_read(const void *data) {
+
+ struct ast_channel *c = (struct ast_channel *) data;
+ struct ooh323_pvt *p = (struct ooh323_pvt *) c->tech_pvt;
+ int len;
+
+ static uint8_t buffer[AST_FRIENDLY_OFFSET + MAXT30 * sizeof(uint16_t)];
+ int16_t *buf = (int16_t *) (buffer + AST_FRIENDLY_OFFSET);
+ static struct ast_frame outf = {
+ .frametype = AST_FRAME_VOICE,
+ .subclass = AST_FORMAT_SLINEAR,
+ };
+
+
+ if (!p) {
+ ast_log(LOG_ERROR, "No private structure for %s\n", c->name);
+ return 0;
+ }
+
+ ast_mutex_lock(&p->lock);
+
+ if (p->owner) {
+ while (p->owner && ast_channel_trylock(c)) {
+ ast_debug(1,"Failed to grab lock, trying again\n");
+ ast_mutex_unlock(&p->lock);
+ usleep(1);
+ ast_mutex_lock(&p->lock);
+ }
+ if (!p->owner) {
+ ast_mutex_unlock(&p->lock);
+ ast_log(LOG_ERROR, "Channel has no owner\n");
+ return 0;
+ }
+ } else {
+ ast_mutex_unlock(&p->lock);
+ ast_log(LOG_ERROR, "Channel has no owner\n");
+ return 0;
+ }
+
+
+
+ if (p->faxmode && p->t38_init && p->t38_tx_enable) {
+
+ if ((len = t38_gateway_tx(&p->t38r_state, buf, MAXT30))) {
+
+ outf.samples = len;
+ AST_FRAME_SET_BUFFER(&outf, buffer, AST_FRIENDLY_OFFSET,
+ len * sizeof(int16_t));
+ ast_queue_frame(c, &outf);
+
+ }
+ }
+
+ ast_settimeout(c, 50, t30_read, c);
+ ast_channel_unlock(c);
+ ast_mutex_unlock(&p->lock);
+ return 0;
+}
+
+
+static int t38_tx_packet_handler(t38_core_state_t *s, void *data,
+ unsigned int* buf, int len, int cout)
+{
+ struct ast_frame f = { AST_FRAME_MODEM, AST_MODEM_T38 };
+ struct ooh323_pvt* p = (struct ooh323_pvt*) data;
+ int res;
+ f.datalen = len;
+ f.data.ptr = buf;
+ f.offset = 0;
+
+ if (gH323Debug)
+ ast_debug(1, "Sending UDPTL packet of %d bytes\n", len);
+ if (p) {
+ ast_mutex_lock(&p->lock);
+ if (p->udptl) {
+ res = ast_udptl_write(p->udptl, &f);
+ p->lastTxT38 = time(NULL);
+ }
+ ast_mutex_unlock(&p->lock);
+ }
+ return 0;
+
+}
+
+static void span_message(int level, const char* msg) {
+ if (gH323Debug) ast_debug(1, msg);
+}
+
+
+void onModeChanged(ooCallData *call, int t38mode) {
+ struct ooh323_pvt *p;
+ struct ast_frame f;
+
+ p = find_call(call);
+ if (!p) {
+ ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken);
+ return;
+ }
+
+ ast_mutex_lock(&p->lock);
+
+ if (gH323Debug)
+ ast_debug(1, "change mode to %d for %s\n", t38mode, call->callToken);
+
+ if (p->owner) {
+ while (p->owner && ast_channel_trylock(p->owner)) {
+ ast_debug(1,"Failed to grab lock, trying again\n");
+ ast_mutex_unlock(&p->lock);
+ usleep(1);
+ ast_mutex_lock(&p->lock);
+ }
+ if (!p->owner) {
+ ast_mutex_unlock(&p->lock);
+ ast_log(LOG_ERROR, "Channel has no owner\n");
+ return;
+ }
+ } else {
+ ast_mutex_unlock(&p->lock);
+ ast_log(LOG_ERROR, "Channel has no owner\n");
+ return;
+ }
+
+#if 0
+ f.frametype = AST_FRAME_MODEM;
+ f.subclass = 'c';
+ f.datalen = 0;
+ f.samples = 0;
+ f.offset = 0;
+ f.data = NULL;
+ f.mallocd = 0;
+ f.src = "CHANGE_MODE";
+ if (p->owner && !ast_channel_trylock(pvt->owner)) {
+ ast_queue_frame(pvt->owner, &f);
+ ast_mutex_unlock(&pvt->owner->lock);
+ }
+#endif
+
+ if (t38mode) {
+
+ if (t38_gateway_init(&p->t38r_state, t38_tx_packet_handler, p)) {
+ p->t38_init = 1;
+ t38_gateway_set_transmit_on_idle(&p->t38r_state, FALSE);
+ span_log_set_tag(&p->t38r_state.logging, "T.38G");
+ span_log_set_tag(&p->t38r_state.t38.logging, "T.38");
+ span_log_set_message_handler(&p->t38r_state.logging, span_message);
+ span_log_set_message_handler(&p->t38r_state.t38.logging, span_message);
+ span_log_set_level(&p->t38r_state.logging,
+ SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
+ span_log_set_level(&p->t38r_state.t38.logging,
+ SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
+
+ t38_set_t38_version(&p->t38r_state.t38, 0);
+ t38_set_sequence_number_handling(&p->t38r_state.t38,0);
+ t38_gateway_set_ecm_capability(&p->t38r_state, 1);
+ t38_gateway_set_tep_mode(&p->t38r_state, TRUE);
+ t38_gateway_set_supported_modems(&p->t38r_state,
+ T30_SUPPORT_V17 | T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
+ if (gH323Debug)
+ ast_debug(1,"Going to change native format for %s\n", call->callToken);
+ p->owner->nativeformats = AST_FORMAT_SLINEAR;
+ p->owner->rawreadformat = AST_FORMAT_SLINEAR;
+ p->owner->rawwriteformat = AST_FORMAT_SLINEAR;
+ ast_set_read_format(p->owner, p->owner->rawreadformat);
+ ast_set_write_format(p->owner, p->owner->rawwriteformat);
+ p->faxmode = 1;
+ ast_channel_unlock(p->owner);
+ ast_settimeout(p->owner, 50, t30_read, p->owner);
+ ast_channel_lock(p->owner);
+ }
+ } else {
+ p->faxmode = 0;
+ p->t38_init = 0;
+ /* p->chmodepending = 0; */
+ }
+
+
+ ast_channel_unlock(p->owner);
+ ast_mutex_unlock(&p->lock);
+}
+
int ooh323_convert_hangupcause_asteriskToH323(int cause)
Modified: team/may/chan_ooh323_rework/addons/chan_ooh323.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/may/chan_ooh323_rework/addons/chan_ooh323.h?view=diff&rev=207350&r1=207349&r2=207350
==============================================================================
--- team/may/chan_ooh323_rework/addons/chan_ooh323.h (original)
+++ team/may/chan_ooh323_rework/addons/chan_ooh323.h Sat Jul 18 21:50:11 2009
@@ -62,6 +62,8 @@
#include <asterisk/dsp.h>
#include <asterisk/stringfields.h>
+#include <asterisk/udptl.h>
+
#include "ootypes.h"
#include "ooCapability.h"
#include "oochannels.h"
Modified: team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.c?view=diff&rev=207350&r1=207349&r2=207350
==============================================================================
--- team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.c (original)
+++ team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.c Sat Jul 18 21:50:11 2009
@@ -98,6 +98,10 @@
if (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN))
OO_SETFLAG (call->flags, OO_M_MEDIAWAITFORCONN);
+
+// May 20090713. Fix it for Video session
+
+ OO_SETFLAG(call->flags, OO_M_AUDIOSESSION);
call->callState = OO_CALL_CREATED;
call->callEndReason = OO_REASON_UNKNOWN;
@@ -827,6 +831,23 @@
}
}
}
+ if(type == OO_CAP_TYPE_DATA)
+ {
+ if(!ooGetLogicalChannel(call, 3, dir))
+ {
+ sessionID = 3;
+ }
+ else{
+ if(call->masterSlaveState == OO_MasterSlave_Master)
+ sessionID = call->nextSessionID++;
+ else{
+ sessionID = 0; /* Will be assigned by remote */
+ OOTRACEDBGC4("Session id for %s channel of type data has to be "
+ "provided by remote.(%s, %s)\n", dir, call->callType,
+ call->callToken);
+ }
+ }
+ }
return sessionID;
}
Modified: team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.h?view=diff&rev=207350&r1=207349&r2=207350
==============================================================================
--- team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.h (original)
+++ team/may/chan_ooh323_rework/addons/ooh323c/src/ooCalls.h Sat Jul 18 21:50:11 2009
@@ -55,6 +55,8 @@
#define OO_M_MANUALRINGBACK ASN1UINTCNT(0x10000000)
#define OO_M_TRYBEMASTER ASN1UINTCNT(0x00000010)
+#define OO_M_AUDIOSESSION ASN1UINTCNT(0x00000100)
+#define OO_M_DATASESSION ASN1UINTCNT(0x00000200)
/**
* Call states.
@@ -292,6 +294,14 @@
(struct OOH323CallData *call, const char *dtmf);
/**
+ * This callback function is triggered when dtmf is received over Q.931(keypad)
+ * or H.245(alphanumeric) or H.245(signal). This is not triggered when rfc
+ * 2833 based dtmf is received.
+ */
+typedef int (*cb_OnModeChanged)
+ (struct OOH323CallData *call, int isT38Mode);
+
+/**
* This structure holds all of the H.323 signaling callback function
* addresses.
* @see ooH323EpSetH323Callbacks
@@ -307,6 +317,7 @@
cb_OnCallCleared onCallCleared;
cb_OpenLogicalChannels openLogicalChannels;
cb_OnReceivedDTMF onReceivedDTMF;
+ cb_OnModeChanged onModeChanged;
} OOH323CALLBACKS;
/**
Modified: team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.c?view=diff&rev=207350&r1=207349&r2=207350
==============================================================================
--- team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.c (original)
+++ team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.c Sat Jul 18 21:50:11 2009
@@ -452,7 +452,6 @@
return OO_OK;
}
-
int ooCapabilityAddGSMCapability(OOH323CallData *call, int cap,
unsigned framesPerPkt, OOBOOL comfortNoise,
OOBOOL scrambled, int dir,
@@ -544,6 +543,98 @@
}
}
+ return OO_OK;
+}
+
+/* Used for T38 */
+int ooCapabilityAddT38Capability
+ (OOH323CallData *call, int cap, int dir,
+ cb_StartReceiveChannel startReceiveChannel,
+ cb_StartTransmitChannel startTransmitChannel,
+ cb_StopReceiveChannel stopReceiveChannel,
+ cb_StopTransmitChannel stopTransmitChannel,
+ OOBOOL remote)
+{
+ ooH323EpCapability *epCap = NULL, *cur=NULL;
+ OOCapParams *params=NULL;
+ OOCTXT *pctxt=NULL;
+ if(!call) pctxt = &gH323ep.ctxt;
+ else pctxt = call->pctxt;
+
+ epCap = (ooH323EpCapability*)memAllocZ(pctxt, sizeof(ooH323EpCapability));
+ params = (OOCapParams*) memAlloc(pctxt, sizeof(OOCapParams));
+ memset(params, 0 , sizeof(OOCapParams));
+ if(!epCap || !params)
+ {
+ OOTRACEERR1("ERROR: Memory - ooCapabilityAddT38Capability - "
+ "epCap/params\n");
+ return OO_FAILED;
+ }
+
+ if(dir & OORXANDTX) {
+ epCap->dir = OORX;
+ epCap->dir |= OOTX;
+ }
+ else {
+ epCap->dir = dir;
+ }
+
+ epCap->cap = cap;
+ epCap->capType = OO_CAP_TYPE_DATA;
+ epCap->params = (void*)params;
+ epCap->startReceiveChannel = startReceiveChannel;
+ epCap->startTransmitChannel = startTransmitChannel;
+ epCap->stopReceiveChannel = stopReceiveChannel;
+ epCap->stopTransmitChannel = stopTransmitChannel;
+ epCap->next = NULL;
+
+ if(!call)
+ {
+ /* Add as local capability */
+ OOTRACEDBGC2("Adding endpoint capability %s. \n",
+ ooGetCapTypeText(epCap->cap));
+ if(!gH323ep.myCaps) {
+ gH323ep.myCaps = epCap;
+ }
+ else{
+ cur = gH323ep.myCaps;
+ while(cur->next) cur = cur->next;
+ cur->next = epCap;
+ }
+ ooAppendCapToCapPrefs(NULL, cap);
+ gH323ep.noOfCaps++;
+ }
+ else{
+ if(remote)
+ {
+ /* Add as remote capability */
+ if(!call->remoteCaps) {
+ call->remoteCaps = epCap;
+ }
+ else{
+ cur = call->remoteCaps;
+ while(cur->next) cur = cur->next;
+ cur->next = epCap;
+ }
+ }
+ else{
+ /* Add as our capability */
+ OOTRACEDBGC4("Adding call specific capability %s. (%s, %s)\n",
+ ooGetCapTypeText(epCap->cap), call->callType,
+ call->callToken);
+ if(!call->ourCaps){
+ call->ourCaps = epCap;
+ ooResetCapPrefs(call);
+ }
+ else{
+ cur = call->ourCaps;
+ while(cur->next) cur = cur->next;
+ cur->next = epCap;
+ }
+ ooAppendCapToCapPrefs(call, cap);
+ }
+ }
+
return OO_OK;
}
@@ -990,6 +1081,67 @@
return NULL;
}
+/* This is used for T.38 */
+struct H245DataApplicationCapability* ooCapabilityCreateT38Capability
+ (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir)
+{
+ H245DataApplicationCapability *pT38=NULL;
+ OOCapParams *params;
+ if(!epCap || !epCap->params)
+ {
+ OOTRACEERR1("Error:Invalid capability parameters to "
+ "ooCapabilityCreateSimpleCapability.\n");
+ return NULL;
+ }
+ params =(OOCapParams*)epCap->params;
+ pT38 = (H245DataApplicationCapability*)memAlloc(pctxt,
+ sizeof(H245DataApplicationCapability));
+ if(!pT38)
+ {
+ OOTRACEERR1("ERROR:Memory - ooCapabilityCreateT38Capability - pT38\n");
+ return NULL;
+ }
+ memset(pT38, 0, sizeof(H245DataApplicationCapability));
+
+
+ switch(epCap->cap)
+ {
+ case OO_T38:
+ pT38->maxBitRate = 144;
+ pT38->application.t = T_H245DataApplicationCapability_application_t38fax;
+ pT38->application.u.t38fax =
+ (H245DataApplicationCapability_application_t38fax *) memAlloc(pctxt,
+ sizeof(H245DataApplicationCapability_application_t38fax));
+ if (!pT38->application.u.t38fax) {
+ OOTRACEERR2("Error:Memory - ooCapabilityCreateT38Capability - %d\n", epCap->cap);
+ memFreePtr(pctxt, pT38);
+ return NULL;
+ }
+ memset(pT38->application.u.t38fax, 0, sizeof(H245DataApplicationCapability_application_t38fax));
+ pT38->application.u.t38fax->t38FaxProtocol.t = T_H245DataProtocolCapability_udp;
+ pT38->application.u.t38fax->t38FaxProfile.m.versionPresent = TRUE;
+ pT38->application.u.t38fax->t38FaxProfile.version = 0;
+ pT38->application.u.t38fax->t38FaxProfile.m.t38FaxRateManagementPresent = TRUE;
+ pT38->application.u.t38fax->t38FaxProfile.t38FaxRateManagement.t =
+ T_H245T38FaxRateManagement_transferredTCF;
+ pT38->application.u.t38fax->t38FaxProfile.m.t38FaxUdpOptionsPresent = TRUE;
+ pT38->application.u.t38fax->t38FaxProfile.t38FaxUdpOptions.m.t38FaxMaxBufferPresent = TRUE;
+ pT38->application.u.t38fax->t38FaxProfile.t38FaxUdpOptions.t38FaxMaxBuffer = 200;
+ pT38->application.u.t38fax->t38FaxProfile.t38FaxUdpOptions.m.t38FaxMaxDatagramPresent = TRUE;
+ pT38->application.u.t38fax->t38FaxProfile.t38FaxUdpOptions.t38FaxMaxDatagram = 72;
+ pT38->application.u.t38fax->t38FaxProfile.t38FaxUdpOptions.t38FaxUdpEC.t =
+ T_H245T38FaxUdpOptions_t38FaxUdpEC_t38UDPFEC;
+
+ return pT38;
+
+ default:
+ OOTRACEERR2("ERROR: Don't know how to create T38 capability %d\n",
+ epCap->cap);
+ }
+ return NULL;
+}
+
+
/* Used for g711 ulaw/alaw, g728, g729, g729a, g7231 */
ASN1BOOL ooCapabilityCheckCompatibility_Simple
(OOH323CallData *call, ooH323EpCapability* epCap,
@@ -1179,6 +1331,25 @@
}
+OOBOOL ooCapabilityCheckCompatibility_T38
+ (OOH323CallData *call, ooH323EpCapability* epCap,
+ H245DataApplicationCapability* t38Cap, int dir)
+{
+ unsigned cap = 0;
+ switch(t38Cap->application.t)
+ {
+ case T_H245DataApplicationCapability_application_t38fax:
+ cap = OO_T38;
+ break;
+ default:
+ return FALSE;
+ }
+
+ if(cap != epCap->cap) { return FALSE; }
+
+ return TRUE;
+}
+
OOBOOL ooCapabilityCheckCompatibility_H263Video
(struct OOH323CallData *call, ooH323EpCapability *epCap,
@@ -1407,6 +1578,8 @@
dataType->u.videoData, dir);
break;
case T_H245DataType_data:
+ if(epCap->capType == OO_CAP_TYPE_DATA)
+ return ooCapabilityCheckCompatibility_T38(call, epCap, dataType->u.data, dir);
default:
OOTRACEDBGC3("ooCapabilityCheckCompatibility - Unsupported "
"capability. (%s, $s)\n", call->callType, call->callToken);
@@ -1930,6 +2103,110 @@
}
}
+ooH323EpCapability* ooIsT38Supported
+ (OOH323CallData *call, H245DataApplicationCapability* t38Cap, int dir)
+{
+ int cap = 0;
+ ooH323EpCapability *cur=NULL, *epCap=NULL;
+ OOH263CapParams *params= NULL;
+ /* Find similar capability */
+ switch(t38Cap->application.t)
+ {
+ case T_H245DataApplicationCapability_application_t38fax:
+ cap = OO_T38;
+ break;
+ default:
+ return NULL;
+ }
+
+ if(call->ourCaps)
+ cur = call->ourCaps;
+ else
+ cur = gH323ep.myCaps;
+
+ while(cur)
+ {
+ OOTRACEDBGC4("Local cap being compared %s. (%s, %s)\n",
+ ooGetCapTypeText(cur->cap),call->callType, call->callToken);
+
+ if(cur->cap == cap && (cur->dir & dir))
+ break;
+ cur = cur->next;
+ }
+
+ if(!cur) return NULL;
+
+ OOTRACEDBGC4("Found matching t38 capability type %s. Comparing"
+ " other parameters. (%s, %s)\n", ooGetCapTypeText(cap),
+ call->callType, call->callToken);
+
+ /* can we receive this capability */
+ if(dir & OORX)
+ {
+ OOTRACEDBGC4("We can receive Simple capability %s. (%s, %s)\n",
+ ooGetCapTypeText(cur->cap), call->callType,
+ call->callToken);
+ epCap = (ooH323EpCapability*)memAllocZ(call->pctxt,
+ sizeof(ooH323EpCapability));
+ params=(OOCapParams*)memAlloc(call->pctxt,sizeof(OOCapParams));
+ if(!epCap || !params)
+ {
+ OOTRACEERR3("Error:Memory - ooIsT38Supported - "
+ "epCap/params (%s, %s)\n", call->callType,
+ call->callToken);
+ return NULL;
+ }
+ epCap->params = params;
+ epCap->cap = cur->cap;
+ epCap->dir = cur->dir;
+ epCap->capType = cur->capType;
+ epCap->startReceiveChannel = cur->startReceiveChannel;
+ epCap->startTransmitChannel= cur->startTransmitChannel;
+ epCap->stopReceiveChannel = cur->stopReceiveChannel;
+ epCap->stopTransmitChannel = cur->stopTransmitChannel;
+ epCap->next = NULL;
+ memcpy(epCap->params, cur->params, sizeof(OOCapParams));
+ OOTRACEDBGC4("Returning copy of matched receive capability %s. "
+ "(%s, %s)\n",
+ ooGetCapTypeText(cur->cap), call->callType,
+ call->callToken);
+ return epCap;
+ }
+
+ /* Can we transmit compatible stream */
+ if(dir & OOTX)
+ {
+ OOTRACEDBGC4("We can transmit Simple capability %s. (%s, %s)\n",
+ ooGetCapTypeText(cur->cap), call->callType,
+ call->callToken);
+ epCap = (ooH323EpCapability*)memAlloc(call->pctxt,
+ sizeof(ooH323EpCapability));
+ params =(OOCapParams*)memAllocZ(call->pctxt,sizeof(OOCapParams));
+ if(!epCap || !params)
+ {
+ OOTRACEERR3("Error:Memory - ooIsAudioDataTypeSimpleSupported - "
+ "epCap/params (%s, %s)\n", call->callType,
+ call->callToken);
+ return NULL;
+ }
+ epCap->params = params;
+ epCap->cap = cur->cap;
+ epCap->dir = cur->dir;
+ epCap->capType = cur->capType;
+ epCap->startReceiveChannel = cur->startReceiveChannel;
+ epCap->startTransmitChannel= cur->startTransmitChannel;
+ epCap->stopReceiveChannel = cur->stopReceiveChannel;
+ epCap->stopTransmitChannel = cur->stopTransmitChannel;
+ epCap->next = NULL;
+ memcpy(epCap->params, cur->params, sizeof(OOCapParams));
+ OOTRACEDBGC4("Returning copy of matched transmit capability %s."
+ "(%s, %s)\n",
+ ooGetCapTypeText(cur->cap), call->callType,
+ call->callToken);
+ return epCap;
+ }
+ return NULL;
+}
ooH323EpCapability* ooIsVideoDataTypeH263Supported
(OOH323CallData *call, H245H263VideoCapability* pH263Cap, int dir,
@@ -2130,10 +2407,12 @@
OOTRACEDBGC3("Looking for audio dataType support. (%s, %s)\n",
call->callType, call->callToken);
return ooIsAudioDataTypeSupported(call, data->u.audioData, dir);
+
case T_H245DataType_data:
- OOTRACEDBGC3("Data type not supported.(%s, %s)\n",
+ OOTRACEDBGC3("Looking for application data dataType support.(%s, %s)\n",
call->callType, call->callToken);
- return NULL;
+ return ooIsT38Supported(call, data->u.data, dir);
+
case T_H245DataType_encryptionData:
OOTRACEDBGC3("Encryption data type not supported.(%s, %s)\n",
call->callType, call->callToken);
@@ -2274,12 +2553,42 @@
case T_H245Capability_receiveAndTransmitAudioCapability:
return ooAddRemoteAudioCapability(call,
cap->u.receiveAndTransmitAudioCapability, OORXTX);
+
+
+ case T_H245Capability_receiveDataApplicationCapability:
+ return ooAddRemoteDataApplicationCapability(call, cap->u.receiveDataApplicationCapability,
+ OORX);
+ case T_H245Capability_transmitDataApplicationCapability:
+ return ooAddRemoteDataApplicationCapability(call, cap->u.transmitDataApplicationCapability,
+ OOTX);
+ case T_H245Capability_receiveAndTransmitDataApplicationCapability:
+ return ooAddRemoteDataApplicationCapability(call,
+ cap->u.receiveAndTransmitDataApplicationCapability, OORXTX);
+
+
default:
OOTRACEDBGA3("Unsupported cap type encountered. Ignoring. (%s, %s)\n",
call->callType, call->callToken);
}
return OO_OK;
}
+
+int ooAddRemoteDataApplicationCapability(OOH323CallData *call,
+ H245DataApplicationCapability *dataCap,
+ int dir)
+{
+ switch(dataCap->application.t)
+ {
+ case T_H245DataApplicationCapability_application_t38fax:
+ return ooCapabilityAddT38Capability(call, OO_T38,
+ dir, NULL, NULL, NULL, NULL,TRUE);
+ default:
+ OOTRACEDBGA1("Unsupported data capability type\n");
+
+ }
+ return OO_OK;
+}
+
int ooAddRemoteAudioCapability(OOH323CallData *call,
H245AudioCapability *audioCap,
@@ -2442,10 +2751,6 @@
return OO_OK;
}
-
-
-
-
int ooCapabilityUpdateJointCapabilities
(OOH323CallData* call, H245Capability *cap)
{
@@ -2474,6 +2779,22 @@
case T_H245Capability_transmitVideoCapability:
return ooCapabilityUpdateJointCapabilitiesVideo(call,
cap->u.transmitVideoCapability, OORX);
+
+ case T_H245Capability_receiveDataApplicationCapability:
+ epCap= ooIsT38Supported(call, cap->u.receiveDataApplicationCapability,
+ OOTX);
+ break;
+ case T_H245Capability_transmitDataApplicationCapability:
+ epCap = ooIsT38Supported(call, cap->u.transmitDataApplicationCapability,
+ OORX);
+ break;
+ case T_H245Capability_receiveAndTransmitDataApplicationCapability:
+ epCap = ooIsT38Supported(call, cap->u.receiveAndTransmitDataApplicationCapability, OOTX);
+ if (!epCap)
+ epCap = ooIsT38Supported(call, cap->u.receiveAndTransmitDataApplicationCapability, OORX);
+ break;
+
+
case T_H245Capability_receiveUserInputCapability:
if((cap->u.receiveUserInputCapability->t ==
T_H245UserInputCapability_basicString) &&
@@ -2686,7 +3007,8 @@
"OO_H263VIDEO",
"OO_IS11172VIDEO", /* mpeg */
"OO_GENERICVIDEO",
- "OO_EXTELEMVIDEO"
+ "OO_EXTELEMVIDEO",
+ "OO_T38" /* T.38 */
};
return ooUtilsGetText (cap, capTypes, OONUMBEROF(capTypes));
}
Modified: team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.h?view=diff&rev=207350&r1=207349&r2=207350
==============================================================================
--- team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.h (original)
+++ team/may/chan_ooh323_rework/addons/ooh323c/src/ooCapability.h Sat Jul 18 21:50:11 2009
@@ -71,7 +71,8 @@
OO_H263VIDEO = 31,
OO_IS11172VIDEO = 32, /* mpeg */
OO_GENERICVIDEO = 33,
- OO_EXTELEMVIDEO = 34
+ OO_EXTELEMVIDEO = 34,
+ OO_T38 = 35
} OOCapabilities;
Modified: team/may/chan_ooh323_rework/addons/ooh323c/src/ooh245.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/may/chan_ooh323_rework/addons/ooh323c/src/ooh245.c?view=diff&rev=207350&r1=207349&r2=207350
==============================================================================
--- team/may/chan_ooh323_rework/addons/ooh323c/src/ooh245.c (original)
+++ team/may/chan_ooh323_rework/addons/ooh323c/src/ooh245.c Sat Jul 18 21:50:11 2009
@@ -323,6 +323,7 @@
ooH323EpCapability *epCap=NULL;
H245TerminalCapabilitySet *termCap=NULL;
H245AudioCapability *audioCap=NULL;
+ H245DataApplicationCapability *t38Cap = NULL;
H245AudioTelephonyEventCapability *ateCap=NULL;
H245UserInputCapability *userInputCap = NULL;
H245CapabilityTableEntry *entry=NULL;
@@ -472,6 +473,80 @@
else{
entry->capability.t = T_H245Capability_transmitAudioCapability;
entry->capability.u.transmitAudioCapability = audioCap;
+ }
+ entry->capabilityTableEntryNumber = i+1;
+ dListAppend(pctxt , &(termCap->capabilityTable), entry);
+ altSetAudio->elem[altSetAudio->n] = i+1;
+ altSetAudio->n++;
+ i++;
+ }
+ else if(epCap->capType == OO_CAP_TYPE_DATA)
+ {
+
+ /* Create t.38 capability. If capability supports receive, we only
+ add it as receive capability in TCS. However, if it supports only
+ transmit, we add it as transmit capability in TCS.
+ */
+ if((epCap->dir & OORX) && !(epCap->dir & OOTX))
+ {
+
+ OOTRACEDBGC3("Sending receive capability t38 in TCS.(%s, %s)\n",
+ call->callType, call->callToken);
+
+ t38Cap = ooCapabilityCreateT38Capability(epCap, pctxt, OORX);
+ if(!t38Cap)
+ {
+ OOTRACEWARN3("WARN:Failed to create t38 capability for"
+ "%s, %s\n",
+ call->callType, call->callToken);
+ continue;
+ }
+ }
+ else if((epCap->dir & OOTX) && !(epCap->dir & OORX))
+ {
+ OOTRACEDBGC3("Sending transmit capability t38 in TCS.(%s, %s)\n",
+ call->callType, call->callToken);
+ t38Cap = ooCapabilityCreateT38Capability(epCap, pctxt, OOTX);
+ if(!t38Cap)
+ {
+ OOTRACEWARN3("WARN:Failed to create capability t38 "
+ "(%s, %s)\n",
+ call->callType, call->callToken);
+ continue;
+ }
+ }
+ else{
+ OOTRACEDBGC3("Sending transmit&recevie capability t38 in TCS.(%s, %s)\n",
+ call->callType, call->callToken);
+ t38Cap = ooCapabilityCreateT38Capability(epCap, pctxt, OOTX&OORX);
+ if(!t38Cap)
+ {
+ OOTRACEWARN3("WARN:Failed to create capability t38 "
+ "(%s, %s)\n",
+ call->callType, call->callToken);
+ continue;
+ }
+ }
+ /* Add Capabilities to Capability Table */
+ entry = (H245CapabilityTableEntry*) memAlloc(pctxt,
+ sizeof(H245CapabilityTableEntry));
+ if(!entry)
+ {
+ OOTRACEERR3("Error:Memory - ooSendTermCapMsg - entry(audio Cap)."
+ "(%s, %s)\n", call->callType, call->callToken);
+ return OO_FAILED;
+ }
+ memset(entry, 0, sizeof(H245CapabilityTableEntry));
+ entry->m.capabilityPresent = 1;
+ if((epCap->dir & OORX) && (epCap->dir & OOTX)) {
+ entry->capability.t = T_H245Capability_receiveAndTransmitDataApplicationCapability;
+ entry->capability.u.receiveAndTransmitDataApplicationCapability = t38Cap;
+ } else if((epCap->dir & OORX)) {
+ entry->capability.t = T_H245Capability_receiveDataApplicationCapability;
+ entry->capability.u.receiveDataApplicationCapability = t38Cap;
+ }else{
+ entry->capability.t = T_H245Capability_transmitDataApplicationCapability;
+ entry->capability.u.transmitDataApplicationCapability = t38Cap;
}
entry->capabilityTableEntryNumber = i+1;
dListAppend(pctxt , &(termCap->capabilityTable), entry);
@@ -1092,6 +1167,136 @@
return OO_OK;
}
+/* handling requestmode routines */
+
+int ooSendRequestModeAck(OOH323CallData* call,
[... 447 lines stripped ...]
More information about the asterisk-commits
mailing list