/*=========================================================================== 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 ); }