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