2805 lines
80 KiB
C++
Executable File
2805 lines
80 KiB
C++
Executable File
/*===========================================================================
|
|
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;
|
|
}
|