1121 lines
32 KiB
C++
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;
|
|
}
|