blob: 789280dea8c0ac0e00a554f14ecbbf36c28f20bf [file] [log] [blame]
/*===========================================================================
FILE:
GobiQMICoreSMS.cpp
DESCRIPTION:
QUALCOMM Gobi QMI Based API Core (SMS Service)
PUBLIC CLASSES AND FUNCTIONS:
cGobiQMICore
Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum 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 "StdAfx.h"
#include "GobiQMICore.h"
#include "QMIBuffers.h"
//---------------------------------------------------------------------------
// Definitions
//---------------------------------------------------------------------------
/*=========================================================================*/
// cGobiQMICore Methods
/*=========================================================================*/
/*===========================================================================
METHOD:
DeleteSMS (Public Method)
DESCRIPTION:
This function deletes one or more SMS messages from device memory
PARAMETERS:
storageType [ I ] - SMS message storage type
pMessageIndex [ I ] - (Optional) message index
pMessageTag [ I ] - (Optional) message tag
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::DeleteSMS(
ULONG storageType,
ULONG * pMessageIndex,
ULONG * pMessageTag )
{
WORD msgID = (WORD)eQMI_WMS_DELETE;
std::vector <sDB2PackingInput> piv;
std::ostringstream tmp;
tmp << (UINT)storageType;
sProtocolEntityKey pek( eDB2_ET_QMI_WMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi );
if (pMessageIndex != 0)
{
std::ostringstream tmp2;
tmp2 << (UINT)*pMessageIndex;
sProtocolEntityKey pek1( eDB2_ET_QMI_WMS_REQ, msgID, 16 );
sDB2PackingInput pi1( pek1, (LPCSTR)tmp2.str().c_str() );
piv.push_back( pi1 );
}
if (pMessageTag != 0)
{
std::ostringstream tmp2;
tmp2 << (UINT)*pMessageTag;
sProtocolEntityKey pek1( eDB2_ET_QMI_WMS_REQ, msgID, 17 );
sDB2PackingInput pi1( pek1, (LPCSTR)tmp2.str().c_str() );
piv.push_back( pi1 );
}
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
// Send the QMI request, check result, and return
return SendAndCheckReturn( eQMI_SVC_WMS, pRequest, 10000 );
}
/*===========================================================================
METHOD:
GetSMSList (Public Method)
DESCRIPTION:
This function returns the list of SMS messages stored on the device
PARAMETERS:
storageType [ I ] - SMS message storage type
pRequestedTag [ I ] - Message index
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:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetSMSList(
ULONG storageType,
ULONG * pRequestedTag,
ULONG * pMessageListSize,
BYTE * pMessageList )
{
// Validate arguments
if (pMessageListSize == 0 || *pMessageListSize == 0 || pMessageList == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
ULONG maxMessageListSz = *pMessageListSize;
// Assume failure
*pMessageListSize = 0;
WORD msgID = (WORD)eQMI_WMS_GET_MSG_LIST;
std::vector <sDB2PackingInput> piv;
std::ostringstream tmp;
tmp << (UINT)storageType;
sProtocolEntityKey pek( eDB2_ET_QMI_WMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi );
if (pRequestedTag != 0)
{
std::ostringstream tmp2;
tmp2 << (UINT)*pRequestedTag;
sProtocolEntityKey pek1( eDB2_ET_QMI_WMS_REQ, msgID, 16 );
sDB2PackingInput pi1( pek1, (LPCSTR)tmp2.str().c_str() );
piv.push_back( pi1 );
}
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
if (pRequest == 0)
{
return eGOBI_ERR_MEMORY;
}
// Send the QMI request
sProtocolBuffer rsp = Send( eQMI_SVC_WMS, pRequest, 5000 );
if (rsp.IsValid() == false)
{
return GetCorrectedLastError();
}
// Did we receive a valid QMI response?
sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
if (qmiRsp.IsValid() == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Check the mandatory QMI result TLV for success
ULONG rc = 0;
ULONG ec = 0;
bool bResult = qmiRsp.GetResult( rc, ec );
if (bResult == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
else if (rc != 0)
{
return GetCorrectedQMIError( ec );
}
// Prepare TLVs for parsing
std::vector <sDB2NavInput> tlvs = DB2ReduceQMIBuffer( qmiRsp );
// Parse the TLV we want (by DB key)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_WMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
ULONG messageListSz = pf[0].mValue.mU32;
if (messageListSz == 0)
{
// No stored messages, but not necessarily a failure
return eGOBI_ERR_NONE;
}
if (pf.size() < (1 + (messageListSz * 2)) )
{
return eGOBI_ERR_INVALID_RSP;
}
if (maxMessageListSz < messageListSz)
{
messageListSz = maxMessageListSz;
}
ULONG m = 0;
ULONG mf = 1;
ULONG * pData = (ULONG *)pMessageList;
for (m = 0; m < messageListSz; m++)
{
*pData++ = pf[mf++].mValue.mU32;
*pData++ = pf[mf++].mValue.mU32;
}
*pMessageListSize = messageListSz;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetSMS (Public Method)
DESCRIPTION:
This function returns an SMS message from device memory
PARAMETERS:
storageType [ I ] - SMS message storage type
messageIndex [ I ] - Message index
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 [ I ] - The message contents array
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetSMS(
ULONG storageType,
ULONG messageIndex,
ULONG * pMessageTag,
ULONG * pMessageFormat,
ULONG * pMessageSize,
BYTE * pMessage )
{
// Validate arguments
if ( (pMessageTag == 0)
|| (pMessageFormat == 0)
|| (pMessageSize == 0)
|| (*pMessageSize == 0)
|| (pMessage == 0) )
{
return eGOBI_ERR_INVALID_ARG;
}
ULONG maxMessageSz = *pMessageSize;
// Assume failure
*pMessageSize = 0;
WORD msgID = (WORD)eQMI_WMS_RAW_READ;
std::vector <sDB2PackingInput> piv;
std::ostringstream tmp;
tmp << (UINT)storageType << " " << (UINT)messageIndex;
sProtocolEntityKey pek( eDB2_ET_QMI_WMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi );
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
if (pRequest == 0)
{
return eGOBI_ERR_MEMORY;
}
// Send the QMI request
sProtocolBuffer rsp = Send( eQMI_SVC_WMS, pRequest, 5000 );
if (rsp.IsValid() == false)
{
return GetCorrectedLastError();
}
// Did we receive a valid QMI response?
sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
if (qmiRsp.IsValid() == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Check the mandatory QMI result TLV for success
ULONG rc = 0;
ULONG ec = 0;
bool bResult = qmiRsp.GetResult( rc, ec );
if (bResult == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
else if (rc != 0)
{
return GetCorrectedQMIError( ec );
}
// Prepare TLVs for parsing
std::vector <sDB2NavInput> tlvs = DB2ReduceQMIBuffer( qmiRsp );
// Parse the TLV we want (by DB key)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_WMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 3)
{
return eGOBI_ERR_INVALID_RSP;
}
*pMessageTag = pf[0].mValue.mU32;
*pMessageFormat = pf[1].mValue.mU32;
ULONG messageSz = (ULONG)pf[2].mValue.mU16;
if (messageSz == 0)
{
// There has to be message data
return eGOBI_ERR_INVALID_RSP;
}
if (pf.size() < 3 + messageSz)
{
return eGOBI_ERR_INVALID_RSP;
}
if (maxMessageSz < messageSz)
{
// We have to be able to copy the whole message
return eGOBI_ERR_BUFFER_SZ;
}
// Copy message data
for (ULONG b = 0; b < messageSz; b++)
{
pMessage[b] = pf[3 + b].mValue.mU8;
}
*pMessageSize = messageSz;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ModifySMSStatus (Public Method)
DESCRIPTION:
This function modifies the status of an SMS message saved in storage on
the device
PARAMETERS:
storageType [ I ] - SMS message storage type
messageIndex [ I ] - Message index
messageTag [ I ] - Message tag
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::ModifySMSStatus(
ULONG storageType,
ULONG messageIndex,
ULONG messageTag )
{
WORD msgID = (WORD)eQMI_WMS_MODIFY_TAG;
std::vector <sDB2PackingInput> piv;
std::ostringstream tmp;
tmp << (UINT)storageType << " " << (UINT)messageIndex << " "
<< (UINT)messageTag;
sProtocolEntityKey pek( eDB2_ET_QMI_WMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi );
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
// Send the QMI request, check result, and return
return SendAndCheckReturn( eQMI_SVC_WMS, pRequest, 5000 );
}
/*===========================================================================
METHOD:
SaveSMS (Public Method)
DESCRIPTION:
This function saves an SMS message to device memory
PARAMETERS:
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
pMessageIndex [ O ] - The message index assigned by the device
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::SaveSMS(
ULONG storageType,
ULONG messageFormat,
ULONG messageSize,
BYTE * pMessage,
ULONG * pMessageIndex )
{
// Validate arguments
if (messageSize == 0 || pMessage == 0 || pMessageIndex == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
WORD msgID = (WORD)eQMI_WMS_RAW_WRITE;
std::vector <sDB2PackingInput> piv;
// "%u %u %u"
std::ostringstream tmp;
tmp << (UINT)storageType << " " << (UINT)messageFormat
<< " " << (UINT)messageSize;
for (ULONG b = 0; b < messageSize; b++)
{
tmp << " " << (UINT)pMessage[b];
}
sProtocolEntityKey pek( eDB2_ET_QMI_WMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi );
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
if (pRequest == 0)
{
return eGOBI_ERR_MEMORY;
}
// Send the QMI request
sProtocolBuffer rsp = Send( eQMI_SVC_WMS, pRequest, 10000 );
if (rsp.IsValid() == false)
{
return GetCorrectedLastError();
}
// Did we receive a valid QMI response?
sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
if (qmiRsp.IsValid() == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Check the mandatory QMI result TLV for success
ULONG rc = 0;
ULONG ec = 0;
bool bResult = qmiRsp.GetResult( rc, ec );
if (bResult == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
else if (rc != 0)
{
return GetCorrectedQMIError( ec );
}
// Prepare TLVs for parsing
std::vector <sDB2NavInput> tlvs = DB2ReduceQMIBuffer( qmiRsp );
// Parse the TLV we want (by DB key)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_WMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
*pMessageIndex = pf[0].mValue.mU32;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
SendSMS (Public Method)
DESCRIPTION:
This function sends an SMS message for immediate over the air transmission
PARAMETERS:
messageFormat [ I ] - Message format
messageSize [ I ] - The length of the message contents in bytes
pMessage [ I ] - The message contents
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:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::SendSMS(
ULONG messageFormat,
ULONG messageSize,
BYTE * pMessage,
ULONG * pMessageFailureCode )
{
// Validate arguments
if (messageSize == 0 || pMessage == 0 || pMessageFailureCode == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume we have no message failure cause code
*pMessageFailureCode = ULONG_MAX;
WORD msgID = (WORD)eQMI_WMS_RAW_SEND;
std::vector <sDB2PackingInput> piv;
std::ostringstream tmp;
tmp << (UINT)messageFormat << " " << (UINT)messageSize;
for (ULONG b = 0; b < messageSize; b++)
{
tmp << " " << (UINT)pMessage[b];
}
sProtocolEntityKey pek( eDB2_ET_QMI_WMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi );
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
if (pRequest == 0)
{
return eGOBI_ERR_MEMORY;
}
// Send the QMI request
sProtocolBuffer rsp = Send( eQMI_SVC_WMS, pRequest, 300000 );
if (rsp.IsValid() == false)
{
return GetCorrectedLastError();
}
// Did we receive a valid QMI response?
sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
if (qmiRsp.IsValid() == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Check the mandatory QMI result TLV for success
ULONG rc = 0;
ULONG ec = 0;
bool bResult = qmiRsp.GetResult( rc, ec );
if (bResult == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
else if (rc != 0)
{
// Prepare TLVs for parsing
std::vector <sDB2NavInput> tlvs = DB2ReduceQMIBuffer( qmiRsp );
// Parse the optional TLV we want (by DB key)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_WMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() >= 1)
{
*pMessageFailureCode = (ULONG)pf[0].mValue.mU16;
}
return GetCorrectedQMIError( ec );
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetSMSCAddress (Public Method)
DESCRIPTION:
Return the SMS center address
PARAMETERS:
addressSize [ I ] - The maximum number of characters (including NULL
terminator) that the SMS center address array
can contain
pSMSCAddress [ 0 ] - 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 [ 0 ] - The SMS center address type represented as a NULL
terminated string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetSMSCAddress(
BYTE addressSize,
CHAR * pSMSCAddress,
BYTE typeSize,
CHAR * pSMSCType )
{
// Validate arguments
if (addressSize == 0 || pSMSCAddress == 0 || typeSize == 0 || pSMSCType == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
pSMSCAddress[0] = 0;
pSMSCType[0] = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_WMS_GET_SMSC_ADDR;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_WMS, msgID );
if (rsp.IsValid() == false)
{
return GetCorrectedLastError();
}
// Did we receive a valid QMI response?
sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
if (qmiRsp.IsValid() == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Check the mandatory QMI result TLV for success
ULONG rc = 0;
ULONG ec = 0;
bool bResult = qmiRsp.GetResult( rc, ec );
if (bResult == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
else if (rc != 0)
{
return GetCorrectedQMIError( ec );
}
// Prepare TLVs for parsing
std::vector <sDB2NavInput> tlvs = DB2ReduceQMIBuffer( qmiRsp );
const cCoreDatabase & db = GetDatabase();
// Parse the TLV we want (by DB key)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_WMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 3)
{
return eGOBI_ERR_INVALID_RSP;
}
LONG strLen = pf[0].mValueString.size();
if (strLen > 0)
{
// Space to perform the copy?
if (typeSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pSMSCType, (LPCSTR)pf[0].mValueString.c_str(), strLen );
pSMSCType[strLen] = 0;
}
strLen = pf[2].mValueString.size();
if (strLen > 0)
{
// Space to perform the copy?
if (addressSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pSMSCAddress, (LPCSTR)pf[2].mValueString.c_str(), strLen );
pSMSCAddress[strLen] = 0;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
SetSMSCAddress (Public Method)
DESCRIPTION:
Set the SMS center address
PARAMETERS:
pSMSCAddress [ I ] - The SMS center address represented as a NULL
terminated string (maximum of 21 characters,
including NULL)
pSMSCType [ I ] - The SMS center address type represented as a NULL
terminated string (optional)
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::SetSMSCAddress(
CHAR * pSMSCAddress,
CHAR * pSMSCType )
{
// Validate arguments
if (pSMSCAddress == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
WORD msgID = (WORD)eQMI_WMS_SET_SMSC_ADDR;
std::vector <sDB2PackingInput> piv;
std::ostringstream addr;
if (pSMSCAddress[0] != 0)
{
addr << "\"" << pSMSCAddress << "\"";
}
sProtocolEntityKey pek( eDB2_ET_QMI_WMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)addr.str().c_str() );
piv.push_back( pi );
if (pSMSCType != 0)
{
std::ostringstream addrType;
if (pSMSCType[0] != 0)
{
addrType << "\"" << pSMSCType << "\"";
}
pek = sProtocolEntityKey( eDB2_ET_QMI_WMS_REQ, msgID, 16 );
pi = sDB2PackingInput( pek, (LPCSTR)addrType.str().c_str() );
piv.push_back( pi );
}
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
// Send the QMI request, check result, and return
return SendAndCheckReturn( eQMI_SVC_WMS, pRequest, 5000 );
}
/*===========================================================================
METHOD:
GetSMSRoutes (Public Method)
DESCRIPTION:
Get the current incoming SMS routing information
PARAMETERS:
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
===========================================================================*/
eGobiError cGobiQMICore::GetSMSRoutes(
BYTE * pRouteSize,
BYTE * pRoutes )
{
// Validate arguments
if (pRouteSize == 0 || *pRouteSize == 0 || pRoutes == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
BYTE maxRoutes = *pRouteSize;
*pRouteSize = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_WMS_GET_ROUTES;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_WMS, msgID, 5000 );
if (rsp.IsValid() == false)
{
return GetCorrectedLastError();
}
// Did we receive a valid QMI response?
sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
if (qmiRsp.IsValid() == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Check the mandatory QMI result TLV for success
ULONG rc = 0;
ULONG ec = 0;
bool bResult = qmiRsp.GetResult( rc, ec );
if (bResult == false)
{
return eGOBI_ERR_MALFORMED_RSP;
}
else if (rc != 0)
{
return GetCorrectedQMIError( ec );
}
// Prepare TLVs for parsing
std::vector <sDB2NavInput> tlvs = DB2ReduceQMIBuffer( qmiRsp );
const cCoreDatabase & db = GetDatabase();
// Parse the TLV we want (by DB key)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_WMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
ULONG fi = 0;
ULONG routeCount = (ULONG)pf[fi++].mValue.mU16;
if ((ULONG)pf.size() < 1 + 4 * routeCount)
{
return eGOBI_ERR_INVALID_RSP;
}
if (routeCount > (ULONG)maxRoutes)
{
routeCount = (ULONG)maxRoutes;
}
ULONG * pRouteArray = (ULONG *)pRoutes;
for (ULONG r = 0; r < routeCount; r++)
{
// Message type
*pRouteArray++ = pf[fi++].mValue.mU32;
// Message class
*pRouteArray++ = pf[fi++].mValue.mU32;
// Storage type
*pRouteArray++ = pf[fi++].mValue.mU32;
// Receipt action
*pRouteArray++ = pf[fi++].mValue.mU32;
}
*pRouteSize = (BYTE)routeCount;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
SetSMSRoutes (Public Method)
DESCRIPTION:
Set the desired incoming SMS routing information
PARAMETERS:
pRouteSize [ I ] - The number of elements in the SMS route array
pRoutes [ I ] - The SMS route array
RETURN VALUE:
ULONG - Return code
===========================================================================*/
eGobiError cGobiQMICore::SetSMSRoutes(
BYTE * pRouteSize,
BYTE * pRoutes )
{
// Validate arguments
if (pRouteSize == 0 || *pRouteSize == 0 || pRoutes == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Format up the request
ULONG routeCount = (ULONG)*pRouteSize;
// %u
std::ostringstream tmp;
tmp << routeCount;
ULONG * pRouteArray = (ULONG *)pRoutes;
for (ULONG r = 0; r < routeCount; r++)
{
// Message type, class, storage type, receipt action
for (ULONG f = 0; f < 4; f++)
{
// tmp += " %u"
tmp << " " << *pRouteArray++;
}
}
WORD msgID = (WORD)eQMI_WMS_SET_ROUTES;
std::vector <sDB2PackingInput> piv;
sProtocolEntityKey pek( eDB2_ET_QMI_WMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi );
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
if (pRequest == 0)
{
return eGOBI_ERR_MEMORY;
}
// Send the QMI request, check result, and return
return SendAndCheckReturn( eQMI_SVC_WMS, pRequest, 5000 );
}