// **************************************************************************
// $Id: clientmsgtranslator.cc,v 1.11 2007/03/06 21:29:26 cnepveu Exp $
//
// Copyright (c) 2007 Hexago Inc. All rights reserved.
//
// LICENSE NOTICE: You may use and modify this source code only if you
// have executed a valid license agreement with Hexago Inc. granting
// you the right to do so, the said license agreement governing such
// use and modifications. Copyright or other intellectual property
// notices are not to be removed from the source code.
//
// Description:
// Implementation of the ClientMsgTranslator class.
//
// Author: Charles Nepveu
//
// Creation Date: November 2006
// __________________________________________________________________________
// **************************************************************************
#include <gw6cmessaging/clientmsgtranslator.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#ifdef WIN32
#define strdup _strdup
#endif
namespace gw6cmessaging
{
// --------------------------------------------------------------------------
// Function : ClientMsgTranslator constructor
//
// Description:
// Will initialize a new ClientMsgTranslator object.
//
// Arguments: (none)
//
// Return values: (N/A)
//
// --------------------------------------------------------------------------
ClientMsgTranslator::ClientMsgTranslator( void ) :
MessageProcessor()
{
// Enable message processing.
MessageProcessor::m_eProcessorState = STATE_ENABLED;
}
// --------------------------------------------------------------------------
// Function : Gw6cMsgClientReceiver destructor
//
// Description:
// Will clean-up space allocated during object lifetime.
//
// Arguments: (none)
//
// Return values: (N/A)
//
// --------------------------------------------------------------------------
ClientMsgTranslator::~ClientMsgTranslator( void )
{
}
// --------------------------------------------------------------------------
// Function : ProcessMessage
//
// Description:
// Will verify the message type and call the proper translator.
// NOTE: Try not to do any lengthy operations here, because we're executing
// in the receiver thread.
//
// Arguments:
// pMsg: Message* [IN], The message to process.
//
// Return values:
// GW6CM_UIS__NOERROR: Successful operation.
// GW6CM_UIS_MESSAGENOTIMPL: Message not implemented.
// GW6CM_UIS_MSGPROCDISABLED: Message processing is disabled.
// <any other error message>
//
// --------------------------------------------------------------------------
error_t ClientMsgTranslator::ProcessMessage( Message* pMsg )
{
error_t retCode;
assert( pMsg );
// Process messages only if the message processor is enabled.
if( m_eProcessorState == STATE_ENABLED )
{
// -------------------------------------
// Verify what kind of message this is.
// -------------------------------------
switch( pMsg->msg.header._msgid )
{
case MESSAGEID_STATUSINFO:
retCode = TranslateStatusInfo( pMsg->msg._data, pMsg->msg.header._datalen );
break;
case MESSAGEID_TUNNELINFO:
retCode = TranslateTunnelInfo( pMsg->msg._data, pMsg->msg.header._datalen );
break;
case MESSAGEID_BROKERLIST:
retCode = TranslateBrokerList( pMsg->msg._data, pMsg->msg.header._datalen );
break;
case MESSAGEID_HAP6STATUSINFO:
retCode = TranslateHAP6StatusInfo( pMsg->msg._data, pMsg->msg.header._datalen );
break;
default:
retCode = GW6CM_UIS_MESSAGENOTIMPL; // Unknown / invalid message.
break;
}
}
else
retCode = GW6CM_UIS_MSGPROCDISABLED;
// Return completion status.
return retCode;
}
// --------------------------------------------------------------------------
// Function : TranslateStatusInfo
//
// Description:
// Will extract the status information from the byte buffer and invoke the
// handler.
//
// Arguments:
// pData: BYTE* [IN], The raw data.
// nDataLen: WORD [IN], The length of the raw data.
//
// Return values:
// GW6CM_UIS__NOERROR: Successful operation.
// any other value on error.
//
// --------------------------------------------------------------------------
error_t ClientMsgTranslator::TranslateStatusInfo( BYTE* pData, const WORD nDataLen )
{
Gw6cStatusInfo statusInfo;
WORD nCursor = 0;
error_t retCode;
// ----------------------------------------------
// Extract the status info from the byte buffer.
// ----------------------------------------------
memcpy( (void*)&(statusInfo.eStatus), (void*)pData, sizeof(Gw6cCliStatus) );
nCursor += sizeof(Gw6cCliStatus);
// Extract message sent along status info.
memcpy( (void*)&(statusInfo.nStatus), (void*)(pData + nCursor), sizeof(statusInfo.nStatus) );
nCursor += sizeof(statusInfo.nStatus);
// -----------------------------------------------------------------------
// Sanity check. Verify that the bytes of data we extracted match that of
// what was expected.
// -----------------------------------------------------------------------
assert( nCursor == nDataLen );
// ---------------------------------
// Invoke derived function handler.
// ---------------------------------
retCode = Recv_StatusInfo( &statusInfo );
// Return completion code.
return retCode;
}
// --------------------------------------------------------------------------
// Function : TranslateTunnelInfo
//
// Description:
// Will extract the tunnel information from the byte buffer and invoke the
// handler.
//
// Arguments:
// pData: BYTE* [IN], The raw data.
// nDataLen: WORD [IN], The length of the raw data.
//
// Return values:
// GW6CM_UIS__NOERROR: Successful operation.
// any other value on error.
//
// --------------------------------------------------------------------------
error_t ClientMsgTranslator::TranslateTunnelInfo( BYTE* pData, const WORD nDataLen )
{
Gw6cTunnelInfo tunnelInfo;
WORD nCursor = 0;
error_t retCode;
// -- D A T A E X T R A C T I O N --
// Extract broker name from data buffer.
tunnelInfo.szBrokerName = strdup( (char*)(pData + nCursor) );
nCursor += strlen( (char*)(pData + nCursor) ) + 1;
// Extract tunnel type from data buffer.
memcpy( (void*)&(tunnelInfo.eTunnelType), pData + nCursor, sizeof(Gw6cTunnelType) );
nCursor += sizeof(Gw6cTunnelType);
// Extract Local tunnel endpoint IPv4 address from data buffer.
tunnelInfo.szIPV4AddrLocalEndpoint = strdup( (char*)(pData + nCursor) );
nCursor += strlen( (char*)(pData + nCursor) ) + 1;
// Extract Local tunnel endpoint IPv6 address from data buffer.
tunnelInfo.szIPV6AddrLocalEndpoint = strdup( (char*)(pData + nCursor) );
nCursor += strlen( (char*)(pData + nCursor) ) + 1;
// Extract Remote tunnel endpoint IPv4 address from data buffer.
tunnelInfo.szIPV4AddrRemoteEndpoint = strdup( (char*)(pData + nCursor) );
nCursor += strlen( (char*)(pData + nCursor) ) + 1;
// Extract Remote tunnel endpoint IPv6 address from data buffer.
tunnelInfo.szIPV6AddrRemoteEndpoint = strdup( (char*)(pData + nCursor) );
nCursor += strlen( (char*)(pData + nCursor) ) + 1;
// Extract The delegated prefix from data buffer.
tunnelInfo.szDelegatedPrefix = strdup( (char*)(pData + nCursor) );
nCursor += strlen( (char*)(pData + nCursor) ) + 1;
// Extract The delegated user domain from data buffer.
tunnelInfo.szUserDomain = strdup( (char*)(pData + nCursor) );
nCursor += strlen( (char*)(pData + nCursor) ) + 1;
// Extract tunnel uptime from data buffer.
memcpy( (void*)&(tunnelInfo.tunnelUpTime), pData + nCursor, sizeof(time_t) );
nCursor += sizeof(time_t);
// -----------------------------------------------------------------------
// Sanity check. Verify that the bytes of data we extracted match that of
// what was expected.
// -----------------------------------------------------------------------
assert( nCursor == nDataLen );
// ---------------------------------
// Invoke derived function handler.
// ---------------------------------
retCode = Recv_TunnelInfo( &tunnelInfo );
// -----------------------------------------------
// Clean up allocated memory used for extraction.
// -----------------------------------------------
free( tunnelInfo.szBrokerName );
free( tunnelInfo.szIPV4AddrLocalEndpoint );
free( tunnelInfo.szIPV6AddrLocalEndpoint );
free( tunnelInfo.szIPV4AddrRemoteEndpoint );
free( tunnelInfo.szIPV6AddrRemoteEndpoint );
free( tunnelInfo.szDelegatedPrefix );
free( tunnelInfo.szUserDomain );
// Return completion code.
return retCode;
}
// --------------------------------------------------------------------------
// Function : TranslateBrokerList
//
// Description:
// Will extract the broker list from the byte buffer and invoke the
// handler.
//
// Arguments:
// pData: BYTE* [IN], The raw data.
// nDataLen: WORD [IN], The length of the raw data.
//
// Return values:
// GW6CM_UIS__NOERROR: Successful operation.
// any other value on error.
//
// --------------------------------------------------------------------------
Gw6cBrokerList* BuildBrokerList( BYTE* pData, const size_t nDataLen, size_t& nCursor )
{
if( nCursor >= nDataLen ) // End condition.
return NULL;
Gw6cBrokerList* pList = new Gw6cBrokerList;
size_t nNameLen = strlen( (const char*)pData ) + 1;
nCursor += nNameLen;
pList->szAddress = strdup( (const char*)pData );
memcpy( (void*)&(pList->nDistance), pData + nCursor, sizeof(int) );
nCursor += sizeof(int);
pList->next = BuildBrokerList( pData + nNameLen + sizeof(int), nDataLen, nCursor );
return pList;
}
// --------------------------------------------------------------------------
error_t ClientMsgTranslator::TranslateBrokerList( BYTE* pData, const WORD nDataLen )
{
Gw6cBrokerList* pList;
size_t nCursor = 0;
error_t retCode;
// ------------------------------------------
// Extract broker list from the byte buffer.
// ------------------------------------------
pList = BuildBrokerList( pData, nDataLen, nCursor );
// -----------------------------------------------------------------------
// Sanity check. Verify that the bytes of data we extracted match that of
// what was expected.
// -----------------------------------------------------------------------
assert( nCursor == nDataLen );
// ---------------------------------
// Invoke derived function handler.
// ---------------------------------
retCode = Recv_BrokerList( pList );
// -----------------------------------------------
// Clean up allocated memory used for extraction.
// -----------------------------------------------
Gw6cBrokerList* pListLast = NULL;
for(; pList!=NULL; pList = pList->next )
{
if( pListLast != NULL ) delete pListLast;
free( pList->szAddress );
pListLast = pList;
}
if( pListLast != NULL ) delete pListLast;
// Return completion status.
return retCode;
}
// --------------------------------------------------------------------------
// Function : TranslateHAP6StatusInfo
//
// Description:
// Will extract the HAP6 Status Info from the byte buffer and invoke the
// handler.
//
// Arguments:
// pData: BYTE* [IN], The raw data.
// nDataLen: WORD [IN], The length of the raw data.
//
// Return values:
// GW6CM_UIS__NOERROR: Successful operation.
// any other value on error.
//
// --------------------------------------------------------------------------
PMAPPING_STATUS BuildMappingStatuses( BYTE* pData, const size_t nDataLen, size_t& nCursor )
{
if( nCursor >= nDataLen ) // End condition.
return NULL;
PMAPPING_STATUS pMappingStatus = new MAPPING_STATUS;
// Extract Device Name
pMappingStatus->device_name = strdup( (const char*)pData );
size_t nNameLen = strlen( (const char*)pData ) + 1;
nCursor += nNameLen;
// Extract Device mapping status
memcpy( (void*)&(pMappingStatus->mapping_status), pData + nNameLen, sizeof(HAP6DevMapStts) );
nCursor += sizeof(int);
// Extract the next.
pMappingStatus->next = BuildMappingStatuses( pData + nNameLen + sizeof(int), nDataLen, nCursor );
return pMappingStatus;
}
void FreeMappingStatus( PMAPPING_STATUS mapStat )
{
if( mapStat != NULL )
{
FreeMappingStatus( mapStat->next );
assert( mapStat->device_name != NULL );
delete [] mapStat->device_name;
delete mapStat;
}
}
error_t ClientMsgTranslator::TranslateHAP6StatusInfo( BYTE* pData, const WORD nDataLen )
{
HAP6StatusInfo statusInfo;
size_t nCursor = 0;
error_t retCode;
// -- D A T A E X T R A C T I O N --
// Extract the proxy status from data buffer.
memcpy( (void*)&(statusInfo.hap6_proxy_status), pData + nCursor, sizeof(HAP6FeatStts) );
nCursor += sizeof(HAP6FeatStts);
// Extract the web status from data buffer.
memcpy( (void*)&(statusInfo.hap6_web_status), pData + nCursor, sizeof(HAP6FeatStts) );
nCursor += sizeof(HAP6FeatStts);
// Extract the Device Mapping Module status from data buffer.
memcpy( (void*)&(statusInfo.hap6_devmapmod_status), pData + nCursor, sizeof(HAP6FeatStts) );
nCursor += sizeof(HAP6FeatStts);
// Extract the device mapping statuses. Unserialize the linked list.
statusInfo.hap6_devmap_statuses = BuildMappingStatuses( pData + nCursor, nDataLen, nCursor );
// -----------------------------------------------------------------------
// Sanity check. Verify that the bytes of data we extracted match that of
// what was expected.
// -----------------------------------------------------------------------
assert( nCursor == nDataLen );
// ---------------------------------
// Invoke derived function handler.
// ---------------------------------
retCode = Recv_HAP6StatusInfo( &statusInfo );
// -----------------------------------------------
// Clean up allocated memory used for extraction.
// -----------------------------------------------
FreeMappingStatus( statusInfo.hap6_devmap_statuses );
// Return completion code.
return retCode;
}
} // namespace
syntax highlighted by Code2HTML, v. 0.9.1