--- ../bb/asterisk-addons-1.6.1.0/channels/ooh323cDriver.h 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323cDriver.h 2009-10-13 05:17:17.000000000 +0400 @@ -27,14 +27,16 @@ #define H323_DTMF_H245ALPHANUMERIC (1 << 2) #define H323_DTMF_H245SIGNAL (1 << 3) #define H323_DTMF_INBAND (1 << 4) +#define H323_DTMF_CISCO (1 << 5) #define H323_DTMF_INBANDRELAX (1 << 8) struct h323_pvt; int ooh323c_start_stack_thread(void); int ooh323c_stop_stack_thread(void); int ooh323c_set_capability - (struct ast_codec_pref *prefs, int capability, int dtmf); + (struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec); int convertH323CapToAsteriskCap(int cap); int ooh323c_set_capability_for_call - (ooCallData *call, struct ast_codec_pref *prefs, int capability, int dtmf, int t38support); + (ooCallData *call, struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcode, + int t38support); #endif --- ../bb/asterisk-addons-1.6.1.0/channels/chan_ooh323.h 2009-10-20 23:02:27.000000000 +0400 +++ channels/chan_ooh323.h 2009-08-04 04:59:40.000000000 +0400 @@ -97,7 +97,7 @@ struct ast_frame *ooh323_rtp_read (struct ast_channel *ast, struct ooh323_pvt *p); -void ooh323_set_write_format(ooCallData *call, int fmt); +void ooh323_set_write_format(ooCallData *call, int fmt, int txframes); void ooh323_set_read_format(ooCallData *call, int fmt); int ooh323_update_capPrefsOrderForCall --- ../bb/asterisk-addons-1.6.1.0/channels/chan_ooh323.c 2009-10-20 23:02:27.000000000 +0400 +++ channels/chan_ooh323.c 2009-10-18 01:35:52.000000000 +0400 @@ -17,6 +17,7 @@ #include "chan_ooh323.h" #include +#include #define HAVE_SPANDSP_EXPOSE_H #include @@ -53,6 +54,14 @@ static const char tdesc[] = "Objective Systems H323 Channel Driver"; static const char config[] = "ooh323.conf"; +static struct ast_jb_conf default_jbconf = +{ + .flags = 0, + .max_size = -1, + .resync_threshold = -1, + .impl = "" +}; +static struct ast_jb_conf global_jbconf; /* Channel Definition */ static struct ast_channel *ooh323_request(const char *type, int format, @@ -162,6 +171,7 @@ int capability; struct ast_codec_pref prefs; int dtmfmode; + int dtmfcodec; char exten[AST_MAX_EXTENSION]; /* Requested extension */ char context[AST_MAX_EXTENSION]; /* Context where to start */ char accountcode[256]; /* Account code */ @@ -169,6 +179,8 @@ int amaflags; int progsent; /* progress is sent */ struct ast_dsp *vad; + struct OOH323Regex *rtpmask; /* rtp ip regexp */ + char rtpmaskstr[120]; struct ooh323_pvt *next; /* Next entity */ } *iflist = NULL; @@ -187,10 +199,13 @@ int capability; struct ast_codec_pref prefs; int dtmfmode; + int dtmfcodec; int t38support; int rtptimeout; int mUseIP; /* Use IP address or H323-ID to search user */ char mIP[20]; + struct OOH323Regex *rtpmask; + char rtpmaskstr[120]; struct ooh323_user *next; }; @@ -205,6 +220,7 @@ char accountcode[20]; int amaflags; int dtmfmode; + int dtmfcodec; int t38support; int mFriend; /* indicates defined as friend */ char ip[20]; @@ -214,6 +230,8 @@ char *url; /* url alias, which asterisk will register with gk to reach this peer*/ char *e164; /* e164 alias, which asterisk will register with gk to reach this peer*/ int rtptimeout; + struct OOH323Regex *rtpmask; + char rtpmaskstr[120]; struct ooh323_peer *next; }; @@ -259,6 +277,7 @@ static int gCapability = AST_FORMAT_ULAW; static struct ast_codec_pref gPrefs; static int gDTMFMode = H323_DTMF_RFC2833; +static int gDTMFCodec = 101; static int gT38Support = T38_FAXGW; static char gGatekeeper[100]; static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper; @@ -308,9 +327,9 @@ const char *host, int capability) { struct ast_channel *ch = NULL; - int fmt; + int fmt = 0; if (gH323Debug) - ast_verbose("--- ooh323_new - %s\n", host); + ast_verbose("--- ooh323_new - %s, %d\n", host, capability); /* Don't hold a h323 pvt lock while we allocate a channel */ @@ -328,23 +347,23 @@ ast_channel_lock(ch); ch->tech = &ooh323_tech; - fmt = ast_codec_pref_index(&i->prefs, 0); - if (!fmt) + if (capability) fmt = ast_best_codec(capability); + if (!fmt) + fmt = ast_codec_pref_index(&i->prefs, 0); ch->nativeformats = ch->rawwriteformat = ch->rawreadformat = fmt; ast_channel_set_fd(ch, 0, ast_rtp_fd(i->rtp)); ast_channel_set_fd(ch, 1, ast_rtcp_fd(i->rtp)); ast_channel_set_fd(ch, 5, ast_udptl_fd(i->udptl)); - + + ast_jb_configure(ch, &global_jbconf); if (state == AST_STATE_RING) ch->rings = 1; ch->adsicpe = AST_ADSI_UNAVAILABLE; - if (capability) - fmt = ast_best_codec(capability); ast_set_write_format(ch, fmt); ast_set_read_format(ch, fmt); ch->tech_pvt = i; @@ -484,6 +503,7 @@ OO_SETFLAG(pvt->flags, H323_DISABLEGK); pvt->dtmfmode = gDTMFMode; + pvt->dtmfcodec = gDTMFCodec; ast_copy_string(pvt->context, gContext, sizeof(pvt->context)); ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode)); @@ -592,11 +612,17 @@ p->capability = peer->capability; memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref)); p->dtmfmode |= peer->dtmfmode; + p->dtmfcodec = peer->dtmfcodec; p->t38support = peer->t38support; + if (peer->rtpmask && peer->rtpmaskstr[0]) { + p->rtpmask = peer->rtpmask; + ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr)); + } ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode)); p->amaflags = peer->amaflags; } else { p->dtmfmode = gDTMFMode; + p->dtmfcodec = gDTMFCodec; p->t38support = gT38Support; p->capability = gCapability; @@ -794,9 +820,7 @@ (p->dtmfmode & H323_DTMF_H245SIGNAL))) { dtmf[0] = digit; dtmf[1] = '\0'; - /* ast_mutex_lock(&ooh323c_cmd_lock); */ ooSendDTMFDigit(p->callToken, dtmf); - /* ast_mutex_unlock(&ooh323c_cmd_lock); */ } ast_mutex_unlock(&p->lock); if (gH323Debug) @@ -817,7 +841,7 @@ return -1; } ast_mutex_lock(&p->lock); - if (p->rtp && (p->dtmfmode & H323_DTMF_RFC2833)) + if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) ast_rtp_senddigit_end(p->rtp, digit); ast_mutex_unlock(&p->lock); @@ -961,10 +985,8 @@ ast_verbose(" hanging %s with cause: %d\n", p->username, q931cause); ast->tech_pvt = NULL; if (!ast_test_flag(p, H323_ALREADYGONE)) { - ast_mutex_lock(&ooh323c_cmd_lock); ooHangCall(p->callToken, ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause); - ast_mutex_unlock(&ooh323c_cmd_lock); ast_set_flag(p, H323_ALREADYGONE); /* ast_mutex_unlock(&p->lock); */ } else @@ -1010,9 +1032,7 @@ if (option_debug) ast_debug(1, "ooh323_answer(%s)\n", ast->name); ast_channel_unlock(ast); - /* ast_mutex_lock(&ooh323c_cmd_lock); */ ooAnswerCall(p->callToken); - /* ast_mutex_unlock(&ooh323c_cmd_lock); */ } ast_mutex_unlock(&p->lock); } @@ -1165,21 +1185,18 @@ if (gH323Debug) ast_verbose("----- ooh323_indicate %d on call %s\n", condition, callToken); - ast_mutex_lock(&p->lock); + ast_mutex_lock(&p->lock); switch (condition) { case AST_CONTROL_CONGESTION: if (!ast_test_flag(p, H323_ALREADYGONE)) { - ast_mutex_lock(&ooh323c_cmd_lock); - ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION); - ast_mutex_unlock(&ooh323c_cmd_lock); + ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, + AST_CAUSE_SWITCH_CONGESTION); ast_set_flag(p, H323_ALREADYGONE); } break; case AST_CONTROL_BUSY: if (!ast_test_flag(p, H323_ALREADYGONE)) { - ast_mutex_lock(&ooh323c_cmd_lock); - ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY); - ast_mutex_unlock(&ooh323c_cmd_lock); + ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY); ast_set_flag(p, H323_ALREADYGONE); } break; @@ -1190,23 +1207,26 @@ ast_moh_stop(ast); break; case AST_CONTROL_PROGRESS: - if (!p->progsent) { - /* ast_mutex_lock(&ooh323c_cmd_lock); */ - if (gH323Debug) - ast_log(LOG_DEBUG,"Sending manual progress for %s, res = %d\n", callToken, - ooManualProgress(callToken)); else - ooManualProgress(callToken); - p->progsent = 1; - /* ast_mutex_unlock(&ooh323c_cmd_lock); */ - } + if (ast->_state != AST_STATE_UP) { + if (!p->progsent) { + if (gH323Debug) + ast_log(LOG_DEBUG,"Sending manual progress for %s, res = %d\n", callToken, + ooManualProgress(callToken)); + else + ooManualProgress(callToken); + p->progsent = 1; + } + } break; case AST_CONTROL_RINGING: - /* ast_mutex_lock(&ooh323c_cmd_lock); */ - if (gH323Debug) - ast_log(LOG_DEBUG,"Sending manual ringback for %s, res = %d\n", callToken, - ooManualRingback(callToken)); else - ooManualRingback(callToken); - /* ast_mutex_unlock(&ooh323c_cmd_lock); */ + if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) { + if (gH323Debug) + ast_log(LOG_DEBUG,"Sending manual ringback for %s, res = %d\n", + callToken, + ooManualRingback(callToken)); + else + ooManualRingback(callToken); + } break; case AST_CONTROL_SRCUPDATE: ast_rtp_new_source(p->rtp); @@ -1346,14 +1366,14 @@ } -void ooh323_set_write_format(ooCallData *call, int fmt) +void ooh323_set_write_format(ooCallData *call, int fmt, int txframes) { struct ooh323_pvt *p = NULL; char formats[512]; if (gH323Debug) - ast_verbose("--- ooh323_update_writeformat %s\n", - ast_getformatname_multiple(formats,512, fmt)); + ast_verbose("--- ooh323_update_writeformat %s/%d\n", + ast_getformatname_multiple(formats,512, fmt), txframes); p = find_call(call); if (!p) { @@ -1381,6 +1401,10 @@ ast_verbose("Writeformat before update %s/%s\n", ast_getformatname_multiple(formats,512, p->owner->writeformat), ast_getformatname_multiple(formats,512, p->owner->nativeformats)); + if (txframes) + ast_codec_pref_setsize(&p->prefs, fmt, txframes); + ast_rtp_codec_setpref(p->rtp, &p->prefs); + p->owner->nativeformats = fmt; ast_set_write_format(p->owner, p->owner->writeformat); ast_set_read_format(p->owner, p->owner->readformat); @@ -1666,8 +1690,8 @@ } if (p->callerid_name) { */ - user = find_user(p->callerid_name, call->remoteIP); - if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) { + user = find_user(p->callerid_name, call->remoteIP); + if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) { ast_mutex_lock(&user->lock); p->username = strdup(user->name); p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) : @@ -1678,7 +1702,13 @@ p->capability = user->capability; memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref)); p->dtmfmode |= user->dtmfmode; + p->dtmfcodec = user->dtmfcodec; p->t38support = user->t38support; + if (user->rtpmask && user->rtpmaskstr[0]) { + p->rtpmask = user->rtpmask; + ast_copy_string(p->rtpmaskstr, user->rtpmaskstr, + sizeof(p->rtpmaskstr)); + } /* Since, call is coming from a pbx user, no need to use gk */ /* OO_SETFLAG(p->flags, H323_DISABLEGK); OO_SETFLAG(call->flags, OO_M_DISABLEGK); */ @@ -1690,19 +1720,16 @@ } else { ast_mutex_unlock(&p->lock); ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP); - ast_mutex_lock(&ooh323c_cmd_lock); if (!user) ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED); else ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION); - ast_mutex_unlock(&ooh323c_cmd_lock); - ast_set_flag(p, H323_NEEDDESTROY); + ast_set_flag(p, H323_ALREADYGONE); return -1; } } -/* } */ - ooh323c_set_capability_for_call(call, &p->prefs, p->capability, p->dtmfmode, p->t38support); + ooh323c_set_capability_for_call(call, &p->prefs, p->capability, p->dtmfmode, p->dtmfcodec, p->t38support); configure_local_rtp(p, call); /* Incoming call */ @@ -1774,7 +1801,13 @@ ooCallAddAliasH323ID(call, p->callerid_num); } } - + if (p->rtpmask && p->rtpmaskstr[0]) { + call->rtpMask = p->rtpmask; + ast_mutex_lock(&call->rtpMask->lock); + call->rtpMask->inuse++; + ast_mutex_unlock(&call->rtpMask->lock); + ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr)); + } ast_mutex_unlock(&p->lock); } @@ -1804,6 +1837,7 @@ p = find_call(call); if (!p) { ast_log(LOG_ERROR, "Failed to find a matching call.\n"); + ast_mutex_unlock(&call->Lock); return -1; } ast_mutex_lock(&p->lock); @@ -1862,7 +1896,7 @@ } ooh323c_set_capability_for_call(call, &p->prefs, p->capability, - p->dtmfmode, p->t38support); + p->dtmfmode, p->dtmfcodec, p->t38support); configure_local_rtp(p, call); ast_mutex_unlock(&p->lock); @@ -1933,7 +1967,7 @@ while (p->owner) { if (ast_channel_trylock(p->owner)) { ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n"); - ast_log(LOG_DEBUG,"Failed to grab lock, trying again\n"); + ast_log(LOG_DEBUG,"Failed to grab lock, trying again\n"); ast_mutex_unlock(&p->lock); usleep(1); ast_mutex_lock(&p->lock); @@ -2055,12 +2089,14 @@ user = ast_calloc(1,sizeof(struct ooh323_user)); if (user) { + memset(user, 0, sizeof(struct ooh323_user)); ast_mutex_init(&user->lock); ast_copy_string(user->name, name, sizeof(user->name)); user->capability = gCapability; memcpy(&user->prefs, &gPrefs, sizeof(user->prefs)); user->rtptimeout = gRTPTimeout; user->dtmfmode = gDTMFMode; + user->dtmfcodec = gDTMFCodec; user->t38support = gT38Support; /* set default context */ ast_copy_string(user->context, gContext, sizeof(user->context)); @@ -2081,6 +2117,15 @@ user->rtptimeout = atoi(v->value); if (user->rtptimeout < 0) user->rtptimeout = gRTPTimeout; + } else if (!strcasecmp(v->name, "rtpmask")) { + if ((user->rtpmask = malloc(sizeof(struct OOH323Regex))) && + (regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED) + == 0)) { + ast_mutex_init(&user->rtpmask->lock); + user->rtpmask->inuse = 1; + ast_copy_string(user->rtpmaskstr, v->value, + sizeof(user->rtpmaskstr)); + } else user->rtpmask = NULL; } else if (!strcasecmp(v->name, "disallow")) { ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0); @@ -2102,6 +2147,8 @@ } else if (!strcasecmp(v->name, "dtmfmode")) { if (!strcasecmp(v->value, "rfc2833")) user->dtmfmode = H323_DTMF_RFC2833; + if (!strcasecmp(v->value, "cisco")) + user->dtmfmode = H323_DTMF_CISCO; else if (!strcasecmp(v->value, "q931keypad")) user->dtmfmode = H323_DTMF_Q931; else if (!strcasecmp(v->value, "h245alphanumeric")) @@ -2112,6 +2159,8 @@ user->dtmfmode = H323_DTMF_INBAND; } else if (!strcasecmp(v->name, "relaxdtmf")) { user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; + } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { + user->dtmfcodec = atoi(v->value); } else if (!strcasecmp(v->name, "t38support")) { if (!strcasecmp(v->value, "disabled")) user->t38support = T38_DISABLED; @@ -2152,6 +2201,7 @@ ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode)); peer->amaflags = gAMAFLAGS; peer->dtmfmode = gDTMFMode; + peer->dtmfcodec = gDTMFCodec; peer->t38support = gT38Support; peer->port = 1720; if (0 == friend_type) { @@ -2191,18 +2241,27 @@ peer->port = atoi(v->value); } else if (!strcasecmp(v->name, "ip")) { ast_copy_string(peer->ip, v->value, sizeof(peer->ip)); - } else if (!strcasecmp(v->name, "host")) { - ast_copy_string(peer->ip, v->value, sizeof(peer->ip)); + } else if (!strcasecmp(v->name, "host")) { + ast_copy_string(peer->ip, v->value, sizeof(peer->ip)); } else if (!strcasecmp(v->name, "outgoinglimit")) { - peer->outgoinglimit = atoi(v->value); - if (peer->outgoinglimit < 0) + peer->outgoinglimit = atoi(v->value); + if (peer->outgoinglimit < 0) peer->outgoinglimit = 0; } else if (!strcasecmp(v->name, "accountcode")) { ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); } else if (!strcasecmp(v->name, "rtptimeout")) { - peer->rtptimeout = atoi(v->value); - if(peer->rtptimeout < 0) + peer->rtptimeout = atoi(v->value); + if(peer->rtptimeout < 0) peer->rtptimeout = gRTPTimeout; + } else if (!strcasecmp(v->name, "rtpmask")) { + if ((peer->rtpmask = malloc(sizeof(struct OOH323Regex))) && + (regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED) + == 0)) { + ast_mutex_init(&peer->rtpmask->lock); + peer->rtpmask->inuse = 1; + ast_copy_string(peer->rtpmaskstr, v->value, + sizeof(peer->rtpmaskstr)); + } else peer->rtpmask = NULL; } else if (!strcasecmp(v->name, "disallow")) { ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); @@ -2218,6 +2277,8 @@ } else if (!strcasecmp(v->name, "dtmfmode")) { if (!strcasecmp(v->value, "rfc2833")) peer->dtmfmode = H323_DTMF_RFC2833; + if (!strcasecmp(v->value, "cisco")) + peer->dtmfmode = H323_DTMF_CISCO; else if (!strcasecmp(v->value, "q931keypad")) peer->dtmfmode = H323_DTMF_Q931; else if (!strcasecmp(v->value, "h245alphanumeric")) @@ -2228,6 +2289,8 @@ peer->dtmfmode = H323_DTMF_INBAND; } else if (!strcasecmp(v->name, "relaxdtmf")) { peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; + } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { + peer->dtmfcodec = atoi(v->value); } else if (!strcasecmp(v->name, "t38support")) { if (!strcasecmp(v->value, "disabled")) peer->t38support = T38_DISABLED; @@ -2355,6 +2418,7 @@ gCapability = AST_FORMAT_ALAW; memset(&gPrefs, 0, sizeof(struct ast_codec_pref)); gDTMFMode = H323_DTMF_RFC2833; + gDTMFCodec = 101; gT38Support = T38_FAXGW; gTRCLVL = OOTRCLVLERR; gRasGkMode = RasNoGatekeeper; @@ -2372,6 +2436,11 @@ v = ast_variable_browse(cfg, "general"); while (v) { + + if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) { + v = v->next; + continue; + } if (!strcasecmp(v->name, "port")) { gPort = (int)strtol(v->value, NULL, 10); @@ -2489,7 +2558,7 @@ if (gRTPTimeout <= 0) gRTPTimeout = 60; } else if (!strcasecmp(v->name, "tos")) { - if (sscanf(v->value, "%i", &format) == 1) + if (sscanf(v->value, "%30i", &format) == 1) gTOS = format & 0xff; else if (!strcasecmp(v->value, "lowdelay")) gTOS = IPTOS_LOWDELAY; @@ -2522,6 +2591,8 @@ gDTMFMode = H323_DTMF_INBAND; else if (!strcasecmp(v->value, "rfc2833")) gDTMFMode = H323_DTMF_RFC2833; + else if (!strcasecmp(v->value, "cisco")) + gDTMFMode = H323_DTMF_CISCO; else if (!strcasecmp(v->value, "q931keypad")) gDTMFMode = H323_DTMF_Q931; else if (!strcasecmp(v->value, "h245alphanumeric")) @@ -2535,6 +2606,8 @@ } } else if (!strcasecmp(v->name, "relaxdtmf")) { gDTMFMode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; + } else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { + gDTMFCodec = atoi(v->value); } else if (!strcasecmp(v->name, "t38support")) { if (!strcasecmp(v->value, "disabled")) gT38Support = T38_DISABLED; @@ -2645,9 +2718,13 @@ print_codec_to_cli(a->fd, &peer->prefs); ast_cli(a->fd, ")\n"); ast_cli(a->fd, "%-15.15s", "DTMF Mode: "); - if (peer->dtmfmode & H323_DTMF_RFC2833) + if (peer->dtmfmode & H323_DTMF_CISCO) { + ast_cli(a->fd, "%s\n", "cisco"); + ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec); + } else if (peer->dtmfmode & H323_DTMF_RFC2833) { ast_cli(a->fd, "%s\n", "rfc2833"); - else if (peer->dtmfmode & H323_DTMF_Q931) + ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec); + } else if (peer->dtmfmode & H323_DTMF_Q931) ast_cli(a->fd, "%s\n", "q931keypad"); else if (peer->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ast_cli(a->fd, "%s\n", "h245alphanumeric"); @@ -2660,7 +2737,7 @@ else ast_cli(a->fd, "%s\n", "unknown"); - ast_cli(a->fd,"%-15s", "T.38 Mode: "); + ast_cli(a->fd,"%-15s", "T.38 Mode: "); if (peer->t38support == T38_DISABLED) ast_cli(a->fd, "%s\n", "disabled"); else if (peer->t38support == T38_TRANSPARENT) @@ -2668,16 +2745,18 @@ else if (peer->t38support == T38_FAXGW) ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible"); - ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode); - ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", + ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode); + ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ", ast_cdr_flags2str(peer->amaflags)); - ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port); - ast_cli(a->fd, "%-15.15s%d\n", "OutgoingLimit: ", peer->outgoinglimit); - ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout); - ast_mutex_unlock(&peer->lock); + ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port); + ast_cli(a->fd, "%-15.15s%d\n", "OutgoingLimit: ", peer->outgoinglimit); + ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout); + if (peer->rtpmaskstr[0]) + ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", peer->rtpmaskstr); + ast_mutex_unlock(&peer->lock); } else { - ast_cli(a->fd, "Peer %s not found\n", a->argv[3]); - ast_cli(a->fd, "\n"); + ast_cli(a->fd, "Peer %s not found\n", a->argv[3]); + ast_cli(a->fd, "\n"); } ast_mutex_unlock(&peerl.lock); @@ -2782,9 +2861,13 @@ print_codec_to_cli(a->fd, &user->prefs); ast_cli(a->fd, ")\n"); ast_cli(a->fd, "%-15.15s", "DTMF Mode: "); - if (user->dtmfmode & H323_DTMF_RFC2833) + if (user->dtmfmode & H323_DTMF_CISCO) { + ast_cli(a->fd, "%s\n", "cisco"); + ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec); + } else if (user->dtmfmode & H323_DTMF_RFC2833) { ast_cli(a->fd, "%s\n", "rfc2833"); - else if (user->dtmfmode & H323_DTMF_Q931) + ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec); + } else if (user->dtmfmode & H323_DTMF_Q931) ast_cli(a->fd, "%s\n", "q931keypad"); else if (user->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ast_cli(a->fd, "%s\n", "h245alphanumeric"); @@ -2812,6 +2895,8 @@ ast_cli(a->fd, "%-15.15s%d\n", "IncomingLimit: ", user->incominglimit); ast_cli(a->fd, "%-15.15s%d\n", "InUse: ", user->inUse); ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", user->rtptimeout); + if (user->rtpmaskstr[0]) + ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", user->rtpmaskstr); ast_mutex_unlock(&user->lock); } else { ast_cli(a->fd, "User %s not found\n", a->argv[3]); @@ -2954,9 +3039,13 @@ ast_getformatname_multiple(value,512,gCapability)); ast_cli(a->fd, "%-20s", "DTMF Mode: "); - if (gDTMFMode & H323_DTMF_RFC2833) + if (gDTMFMode & H323_DTMF_CISCO) { + ast_cli(a->fd, "%s\n", "cisco"); + ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec); + } else if (gDTMFMode & H323_DTMF_RFC2833) { ast_cli(a->fd, "%s\n", "rfc2833"); - else if (gDTMFMode & H323_DTMF_Q931) + ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec); + } else if (gDTMFMode & H323_DTMF_Q931) ast_cli(a->fd, "%s\n", "q931keypad"); else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC) ast_cli(a->fd, "%s\n", "h245alphanumeric"); @@ -3149,7 +3238,7 @@ ooH323EpSetH323Callbacks(h323Callbacks); /* Add endpoint capabilities */ - if (ooh323c_set_capability(&gPrefs, gCapability, gDTMFMode) < 0) { + if (ooh323c_set_capability(&gPrefs, gCapability, gDTMFMode, gDTMFCodec) < 0) { ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n"); return 1; } @@ -3326,7 +3415,6 @@ cur->callerid_num = 0; } - if (cur->rtp) { ast_rtp_destroy(cur->rtp); cur->rtp = 0; @@ -3398,6 +3486,16 @@ if(prev->email) free(prev->email); if(prev->url) free(prev->url); if(prev->e164) free(prev->e164); + if(prev->rtpmask) { + ast_mutex_lock(&prev->rtpmask->lock); + prev->rtpmask->inuse--; + ast_mutex_unlock(&prev->rtpmask->lock); + if (prev->rtpmask->inuse == 0) { + regfree(&prev->rtpmask->regex); + ast_mutex_destroy(&prev->rtpmask->lock); + free(prev->rtpmask); + } + } free(prev); if (cur == peerl.peers) { @@ -3418,6 +3516,17 @@ prev = cur; cur = cur->next; ast_mutex_destroy(&prev->lock); + + if(prev->rtpmask) { + ast_mutex_lock(&prev->rtpmask->lock); + prev->rtpmask->inuse--; + ast_mutex_unlock(&prev->rtpmask->lock); + if (prev->rtpmask->inuse == 0) { + regfree(&prev->rtpmask->regex); + ast_mutex_destroy(&prev->rtpmask->lock); + free(prev->rtpmask); + } + } free(prev); if (cur == userl.users) { break; @@ -3619,6 +3728,10 @@ case AST_FORMAT_AMRNB: return OO_AMRNB; #endif +#ifdef AST_FORMAT_SPEEX + case AST_FORMAT_SPEEX: + return OO_SPEEX; +#endif case AST_FORMAT_G729A: return OO_G729A; @@ -3678,7 +3791,15 @@ if (p->rtp) { ast_rtp_codec_setpref(p->rtp, &p->prefs); - } + if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) { + ast_rtp_set_rtpmap_type(p->rtp, p->dtmfcodec, "audio", + "telephone-event", 0); + } + if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) { + ast_rtp_set_rtpmap_type(p->rtp, p->dtmfcodec, "audio", + "cisco-telephone-event", 0); + } + } /* figure out our local RTP port and tell the H.323 stack about it*/ ast_rtp_get_us(p->rtp, &us); @@ -3730,7 +3851,7 @@ struct sockaddr_in them; if (gH323Debug) - ast_verbose("--- setup_rtp_connection\n"); + ast_verbose("--- setup_rtp_connection %s:%d\n", remoteIp, remotePort); /* Find the call or allocate a private structure if call not found */ p = find_call(call); --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323cDriver.c 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323cDriver.c 2009-10-20 01:08:30.000000000 +0400 @@ -16,12 +16,17 @@ #include "ooh323cDriver.h" +#include +#include + #include #include #undef AST_BACKGROUND_STACKSIZE #define AST_BACKGROUND_STACKSIZE 768 * 1024 +#define SEC_TO_HOLD_THREAD 24 + extern OOBOOL gH323Debug; extern OOH323EndPoint gH323ep; /* ooh323c stack thread. */ @@ -31,6 +36,17 @@ static int gtxframes = 20; +static struct callthread { + ast_mutex_t lock; + int thePipe[2]; + OOBOOL inUse; + ooCallData* call; + struct callthread *next, *prev; +} *callThreads = NULL; + +AST_MUTEX_DEFINE_STATIC(callThreadsLock); + + int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel); int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel); int ooh323c_stop_receive_channel(ooCallData *call, ooLogicalChannel *pChannel); @@ -57,36 +73,111 @@ void* ooh323c_call_thread(void* dummy) { - ooMonitorCallChannels((ooCallData*)dummy); - /* ast_mutex_lock(&call->Lock); - ast_mutex_unlock(&call->Lock); - ast_mutex_destroy(&call->Lock); - memFreePtr(&gH323ep.ctxt, call); */ + struct callthread* mycthread = (struct callthread *)dummy; + struct timespec ts; + struct pollfd pfds[1]; + char c; + + do { + + ooMonitorCallChannels((ooCallData*)mycthread->call); + mycthread->call = NULL; + mycthread->prev = NULL; + mycthread->inUse = FALSE; + + ast_mutex_lock(&callThreadsLock); + mycthread->next = callThreads; + callThreads = mycthread; + if (mycthread->next) mycthread->next->prev = mycthread; + ast_mutex_unlock(&callThreadsLock); + + pfds[0].fd = mycthread->thePipe[0]; + pfds[0].events = POLLIN; + ooSocketPoll(pfds, 1, SEC_TO_HOLD_THREAD * 1000); + if (ooPDRead(pfds, 1, mycthread->thePipe[0])) + read(mycthread->thePipe[0], &c, 1); + + ast_mutex_lock(&callThreadsLock); + ast_mutex_lock(&mycthread->lock); + if (mycthread->prev) + mycthread->prev->next = mycthread->next; + else + callThreads = mycthread->next; + if (mycthread->next) + mycthread->next->prev = mycthread->prev; + ast_mutex_unlock(&mycthread->lock); + ast_mutex_unlock(&callThreadsLock); + + } while (mycthread->call != NULL); + + + ast_mutex_destroy(&mycthread->lock); + + free(mycthread); return dummy; } -/* int ooh323c_start_call_thread(ooCallData *call) { - if(ast_pthread_create(&call->callThread, NULL, ooh323c_call_thread, call) < 0) - { - ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n", call->callToken); - return -1; - } - return 0; -} */ - int ooh323c_start_call_thread(ooCallData *call) { pthread_attr_t attr; + char c = 'c'; + struct callthread *cur = callThreads; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ast_mutex_lock(&callThreadsLock); + while (cur != NULL && (cur->inUse || ast_mutex_trylock(&cur->lock))) { + cur = cur->next; + } + ast_mutex_unlock(&callThreadsLock); + + if (cur != NULL && cur->inUse) { + ast_mutex_unlock(&cur->lock); + cur = NULL; + } + +/* make new thread */ + if (cur == NULL) { + if (!(cur = ast_malloc(sizeof(struct callthread)))) { + ast_log(LOG_ERROR, "Unable to allocate thread structure for call %s\n", + call->callToken); + return -1; + } + + memset(cur, 0, sizeof(cur)); + if ((socketpair(PF_LOCAL, SOCK_STREAM, 0, cur->thePipe)) == -1) { + ast_log(LOG_ERROR, "Can't create thread pipe for call %s\n", call->callToken); + free(cur); + return -1; + } + cur->inUse = TRUE; + cur->call = call; + + ast_mutex_init(&cur->lock); + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + if (gH323Debug) + ast_debug(1,"new call thread created for call %s\n", call->callToken); + + if(ast_pthread_create_background(&call->callThread, &attr, ooh323c_call_thread, cur) < 0) + { + ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n", + call->callToken); + pthread_attr_destroy(&attr); + ast_mutex_destroy(&cur->lock); + free(cur); + return -1; + } + pthread_attr_destroy(&attr); + + } else { + if (gH323Debug) + ast_debug(1,"using existing call thread for call %s\n", call->callToken); + cur->inUse = TRUE; + cur->call = call; + write(cur->thePipe[1], &c, 1); + ast_mutex_unlock(&cur->lock); - if(ast_pthread_create_background(&call->callThread, &attr, ooh323c_call_thread, call) < 0) - { - ast_log(LOG_ERROR, "Unable to start ooh323c call thread for call %s\n", call->callToken); - pthread_attr_destroy(&attr); - return -1; } - pthread_attr_destroy(&attr); return 0; } @@ -94,8 +185,6 @@ int ooh323c_stop_call_thread(ooCallData *call) { if (call->callThread != AST_PTHREADT_NULL) { ooStopMonitorCallChannels(call); - /* pthread_join(call->callThread, NULL); - call->callThread = AST_PTHREADT_NULL;*/ } return 0; } @@ -129,7 +218,7 @@ } int ooh323c_set_capability - (struct ast_codec_pref *prefs, int capability, int dtmf) + (struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec) { int ret, x, format=0; if(gH323Debug) @@ -188,7 +277,7 @@ { if(gH323Debug) ast_verbose("\tAdding g7231 capability to H323 endpoint\n"); - ret = ooH323EpAddG7231Capability(OO_G7231, 4, 7, FALSE, + ret = ooH323EpAddG7231Capability(OO_G7231, 1, 1, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, @@ -257,9 +346,25 @@ } #endif + +#ifdef AST_FORMAT_SPEEX + if(format & AST_FORMAT_SPEEX) + { + if(gH323Debug) + ast_verbose("\tAdding speex capability to H323 endpoint\n"); + ret = ooH323EpAddSpeexCapability(OO_SPEEX, 4, 4, FALSE, + OORXANDTX, &ooh323c_start_receive_channel, + &ooh323c_start_transmit_channel, + &ooh323c_stop_receive_channel, + &ooh323c_stop_transmit_channel); + + } +#endif } + if(dtmf & H323_DTMF_CISCO) + ret |= ooH323EpEnableDTMFCISCO(0); if(dtmf & H323_DTMF_RFC2833) ret |= ooH323EpEnableDTMFRFC2833(0); else if(dtmf & H323_DTMF_H245ALPHANUMERIC) @@ -271,15 +376,18 @@ } int ooh323c_set_capability_for_call - (ooCallData *call, struct ast_codec_pref *prefs, int capability, int dtmf, int t38support) + (ooCallData *call, struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec, + int t38support) { int ret, x, txframes; int format=0; if(gH323Debug) ast_verbose("\tAdding capabilities to call(%s, %s)\n", call->callType, call->callToken); + if(dtmf & H323_DTMF_CISCO || 1) + ret |= ooCallEnableDTMFCISCO(call,dtmfcodec); if(dtmf & H323_DTMF_RFC2833 || 1) - ret |= ooCallEnableDTMFRFC2833(call,0); + ret |= ooCallEnableDTMFRFC2833(call,dtmfcodec); if(dtmf & H323_DTMF_H245ALPHANUMERIC || 1) ret |= ooCallEnableDTMFH245Alphanumeric(call); if(dtmf & H323_DTMF_H245SIGNAL || 1) @@ -302,7 +410,7 @@ call->callType, call->callToken); txframes = prefs->framing[x]; ret= ooCallAddG711Capability(call, OO_G711ULAW64K, txframes, - grxframes, OORXANDTX, + txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, @@ -315,7 +423,7 @@ call->callType, call->callToken); txframes = prefs->framing[x]; ret= ooCallAddG711Capability(call, OO_G711ALAW64K, txframes, - grxframes, OORXANDTX, + txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, @@ -357,7 +465,7 @@ if(gH323Debug) ast_verbose("\tAdding g729 capability to call(%s, %s)\n", call->callType, call->callToken); - ret|= ooCallAddG729Capability(call, OO_G729, txframes, 4, + ret|= ooCallAddG729Capability(call, OO_G729, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, @@ -365,7 +473,7 @@ if(gH323Debug) ast_verbose("\tAdding g729A capability to call(%s, %s)\n", call->callType, call->callToken); - ret= ooCallAddG729Capability(call, OO_G729A, txframes, 4, + ret= ooCallAddG729Capability(call, OO_G729A, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, @@ -373,7 +481,7 @@ if(gH323Debug) ast_verbose("\tAdding g729B capability to call(%s, %s)\n", call->callType, call->callToken); - ret|= ooCallAddG729Capability(call, OO_G729B, txframes, 4, + ret|= ooCallAddG729Capability(call, OO_G729B, txframes, txframes, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, @@ -386,7 +494,7 @@ if(gH323Debug) ast_verbose("\tAdding g7231 capability to call (%s, %s)\n", call->callType, call->callToken); - ret = ooCallAddG7231Capability(call, OO_G7231, 4, 7, FALSE, + ret = ooCallAddG7231Capability(call, OO_G7231, 1, 1, FALSE, OORXANDTX, &ooh323c_start_receive_channel, &ooh323c_start_transmit_channel, &ooh323c_stop_receive_channel, @@ -432,6 +540,19 @@ &ooh323c_stop_transmit_channel); } #endif +#ifdef AST_FORMAT_SPEEX + if(format & AST_FORMAT_SPEEX) + { + if(gH323Debug) + ast_verbose("\tAdding Speex capability to call(%s, %s)\n", + call->callType, call->callToken); + ret = ooCallAddSpeexCapability(call, OO_SPEEX, 4, 4, FALSE, + OORXANDTX, &ooh323c_start_receive_channel, + &ooh323c_start_transmit_channel, + &ooh323c_stop_receive_channel, + &ooh323c_stop_transmit_channel); + } +#endif } } @@ -481,7 +602,17 @@ int fmt=-1; fmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap); if(fmt>0) { - ooh323_set_write_format(call, fmt); + switch (fmt) { + case AST_FORMAT_ALAW: + case AST_FORMAT_ULAW: + ooh323_set_write_format(call, fmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes); + break; + case AST_FORMAT_G729A: + ooh323_set_write_format(call, fmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10); + break; + default: + ooh323_set_write_format(call, fmt, 0); + } }else{ ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n", call->callToken); @@ -541,6 +672,10 @@ case OO_AMRNB: return AST_FORMAT_AMRNB; #endif +#ifdef AST_FORMAT_SPEEX + case OO_SPEEX: + return AST_FORMAT_SPEEX; +#endif case OO_G729: return AST_FORMAT_G729A; --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/oochannels.c 2009-10-20 23:02:38.000000000 +0400 +++ channels/ooh323c/src/oochannels.c 2009-10-18 23:34:33.000000000 +0400 @@ -959,7 +959,7 @@ ast_mutex_lock(&call->Lock); ast_mutex_unlock(&call->Lock); ast_mutex_destroy(&call->Lock); - sem_destroy(&call->gkWait); + ast_cond_destroy(&call->gkWait); pctxt = call->pctxt; freeContext(pctxt); free(pctxt); @@ -1037,6 +1037,21 @@ /* Remaining message length is length - tpkt length */ len = len - 4; + if(len > MAXMSGLEN - 4) + { + OOTRACEERR4("Error: Invalid TPKT header for H225 message " + "Len = %d (%s, %s)\n", len, call->callType, + call->callToken); + ooCloseH225Connection(call); + ooFreeQ931Message(pctxt, pmsg); + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + /* Now read actual Q931 message body. We should make sure that we receive complete message as indicated by len. If we don't then there is something wrong. The loop below receives message, then checks whether @@ -1198,6 +1213,20 @@ for remaining bytes of the message. If message is not received in 3 seconds, then we have a problem. Report an error and exit. */ + + if(len > MAXMSGLEN - 4) + { + OOTRACEERR4("Error: Invalid TPKT header length %d for H245 message (%s, %s)\n", + len, call->callType, call->callToken); + ooFreeH245Message(call, pmsg); + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + while(total < len) { recvLen = ooSocketRecv (call->pH245Channel->sock, message1, len-total); --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooCalls.c 2009-10-20 23:02:46.000000000 +0400 +++ channels/ooh323c/src/ooCalls.c 2009-10-13 05:33:19.000000000 +0400 @@ -62,7 +62,7 @@ return NULL; } memset(call, 0, sizeof(OOH323CallData)); - sem_init(&call->gkWait, 0, 0); + ast_cond_init(&call->gkWait, NULL); ast_mutex_init(&call->Lock); call->pctxt = pctxt; call->msgctxt = msgctxt; @@ -302,7 +302,7 @@ /* First clean all the logical channels, if not already cleaned. */ if(call->logicalChans) ooClearAllLogicalChannels(call); - + /* Close H.245 connection, if not already closed */ if(call->h245SessionState != OO_H245SESSION_CLOSED) ooCloseH245Connection(call); @@ -358,6 +358,17 @@ gH323ep.h323Callbacks.onCallCleared(call); } + if (call->rtpMask) { + ast_mutex_lock(&call->rtpMask->lock); + call->rtpMask->inuse--; + ast_mutex_unlock(&call->rtpMask->lock); + if ((call->rtpMask->inuse) == 0) { + regfree(&call->rtpMask->regex); + ast_mutex_destroy(&call->rtpMask->lock); + free(call->rtpMask); + } + } + pctxt = call->msgctxt; freeContext(pctxt); free(pctxt); @@ -562,6 +573,19 @@ stopTransmitChannel, FALSE); } +int ooCallAddSpeexCapability(OOH323CallData *call, int cap, int txframes, + int rxframes, OOBOOL silenceSuppression, int dir, + cb_StartReceiveChannel startReceiveChannel, + cb_StartTransmitChannel startTransmitChannel, + cb_StopReceiveChannel stopReceiveChannel, + cb_StopTransmitChannel stopTransmitChannel) +{ + return ooCapabilityAddSimpleCapability(call, cap, txframes, rxframes, + silenceSuppression, dir, startReceiveChannel, + startTransmitChannel, stopReceiveChannel, + stopTransmitChannel, FALSE); +} + int ooCallAddG7231Capability(OOH323CallData *call, int cap, int txframes, int rxframes, OOBOOL silenceSuppression, int dir, cb_StartReceiveChannel startReceiveChannel, @@ -669,6 +693,16 @@ return ooCapabilityDisableDTMFRFC2833(call); } +int ooCallEnableDTMFCISCO(OOH323CallData *call, int dynamicRTPPayloadType) +{ + return ooCapabilityEnableDTMFCISCO(call, dynamicRTPPayloadType); +} + +int ooCallDisableDTMFCISCO(OOH323CallData *call) +{ + return ooCapabilityDisableDTMFCISCO(call); +} + int ooCallEnableDTMFH245Alphanumeric(OOH323CallData *call) { --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooCapability.h 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323c/src/ooCapability.h 2009-10-13 05:33:19.000000000 +0400 @@ -60,7 +60,11 @@ OO_GSMENHANCEDFULLRATE = 20, OO_GENERICAUDIO = 21, OO_G729EXT = 22, +#if 0 OO_AUDIO_VBD = 23, +#else + OO_SPEEX = 23, +#endif OO_AUDIOTELEPHONYEVENT = 24, OO_AUDIO_TONE = 25, OO_EXTELEM1 = 26, @@ -81,6 +85,7 @@ #define OO_CAP_DTMF_Q931 (1<<1) #define OO_CAP_DTMF_H245_alphanumeric (1<<2) #define OO_CAP_DTMF_H245_signal (1<<3) +#define OO_CAP_DTMF_CISCO (1<<4) /** * This structure defines the preference order for capabilities. @@ -555,7 +560,7 @@ * @return Pointer to the created DTMF capability, NULL in case of * failure. */ -void * ooCapabilityCreateDTMFCapability(int cap, OOCTXT *pctxt); +void * ooCapabilityCreateDTMFCapability(int cap, int dtmfcodec, OOCTXT *pctxt); /** @@ -661,12 +666,8 @@ (struct OOH323CallData *call, H245DataType *data, int dir); /* fill t.38 application data */ -struct H245DataApplicationCapability_application* ooCreateT38ApplicationData - (OOCTXT* pctxt, H245DataApplicationCapability_application *app); - -/* create t.38 capability */ -struct H245DataApplicationCapability* ooCapabilityCreateT38Capability - (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir); +H245DataMode_application* ooCreateT38ApplicationData + (OOCTXT* pctxt, H245DataMode_application *app); /** * This function is used to clear the capability preference order. --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooh323ep.c 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323c/src/ooh323ep.c 2009-10-13 05:33:19.000000000 +0400 @@ -683,6 +683,18 @@ startTransmitChannel, stopReceiveChannel, stopTransmitChannel, FALSE); } +int ooH323EpAddSpeexCapability(int cap, int txframes, int rxframes, + OOBOOL silenceSuppression, int dir, + cb_StartReceiveChannel startReceiveChannel, + cb_StartTransmitChannel startTransmitChannel, + cb_StopReceiveChannel stopReceiveChannel, + cb_StopTransmitChannel stopTransmitChannel) +{ + return ooCapabilityAddSimpleCapability(NULL, cap, txframes, rxframes, + silenceSuppression, dir, startReceiveChannel, + startTransmitChannel, stopReceiveChannel, + stopTransmitChannel, FALSE); +} int ooH323EpAddGSMCapability(int cap, ASN1USINT framesPerPkt, OOBOOL comfortNoise, OOBOOL scrambled, int dir, @@ -717,6 +729,16 @@ } +int ooH323EpEnableDTMFCISCO(int dynamicRTPPayloadType) +{ + return ooCapabilityEnableDTMFCISCO(NULL, dynamicRTPPayloadType); +} + +int ooH323EpDisableDTMFCISCO(void) +{ + return ooCapabilityDisableDTMFCISCO(NULL); +} + int ooH323EpEnableDTMFRFC2833(int dynamicRTPPayloadType) { return ooCapabilityEnableDTMFRFC2833(NULL, dynamicRTPPayloadType); --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooh323.c 2009-10-20 23:02:46.000000000 +0400 +++ channels/ooh323c/src/ooh323.c 2009-10-14 23:48:37.000000000 +0400 @@ -33,6 +33,196 @@ /** Global endpoint structure */ extern OOH323EndPoint gH323ep; +int ooHandleFastStart(OOH323CallData *call, H225Facility_UUIE *facility) +{ + H245OpenLogicalChannel* olc; + ASN1OCTET msgbuf[MAXMSGLEN]; + ooLogicalChannel * pChannel = NULL; + H245H2250LogicalChannelParameters * h2250lcp = NULL; + int i=0, ret=0; + + /* Handle fast-start */ + if(OO_TESTFLAG (call->flags, OO_M_FASTSTART)) + { + if(facility->m.fastStartPresent) + { + /* For printing the decoded message to log, initialize handler. */ + initializePrintHandler(&printHandler, "FastStart Elements"); + + /* Set print handler */ + setEventHandler (call->pctxt, &printHandler); + + for(i=0; i<(int)facility->fastStart.n; i++) + { + olc = NULL; + + olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, + sizeof(H245OpenLogicalChannel)); + if(!olc) + { + OOTRACEERR3("ERROR:Memory - ooHandleFastStart - olc" + "(%s, %s)\n", call->callType, call->callToken); + /*Mark call for clearing */ + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_LOCAL_CLEARED; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + memset(olc, 0, sizeof(H245OpenLogicalChannel)); + memcpy(msgbuf, facility->fastStart.elem[i].data, + facility->fastStart.elem[i].numocts); + setPERBuffer(call->pctxt, msgbuf, + facility->fastStart.elem[i].numocts, 1); + ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc); + if(ret != ASN_OK) + { + OOTRACEERR3("ERROR:Failed to decode fast start olc element " + "(%s, %s)\n", call->callType, call->callToken); + /* Mark call for clearing */ + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + + dListAppend(call->pctxt, &call->remoteFastStartOLCs, olc); + + pChannel = ooFindLogicalChannelByOLC(call, olc); + if(!pChannel) + { + OOTRACEERR4("ERROR: Logical Channel %d not found, fast start. " + "(%s, %s)\n", + olc->forwardLogicalChannelNumber, call->callType, + call->callToken); + return OO_FAILED; + } + if(pChannel->channelNo != olc->forwardLogicalChannelNumber) + { + OOTRACEINFO5("Remote endpoint changed forwardLogicalChannel" + "Number from %d to %d (%s, %s)\n", + pChannel->channelNo, + olc->forwardLogicalChannelNumber, call->callType, + call->callToken); + pChannel->channelNo = olc->forwardLogicalChannelNumber; + } + if(!strcmp(pChannel->dir, "transmit")) + { + + if(olc->forwardLogicalChannelParameters.multiplexParameters.t != + T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) + { + OOTRACEERR4("ERROR:Unknown multiplex parameter type for " + "channel %d (%s, %s)\n", + olc->forwardLogicalChannelNumber, call->callType, + call->callToken); + continue; + } + + /* Extract the remote media endpoint address */ + h2250lcp = olc->forwardLogicalChannelParameters.multiplexParameters.u.h2250LogicalChannelParameters; + if(!h2250lcp) + { + OOTRACEERR3("ERROR:Invalid OLC received in fast start. No " + "forward Logical Channel Parameters found. " + "(%s, %s)\n", call->callType, call->callToken); + 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); + return OO_FAILED; + } + ret = ooGetIpPortFromH245TransportAddress(call, + &h2250lcp->mediaChannel, pChannel->remoteIP, + &pChannel->remoteMediaPort); + + if(ret != OO_OK) + { + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } + OOTRACEERR3("ERROR:Unsupported media channel address type " + "(%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + + if(!pChannel->chanCap->startTransmitChannel) + { + OOTRACEERR3("ERROR:No callback registered to start transmit " + "channel (%s, %s)\n",call->callType, + call->callToken); + return OO_FAILED; + } + pChannel->chanCap->startTransmitChannel(call, pChannel); + } + /* Mark the current channel as established and close all other + logical channels with same session id and in same direction. + */ + ooOnLogicalChannelEstablished(call, pChannel); + } + finishPrint(); + removeEventHandler(call->pctxt); + OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED); + } + + } + + if(facility->m.h245AddressPresent) + { + if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) + { + OO_CLRFLAG (call->flags, OO_M_TUNNELING); + OOTRACEINFO3("Tunneling is disabled for call as H245 address is " + "provided in facility message (%s, %s)\n", + call->callType, call->callToken); + } + ret = ooH323GetIpPortFromH225TransportAddress(call, + &facility->h245Address, call->remoteIP, + &call->remoteH245Port); + if(ret != OO_OK) + { + OOTRACEERR3("Error: Unknown H245 address type in received " + "CallProceeding message (%s, %s)", call->callType, + call->callToken); + /* Mark call for clearing */ + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + if(call->remoteH245Port != 0 && !call->pH245Channel) { + /* Create an H.245 connection. + */ + if(ooCreateH245Connection(call)== OO_FAILED) + { + OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", + call->callType, call->callToken); + + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_TRANSPORTFAILURE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + } + } else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { + ret =ooSendTCSandMSD(call); + if (ret != OO_OK) + return ret; + } + return OO_OK; +} int ooOnReceivedReleaseComplete(OOH323CallData *call, Q931Message *q931Msg) { @@ -474,26 +664,6 @@ } if(!strcmp(pChannel->dir, "transmit")) { - /* May 20090728 */ - if (!epCapIsPreferred(call, pChannel->chanCap)) { - if(call->localTermCapState == OO_LocalTermCapExchange_Idle) { - ret = ooSendTermCapMsg(call); - if(ret != OO_OK) { - OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n", - call->callType, call->callToken); - return ret; - } - } - if(call->masterSlaveState == OO_MasterSlave_Idle) { - ret = ooSendMasterSlaveDetermination(call); - if(ret != OO_OK) { - OOTRACEERR3("ERROR:Sending Master-slave determination message " - "(%s, %s)\n", call->callType, call->callToken); - return ret; - } - } - } - if(olc->forwardLogicalChannelParameters.multiplexParameters.t != T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) { @@ -526,6 +696,11 @@ if(ret != OO_OK) { + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } OOTRACEERR3("ERROR:Unsupported media channel address type " "(%s, %s)\n", call->callType, call->callToken); return OO_FAILED; @@ -585,6 +760,26 @@ } return OO_FAILED; } + if(call->remoteH245Port != 0 && !call->pH245Channel) { + /* Create an H.245 connection. + */ + if(ooCreateH245Connection(call)== OO_FAILED) + { + OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", + call->callType, call->callToken); + + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_TRANSPORTFAILURE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + } + } else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { + ret =ooSendTCSandMSD(call); + if (ret != OO_OK) + return ret; } return OO_OK; } @@ -691,26 +886,6 @@ } if(!strcmp(pChannel->dir, "transmit")) { - /* May 20090728 */ - if (!epCapIsPreferred(call, pChannel->chanCap)) { - if(call->localTermCapState == OO_LocalTermCapExchange_Idle) { - ret = ooSendTermCapMsg(call); - if(ret != OO_OK) { - OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n", - call->callType, call->callToken); - return ret; - } - } - if(call->masterSlaveState == OO_MasterSlave_Idle) { - ret = ooSendMasterSlaveDetermination(call); - if(ret != OO_OK) { - OOTRACEERR3("ERROR:Sending Master-slave determination message " - "(%s, %s)\n", call->callType, call->callToken); - return ret; - } - } - } - if(olc->forwardLogicalChannelParameters.multiplexParameters.t != T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) { @@ -743,6 +918,11 @@ if(ret != OO_OK) { + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } OOTRACEERR3("ERROR:Unsupported media channel address type " "(%s, %s)\n", call->callType, call->callToken); return OO_FAILED; @@ -765,8 +945,8 @@ finishPrint(); removeEventHandler(call->pctxt); OO_SETFLAG(call->flags, OO_M_FASTSTARTANSWERED); - } - + } + } /* Retrieve the H.245 control channel address from the connect msg */ @@ -802,6 +982,26 @@ } return OO_FAILED; } + if(call->remoteH245Port != 0 && !call->pH245Channel) { + /* Create an H.245 connection. + */ + if(ooCreateH245Connection(call)== OO_FAILED) + { + OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", + call->callType, call->callToken); + + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_TRANSPORTFAILURE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + } + } else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { + ret =ooSendTCSandMSD(call); + if (ret != OO_OK) + return ret; } @@ -909,26 +1109,6 @@ } if(!strcmp(pChannel->dir, "transmit")) { - /* May 20090728 */ - if (!epCapIsPreferred(call, pChannel->chanCap)) { - if(call->localTermCapState == OO_LocalTermCapExchange_Idle) { - ret = ooSendTermCapMsg(call); - if(ret != OO_OK) { - OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n", - call->callType, call->callToken); - return ret; - } - } - if(call->masterSlaveState == OO_MasterSlave_Idle) { - ret = ooSendMasterSlaveDetermination(call); - if(ret != OO_OK) { - OOTRACEERR3("ERROR:Sending Master-slave determination message " - "(%s, %s)\n", call->callType, call->callToken); - return ret; - } - } - } - if(olc->forwardLogicalChannelParameters.multiplexParameters.t != T_H245OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) { @@ -961,6 +1141,11 @@ if(ret != OO_OK) { + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } OOTRACEERR3("ERROR:Unsupported media channel address type " "(%s, %s)\n", call->callType, call->callToken); return OO_FAILED; @@ -1020,6 +1205,26 @@ } return OO_FAILED; } + if(call->remoteH245Port != 0 && !call->pH245Channel) { + /* Create an H.245 connection. + */ + if(ooCreateH245Connection(call)== OO_FAILED) + { + OOTRACEERR3("Error: H.245 channel creation failed (%s, %s)\n", + call->callType, call->callToken); + + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_TRANSPORTFAILURE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + } + } else if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { + ret =ooSendTCSandMSD(call); + if (ret != OO_OK) + return ret; } return OO_OK; @@ -1184,6 +1389,11 @@ &pChannel->remoteMediaPort); if(ret != OO_OK) { + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_INVALIDMESSAGE; + call->callState = OO_CALL_CLEAR; + } OOTRACEERR3("ERROR:Unsupported media channel address type " "(%s, %s)\n", call->callType, call->callToken); finishPrint(); @@ -1243,7 +1453,7 @@ } } - if(call->remoteH245Port != 0) + if(call->remoteH245Port != 0 && !call->pH245Channel) { /* Create an H.245 connection. */ @@ -1349,15 +1559,15 @@ if(gH323ep.gkClient->state == GkClientRegistered) { call->callState = OO_CALL_WAITING_ADMISSION; - // ast_mutex_lock(&call->Lock); + ast_mutex_lock(&call->Lock); ret = ooGkClientSendAdmissionRequest(gH323ep.gkClient, call, FALSE); clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 24; - sem_timedwait(&call->gkWait, &ts); + ast_cond_timedwait(&call->gkWait, &call->Lock, &ts); if (call->callState == OO_CALL_WAITING_ADMISSION) call->callState = OO_CALL_CLEAR; - // ast_mutex_unlock(&call->Lock); + ast_mutex_unlock(&call->Lock); } else { @@ -1624,6 +1834,19 @@ return OO_OK; } } + else if(facility->reason.t == T_H225FacilityReason_forwardedElements) + { + OOTRACEINFO3("Handling fast start in forwardedElem facility for " + "(%s, %s)\n", call->callType, call->callToken); + /*start H.245 channel*/ + ret = ooHandleFastStart(call, facility); + if(ret != OO_OK) + { + OOTRACEERR3("ERROR: Handling transportedInformation facility message " + "(%s, %s)\n", call->callType, call->callToken); + return ret; + } + } else{ OOTRACEINFO3("Unhandled Facility reason type received (%s, %s)\n", call->callType, call->callToken); @@ -1676,9 +1899,8 @@ ipAddress->ip.data[3]); call->remoteH245Port = ipAddress->port; - /* disable tunneling & faststart for this call */ + /* disable tunneling for this call */ OO_CLRFLAG (call->flags, OO_M_TUNNELING); - OO_CLRFLAG (call->flags, OO_M_FASTSTART); /*Establish an H.245 connection */ ret = ooCreateH245Connection(call); --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooCalls.h 2009-10-20 23:02:46.000000000 +0400 +++ channels/ooh323c/src/ooCalls.h 2009-10-13 05:33:19.000000000 +0400 @@ -22,6 +22,7 @@ #include "ooLogChan.h" #include "ooCapability.h" +#include #ifdef __cplusplus extern "C" { @@ -133,6 +134,12 @@ ASN1DynOctStr *elem; } FastStartResponse; +typedef struct OOH323Regex { + regex_t regex; + int inuse; + ast_mutex_t lock; +} OOH323Regex; + /** * This structure is used to maintain all information on an active call. @@ -143,7 +150,7 @@ OOCTXT *pctxt; OOCTXT *msgctxt; pthread_t callThread; - sem_t gkWait; + ast_cond_t gkWait; ast_mutex_t Lock; OOBOOL Monitor; OOBOOL fsSent; @@ -168,6 +175,7 @@ unsigned h245ConnectionAttempts; OOH245SessionState h245SessionState; int dtmfmode; + int dtmfcodec; OOMediaInfo *mediaInfo; OOCallFwdData *pCallFwdData; char localIP[20];/* Local IP address */ @@ -207,6 +215,10 @@ ASN1UINT t38sides; H235TimeStamp alertingTime, connectTime, endTime; /* time data for gatekeeper */ FastStartResponse *pFastStartRes; /* fast start response */ + struct OOH323Regex* rtpMask; + char rtpMaskStr[120]; + char lastDTMF; + ASN1UINT nextDTMFstamp; void *usrData; /*!forwardLogicalChannelNumber); @@ -1192,6 +1192,35 @@ return ASN_OK; } +/* + +H225 CapSet/MS determination helper function + +*/ + +int ooSendTCSandMSD(OOH323CallData *call) +{ + int ret; + if(call->localTermCapState == OO_LocalTermCapExchange_Idle) { + ret = ooSendTermCapMsg(call); + if(ret != OO_OK) { + OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n", + call->callType, call->callToken); + return ret; + } + } + if(call->masterSlaveState == OO_MasterSlave_Idle) { + ret = ooSendMasterSlaveDetermination(call); + if(ret != OO_OK) { + OOTRACEERR3("ERROR:Sending Master-slave determination message " + "(%s, %s)\n", call->callType, call->callToken); + return ret; + } + } + + return OO_OK; +} + /* @@ -1426,8 +1455,8 @@ OOTRACEERR3("Error: Failed to enqueue Alerting message to outbound queue. (%s, %s)\n", call->callType, call->callToken); } - /* memReset(&gH323ep.msgctxt); */ - memReset(call->msgctxt); + ooSendTCSandMSD(call); + memReset (call->msgctxt); return ret; } @@ -1438,7 +1467,7 @@ H225Progress_UUIE *progress; H225VendorIdentifier *vendor; Q931Message *q931msg=NULL; - /* OOCTXT *pctxt = &gH323ep.msgctxt; */ + H225TransportAddress_ipAddress *h245IpAddr; OOCTXT *pctxt = call->msgctxt; ret = ooCreateQ931Message(pctxt, &q931msg, Q931ProgressMsg); @@ -1527,6 +1556,31 @@ } else { progress->m.fastStartPresent = FALSE; } + + /* Add h245 listener address. Do not add H245 listener address in case + of tunneling. */ + if (/* (!OO_TESTFLAG(call->flags, OO_M_FASTSTART) || + call->remoteFastStartOLCs.count == 0) && */ + !OO_TESTFLAG (call->flags, OO_M_TUNNELING) && + !call->h245listener && ooCreateH245Listener(call) == OO_OK) + { + progress->m.h245AddressPresent = TRUE; + progress->h245Address.t = T_H225TransportAddress_ipAddress; + + h245IpAddr = (H225TransportAddress_ipAddress*) + memAllocZ (pctxt, sizeof(H225TransportAddress_ipAddress)); + if(!h245IpAddr) + { + OOTRACEERR3("Error:Memory - ooAcceptCall - h245IpAddr" + "(%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + ooSocketConvertIpToNwAddr(call->localIP, h245IpAddr->ip.data); + h245IpAddr->ip.numocts=4; + h245IpAddr->port = *(call->h245listenport); + progress->h245Address.u.ipAddress = h245IpAddr; + } + OOTRACEDBGA3("Built Progress (%s, %s)\n", call->callType, call->callToken); ret = ooSendH225Msg(call, q931msg); @@ -1535,20 +1589,21 @@ OOTRACEERR3("Error: Failed to enqueue Alerting message to outbound queue. (%s, %s)\n", call->callType, call->callToken); } - /* memReset(&gH323ep.msgctxt); */ - memReset(call->msgctxt); + ooSendTCSandMSD(call); + memReset (call->msgctxt); return ret; } -int ooSendFacility(OOH323CallData *call) +int ooSendStartH245Facility(OOH323CallData *call) { int ret=0; Q931Message *pQ931Msg = NULL; H225Facility_UUIE *facility=NULL; /* OOCTXT *pctxt = &gH323ep.msgctxt; */ OOCTXT *pctxt = call->msgctxt; + H225TransportAddress_ipAddress *h245IpAddr; OOTRACEDBGA3("Building Facility message (%s, %s)\n", call->callType, call->callToken); @@ -1600,7 +1655,29 @@ memcpy(facility->callIdentifier.guid.data, call->callIdentifier.guid.data, call->callIdentifier.guid.numocts); - facility->reason.t = T_H225FacilityReason_transportedInformation; + facility->reason.t = T_H225FacilityReason_startH245; + + if (!call->h245listener && ooCreateH245Listener(call) != OO_OK) { + OOTRACEERR3("Error:No H245Listener, can't send startH245 facility (%s, %s)\n", + call->callType, call->callToken); + return OO_FAILED; + } + + facility->m.h245AddressPresent = TRUE; + facility->h245Address.t = T_H225TransportAddress_ipAddress; + + h245IpAddr = (H225TransportAddress_ipAddress*) + memAllocZ (pctxt, sizeof(H225TransportAddress_ipAddress)); + if(!h245IpAddr) { + OOTRACEERR3("Error:Memory - ooSendFacility - h245IpAddr" + "(%s, %s)\n", call->callType, call->callToken); + return OO_FAILED; + } + ooSocketConvertIpToNwAddr(call->localIP, h245IpAddr->ip.data); + h245IpAddr->ip.numocts=4; + h245IpAddr->port = *(call->h245listenport); + facility->h245Address.u.ipAddress = h245IpAddr; + OOTRACEDBGA3("Built Facility message to send (%s, %s)\n", call->callType, call->callToken); @@ -1883,11 +1960,11 @@ /* Add h245 listener address. Do not add H245 listener address in case of fast-start. */ - if ((!OO_TESTFLAG(call->flags, OO_M_FASTSTART) || - call->remoteFastStartOLCs.count == 0) && - !OO_TESTFLAG (call->flags, OO_M_TUNNELING)) + if (/* (!OO_TESTFLAG(call->flags, OO_M_FASTSTART) || + call->remoteFastStartOLCs.count == 0) && */ + !OO_TESTFLAG (call->flags, OO_M_TUNNELING) && + !call->h245listener && ooCreateH245Listener(call) == OO_OK) { - ooCreateH245Listener(call); /* First create an H.245 listener */ connect->m.h245AddressPresent = TRUE; connect->h245Address.t = T_H225TransportAddress_ipAddress; @@ -1923,26 +2000,6 @@ /* memReset(&gH323ep.msgctxt); */ memReset(call->msgctxt); -#if 0 - if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) - { - /* Start terminal capability exchange and master slave determination */ - ret = ooSendTermCapMsg(call); - if(ret != OO_OK) - { - OOTRACEERR3("ERROR:Sending Terminal capability message (%s, %s)\n", - call->callType, call->callToken); - return ret; - } - ret = ooSendMasterSlaveDetermination(call); - if(ret != OO_OK) - { - OOTRACEERR3("ERROR:Sending Master-slave determination message " - "(%s, %s)\n", call->callType, call->callToken); - return ret; - } - } -#endif return OO_OK; } @@ -2009,7 +2066,7 @@ ast_mutex_lock(&fwdedCall->Lock); clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 24; - sem_timedwait(&fwdedCall->gkWait, &ts); + ast_cond_timedwait(&fwdedCall->gkWait, &fwdedCall->Lock, &ts); if (fwdedCall->callState == OO_CALL_WAITING_ADMISSION) /* GK is not responding */ fwdedCall->callState = OO_CALL_CLEAR; ast_mutex_unlock(&fwdedCall->Lock); @@ -2128,14 +2185,14 @@ MakeCall command */ call->callState = OO_CALL_WAITING_ADMISSION; - // ast_mutex_lock(&call->Lock); + ast_mutex_lock(&call->Lock); ret = ooGkClientSendAdmissionRequest(gH323ep.gkClient, call, FALSE); clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 24; - sem_timedwait(&call->gkWait, &ts); + ast_cond_timedwait(&call->gkWait, &call->Lock, &ts); if (call->callState == OO_CALL_WAITING_ADMISSION) call->callState = OO_CALL_CLEAR; - // ast_mutex_unlock(&call->Lock); + ast_mutex_unlock(&call->Lock); } @@ -2470,7 +2527,7 @@ /* don't send t38/other data caps in fasstart olcs */ - if (epCap->capType == OO_CAP_TYPE_DATA) + if (epCap->capType == OO_CAP_TYPE_DATA) continue; OOTRACEDBGC4("Building olcs with capability %s. (%s, %s)\n", @@ -2981,6 +3038,9 @@ return OO_OK; } + + + int ooQ931SetCallingPartyNumberIE (OOCTXT* pctxt, Q931Message *pmsg, const char *number, unsigned plan, unsigned type, unsigned presentation, unsigned screening) --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooLogChan.h 2008-02-07 23:59:47.000000000 +0300 +++ channels/ooh323c/src/ooLogChan.h 2009-08-25 23:34:14.000000000 +0400 @@ -41,7 +41,8 @@ OO_LOGICAL_CHAN_UNKNOWN, OO_LOGICALCHAN_IDLE, OO_LOGICALCHAN_PROPOSED, - OO_LOGICALCHAN_ESTABLISHED + OO_LOGICALCHAN_ESTABLISHED, + OO_LOGICALCHAN_PROPOSEDFS } OOLogicalChannelState; /** --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooSocket.c 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323c/src/ooSocket.c 2009-10-15 22:16:13.000000000 +0400 @@ -273,8 +273,10 @@ if (bind (socket, (struct sockaddr *) (void*) &m_addr, sizeof (m_addr)) == -1) { - perror ("bind"); - OOTRACEERR1("Error:Bind failed\n"); + if (errno != EADDRINUSE) { + perror ("bind"); + OOTRACEERR2("Error:Bind failed, error: %d\n", errno); + } return ASN_E_INVSOCKET; } --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooGkClient.h 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323c/src/ooGkClient.h 2009-08-25 23:34:14.000000000 +0400 @@ -412,7 +412,7 @@ /** - * This function is used to send an unregistration confirm messsage to + * This function is used to send an unregistration confirm message to * gatekeeper. * @param pGkClient Handle to gatekeeper client. * @param reqNo Request Sequence number for the confirm message. --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooLogChan.c 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323c/src/ooLogChan.c 2009-08-05 02:16:05.000000000 +0400 @@ -245,7 +245,8 @@ 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, "transmit") && pChannel->state == OO_LOGICALCHAN_IDLE) + if(!strcmp(pChannel->dir, "transmit") && pChannel->state != OO_LOGICALCHAN_IDLE && + pChannel->state != OO_LOGICALCHAN_PROPOSEDFS) return pChannel; else pChannel = pChannel->next; --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooh245.c 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323c/src/ooh245.c 2009-10-13 23:16:06.000000000 +0400 @@ -323,7 +323,7 @@ ooH323EpCapability *epCap=NULL; H245TerminalCapabilitySet *termCap=NULL; H245AudioCapability *audioCap=NULL; - H245DataApplicationCapability *t38Cap = NULL; + H245DataApplicationCapability *t38Cap, *rtdCap = NULL; H245AudioTelephonyEventCapability *ateCap=NULL; H245UserInputCapability *userInputCap = NULL; H245CapabilityTableEntry *entry=NULL; @@ -619,7 +619,7 @@ if(call->dtmfmode & OO_CAP_DTMF_RFC2833) { ateCap = (H245AudioTelephonyEventCapability*) - ooCapabilityCreateDTMFCapability(OO_CAP_DTMF_RFC2833, pctxt); + ooCapabilityCreateDTMFCapability(OO_CAP_DTMF_RFC2833, call->dtmfcodec, pctxt); if(!ateCap) { OOTRACEWARN3("WARN:Failed to add RFC2833 cap to TCS(%s, %s)\n", @@ -652,10 +652,46 @@ } } + if(call->dtmfmode & OO_CAP_DTMF_CISCO) + { + rtdCap = (H245DataApplicationCapability*) + ooCapabilityCreateDTMFCapability(OO_CAP_DTMF_CISCO, call->dtmfcodec, pctxt); + if(!rtdCap) + { + OOTRACEWARN3("WARN:Failed to add RTP/CISCO DTMF cap to TCS(%s, %s)\n", + call->callType, call->callToken); + } + else { + entry = (H245CapabilityTableEntry*) memAlloc(pctxt, + sizeof(H245CapabilityTableEntry)); + if(!entry) + { + OOTRACEERR3("Error:Failed to allocate memory for new capability " + "table entry. (%s, %s)\n", call->callType, + call->callToken); + ooFreeH245Message(call, ph245msg); + return OO_FAILED; + } + + memset(entry, 0, sizeof(H245CapabilityTableEntry)); + entry->m.capabilityPresent = 1; + + entry->capability.t = T_H245Capability_receiveDataApplicationCapability; + entry->capability.u.receiveDataApplicationCapability = rtdCap; + + entry->capabilityTableEntryNumber = i+1; + dListAppend(pctxt , &(termCap->capabilityTable), entry); + altSetDtmf->elem[altSetDtmf->n] = i+1; + altSetDtmf->n++; + + i++; + } + } + if(call->dtmfmode & OO_CAP_DTMF_H245_alphanumeric) { userInputCap = (H245UserInputCapability*)ooCapabilityCreateDTMFCapability - (OO_CAP_DTMF_H245_alphanumeric, pctxt); + (OO_CAP_DTMF_H245_alphanumeric, 0, pctxt); if(!userInputCap) { OOTRACEWARN3("WARN:Failed to add H245(alphanumeric) cap to " @@ -691,7 +727,7 @@ if(call->dtmfmode & OO_CAP_DTMF_H245_signal) { userInputCap = (H245UserInputCapability*)ooCapabilityCreateDTMFCapability - (OO_CAP_DTMF_H245_signal, pctxt); + (OO_CAP_DTMF_H245_signal, 0, pctxt); if(!userInputCap) { OOTRACEWARN3("WARN:Failed to add H245(signal) cap to " @@ -922,7 +958,7 @@ if(gH323ep.h323Callbacks.openLogicalChannels) gH323ep.h323Callbacks.openLogicalChannels(call); else{ - if(!call->logicalChans) + if(!ooGetTransmitLogicalChannel(call)) ooOpenLogicalChannels(call); } #if 0 @@ -1306,8 +1342,7 @@ pModeElem.type.t = T_H245ModeElementType_dataMode; pModeElem.type.u.dataMode = (H245DataMode *) memAllocZ(pctxt, sizeof(H245DataMode)); pModeElem.type.u.dataMode->bitRate = 144; - if (!ooCreateT38ApplicationData(pctxt, - (H245DataApplicationCapability_application*) &(pModeElem.type.u.dataMode->application))) { + if (!ooCreateT38ApplicationData(pctxt,&(pModeElem.type.u.dataMode->application))) { OOTRACEERR3("Error:Memory - ooCapabilityCreateT38Capability - (%s, %s)\n", call->callType, call->callToken); @@ -1735,6 +1770,8 @@ H245OpenLogicalChannelAck *olcAck) { char remoteip[20]; + regmatch_t pmatch[1]; + int i; ooLogicalChannel *pLogicalChannel; H245H2250LogicalChannelAckParameters *h2250lcap; H245UnicastAddress *unicastAddr; @@ -1828,6 +1865,15 @@ pLogicalChannel->sessionID = h2250lcap->sessionID; /* Populate ports &ip for channel */ + + if (call->rtpMaskStr[0]) { + if (regexec(&call->rtpMask->regex, remoteip, 1, pmatch, 0)) { + OOTRACEERR5("ERROR:H245 Address is not matched with filter %s/%s" + "(%s, %s)\n", remoteip, call->rtpMaskStr, call->callType, call->callToken); + return OO_FAILED; + } + } + strcpy(pLogicalChannel->remoteIP, remoteip); pLogicalChannel->remoteMediaPort = iPAddress->tsapIdentifier; if (iPAddress1) @@ -2072,7 +2118,7 @@ if(gH323ep.h323Callbacks.openLogicalChannels) gH323ep.h323Callbacks.openLogicalChannels(call); else{ - if(!call->logicalChans) + if(!ooGetTransmitLogicalChannel(call)) ooOpenLogicalChannels(call); } #if 0 @@ -2741,6 +2787,8 @@ } ooOnReceivedCloseChannelAck(call, response->u.closeLogicalChannelAck); + if(!ooGetTransmitLogicalChannel(call)) + ooOpenLogicalChannels(call); break; case T_H245ResponseMessage_requestChannelCloseAck: OOTRACEINFO4("RequestChannelCloseAck received - %d (%s, %s)\n", @@ -2830,6 +2878,24 @@ } else if((indication->t == T_H245UserInputIndication_signal) && (call->dtmfmode & OO_CAP_DTMF_H245_signal)) { + if(call->lastDTMF && indication->u.signal->signalType[0] == call->lastDTMF && + call->nextDTMFstamp && indication->u.signal->m.rtpPresent && + indication->u.signal->rtp.m.timestampPresent) { + if(call->nextDTMFstamp > indication->u.signal->rtp.timestamp) { + OOTRACEERR4("ERROR:Duplicate dtmf %c on ((%s, %s)\n", call->lastDTMF, call->callType, + call->callToken); + return OO_OK; + } + } + if (indication->u.signal->m.rtpPresent && indication->u.signal->rtp.m.timestampPresent && + indication->u.signal->m.durationPresent) { + call->nextDTMFstamp = indication->u.signal->rtp.timestamp + + indication->u.signal->duration; + call->lastDTMF = indication->u.signal->signalType[0]; + } else { + call->nextDTMFstamp = 0; + call->lastDTMF = 0; + } if(gH323ep.h323Callbacks.onReceivedDTMF) gH323ep.h323Callbacks.onReceivedDTMF(call, indication->u.signal->signalType); @@ -2849,7 +2915,7 @@ H245CapabilityTableEntry *capEntry = NULL; tcs = pmsg->h245Msg.u.request->u.terminalCapabilitySet; - if(call->remoteTermCapSeqNo >= tcs->sequenceNumber) + if(call->remoteTermCapSeqNo > tcs->sequenceNumber) { OOTRACEINFO4("Rejecting TermCapSet message with SeqNo %d, as already " "acknowledged message with this SeqNo (%s, %s)\n", @@ -2857,6 +2923,16 @@ ooSendTerminalCapabilitySetReject(call, tcs->sequenceNumber, T_H245TerminalCapabilitySetReject_cause_unspecified); return OO_OK; + + } else { +/* 20090924 */ +/* bogus soft-switch can send more than one request with cap set + if it goto to next choice. Right swith don't send but not all are right ;( + we can accept new capability set only. We must remember also that new join caps + will be previously joined caps with new cap set. + */ + if(call->remoteTermCapSeqNo == tcs->sequenceNumber) + call->localTermCapState = OO_LocalTermCapExchange_Idle; } if(!tcs->m.capabilityTablePresent) @@ -2933,7 +3009,7 @@ if(gH323ep.h323Callbacks.openLogicalChannels) gH323ep.h323Callbacks.openLogicalChannels(call); else{ - if(!call->logicalChans) + if(!ooGetTransmitLogicalChannel(call)) ooOpenLogicalChannels(call); } #if 0 @@ -3330,7 +3406,7 @@ } } - else if(call->masterSlaveState == OO_MasterSlave_Slave) + else { epCap = call->jointCaps; @@ -3358,6 +3434,7 @@ case OO_G726: case OO_G726AAL2: case OO_AMRNB: + case OO_SPEEX: case OO_G728: case OO_G729: case OO_G729A: @@ -3816,7 +3893,7 @@ else { /* Calling other ep, with SETUP message */ /* Call is "outgoing */ - pLogicalChannel->state = OO_LOGICALCHAN_PROPOSED; + pLogicalChannel->state = OO_LOGICALCHAN_PROPOSEDFS; } return OO_OK; @@ -3968,6 +4045,8 @@ { H245UnicastAddress *unicastAddress = NULL; H245UnicastAddress_iPAddress *ipAddress = NULL; + int i; + regmatch_t pmatch[1]; if(h245Address->t != T_H245TransportAddress_unicastAddress) { @@ -3991,6 +4070,14 @@ ipAddress->network.data[1], ipAddress->network.data[2], ipAddress->network.data[3]); + if (call->rtpMaskStr[0]) { + if (regexec(&call->rtpMask->regex, ip, 1, pmatch, 0)) { + OOTRACEERR5("ERROR:H245 Address is not matched with filter %s/%s" + "(%s, %s)\n", ip, call->rtpMaskStr, call->callType, call->callToken); + return OO_FAILED; + } + } + return OO_OK; } --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooGkClient.c 2009-10-20 23:02:38.000000000 +0400 +++ channels/ooh323c/src/ooGkClient.c 2009-08-25 23:34:15.000000000 +0400 @@ -1950,7 +1950,7 @@ pCallAdmInfo->call->callToken); pCallAdmInfo->call->callState = OO_CALL_CONNECTING; - sem_post(&pCallAdmInfo->call->gkWait); + ast_cond_signal(&pCallAdmInfo->call->gkWait); /* ooH323CallAdmitted( pCallAdmInfo->call); */ dListRemove(&pGkClient->callsPendingList, pNode); @@ -1975,9 +1975,10 @@ (ooGkClient *pGkClient, H225AdmissionReject *pAdmissionReject) { RasCallAdmissionInfo* pCallAdmInfo=NULL; - unsigned int x; - DListNode *pNode=NULL; + unsigned int x, y; + DListNode *pNode=NULL, *pNode1=NULL; OOH323CallData *call=NULL; + OOTimer *pTimer = NULL; /* Search call in pending calls list */ for(x=0 ; xcallsPendingList.count; x++) @@ -2004,6 +2005,24 @@ memFreePtr(&pGkClient->ctxt, pNode); } + /* Delete ARQ timer */ + for(y=0; ytimerList.count; y++) + { + pNode1 = dListFindByIndex(&pGkClient->timerList, y); + pTimer = (OOTimer*)pNode1->data; + if(((ooGkClientTimerCb*)pTimer->cbData)->timerType & OO_ARQ_TIMER) + { + if(((ooGkClientTimerCb*)pTimer->cbData)->pAdmInfo == + pCallAdmInfo) + { + memFreePtr(&pGkClient->ctxt, pTimer->cbData); + ooTimerDelete(&pGkClient->ctxt, &pGkClient->timerList, + pTimer); + OOTRACEDBGA1("Deleted ARQ Timer.\n"); + break; + } + } + } OOTRACEINFO4("Admission Reject message received with reason code %d for " "(%s, %s)\n", pAdmissionReject->rejectReason.t, call->callType, call->callToken); @@ -2049,7 +2068,7 @@ break; } - sem_post(&pCallAdmInfo->call->gkWait); + ast_cond_signal(&pCallAdmInfo->call->gkWait); return OO_OK; } @@ -2564,6 +2583,9 @@ OOTRACEDBGA1("Gatekeeper client ARQ timer expired.\n"); memFreePtr(&pGkClient->ctxt, cbData); + if(!pAdmInfo) + return OO_OK; + if(pAdmInfo->retries < OO_MAX_ARQ_RETRIES) { ret = ooGkClientSendAdmissionRequest(pGkClient, pAdmInfo->call, TRUE); --- ../bb/asterisk-addons-1.6.1.0/channels/ooh323c/src/ooCapability.c 2009-10-20 23:02:27.000000000 +0400 +++ channels/ooh323c/src/ooCapability.c 2009-10-13 05:33:19.000000000 +0400 @@ -25,6 +25,7 @@ extern OOH323EndPoint gH323ep; static int giDynamicRTPPayloadType = 101; +static int gcDynamicRTPPayloadType = 121; int ooCapabilityEnableDTMFRFC2833 (OOH323CallData *call, int dynamicRTPPayloadType) @@ -33,16 +34,47 @@ { gH323ep.dtmfmode |= OO_CAP_DTMF_RFC2833; OOTRACEINFO1("Enabled RFC2833 DTMF capability for end-point\n"); + /*Dynamic RTP payload type range is from 96 - 127 */ + if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127) + giDynamicRTPPayloadType = dynamicRTPPayloadType; } else{ call->dtmfmode |= OO_CAP_DTMF_RFC2833; OOTRACEINFO3("Enabled RFC2833 DTMF capability for (%s, %s) \n", call->callType, call->callToken); + if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127) + call->dtmfcodec = dynamicRTPPayloadType; + else + call->dtmfcodec = giDynamicRTPPayloadType; } - /*Dynamic RTP payload type range is from 96 - 127 */ + + return OO_OK; +} + +int ooCapabilityEnableDTMFCISCO + (OOH323CallData *call, int dynamicRTPPayloadType) +{ + if(!call) + { + gH323ep.dtmfmode |= OO_CAP_DTMF_CISCO; + OOTRACEINFO1("Enabled RTP/CISCO DTMF capability for end-point\n"); + /*Dynamic RTP payload type range is from 96 - 127 */ + if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127) + gcDynamicRTPPayloadType = dynamicRTPPayloadType; + else + call->dtmfcodec = dynamicRTPPayloadType; + } + else{ + call->dtmfmode |= OO_CAP_DTMF_CISCO; + OOTRACEINFO3("Enabled RTP/CISCO DTMF capability for (%s, %s) \n", + call->callType, call->callToken); if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127) - giDynamicRTPPayloadType = dynamicRTPPayloadType; + call->dtmfcodec = dynamicRTPPayloadType; + else + call->dtmfcodec = gcDynamicRTPPayloadType; + } + return OO_OK; } @@ -64,6 +96,21 @@ return OO_OK; } +int ooCapabilityDisableDTMFCISCO(OOH323CallData *call) +{ + if(!call){ + gH323ep.dtmfmode ^= OO_CAP_DTMF_CISCO; + OOTRACEINFO1("Disabled RTP/CISCO DTMF capability for end-point\n"); + } + else{ + call->dtmfmode ^= OO_CAP_DTMF_CISCO; + OOTRACEINFO3("Disabled RTP/CISCO DTMF capability for (%s, %s)\n", + call->callType, call->callToken); + } + + return OO_OK; +} + int ooCapabilityEnableDTMFH245Alphanumeric(OOH323CallData *call) { if(!call){ @@ -463,6 +510,7 @@ } curCap = curCap->next; } + return 0; } int ooCapabilityAddGSMCapability(OOH323CallData *call, int cap, @@ -727,6 +775,7 @@ case OO_G726: case OO_G726AAL2: case OO_AMRNB: + case OO_SPEEX: return ooCapabilityCreateNonStandardCapability(epCap, pctxt, dir); case OO_GSMHALFRATE: case OO_GSMENHANCEDFULLRATE: @@ -741,9 +790,10 @@ -void* ooCapabilityCreateDTMFCapability(int cap, OOCTXT *pctxt) +void* ooCapabilityCreateDTMFCapability(int cap, int dtmfcodec, OOCTXT *pctxt) { H245AudioTelephonyEventCapability *pATECap=NULL; + H245DataApplicationCapability *pCSDTMFCap=NULL; H245UserInputCapability *userInput = NULL; char *events=NULL; switch(cap) @@ -757,7 +807,7 @@ return NULL; } memset(pATECap, 0, sizeof(H245AudioTelephonyEventCapability)); - pATECap->dynamicRTPPayloadType = giDynamicRTPPayloadType; + pATECap->dynamicRTPPayloadType = dtmfcodec; events = (char*)memAlloc(pctxt, strlen("0-16")+1); memset(events, 0, strlen("0-16")+1); if(!events) @@ -769,6 +819,40 @@ strncpy(events, "0-16", strlen("0-16")); pATECap->audioTelephoneEvent = events; return pATECap; + case OO_CAP_DTMF_CISCO: + pCSDTMFCap = (H245DataApplicationCapability*)memAlloc(pctxt, + sizeof(H245DataApplicationCapability)); + if(!pCSDTMFCap) + { + OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - pCSDTMFCap\n"); + return NULL; + } + memset(pCSDTMFCap, 0, sizeof(H245DataApplicationCapability)); + pCSDTMFCap->application.t = T_H245DataApplicationCapability_application_nonStandard; + if ( (pCSDTMFCap->application.u.nonStandard = (H245NonStandardParameter *) + memAllocZ(pctxt, sizeof(H245NonStandardParameter))) == NULL) { + OOTRACEERR1("Error:Memory-ooCapabilityCreateDTMFCapability-H245NonStandardParameter\n"); + memFreePtr(pctxt, pCSDTMFCap); + return NULL; + } + + pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.t=T_H245NonStandardIdentifier_h221NonStandard; + pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard = + (H245NonStandardIdentifier_h221NonStandard *) memAllocZ(pctxt, + sizeof(H245NonStandardIdentifier_h221NonStandard)); + if (!pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard) { + OOTRACEERR1("Error:Memory-ooCapabilityCreateDTMFCapability-H245NonStandardParameter\n"); + memFreePtr(pctxt, pCSDTMFCap); + return NULL; + } + + pCSDTMFCap->application.u.nonStandard->data.data = "RtpDtmfRelay"; + pCSDTMFCap->application.u.nonStandard->data.numocts = sizeof("RtpDtmfRelay")-1; + pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35CountryCode = 181; + pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35Extension = 0; + pCSDTMFCap->application.u.nonStandard->nonStandardIdentifier.u.h221NonStandard->manufacturerCode = 18; + + return pCSDTMFCap; case OO_CAP_DTMF_H245_alphanumeric: userInput = (H245UserInputCapability*)memAllocZ(pctxt, sizeof(H245UserInputCapability)); @@ -1015,7 +1099,7 @@ } return NULL; } -/* This is used for g726, AMRNB */ +/* This is used for g726, AMRNB, Speex */ struct H245AudioCapability* ooCapabilityCreateNonStandardCapability (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir) { @@ -1042,6 +1126,7 @@ case OO_AMRNB: case OO_G726: case OO_G726AAL2: + case OO_SPEEX: pAudio->t = T_H245AudioCapability_nonStandard; pAudio->u.nonStandard = (H245NonStandardParameter*)memAlloc(pctxt, sizeof(H245NonStandardParameter)); @@ -1086,6 +1171,17 @@ case OO_AMRNB: pAudio->u.nonStandard->data.data = "AMRNB"; pAudio->u.nonStandard->data.numocts = sizeof("AMRNB")-1; + break; + + case OO_SPEEX: + pAudio->u.nonStandard->data.data = "Speex"; + pAudio->u.nonStandard->data.numocts = sizeof("Speex")-1; + /* Equivalence OpenH323 SpeexNB */ + pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35CountryCode = 9; + pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->t35Extension = 0; + pAudio->u.nonStandard->nonStandardIdentifier.u.h221NonStandard->manufacturerCode = 61; + + break; } return pAudio; @@ -1098,8 +1194,8 @@ /* Our t.38 params */ -struct H245DataApplicationCapability_application* ooCreateT38ApplicationData - (OOCTXT* pctxt, H245DataApplicationCapability_application *app) +struct H245DataMode_application* ooCreateT38ApplicationData + (OOCTXT* pctxt, H245DataMode_application *app) { app->t = T_H245DataApplicationCapability_application_t38fax; app->u.t38fax = @@ -1288,10 +1384,13 @@ else return FALSE; break; - case sizeof("AMRNB")-1: + case sizeof("AMRNB")-1: /* case sizeof("Speex")-1 */ if (!strncmp(audioCap->u.nonStandard->data.data, "AMRNB", audioCap->u.nonStandard->data.numocts)) cap = OO_AMRNB; + else if (!strncmp(audioCap->u.nonStandard->data.data, "Speex", + audioCap->u.nonStandard->data.numocts)) + cap = OO_SPEEX; else return FALSE; break; @@ -1889,7 +1988,9 @@ { if(((OOCapParams*)cur->params)->rxframes < framesPerPkt) return NULL; - else{ + if(((OOCapParams*)cur->params)->rxframes > framesPerPkt) + ((OOCapParams*)cur->params)->rxframes = framesPerPkt; + OOTRACEDBGC4("We can receive Simple capability %s. (%s, %s)\n", ooGetCapTypeText(cur->cap), call->callType, call->callToken); @@ -1918,7 +2019,6 @@ ooGetCapTypeText(cur->cap), call->callType, call->callToken); return epCap; - } } /* Can we transmit compatible stream */ @@ -1991,10 +2091,13 @@ else return NULL; break; - case sizeof("AMRNB")-1: + case sizeof("AMRNB")-1: /* sizeof("Speex") */ if (!strncmp(audioCap->u.nonStandard->data.data, "AMRNB", audioCap->u.nonStandard->data.numocts)) cap = OO_AMRNB; + else if (!strncmp(audioCap->u.nonStandard->data.data, "Speex", + audioCap->u.nonStandard->data.numocts)) + cap = OO_SPEEX; else return NULL; break; @@ -2698,6 +2801,15 @@ audioCap->u.nonStandard->data.numocts)) return ooCapabilityAddSimpleCapability(call, OO_AMRNB, 4, 4, FALSE, dir, NULL, NULL, NULL, NULL, TRUE); + + if (audioCap->u.nonStandard && + audioCap->u.nonStandard->nonStandardIdentifier.t == + T_H245NonStandardIdentifier_h221NonStandard && + audioCap->u.nonStandard->data.numocts == sizeof("Speex")-1 && + !strncmp(audioCap->u.nonStandard->data.data, "Speex", + audioCap->u.nonStandard->data.numocts)) + return ooCapabilityAddSimpleCapability(call, OO_SPEEX, 4, + 4, FALSE, dir, NULL, NULL, NULL, NULL, TRUE); break; case T_H245AudioCapability_g728: @@ -3022,7 +3134,7 @@ "OO_GSMENHANCEDFULLRATE", "OO_GENERICAUDIO", "OO_G729EXTENSIONS", - "OO_VBD", + "OO_SPEEX", "OO_AUDIOTELEPHONYEVENT", "OO_AUDIOTONE", "OO_EXTELEM1",