#include <stdio.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "mslp_sd.h"
#include "slp.h"
#include "mslp.h"
#include "mslp_dat.h"
#include "mslplib.h"
#include "mslplib_opt.h"
#include "CNSLTimingUtils.h"
static MslpHashtable *pmhConfig = NULL;
static SLPInternalError get_reply(char *pcSend, int iSize,
const char *pcScope,
UA_State *puas,
void *pvCallback, void *pvUser, CBType cbt );
EXPORT void EncodeChar( const char c, char* newEscapedBufPtr );
EXPORT char DecodeChar( const char* encodedTriplet );
EXPORT SLPInternalError SLPOpen(const char *pcLang, SLPBoolean isAsync, SLPHandle *phSLP, CFRunLoopRef runLoopRef )
{
SLPInternalError err = SLP_OK;
UA_State *puas;
int piTimes[5] = { 3000, 3000, 3000, 3000, 3000 };
*phSLP = NULL;
if (isAsync)
return SLP_NOT_IMPLEMENTED;
SLP_LOG( SLP_LOG_DEBUG, "SLPOpen called" );
if (pmhConfig == NULL)
pmhConfig = mslp_hash_init();
#ifdef EXTRA_MSGS
if (!SLPGetProperty("com.sun.slp.regfile"))
SLPSetProperty("com.sun.slp.regfile",SDDefaultRegfile());
if (!SLPGetProperty("com.sun.slp.tempfile"))
SLPSetProperty("com.sun.slp.tempfile",SDDefaultTempfile());
#endif
if (!SLPGetProperty("net.slp.multicastMaximumWait"))
SLPSetProperty("net.slp.multicastMaximumWait","15000"); if (!SLPGetProperty("net.slp.multicastTTL"))
SLPSetProperty("net.slp.multicastTTL",MCAST_TTL);
if (!SLPGetProperty("net.slp.MTU"))
SLPSetProperty("net.slp.MTU",SENDMTU);
if (!SLPGetProperty("com.apple.slp.port"))
SLPSetProperty("com.apple.slp.port","427");
if (!SLPGetProperty("com.sun.slp.minRefreshInterval"))
SLPSetProperty("com.sun.slp.minRefreshInterval","10800");
if (!SLPGetProperty("net.slp.locale"))
{
if (pcLang)
SLPSetProperty("net.slp.locale",pcLang);
else
SLPSetProperty("net.slp.locale","en");
}
if (getenv("SLP_CONF_FILE") != NULL)
mslp_hash_read(pmhConfig,getenv("SLP_CONF_FILE"));
InitializeSLPSystemConfigurator(runLoopRef);
puas = (UA_State*) safe_malloc(sizeof(UA_State), NULL, 0);
char* endPtr = NULL;
puas->pcSendBuf = safe_malloc(strtol(SLPGetProperty("net.slp.MTU"),&endPtr,10),NULL,0);
assert( puas->pcSendBuf );
puas->pcRecvBuf = safe_malloc(RECVMTU, NULL, 0);
puas->iRecvSz = RECVMTU;
memset(&(puas->config),0,sizeof(puas->config));
puas->config.pi_net_slp_multicastTimeouts = (int*)
safe_malloc(5*sizeof(int),(char*) piTimes,5*sizeof(int));
puas->config.pi_net_slp_DADiscoveryTimeouts = (int*)
safe_malloc(5*sizeof(int),(char*) piTimes,5*sizeof(int));
*phSLP = (SLPHandle) puas;
err = mslplib_init_network(&(puas->sdSend),&(puas->sdTCP),&(puas->sdMax));
if ( !err && !OnlyUsePreConfiguredDAs() )
{
if (SLPGetProperty("net.slp.isBroadcastOnly") && !(SDstrcasecmp(SLPGetProperty("net.slp.isBroadcastOnly"),"true")))
{
int i = 1;
int iErr = setsockopt( puas->sdSend, SOL_SOCKET, SO_BROADCAST, (char*)&i, sizeof(int) );
if (iErr)
{
err = SLP_NETWORK_INIT_FAILED;
mslplog(SLP_LOG_DEBUG,"SLPOpen could not set broadcast interface",strerror(errno));
}
puas->sinSendTo.sin_addr.s_addr = BROADCAST;
}
else
{
err = set_multicast_sender_interf(puas->sdSend);
if ( err )
{
SLP_LOG( SLP_LOG_DROP,"SLPOpen could not set multicast interface: %s", strerror(errno) );
}
else
puas->sinSendTo.sin_addr.s_addr = SLP_MCAST;
}
}
if ( err == SLP_OK )
{
puas->sinSendTo.sin_port = htons(SLP_PORT);
puas->sinSendTo.sin_family = AF_INET;
puas->tv.tv_sec = WAIT_MSEC;
puas->tv.tv_usec = (WAIT_MSEC % 1000) * 1000;
if (err == SLP_OK && runLoopRef)
err = StartSLPDALocator( (void*)mslplib_daadvert_callback, runLoopRef, NULL );
#ifdef EXTRA_MSGS
if (SLPGetProperty("com.sun.slp.isSA") == NULL)
puas->pvMutex = SDGetMutex(MSLP_CLIENT);
#endif
}
SLP_LOG( SLP_LOG_DEBUG, "SLPOpen finished" );
return err;
}
EXPORT void SLPClose(SLPHandle slpc) {
UA_State *puas = (UA_State*) slpc;
if (puas) {
#ifdef EXTRA_MSGS
if (SLPGetProperty("com.sun.slp.isSA") == NULL && puas->pvMutex)
SDFreeMutex(puas->pvMutex, MSLP_CLIENT);
#endif
if (puas->pcSendBuf) free(puas->pcSendBuf);
if (puas->pcRecvBuf) free(puas->pcRecvBuf);
if (puas->config.pi_net_slp_DADiscoveryTimeouts)
free(puas->config.pi_net_slp_DADiscoveryTimeouts);
if (puas->config.pi_net_slp_multicastTimeouts)
free(puas->config.pi_net_slp_multicastTimeouts);
if (puas->config.pc_net_slp_locale)
free(puas->config.pc_net_slp_locale);
CLOSESOCKET(puas->sdSend);
CLOSESOCKET(puas->sdTCP);
free(puas);
}
CLOSE_NETWORKING;
}
EXPORT SLPInternalError SLPFindSrvs(SLPHandle hSLP,
const char *pcSrvType,
const char *pcScope,
const char *pcSearchFilter,
SLPSrvURLCallback callback,
void *pvUser)
{
SLPInternalError err = SLP_OK;
UA_State *puas = (UA_State*) hSLP;
char* endPtr = NULL;
int iSize = (SLPGetProperty("net.slp.MTU"))?strtol(SLPGetProperty("net.slp.MTU"),&endPtr,10):1400;
const char *pcLocale = SLPGetProperty("net.slp.locale");
char *pcTCPbuf = NULL;
if (hSLP == NULL || !pcScope || !pcSrvType || !callback)
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"SLPFindSrvs bad parameter",SLP_PARAMETER_BAD);
memset(puas->pcSendBuf,0,iSize);
if ( strcmp( pcScope, SLP_DEFAULT_SA_ONLY_SCOPE ) != 0 )
err = generate_srvrqst( puas->pcSendBuf, &iSize, pcLocale, pcScope, pcSrvType, pcSearchFilter);
else
{
err = generate_srvrqst( puas->pcSendBuf, &iSize, pcLocale, SLP_DEFAULT_SCOPE, pcSrvType, pcSearchFilter);
}
#ifdef SLPTCP
if (err == SLP_BUFFER_OVERFLOW)
{
iSize = HDRLEN + strlen(pcLocale) + 2 +
2+strlen(pcScope) +2+strlen(pcSrvType) +2+strlen(pcSearchFilter) +
10;
pcTCPbuf = safe_malloc(iSize,NULL,0);
if ( strcmp( pcScope, SLP_DEFAULT_SA_ONLY_SCOPE ) != 0 )
err = generate_srvrqst(pcTCPbuf, &iSize, pcLocale, pcScope, pcSrvType, pcSearchFilter);
else
err = generate_srvrqst(pcTCPbuf, &iSize, pcLocale, SLP_DEFAULT_SCOPE, pcSrvType, pcSearchFilter);
if (err != SLP_OK)
{
SLPFree(pcTCPbuf);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"SLPFindSrvs generate overflowed request failed",err);
}
}
#endif
if ( strcmp( pcScope, SLP_DEFAULT_SA_ONLY_SCOPE ) != 0 )
GetGlobalDATableForRequester(); err = get_reply((pcTCPbuf)?pcTCPbuf:puas->pcSendBuf,iSize,
pcScope, puas, (void*) callback, pvUser, SLPSRVURL_CALLBACK);
SLPFree(pcTCPbuf);
return err;
}
#ifdef MAC_OS_X
EXPORT SLPInternalError SLPFindScopesAsync(SLPHandle hSLP,
SLPScopeCallback callback,
void *pvUser)
{
SLPInternalError err = SLP_OK;
DATable* pdat = NULL;
pdat = GetGlobalDATableForRequester();
if ( pdat && pdat->iSize > 0 && !GlobalDATableCreationCompleted() )
{
int lastCheckedSize = 0;
SLP_LOG( SLP_LOG_DEBUG, "SLPFindScopesAsync is getting scopelist from the currently running DA Discovery" );
do {
SmartSleep(2*USEC_PER_SEC);
LockGlobalDATable();
if ( pdat->iSize > lastCheckedSize && pdat->pDAE[lastCheckedSize].pcScopeList != NULL )
{
int iListLen = LISTINCR, i, offset=0;
char *pcList=NULL, *pcScan=NULL, *pcScope=NULL, c;
SLPBoolean slpbDone = SLP_FALSE;
iListLen += strlen(pdat->pDAE[lastCheckedSize].pcScopeList);
pcList = safe_malloc(iListLen, (char*)pdat->pDAE[lastCheckedSize].pcScopeList, iListLen-LISTINCR);
for (i = lastCheckedSize+1; i < pdat->iSize; i++)
{
pcScan = list_pack(pdat->pDAE[i].pcScopeList);
list_merge(pcScan,&pcList,&iListLen,CHECK);
free(pcScan);
}
while( !slpbDone && (pcScope = get_next_string(",",pcList,&offset,&c)) ) {
SLP_LOG( SLP_LOG_DEBUG, "SLPFindScopesAsync is returning single scope %s", pcScope );
slpbDone = !callback( hSLP, pcScope, err, pvUser );
SLPFree(pcScope);
}
free( pcList );
lastCheckedSize = pdat->iSize;
}
UnlockGlobalDATable();
} while ( !GlobalDATableCreationCompleted() );
}
else if ( pdat && pdat->iSize > 0 && pdat->pDAE[0].pcScopeList != NULL )
{
int iListLen = LISTINCR, i, offset=0;
char *pcList=NULL, *pcScan=NULL, *pcScope=NULL, c;
SLPBoolean slpbDone = SLP_FALSE;
SLP_LOG( SLP_LOG_DEBUG, "SLPFindScopesAsync is returning scopelist from the %d DA(s) we know about", pdat->iSize );
LockGlobalDATable();
iListLen += strlen(pdat->pDAE[0].pcScopeList);
pcList = safe_malloc(iListLen, (char*)pdat->pDAE[0].pcScopeList, iListLen-LISTINCR);
if (pdat->iSize > 1)
{
for (i = 1; i < pdat->iSize; i++)
{
pcScan = list_pack(pdat->pDAE[i].pcScopeList);
list_merge(pcScan,&pcList,&iListLen,CHECK);
free(pcScan);
}
}
UnlockGlobalDATable();
SLP_LOG( SLP_LOG_DEBUG, "SLPFindScopesAsync is returning scopelist %s", pcList );
while( !slpbDone && (pcScope = get_next_string(",",pcList,&offset,&c)) ) {
SLP_LOG( SLP_LOG_DEBUG, "SLPFindScopesAsync is returning single scope %s", pcScope );
slpbDone = !callback( hSLP, pcScope, err, pvUser );
SLPFree(pcScope);
}
free( pcList );
}
else
{
const char *pcTypeHint = SLPGetProperty("net.slp.typeHint");
SLP_LOG( SLP_LOG_DEBUG, "SLPFindScopesAsync is getting scopelist from active sa discovery" );
err = active_sa_async_discovery( hSLP, callback, pvUser, pcTypeHint );
}
SLP_LOG( SLP_LOG_DEBUG, "SLPFindScopesAsync is finished" );
return err;
}
#endif
EXPORT SLPInternalError SLPFindScopes(SLPHandle hSLP ,
char ** ppcScopeList) {
const char *pcTypeHint = SLPGetProperty("net.slp.typeHint");
if (!hSLP || !ppcScopeList) return SLP_PARAMETER_BAD;
return dat_get_scopes(hSLP, pcTypeHint, GetGlobalDATable(), ppcScopeList);
}
EXPORT void SLPFree(void* pvMem) {
if (pvMem) free(pvMem);
}
EXPORT SLPBoolean SLPIsReserved(char c) {
if (c=='(' || c==')' || c==',' || c=='\\' || c=='!' || c=='<' ||
c=='=' || c=='>' || c=='~' || c<0x20) return SLP_FALSE;
else return SLP_FALSE;
}
EXPORT const char* SLPGetProperty(const char* pcName )
{
if (pmhConfig == NULL)
pmhConfig = mslp_hash_init();
return mslp_hash_find(pmhConfig,pcName);
}
EXPORT void SLPSetProperty(const char * pcName ,
const char * pcValue )
{
if (!pcName) return;
if (NULL == pcValue &&
(!SDstrcasecmp(pcName,"net.slp.locale") ||
!SDstrcasecmp(pcName,"net.slp.multicastMaximumWait") ||
!SDstrcasecmp(pcName,"net.slp.multicastTTL") ||
!SDstrcasecmp(pcName,"net.slp.MTU") ||
(!SDstrcasecmp(pcName,"net.slp.useScopes") &&
SLPGetProperty("com.sun.slp.isSA"))))
{
LOG(SLP_LOG_ERR,"SLPSetProperty: attempt to erase a critical property failed");
return;
}
if (pmhConfig == NULL)
pmhConfig = mslp_hash_init();
mslp_hash_add(pmhConfig,pcName,pcValue);
}
EXPORT void SLPReadConfigFile(const char *pcFileName) {
if (pcFileName == NULL) return;
if (pmhConfig == NULL) pmhConfig = mslp_hash_init();
mslp_hash_read(pmhConfig, pcFileName);
}
EXPORT void SLPWriteConfigFile(const char *pcFileName) {
if (pcFileName == NULL) return;
if (pmhConfig == NULL) pmhConfig = mslp_hash_init();
mslp_hash_write(pmhConfig, pcFileName);
}
EXPORT void SLPLogConfigState( void )
{
if (pmhConfig == NULL) pmhConfig = mslp_hash_init();
}
EXPORT SLPInternalError SLPReg(SLPHandle hSLP,
const char *pcSrvURL,
const unsigned short usLifetime,
const char *pcSrvType,
const char *pcAttrs,
SLPBoolean fresh,
SLPRegReport callback,
void *pvCookie)
{
UA_State *puas = (UA_State*) hSLP;
SLPInternalError err = SLP_OK;
SLPRegReport *srr = (SLPRegReport *) callback;
if (!hSLP || !pcSrvURL || usLifetime == 0 || !pcSrvType || !callback) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"SLPReg bad parameter",SLP_PARAMETER_BAD);
}
err = mslplib_Reg(puas, pcSrvURL, usLifetime, pcSrvType, pcAttrs, fresh);
srr(hSLP, err, pvCookie);
return SLP_OK;
}
EXPORT SLPInternalError SLPDereg(SLPHandle hSLP,
const char *pcURL,
const char *pcScopes,
SLPRegReport callback,
void *pvCookie) {
#ifdef EXTRA_MSGS
UA_State *puas = (UA_State*) hSLP;
SLPInternalError err = SLP_OK;
SLPRegReport *srr = (SLPRegReport *) callback;
if (!hSLP || !pcURL || !callback) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"SLPDereg bad parameter",SLP_PARAMETER_BAD);
}
err = mslplib_Dereg(puas, pcURL, pcScopes);
srr(hSLP, err, pvCookie);
return err;
#else
return SLP_NOT_IMPLEMENTED;
#endif
}
EXPORT SLPInternalError SLPFindAttrs(SLPHandle hSLP ,
const char * pcURL ,
const char * pcScope ,
const char * pcAttrIds ,
SLPAttrCallback callback ,
void * pvUser ) {
#ifdef EXTRA_MSGS
SLPInternalError err = SLP_OK;
UA_State *puas = (UA_State*) hSLP;
char* endPtr = NULL;
int iSize = (SLPGetProperty("net.slp.MTU"))?strtol(SLPGetProperty("net.slp.MTU"),&endPtr,10):1400;
const char *pcLocale = SLPGetProperty("net.slp.locale");
char *pcTCPbuf = NULL;
char *pcUseBuf = NULL;
if (hSLP == NULL || !pcURL || !callback) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"SLPFindSrvs bad parameter",SLP_PARAMETER_BAD);
}
if (pcAttrIds == NULL) pcAttrIds = "";
if (pcScope == NULL) pcScope = SLPGetProperty("net.slp.useScopes");
memset(puas->pcSendBuf,0,iSize);
err = generate_attrrqst( puas->pcSendBuf, &iSize, pcLocale,
pcURL, pcScope, pcAttrIds);
#ifdef SLPTCP
if (err == SLP_BUFFER_OVERFLOW) {
iSize = HDRLEN + strlen(pcLocale) + 2 +
2+strlen(pcScope) +2+strlen(pcURL) +2+strlen(pcAttrIds) +
10;
pcTCPbuf = safe_malloc(iSize,NULL,0);
err = generate_attrrqst(pcTCPbuf, &iSize, pcLocale,
pcURL, pcScope, pcAttrIds);
if (err != SLP_OK) {
SLPFree(pcTCPbuf);
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"SLPFindAttrs generate overflowed request failed",err);
}
}
#endif
if (pcTCPbuf != NULL) {
pcUseBuf = pcTCPbuf;
} else {
pcUseBuf = puas->pcSendBuf;
}
err = get_reply(pcUseBuf,iSize, pcScope, puas, (void*)callback, pvUser,
SLPATTR_CALLBACK);
SLPFree(pcTCPbuf);
return err;
#else
return SLP_NOT_IMPLEMENTED;
#endif
}
EXPORT SLPInternalError SLPFindSrvTypes(SLPHandle hSLP ,
const char * pcNamingAuthority ,
const char * pcScopeList ,
SLPSrvTypeCallback callback ,
void * pvUser ) {
#ifdef EXTRA_MSGS
SLPInternalError err = SLP_OK;
UA_State *puas = (UA_State*) hSLP;
char* endPtr = NULL;
int iSize = (SLPGetProperty("net.slp.MTU"))?strtol(SLPGetProperty("net.slp.MTU"),&endPtr,10):1400;
const char *pcLocale = SLPGetProperty("net.slp.locale");
if (hSLP == NULL || !callback) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"SLPFindSrvTypes bad parameter",SLP_PARAMETER_BAD);
}
if (pcScopeList == NULL) pcScopeList = SLPGetProperty("net.slp.useScopes");
if (pcNamingAuthority == NULL) pcNamingAuthority = "";
memset(puas->pcSendBuf,0,iSize);
if ((err = generate_srvtyperqst( puas->pcSendBuf, &iSize, pcLocale,
pcNamingAuthority, pcScopeList)) != SLP_OK) {
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_ERR,"SLPFindSrvTypes couldn't generate message",err);
}
return get_reply(puas->pcSendBuf,iSize, pcScopeList, puas, (void*) callback,
pvUser, SLPSRVTYPE_CALLBACK);
#else
return SLP_NOT_IMPLEMENTED;
#endif
}
EXPORT SLPInternalError SLPDelAttrs(SLPHandle hSLP,
const char *pcURL,
const char *pcAttrs,
SLPRegReport callback,
void *pvCookie) {
return SLP_NOT_IMPLEMENTED;
}
EXPORT SLPInternalError SLPParseSrvURL(const char * pcSrvURL ,
SLPSrvURL ** ppSrvURL ) {
return SLP_NOT_IMPLEMENTED;
}
EXPORT SLPInternalError SLPEscape(const char* pcInBuf, char** ppcOutBuf)
{
SLPInternalError status = SLP_OK;
char* newTextBuffer = NULL;
char* curWritePtr = NULL;
u_short writeBufferMaxLen, newTextBufferLen, rawTextLen,i;
if ( !pcInBuf || !ppcOutBuf )
status = SLP_PARAMETER_BAD;
rawTextLen = strlen(pcInBuf);
newTextBufferLen = rawTextLen * 3 + 1;
newTextBuffer = (char*)malloc( newTextBufferLen );
curWritePtr = newTextBuffer;
writeBufferMaxLen = newTextBufferLen;
for ( i=0; !status && i<rawTextLen; i++ )
{
if ( SLPIsReserved( pcInBuf[i] ) == SLP_TRUE )
{
if ( curWritePtr > newTextBuffer + writeBufferMaxLen + 2 ) {
status = SLP_INTERNAL_SYSTEM_ERROR;
break;
}
EncodeChar( pcInBuf[i], curWritePtr );
curWritePtr += 3;
}
else
{
if ( curWritePtr > newTextBuffer + writeBufferMaxLen )
{
status = SLP_INTERNAL_SYSTEM_ERROR;
break;
}
*curWritePtr = pcInBuf[i];
curWritePtr++;
}
}
if ( !status )
{
newTextBufferLen = curWritePtr - newTextBuffer;
*ppcOutBuf = (char*)malloc( newTextBufferLen + 1 );
memcpy( *ppcOutBuf, newTextBuffer, newTextBufferLen );
(*ppcOutBuf)[newTextBufferLen] = '\0';
}
else
{
newTextBufferLen = 0;
}
if ( newTextBuffer )
free( newTextBuffer );
return status;
}
EXPORT SLPInternalError SLPUnescape(const char* pcInBuf, char** ppcOutBuf )
{
const char* curReadPtr = pcInBuf;
char* curWritePtr = NULL;
char* tempTextBuffer = NULL;
u_short newTextBufferLen, encodedTextLen;
SLPInternalError status = SLP_OK;
if ( !pcInBuf || !ppcOutBuf )
status = SLP_PARAMETER_BAD;
encodedTextLen = strlen( pcInBuf );
tempTextBuffer = (char*)malloc( encodedTextLen + 1 );
curWritePtr = tempTextBuffer;
while ( !status && (curReadPtr <= pcInBuf+encodedTextLen) )
{
if ( curWritePtr > tempTextBuffer + encodedTextLen )
{
status = SLP_INTERNAL_SYSTEM_ERROR;
break;
}
if ( *curReadPtr == 0x5c )
{
*curWritePtr = DecodeChar( curReadPtr );
curWritePtr++;
curReadPtr += 3;
}
else
{
*curWritePtr = *curReadPtr;
curWritePtr++;
curReadPtr++;
}
}
if ( !status )
newTextBufferLen = (curWritePtr-tempTextBuffer);
else
newTextBufferLen = 0;
return status;
}
EXPORT void EncodeChar( const char c, char* newEscapedBufPtr )
{
div_t result;
short hexValue = c;
char c1, c2;
if ( hexValue < 0 )
hexValue -= 0xFF00;
result = div( hexValue, 16 );
if ( result.quot < 0xA )
c1 = (char)result.quot + '0';
else
c1 = (char)result.quot + 'a' - 10;
if ( result.rem < 0xA )
c2 = (char)result.rem + '0';
else
c2 = (char)result.rem + 'a' - 10;
newEscapedBufPtr[0] = 0x5c; newEscapedBufPtr[1] = c1;
newEscapedBufPtr[2] = c2;
}
EXPORT char DecodeChar( const char* encodedTriplet )
{
char c, c1, c2;
c = *encodedTriplet;
if ( c == 0x5c )
{
c1 = tolower(encodedTriplet[1]);
c2 = tolower(encodedTriplet[2]);
if (isdigit(c1) && isdigit(c2))
{
c1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10;
c2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10;
c = (c1 << 4) | c2;
}
}
return c;
}
EXPORT int SLPGetRefreshInterval() {
const char *pcRefreshInterval =
SLPGetProperty("com.sun.slp.minRefreshInterval");
if (pcRefreshInterval) {
char* endPtr = NULL;
return strtol(pcRefreshInterval,&endPtr,10);
} else {
return MIN_REFRESH_DEFAULT;
}
}
#define ALL_DONE 1
static void last_one(SLPInternalError slperr, int iLast,
SLPHandle slph, void *pvUser,
void *pvCallback, CBType cbt) {
if (iLast == ALL_DONE) {
(void) process_reply(NULL, NULL, 0, &iLast, pvUser, slph, pvCallback,cbt);
}
}
static SLPInternalError get_reply( char* pcSend,
int iSize,
const char* pcScope,
UA_State* puas,
void* pvCallback,
void* pvUser,
CBType cbt )
{
char* pcRecvBuf = NULL;
int iLast = 0;
int use_da = 0;
struct sockaddr_in sin;
SLPInternalError err = SLP_OK;
char* endPtr = NULL;
int iMTU = (SLPGetProperty("net.slp.MTU"))?strtol(SLPGetProperty("net.slp.MTU"),&endPtr,10):1400;
int len = 0;
unsigned char ttl = (SLPGetProperty("net.slp.multicastTTL"))?(unsigned char) strtol(SLPGetProperty("net.slp.multicastTTL"), &endPtr, 10):255;
int multicastMaximumWait = (SLPGetProperty("net.slp.multicastMaximumWait"))?strtol(SLPGetProperty("net.slp.multicastMaximumWait"), &endPtr, 10):15000;
if ( strcmp( pcScope, SLP_DEFAULT_SA_ONLY_SCOPE ) == 0 )
ttl = 1;
while ( 1 )
{
if ((err = get_target(puas, pcScope, &use_da, &sin)) != SLP_OK)
{
if ( err == SLP_SCOPE_NOT_SUPPORTED )
return SLP_OK;
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DEBUG,"get_reply: Could not get to-address for request", SLP_PARSE_ERROR);
}
if (iSize >= iMTU)
{
if (use_da == 0)
{
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DEBUG,"get_reply: Request overflowed MTU", SLP_BUFFER_OVERFLOW);
}
else
{
pcRecvBuf = NULL;
if ((err=get_tcp_result(pcSend,iSize, sin,&pcRecvBuf,&len))!= SLP_OK)
{
SLPFree(pcRecvBuf);
pcRecvBuf = NULL;
LOG_SLP_ERROR_AND_RETURN(SLP_LOG_DEBUG,"get_reply of overflowed result failed",err);
}
err = process_reply(pcSend, pcRecvBuf, len, &iLast, pvUser, (SLPHandle) puas, pvCallback,cbt);
last_one(err, iLast,pvUser,(SLPHandle)puas,pvCallback,cbt);
SLPFree(pcRecvBuf);
pcRecvBuf = NULL;
return err;
}
}
if (use_da)
{
int tcp_used = 0;
SLP_LOG( SLP_LOG_DEBUG, "get_reply connecting to DA [%s]",inet_ntoa(sin.sin_addr));
pcRecvBuf = (char*)malloc(RECVMTU);
if ((err = get_unicast_result(
MAX_UNICAST_WAIT,
puas->sdSend,
pcSend,
iSize,
pcRecvBuf,
RECVMTU,
&len,
sin)) != SLP_OK)
{
SLP_LOG( SLP_LOG_DA, "get_reply could not get_da_results from [%s]...: %s",inet_ntoa(sin.sin_addr), slperror(err) );
dat_strike_da( NULL, sin );
SLPFree(pcRecvBuf);
pcRecvBuf = NULL;
continue; }
else
{
if (GETFLAGS(pcRecvBuf) & OVERFLOWFLAG)
{
SLPFree(pcRecvBuf);
pcRecvBuf = NULL;
sin.sin_port = htons(SLP_PORT);
err=get_tcp_result(pcSend,iSize, sin, &pcRecvBuf,&len);
if (err != SLP_OK)
err=get_tcp_result(pcSend,iSize, sin, &pcRecvBuf,&len);
if (err != SLP_OK)
{
SLPFree(pcRecvBuf);
pcRecvBuf = NULL;
SLP_LOG(SLP_LOG_DEBUG, "get_reply overflow, tcp failed from [%s] when getting a reply...: %s",inet_ntoa(sin.sin_addr), slperror(err));
dat_strike_da( NULL, sin );
continue; }
else
SLP_LOG( SLP_LOG_DEBUG, "get_tcp_result, received %ld bytes from [%s]", len, inet_ntoa(sin.sin_addr) );
tcp_used = 1;
}
else
SLP_LOG( SLP_LOG_DEBUG, "get_unicast_result, received %ld bytes from [%s]", len, inet_ntoa(sin.sin_addr) );
}
if ( !err )
err = process_reply(pcSend, pcRecvBuf, len, &iLast, pvUser, (SLPHandle) puas, pvCallback, cbt);
if ( pcRecvBuf );
{
SLPFree(pcRecvBuf);
pcRecvBuf = NULL;
}
if ( !err )
last_one(err, ALL_DONE,pvUser,(SLPHandle)puas,pvCallback,cbt);
return err;
}
else
{
SETFLAGS( pcSend,(unsigned char) MCASTFLAG);
err = get_converge_result(
multicastMaximumWait,
puas->sdSend,
puas->pcSendBuf,
iSize,
puas->pcRecvBuf,
RECVMTU,
sin,
ttl,
pvUser,
(SLPHandle) puas,
pvCallback,
cbt);
return err;
}
}
}