aboutsummaryrefslogtreecommitdiffstats
path: root/gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQMICoreWDS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQMICoreWDS.cpp')
-rwxr-xr-xgobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQMICoreWDS.cpp2804
1 files changed, 2804 insertions, 0 deletions
diff --git a/gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQMICoreWDS.cpp b/gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQMICoreWDS.cpp
new file mode 100755
index 0000000..9a6677d
--- /dev/null
+++ b/gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQMICoreWDS.cpp
@@ -0,0 +1,2804 @@
+/*===========================================================================
+FILE:
+ GobiQMICoreWDS.cpp
+
+DESCRIPTION:
+ QUALCOMM Gobi QMI Based API Core (WDS 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:
+ GetSessionState (Public Method)
+
+DESCRIPTION:
+ This function returns the state of the current packet data session
+
+PARAMETERS:
+ pState [ O ] - State of the current packet session
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetSessionState( ULONG * pState )
+{
+ // Validate arguments
+ if (pState == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_PKT_STATUS;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the state
+ *pState = pf[0].mValue.mU32;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ GetSessionDuration (Public Method)
+
+DESCRIPTION:
+ This function returns the duration of the current packet data session
+
+PARAMETERS:
+ pDuration [ O ] - Duration of the current packet session
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetSessionDuration( ULONGLONG * pDuration )
+{
+ // Validate arguments
+ if (pDuration == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_DURATION;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the state
+ *pDuration = pf[0].mValue.mU64;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ GetSessionDurations (Public Method)
+
+DESCRIPTION:
+ This function returns the the active/total durations of the current
+ packet data session
+
+PARAMETERS:
+ pActiveDuration [ O ] - Active duration of the current packet session
+ pTotalDuration [ O ] - Total duration of the current packet session
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetSessionDurations(
+ ULONGLONG * pActiveDuration,
+ ULONGLONG * pTotalDuration )
+{
+ // Validate arguments
+ if (pActiveDuration == 0 || pTotalDuration == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_DURATION;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the total duration
+ *pTotalDuration = pf[0].mValue.mU64;
+
+ // Parse the TLV we want (by DB key)
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 17 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the active duration
+ *pActiveDuration = pf[0].mValue.mU64;
+
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ GetDormancyState (Public Method)
+
+DESCRIPTION:
+ This function returns the dormancy state of the current packet
+ data session (when connected)
+
+PARAMETERS:
+ pState [ O ] - Dormancy state of the current packet session
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetDormancyState( ULONG * pState )
+{
+ // Validate arguments
+ if (pState == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_DORMANCY;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the state
+ *pState = pf[0].mValue.mU32;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ GetEnhancedAutoconnect (Public Method)
+
+DESCRIPTION:
+ This function returns the current autoconnect data session setting
+
+PARAMETERS:
+ pSetting [ O ] - NDIS autoconnect setting
+ pRoamSetting [ O ] - NDIS autoconnect roam setting
+
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetEnhancedAutoconnect(
+ ULONG * pSetting,
+ ULONG * pRoamSetting )
+{
+ // Validate arguments
+ if (pSetting == 0 || pRoamSetting == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ *pSetting = ULONG_MAX;
+ *pRoamSetting = ULONG_MAX;
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_AUTOCONNECT;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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();
+
+ sProtocolEntityKey tlvKey( eDB2_ET_QMI_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ *pSetting = (ULONG)pf[0].mValue.mU32;
+
+ // Parse the TLV we want (by DB key)
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 16 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() > 0)
+ {
+ *pRoamSetting = (ULONG)pf[0].mValue.mU32;
+ }
+
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ SetEnhancedAutoconnect (Public Method)
+
+DESCRIPTION:
+ This function sets the autoconnect data session setting
+
+PARAMETERS:
+ setting [ I ] - NDIS autoconnect setting
+ pRoamSetting [ I ] - (Optional) NDIS autoconnect roam setting
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::SetEnhancedAutoconnect(
+ ULONG setting,
+ ULONG * pRoamSetting )
+{
+ WORD msgID = (WORD)eQMI_WDS_SET_AUTOCONNECT;
+ std::vector <sDB2PackingInput> piv;
+
+ // "%u"
+ std::ostringstream tmp;
+ tmp << setting;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 1 );
+ sDB2PackingInput pi( pek, tmp.str().c_str() );
+ piv.push_back( pi );
+
+ if (pRoamSetting != 0)
+ {
+ std::ostringstream tmp2;
+ tmp2 << *pRoamSetting;
+
+ sProtocolEntityKey pek1( eDB2_ET_QMI_WDS_REQ, msgID, 16 );
+ sDB2PackingInput pi1( pek1, tmp2.str().c_str() );
+ piv.push_back( pi1 );
+ }
+
+ ULONG to = 5000;
+ if (setting == 1)
+ {
+ // Connections can take a long time
+ to = 300000;
+ }
+
+ // 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_WDS, pRequest, to );
+}
+
+/*===========================================================================
+METHOD:
+ SetDefaultProfile (Public Method)
+
+DESCRIPTION:
+ This function writes the default profile settings to the device, the
+ default profile is used during autoconnect
+
+PARAMETERS:
+ profileType [ I ] - Profile type being written
+ pPDPType [ I ] - (Optional) PDP type
+ pIPAddress [ I ] - (Optional) Preferred assigned IPv4 address
+ pPrimaryDNS [ I ] - (Optional) Primary DNS IPv4 address
+ pSecondaryDNS [ I ] - (Optional) Secondary DNS IPv4 address
+ pAuthentication [ I ] - (Optional) Authentication algorithm bitmap
+ pName [ I ] - (Optional) The profile name or description
+ pAPNName [ I ] - (Optional) Access point name
+ pUsername [ I ] - (Optional) Username used during authentication
+ pPassword [ I ] - (Optional) Password used during authentication
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::SetDefaultProfile(
+ ULONG profileType,
+ ULONG * pPDPType,
+ ULONG * pIPAddress,
+ ULONG * pPrimaryDNS,
+ ULONG * pSecondaryDNS,
+ ULONG * pAuthentication,
+ CHAR * pName,
+ CHAR * pAPNName,
+ CHAR * pUsername,
+ CHAR * pPassword )
+{
+ WORD msgID = (WORD)eQMI_WDS_MODIFY_PROFILE;
+ std::vector <sDB2PackingInput> piv;
+
+ // "%u 1"
+ std::ostringstream tmp;
+ tmp << (UINT)profileType << " 1";
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 1 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+
+ if (pName != 0)
+ {
+ std::ostringstream tmp2;
+ if (pName[0] != 0)
+ {
+ tmp2 << "\"" << pName << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 16 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pPDPType != 0)
+ {
+ // "%u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)*pPDPType;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 17 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pAPNName != 0)
+ {
+ std::ostringstream tmp2;
+ if (pAPNName[0] != 0)
+ {
+ tmp2 << "\"" << pAPNName << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 20 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pPrimaryDNS != 0)
+ {
+ ULONG ip4 = (*pPrimaryDNS & 0x000000FF);
+ ULONG ip3 = (*pPrimaryDNS & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pPrimaryDNS & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pPrimaryDNS & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 21 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pSecondaryDNS != 0)
+ {
+ ULONG ip4 = (*pSecondaryDNS & 0x000000FF);
+ ULONG ip3 = (*pSecondaryDNS & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pSecondaryDNS & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pSecondaryDNS & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 22 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pUsername != 0)
+ {
+ std::ostringstream tmp2;
+ if (pUsername[0] != 0)
+ {
+ tmp2 << "\"" << pUsername << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 27 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pPassword != 0)
+ {
+ std::ostringstream tmp2;
+ if (pPassword[0] != 0)
+ {
+ tmp2 << "\"" << pPassword << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 28 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pAuthentication != 0)
+ {
+ ULONG pap = *pAuthentication & 0x00000001;
+ ULONG chap = *pAuthentication & 0x00000002;
+
+ // "%u %u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)pap << " " << (UINT)chap;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 29 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pIPAddress != 0)
+ {
+ ULONG ip4 = (*pIPAddress & 0x000000FF);
+ ULONG ip3 = (*pIPAddress & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pIPAddress & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pIPAddress & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 30 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // We need to be doing something here (beyond profile type)
+ if (piv.size() <= 1)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Pack up and send the QMI request
+ const cCoreDatabase & db = GetDatabase();
+ sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
+
+ // Send the QMI request, check result, and return
+ return SendAndCheckReturn( eQMI_SVC_WDS, pRequest );
+}
+
+/*===========================================================================
+METHOD:
+ GetDefaultProfile (Public Method)
+
+DESCRIPTION:
+ This function reads the default profile settings from the device, the
+ default profile is used during autoconnect
+
+PARAMETERS:
+ profileType [ I ] - Profile type being read
+ pPDPType [ O ] - PDP type
+ pIPAddress [ O ] - Preferred assigned IPv4 address
+ pPrimaryDNS [ O ] - Primary DNS IPv4 address
+ pSecondaryDNS [ O ] - Secondary DNS IPv4 address
+ pAuthentication [ O ] - Authentication algorithm bitmap
+ nameSize [ I ] - The maximum number of characters (including
+ NULL terminator) that the profile name array
+ can contain
+ pName [ O ] - The profile name or description
+ apnSize [ I ] - The maximum number of characters (including
+ NULL terminator) that the APN name array
+ can contain
+ pAPNName [ O ] - Access point name represented as a NULL
+ terminated string (empty string returned when
+ unknown)
+ userSize [ I ] - The maximum number of characters (including
+ NULL terminator) that the username array
+ can contain
+ pUsername [ O ] - Username used during authentication
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetDefaultProfile(
+ ULONG profileType,
+ ULONG * pPDPType,
+ ULONG * pIPAddress,
+ ULONG * pPrimaryDNS,
+ ULONG * pSecondaryDNS,
+ ULONG * pAuthentication,
+ BYTE nameSize,
+ CHAR * pName,
+ BYTE apnSize,
+ CHAR * pAPNName,
+ BYTE userSize,
+ CHAR * pUsername )
+{
+ // Validate arguments
+ if ( (pPDPType == 0)
+ || (pIPAddress == 0)
+ || (pPrimaryDNS == 0)
+ || (pSecondaryDNS == 0)
+ || (pAuthentication == 0)
+ || (nameSize == 0)
+ || (pName == 0)
+ || (apnSize == 0)
+ || (pAPNName == 0)
+ || (userSize == 0)
+ || (pUsername == 0) )
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ *pPDPType = ULONG_MAX;
+ *pIPAddress = ULONG_MAX;
+ *pPrimaryDNS = ULONG_MAX;
+ *pSecondaryDNS = ULONG_MAX;
+ *pAuthentication = ULONG_MAX;
+ pName[0] = 0;
+ pAPNName[0] = 0;
+ pUsername[0] = 0;
+
+ WORD msgID = (WORD)eQMI_WDS_GET_DEFAULTS;
+ std::vector <sDB2PackingInput> piv;
+
+ // "%u 0"
+ std::ostringstream tmp;
+ tmp << (UINT)profileType << " 0";
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_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_WDS, pRequest );
+ 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 );
+
+ sProtocolEntityKey tlvKey( eDB2_ET_QMI_WDS_RSP, msgID, 16 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ LONG strLen = pf[0].mValueString.size();
+ if (strLen <= 0)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Space to perform the copy?
+ if (nameSize < strLen + 1)
+ {
+ return eGOBI_ERR_BUFFER_SZ;
+ }
+
+ memcpy( (LPVOID)pName, (LPCSTR)pf[0].mValueString.c_str(), strLen );
+ pName[strLen] = 0;
+ }
+
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 17 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pPDPType = pf[0].mValue.mU32;
+ }
+
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 20 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ LONG strLen = pf[0].mValueString.size();
+ if (strLen <= 0)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Space to perform the copy?
+ if (apnSize < strLen + 1)
+ {
+ return eGOBI_ERR_BUFFER_SZ;
+ }
+
+ memcpy( (LPVOID)pAPNName, (LPCSTR)pf[0].mValueString.c_str(), strLen );
+ pAPNName[strLen] = 0;
+ }
+
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 21 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 4)
+ {
+ ULONG ip4 = (ULONG)pf[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf[3].mValue.mU8 << 24;
+ *pPrimaryDNS = (ip4 | ip3 | ip2 | ip1);
+ }
+
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 22 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 4)
+ {
+ ULONG ip4 = (ULONG)pf[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf[3].mValue.mU8 << 24;
+ *pSecondaryDNS = (ip4 | ip3 | ip2 | ip1);
+ }
+
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 27 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ LONG strLen = pf[0].mValueString.size();
+ if (strLen <= 0)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Space to perform the copy?
+ if (userSize < strLen + 1)
+ {
+ return eGOBI_ERR_BUFFER_SZ;
+ }
+
+ memcpy( (LPVOID)pUsername, (LPCSTR)pf[0].mValueString.c_str(), strLen );
+ pUsername[strLen] = 0;
+ }
+
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 29 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 2)
+ {
+ ULONG pap = (ULONG)pf[0].mValue.mU8;
+ ULONG chap = (ULONG)pf[1].mValue.mU8 << 1;
+
+ *pAuthentication = (pap | chap);
+ }
+
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 30 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 4)
+ {
+ ULONG ip4 = (ULONG)pf[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf[3].mValue.mU8 << 24;
+ *pIPAddress = (ip4 | ip3 | ip2 | ip1);
+ }
+
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ StartDataSession (Public Method)
+
+DESCRIPTION:
+ This function activates a packet data session
+
+PARAMETERS:
+ pTechnology [ I ] - (Optional) Technology bitmap
+ pPrimaryDNS [ I ] - (Optional) Primary DNS IPv4 address
+ pSecondaryDNS [ I ] - (Optional) Secondary DNS IPv4 address
+ pPrimaryNBNS [ I ] - (Optional) Primary NetBIOS NS IPv4 address
+ pSecondaryNBNS [ I ] - (Optional) Secondary NetBIOS NS IPv4 address
+ pAPNName [ I ] - (Optional) Access point name
+ pIPAddress [ I ] - (Optional) Preferred assigned IPv4 address
+ pAuthentication [ I ] - (Optional) Authentication algorithm bitmap
+ pUsername [ I ] - (Optional) Username used during authentication
+ pPassword [ I ] - (Optional) Password used during authentication
+ pSessionId [ O ] - The assigned session ID
+ pFailureReason [ O ] - Upon call failure the failure reason
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::StartDataSession(
+ ULONG * pTechnology,
+ ULONG * pPrimaryDNS,
+ ULONG * pSecondaryDNS,
+ ULONG * pPrimaryNBNS,
+ ULONG * pSecondaryNBNS,
+ CHAR * pAPNName,
+ ULONG * pIPAddress,
+ ULONG * pAuthentication,
+ CHAR * pUsername,
+ CHAR * pPassword,
+ ULONG * pSessionId,
+ ULONG * pFailureReason )
+{
+ *pFailureReason = (ULONG)eQMI_CALL_END_REASON_UNSPECIFIED;
+
+ // Validate arguments
+ if (pSessionId == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ WORD msgID = (WORD)eQMI_WDS_START_NET;
+ std::vector <sDB2PackingInput> piv;
+
+ if (pTechnology != 0)
+ {
+ ULONG umts = *pTechnology & 0x00000001;
+ ULONG cdma = *pTechnology & 0x00000002;
+
+ // "%u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)umts << " " << (UINT)cdma;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 48 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pPrimaryDNS != 0)
+ {
+ ULONG ip4 = (*pPrimaryDNS & 0x000000FF);
+ ULONG ip3 = (*pPrimaryDNS & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pPrimaryDNS & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pPrimaryDNS & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 16 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pSecondaryDNS != 0)
+ {
+ ULONG ip4 = (*pSecondaryDNS & 0x000000FF);
+ ULONG ip3 = (*pSecondaryDNS & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pSecondaryDNS & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pSecondaryDNS & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 17 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pPrimaryNBNS != 0)
+ {
+ ULONG ip4 = (*pPrimaryNBNS & 0x000000FF);
+ ULONG ip3 = (*pPrimaryNBNS & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pPrimaryNBNS & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pPrimaryNBNS & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 18 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pSecondaryNBNS != 0)
+ {
+ ULONG ip4 = (*pSecondaryNBNS & 0x000000FF);
+ ULONG ip3 = (*pSecondaryNBNS & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pSecondaryNBNS & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pSecondaryNBNS & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 19 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pAPNName != 0)
+ {
+ std::ostringstream tmp;
+ if (pAPNName[0] != 0)
+ {
+ tmp << "\"" << pAPNName << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 20 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pIPAddress != 0)
+ {
+ ULONG ip4 = (*pIPAddress & 0x000000FF);
+ ULONG ip3 = (*pIPAddress & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pIPAddress & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pIPAddress & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 21 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pAuthentication != 0)
+ {
+ ULONG pap = *pAuthentication & 0x00000001;
+ ULONG chap = *pAuthentication & 0x00000002;
+
+ // "%u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)pap << " " << (UINT)chap;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 22 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pUsername != 0)
+ {
+ std::ostringstream tmp;
+ if (pUsername[0] != 0)
+ {
+ tmp << "\"" << pUsername << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 23 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pPassword != 0)
+ {
+ std::ostringstream tmp;
+ if (pPassword[0] != 0)
+ {
+ tmp << "\"" << pPassword << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 24 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ sProtocolBuffer rsp;
+ if (piv.size() > 0)
+ {
+ // Pack up and send the QMI request
+ const cCoreDatabase & db = GetDatabase();
+ sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
+ if (pRequest == 0)
+ {
+ return eGOBI_ERR_MEMORY;
+ }
+ else
+ {
+ rsp = Send( eQMI_SVC_WDS, pRequest, 300000 );
+ }
+ }
+ else
+ {
+ // Generate and send the QMI request
+ rsp = SendSimple( eQMI_SVC_WDS, msgID, 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 );
+ const cCoreDatabase & db = GetDatabase();
+
+ // Parse the TLV we want (by DB key)
+ sProtocolEntityKey tlvKey( eDB2_ET_QMI_WDS_RSP, msgID, 16 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pFailureReason = pf[0].mValue.mU32;
+ }
+
+ 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the session ID
+ *pSessionId = pf[0].mValue.mU32;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ CancelDataSession (Public Method)
+
+DESCRIPTION:
+ Cancel an in-progress packet data session activation
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::CancelDataSession()
+{
+ if (mLastNetStartID == (WORD)INVALID_QMI_TRANSACTION_ID)
+ {
+ return eGOBI_ERR_NO_CANCELABLE_OP;
+ }
+
+ WORD msgID = (WORD)eQMI_WDS_ABORT;
+ std::vector <sDB2PackingInput> piv;
+
+ // %hu
+ std::ostringstream tmp;
+ tmp << mLastNetStartID;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_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
+ mLastNetStartID = (WORD)INVALID_QMI_TRANSACTION_ID;
+ return SendAndCheckReturn( eQMI_SVC_WDS, pRequest, 60000 );
+}
+
+/*===========================================================================
+METHOD:
+ StopDataSession (Public Method)
+
+DESCRIPTION:
+ This function stops the current data session
+
+PARAMETERS:
+ sessionId [ I ] - The ID of the session to terminate
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::StopDataSession( ULONG sessionId )
+{
+ WORD msgID = (WORD)eQMI_WDS_STOP_NET;
+ std::vector <sDB2PackingInput> piv;
+
+ // "%u"
+ std::ostringstream tmp;
+ tmp << (UINT)sessionId;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_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_WDS, pRequest, 60000 );
+}
+
+/*===========================================================================
+METHOD:
+ GetIPAddress
+
+DESCRIPTION:
+ This function returns the current packet data session IP address
+
+PARAMETERS:
+ pIPAddress [ I ] - Assigned IPv4 address
+
+RETURN VALUE:
+ ULONG - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetIPAddress( ULONG * pIPAddress )
+{
+ // Validate arguments
+ if (pIPAddress == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Assume failure
+ *pIPAddress = ULONG_MAX;
+
+ WORD msgID = (WORD)eQMI_WDS_GET_SETTINGS;
+ std::vector <sDB2PackingInput> piv;
+
+ std::string tmp = "0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0";
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 16 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.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_WDS, pRequest );
+ 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 TLVs we want (IP address)
+ sProtocolEntityKey tlvKey( eDB2_ET_QMI_WDS_RSP, msgID, 30 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 4)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ ULONG ip4 = (ULONG)pf[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf[3].mValue.mU8 << 24;
+ *pIPAddress = (ip4 | ip3 | ip2 | ip1);
+
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ GetConnectionRate (Public Method)
+
+DESCRIPTION:
+ This function returns connection rate information for the packet data
+ connection
+
+PARAMETERS:
+ pCurrentChannelTXRate [ O ] - Current channel TX rate (bps)
+ pCurrentChannelRXRate [ O ] - Current channel RX rate (bps)
+ pMaxChannelTXRate [ O ] - Maximum channel TX rate (bps)
+ pMaxChannelRXRate [ O ] - Maximum channel RX rate (bps)
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetConnectionRate(
+ ULONG * pCurrentChannelTXRate,
+ ULONG * pCurrentChannelRXRate,
+ ULONG * pMaxChannelTXRate,
+ ULONG * pMaxChannelRXRate )
+{
+ // Validate arguments
+ if ( (pCurrentChannelTXRate == 0)
+ || (pCurrentChannelRXRate == 0)
+ || (pMaxChannelTXRate == 0)
+ || (pMaxChannelRXRate == 0) )
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_RATES;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 4)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the rates
+ *pCurrentChannelTXRate = pf[0].mValue.mU32;
+ *pCurrentChannelRXRate = pf[1].mValue.mU32;
+ *pMaxChannelTXRate = pf[2].mValue.mU32;
+ *pMaxChannelRXRate = pf[3].mValue.mU32;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ GetPacketStatus (Public Method)
+
+DESCRIPTION:
+ This function returns the packet data transfer statistics since the start
+ of the current packet data session
+
+PARAMETERS:
+ pTXPacketSuccesses [ O ] - Packets transmitted without error
+ pRXPacketSuccesses [ O ] - Packets received without error
+ pTXPacketErrors [ O ] - Outgoing packets with framing errors
+ pRXPacketErrors [ O ] - Incoming packets with framing errors
+ pTXPacketOverflows [ O ] - Packets dropped because TX buffer overflowed
+ pRXPacketOverflows [ O ] - Packets dropped because RX buffer overflowed
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetPacketStatus(
+ ULONG * pTXPacketSuccesses,
+ ULONG * pRXPacketSuccesses,
+ ULONG * pTXPacketErrors,
+ ULONG * pRXPacketErrors,
+ ULONG * pTXPacketOverflows,
+ ULONG * pRXPacketOverflows )
+{
+ // Validate arguments
+ if ( (pTXPacketSuccesses == 0)
+ || (pRXPacketSuccesses == 0)
+ || (pTXPacketErrors == 0)
+ || (pRXPacketErrors == 0)
+ || (pTXPacketOverflows == 0)
+ || (pRXPacketOverflows == 0) )
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ WORD msgID = (WORD)eQMI_WDS_GET_STATISTICS;
+ std::vector <sDB2PackingInput> piv;
+
+ std::string tmp = "1 1 1 1 1 1 0 0";
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 1 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.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_WDS, pRequest );
+ 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 TLVs we want (by DB key)
+ sProtocolEntityKey tlvKey1( eDB2_ET_QMI_WDS_RSP, msgID, 16 );
+ cDataParser::tParsedFields pf1 = ParseTLV( db, rsp, tlvs, tlvKey1 );
+ if (pf1.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ sProtocolEntityKey tlvKey2( eDB2_ET_QMI_WDS_RSP, msgID, 17 );
+ cDataParser::tParsedFields pf2 = ParseTLV( db, rsp, tlvs, tlvKey2 );
+ if (pf2.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ sProtocolEntityKey tlvKey3( eDB2_ET_QMI_WDS_RSP, msgID, 18 );
+ cDataParser::tParsedFields pf3 = ParseTLV( db, rsp, tlvs, tlvKey3 );
+ if (pf3.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ sProtocolEntityKey tlvKey4( eDB2_ET_QMI_WDS_RSP, msgID, 19 );
+ cDataParser::tParsedFields pf4 = ParseTLV( db, rsp, tlvs, tlvKey4 );
+ if (pf4.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ sProtocolEntityKey tlvKey5( eDB2_ET_QMI_WDS_RSP, msgID, 20 );
+ cDataParser::tParsedFields pf5 = ParseTLV( db, rsp, tlvs, tlvKey5 );
+ if (pf5.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ sProtocolEntityKey tlvKey6( eDB2_ET_QMI_WDS_RSP, msgID, 21 );
+ cDataParser::tParsedFields pf6 = ParseTLV( db, rsp, tlvs, tlvKey5 );
+ if (pf6.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the statistics
+ *pTXPacketSuccesses = pf1[0].mValue.mU32;
+ *pRXPacketSuccesses = pf2[0].mValue.mU32;
+ *pTXPacketErrors = pf3[0].mValue.mU32;
+ *pRXPacketErrors = pf4[0].mValue.mU32;
+ *pTXPacketOverflows = pf5[0].mValue.mU32;
+ *pRXPacketOverflows = pf6[0].mValue.mU32;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ GetByteTotals (Public Method)
+
+DESCRIPTION:
+ This function returns the RX/TX byte counts since the start of the
+ current packet data session
+
+PARAMETERS:
+ pTXTotalBytes [ O ] - Bytes transmitted without error
+ pRXTotalBytes [ O ] - Bytes received without error
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetByteTotals(
+ ULONGLONG * pTXTotalBytes,
+ ULONGLONG * pRXTotalBytes )
+{
+ // Validate arguments
+ if (pTXTotalBytes == 0 || pRXTotalBytes == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ WORD msgID = (WORD)eQMI_WDS_GET_STATISTICS;
+ std::vector <sDB2PackingInput> piv;
+
+ std::string tmp = "0 0 0 0 0 0 1 1";
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 1 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.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_WDS, pRequest );
+ 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 );
+
+ sProtocolEntityKey tlvKey1( eDB2_ET_QMI_WDS_RSP, msgID, 25 );
+ cDataParser::tParsedFields pf1 = ParseTLV( db, rsp, tlvs, tlvKey1 );
+ if (pf1.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ sProtocolEntityKey tlvKey2( eDB2_ET_QMI_WDS_RSP, msgID, 26 );
+ cDataParser::tParsedFields pf2 = ParseTLV( db, rsp, tlvs, tlvKey2 );
+ if (pf2.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the statistics
+ *pTXTotalBytes = pf1[0].mValue.mU64;
+ *pRXTotalBytes = pf2[0].mValue.mU64;
+
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ SetMobileIP (Public Method)
+
+DESCRIPTION:
+ This function sets the current mobile IP setting
+
+PARAMETERS:
+ mode [ I ] - Desired mobile IP setting
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::SetMobileIP( ULONG mode )
+{
+ WORD msgID = (WORD)eQMI_WDS_SET_MIP;
+ std::vector <sDB2PackingInput> piv;
+
+ // "%u"
+ std::ostringstream tmp;
+ tmp << (UINT)mode;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_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_WDS, pRequest );
+}
+
+/*===========================================================================
+METHOD:
+ GetMobileIP (Public Method)
+
+DESCRIPTION:
+ This function gets the current mobile IP setting
+
+PARAMETERS:
+ pMode [ I ] - Desired mobile IP setting
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetMobileIP( ULONG * pMode )
+{
+ // Validate arguments
+ if (pMode == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_MIP;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the mode
+ *pMode = pf[0].mValue.mU32;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ SetActiveMobileIPProfile (Public Method)
+
+DESCRIPTION:
+ This function sets the active mobile IP profile index
+
+PARAMETERS:
+ pSPC [ I ] - Six digit service programming code
+ index [ I ] - Desired mobile IP profile index
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::SetActiveMobileIPProfile(
+ CHAR * pSPC,
+ BYTE index )
+{
+ // Validate arguments
+ if (pSPC == 0 || pSPC[0] == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ std::string spc( pSPC );
+ if (spc.size() > 6)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ int nNonDigit = spc.find_first_not_of( "0123456789" );
+ std::string digitSPC = spc.substr( 0, nNonDigit );
+ if (digitSPC.size() != spc.size())
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ WORD msgID = (WORD)eQMI_WDS_SET_ACTIVE_MIP;
+ std::vector <sDB2PackingInput> piv;
+
+ // "%s %u"
+ std::ostringstream tmp;
+ tmp << spc << " " << (UINT)index;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_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_WDS, pRequest );
+}
+
+/*===========================================================================
+METHOD:
+ GetActiveMobileIPProfile (Public Method)
+
+DESCRIPTION:
+ This function gets the the active mobile IP profile index
+
+PARAMETERS:
+ pIndex [ O ] - Active mobile IP profile index
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetActiveMobileIPProfile( BYTE * pIndex )
+{
+ // Validate arguments
+ if (pIndex == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_ACTIVE_MIP;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the index
+ *pIndex = pf[0].mValue.mU8;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ SetMobileIPProfile (Public Method)
+
+DESCRIPTION:
+ This function sets the specified mobile IP profile settings
+
+PARAMETERS:
+ pSPC [ I ] - Six digit service programming code
+ index [ I ] - Mobile IP profile ID
+ pEnabled [ I ] - (Optional) Enable MIP profile?
+ pAddress [ I ] - (Optional) Home IPv4 address
+ pPrimaryHA [ I ] - (Optional) Primary home agent IPv4 address
+ pSecondaryHA [ I ] - (Optional) Secondary home agent IPv4 address
+ pRevTunneling [ I ] - (Optional) Enable reverse tunneling?
+ pNAI [ I ] - (Optional) Network access identifier string
+ pHASPI [ I ] - (Optional) HA security parameter index
+ pAAASPI [ I ] - (Optional) AAA security parameter index
+ pMNHA [ I ] - (Optional) MN-HA string
+ pMNAAA [ I ] - (Optional) MN-AAA string
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::SetMobileIPProfile(
+ CHAR * pSPC,
+ BYTE index,
+ BYTE * pEnabled,
+ ULONG * pAddress,
+ ULONG * pPrimaryHA,
+ ULONG * pSecondaryHA,
+ BYTE * pRevTunneling,
+ CHAR * pNAI,
+ ULONG * pHASPI,
+ ULONG * pAAASPI,
+ CHAR * pMNHA,
+ CHAR * pMNAAA )
+{
+ // Validate arguments
+ if (pSPC == 0 || pSPC[0] == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ std::string spc( pSPC );
+ if (spc.size() > 6)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ int nNonDigit = spc.find_first_not_of( "0123456789" );
+ std::string digitSPC = spc.substr( 0, nNonDigit );
+ if (digitSPC.size() != spc.size())
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ WORD msgID = (WORD)eQMI_WDS_SET_MIP_PROFILE;
+ std::vector <sDB2PackingInput> piv;
+
+ // "%s %u"
+ std::ostringstream tmp;
+ tmp << spc << " " << (UINT)index;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 1 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+
+ // Enabled flag provided?
+ if (pEnabled != 0)
+ {
+ // "%u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)(*pEnabled == 0 ? 0 : 1);
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 16 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Home address provided?
+ if (pAddress != 0)
+ {
+ ULONG ip4 = (*pAddress & 0x000000FF);
+ ULONG ip3 = (*pAddress & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pAddress & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pAddress & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 17 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Primary HA address provided?
+ if (pPrimaryHA != 0)
+ {
+ ULONG ip4 = (*pPrimaryHA & 0x000000FF);
+ ULONG ip3 = (*pPrimaryHA & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pPrimaryHA & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pPrimaryHA & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 18 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Secondary HA address provided?
+ if (pSecondaryHA != 0)
+ {
+ ULONG ip4 = (*pSecondaryHA & 0x000000FF);
+ ULONG ip3 = (*pSecondaryHA & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pSecondaryHA & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pSecondaryHA & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 19 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Reverse tunneling flag provided?
+ if (pRevTunneling != 0)
+ {
+ // "%u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)(*pRevTunneling == 0 ? 0 : 1);
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 20 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // NAI provided?
+ if (pNAI != 0)
+ {
+ std::ostringstream tmp2;
+ if (pNAI[0] != 0)
+ {
+ tmp2 << "\"" << pNAI << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 21 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // HA SPI provided?
+ if (pHASPI != 0)
+ {
+ // "%u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)*pHASPI;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 22 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // AAA SPI provided?
+ if (pAAASPI != 0)
+ {
+ // "%u"
+ std::ostringstream tmp2;
+ tmp2 << (UINT)*pAAASPI;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 23 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // MN-HA key provided?
+ if (pMNHA != 0)
+ {
+ std::ostringstream tmp2;
+ if (pMNHA[0] != 0)
+ {
+ tmp2 << "\"" << pMNHA << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 24 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // MN-AAA key provided?
+ if (pMNAAA != 0)
+ {
+ std::ostringstream tmp2;
+ if (pMNAAA[0] != 0)
+ {
+ tmp2 << "\"" << pMNAAA << "\"";
+ }
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 25 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // We require at least one of the optional arguments
+ if (piv.size() <= 1)
+ {
+ // Much ado about nothing
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // 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_WDS, pRequest );
+}
+
+/*===========================================================================
+METHOD:
+ GetMobileIPProfile (Public Method)
+
+DESCRIPTION:
+ This function gets the specified mobile IP profile settings
+
+PARAMETERS:
+ index [ I ] - Mobile IP profile ID
+ pEnabled [ O ] - MIP profile enabled?
+ pAddress [ O ] - Home IPv4 address
+ pPrimaryHA [ O ] - Primary home agent IPv4 address
+ pSecondaryHA [ O ] - Secondary home agent IPv4 address
+ pRevTunneling [ O ] - Reverse tunneling enabled?
+ naiSize [ I ] - The maximum number of characters (including NULL
+ terminator) that the NAI array can contain
+ pNAI [ O ] - Network access identifier string
+ pHASPI [ O ] - HA security parameter index
+ pAAASPI [ O ] - AAA security parameter index
+ pHAState [ O ] - HA key state
+ pAAAState [ O ] - AAA key state
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetMobileIPProfile(
+ BYTE index,
+ BYTE * pEnabled,
+ ULONG * pAddress,
+ ULONG * pPrimaryHA,
+ ULONG * pSecondaryHA,
+ BYTE * pRevTunneling,
+ BYTE naiSize,
+ CHAR * pNAI,
+ ULONG * pHASPI,
+ ULONG * pAAASPI,
+ ULONG * pHAState,
+ ULONG * pAAAState )
+{
+
+ // Validate arguments
+ if ( (pEnabled == 0)
+ || (pAddress == 0)
+ || (pPrimaryHA == 0)
+ || (pSecondaryHA == 0)
+ || (pRevTunneling == 0)
+ || (naiSize == 0)
+ || (pNAI == 0)
+ || (pHASPI == 0)
+ || (pAAASPI == 0)
+ || (pHAState == 0)
+ || (pAAAState == 0) )
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Assume errors
+ *pEnabled = UCHAR_MAX;
+ *pAddress = ULONG_MAX;
+ *pPrimaryHA = ULONG_MAX;
+ *pSecondaryHA = ULONG_MAX;
+ *pRevTunneling = UCHAR_MAX;
+ *pHASPI = ULONG_MAX;
+ *pAAASPI = ULONG_MAX;
+ *pHAState = ULONG_MAX;
+ *pAAAState = ULONG_MAX;
+
+ WORD msgID = (WORD)eQMI_WDS_GET_MIP_PROFILE;
+ std::vector <sDB2PackingInput> piv;
+
+ // "%u"
+ std::ostringstream arg;
+ arg << (UINT)index;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 1 );
+ sDB2PackingInput pi( pek, (LPCSTR)arg.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_WDS, pRequest );
+ 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 );
+
+ sProtocolEntityKey tlvKey1( eDB2_ET_QMI_WDS_RSP, msgID, 16 );
+ cDataParser::tParsedFields pf1 = ParseTLV( db, rsp, tlvs, tlvKey1 );
+ if (pf1.size() >= 1)
+ {
+ *pEnabled = pf1[0].mValue.mU8;
+ }
+
+ sProtocolEntityKey tlvKey2( eDB2_ET_QMI_WDS_RSP, msgID, 17 );
+ cDataParser::tParsedFields pf2 = ParseTLV( db, rsp, tlvs, tlvKey2 );
+ if (pf2.size() >= 4)
+ {
+ ULONG ip4 = (ULONG)pf2[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf2[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf2[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf2[3].mValue.mU8 << 24;
+ *pAddress = (ip4 | ip3 | ip2 | ip1);
+ }
+
+
+ sProtocolEntityKey tlvKey3( eDB2_ET_QMI_WDS_RSP, msgID, 18 );
+ cDataParser::tParsedFields pf3 = ParseTLV( db, rsp, tlvs, tlvKey3 );
+ if (pf3.size() >= 4)
+ {
+ ULONG ip4 = (ULONG)pf3[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf3[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf3[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf3[3].mValue.mU8 << 24;
+ *pPrimaryHA = (ip4 | ip3 | ip2 | ip1);
+ }
+
+ sProtocolEntityKey tlvKey4( eDB2_ET_QMI_WDS_RSP, msgID, 19 );
+ cDataParser::tParsedFields pf4 = ParseTLV( db, rsp, tlvs, tlvKey4 );
+ if (pf4.size() >= 4)
+ {
+ ULONG ip4 = (ULONG)pf4[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf4[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf4[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf4[3].mValue.mU8 << 24;
+ *pSecondaryHA = (ip4 | ip3 | ip2 | ip1);
+ }
+
+ sProtocolEntityKey tlvKey5( eDB2_ET_QMI_WDS_RSP, msgID, 20 );
+ cDataParser::tParsedFields pf5 = ParseTLV( db, rsp, tlvs, tlvKey5 );
+ if (pf5.size() >= 1)
+ {
+ *pRevTunneling = pf5[0].mValue.mU8;
+ }
+
+ sProtocolEntityKey tlvKey6( eDB2_ET_QMI_WDS_RSP, msgID, 21 );
+ cDataParser::tParsedFields pf6 = ParseTLV( db, rsp, tlvs, tlvKey6 );
+ if (pf6.size() >= 1)
+ {
+ LONG strLen = pf6[0].mValueString.size();
+ if (strLen <= 0)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Space to perform the copy?
+ if (naiSize < strLen + 1)
+ {
+ return eGOBI_ERR_BUFFER_SZ;
+ }
+
+ memcpy( (LPVOID)pNAI, (LPCSTR)pf6[0].mValueString.c_str(), strLen );
+ pNAI[strLen] = 0;
+ }
+
+ sProtocolEntityKey tlvKey7( eDB2_ET_QMI_WDS_RSP, msgID, 22 );
+ cDataParser::tParsedFields pf7 = ParseTLV( db, rsp, tlvs, tlvKey7 );
+ if (pf7.size() >= 1)
+ {
+ *pHASPI = pf7[0].mValue.mU32;
+ }
+
+ sProtocolEntityKey tlvKey8( eDB2_ET_QMI_WDS_RSP, msgID, 23 );
+ cDataParser::tParsedFields pf8 = ParseTLV( db, rsp, tlvs, tlvKey8 );
+ if (pf8.size() >= 1)
+ {
+ *pAAASPI = pf8[0].mValue.mU32;
+ }
+ sProtocolEntityKey tlvKey9( eDB2_ET_QMI_WDS_RSP, msgID, 26 );
+ cDataParser::tParsedFields pf9 = ParseTLV( db, rsp, tlvs, tlvKey9 );
+ if (pf9.size() >= 1)
+ {
+ *pHAState = pf9[0].mValue.mU32;
+ }
+
+ sProtocolEntityKey tlvKey10( eDB2_ET_QMI_WDS_RSP, msgID, 27 );
+ cDataParser::tParsedFields pf10 = ParseTLV( db, rsp, tlvs, tlvKey10 );
+ if (pf10.size() >= 1)
+ {
+ *pAAAState = pf10[0].mValue.mU32;
+ }
+
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ SetMobileIPParameters (Public Method)
+
+DESCRIPTION:
+ This function sets the specified mobile IP parameters
+
+PARAMETERS:
+ pSPC [ I ] - Six digit service programming code
+ pMode [ I ] - (Optional) Desired mobile IP setting
+ pRetryLimit [ I ] - (Optional) Retry attempt limit
+ pRetryInterval [ I ] - (Optional) Retry attempt interval
+ pReRegPeriod [ I ] - (Optional) Re-registration period
+ pReRegTraffic [ I ] - (Optional) Re-registration only with traffic?
+ pHAAuthenticator [ I ] - (Optional) MH-HA authenticator calculator?
+ pHA2002bis [ I ] - (Optional) MH-HA RFC 2002bis authentication?
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::SetMobileIPParameters(
+ CHAR * pSPC,
+ ULONG * pMode,
+ BYTE * pRetryLimit,
+ BYTE * pRetryInterval,
+ BYTE * pReRegPeriod,
+ BYTE * pReRegTraffic,
+ BYTE * pHAAuthenticator,
+ BYTE * pHA2002bis )
+{
+ // Validate arguments
+ if (pSPC == 0 || pSPC[0] == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ std::string spc( pSPC );
+ if (spc.size() > 6)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ int nNonDigit = spc.find_first_not_of( "0123456789" );
+ std::string digitSPC = spc.substr( 0, nNonDigit );
+ if (digitSPC.size() != spc.size())
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ WORD msgID = (WORD)eQMI_WDS_SET_MIP_PARAMS;
+ std::vector <sDB2PackingInput> piv;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 1 );
+ sDB2PackingInput pi( pek, (LPCSTR)spc.c_str() );
+ piv.push_back( pi );
+
+ // Mode provided?
+ if (pMode != 0)
+ {
+ // "%u"
+ std::ostringstream tmp;
+ tmp << (UINT)*pMode;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 16 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Retry limit provided?
+ if (pRetryLimit != 0)
+ {
+ std::ostringstream tmp;
+ tmp << (UINT)*pRetryLimit;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 17 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Retry interval provided?
+ if (pRetryInterval != 0)
+ {
+ std::ostringstream tmp;
+ tmp << (UINT)*pRetryInterval;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 18 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Re-registration period provided?
+ if (pReRegPeriod != 0)
+ {
+ std::ostringstream tmp;
+ tmp << (UINT)*pReRegPeriod;
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 19 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Re-registration on traffic flag provided?
+ if (pReRegTraffic != 0)
+ {
+ std::ostringstream tmp;
+ tmp << (UINT)(*pReRegTraffic == 0 ? 0 : 1);
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 20 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // HA authenticator flag provided?
+ if (pHAAuthenticator != 0)
+ {
+ std::ostringstream tmp;
+ tmp << (UINT)(*pHAAuthenticator == 0 ? 0 : 1);
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 21 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // HA RFC2002bis authentication flag provided?
+ if (pHA2002bis != 0)
+ {
+ std::ostringstream tmp;
+ tmp << (UINT)(*pHA2002bis == 0 ? 0 : 1);
+
+ pek = sProtocolEntityKey( eDB2_ET_QMI_WDS_REQ, msgID, 22 );
+ pi = sDB2PackingInput( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // We require at least one of the optional arguments
+ if (piv.size() <= 1)
+ {
+ // Much ado about nothing
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // 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_WDS, pRequest );
+}
+
+/*===========================================================================
+METHOD:
+ GetMobileIPParameters (Public Method)
+
+DESCRIPTION:
+ This function gets the mobile IP parameters
+
+PARAMETERS:
+ pMode [ 0 ] - Current mobile IP setting
+ pRetryLimit [ 0 ] - Retry attempt limit
+ pRetryInterval [ 0 ] - Retry attempt interval
+ pReRegPeriod [ 0 ] - Re-registration period
+ pReRegTraffic [ 0 ] - Re-registration only with traffic?
+ pHAAuthenticator [ 0 ] - MH-HA authenticator calculator?
+ pHA2002bis [ 0 ] - MH-HA RFC 2002bis authentication?
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetMobileIPParameters(
+ ULONG * pMode,
+ BYTE * pRetryLimit,
+ BYTE * pRetryInterval,
+ BYTE * pReRegPeriod,
+ BYTE * pReRegTraffic,
+ BYTE * pHAAuthenticator,
+ BYTE * pHA2002bis )
+{
+ // Validate arguments
+ if ( (pMode == 0)
+ || (pRetryLimit == 0)
+ || (pRetryInterval == 0)
+ || (pReRegPeriod == 0)
+ || (pReRegTraffic == 0)
+ || (pHAAuthenticator == 0)
+ || (pHA2002bis == 0) )
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ *pMode = ULONG_MAX;
+ *pRetryLimit = UCHAR_MAX;
+ *pRetryInterval = UCHAR_MAX;
+ *pReRegPeriod = UCHAR_MAX;
+ *pReRegTraffic = UCHAR_MAX;
+ *pHAAuthenticator = UCHAR_MAX;
+ *pHA2002bis = UCHAR_MAX;
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_MIP_PARAMS;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 16 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pMode = pf[0].mValue.mU32;
+ }
+
+ tlvKey = sProtocolEntityKey ( eDB2_ET_QMI_WDS_RSP, msgID, 17 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pRetryLimit = pf[0].mValue.mU8;
+ }
+
+ tlvKey = sProtocolEntityKey ( eDB2_ET_QMI_WDS_RSP, msgID, 18 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pRetryInterval = pf[0].mValue.mU8;
+ }
+
+ tlvKey = sProtocolEntityKey ( eDB2_ET_QMI_WDS_RSP, msgID, 19 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pReRegPeriod = pf[0].mValue.mU8;
+ }
+
+ tlvKey = sProtocolEntityKey ( eDB2_ET_QMI_WDS_RSP, msgID, 20 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pReRegTraffic = pf[0].mValue.mU8;
+ }
+
+ tlvKey = sProtocolEntityKey ( eDB2_ET_QMI_WDS_RSP, msgID, 21 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pHAAuthenticator = pf[0].mValue.mU8;
+ }
+
+
+ tlvKey = sProtocolEntityKey ( eDB2_ET_QMI_WDS_RSP, msgID, 22 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 1)
+ {
+ *pHA2002bis = pf[0].mValue.mU8;
+ }
+
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ GetLastMobileIPError (Public Method)
+
+DESCRIPTION:
+ This function gets the last mobile IP error
+
+PARAMETERS:
+ pError [ 0 ] - Last mobile IP error
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetLastMobileIPError( ULONG * pError )
+{
+ // Validate arguments
+ if (pError == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_LAST_MIP_STATUS;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 1 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() < 1)
+ {
+ return eGOBI_ERR_INVALID_RSP;
+ }
+
+ // Populate the index
+ *pError = (ULONG)pf[0].mValue.mU8;
+ return eGOBI_ERR_NONE;
+}
+
+/*===========================================================================
+METHOD:
+ SetDNSSettings
+
+DESCRIPTION:
+ This function sets the DNS settings for the device
+
+PARAMETERS:
+ pPrimaryDNS [ I ] - (Optional) Primary DNS IPv4 address
+ pSecondaryDNS [ I ] - (Optional) Secondary DNS IPv4 address
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::SetDNSSettings(
+ ULONG * pPrimaryDNS,
+ ULONG * pSecondaryDNS )
+{
+ // Validate arguments
+ if (pPrimaryDNS == 0 && pSecondaryDNS == 0)
+ {
+ // At least one must be specified
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ WORD msgID = (WORD)eQMI_WDS_SET_DNS;
+ std::vector <sDB2PackingInput> piv;
+
+ if (pPrimaryDNS != 0)
+ {
+ ULONG ip4 = (*pPrimaryDNS & 0x000000FF);
+ ULONG ip3 = (*pPrimaryDNS & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pPrimaryDNS & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pPrimaryDNS & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 16 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ if (pSecondaryDNS != 0)
+ {
+ ULONG ip4 = (*pSecondaryDNS & 0x000000FF);
+ ULONG ip3 = (*pSecondaryDNS & 0x0000FF00) >> 8;
+ ULONG ip2 = (*pSecondaryDNS & 0x00FF0000) >> 16;
+ ULONG ip1 = (*pSecondaryDNS & 0xFF000000) >> 24;
+
+ // "%u %u %u %u"
+ std::ostringstream tmp;
+ tmp << (UINT)ip4 << " " << (UINT)ip3 << " " << (UINT)ip2
+ << " " << (UINT)ip1;
+
+ sProtocolEntityKey pek( eDB2_ET_QMI_WDS_REQ, msgID, 17 );
+ sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
+ piv.push_back( pi );
+ }
+
+ // Pack up and send the QMI request
+ const cCoreDatabase & db = GetDatabase();
+ sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
+
+ // Send the QMI request, check result, and return
+ return SendAndCheckReturn( eQMI_SVC_WDS, pRequest );
+}
+
+/*===========================================================================
+METHOD:
+ GetDNSSettings
+
+DESCRIPTION:
+ This function gets the DNS settings for the device
+
+PARAMETERS:
+ pPrimaryDNS [ O ] - Primary DNS IPv4 address
+ pSecondaryDNS [ O ] - Secondary DNS IPv4 address
+
+RETURN VALUE:
+ eGobiError - Return code
+===========================================================================*/
+eGobiError cGobiQMICore::GetDNSSettings(
+ ULONG * pPrimaryDNS,
+ ULONG * pSecondaryDNS )
+{
+ // Validate arguments
+ if (pPrimaryDNS == 0 || pSecondaryDNS == 0)
+ {
+ return eGOBI_ERR_INVALID_ARG;
+ }
+
+ *pPrimaryDNS = 0;
+ *pSecondaryDNS = 0;
+
+ // Generate and send the QMI request
+ WORD msgID = (WORD)eQMI_WDS_GET_DNS;
+ sProtocolBuffer rsp = SendSimple( eQMI_SVC_WDS, 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_WDS_RSP, msgID, 16 );
+ cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 4)
+ {
+ ULONG ip4 = (ULONG)pf[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf[3].mValue.mU8 << 24;
+ *pPrimaryDNS = (ip4 | ip3 | ip2 | ip1);
+ }
+
+ tlvKey = sProtocolEntityKey( eDB2_ET_QMI_WDS_RSP, msgID, 17 );
+ pf = ParseTLV( db, rsp, tlvs, tlvKey );
+ if (pf.size() >= 4)
+ {
+ ULONG ip4 = (ULONG)pf[0].mValue.mU8;
+ ULONG ip3 = (ULONG)pf[1].mValue.mU8 << 8;
+ ULONG ip2 = (ULONG)pf[2].mValue.mU8 << 16;
+ ULONG ip1 = (ULONG)pf[3].mValue.mU8 << 24;
+ *pSecondaryDNS = (ip4 | ip3 | ip2 | ip1);
+ }
+
+ return eGOBI_ERR_NONE;
+}