Index: channels/ooh323c/src/ooGkClient.c =================================================================== --- channels/ooh323c/src/ooGkClient.c (revision 599) +++ channels/ooh323c/src/ooGkClient.c (working copy) @@ -981,6 +981,37 @@ pRegReq->discoveryComplete= pGkClient->discoveryComplete; pRegReq->m.keepAlivePresent=TRUE; pRegReq->keepAlive= keepAlive; + + /* + * Cisco Gatekeeper re-registration fix. Thanks to Mike Tubby (mike@tubby.org) 28feb2007 + * Without this patch initial registration works, but re-registration fails! + * + * For light-weight re-registration, keepalive is set true + * GK needs rasAddress, keepAlive, endpointIdentifier, gatekeeperIdentifier, + * tokens, and timeToLive + * GK will ignore all other params if KeepAlive is set. + * + */ + if(keepAlive) { + /* KeepAlive, re-registration message... + allocate storage for endpoint-identifier, and populate it from what the + GK told us from the previous RCF. Only allocate on the first pass thru here */ + pRegReq->endpointIdentifier.data = + (ASN116BITCHAR*)memAlloc(pctxt, pGkClient->gkId.nchars*sizeof(ASN116BITCHAR)); + if (pRegReq->endpointIdentifier.data) { + pRegReq->endpointIdentifier.nchars = pGkClient->endpointId.nchars; + pRegReq->m.endpointIdentifierPresent = TRUE; + memcpy(pRegReq->endpointIdentifier.data, pGkClient->endpointId.data, pGkClient->endpointId.nchars*sizeof(ASN116BITCHAR)); + OOTRACEINFO1("Sending RRQ for re-registration (with EndpointID)\n"); + } + else { + OOTRACEERR1("Error: Failed to allocate memory for EndpointIdentifier in RRQ \n"); + memReset(pctxt); + pGkClient->state = GkClientFailed; + return OO_FAILED; + } + } + pRegReq->m.timeToLivePresent = TRUE; pRegReq->timeToLive = pGkClient->regTimeout; Index: channels/ooh323c/src/ootypes.h =================================================================== --- channels/ooh323c/src/ootypes.h (revision 599) +++ channels/ooh323c/src/ootypes.h (working copy) @@ -61,7 +61,7 @@ -#define OOH323C_VERSION "v0.8.2" +#define OOH323C_VERSION "v0.8.3" #ifndef EXTERN #ifdef MAKE_DLL Index: channels/ooh323c/src/ooLogChan.c =================================================================== --- channels/ooh323c/src/ooLogChan.c (revision 599) +++ channels/ooh323c/src/ooLogChan.c (working copy) @@ -191,6 +191,8 @@ { if(!strcmp(pChannel->dir, dir)) { + OOTRACEDBGC3("ooFindLogicalChannel, comparing channel: %d:%s\n", + pChannel->channelNo, pChannel->dir); if(!strcmp(dir, "receive")) { if(ooCapabilityCheckCompatibility(call, pChannel->chanCap, Index: channels/ooh323c/src/ooh323.c =================================================================== --- channels/ooh323c/src/ooh323.c (revision 599) +++ channels/ooh323c/src/ooh323.c (working copy) @@ -528,7 +528,14 @@ } /* Retrieve the H.245 control channel address from the connect msg */ - if(callProceeding->m.h245AddressPresent) + if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent && + q931Msg->userInfo->h323_uu_pdu.h245Tunneling && + callProceeding->m.h245AddressPresent) { + OOTRACEINFO3("Tunneling and h245address provided." + "Using Tunneling for H.245 messages (%s, %s)\n", + call->callType, call->callToken); + } + else if(callProceeding->m.h245AddressPresent) { if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { @@ -718,7 +725,14 @@ } /* Retrieve the H.245 control channel address from the connect msg */ - if(alerting->m.h245AddressPresent) + if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent && + q931Msg->userInfo->h323_uu_pdu.h245Tunneling && + alerting->m.h245AddressPresent) { + OOTRACEINFO3("Tunneling and h245address provided." + "Giving preference to Tunneling (%s, %s)\n", + call->callType, call->callToken); + } + else if(alerting->m.h245AddressPresent) { if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { @@ -933,7 +947,14 @@ } /* Retrieve the H.245 control channel address from the CONNECT msg */ - if(connect->m.h245AddressPresent) + if(q931Msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent && + q931Msg->userInfo->h323_uu_pdu.h245Tunneling && + connect->m.h245AddressPresent) { + OOTRACEINFO3("Tunneling and h245address provided." + "Giving preference to Tunneling (%s, %s)\n", + call->callType, call->callToken); + } + else if(connect->m.h245AddressPresent) { if (OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { Index: channels/ooh323c/src/ooSocket.c =================================================================== --- channels/ooh323c/src/ooSocket.c (revision 599) +++ channels/ooh323c/src/ooSocket.c (working copy) @@ -338,7 +338,7 @@ if (pNewSocket == 0) return ASN_E_INVPARAM; *pNewSocket = accept (socket, (struct sockaddr *) (void*) &m_addr, - (socklen_t*)&addr_length); + &addr_length); if (*pNewSocket <= 0) return ASN_E_INVSOCKET; if (destAddr != 0) Index: channels/ooh323c/src/ooq931.c =================================================================== --- channels/ooh323c/src/ooq931.c (revision 599) +++ channels/ooh323c/src/ooq931.c (working copy) @@ -2037,10 +2037,10 @@ /* Set calling party number Q931 IE */ if(call->callingPartyNumber) ooQ931SetCallingPartyNumberIE(q931msg, - (const char*)call->callingPartyNumber, 1, 0, 1, 1); + (const char*)call->callingPartyNumber, 1, 0, 0, 0); - /* Set called party number Q931 ie */ + /* Set called party number Q931 IE */ if(call->calledPartyNumber) ooQ931SetCalledPartyNumberIE(q931msg, (const char*)call->calledPartyNumber, 1, 0); @@ -3358,6 +3358,7 @@ "OOConnect", "OOReleaseComplete", "OOFacility", + "OOInformation", "OOMasterSlaveDetermination", "OOMasterSlaveAck", "OOMasterSlaveReject", Index: channels/ooh323c/src/ooCapability.c =================================================================== --- channels/ooh323c/src/ooCapability.c (revision 599) +++ channels/ooh323c/src/ooCapability.c (working copy) @@ -898,6 +898,9 @@ H245AudioCapability* audioCap, int dir) { int noofframes=0, cap; + + OOTRACEDBGC2("Comparing channel with codec type: %d\n", audioCap->t); + switch(audioCap->t) { case T_H245AudioCapability_g711Ulaw56k: @@ -929,7 +932,7 @@ noofframes = audioCap->u.g729; break; case T_H245AudioCapability_g729AnnexA: - cap = OO_G729; + cap = OO_G729A; noofframes = audioCap->u.g729AnnexA; break; case T_H245AudioCapability_g7231: @@ -940,11 +943,15 @@ return FALSE; } + OOTRACEDBGC3("Comparing codecs: current=%d, requested=%d\n", + epCap->cap, cap); if(cap != epCap->cap) { return FALSE; } /* Can we receive this capability */ if(dir & OORX) { + OOTRACEDBGC3("Comparing RX frame rate: channel's=%d, requested=%d\n", + ((OOCapParams*)epCap->params)->rxframes, noofframes); if(((OOCapParams*)epCap->params)->rxframes >= noofframes) { return TRUE; } @@ -958,6 +965,8 @@ /* Can we transmit compatible stream */ if(dir & OOTX) { + OOTRACEDBGC3("Comparing TX frame rate: channel's=%d, requested=%d\n", + ((OOCapParams*)epCap->params)->txframes, noofframes); if(((OOCapParams*)epCap->params)->txframes <= noofframes) { return TRUE; } @@ -1684,7 +1693,7 @@ if(!cur) return NULL; - OOTRACEDBGC4("Found matching simple audio capability type %s. Comparing" + OOTRACEDBGC4("Found matching H.263 video capability type %s. Comparing" " other parameters. (%s, %s)\n", ooGetCapTypeText(cap), call->callType, call->callToken); if(dir & OORX) Index: channels/ooh323c/src/ootrace.c =================================================================== --- channels/ooh323c/src/ootrace.c (revision 599) +++ channels/ooh323c/src/ootrace.c (working copy) @@ -37,7 +37,6 @@ gs_traceLevel = traceLevel; } -__attribute__((format (printf, 2, 3))) void ooTrace(OOUINT32 traceLevel, const char * fmtspec, ...) { va_list arglist; @@ -101,7 +100,7 @@ if(printDate) { printDate = 0; - strftime(dateString, 10, "%F", ptime); + strftime(dateString, 10, "%D", ptime); fprintf(gH323ep.fptraceFile, "---------Date %s---------\n", dateString); } Index: channels/chan_ooh323.c =================================================================== --- channels/chan_ooh323.c (revision 599) +++ channels/chan_ooh323.c (working copy) @@ -84,10 +84,10 @@ }; static struct ast_rtp_protocol ooh323_rtp = { - type: type, - get_rtp_info: ooh323_get_rtp_peer, - get_vrtp_info: ooh323_get_vrtp_peer, - set_rtp_peer: ooh323_set_rtp_peer + .type = type, + .get_rtp_info = ooh323_get_rtp_peer, + .get_vrtp_info = ooh323_get_vrtp_peer, + .set_rtp_peer = ooh323_set_rtp_peer }; /* H.323 channel private structure */ @@ -145,6 +145,8 @@ struct ast_codec_pref prefs; int dtmfmode; int rtptimeout; + int mUseIP; /* Use IP address or H323-ID to search user */ + char mIP[20]; struct ooh323_user *next; }; @@ -159,6 +161,7 @@ char accountcode[20]; int amaflags; int dtmfmode; + int mFriend; /* indicates defined as friend */ char ip[20]; int port; char *h323id; /* H323-ID alias, which asterisk will register with gk to reach this peer*/ @@ -221,6 +224,11 @@ static int gOutgoingLimit = 4; OOBOOL gH323Debug = FALSE; +static struct ooh323_config +{ + int mTCPPortStart; + int mTCPPortEnd; +}ooconfig; /** Asterisk RTP stuff*/ static struct sched_context *sched; @@ -460,6 +468,9 @@ char tmp[256]; char formats[512]; int oldformat; + char *sport = NULL; + int port = 0; + if(gH323Debug) ast_verbose("--- ooh323_request - data %s format %s\n", (char*)data, ast_getformatname_multiple(formats,512,format) ); @@ -504,9 +515,16 @@ dest = tmp; ext = NULL; } + + /*if((sport = strchr(dest, ':'))) { + *sport = '\0'; + sport++; + port = atoi(sport); + }*/ - if(dest) - peer = find_peer(dest); + if(dest) { + peer = find_peer(dest, port); + } else{ ast_log(LOG_ERROR, "Destination format is not supported\n"); return NULL; @@ -542,8 +560,12 @@ p->host = strdup(dest); - if(ext) + if(port > 0) { + p->port = port; + } + if(ext) { strncpy(p->exten, ext, sizeof(p->exten)-1); + } } @@ -594,53 +616,104 @@ return p; } -struct ooh323_user *find_user(const char * name) +struct ooh323_user *find_user(const char * name, const char* ip) { struct ooh323_user *user=NULL; if(gH323Debug) ast_verbose("--- find_user\n"); - user = userl.users; ast_mutex_lock(&userl.lock); while(user) { - if(name && !strcmp(user->name, name)) + if(ip && user->mUseIP && !strcmp(user->mIP, ip)) { break; + } + if(name && !strcmp(user->name, name)) { + break; + } user = user->next; } ast_mutex_unlock(&userl.lock); + if(gH323Debug) ast_verbose("+++ find_user\n"); return user; } -struct ooh323_peer *find_peer(const char * name) +struct ooh323_peer *find_friend(const char *name, int port) { + struct ooh323_peer *peer=NULL; + + if(gH323Debug) + ast_verbose("--- find_friend \"%s\"\n", name); + + + peer = peerl.peers; + ast_mutex_lock(&peerl.lock); + while(peer) + { + if(gH323Debug) { + ast_verbose(" comparing with \"%s\"\n", peer->ip); + } + if(!strcmp(peer->ip, name)) { + if(port > 0 && peer->port == port) { break; } + else if (port <= 0) { break; } + } + peer = peer->next; + } + ast_mutex_unlock(&peerl.lock); + + if(gH323Debug) { + if(peer) { + ast_verbose(" found matching friend\n"); + } + ast_verbose("+++ find_friend \"%s\"\n", name); + } + + return peer; +} + + +struct ooh323_peer *find_peer(const char * name, int port) +{ struct ooh323_peer *peer=NULL; if(gH323Debug) - ast_verbose("--- find_peer\n"); + ast_verbose("--- find_peer \"%s\"\n", name); peer = peerl.peers; ast_mutex_lock(&peerl.lock); while(peer) { + if(gH323Debug) { + ast_verbose(" comparing with \"%s\"\n", peer->ip); + } if(!strcasecmp(peer->name, name)) break; if(peer->h323id && !strcasecmp(peer->h323id, name)) break; if(peer->e164 && !strcasecmp(peer->e164, name)) break; + /* + if(!strcmp(peer->ip, name)) { + if(port > 0 && peer->port == port) { break; } + else if (port <= 0) { break; } + } + */ peer = peer->next; } ast_mutex_unlock(&peerl.lock); - if(gH323Debug) - ast_verbose("+++ find_peer\n"); + if(gH323Debug) { + if(peer) { + ast_verbose(" found matching peer\n"); + } + ast_verbose("+++ find_peer \"%s\"\n", name); + } return peer; } @@ -890,7 +963,7 @@ fr = ooh323_rtp_read(ast, p); else fr = &null_frame; - // time(&p->lastrtprx); + /* time(&p->lastrtprx); */ ast_mutex_unlock(&p->lock); return fr; } @@ -996,7 +1069,7 @@ struct ooh323_pvt *p = newchan->tech_pvt; if(gH323Debug) - ast_verbose("start: ooh323c ooh323_fixup\n"); + ast_verbose("--- ooh323c ooh323_fixup\n"); ast_mutex_lock(&p->lock); if (p->owner != oldchan) { @@ -1015,7 +1088,7 @@ ast_mutex_unlock(&p->lock); if(gH323Debug) - ast_verbose("end: ooh323c ooh323_fixup \n"); + ast_verbose("+++ ooh323c ooh323_fixup \n"); return 0; } @@ -1268,7 +1341,7 @@ if(p->callerid_name) { p->username = strdup(p->callerid_name); - user = find_user(p->username); + user = find_user(p->username, call->remoteIP); if(user) { ast_mutex_lock(&user->lock); @@ -1605,12 +1678,20 @@ v->value, 0); } else if (!strcasecmp(v->name, "allow")) { + const char* tcodecs = v->value; + if(!strcasecmp(v->value, "all")) { + tcodecs = "ulaw,alaw,g729,g723,gsm"; + } ast_parse_allow_disallow(&user->prefs, &user->capability, - v->value, 1); + tcodecs, 1); } else if (!strcasecmp(v->name, "amaflags")) { user->amaflags = ast_cdr_amaflags2int(v->value); } + else if (!strcasecmp(v->name, "ip")) { + strncpy(user->mIP, v->value, sizeof(user->mIP)-1); + user->mUseIP = 1; + } else if (!strcasecmp(v->name, "dtmfmode")) { if(!strcasecmp(v->value, "rfc2833")) user->dtmfmode = H323_DTMF_RFC2833; @@ -1631,7 +1712,7 @@ return user; } -static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v) +static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type) { struct ooh323_peer *peer=NULL; @@ -1649,6 +1730,9 @@ strncpy(peer->accountcode, gAccountcode, sizeof(peer->accountcode)-1); peer->amaflags = gAMAFLAGS; peer->dtmfmode = gDTMFMode; + if(0 == friend_type) { + peer->mFriend = 1; + } while(v) { if (!strcasecmp(v->name, "h323id")) { @@ -1719,8 +1803,12 @@ v->value, 0); } else if (!strcasecmp(v->name, "allow")) { + const char* tcodecs = v->value; + if(!strcasecmp(v->value, "all")) { + tcodecs = "ulaw,alaw,g729,g723,gsm"; + } ast_parse_allow_disallow(&peer->prefs, &peer->capability, - v->value, 1); + tcodecs, 1); } else if (!strcasecmp(v->name, "amaflags")) { peer->amaflags = ast_cdr_amaflags2int(v->value); @@ -1839,6 +1927,8 @@ strcpy(gContext, DEFAULT_CONTEXT); gAliasList = NULL; gMediaWaitForConnect = 0; + ooconfig.mTCPPortStart = 12030; + ooconfig.mTCPPortEnd = 12230; v = ast_variable_browse(cfg, "general"); while(v) { @@ -1849,6 +1939,27 @@ else if (!strcasecmp(v->name, "bindaddr")) { strncpy(gIP, v->value, sizeof(gIP)-1); } + else if (!strcasecmp(v->name, "h225portrange")) { + char* endlimit = 0; + char temp[512]; + strncpy(temp, v->value, sizeof(temp) - 1); + /* char *temp = ast_strdupa(v->value); */ + endlimit = strchr(temp, ','); + if (endlimit) { + *endlimit = '\0'; + endlimit++; + ooconfig.mTCPPortStart = atoi(temp); + ooconfig.mTCPPortEnd = atoi(endlimit); + + if(ooH323EpSetTCPPortRange(ooconfig.mTCPPortStart, + ooconfig.mTCPPortEnd) == OO_FAILED) { + ast_log(LOG_ERROR, "h225portrange: Failed to set range\n"); + } + } + else { + ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n"); + } + } else if (!strcasecmp(v->name, "gateway")) { gIsGateway = ast_true(v->value); } @@ -1971,7 +2082,11 @@ ast_parse_allow_disallow(&gPrefs, &gCapability, v->value, 0); } else if (!strcasecmp(v->name, "allow")) { - ast_parse_allow_disallow(&gPrefs, &gCapability, v->value, 1); + const char* tcodecs = v->value; + if(!strcasecmp(v->value, "all")) { + tcodecs = "ulaw,alaw,g729,g723,gsm"; + } + ast_parse_allow_disallow(&gPrefs, &gCapability, tcodecs, 1); } else if (!strcasecmp(v->name, "dtmfmode")) { if (!strcasecmp(v->value, "inband")) @@ -1998,10 +2113,12 @@ { if(strcasecmp(cat, "general")) { + int friend_type = 0; utype = ast_variable_retrieve(cfg, cat, "type"); if(utype) { - if(!strcmp(utype, "user") || !strcasecmp(utype, "friend")) + friend_type = strcasecmp(utype, "friend"); + if(!strcmp(utype, "user") || 0 == friend_type) { user = build_user(cat, ast_variable_browse(cfg, cat)); if (user) @@ -2015,15 +2132,15 @@ ast_log(LOG_WARNING, "Failed to build user %s\n", cat); } } - if(!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) + if(!strcasecmp(utype, "peer") || 0 == friend_type) { - peer = build_peer(cat, ast_variable_browse(cfg, cat)); + peer = build_peer(cat, ast_variable_browse(cfg, cat), friend_type); if(peer) { - ast_mutex_lock(&userl.lock); + ast_mutex_lock(&peerl.lock); peer->next = peerl.peers; peerl.peers = peer; - ast_mutex_unlock(&userl.lock); + ast_mutex_unlock(&peerl.lock); } else { ast_log(LOG_WARNING, "Failed to build peer %s\n", cat); @@ -2341,7 +2458,6 @@ 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, "%-15s%s\n", "MediaWaitForConnect", gMediaWaitForConnect ? "yes" : "no"); #if (0) { @@ -2696,24 +2812,36 @@ else iflist = cur->next; - if(cur->callToken) + if(cur->callToken) { free(cur->callToken); + cur->callToken = 0; + } - if(cur->username) + if(cur->username) { free(cur->username); + cur->username = 0; + } - if(cur->host) + if(cur->host) { free(cur->host); + cur->host = 0; + } - if(cur->callerid_name) + if(cur->callerid_name) { free(cur->callerid_name); + cur->callerid_name = 0; + } - if(cur->callerid_num) + if(cur->callerid_num) { free(cur->callerid_num); + cur->callerid_num = 0; + } - if (cur->rtp) + if (cur->rtp) { ast_rtp_destroy(cur->rtp); + cur->rtp = 0; + } /* Unlink us from the owner if we have one */ if (cur->owner) { @@ -2978,6 +3106,8 @@ return OO_G729A; case AST_FORMAT_G723_1: return OO_G7231; + case AST_FORMAT_H263: + return OO_H263VIDEO; default: ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_getformatname_multiple(formats,512,cap)); @@ -3075,7 +3205,7 @@ } them.sin_family = AF_INET; - them.sin_addr.s_addr = inet_addr(remoteIp); // only works for IPv4 + them.sin_addr.s_addr = inet_addr(remoteIp); /* only works for IPv4 */ them.sin_port = htons(remotePort); ast_rtp_set_peer(p->rtp, &them); Index: channels/chan_ooh323.h =================================================================== --- channels/chan_ooh323.h (revision 599) +++ channels/chan_ooh323.h (working copy) @@ -77,8 +77,8 @@ struct ooh323_user; struct ooh323_peer; /* Helper functions */ -struct ooh323_user *find_user(const char * name); -struct ooh323_peer *find_peer(const char * name); +struct ooh323_user *find_user(const char * name, const char *ip); +struct ooh323_peer *find_peer(const char * name, int port); void ooh323_delete_peer(struct ooh323_peer *peer); int delete_users(void); Index: channels/ooh323cDriver.c =================================================================== --- channels/ooh323cDriver.c (revision 599) +++ channels/ooh323cDriver.c (working copy) @@ -121,6 +121,18 @@ } + if(format & AST_FORMAT_H263) + { + if(gH323Debug) + ast_verbose("\tAdding h263 capability to H323 endpoint\n"); + ret = ooH323EpAddH263VideoCapability(OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, + OORXANDTX, &ooh323c_start_receive_channel, + &ooh323c_start_transmit_channel, + &ooh323c_stop_receive_channel, + &ooh323c_stop_transmit_channel); + + } + if(format & AST_FORMAT_GSM) { if(gH323Debug) @@ -225,6 +237,19 @@ } + if(format & AST_FORMAT_H263) + { + if(gH323Debug) + ast_verbose("\tAdding h263 capability to call (%s, %s)\n", + call->callType, call->callToken); + ret = ooCallAddH263VideoCapability(call, OO_H263VIDEO, 1, 0, 0, 0, 0, 320*1024, + OORXANDTX, &ooh323c_start_receive_channel, + &ooh323c_start_transmit_channel, + &ooh323c_stop_receive_channel, + &ooh323c_stop_transmit_channel); + + } + if(format & AST_FORMAT_GSM) { if(gH323Debug) @@ -323,6 +348,8 @@ return AST_FORMAT_G729A; case OO_G7231: return AST_FORMAT_G723_1; + case OO_H263VIDEO: + return AST_FORMAT_H263; default: ast_debug(1, "Cap %d is not supported by driver yet\n", cap); return -1;