libqmi-qmuxd/gobi-api/GobiAPI_2013-07-31-1347/Gobi3000Translation/Gobi3000TranslationWMS.cpp

1121 lines
32 KiB
C++

/*===========================================================================
FILE:
Gobi3000TranslationWMS.cpp
DESCRIPTION:
QUALCOMM Translation for Gobi 3000 (WMS Service)
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.
==========================================================================*/
//---------------------------------------------------------------------------
// Include Files
//---------------------------------------------------------------------------
#include "Gobi3000Translation.h"
/*===========================================================================
METHOD:
PackDeleteSMS
DESCRIPTION:
This function deletes one or more SMS messages from device memory
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
storageType [ I ] - SMS message storage type
pMessageIndex [ I ] - (Optional) message index
pMessageTag [ I ] - (Optional) message tag
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackDeleteSMS(
ULONG * pOutLen,
BYTE * pOut,
ULONG storageType,
ULONG * pMessageIndex,
ULONG * pMessageTag )
{
// Validate arguments
if (pOut == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sWMSDeleteRequest_MemoryStorage );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// The SPC
sWMSDeleteRequest_MemoryStorage * pTLVx01;
pTLVx01 = (sWMSDeleteRequest_MemoryStorage*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mStorageType = (eQMIWMSStorageTypes)storageType;
offset += tlvx01Sz;
// Add the Message index, if specified
if (pMessageIndex != 0)
{
// Check size
WORD tlvx10Sz = sizeof( sWMSDeleteRequest_MessageIndex );
if (*pOutLen < offset + sizeof( sQMIRawContentHeader ) + tlvx10Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
pHeader = (sQMIRawContentHeader*)(pOut + offset);
pHeader->mTypeID = 0x10;
pHeader->mLength = tlvx10Sz;
offset += sizeof( sQMIRawContentHeader );
// The SPC
sWMSDeleteRequest_MessageIndex * pTLVx10;
pTLVx10 = (sWMSDeleteRequest_MessageIndex*)(pOut + offset);
memset( pTLVx10, 0, tlvx10Sz );
// Set the values
pTLVx10->mStorageIndex = *pMessageIndex;
offset += tlvx10Sz;
}
// Add the Message tag, if specified
if (pMessageTag != 0)
{
// Check size
WORD tlvx11Sz = sizeof( sWMSDeleteRequest_MessageTag );
if (*pOutLen < offset + sizeof( sQMIRawContentHeader ) + tlvx11Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
pHeader = (sQMIRawContentHeader*)(pOut + offset);
pHeader->mTypeID = 0x11;
pHeader->mLength = tlvx11Sz;
offset += sizeof( sQMIRawContentHeader );
// The SPC
sWMSDeleteRequest_MessageTag * pTLVx11;
pTLVx11 = (sWMSDeleteRequest_MessageTag*)(pOut + offset);
memset( pTLVx11, 0, tlvx11Sz );
// Set the values
pTLVx11->mMessageTag = (eQMIWMSMessageTags)*pMessageTag;
offset += tlvx11Sz;
}
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackGetSMSList
DESCRIPTION:
This function returns the list of SMS messages stored on the device
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
storageType [ I ] - SMS message storage type
pRequestedTag [ I ] - Message index
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackGetSMSList(
ULONG * pOutLen,
BYTE * pOut,
ULONG storageType,
ULONG * pRequestedTag )
{
// Validate arguments
if (pOut == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sWMSListMessagesRequest_MemoryStorage );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// The storage type
sWMSListMessagesRequest_MemoryStorage * pTLVx01;
pTLVx01 = (sWMSListMessagesRequest_MemoryStorage*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mStorageType = (eQMIWMSStorageTypes)storageType;
offset += tlvx01Sz;
// Add the Message tag, if specified
if (pRequestedTag != 0)
{
// Check size
WORD tlvx10Sz = sizeof( sWMSListMessagesRequest_MessageTag );
if (*pOutLen < offset + sizeof( sQMIRawContentHeader ) + tlvx10Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
pHeader = (sQMIRawContentHeader*)(pOut + offset);
pHeader->mTypeID = 0x10;
pHeader->mLength = tlvx10Sz;
offset += sizeof( sQMIRawContentHeader );
// The SPC
sWMSListMessagesRequest_MessageTag * pTLVx10;
pTLVx10 = (sWMSListMessagesRequest_MessageTag*)(pOut + offset);
memset( pTLVx10, 0, tlvx10Sz );
// Set the values
pTLVx10->mMessageTag = (eQMIWMSMessageTags)*pRequestedTag;
offset += tlvx10Sz;
}
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetSMSList
DESCRIPTION:
This function returns the list of SMS messages stored on the device
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pMessageListSize [I/O] - Upon input the maximum number of elements that the
message list array can contain. Upon successful
output the actual number of elements in the message
list array
pMessageList [ O ] - The message list array
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetSMSList(
ULONG inLen,
const BYTE * pIn,
ULONG * pMessageListSize,
BYTE * pMessageList )
{
// Validate arguments
if (pIn == 0 || pMessageListSize == 0
|| *pMessageListSize == 0 || pMessageList == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
ULONG maxMessageListSz = *pMessageListSize;
// Assume failure
*pMessageListSize = 0;
// Find the messages
const sWMSListMessagesResponse_MessageList * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sWMSListMessagesResponse_MessageList ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
ULONG messageListSz = pTLVx01->mNumberOfMessages;
if (messageListSz == 0)
{
// No stored messages, but not necessarily a failure
return eGOBI_ERR_NONE;
}
if (maxMessageListSz < messageListSz)
{
messageListSz = maxMessageListSz;
}
const sWMSListMessagesResponse_MessageList::sMessage * pMessages;
// Verify there is room for the array in the TLV
if (outLenx01 < sizeof( sWMSListMessagesResponse_MessageList )
+ sizeof( sWMSListMessagesResponse_MessageList::sMessage )
* messageListSz)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Align to the first array element
pMessages = (const sWMSListMessagesResponse_MessageList::sMessage *)
((const BYTE *)pTLVx01
+ sizeof( sWMSListMessagesResponse_MessageList ));
ULONG * pData = (ULONG *)pMessageList;
for (ULONG m = 0; m < messageListSz; m++)
{
*pData++ = pMessages->mStorageIndex;
*pData++ = pMessages->mMessageTag;
pMessages++;
}
*pMessageListSize = messageListSz;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackGetSMS
DESCRIPTION:
This function returns an SMS message from device memory
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
storageType [ I ] - SMS message storage type
messageIndex [ I ] - Message index
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackGetSMS(
ULONG * pOutLen,
BYTE * pOut,
ULONG storageType,
ULONG messageIndex )
{
// Validate arguments
if (pOut == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sWMSRawReadRequest_MessageIndex );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// The index
sWMSRawReadRequest_MessageIndex * pTLVx01;
pTLVx01 = (sWMSRawReadRequest_MessageIndex*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mStorageType = (eQMIWMSStorageTypes)storageType;
pTLVx01->mStorageIndex = messageIndex;
offset += tlvx01Sz;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetSMS
DESCRIPTION:
This function returns an SMS message from device memory
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pMessageTag [ O ] - Message tag
pMessageFormat [ O ] - Message format
pMessageSize [I/O] - Upon input the maximum number of bytes that can be
written to the message array. Upon successful
output the actual number of bytes written to the
message array
pMessage [ O ] - The message contents array
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetSMS(
ULONG inLen,
const BYTE * pIn,
ULONG * pMessageTag,
ULONG * pMessageFormat,
ULONG * pMessageSize,
BYTE * pMessage )
{
// Validate arguments
if (pIn == 0
|| pMessageTag == 0
|| pMessageFormat == 0
|| pMessageSize == 0
|| *pMessageSize == 0
|| pMessage == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
ULONG maxMessageSz = *pMessageSize;
// Assume failure
*pMessageSize = 0;
// Find the messages
const sWMSRawReadResponse_MessageData * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sWMSRawReadResponse_MessageData ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
*pMessageTag = pTLVx01->mMessageTag;
*pMessageFormat = pTLVx01->mMessageFormat;
ULONG messageSz = pTLVx01->mRawMessageLength;
if (messageSz == 0)
{
// No stored messages, but not necessarily a failure
return eGOBI_ERR_NONE;
}
if (messageSz > maxMessageSz)
{
messageSz = maxMessageSz;
}
// Verify there is room for the array in the TLV
if (outLenx01 < sizeof( sWMSRawReadResponse_MessageData ) + messageSz)
{
return eGOBI_ERR_MALFORMED_RSP;
}
memcpy( pMessage,
pTLVx01 + sizeof( sWMSRawReadResponse_MessageData ),
messageSz );
*pMessageSize = messageSz;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackModifySMSStatus
DESCRIPTION:
This function modifies the status of an SMS message saved in storage on
the device
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
storageType [ I ] - SMS message storage type
messageIndex [ I ] - Message index
messageTag [ I ] - Message tag
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackModifySMSStatus(
ULONG * pOutLen,
BYTE * pOut,
ULONG storageType,
ULONG messageIndex,
ULONG messageTag )
{
// Validate arguments
if (pOut == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sWMSModifyTagRequest_MessageTag );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// The index
sWMSModifyTagRequest_MessageTag * pTLVx01;
pTLVx01 = (sWMSModifyTagRequest_MessageTag*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mStorageType = (eQMIWMSStorageTypes)storageType;
pTLVx01->mStorageIndex = messageIndex;
pTLVx01->mMessageTag = (eQMIWMSMessageTags)messageTag;
offset += tlvx01Sz;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackSaveSMS
DESCRIPTION:
This function saves an SMS message to device memory
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
storageType [ I ] - SMS message storage type
messageFormat [ I ] - Message format
messageSize [ I ] - The length of the message contents in bytes
pMessage [ I ] - The message contents
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackSaveSMS(
ULONG * pOutLen,
BYTE * pOut,
ULONG storageType,
ULONG messageFormat,
ULONG messageSize,
BYTE * pMessage )
{
// Validate arguments
if (pOut == 0 || messageSize == 0 || pMessage == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sWMSRawWriteRequest_MessageData )
+ (WORD)messageSize;
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// The index
sWMSRawWriteRequest_MessageData * pTLVx01;
pTLVx01 = (sWMSRawWriteRequest_MessageData*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mStorageType = (eQMIWMSStorageTypes)storageType;
pTLVx01->mMessageFormat = (eQMIWMSMessageFormats)messageFormat;
pTLVx01->mRawMessageLength = (UINT16)messageSize;
offset += sizeof( sWMSRawWriteRequest_MessageData );
// Add the message
memcpy( (pOut + offset), pMessage, messageSize );
offset += messageSize;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseSaveSMS
DESCRIPTION:
This function saves an SMS message to device memory
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pMessageIndex [ O ] - The message index assigned by the device
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseSaveSMS(
ULONG inLen,
const BYTE * pIn,
ULONG * pMessageIndex )
{
// Validate arguments
if (pIn == 0 || pMessageIndex == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Find the messages
const sWMSRawWriteResponse_MessageIndex * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sWMSRawWriteResponse_MessageIndex ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
*pMessageIndex = pTLVx01->mStorageIndex;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackSendSMS
DESCRIPTION:
This function sends an SMS message for immediate over the air transmission
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
messageFormat [ I ] - Message format
messageSize [ I ] - The length of the message contents in bytes
pMessage [ I ] - The message contents
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackSendSMS(
ULONG * pOutLen,
BYTE * pOut,
ULONG messageFormat,
ULONG messageSize,
BYTE * pMessage )
{
// Validate arguments
if (pOut == 0 || messageSize == 0 || pMessage == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sWMSRawSendRequest_MessageData )
+ (WORD)messageSize;
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// The index
sWMSRawSendRequest_MessageData * pTLVx01;
pTLVx01 = (sWMSRawSendRequest_MessageData*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mMessageFormat = (eQMIWMSMessageFormats)messageFormat;
pTLVx01->mRawMessageLength = (UINT16)messageSize;
offset += sizeof( sWMSRawSendRequest_MessageData );
// Add the message
memcpy( (pOut + offset), pMessage, messageSize );
offset += messageSize;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseSendSMS
DESCRIPTION:
This function sends an SMS message for immediate over the air transmission
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pMessageFailureCode [ O ] - When the function fails due to an error sending
the message this parameter may contain the
message failure cause code (see 3GPP2 N.S0005
Section 6.5.2.125). If the cause code is not
provided then the value will be 0xFFFFFFFF
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseSendSMS(
ULONG inLen,
const BYTE * pIn,
ULONG * pMessageFailureCode )
{
// Validate arguments
if (pIn == 0 || pMessageFailureCode == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume we have no message failure cause code
*pMessageFailureCode = 0xffffffff;
// Check mandatory response
const sResultCode * pTLVx02;
ULONG outLenx02;
ULONG rc = GetTLV( inLen, pIn, 0x02, &outLenx02, (const BYTE **)&pTLVx02 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx02 < sizeof( sResultCode ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
if (pTLVx02->mQMIResult != eQMIResults_Success)
{
rc = pTLVx02->mQMIError + eGOBI_ERR_QMI_OFFSET;
}
if (rc != eGOBI_ERR_NONE)
{
// Check for the failure code (optional)
const sWMSRawSendResponse_CauseCode * pTLVx10;
ULONG outLenx10;
ULONG rc2 = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
if (rc2 == eGOBI_ERR_NONE)
{
if (outLenx10 < sizeof( sWMSRawSendResponse_CauseCode ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
*pMessageFailureCode = pTLVx10->mCauseCode;
}
}
return rc;
}
/*===========================================================================
METHOD:
ParseGetSMSCAddress
DESCRIPTION:
This function returns the SMS center address
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
addressSize [ I ] - The maximum number of characters (including NULL
terminator) that the SMS center address array
can contain
pSMSCAddress [ O ] - The SMS center address represented as a NULL
terminated string
typeSize [ I ] - The maximum number of characters (including NULL
terminator) that the SMS center address type array
can contain
pSMSCType [ O ] - The SMS center address type represented as a NULL
terminated string
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetSMSCAddress(
ULONG inLen,
const BYTE * pIn,
BYTE addressSize,
CHAR * pSMSCAddress,
BYTE typeSize,
CHAR * pSMSCType )
{
// Validate arguments
if (pIn == 0
|| addressSize == 0 || pSMSCAddress == 0
|| typeSize == 0 || pSMSCType == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume empty
pSMSCAddress[0] = 0;
pSMSCType[0] = 0;
// Get the address (mandatory)
const sWMSGetSMSCAddressResponse_Address * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sWMSRawSendResponse_CauseCode ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Handle the type as a string (maximum 3 chars)
std::string smscType( &pTLVx01->mSMSCAddressType[0], 3 );
// Is the SMSC type present? (optional)
ULONG smscTypeLen = (ULONG)smscType.size();
if (smscTypeLen > 0)
{
// Space to perform copy?
if (typeSize < smscTypeLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pSMSCType, &pTLVx01->mSMSCAddressType[0], smscTypeLen );
pSMSCType[smscTypeLen] = 0;
}
// Treat the address as a null terminated string
std::string smscAddr( (const CHAR *)pTLVx01
+ sizeof( sWMSGetSMSCAddressResponse_Address ),
pTLVx01->mSMSCAddressLength );
ULONG smscAddrLen = (ULONG)smscAddr.size();
if (addressSize < smscAddrLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pSMSCAddress, smscAddr.c_str(), addressSize );
pSMSCAddress[addressSize] = 0;
return rc;
}
/*===========================================================================
METHOD:
PackSetSMSCAddress
DESCRIPTION:
This function sets the SMS center address
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
pSMSCAddress [ I ] - The SMS center address represented as a NULL
terminated string
pSMSCType [ I ] - The SMS center address type represented as a NULL
terminated string (optional)
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackSetSMSCAddress(
ULONG * pOutLen,
BYTE * pOut,
CHAR * pSMSCAddress,
CHAR * pSMSCType )
{
// Validate arguments
if (pOut == 0 || pSMSCAddress == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// The TLV contains only the address
std::string smscAddr( pSMSCAddress );
// Check size
WORD tlvx01Sz = (WORD)smscAddr.size();
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
memcpy( (pOut + offset), smscAddr.c_str(), tlvx01Sz );
offset += tlvx01Sz;
// smscType is optional
if (pSMSCType != 0)
{
// The TLV contains only the type
std::string smscType( pSMSCType );
if (smscType.size() != 0)
{
// Check size
WORD tlvx10Sz = (WORD)smscType.size();
if (*pOutLen < offset + sizeof( sQMIRawContentHeader ) + tlvx10Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x10;
pHeader->mLength = tlvx10Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
memcpy( (pOut + offset), smscType.c_str(), tlvx10Sz );
offset += tlvx10Sz;
}
}
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetSMSRoutes
DESCRIPTION:
This function gets the current incoming SMS routing information
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pRouteSize [I/O] - Upon input the maximum number of elements that the
SMS route array can contain. Upon succes the actual
number of elements in the SMS route array
pRoutes [ O ] - The SMS route array
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetSMSRoutes(
ULONG inLen,
const BYTE * pIn,
BYTE * pRouteSize,
BYTE * pRoutes )
{
// Validate arguments
if (pIn == 0 || pRouteSize == 0 || *pRouteSize == 0 || pRoutes == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
BYTE maxRoutes = *pRouteSize;
*pRouteSize = 0;
// Get the route list
const sWMSGetRoutesResponse_RouteList * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sWMSGetRoutesResponse_RouteList ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
ULONG routeCount = pTLVx01->mNumberOfRoutes;
if (routeCount > (ULONG)maxRoutes)
{
routeCount = (ULONG)maxRoutes;
}
const sWMSGetRoutesResponse_RouteList::sRoute * pInRoute;
// Verify there is room for the array in the TLV
if (outLenx01 < sizeof( sWMSGetRoutesResponse_RouteList )
+ sizeof( sWMSGetRoutesResponse_RouteList::sRoute )
* routeCount)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Align to the first array element
pInRoute = (const sWMSGetRoutesResponse_RouteList::sRoute *)
((const BYTE *)pTLVx01
+ sizeof( sWMSGetRoutesResponse_RouteList ));
ULONG * pRouteArray = (ULONG *)pRoutes;
for (ULONG r = 0; r < routeCount; r++)
{
*pRouteArray++ = pInRoute->mMessageType;
*pRouteArray++ = pInRoute->mMessageClass;
*pRouteArray++ = pInRoute->mStorageType;
*pRouteArray++ = pInRoute->mRouteValue;
pInRoute++;
}
*pRouteSize = (BYTE)routeCount;
return rc;
}
/*===========================================================================
METHOD:
PackSetSMSRoutes
DESCRIPTION:
This function sets the desired incoming SMS routing information
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied to pOut
pOut [ O ] - Output buffer
pRouteSize [ I ] - The number of elements in the SMS route array
pRoutes [ I ] - The SMS route array
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackSetSMSRoutes(
ULONG * pOutLen,
BYTE * pOut,
BYTE * pRouteSize,
BYTE * pRoutes )
{
// Validate arguments
if (pOut == 0 || pRouteSize == 0 || *pRouteSize == 0 || pRoutes == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
UINT16 routeCount = (ULONG)*pRouteSize;
// Check size
WORD tlvx01Sz = sizeof( sWMSSetRoutesRequest_RouteList )
+ sizeof( sWMSSetRoutesRequest_RouteList::sRoute ) * routeCount;
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// Add route count
sWMSSetRoutesRequest_RouteList * pTLVx01;
pTLVx01 = (sWMSSetRoutesRequest_RouteList*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mNumberOfRoutes = routeCount;
offset += sizeof( sWMSSetRoutesRequest_RouteList );
sWMSSetRoutesRequest_RouteList::sRoute * pOutRoute;
// Align to the first array element
pOutRoute = (sWMSSetRoutesRequest_RouteList::sRoute *)(pOut + offset);
// Add the routes
ULONG * pRouteArray = (ULONG *)pRoutes;
for (ULONG r = 0; r < routeCount; r++)
{
pOutRoute->mMessageType = (eQMIWMSMessageTypes)*pRouteArray++;
pOutRoute->mMessageClass = (eQMIWMSMessageClasses)*pRouteArray++;
pOutRoute->mStorageType = (eQMIWMSStorageTypes)*pRouteArray++;
pOutRoute->mReceiptAction = (eQMIWMSReceiptActions)*pRouteArray++;
pOutRoute++;
offset += sizeof( sWMSSetRoutesRequest_RouteList::sRoute );
}
*pOutLen = offset;
return eGOBI_ERR_NONE;
}