are resolved and each address is attempted in turn until one succeeds or
all fail.
+chan_ooh323
+-----------
+ * Direct media functionality has been added.
+ Options in config are: directmedia (directrtp) and directrtpsetup (earlydirect)
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 1.8 to Asterisk 10 -------------------
------------------------------------------------------------------------------
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);
.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 = {
/* 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 */
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 */
int rtdrcount, rtdrinterval;
int nat;
int faststart, h245tunneling;
+ int directrtp;
+ int earlydirect;
int g729onlyA;
struct ooh323_user *next;
};
int rtdrcount,rtdrinterval;
int nat;
int faststart, h245tunneling;
+ int directrtp;
+ int earlydirect;
int g729onlyA;
struct ooh323_peer *next;
};
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;
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));
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);
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);
}
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;
}
if (gH323Debug) {
ast_verb(0, "+++ ooh323_digit_end, res = %d\n", res);
}
-
return res;
}
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) {
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;
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)) {
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);
} 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);
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;
}
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);
}
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));
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")) {
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) {
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")) {
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")) {
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");
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");
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;
.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;
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);
}
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);
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;
*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;
}
}
*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;
}
{
/* 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) {
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;
+
}
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;
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);
}
/* 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);
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);
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");
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;
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");
parameters.rate = AST_T38_RATE_14400;
ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, 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);
int cap;
int lMediaPort;
int lMediaCntrlPort;
+ int lMediaRedirPort;
+ int lMediaRedirCPort;
char lMediaIP[2+8*4+7];
struct OOMediaInfo *next;
} OOMediaInfo;
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;
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.
cb_OpenLogicalChannels openLogicalChannels;
cb_OnReceivedDTMF onReceivedDTMF;
cb_OnModeChanged onModeChanged;
+ cb_OnMediaChanged onMediaChanged;
} OOH323CALLBACKS;
/**
}
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);
+ }
}
{
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.
*/
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,
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;
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;
}
OO_LOGICALCHAN_IDLE,
OO_LOGICALCHAN_PROPOSED,
OO_LOGICALCHAN_ESTABLISHED,
- OO_LOGICALCHAN_PROPOSEDFS
+ OO_LOGICALCHAN_PROPOSEDFS,
+ OO_LOGICALCHAN_CLOSEPENDING
} OOLogicalChannelState;
/**
(struct OOH323CallData* call, int sessionID, char *dir, H245DataType* dataType);
EXTERN OOLogicalChannel* ooGetTransmitLogicalChannel(struct OOH323CallData *call);
+EXTERN OOLogicalChannel* ooGetReceiveLogicalChannel(struct OOH323CallData *call);
/**
* @}
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;
return OO_STKCMD_SUCCESS;
}
-
const char* ooGetStkCmdStatusCodeTxt(OOStkCmdStat stat)
{
switch(stat)
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;
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
}
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()
}
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;
}
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 {
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;
}
{
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);
}
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;
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;
}
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;
}
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;
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;
}
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:
}
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",
break;
}
}
- ooOnReceivedRequestChannelCloseAck(call,
- response->u.requestChannelCloseAck);
+ /* Do nothing by receive reqChanCloseAck */
break;
case T_H245ResponseMessage_requestChannelCloseReject:
OOTRACEINFO4("RequestChannelCloseReject received - %d (%s, %s)\n",
H245TerminalCapabilitySet *tcs=NULL;
DListNode *pNode=NULL;
H245CapabilityTableEntry *capEntry = NULL;
+ ooLogicalChannel *temp = NULL;
tcs = pmsg->h245Msg.u.request->u.terminalCapabilitySet;
if(call->remoteTermCapSeqNo > tcs->sequenceNumber)
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;
* @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
*/
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
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
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)
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
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. */
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
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)
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,
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
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);
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
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)
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,
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);
call->callEndReason = OO_REASON_LOCAL_CLEARED;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
memset(olc, 0, sizeof(H245OpenLogicalChannel));
call->callEndReason = OO_REASON_INVALIDMESSAGE;
call->callState = OO_CALL_CLEAR;
}
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
"(%s, %s)\n",
olc->forwardLogicalChannelNumber, call->callType,
call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
if(pChannel->channelNo != olc->forwardLogicalChannelNumber)
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)
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,
}
OOTRACEERR3("ERROR:Unsupported media channel address type "
"(%s, %s)\n", call->callType, call->callToken);
+ finishPrint();
+ removeEventHandler(call->pctxt);
return OO_FAILED;
}
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);
{
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);
}
}
}
}
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;
gH323ep.h323Callbacks.openLogicalChannels = h323Callbacks.openLogicalChannels;
gH323ep.h323Callbacks.onReceivedDTMF = h323Callbacks.onReceivedDTMF;
gH323ep.h323Callbacks.onModeChanged = h323Callbacks.onModeChanged;
+ gH323ep.h323Callbacks.onMediaChanged = h323Callbacks.onMediaChanged;
return OO_OK;
}
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)
{
}
+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;
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);
/**
* @}
{
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,
}
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,
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,
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,
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,
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,
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,
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,
#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,
#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,
{
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)
{
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,
}
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,
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,
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,
{
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,
&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,
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,
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,
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,
#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,
#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,
; OOH323/exten/peer OR OOH323/exten@ip
;
; Domain name resolution is not yet supported.
-;
+;
; When a H.323 user calls into asterisk, his H323ID is matched with the profile
; name and context is determined to route the call
;
-; The channel driver will register all global aliases and aliases defined in
+; The channel driver will register all global aliases and aliases defined in
; peer profiles with the gatekeeper, if one exists. So, that when someone
-; outside our pbx (non-user) calls an extension, gatekeeper will route that
+; outside our pbx (non-user) calls an extension, gatekeeper will route that
; call to our asterisk box, from where it will be routed as per dial plan.
;The dotted IP address asterisk should listen on for incoming H323
;connections
;Default - tries to find out local ip address on it's own
-bindaddr=0.0.0.0
+bindaddr=0.0.0.0
-;This parameter indicates whether channel driver should register with
+;This parameter indicates whether channel driver should register with
;gatekeeper as a gateway or an endpoint.
;Default - no
;gateway=no
;H323-ID to be used for asterisk server
;Default - Asterisk PBX
-h323id=ObjSysAsterisk
+h323id=ObjSysAsterisk
e164=100
;CallerID to use for calls
;Sets default context all clients will be placed in.
;Default - default
-context=public
+context=default
;Sets rtptimeout for all clients, unless overridden
;Default - 60 seconds
; CNG tone or an incoming T.38 RequestMode packet
;
; yes - enable both detection (CNG & T.38)
-; no - disable both
+; no - disable both
; cng - enable CNG detection (default)
; t38 - enable T.38 request detection
;
; User/peer/friend definitions:
; User config options Peer config options
; ------------------ -------------------
-; context
+; context
; disallow disallow
; allow allow
; accountcode accountcode
;
+;
+; direct rtp between two remote peers, disabled by default
+; can be specified globally or per peer/user section
+;
+directmedia=no
+;
+; early direct rtp (try to establish direct rtp before asnwer)
+; disabled by default, auto enabled by directmedia is enabled
+; can be disabled escpecially if directmedia is enabled.
+; can be specified globally or per peer/user section
+;
+;
+directrtpsetup=no
+
;Define users here
;Section header is extension
[myuser1]
context=context1
disallow=all
allow=gsm
-allow=ulaw
+allow=ulaw