libqmi-qmuxd/gobi-api/GobiAPI_2013-07-31-1347/Core/QMIBuffers.h

391 lines
12 KiB
C++

/*===========================================================================
FILE:
QMIBuffers.h
DESCRIPTION:
QMI service protocol related structures and affliated methods
PUBLIC CLASSES AND METHODS:
sQMUXHeader
sQMIControlRawTransactionHeader
sQMIServiceRawTransactionHeader
sQMIRawMessageHeader
sQMIRawContentHeader
sQMIServiceBuffer
Copyright (c) 2013, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
===========================================================================*/
//---------------------------------------------------------------------------
// Pragmas
//---------------------------------------------------------------------------
#pragma once
//---------------------------------------------------------------------------
// Include Files
//---------------------------------------------------------------------------
#include "ProtocolBuffer.h"
#include "QMIEnum.h"
#include <map>
#include <vector>
//---------------------------------------------------------------------------
// Definitions
//---------------------------------------------------------------------------
// QMI maximum buffer size (cannot be larger than MAX_SHARED_BUFFER_SIZE)
const ULONG QMI_MAX_BUFFER_SIZE = MAX_SHARED_BUFFER_SIZE;
// Content ID for mandatory result TLV
const ULONG QMI_TLV_ID_RESULT = 2;
/*===========================================================================
METHOD:
MapQMIServiceToProtocol (Inline Method)
DESCRIPTION:
Map QMI service type (eQMIService) and direction to a protocol type
(eProtocolType)
PARAMETERS:
serviceType [ I ] - Enum value being mapped
bTransmission [ I ] - Is this a transmission (TX vs. RX)?
RETURN VALUE:
eProtocolType
===========================================================================*/
inline eProtocolType MapQMIServiceToProtocol(
eQMIService serviceType,
bool bTransmission = true )
{
eProtocolType pt = ePROTOCOL_ENUM_BEGIN;
if (IsValid( serviceType ) == false)
{
return pt;
}
DWORD tmp = ((DWORD)serviceType * 2) + (DWORD)ePROTOCOL_QMI_CTL_RX;
if (bTransmission == true)
{
tmp++;
}
if (IsQMIProtocol( (eProtocolType)tmp ) == true)
{
pt = (eProtocolType)tmp;
}
return pt;
};
/*===========================================================================
METHOD:
MapProtocolToQMIService (Inline Method)
DESCRIPTION:
Map protocol type (eProtocolType) to QMI service type (eQMIService)
PARAMETERS:
protocolType [ I ] - Enum value being mapped
RETURN VALUE:
bool
===========================================================================*/
inline eQMIService MapProtocolToQMIService( eProtocolType protocolType )
{
eQMIService st = eQMI_SVC_ENUM_BEGIN;
if (IsQMIProtocol( protocolType ) == false)
{
return st;
}
DWORD tmp = ((DWORD)protocolType - (DWORD)ePROTOCOL_QMI_CTL_RX) / 2;
if (IsValid( (eQMIService)tmp ) == true)
{
st = (eQMIService)tmp;
}
return st;
};
//---------------------------------------------------------------------------
// Pragmas (pack structs)
//---------------------------------------------------------------------------
#pragma pack( push, 1 )
/*=========================================================================*/
// Struct sQMUXHeader
// Struct to represent a QMUX transaction header (raw)
/*=========================================================================*/
struct sQMUXHeader
{
public:
WORD mLength;
BYTE mFlags;
BYTE mServiceType;
BYTE mClientID;
};
/*=========================================================================*/
// Struct sQMIControlRawTransactionHeader
// Struct to represent a QMI control transaction header (raw)
/*=========================================================================*/
struct sQMIControlRawTransactionHeader
{
public:
BYTE mResponse : 1; // Is this a response transaction?
BYTE mIndication : 1; // Is this an indication transaction?
BYTE mReserved : 6;
BYTE mTransactionID; // Transaction ID
};
/*=========================================================================*/
// Struct sQMIServiceRawTransactionHeader
// Struct to represent a QMI service transaction header (raw)
/*=========================================================================*/
struct sQMIServiceRawTransactionHeader
{
public:
BYTE mCompound : 1; // Is this a compound transaction?
BYTE mResponse : 1; // Is this a response transaction?
BYTE mIndication : 1; // Is this an indication transaction?
BYTE mReserved : 5;
WORD mTransactionID; // Transaction ID
};
/*=========================================================================*/
// Struct sQMIRawMessageHeader
// Struct to represent a QMI (control/service) message header (raw)
/*=========================================================================*/
struct sQMIRawMessageHeader
{
public:
WORD mMessageID; // Message ID
WORD mLength; // Length of message (not including this header)
};
/*=========================================================================*/
// Struct sQMIRawContentHeader
// Struct to represent a QMI (control/service) content
// (i.e Type/Length/Value, TLV) header (raw)
/*=========================================================================*/
struct sQMIRawContentHeader
{
public:
BYTE mTypeID; // Content type ID
WORD mLength; // Content length (not including this header)
};
//---------------------------------------------------------------------------
// Pragmas
//---------------------------------------------------------------------------
#pragma pack( pop )
/*=========================================================================*/
// Struct sQMIServiceBuffer
// Struct to represent a QMI service channel request/response/indication
// (shared buffer)
/*=========================================================================*/
struct sQMIServiceBuffer : public sProtocolBuffer
{
public:
// Constructor
sQMIServiceBuffer( sSharedBuffer * pBuffer );
// Destructor
virtual ~sQMIServiceBuffer();
// (Inline) Is this a request?
bool IsRequest() const
{
bool bRequest = false;
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
if (pHdr != 0)
{
bRequest = (pHdr->mResponse == 0 && pHdr->mIndication == 0);
}
return bRequest;
};
// (Inline) Is this a response?
bool IsResponse() const
{
bool bResponse = false;
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
if (pHdr != 0)
{
bResponse = (pHdr->mResponse == 1);
}
return bResponse;
};
// (Inline) Is this an indication?
bool IsIndication() const
{
bool bInd = false;
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
if (pHdr != 0)
{
bInd = (pHdr->mIndication == 1);
}
return bInd;
};
// (Inline) Return raw header
const sQMIServiceRawTransactionHeader * GetHeader() const
{
const sQMIServiceRawTransactionHeader * pHdr = 0;
if (IsValid() == true)
{
pHdr = (const sQMIServiceRawTransactionHeader *)GetBuffer();
}
return pHdr;
};
// (Inline) Return the message ID
ULONG GetMessageID() const
{
ULONG id = (ULONG)0xffffffff;
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
if (pHdr != 0)
{
pHdr++;
const sQMIRawMessageHeader * pMsgHdr = 0;
pMsgHdr = (sQMIRawMessageHeader *)pHdr;
id = pMsgHdr->mMessageID;
}
return id;
};
// (Inline) Return the transaction ID
WORD GetTransactionID() const
{
WORD id = (WORD)INVALID_QMI_TRANSACTION_ID;
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
if (pHdr != 0)
{
id = pHdr->mTransactionID;
}
return id;
};
// (Inline) Return raw content array
const sQMIRawContentHeader * GetRawContents( ULONG & contentLen ) const
{
// Assume failure
ULONG len = 0;
const sQMIRawContentHeader * pRaw = 0;
const sQMIServiceRawTransactionHeader * pHdr = GetHeader();
if (pHdr != 0)
{
pHdr++;
const sQMIRawMessageHeader * pMsgHdr = 0;
pMsgHdr = (sQMIRawMessageHeader *)pHdr;
len = pMsgHdr->mLength;
pMsgHdr++;
if (len > 0)
{
pRaw = (const sQMIRawContentHeader *)pMsgHdr;
}
}
contentLen = len;
return pRaw;
};
// (Inline) Return content structures
std::map <ULONG, const sQMIRawContentHeader *> GetContents() const
{
return mContents;
};
// Return contents of mandatory result content
bool GetResult(
ULONG & returnCode,
ULONG & errorCode );
// Build a QMI request/response/indication
static sSharedBuffer * BuildBuffer(
eQMIService serviceType,
WORD msgID,
bool bResponse = false,
bool bIndication = false,
const BYTE * pData = 0,
ULONG dataLen = 0 );
protected:
// QMI protocol server has to be able to set the transaction ID
friend class cQMIProtocolServer;
// Set the transaction ID
void SetTransactionID( WORD tid ) const
{
if (tid == (WORD)INVALID_QMI_TRANSACTION_ID || IsValid() == false)
{
return;
}
sQMIServiceRawTransactionHeader * pHdr = 0;
pHdr = (sQMIServiceRawTransactionHeader *)GetHeader();
if (pHdr != 0)
{
pHdr->mTransactionID = tid;
}
};
// Is this QMI request/response/indication packet valid?
virtual bool Validate();
/* Content TLV structures (indexed by type ID) */
std::map <ULONG, const sQMIRawContentHeader *> mContents;
private:
// Prevent 'upcopying'
sQMIServiceBuffer( const sProtocolBuffer & );
sQMIServiceBuffer & operator = ( const sProtocolBuffer & );
};