391 lines
12 KiB
C++
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 & );
|
|
};
|
|
|