/*********************************************************************** * * 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 * ***********************************************************************/ //===[ 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() --*/ //========================================================================= //=========================================================================