CASA/CASA-auth-token/server/utilities/IpcLibs/linux/common/channelproto.cpp

429 lines
12 KiB
C++

/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
//===[ Include files ]=====================================================
#include "ipcint.h"
//===[ External data ]=====================================================
//===[ External prototypes ]===============================================
//===[ Manifest constants ]================================================
//===[ Type definitions ]==================================================
//===[ Function prototypes ]===============================================
//===[ Global variables ]==================================================
// Channel Packet Types
string DataCarrierTypeTemplate = "TypeXX";
string ReqDataCarrierType = "Type01";
string ReqErrorCarrierType = "Type02";
// Channel Packet Headers
string ReqIdHdr = "ReqIdHdr =";
string PayloadLengthHdr = "PayloadLength =";
// Req Data Pkt Hdr Template
string ReqDataPktHdrTemplate = "Type01\r\nReqIdHdr =XXXXXXXX\r\nPayloadLength =XXXXXXXX\r\n\r\n";
// Req Error Pkt Hdr Template
string ReqErrorPktHdrTemplate = "Type02\r\nReqIdHdr =XXXXXXXX\r\nPayloadLength =XXXXXXXX\r\n\r\n";
//++=======================================================================
int
ChannelProto::buildReqDataPktHdr(
uint32_t reqId,
int32_t payloadLength,
char *pPktHdr)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes: pPktHdr must point to a buffer of size ReqDataPktHdrTemple.length().
//
// L2
//=======================================================================--
{
int retStatus = -1;
DbgTrace(1, "ChannelProto::buildReqDataPktHdr- Start\n", 0);
try {
// - Req Data Packet Header Format -
//
// ReqDataCarrierType
// ReqIdHdr value (value format=%08X)
// PayloadLengthHdr value (value format=%08X)
//
// Setup the necessary value strings
char wrkBuffer[10];
sprintf(wrkBuffer, "%08X", reqId);
string reqIdValue = wrkBuffer;
sprintf(wrkBuffer, "%08X", payloadLength);
string payloadLengthValue = wrkBuffer;
// Format the header.
char* pCurr = pPktHdr;
memcpy(pCurr, ReqDataCarrierType.c_str(), ReqDataCarrierType.length());
pCurr += ReqDataCarrierType.length();
memcpy(pCurr, "\r\n", 2);
pCurr += 2;
memcpy(pCurr, ReqIdHdr.c_str(), ReqIdHdr.length());
pCurr += ReqIdHdr.length();
memcpy(pCurr, reqIdValue.c_str(), reqIdValue.length());
pCurr += reqIdValue.length();
memcpy(pCurr, "\r\n", 2);
pCurr += 2;
memcpy(pCurr, PayloadLengthHdr.c_str(), PayloadLengthHdr.length());
pCurr += PayloadLengthHdr.length();
memcpy(pCurr, payloadLengthValue.c_str(), payloadLengthValue.length());
pCurr += payloadLengthValue.length();
memcpy(pCurr, "\r\n\r\n", 4);
// Success
retStatus = 0;
}
catch (...) {
DbgTrace(0, "ChannelProto::buildReqDataPktHdr- Exception caught while creating header\n", 0);
}
DbgTrace(1, "ChannelProto::buildReqDataPktHdr- End, retStatus = %0X\n", retStatus);
return retStatus;
} /*-- ChannelProto::buildReqDataPktHdr() --*/
//++=======================================================================
int
ChannelProto::buildReqErrorPktHdr(
uint32_t reqId,
int32_t payloadLength,
char *pPktHdr)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes: pPktHdr must point to a buffer of size ReqErrorPktHdrTemple.length().
//
// L2
//=======================================================================--
{
int retStatus = -1;
DbgTrace(1, "ChannelProto::buildReqErrorPktHdr- Start\n", 0);
try {
// - Req Error Packet Header Format -
//
// ReqErrorCarrierType
// ReqIdHdr value (value format=%08X)
// PayloadLengthHdr value (value format=%08X)
//
// Setup the necessary value strings
char wrkBuffer[10];
sprintf(wrkBuffer, "%08X", reqId);
string reqIdValue = wrkBuffer;
sprintf(wrkBuffer, "%08X", payloadLength);
string payloadLengthValue = wrkBuffer;
// Format the header.
char* pCurr = pPktHdr;
memcpy(pCurr, ReqErrorCarrierType.c_str(), ReqErrorCarrierType.length());
pCurr += ReqErrorCarrierType.length();
memcpy(pCurr, "\r\n", 2);
pCurr += 2;
memcpy(pCurr, ReqIdHdr.c_str(), ReqIdHdr.length());
pCurr += ReqIdHdr.length();
memcpy(pCurr, reqIdValue.c_str(), reqIdValue.length());
pCurr += reqIdValue.length();
memcpy(pCurr, "\r\n", 2);
pCurr += 2;
memcpy(pCurr, PayloadLengthHdr.c_str(), PayloadLengthHdr.length());
pCurr += PayloadLengthHdr.length();
memcpy(pCurr, payloadLengthValue.c_str(), payloadLengthValue.length());
pCurr += payloadLengthValue.length();
memcpy(pCurr, "\r\n\r\n", 4);
// Success
retStatus = 0;
}
catch (...) {
DbgTrace(0, "ChannelProto::buildReqErrorPktHdr- Exception caught while creating header\n", 0);
}
DbgTrace(1, "ChannelProto::buildReqErrorPktHdr- End, retStatus = %0X\n", retStatus);
return retStatus;
} /*-- ChannelProto::buildReqErrorPktHdr() --*/
//++=======================================================================
ChannelProto::PacketTypes
ChannelProto::getPktType(
char &buff,
int hdrLength)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
PacketTypes packetType = UnknownPacketType;
DbgTrace(1, "ChannelProto::getPktType- Start\n", 0);
// Find the end of the Channel Packet Type
char *pCurr = &buff;
int bytesLeft = hdrLength;
bool endFound = false;
while (bytesLeft)
{
if (*pCurr == '\r')
{
endFound = true;
break;
}
pCurr ++;
bytesLeft --;
}
if (endFound)
{
// Found the end of the Channel Packet Type, now
// calculate its length.
int channelPktTypeLength = pCurr - &buff;
// Now start comparing
if (channelPktTypeLength == ReqDataCarrierType.length()
&& !memcmp(&buff, ReqDataCarrierType.c_str(), channelPktTypeLength))
{
// The type is Channel Req Data Carrier
packetType = ReqDataCarrierPacketType;
}
else if (channelPktTypeLength == ReqErrorCarrierType.length()
&& !memcmp(&buff, ReqErrorCarrierType.c_str(), channelPktTypeLength))
{
// The type is Channel Req Error Carrier
packetType = ReqErrorCarrierPacketType;
}
else
{
DbgTrace(0, "ChannelProto::getPktType- No match found\n", 0);
}
}
else
{
DbgTrace(0, "ChannelProto::getPktType- Invalid header\n", 0);
}
DbgTrace(1, "ChannelProto::getPktType- End, type = %d\n", packetType);
return packetType;
} /*-- ChannelProto::getPktType() --*/
//++=======================================================================
bool
ChannelProto::getReqIdAndPayloadLength(
char *pBuff,
int hdrLength,
uint32_t *pReqId,
int32_t *pPayloadLength)
//
// Arguments:
//
// Returns:
//
// Abstract:
//
// Notes:
//
// L2
//=======================================================================--
{
bool reqIdObtained = false;
bool payloadLengthObtained = false;
DbgTrace(1, "ChannelProto::getReqIdAndPayloadLength- Start\n", 0);
char *pCurr = pBuff;
char *pChannelHdr = NULL;
int bytesLeft = hdrLength;
// Skip the Channel Packet Type which should always
// be the first header.
while (bytesLeft >= 2)
{
if (*pCurr == '\r'
&& *(pCurr+1) == '\n')
{
// Found the end of the channel packet type
pCurr += 2;
bytesLeft -= 2;
break;
}
else
{
pCurr ++;
bytesLeft --;
}
}
// Start processing Channel Packet Headers
pChannelHdr = pCurr;
while (bytesLeft >= 2
&& (!reqIdObtained || !payloadLengthObtained))
{
if (*pCurr == '\r'
&& *(pCurr+1) == '\n')
{
// Found the end of the current channel header
pCurr += 2;
bytesLeft -= 2;
// Check if the line is empty or if it contained a
// channel header.
if ((pCurr - pChannelHdr) == 2)
{
// This was an empty line, which means that
// we reached the end of the channel packet header.
break;
}
else
{
// Check if the header is the Req Id Hdr
if (!reqIdObtained && (pCurr - pChannelHdr) > ReqIdHdr.length()
&& !memcmp(pChannelHdr, ReqIdHdr.c_str(), ReqIdHdr.length()))
{
// We found the Req Id Hdr, get the value.
char *pValue = pChannelHdr + ReqIdHdr.length();
// Temporarily NULL terminate the value
*(pCurr-2) = '\0';
// Convert the value to hex
errno = 0;
unsigned long int value = strtoul(pValue, NULL, 16);
if (errno != 0
|| value > UINT32_MAX)
{
DbgTrace(0, "ChannelProto::getReqIdAndPayloadLength- Invalid reqId value, %s\n", pValue);
break;
}
// Use the value
*pReqId = (uint32_t) value;
// Undo the damage that we did
*(pCurr-2) = '\r';
// Remember that the Req Id was obtained
reqIdObtained = true;
}
// Check if the header is the Payload Length Hdr
else if ((pCurr - pChannelHdr) > PayloadLengthHdr.length()
&& !memcmp(pChannelHdr, PayloadLengthHdr.c_str(), PayloadLengthHdr.length()))
{
// We found the Payload Length Hdr, get the value.
char *pValue = pChannelHdr + PayloadLengthHdr.length();
// Temporarily NULL terminate the value
*(pCurr-2) = '\0';
// Convert the value to hex
errno = 0;
long int value = strtol(pValue, NULL, 16);
if (errno != 0
|| value > INT32_MAX)
{
DbgTrace(0, "ChannelProto::getReqIdAndPayloadLength- Invalid payloadLength value, %s\n", pValue);
break;
}
// Use the value
*pPayloadLength = (int32_t) value;
// Undo the damage that we did
*(pCurr-2) = '\r';
// Remember that the Payload Lenght was obtained
payloadLengthObtained = true;
}
// Get set to process the next header
pChannelHdr = pCurr;
}
}
else
{
pCurr ++;
bytesLeft --;
}
}
DbgTrace(1,
"ChannelProto::getReqIdAndPayloadLength- End, retStatus = %0X\n",
reqIdObtained && payloadLengthObtained);
return reqIdObtained && payloadLengthObtained;
} /*-- ChannelProto::getReqIdAndPayloadLength() --*/
//=========================================================================
//=========================================================================