summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
Diffstat (limited to 'addons')
-rw-r--r--addons/chan_ooh323.c252
-rw-r--r--addons/ooh323c/src/ooCalls.h7
-rw-r--r--addons/ooh323c/src/ooCmdChannel.c20
-rw-r--r--addons/ooh323c/src/ooLogChan.c29
-rw-r--r--addons/ooh323c/src/ooLogChan.h4
-rw-r--r--addons/ooh323c/src/ooStackCmds.c63
-rw-r--r--addons/ooh323c/src/ooStackCmds.h4
-rw-r--r--addons/ooh323c/src/ooh245.c199
-rw-r--r--addons/ooh323c/src/ooh245.h3
-rw-r--r--addons/ooh323c/src/ooh323.c65
-rw-r--r--addons/ooh323c/src/ooh323ep.c1
-rw-r--r--addons/ooh323c/src/ooq931.c185
-rw-r--r--addons/ooh323c/src/ooq931.h2
-rw-r--r--addons/ooh323cDriver.c132
14 files changed, 825 insertions, 141 deletions
diff --git a/addons/chan_ooh323.c b/addons/chan_ooh323.c
index 296dd54ea..40cd86561 100644
--- a/addons/chan_ooh323.c
+++ b/addons/chan_ooh323.c
@@ -89,6 +89,8 @@ static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, st
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, const struct ast_format_cap *codecs, int nat_active);
+static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result);
+void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort);
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);
@@ -126,6 +128,7 @@ static struct ast_rtp_glue ooh323_rtp = {
.get_rtp_info = ooh323_get_rtp_peer,
.get_vrtp_info = ooh323_get_vrtp_peer,
.update_peer = ooh323_set_rtp_peer,
+ .get_codec = ooh323_get_codec,
};
static struct ast_udptl_protocol ooh323_udptl = {
@@ -141,7 +144,9 @@ struct ooh323_user;
/* H.323 channel private structure */
static struct ooh323_pvt {
ast_mutex_t lock; /* Channel private lock */
+ ast_cond_t rtpcond; /* RTP condition */
struct ast_rtp_instance *rtp;
+ struct ast_sockaddr redirip; /* redir ip */
struct ast_rtp_instance *vrtp; /* Placeholder for now */
int t38support; /* T.38 mode - disable, transparent, faxgw */
@@ -193,6 +198,8 @@ static struct ooh323_pvt {
int amaflags;
int progsent; /* progress is sent */
int alertsent; /* alerting is sent */
+ int directrtp; /* direct rtp */
+ int earlydirect; /* early direct rtp */
int g729onlyA; /* G.729 only A */
struct ast_dsp *vad;
struct OOH323Regex *rtpmask; /* rtp ip regexp */
@@ -228,6 +235,8 @@ struct ooh323_user{
int rtdrcount, rtdrinterval;
int nat;
int faststart, h245tunneling;
+ int directrtp;
+ int earlydirect;
int g729onlyA;
struct ooh323_user *next;
};
@@ -259,6 +268,8 @@ struct ooh323_peer{
int rtdrcount,rtdrinterval;
int nat;
int faststart, h245tunneling;
+ int directrtp;
+ int earlydirect;
int g729onlyA;
struct ooh323_peer *next;
};
@@ -318,6 +329,8 @@ static int gFastStart = 1;
static int gTunneling = 1;
static int gBeMaster = 0;
static int gMediaWaitForConnect = 0;
+static int gDirectRTP = 0;
+static int gEarlyDirect = 0;
static int gTOS = 0;
static int gRTPTimeout = 60;
static int g729onlyA = 0;
@@ -655,6 +668,8 @@ static struct ast_channel *ooh323_request(const char *type, struct ast_format_ca
p->nat = peer->nat;
p->faststart = peer->faststart;
p->h245tunneling = peer->h245tunneling;
+ p->directrtp = peer->directrtp;
+ p->earlydirect = peer->earlydirect;
if (peer->rtpmask && peer->rtpmaskstr[0]) {
p->rtpmask = peer->rtpmask;
ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr));
@@ -689,6 +704,8 @@ static struct ast_channel *ooh323_request(const char *type, struct ast_format_ca
p->rtdrcount = gRTDRCount;
p->faststart = gFastStart;
p->h245tunneling = gTunneling;
+ p->directrtp = gDirectRTP;
+ p->earlydirect = gEarlyDirect;
memcpy(&p->prefs, &gPrefs, sizeof(struct ast_codec_pref));
p->username = strdup(dest);
@@ -726,7 +743,14 @@ static struct ast_channel *ooh323_request(const char *type, struct ast_format_ca
ast_mutex_unlock(&p->lock);
ast_mutex_lock(&ooh323c_cmd_lock);
+ ast_cond_init(&p->rtpcond, NULL);
ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL);
+ ast_mutex_lock(&p->lock);
+ if (!p->rtp) {
+ ast_cond_wait(&p->rtpcond, &p->lock);
+ }
+ ast_mutex_unlock(&p->lock);
+ ast_cond_destroy(&p->rtpcond);
ast_mutex_unlock(&ooh323c_cmd_lock);
}
@@ -886,7 +910,7 @@ static int ooh323_digit_begin(struct ast_channel *chan, char digit)
ast_mutex_unlock(&p->lock);
if (gH323Debug) {
- ast_verb(0, "+++ ooh323_digit_begin %d\n", res);
+ ast_verb(0, "+++ ooh323_digit_begin, res = %d\n", res);
}
return res;
}
@@ -915,7 +939,6 @@ static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int d
if (gH323Debug) {
ast_verb(0, "+++ ooh323_digit_end, res = %d\n", res);
}
-
return res;
}
@@ -1230,8 +1253,13 @@ static int ooh323_indicate(struct ast_channel *ast, int condition, const void *d
return -1;
}
- if (gH323Debug)
+ if (!ast_sockaddr_isnull(&p->redirip)) {
+ res = 0;
+ }
+
+ if (gH323Debug) {
ast_verb(0, "----- ooh323_indicate %d on call %s\n", condition, callToken);
+ }
ast_mutex_lock(&p->lock);
switch (condition) {
@@ -1383,8 +1411,9 @@ static int ooh323_indicate(struct ast_channel *ast, int condition, const void *d
ast_mutex_unlock(&p->lock);
- if (gH323Debug)
- ast_verb(0, "++++ ooh323_indicate %d on %s\n", condition, callToken);
+ if (gH323Debug) {
+ ast_verb(0, "++++ ooh323_indicate %d on %s is %d\n", condition, callToken, res);
+ }
free(callToken);
return res;
@@ -1604,7 +1633,7 @@ int onAlerting(ooCallData *call)
ast_mutex_lock(&p->lock);
if (!p->owner) {
ast_mutex_unlock(&p->lock);
- ast_log(LOG_ERROR, "Channel has no owner\n");
+ ast_debug(1, "Channel has no owner\n");
return 0;
}
while (p->owner && ast_channel_trylock(p->owner)) {
@@ -1843,6 +1872,8 @@ int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
p->nat = user->nat;
p->h245tunneling = user->h245tunneling;
p->faststart = user->faststart;
+ p->directrtp = user->directrtp;
+ p->earlydirect = user->earlydirect;
if (p->faststart)
OO_SETFLAG(call->flags, OO_M_FASTSTART);
@@ -1869,6 +1900,8 @@ int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
} else {
if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) {
p->username = strdup(call->remoteIP);
+ p->directrtp = gDirectRTP;
+ p->earlydirect = gEarlyDirect;
} else {
ast_mutex_unlock(&p->lock);
ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP);
@@ -1970,7 +2003,7 @@ int onOutgoingCall(ooCallData *call)
ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr));
}
- if (!configure_local_rtp(p, call)) {
+ if (!p->rtp && !configure_local_rtp(p, call)) {
ast_mutex_unlock(&p->lock);
return OO_FAILED;
}
@@ -2064,7 +2097,8 @@ int onNewCallCreated(ooCallData *call)
ooh323c_set_capability_for_call(call, &p->prefs, p->cap,
p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA);
- /* configure_local_rtp(p, call); */
+ configure_local_rtp(p, call);
+ ast_cond_signal(&p->rtpcond);
ast_mutex_unlock(&p->lock);
}
@@ -2284,6 +2318,8 @@ static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
user->t38support = gT38Support;
user->faststart = gFastStart;
user->h245tunneling = gTunneling;
+ user->directrtp = gDirectRTP;
+ user->earlydirect = gEarlyDirect;
user->g729onlyA = g729onlyA;
/* set default context */
ast_copy_string(user->context, gContext, sizeof(user->context));
@@ -2305,6 +2341,11 @@ static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
user->faststart = ast_true(v->value);
} else if (!strcasecmp(v->name, "h245tunneling")) {
user->h245tunneling = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
+ user->directrtp = ast_true(v->value);
+ user->earlydirect = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
+ user->earlydirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "g729onlyA")) {
user->g729onlyA = ast_true(v->value);
} else if (!strcasecmp(v->name, "nat")) {
@@ -2427,6 +2468,8 @@ static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v,
peer->t38support = gT38Support;
peer->faststart = gFastStart;
peer->h245tunneling = gTunneling;
+ peer->directrtp = gDirectRTP;
+ peer->earlydirect = gEarlyDirect;
peer->g729onlyA = g729onlyA;
peer->port = 1720;
if (0 == friend_type) {
@@ -2482,6 +2525,11 @@ static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v,
peer->faststart = ast_true(v->value);
} else if (!strcasecmp(v->name, "h245tunneling")) {
peer->h245tunneling = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
+ peer->directrtp = ast_true(v->value);
+ peer->earlydirect = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
+ peer->earlydirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "g729onlyA")) {
peer->g729onlyA = ast_true(v->value);
} else if (!strcasecmp(v->name, "nat")) {
@@ -2761,6 +2809,11 @@ int reload_config(int reload)
ooH323EpEnableH245Tunneling();
else
ooH323EpDisableH245Tunneling();
+ } else if (!strcasecmp(v->name, "directrtp") || !strcasecmp(v->name, "directmedia")) {
+ gDirectRTP = ast_true(v->value);
+ gEarlyDirect = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "earlydirect") || !strcasecmp(v->name, "directrtpsetup")) {
+ gEarlyDirect = ast_true(v->value);
} else if (!strcasecmp(v->name, "g729onlyA")) {
g729onlyA = ast_true(v->value);
} else if (!strcasecmp(v->name, "roundtrip")) {
@@ -3022,6 +3075,8 @@ static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struc
ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name);
ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no",
peer->h245tunneling?"yes":"no");
+ ast_cli(a->fd, "%-15s%s\n", "DirectRTP", peer->directrtp ? "yes" : "no");
+ ast_cli(a->fd, "%-15s%s\n", "EarlyDirectRTP", peer->earlydirect ? "yes" : "no");
ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
print_codec_to_cli(a->fd, &peer->prefs);
ast_cli(a->fd, ")\n");
@@ -3179,6 +3234,8 @@ static char *handle_cli_ooh323_show_user(struct ast_cli_entry *e, int cmd, struc
ast_cli(a->fd, "%-15.15s%s\n", "Name: ", user->name);
ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", user->faststart?"yes":"no",
user->h245tunneling?"yes":"no");
+ ast_cli(a->fd, "%-15s%s\n", "DirectRTP", user->directrtp ? "yes" : "no");
+ ast_cli(a->fd, "%-15s%s\n", "EarlyDirectRTP", user->earlydirect ? "yes" : "no");
ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "(");
print_codec_to_cli(a->fd, &user->prefs);
ast_cli(a->fd, ")\n");
@@ -3341,6 +3398,8 @@ static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, str
ast_cli(a->fd, "%-20s%s\n", "Tunneling", gTunneling?"yes":"no");
ast_cli(a->fd, "%-20s%s\n", "CallerId", gCallerID);
ast_cli(a->fd, "%-20s%s\n", "MediaWaitForConnect", gMediaWaitForConnect?"yes":"no");
+ ast_cli(a->fd, "%-20s%s\n", "DirectRTP", gDirectRTP ? "yes" : "no");
+ ast_cli(a->fd, "%-20s%s\n", "EarlyDirectRTP", gEarlyDirect ? "yes" : "no");
#if (0)
extern OOH323EndPoint gH323ep;
@@ -3556,7 +3615,8 @@ static int load_module(void)
.onCallCleared = onCallCleared,
.openLogicalChannels = NULL,
.onReceivedDTMF = ooh323_onReceivedDigit,
- .onModeChanged = onModeChanged
+ .onModeChanged = onModeChanged,
+ .onMediaChanged = (cb_OnMediaChanged) setup_rtp_remote,
};
if (!(gCap = ast_format_cap_alloc())) {
return 1;
@@ -3736,8 +3796,6 @@ static void *do_monitor(void *data)
while (h323) {
h323_next = h323->next;
- /* TODO: Need to add rtptimeout keepalive support */
-
if (h323->rtp && h323->rtptimeout && h323->lastrtptx &&
h323->lastrtptx + h323->rtptimeout < t) {
ast_rtp_instance_sendcng(h323->rtp, 0);
@@ -3745,7 +3803,7 @@ static void *do_monitor(void *data)
}
if (h323->rtp && h323->owner && h323->rtptimeout &&
- h323->lastrtprx &&
+ h323->lastrtprx && ast_sockaddr_isnull(&h323->redirip) &&
h323->lastrtprx + h323->rtptimeout < t) {
if (!ast_channel_trylock(h323->owner)) {
ast_softhangup_nolock(h323->owner, AST_SOFTHANGUP_DEV);
@@ -4123,12 +4181,34 @@ static int unload_module(void)
return 0;
}
+static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
+{
+ struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
+ if (gH323Debug) {
+ ast_verb(0, "+++ ooh323 get_codec, %s\n", ast_channel_name(chan));
+ }
+
+ if (p) {
+ ast_format_cap_append(result, ast_format_cap_is_empty(ast_channel_nativeformats(chan)) ?
+ (ast_format_cap_is_empty(p->cap) ? NULL : p->cap) : ast_channel_nativeformats(chan));
+ }
+
+ if (gH323Debug) {
+ ast_verb(0, "--- ooh323 get_codec, %s\n", ast_channel_name(chan));
+ }
+}
+
static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp)
{
struct ooh323_pvt *p = NULL;
enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
+ struct ast_sockaddr tmp;
+
+ if (gH323Debug) {
+ ast_verb(0, "+++ ooh323 get_rtp_peer \n");
+ }
if (!(p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan)))
return AST_RTP_GLUE_RESULT_FORBID;
@@ -4139,12 +4219,27 @@ static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, st
*rtp = p->rtp ? ao2_ref(p->rtp, +1), p->rtp : NULL;
- res = AST_RTP_GLUE_RESULT_LOCAL;
+ /* there must be checking of directmedia setting */
+
+ if ((ast_channel_state(chan) != AST_STATE_UP && !p->earlydirect) || !p->directrtp) {
+ res = AST_RTP_GLUE_RESULT_LOCAL;
+ } else {
+ res = AST_RTP_GLUE_RESULT_REMOTE;
+ }
if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) {
res = AST_RTP_GLUE_RESULT_FORBID;
}
+ ast_rtp_instance_get_remote_address(*rtp, &tmp);
+ if (gH323Debug) {
+ ast_verb(0, "ooh323_get_rtp_peer %s -> %s:%d, %d\n", ast_channel_name(chan), ast_sockaddr_stringify_addr(&tmp),
+ ast_sockaddr_port(&tmp), res);
+ }
+ if (gH323Debug) {
+ ast_verb(0, "--- ooh323 get_rtp_peer, res = %d\n", (int) res);
+ }
+
return res;
}
@@ -4161,7 +4256,10 @@ static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, s
}
*rtp = p->vrtp ? ao2_ref(p->vrtp, +1), p->vrtp : NULL;
- res = AST_RTP_GLUE_RESULT_LOCAL;
+
+ /* there must check of supporting video per call */
+
+ res = AST_RTP_GLUE_RESULT_FORBID;
return res;
}
@@ -4225,13 +4323,11 @@ static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance
{
/* XXX Deal with Video */
struct ooh323_pvt *p;
- struct ast_sockaddr tmp;
+ int changed = 0;
+ char *callToken = NULL;
- if (gH323Debug)
+ if (gH323Debug) {
ast_verb(0, "--- ooh323_set_peer - %s\n", ast_channel_name(chan));
-
- if (!rtp) {
- return 0;
}
if (ooh323_convertAsteriskCapToH323Cap(ast_channel_writeformat(chan)) < 0) {
@@ -4243,14 +4339,47 @@ static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance
ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
return -1;
}
- ast_rtp_instance_get_remote_address(rtp, &tmp);
- ast_rtp_instance_get_local_address(rtp, &tmp);
- return 0;
-/* May 20101003 */
-/* What we should to do here? */
+ ast_mutex_lock(&p->lock);
+
+ if (rtp) {
+ changed |= ast_rtp_instance_get_and_cmp_remote_address(rtp, &p->redirip);
+ } else if (!ast_sockaddr_isnull(&p->redirip)) {
+ changed = 1;
+ memset(&p->redirip, 0, sizeof(p->redirip));
+ }
+
+ callToken = (p->callToken ? strdup(p->callToken) : NULL);
+
+ if (!callToken) {
+ if (gH323Debug) {
+ ast_verb(0, " set_rtp_peer - No callToken\n");
+ }
+ ast_mutex_unlock(&p->lock);
+ return -1;
+ }
+ if (changed) {
+ if (!ast_sockaddr_isnull(&p->redirip)) {
+ if (gH323Debug) {
+ ast_verb(0, "ooh323_set_rtp_peer %s -> %s:%d\n", ast_channel_name(chan), ast_sockaddr_stringify_addr(&p->redirip),
+ ast_sockaddr_port(&p->redirip));
+ }
+ ooUpdateLogChannels(callToken, ast_sockaddr_stringify_addr(&p->redirip),
+ ast_sockaddr_port(&p->redirip));
+ } else {
+ if (gH323Debug) {
+ ast_verb(0, "ooh323_set_rtp_peer return back to local\n");
+ }
+ ooUpdateLogChannels(callToken, "0.0.0.0" , 0);
+ }
+ }
+
+ ast_mutex_unlock(&p->lock);
+ free(callToken);
+ return 0;
+
}
@@ -4258,7 +4387,8 @@ static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance
int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
{
- char lhost[INET6_ADDRSTRLEN], *lport=NULL;
+ char lhost[INET6_ADDRSTRLEN];
+ unsigned lport = 0;
struct ast_sockaddr tmp;
ooMediaInfo mediaInfo;
int x;
@@ -4269,7 +4399,7 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
if (gH323Debug)
ast_verb(0, "--- configure_local_rtp\n");
-
+ memset(&mediaInfo, 0, sizeof(mediaInfo));
if (ast_parse_arg(call->localIP, PARSE_ADDR, &tmp)) {
ast_sockaddr_copy(&tmp, &bindaddr);
}
@@ -4327,7 +4457,7 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
/* figure out our local RTP port and tell the H.323 stack about it*/
ast_rtp_instance_get_local_address(p->rtp, &tmp);
ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
- lport = ast_sockaddr_stringify_port(&tmp);
+ lport = ast_sockaddr_port(&tmp);
if (p->rtptimeout) {
ast_rtp_instance_set_timeout(p->rtp, p->rtptimeout);
@@ -4345,8 +4475,8 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
- mediaInfo.lMediaPort = atoi(lport);
- mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
+ mediaInfo.lMediaPort = lport;
+ mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort + 1;
for (x = 0; ast_codec_pref_index(&p->prefs, x, &tmpfmt); x++) {
strcpy(mediaInfo.dir, "transmit");
mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(&tmpfmt);
@@ -4371,9 +4501,9 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
if (p->udptl) {
ast_udptl_get_us(p->udptl, &tmp);
ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
- lport = ast_sockaddr_stringify_port(&tmp);
+ lport = ast_sockaddr_port(&tmp);
ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
- mediaInfo.lMediaPort = atoi(lport);
+ mediaInfo.lMediaPort = lport;
mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
mediaInfo.cap = OO_T38;
strcpy(mediaInfo.dir, "transmit");
@@ -4388,8 +4518,46 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
return 1;
}
-void setup_rtp_connection(ooCallData *call, const char *remoteIp,
- int remotePort)
+void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort)
+{
+ struct ooh323_pvt *p = NULL;
+ struct ast_sockaddr tmp;
+
+ if (gH323Debug) {
+ ast_verb(0, "--- setup_rtp_remote %s:%d\n", remoteIp, remotePort);
+ }
+ if (!remoteIp || !remoteIp[0] || !remotePort) {
+ if (gH323Debug) {
+ ast_verb(0, "+++ setup_rtp_remote no data\n");
+ }
+ return;
+ }
+
+ /* Find the call or allocate a private structure if call not found */
+ p = find_call(call);
+
+ if (!p || !p->rtp) {
+ ast_log(LOG_ERROR, "Something is wrong: rtp\n");
+ return;
+ }
+
+ ast_mutex_lock(&p->lock);
+
+ ast_parse_arg(remoteIp, PARSE_ADDR, &tmp);
+ ast_sockaddr_set_port(&tmp, remotePort);
+ ast_rtp_instance_set_remote_address(p->rtp, &tmp);
+
+ ast_mutex_unlock(&p->lock);
+
+ if (gH323Debug) {
+ ast_verb(0, "+++ setup_rtp_remote\n");
+ }
+
+ return;
+}
+
+
+void setup_rtp_connection(ooCallData *call, const char *remoteIp, int remotePort)
{
struct ooh323_pvt *p = NULL;
struct ast_sockaddr tmp;
@@ -4398,20 +4566,25 @@ void setup_rtp_connection(ooCallData *call, const char *remoteIp,
ast_verb(0, "--- setup_rtp_connection %s:%d\n", remoteIp, remotePort);
/* Find the call or allocate a private structure if call not found */
- p = find_call(call);
+ p = find_call(call);
- if (!p) {
+ if (!p || !p->rtp) {
ast_log(LOG_ERROR, "Something is wrong: rtp\n");
return;
}
+ ast_mutex_lock(&p->lock);
+
ast_parse_arg(remoteIp, PARSE_ADDR, &tmp);
ast_sockaddr_set_port(&tmp, remotePort);
ast_rtp_instance_set_remote_address(p->rtp, &tmp);
- if (p->writeformat.id == AST_FORMAT_G726_AAL2)
+ if (p->writeformat.id == AST_FORMAT_G726_AAL2) {
ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, 2,
"audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD);
+ }
+
+ ast_mutex_unlock(&p->lock);
if(gH323Debug)
ast_verb(0, "+++ setup_rtp_connection\n");
@@ -4531,9 +4704,10 @@ void setup_udptl_connection(ooCallData *call, const char *remoteIp,
parameters.rate = AST_T38_RATE_14400;
ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
}
- if (gH323Debug)
- ast_debug(1, "Receiving UDPTL %s:%s\n", ast_sockaddr_stringify_host(&them),
- ast_sockaddr_stringify_port(&them));
+ if (gH323Debug) {
+ ast_debug(1, "Receiving UDPTL %s:%d\n", ast_sockaddr_stringify_host(&them),
+ ast_sockaddr_port(&them));
+ }
ast_channel_unlock(p->owner);
ast_mutex_unlock(&p->lock);
diff --git a/addons/ooh323c/src/ooCalls.h b/addons/ooh323c/src/ooCalls.h
index a81f536f4..8321d342a 100644
--- a/addons/ooh323c/src/ooCalls.h
+++ b/addons/ooh323c/src/ooCalls.h
@@ -97,6 +97,8 @@ typedef struct OOMediaInfo{
int cap;
int lMediaPort;
int lMediaCntrlPort;
+ int lMediaRedirPort;
+ int lMediaRedirCPort;
char lMediaIP[2+8*4+7];
struct OOMediaInfo *next;
} OOMediaInfo;
@@ -197,6 +199,7 @@ typedef struct OOH323CallData {
ASN1UINT statusDeterminationNumber;
OOCapExchangeState localTermCapState;
OOCapExchangeState remoteTermCapState;
+ OOBOOL TCSPending;
struct ooH323EpCapability* ourCaps;
struct ooH323EpCapability* remoteCaps; /* TODO: once we start using jointCaps, get rid of remoteCaps*/
struct ooH323EpCapability* jointCaps;
@@ -325,6 +328,9 @@ typedef int (*cb_OnReceivedDTMF)
typedef void (*cb_OnModeChanged)
(struct OOH323CallData *call, int isT38Mode);
+typedef void (*cb_OnMediaChanged)
+ (struct OOH323CallData *call, char* remoteIP, int remotePort);
+
/**
* This structure holds all of the H.323 signaling callback function
* addresses.
@@ -342,6 +348,7 @@ typedef struct OOH323CALLBACKS {
cb_OpenLogicalChannels openLogicalChannels;
cb_OnReceivedDTMF onReceivedDTMF;
cb_OnModeChanged onModeChanged;
+ cb_OnMediaChanged onMediaChanged;
} OOH323CALLBACKS;
/**
diff --git a/addons/ooh323c/src/ooCmdChannel.c b/addons/ooh323c/src/ooCmdChannel.c
index 8737e6504..17e9e9ae3 100644
--- a/addons/ooh323c/src/ooCmdChannel.c
+++ b/addons/ooh323c/src/ooCmdChannel.c
@@ -411,12 +411,26 @@ int ooReadAndProcessCallStackCommand(OOH323CallData* call)
}
break;
+ case OO_CMD_UPDLC:
+ OOTRACEINFO4("Processing UpdLC command %s, localIP is %s, port is %d\n",
+ (char *)cmd.param1, (char *)cmd.param2, *(int *)cmd.param3);
+ if (cmd.param2) {
+ ooUpdateAllLogicalChannels(call, (char *)cmd.param2, *(int *)cmd.param3);
+ }
+ break;
+
default: OOTRACEERR1("ERROR:Unknown command\n");
}
}
- if(cmd.param1) free(cmd.param1);
- if(cmd.param2) free(cmd.param2);
- if(cmd.param3) free(cmd.param3);
+ if (cmd.param1) {
+ ast_free(cmd.param1);
+ }
+ if (cmd.param2) {
+ ast_free(cmd.param2);
+ }
+ if (cmd.param3) {
+ ast_free(cmd.param3);
+ }
}
diff --git a/addons/ooh323c/src/ooLogChan.c b/addons/ooh323c/src/ooLogChan.c
index d5e8db178..bafb315e6 100644
--- a/addons/ooh323c/src/ooLogChan.c
+++ b/addons/ooh323c/src/ooLogChan.c
@@ -77,8 +77,9 @@ OOLogicalChannel* ooAddNewLogicalChannel(OOH323CallData *call, int channelNo,
{
OOTRACEDBGC3("Using configured media info (%s, %s)\n", call->callType,
call->callToken);
- pNewChannel->localRtpPort = pMediaInfo->lMediaPort;
- pNewChannel->localRtcpPort = pMediaInfo->lMediaCntrlPort;
+ pNewChannel->localRtpPort = pMediaInfo->lMediaRedirPort ? pMediaInfo->lMediaRedirPort : pMediaInfo->lMediaPort;
+ /* check MediaRedirPort here because RedirCPort is ReditPort + 1 and can't be 0 ;) */
+ pNewChannel->localRtcpPort = pMediaInfo->lMediaRedirPort ? pMediaInfo->lMediaRedirCPort : pMediaInfo->lMediaCntrlPort;
/* If user application has not specified a specific ip and is using
multihomed mode, substitute appropriate ip.
*/
@@ -86,6 +87,8 @@ OOLogicalChannel* ooAddNewLogicalChannel(OOH323CallData *call, int channelNo,
strcpy(pNewChannel->localIP, call->localIP);
else
strcpy(pNewChannel->localIP, pMediaInfo->lMediaIP);
+
+ OOTRACEDBGC5("Configured media info (%s, %s) %s:%d\n", call->callType, call->callToken, pNewChannel->localIP, pNewChannel->localRtcpPort);
}
else{
OOTRACEDBGC3("Using default media info (%s, %s)\n", call->callType,
@@ -254,6 +257,26 @@ OOLogicalChannel* ooGetTransmitLogicalChannel
return NULL;
}
+
+OOLogicalChannel* ooGetReceiveLogicalChannel
+ (OOH323CallData *call)
+{
+ OOLogicalChannel * pChannel = NULL;
+ pChannel = call->logicalChans;
+ while (pChannel) {
+ OOTRACEINFO6("Listing logical channel %d cap %d state %d for (%s, %s)\n",
+ pChannel->channelNo, pChannel->chanCap->cap, pChannel->state,
+ call->callType, call->callToken);
+ if (!strcmp(pChannel->dir, "receive") && pChannel->state != OO_LOGICALCHAN_IDLE &&
+ pChannel->state != OO_LOGICALCHAN_PROPOSEDFS) {
+ return pChannel;
+ } else {
+ pChannel = pChannel->next;
+ }
+ }
+ return NULL;
+}
+
int ooClearAllLogicalChannels(OOH323CallData *call)
{
OOLogicalChannel * temp = NULL, *prev = NULL;
@@ -326,7 +349,7 @@ int ooClearLogicalChannel(OOH323CallData *call, int channelNo)
ooRemoveLogicalChannel(call, channelNo);/* TODO: efficiency - This causes re-search of
of logical channel in the list. Can be
easily improved.*/
- } while ((pLogicalChannel = ooFindLogicalChannelByLogicalChannelNo(call,channelNo)));
+ } while ((pLogicalChannel = ooFindLogicalChannelByLogicalChannelNo(call, channelNo)));
return OO_OK;
}
diff --git a/addons/ooh323c/src/ooLogChan.h b/addons/ooh323c/src/ooLogChan.h
index 183eb1445..c52e9a73d 100644
--- a/addons/ooh323c/src/ooLogChan.h
+++ b/addons/ooh323c/src/ooLogChan.h
@@ -42,7 +42,8 @@ typedef enum {
OO_LOGICALCHAN_IDLE,
OO_LOGICALCHAN_PROPOSED,
OO_LOGICALCHAN_ESTABLISHED,
- OO_LOGICALCHAN_PROPOSEDFS
+ OO_LOGICALCHAN_PROPOSEDFS,
+ OO_LOGICALCHAN_CLOSEPENDING
} OOLogicalChannelState;
/**
@@ -181,6 +182,7 @@ EXTERN OOLogicalChannel * ooFindLogicalChannel
(struct OOH323CallData* call, int sessionID, char *dir, H245DataType* dataType);
EXTERN OOLogicalChannel* ooGetTransmitLogicalChannel(struct OOH323CallData *call);
+EXTERN OOLogicalChannel* ooGetReceiveLogicalChannel(struct OOH323CallData *call);
/**
* @}
diff --git a/addons/ooh323c/src/ooStackCmds.c b/addons/ooh323c/src/ooStackCmds.c
index 2cb1902be..8513e44b7 100644
--- a/addons/ooh323c/src/ooStackCmds.c
+++ b/addons/ooh323c/src/ooStackCmds.c
@@ -545,6 +545,68 @@ OOStkCmdStat ooSetANI(const char *callToken, const char* ani)
return OO_STKCMD_SUCCESS;
}
+OOStkCmdStat ooUpdateLogChannels(const char *callToken, const char* localIP, int port)
+{
+ OOStackCommand cmd;
+ OOH323CallData *call;
+
+ if (!callToken) {
+ return OO_STKCMD_INVALIDPARAM;
+ }
+
+ if (!(call = ooFindCallByToken(callToken))) {
+ return OO_STKCMD_INVALIDPARAM;
+ }
+
+ if (localIP == NULL) {
+ return OO_STKCMD_INVALIDPARAM;
+ }
+
+ if (call->CmdChan == 0) {
+ if (ooCreateCallCmdConnection(call) != OO_OK) {
+ return OO_STKCMD_CONNECTIONERR;
+ }
+ }
+
+ memset(&cmd, 0, sizeof(OOStackCommand));
+ cmd.type = OO_CMD_UPDLC;
+
+ cmd.param1 = ast_malloc(strlen(callToken) + 1);
+ cmd.param2 = ast_malloc(strlen(localIP) + 1);
+ cmd.param3 = ast_malloc(sizeof(int) + 1);
+ if (!cmd.param1 || !cmd.param2 || !cmd.param3) {
+ if (cmd.param1) {
+ ast_free(cmd.param1); /* Release memory */
+ }
+ if (cmd.param2) {
+ ast_free(cmd.param2);
+ }
+ if (cmd.param3) {
+ ast_free(cmd.param3);
+ }
+ return OO_STKCMD_MEMERR;
+ }
+ strcpy((char*)cmd.param1, callToken);
+ cmd.plen1 = strlen(callToken);
+ strcpy((char*)cmd.param2, localIP);
+ cmd.plen2 = strlen(localIP);
+ *((int *)cmd.param3) = port;
+ cmd.plen3 = sizeof(int) + 1;
+
+ if (ooWriteCallStackCommand(call, &cmd) != OO_OK) {
+ ast_free(cmd.param1);
+ ast_free(cmd.param2);
+ ast_free(cmd.param3);
+ return OO_STKCMD_WRITEERR;
+ }
+
+ ast_free(cmd.param1);
+ ast_free(cmd.param2);
+ ast_free(cmd.param3);
+
+ return OO_STKCMD_SUCCESS;
+}
+
OOStkCmdStat ooRequestChangeMode(const char *callToken, int isT38Mode)
{
OOStackCommand cmd;
@@ -593,7 +655,6 @@ OOStkCmdStat ooRequestChangeMode(const char *callToken, int isT38Mode)
return OO_STKCMD_SUCCESS;
}
-
const char* ooGetStkCmdStatusCodeTxt(OOStkCmdStat stat)
{
switch(stat)
diff --git a/addons/ooh323c/src/ooStackCmds.h b/addons/ooh323c/src/ooStackCmds.h
index dc6a2128e..df7767ce9 100644
--- a/addons/ooh323c/src/ooStackCmds.h
+++ b/addons/ooh323c/src/ooStackCmds.h
@@ -68,7 +68,8 @@ typedef enum OOStackCmdID {
OO_CMD_MANUALPROGRESS, /*!< Send progress */
OO_CMD_STOPMONITOR, /*!< Stop the event monitor */
OO_CMD_REQMODE, /*!< Request new mode */
- OO_CMD_SETANI /*! <Set conncted info */
+ OO_CMD_SETANI, /*! <Set conncted info */
+ OO_CMD_UPDLC /*! <Update Logical channels */
} OOStackCmdID;
@@ -178,6 +179,7 @@ EXTERN OOStkCmdStat ooRunCall(const char* dest, char* callToken, size_t bufsiz,
int ooGenerateOutgoingCallToken (char *callToken, size_t size);
EXTERN OOStkCmdStat ooSetANI(const char *callToken, const char* ani);
+EXTERN OOStkCmdStat ooUpdateLogChannels(const char *callToken, const char* localIP, const int port);
#ifdef __cplusplus
}
diff --git a/addons/ooh323c/src/ooh245.c b/addons/ooh323c/src/ooh245.c
index 4176b2a42..ff4fa07c8 100644
--- a/addons/ooh323c/src/ooh245.c
+++ b/addons/ooh323c/src/ooh245.c
@@ -817,6 +817,51 @@ int ooSendTermCapMsg(OOH323CallData *call)
return ret;
}
+int ooSendEmptyTermCapMsg(OOH323CallData *call)
+{
+ int ret;
+ H245RequestMessage *request = NULL;
+ OOCTXT *pctxt = NULL;
+ H245TerminalCapabilitySet *termCap = NULL;
+ H245Message *ph245msg = NULL;
+
+ ret = ooCreateH245Message(call, &ph245msg,
+ T_H245MultimediaSystemControlMessage_request);
+
+ if (ret == OO_FAILED) {
+ OOTRACEERR3("Error:Failed to create H245 message for Terminal "
+ "CapabilitySet (%s, %s)\n", call->callType, call->callToken);
+ return OO_FAILED;
+ }
+
+ /* Set request type as TerminalCapabilitySet */
+ request = ph245msg->h245Msg.u.request;
+ pctxt = call->msgctxt;
+ ph245msg->msgType = OOTerminalCapabilitySet;
+ memset(request, 0, sizeof(H245RequestMessage));
+
+ request->t = T_H245RequestMessage_terminalCapabilitySet;
+ request->u.terminalCapabilitySet = (H245TerminalCapabilitySet*)
+ memAlloc(pctxt, sizeof(H245TerminalCapabilitySet));
+ termCap = request->u.terminalCapabilitySet;
+ memset(termCap, 0, sizeof(H245TerminalCapabilitySet));
+ termCap->m.multiplexCapabilityPresent = 0;
+ termCap->m.capabilityTablePresent = 0;
+ termCap->m.capabilityDescriptorsPresent = 0;
+ termCap->sequenceNumber = ++(call->localTermCapSeqNo);
+ termCap->protocolIdentifier = gh245ProtocolID; /* protocol id */
+
+ OOTRACEDBGA3("Built empty terminal capability set message (%s, %s)\n",
+ call->callType, call->callToken);
+ ret = ooSendH245Msg(call, ph245msg);
+ if (ret != OO_OK) {
+ OOTRACEERR3("Error:Failed to enqueue empty TCS message to outbound queue. "
+ "(%s, %s)\n", call->callType, call->callToken);
+ }
+ ooFreeH245Message(call, ph245msg);
+
+ return ret;
+}
ASN1UINT ooGenerateStatusDeterminationNumber()
@@ -1668,11 +1713,11 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call,
}
if (call->versionIP == 6) {
- inet_pton(AF_INET6, call->localIP, iP6Address->network.data);
+ inet_pton(AF_INET6, pLogicalChannel->localIP, iP6Address->network.data);
iP6Address->network.numocts = 16;
iP6Address->tsapIdentifier = pLogicalChannel->localRtpPort;
} else {
- inet_pton(AF_INET, call->localIP, iPAddress->network.data);
+ inet_pton(AF_INET, pLogicalChannel->localIP, iPAddress->network.data);
iPAddress->network.numocts = 4;
iPAddress->tsapIdentifier = pLogicalChannel->localRtpPort;
}
@@ -1692,7 +1737,7 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call,
memAlloc(pctxt, sizeof(H245UnicastAddress_iP6Address));
iP6Address1 = unicastAddrs1->u.iP6Address;
memset(iP6Address1, 0, sizeof(H245UnicastAddress_iP6Address));
- inet_pton(AF_INET6, call->localIP, iP6Address1->network.data);
+ inet_pton(AF_INET6, pLogicalChannel->localIP, iP6Address1->network.data);
iP6Address1->network.numocts = 16;
iP6Address1->tsapIdentifier = pLogicalChannel->localRtcpPort;
} else {
@@ -1702,7 +1747,7 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call,
iPAddress1 = unicastAddrs1->u.iPAddress;
memset(iPAddress1, 0, sizeof(H245UnicastAddress_iPAddress));
- inet_pton(AF_INET, call->localIP, iPAddress1->network.data);
+ inet_pton(AF_INET, pLogicalChannel->localIP, iPAddress1->network.data);
iPAddress1->network.numocts = 4;
iPAddress1->tsapIdentifier = pLogicalChannel->localRtcpPort;
}
@@ -1723,7 +1768,7 @@ int ooHandleOpenLogicalChannel_helper(OOH323CallData *call,
{
epCap->startReceiveChannel(call, pLogicalChannel);
OOTRACEINFO6("Receive channel of type %s started at %s:%d(%s, %s)\n",
- ooGetCapTypeText(epCap->cap), call->localIP,
+ ooGetCapTypeText(epCap->cap), pLogicalChannel->localIP,
pLogicalChannel->localRtpPort, call->callType,
call->callToken);
}
@@ -2219,6 +2264,63 @@ int ooCloseAllLogicalChannels(OOH323CallData *call, char* dir)
return OO_OK;
}
+int ooUpdateAllLogicalChannels(OOH323CallData *call, char* localIP, int port)
+{
+ ooLogicalChannel *temp;
+ OOMediaInfo *pMediaInfo = NULL;
+ char *lIP = localIP;
+ OOBOOL eTCS = FALSE;
+
+ if (!lIP || !lIP[0]) {
+ lIP = call->localIP;
+ }
+
+/* close all log chans */
+
+ temp = call->logicalChans;
+ while (temp) {
+ if (temp->state == OO_LOGICALCHAN_ESTABLISHED) {
+ /* Sending closelogicalchannel only for outgoing channels */
+ if (!strcmp(temp->dir, "transmit")) {
+ if (call->h245SessionState != OO_H245SESSION_IDLE) {
+ ooSendCloseLogicalChannel(call, temp);
+ } else {
+ ooClearLogicalChannel(call, temp->channelNo);
+ }
+ } else if (!eTCS && call->h245SessionState != OO_H245SESSION_IDLE) {
+ ooSendEmptyTermCapMsg(call);
+ eTCS = TRUE;
+ }
+ }
+ temp = temp->next;
+ }
+
+/* change media address for all caps */
+
+ if (call->mediaInfo) {
+ pMediaInfo = call->mediaInfo;
+ while (pMediaInfo) {
+ strcpy(pMediaInfo->lMediaIP, lIP);
+ pMediaInfo->lMediaRedirPort = port;
+ pMediaInfo->lMediaRedirCPort = port + 1;
+ pMediaInfo = pMediaInfo->next;
+ }
+ }
+
+ if (call->h245SessionState == OO_H245SESSION_IDLE) {
+ if (call->fsSent) {
+ ooSendFSUpdate(call);
+ }
+ } else {
+ call->TCSPending = TRUE;
+ }
+
+/* Restart TCS exchange proc - Paul Cadah do it in chan_h323_exts native bridge code */
+/* We must do it after all log channels are closed */
+
+ return OO_OK;
+}
+
int ooSendCloseLogicalChannel(OOH323CallData *call, ooLogicalChannel *logicalChan)
{
int ret = OO_OK, error=0;
@@ -2271,17 +2373,11 @@ int ooSendCloseLogicalChannel(OOH323CallData *call, ooLogicalChannel *logicalCha
ooFreeH245Message(call, ph245msg);
/* Stop the media transmission */
- OOTRACEINFO4("Closing logical channel %d (%s, %s)\n",
- clc->forwardLogicalChannelNumber, call->callType,
- call->callToken);
- ret = ooClearLogicalChannel(call, clc->forwardLogicalChannelNumber);
- if(ret != OO_OK)
- {
- OOTRACEERR4("ERROR:Failed to close logical channel %d (%s, %s)\n",
- clc->forwardLogicalChannelNumber, call->callType, call->callToken);
- return OO_FAILED;
+ /* Moved to OnReceivedClosedChannelAck */
+ logicalChan->state = OO_LOGICALCHAN_CLOSEPENDING;
+ if (error) {
+ return OO_FAILED;
}
- if(error) return OO_FAILED;
return ret;
}
@@ -2459,17 +2555,18 @@ int ooOnReceivedRequestChannelClose(OOH323CallData *call,
ooFreeH245Message(call, ph245msg);
- /* Send Close Logical Channel*/
- ret = ooSendCloseLogicalChannel(call, lChannel);
- if(ret != OO_OK)
- {
+ /* Send Close Logical Channel if LogChan is established */
+ if (lChannel->state == OO_LOGICALCHAN_ESTABLISHED) {
+ ret = ooSendCloseLogicalChannel(call, lChannel);
+ if (ret != OO_OK) {
OOTRACEERR3("ERROR:Failed to build CloseLgicalChannel message(%s, %s)\n",
call->callType, call->callToken);
return OO_FAILED;
+ }
+ }
+ if (error) {
+ return OO_FAILED;
}
-
- if(error) return OO_FAILED;
-
return ret;
}
@@ -2677,8 +2774,7 @@ int ooOnReceivedCloseLogicalChannel(OOH323CallData *call,
clc->forwardLogicalChannelNumber, call->callType, call->callToken);
ret = ooClearLogicalChannel(call, clc->forwardLogicalChannelNumber);
- if(ret != OO_OK)
- {
+ if (ret != OO_OK) {
OOTRACEERR4("ERROR:Failed to close logical channel %d (%s, %s)\n",
clc->forwardLogicalChannelNumber, call->callType, call->callToken);
return OO_FAILED;
@@ -2728,6 +2824,16 @@ int ooOnReceivedCloseChannelAck(OOH323CallData* call,
H245CloseLogicalChannelAck* clcAck)
{
int ret = OO_OK;
+ /* Stop the media transmission */
+ OOTRACEINFO4("Closing logical channel %d (%s, %s)\n",
+ clcAck->forwardLogicalChannelNumber, call->callType,
+ call->callToken);
+ ret = ooClearLogicalChannel(call, clcAck->forwardLogicalChannelNumber);
+ if (ret != OO_OK) {
+ OOTRACEERR4("ERROR:Failed to close logical channel %d (%s, %s)\n",
+ clcAck->forwardLogicalChannelNumber, call->callType, call->callToken);
+ return OO_FAILED;
+ }
return ret;
}
@@ -2789,7 +2895,13 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg)
call->callType, call->callToken);
if (ooOnReceivedCloseLogicalChannel(call,
request->u.closeLogicalChannel) == OO_OK) {
+ if (call->TCSPending && !ooGetTransmitLogicalChannel(call)) {
+ call->TCSPending = FALSE;
+ call->localTermCapState = OO_LocalTermCapExchange_Idle;
+ ooSendTermCapMsg(call);
+ } else if (!call->TCSPending) {
ooCloseAllLogicalChannels(call, NULL);
+ }
}
break;
case T_H245RequestMessage_requestChannelClose:
@@ -2979,8 +3091,13 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg)
}
ooOnReceivedCloseChannelAck(call,
response->u.closeLogicalChannelAck);
- if(!ooGetTransmitLogicalChannel(call))
+ if (call->TCSPending && !ooGetReceiveLogicalChannel(call)) {
+ call->TCSPending = FALSE;
+ call->localTermCapState = OO_LocalTermCapExchange_Idle;
+ ooSendTermCapMsg(call);
+ } else if (!ooGetTransmitLogicalChannel(call)) {
ooOpenLogicalChannels(call);
+ }
break;
case T_H245ResponseMessage_requestChannelCloseAck:
OOTRACEINFO4("RequestChannelCloseAck received - %d (%s, %s)\n",
@@ -3002,8 +3119,7 @@ int ooHandleH245Message(OOH323CallData *call, H245Message * pmsg)
break;
}
}
- ooOnReceivedRequestChannelCloseAck(call,
- response->u.requestChannelCloseAck);
+ /* Do nothing by receive reqChanCloseAck */
break;
case T_H245ResponseMessage_requestChannelCloseReject:
OOTRACEINFO4("RequestChannelCloseReject received - %d (%s, %s)\n",
@@ -3110,6 +3226,7 @@ int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg)
H245TerminalCapabilitySet *tcs=NULL;
DListNode *pNode=NULL;
H245CapabilityTableEntry *capEntry = NULL;
+ ooLogicalChannel *temp = NULL;
tcs = pmsg->h245Msg.u.request->u.terminalCapabilitySet;
if(call->remoteTermCapSeqNo > tcs->sequenceNumber)
@@ -3136,16 +3253,30 @@ int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg)
if(call->remoteTermCapSeqNo && call->remoteTermCapSeqNo == tcs->sequenceNumber)
call->localTermCapState = OO_LocalTermCapExchange_Idle;
}
-
+/* empty tcs - renegotiate logical channels */
if(!tcs->m.capabilityTablePresent)
{
- // OOTRACEWARN3("Warn:Ignoring TCS as no capability table present(%s, %s)\n",
- OOTRACEWARN3("Empty TCS found. Pausing call...(%s, %s)\n",
+ OOTRACEDBGC3("Empty TCS found. (%s, %s)\n",
call->callType, call->callToken);
- call->h245SessionState = OO_H245SESSION_PAUSED;
- //ooSendTerminalCapabilitySetReject(call, tcs->sequenceNumber,
- // T_H245TerminalCapabilitySetReject_cause_unspecified);
- //return OO_OK;
+
+ ooH245AcknowledgeTerminalCapabilitySet(call);
+ call->remoteTermCapSeqNo = tcs->sequenceNumber;
+
+/* close all transmit chans */
+
+ temp = call->logicalChans;
+ while (temp) {
+ if (temp->state == OO_LOGICALCHAN_ESTABLISHED) {
+ /* Sending closelogicalchannel only for outgoing channels */
+ if (!strcmp(temp->dir, "transmit")) {
+ ooSendCloseLogicalChannel(call, temp);
+ }
+ }
+ temp = temp->next;
+ }
+
+ call->TCSPending = TRUE;
+ return OO_OK;
}
call->remoteTermCapSeqNo = tcs->sequenceNumber;
diff --git a/addons/ooh323c/src/ooh245.h b/addons/ooh323c/src/ooh245.h
index e8bce3fb9..a2df67056 100644
--- a/addons/ooh323c/src/ooh245.h
+++ b/addons/ooh323c/src/ooh245.h
@@ -116,6 +116,7 @@ EXTERN int ooGetOutgoingH245Msgbuf(struct OOH323CallData *call,
* @return OO_OK, on success. OO_FAILED, on failure.
*/
EXTERN int ooSendTermCapMsg(struct OOH323CallData *call);
+EXTERN int ooSendEmptyTermCapMsg(struct OOH323CallData *call);
/**
* This function is used to generate a random status determination number
@@ -290,6 +291,8 @@ EXTERN int ooOnReceivedTerminalCapabilitySetAck(struct OOH323CallData* call);
*/
EXTERN int ooCloseAllLogicalChannels(struct OOH323CallData *call, char* dir);
+EXTERN int ooUpdateAllLogicalChannels(struct OOH323CallData *call, char* localIP, int port);
+
/**
* This function is used to send out a CloseLogicalChannel message for a particular
diff --git a/addons/ooh323c/src/ooh323.c b/addons/ooh323c/src/ooh323.c
index cdf187dad..e7708af4a 100644
--- a/addons/ooh323c/src/ooh323.c
+++ b/addons/ooh323c/src/ooh323.c
@@ -104,6 +104,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -122,6 +124,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -134,6 +138,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
@@ -165,6 +171,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"forward Logical Channel Parameters found. "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(!h2250lcp->m.mediaChannelPresent)
@@ -187,6 +195,8 @@ int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility)
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -579,6 +589,8 @@ int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -598,7 +610,9 @@ int ooOnReceivedSetup(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
- return OO_FAILED;
+ finishPrint();
+ removeEventHandler(call->pctxt);
+ return OO_FAILED;
}
/* For now, just add decoded fast start elemts to list. This list
will be processed at the time of sending CONNECT message. */
@@ -672,6 +686,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -690,6 +706,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -702,6 +720,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
@@ -732,6 +752,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"forward Logical Channel Parameters found. "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(!h2250lcp->m.mediaChannelPresent)
@@ -739,6 +761,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"reverse media channel information found."
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
ret = ooGetIpPortFromH245TransportAddress(call,
@@ -754,6 +778,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -762,6 +788,8 @@ int ooOnReceivedCallProceeding(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:No callback registered to start transmit "
"channel (%s, %s)\n",call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
pChannel->chanCap->startTransmitChannel(call, pChannel);
@@ -902,6 +930,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -920,6 +950,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -932,6 +964,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
@@ -962,6 +996,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"forward Logical Channel Parameters found. "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(!h2250lcp->m.mediaChannelPresent)
@@ -969,6 +1005,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"reverse media channel information found."
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
ret = ooGetIpPortFromH245TransportAddress(call,
@@ -992,6 +1030,8 @@ int ooOnReceivedAlerting(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:No callback registered to start transmit "
"channel (%s, %s)\n",call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
pChannel->chanCap->startTransmitChannel(call, pChannel);
@@ -1139,6 +1179,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
@@ -1157,6 +1199,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -1169,6 +1213,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
@@ -1199,6 +1245,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"forward Logical Channel Parameters found. "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(!h2250lcp->m.mediaChannelPresent)
@@ -1206,6 +1254,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:Invalid OLC received in fast start. No "
"reverse media channel information found."
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
ret = ooGetIpPortFromH245TransportAddress(call,
@@ -1221,6 +1271,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
@@ -1229,6 +1281,8 @@ int ooOnReceivedProgress(OOH323CallData *call, Q931Message *q931Msg)
OOTRACEERR3("ERROR:No callback registered to start transmit "
"channel (%s, %s)\n",call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
pChannel->chanCap->startTransmitChannel(call, pChannel);
@@ -1363,8 +1417,6 @@ int ooOnReceivedSignalConnect(OOH323CallData* call, Q931Message *q931Msg)
{
OOTRACEINFO3("Remote endpoint has rejected fastStart. (%s, %s)\n",
call->callType, call->callToken);
- /* Clear all channels we might have created */
- ooClearAllLogicalChannels(call);
OO_CLRFLAG (call->flags, OO_M_FASTSTART);
}
}
@@ -1686,11 +1738,12 @@ int ooHandleH2250Message(OOH323CallData *call, Q931Message *q931Msg)
}
}
if (call->callState < OO_CALL_CLEAR) {
- ooSendCallProceeding(call);/* Send call proceeding message*/
- ret = ooH323CallAdmitted (call);
+ ooHandleFastStartChannels(call);
+ ooSendCallProceeding(call);/* Send call proceeding message*/
+ ret = ooH323CallAdmitted (call);
+ call->callState = OO_CALL_CONNECTING;
}
- call->callState = OO_CALL_CONNECTING;
} /* end ret == OO_OK */
break;
diff --git a/addons/ooh323c/src/ooh323ep.c b/addons/ooh323c/src/ooh323ep.c
index 1d5d9579e..868d31af2 100644
--- a/addons/ooh323c/src/ooh323ep.c
+++ b/addons/ooh323c/src/ooh323ep.c
@@ -346,6 +346,7 @@ int ooH323EpSetH323Callbacks(OOH323CALLBACKS h323Callbacks)
gH323ep.h323Callbacks.openLogicalChannels = h323Callbacks.openLogicalChannels;
gH323ep.h323Callbacks.onReceivedDTMF = h323Callbacks.onReceivedDTMF;
gH323ep.h323Callbacks.onModeChanged = h323Callbacks.onModeChanged;
+ gH323ep.h323Callbacks.onMediaChanged = h323Callbacks.onMediaChanged;
return OO_OK;
}
diff --git a/addons/ooh323c/src/ooq931.c b/addons/ooh323c/src/ooq931.c
index d4cfb6544..d67299d96 100644
--- a/addons/ooh323c/src/ooq931.c
+++ b/addons/ooh323c/src/ooq931.c
@@ -871,6 +871,112 @@ int ooEncodeH225Message(OOH323CallData *call, Q931Message *pq931Msg,
return OO_OK;
}
+/* Handle FS receive channels for early media */
+
+int ooHandleFastStartChannels(OOH323CallData *pCall)
+{
+ int i = 0, j = 0, remoteMediaControlPort = 0, dir = 0;
+ char remoteMediaControlIP[2 + 8 * 4 + 7];
+ DListNode *pNode = NULL;
+ H245OpenLogicalChannel *olc = NULL;
+ ooH323EpCapability *epCap = NULL;
+ H245H2250LogicalChannelParameters *h2250lcp = NULL;
+
+
+ /* If fast start supported and remote endpoint has sent faststart element */
+ if (OO_TESTFLAG(pCall->flags, OO_M_FASTSTART) &&
+ pCall->remoteFastStartOLCs.count>0) {
+
+ /* Go though all the proposed channels */
+
+ for (i = 0, j = 0; i < (int)pCall->remoteFastStartOLCs.count; i++) {
+
+ pNode = dListFindByIndex(&pCall->remoteFastStartOLCs, i);
+ olc = (H245OpenLogicalChannel*)pNode->data;
+
+ /* Don't support both direction channel */
+ if (olc->forwardLogicalChannelParameters.dataType.t !=
+ T_H245DataType_nullData &&
+ olc->m.reverseLogicalChannelParametersPresent) {
+ continue;
+ }
+
+ /* Check forward logic channel */
+ if (olc->forwardLogicalChannelParameters.dataType.t !=
+ T_H245DataType_nullData) {
+ /* Forward Channel - remote transmits - local receives */
+ OOTRACEDBGC4("Processing received forward olc %d (%s, %s)\n",
+ olc->forwardLogicalChannelNumber, pCall->callType,
+ pCall->callToken);
+ dir = OORX;
+ epCap = ooIsDataTypeSupported(pCall,
+ &olc->forwardLogicalChannelParameters.dataType,
+ OORX);
+
+ if (!epCap) {
+ continue; /* Not Supported Channel */
+ }
+
+ OOTRACEINFO1("Receive Channel data type supported\n");
+ if (olc->forwardLogicalChannelParameters.multiplexParameters.t !=
+ T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) {
+ OOTRACEERR4("ERROR:Unknown multiplex parameter type for "
+ "channel %d (%s, %s)\n",
+ olc->forwardLogicalChannelNumber,
+ pCall->callType, pCall->callToken);
+ memFreePtr(pCall->pctxt, epCap);
+ epCap = NULL;
+ continue;
+ }
+ h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters;
+
+ /* Check session is Not already established */
+ if (ooIsSessionEstablished(pCall, olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters->sessionID, "receive")) {
+
+ OOTRACEINFO4("Receive channel with sessionID %d already "
+ "established.(%s, %s)\n", olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters->sessionID,
+ pCall->callType, pCall->callToken);
+ memFreePtr(pCall->pctxt, epCap);
+ epCap = NULL;
+ continue;
+ }
+
+ /* Extract mediaControlChannel info, if supplied */
+ if (h2250lcp->m.mediaControlChannelPresent) {
+ if (OO_OK != ooGetIpPortFromH245TransportAddress(pCall,
+ &h2250lcp->mediaControlChannel,
+ remoteMediaControlIP, &remoteMediaControlPort)) {
+ OOTRACEERR3("Error: Invalid media control channel address "
+ "(%s, %s)\n", pCall->callType, pCall->callToken);
+ memFreePtr(pCall->pctxt, epCap);
+ epCap = NULL;
+ continue;
+ }
+ } else {
+ continue;
+ }
+ } else {
+ /* Don't check reverse channels */
+ continue;
+ }
+
+ if (dir & OORX) {
+ remoteMediaControlPort--;
+ if (gH323ep.h323Callbacks.onMediaChanged &&
+ pCall->callState < OO_CALL_CLEAR) {
+ gH323ep.h323Callbacks.onMediaChanged(pCall, remoteMediaControlIP,
+ remoteMediaControlPort);
+ }
+ }
+
+
+ }
+
+ }
+ return ASN_OK;
+}
+
+
int ooSetFastStartResponse(OOH323CallData *pCall, Q931Message *pQ931msg,
ASN1UINT *fsCount, ASN1DynOctStr **fsElem)
{
@@ -1648,6 +1754,85 @@ int ooSendProgress(OOH323CallData *call)
}
+int ooSendFSUpdate(OOH323CallData *call)
+{
+ int ret = 0;
+ Q931Message *pQ931Msg = NULL;
+ H225Facility_UUIE *facility = NULL;
+ OOCTXT *pctxt = call->msgctxt;
+
+ OOTRACEDBGA3("Building FS update message (%s, %s)\n", call->callType,
+ call->callToken);
+ ret = ooCreateQ931Message(pctxt, &pQ931Msg, Q931FacilityMsg);
+ if (ret != OO_OK) {
+ OOTRACEERR3("ERROR: In allocating memory for facility message (%s, %s)\n",
+ call->callType, call->callToken);
+ return OO_FAILED;
+ }
+
+ pQ931Msg->callReference = call->callReference;
+
+ pQ931Msg->userInfo = (H225H323_UserInformation*)memAlloc(pctxt,
+ sizeof(H225H323_UserInformation));
+ if (!pQ931Msg->userInfo) {
+ OOTRACEERR3("ERROR:Memory - ooSendFSUpdate - userInfo(%s, %s)\n",
+ call->callType, call->callToken);
+ return OO_FAILED;
+ }
+ memset(pQ931Msg->userInfo, 0, sizeof(H225H323_UserInformation));
+ pQ931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent = 1;
+
+ pQ931Msg->userInfo->h323_uu_pdu.h245Tunneling =
+ OO_TESTFLAG (call->flags, OO_M_TUNNELING);
+
+ pQ931Msg->userInfo->h323_uu_pdu.h323_message_body.t =
+ T_H225H323_UU_PDU_h323_message_body_facility;
+
+ facility = (H225Facility_UUIE*)
+ memAllocZ (pctxt, sizeof(H225Facility_UUIE));
+
+ if (!facility) {
+ OOTRACEERR3("ERROR:Memory - ooSendFS Update - facility (%s, %s)\n",
+ call->callType, call->callToken);
+ return OO_FAILED;
+ }
+
+ pQ931Msg->userInfo->h323_uu_pdu.h323_message_body.u.facility = facility;
+
+ /* Populate Facility UUIE */
+ facility->protocolIdentifier = gProtocolID;
+ facility->m.callIdentifierPresent = 1;
+ facility->callIdentifier.guid.numocts =
+ call->callIdentifier.guid.numocts;
+ memcpy(facility->callIdentifier.guid.data,
+ call->callIdentifier.guid.data,
+ call->callIdentifier.guid.numocts);
+ facility->reason.t = T_H225FacilityReason_forwardedElements;
+
+ ret = ooSetFastStartResponse(call, pQ931Msg,
+ &facility->fastStart.n, &facility->fastStart.elem);
+ if (ret != ASN_OK) {
+ return ret;
+ }
+ if (facility->fastStart.n > 0) {
+ facility->m.fastStartPresent = TRUE;
+ call->fsSent = TRUE;
+ } else {
+ facility->m.fastStartPresent = FALSE;
+ }
+
+ OOTRACEDBGA3("Built Facility message to send (%s, %s)\n", call->callType,
+ call->callToken);
+
+ ret = ooSendH225Msg(call, pQ931Msg);
+ if (ret != OO_OK) {
+ OOTRACEERR3("Error:Failed to enqueue Facility message to outbound "
+ "queue.(%s, %s)\n", call->callType, call->callToken);
+ }
+ memReset(call->msgctxt);
+ return ret;
+}
+
int ooSendStartH245Facility(OOH323CallData *call)
{
int ret=0;
diff --git a/addons/ooh323c/src/ooq931.h b/addons/ooh323c/src/ooq931.h
index 047c7959e..8da389328 100644
--- a/addons/ooh323c/src/ooq931.h
+++ b/addons/ooh323c/src/ooq931.h
@@ -772,6 +772,8 @@ EXTERN char* ooQ931GetMessageTypeName(int messageType, char* buf);
EXTERN char* ooQ931GetIEName(int number, char* buf);
EXTERN int ooSendTCSandMSD(struct OOH323CallData *call);
EXTERN int ooSendStartH245Facility(struct OOH323CallData *call);
+EXTERN int ooSendFSUpdate(struct OOH323CallData *call);
+EXTERN int ooHandleFastStartChannels(struct OOH323CallData *pCall);
/**
* @}
diff --git a/addons/ooh323cDriver.c b/addons/ooh323cDriver.c
index 21a733e2b..dd127a499 100644
--- a/addons/ooh323cDriver.c
+++ b/addons/ooh323cDriver.c
@@ -229,15 +229,17 @@ int ooh323c_set_capability
{
int ret = 0, x;
struct ast_format tmpfmt;
- if(gH323Debug)
- ast_verbose("\tAdding capabilities to H323 endpoint\n");
-
+ 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_verbose("\tAdding g711 ulaw capability to H323 endpoint\n");
+ 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,
@@ -246,8 +248,9 @@ int ooh323c_set_capability
}
if(tmpfmt.id == AST_FORMAT_ALAW)
{
- if(gH323Debug)
- ast_verbose("\tAdding g711 alaw capability to H323 endpoint\n");
+ 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,
@@ -257,23 +260,26 @@ int ooh323c_set_capability
if(tmpfmt.id == AST_FORMAT_G729A)
{
- if(gH323Debug)
- ast_verbose("\tAdding g729A capability to H323 endpoint\n");
+ 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_verbose("\tAdding g729 capability to H323 endpoint\n");
+ 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_verbose("\tAdding g729b capability to H323 endpoint\n");
+ 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,
@@ -283,8 +289,9 @@ int ooh323c_set_capability
if(tmpfmt.id == AST_FORMAT_G723_1)
{
- if(gH323Debug)
- ast_verbose("\tAdding g7231 capability to H323 endpoint\n");
+ 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,
@@ -295,8 +302,9 @@ int ooh323c_set_capability
if(tmpfmt.id == AST_FORMAT_G726)
{
- if(gH323Debug)
- ast_verbose("\tAdding g726 capability to H323 endpoint\n");
+ 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,
@@ -307,8 +315,9 @@ int ooh323c_set_capability
if(tmpfmt.id == AST_FORMAT_G726_AAL2)
{
- if(gH323Debug)
- ast_verbose("\tAdding g726aal2 capability to H323 endpoint\n");
+ 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,
@@ -319,8 +328,9 @@ int ooh323c_set_capability
if(tmpfmt.id == AST_FORMAT_H263)
{
- if(gH323Debug)
- ast_verbose("\tAdding h263 capability to H323 endpoint\n");
+ 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,
@@ -331,8 +341,9 @@ int ooh323c_set_capability
if(tmpfmt.id == AST_FORMAT_GSM)
{
- if(gH323Debug)
- ast_verbose("\tAdding gsm capability to H323 endpoint\n");
+ 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,
@@ -344,8 +355,9 @@ int ooh323c_set_capability
#ifdef AST_FORMAT_AMRNB
if(tmpfmt.id == AST_FORMAT_AMRNB)
{
- if(gH323Debug)
- ast_verbose("\tAdding amr nb capability to H323 endpoint\n");
+ 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,
@@ -358,8 +370,9 @@ int ooh323c_set_capability
#ifdef AST_FORMAT_SPEEX
if(tmpfmt.id == AST_FORMAT_SPEEX)
{
- if(gH323Debug)
- ast_verbose("\tAdding speex capability to H323 endpoint\n");
+ 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,
@@ -389,9 +402,10 @@ int ooh323c_set_capability_for_call
{
int ret = 0, x, txframes;
struct ast_format tmpfmt;
- if(gH323Debug)
- ast_verbose("\tAdding capabilities to call(%s, %s)\n", call->callType,
+ 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)
@@ -413,9 +427,10 @@ int ooh323c_set_capability_for_call
{
if(tmpfmt.id == AST_FORMAT_ULAW)
{
- if(gH323Debug)
- ast_verbose("\tAdding g711 ulaw capability to call(%s, %s)\n",
+ 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,
@@ -426,9 +441,10 @@ int ooh323c_set_capability_for_call
}
if(tmpfmt.id == AST_FORMAT_ALAW)
{
- if(gH323Debug)
- ast_verbose("\tAdding g711 alaw capability to call(%s, %s)\n",
+ 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,
@@ -440,9 +456,10 @@ int ooh323c_set_capability_for_call
if(tmpfmt.id == AST_FORMAT_G726)
{
- if(gH323Debug)
- ast_verbose("\tAdding g726 capability to call (%s, %s)\n",
+ 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,
@@ -454,9 +471,10 @@ int ooh323c_set_capability_for_call
if(tmpfmt.id == AST_FORMAT_G726_AAL2)
{
- if(gH323Debug)
- ast_verbose("\tAdding g726aal2 capability to call (%s, %s)\n",
+ 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,
@@ -470,9 +488,10 @@ int ooh323c_set_capability_for_call
{
txframes = (prefs->framing[x])/10;
- if(gH323Debug)
- ast_verbose("\tAdding g729A capability to call(%s, %s)\n",
+ 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,
@@ -480,17 +499,19 @@ int ooh323c_set_capability_for_call
&ooh323c_stop_transmit_channel);
if (g729onlyA)
continue;
- if(gH323Debug)
- ast_verbose("\tAdding g729 capability to call(%s, %s)\n",
+ 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_verbose("\tAdding g729B capability to call(%s, %s)\n",
+ 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,
@@ -501,9 +522,10 @@ int ooh323c_set_capability_for_call
if(tmpfmt.id == AST_FORMAT_G723_1)
{
- if(gH323Debug)
- ast_verbose("\tAdding g7231 capability to call (%s, %s)\n",
+ 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,
@@ -514,9 +536,10 @@ int ooh323c_set_capability_for_call
if(tmpfmt.id == AST_FORMAT_H263)
{
- if(gH323Debug)
- ast_verbose("\tAdding h263 capability to call (%s, %s)\n",
+ 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,
@@ -527,9 +550,10 @@ int ooh323c_set_capability_for_call
if(tmpfmt.id == AST_FORMAT_GSM)
{
- if(gH323Debug)
- ast_verbose("\tAdding gsm capability to call(%s, %s)\n",
+ 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,
@@ -540,9 +564,10 @@ int ooh323c_set_capability_for_call
#ifdef AST_FORMAT_AMRNB
if(tmpfmt.id == AST_FORMAT_AMRNB)
{
- if(gH323Debug)
- ast_verbose("\tAdding AMR capability to call(%s, %s)\n",
+ 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,
@@ -553,9 +578,10 @@ int ooh323c_set_capability_for_call
#ifdef AST_FORMAT_SPEEX
if(tmpfmt.id == AST_FORMAT_SPEEX)
{
- if(gH323Debug)
- ast_verbose("\tAdding Speex capability to call(%s, %s)\n",
+ 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,