libqmi-qmuxd/gobi-api/GobiAPI_1.0.40/Shared/GobiQMICoreDMS.cpp

2051 lines
56 KiB
C++
Executable File

/*===========================================================================
FILE:
GobiQMICoreDMS.cpp
DESCRIPTION:
QUALCOMM Gobi QMI Based API Core (DMS 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:
GetDeviceCapabilities (Public Method)
DESCRIPTION:
This function gets device capabilities
PARAMETERS:
pMaxTXChannelRate [ O ] - Maximum transmission rate (bps)
pMaxRXChannelRate [ O ] - Maximum reception rate (bps)
pDataServiceCapability [ O ] - CS/PS data service capability
pSimCapability [ O ] - Device SIM support
pRadioIfacesSize [I/O] - Upon input the maximum number of elements
that the radio interfaces can contain.
Upon successful output the actual number
of elements in the radio interface array
pRadioIfaces [ O ] - The radio interface array
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetDeviceCapabilities(
ULONG * pMaxTXChannelRate,
ULONG * pMaxRXChannelRate,
ULONG * pDataServiceCapability,
ULONG * pSimCapability,
ULONG * pRadioIfacesSize,
BYTE * pRadioIfaces )
{
// Validate arguments
if ( (pMaxTXChannelRate == 0)
|| (pMaxRXChannelRate == 0)
|| (pDataServiceCapability == 0)
|| (pSimCapability == 0)
|| (pRadioIfacesSize == 0)
|| (*pRadioIfacesSize == 0)
|| (pRadioIfaces == 0) )
{
return eGOBI_ERR_INVALID_ARG;
}
ULONG maxRadioIfaces = (ULONG)*pRadioIfacesSize;
// Assume failure
*pRadioIfacesSize = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_CAPS;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 5)
{
return eGOBI_ERR_INVALID_RSP;
}
// Populate the variables
*pMaxTXChannelRate = pf[0].mValue.mU32;
*pMaxRXChannelRate = pf[1].mValue.mU32;
*pDataServiceCapability = pf[2].mValue.mU32;
*pSimCapability = pf[3].mValue.mU8;
ULONG activeRadioIfaces = (ULONG)pf[4].mValue.mU8;
if (pf.size() < 5 + activeRadioIfaces)
{
return eGOBI_ERR_INVALID_RSP;
}
if (activeRadioIfaces > maxRadioIfaces)
{
activeRadioIfaces = maxRadioIfaces;
}
ULONG * pOutRadioIfaces = (ULONG *)pRadioIfaces;
for (ULONG r = 0; r < activeRadioIfaces; r++)
{
*pOutRadioIfaces++ = pf[5 + r].mValue.mU32;
}
*pRadioIfacesSize = activeRadioIfaces;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetManufacturer (Public Method)
DESCRIPTION:
This function returns the device manufacturer name
PARAMETERS:
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetManufacturer(
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_MANUFACTURER;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
LONG strLen = pf[0].mValueString.size();
if (strLen <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to perform the copy?
if (stringSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pString, (LPCSTR)pf[0].mValueString.c_str(), strLen );
pString[strLen] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetModelID (Public Method)
DESCRIPTION:
This function returns the device model ID
PARAMETERS:
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetModelID(
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_MODEL_ID;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
LONG strLen = pf[0].mValueString.size();
if (strLen <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to perform the copy?
if (stringSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pString, (LPCSTR)pf[0].mValueString.c_str(), strLen );
pString[strLen] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetFirmwareRevision (Public Method)
DESCRIPTION:
This function returns the device firmware revision
PARAMETERS:
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetFirmwareRevision(
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_REV_ID;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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 (PRI revision)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_DMS_RSP, msgID, 17 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1 || pf[0].mValueString.size() <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
std::string tmpPRI = pf[0].mValueString;
ULONG lenPRI = (ULONG)tmpPRI.size();
// Space to perform the copy?
if (stringSize < lenPRI + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pString, (LPCSTR)tmpPRI.c_str(), lenPRI + 1 );
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetFirmwareRevisions (Public Method)
DESCRIPTION:
This function returns the device firmware (AMSS, boot, and PRI)
revisions
PARAMETERS:
amssSize [ I ] - The maximum number of characters (including NULL
terminator) that the AMSS string array can contain
pAMSSString [ O ] - NULL terminated AMSS revision string
bootSize [ I ] - The maximum number of characters (including NULL
terminator) that the boot string array can contain
pBootString [ O ] - NULL terminated boot code revision string
priSize [ I ] - The maximum number of characters (including NULL
terminator) that the PRI string array can contain
pPRIString [ O ] - NULL terminated PRI revision string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetFirmwareRevisions(
BYTE amssSize,
CHAR * pAMSSString,
BYTE bootSize,
CHAR * pBootString,
BYTE priSize,
CHAR * pPRIString )
{
// Validate arguments
if ( (amssSize == 0 || pAMSSString == 0)
|| (bootSize == 0 || pBootString == 0)
|| (priSize == 0 || pPRIString == 0) )
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pAMSSString = 0;
*pBootString = 0;
*pPRIString = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_REV_ID;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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 (PRI revision)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_DMS_RSP, msgID, 17 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1 || pf[0].mValueString.size() <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
std::string tmpPRI = pf[0].mValueString;
ULONG lenPRI = (ULONG)tmpPRI.size();
// Space to perform the copy?
if (priSize < lenPRI + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pPRIString, (LPCSTR)tmpPRI.c_str(), lenPRI + 1 );
// Parse the TLV we want (boot code revision)
tlvKey = sProtocolEntityKey( eDB2_ET_QMI_DMS_RSP, msgID, 16 );
pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1 || pf[0].mValueString.size() <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
std::string tmpBoot = pf[0].mValueString;
ULONG lenBoot = (ULONG)tmpBoot.size();
// Space to perform the copy?
if (bootSize < lenBoot + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pBootString, (LPCSTR)tmpBoot.c_str(), lenBoot + 1 );
// Parse the TLV we want (AMSS revision)
tlvKey = sProtocolEntityKey( eDB2_ET_QMI_DMS_RSP, msgID, 1 );
pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1 || pf[0].mValueString.size() <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
std::string tmpAMSS = pf[0].mValueString;
ULONG lenAMSS = (ULONG)tmpAMSS.size();
// Space to perform the copy?
if (amssSize < lenAMSS + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pAMSSString, (LPCSTR)tmpAMSS.c_str(), lenAMSS + 1 );
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetVoiceNumber (Public Method)
DESCRIPTION:
This function returns the voice number in use by the device
PARAMETERS:
voiceNumberSize [ I ] - The maximum number of characters (including NULL
terminator) that the voice number array can
contain
pVoiceNumber [ O ] - Voice number (MDN or ISDN) string
minSize [ I ] - The maximum number of characters (including NULL
terminator) that the MIN array can contain
pMIN [ O ] - MIN string (empty string returned when MIN is
not supported/programmed)
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetVoiceNumber(
BYTE voiceNumberSize,
CHAR * pVoiceNumber,
BYTE minSize,
CHAR * pMIN )
{
// Validate arguments
if (voiceNumberSize == 0 || pVoiceNumber == 0 || minSize == 0 || pMIN == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pVoiceNumber = 0;
*pMIN = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_NUMBER;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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 tlvKey1( eDB2_ET_QMI_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf1 = ParseTLV( db, rsp, tlvs, tlvKey1 );
if (pf1.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
LONG strLen = pf1[0].mValueString.size();
if (strLen <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to perform the copy?
if (voiceNumberSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pVoiceNumber, (LPCSTR)pf1[0].mValueString.c_str(), strLen );
pVoiceNumber[strLen] = 0;
// Parse the optional TLV we want (by DB key)
sProtocolEntityKey tlvKey2( eDB2_ET_QMI_DMS_RSP, msgID, 16 );
cDataParser::tParsedFields pf2 = ParseTLV( db, rsp, tlvs, tlvKey2 );
if (pf2.size() >= 1)
{
strLen = pf2[0].mValueString.size();
if (strLen <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to perform the copy?
if (minSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pMIN, (LPCSTR)pf2[0].mValueString.c_str(), strLen );
pMIN[strLen] = 0;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetIMSI (Public Method)
DESCRIPTION:
This function returns the device IMSI
PARAMETERS:
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetIMSI(
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_IMSI;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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 (IMSI)
sProtocolEntityKey tlvKey( eDB2_ET_QMI_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1 || pf[0].mValueString.size() <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
std::string tmpIMSI = pf[0].mValueString;
ULONG lenIMSI = (ULONG)tmpIMSI.size();
// Space to perform the copy?
if (stringSize < lenIMSI + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pString, (LPCSTR)tmpIMSI.c_str(), lenIMSI + 1 );
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetSerialNumbers (Public Method)
DESCRIPTION:
This command returns all serial numbers assigned to the device
PARAMETERS:
esnSize [ I ] - The maximum number of characters (including NULL
terminator) that the ESN array can contain
pESNString [ O ] - ESN string (empty string returned when ESN is
not supported/programmed)
imeiSize [ I ] - The maximum number of characters (including NULL
terminator) that the IMEI array can contain
pIMEIString [ O ] - IMEI string (empty string returned when IMEI is
not supported/programmed)
meidSize [ I ] - The maximum number of characters (including NULL
terminator) that the MEID array can contain
pMEIDString [ O ] - MEID string (empty string returned when MEID is
not supported/programmed)
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetSerialNumbers(
BYTE esnSize,
CHAR * pESNString,
BYTE imeiSize,
CHAR * pIMEIString,
BYTE meidSize,
CHAR * pMEIDString )
{
// Validate arguments
if ( (esnSize == 0)
|| (pESNString == 0)
|| (imeiSize == 0)
|| (pIMEIString == 0)
|| (meidSize == 0)
|| (pMEIDString == 0) )
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pESNString = 0;
*pIMEIString = 0;
*pMEIDString = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_IDS;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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 optional TLV we want (by DB key)
sProtocolEntityKey tlvKey1( eDB2_ET_QMI_DMS_RSP, msgID, 16 );
cDataParser::tParsedFields pf1 = ParseTLV( db, rsp, tlvs, tlvKey1 );
if (pf1.size() >= 1)
{
LONG strLen = pf1[0].mValueString.size();
if (strLen <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to perform the copy?
if (esnSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pESNString, (LPCSTR)pf1[0].mValueString.c_str(), strLen );
pESNString[strLen] = 0;
}
// Parse the optional TLV we want (by DB key)
sProtocolEntityKey tlvKey2( eDB2_ET_QMI_DMS_RSP, msgID, 17 );
cDataParser::tParsedFields pf2 = ParseTLV( db, rsp, tlvs, tlvKey2 );
if (pf2.size() >= 1)
{
LONG strLen = pf2[0].mValueString.size();
if (strLen <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to perform the copy?
if (imeiSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pIMEIString, (LPCSTR)pf2[0].mValueString.c_str(), strLen );
pIMEIString[strLen] = 0;
}
// Parse the optional TLV we want (by DB key)
sProtocolEntityKey tlvKey3( eDB2_ET_QMI_DMS_RSP, msgID, 18 );
cDataParser::tParsedFields pf3 = ParseTLV( db, rsp, tlvs, tlvKey3 );
if (pf3.size() >= 1)
{
LONG strLen = pf3[0].mValueString.size();
if (strLen <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to perform the copy?
if (meidSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pMEIDString, (LPCSTR)pf3[0].mValueString.c_str(), strLen );
pMEIDString[strLen] = 0;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
SetLock (Public Method)
DESCRIPTION:
This function sets the user lock state maintained by the device
PARAMETERS:
state [ I ] - Desired lock state
pCurrentPIN [ I ] - Current four digit PIN string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::SetLock(
ULONG state,
CHAR * pCurrentPIN )
{
// Validate arguments
if (pCurrentPIN == 0 || pCurrentPIN[0] == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
std::string thePIN( pCurrentPIN );
if (thePIN.size() > 4)
{
return eGOBI_ERR_INVALID_ARG;
}
int nNonDigit = thePIN.find_first_not_of( "0123456789" );
std::string digitPIN = thePIN.substr( 0, nNonDigit );
if (digitPIN.size() != thePIN.size())
{
return eGOBI_ERR_INVALID_ARG;
}
WORD msgID = (WORD)eQMI_DMS_SET_USER_LOCK_STATE;
std::vector <sDB2PackingInput> piv;
// "%u %s"
std::ostringstream tmp;
tmp << (UINT)state << " " << thePIN;
sProtocolEntityKey pek( eDB2_ET_QMI_DMS_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_DMS, pRequest );
}
/*===========================================================================
METHOD:
QueryLock (Public Method)
DESCRIPTION:
This function sets the user lock state maintained by the device
PARAMETERS:
pState [ O ] - Current lock state
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::QueryLock( ULONG * pState )
{
// Validate arguments
if (pState == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_USER_LOCK_STATE;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
// Populate the mode
*pState = pf[0].mValue.mU32;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ChangeLockPIN (Public Method)
DESCRIPTION:
This command sets the user lock code maintained by the device
PARAMETERS:
pCurrentPIN [ O ] - Current four digit PIN string
pDesiredPIN [ O ] - New four digit PIN string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::ChangeLockPIN(
CHAR * pCurrentPIN,
CHAR * pDesiredPIN )
{
// Validate arguments
if ( (pCurrentPIN == 0)
|| (pCurrentPIN[0] == 0)
|| (pDesiredPIN == 0)
|| (pDesiredPIN[0] == 0) )
{
return eGOBI_ERR_INVALID_ARG;
}
std::string theCurPIN( pCurrentPIN );
if (theCurPIN.size() > 4)
{
return eGOBI_ERR_INVALID_ARG;
}
int nNonDigit = theCurPIN.find_first_not_of( "0123456789" );
std::string digitCurPIN = theCurPIN.substr( 0, nNonDigit );
if (digitCurPIN.size() != theCurPIN.size())
{
return eGOBI_ERR_INVALID_ARG;
}
std::string theNewPIN( pDesiredPIN );
if (theNewPIN.size() > 4)
{
return eGOBI_ERR_INVALID_ARG;
}
nNonDigit = theNewPIN.find_first_not_of( "0123456789" );
std::string digitNewPIN = theNewPIN.substr( 0, nNonDigit );
if (digitNewPIN.size() != theNewPIN.size())
{
return eGOBI_ERR_INVALID_ARG;
}
WORD msgID = (WORD)eQMI_DMS_SET_USER_LOCK_CODE;
std::vector <sDB2PackingInput> piv;
// "%s %s"
std::ostringstream tmp;
tmp << theCurPIN << " " << theNewPIN;
sProtocolEntityKey pek( eDB2_ET_QMI_DMS_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_DMS, pRequest );
}
/*===========================================================================
METHOD:
GetHardwareRevision (Public Method)
DESCRIPTION:
This function returns the device hardware revision
PARAMETERS:
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetHardwareRevision(
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_MSM_ID;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
LONG strLen = pf[0].mValueString.size();
if (strLen <= 0)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to perform the copy?
if (stringSize < strLen + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( (LPVOID)pString, (LPCSTR)pf[0].mValueString.c_str(), strLen );
pString[strLen] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetPRLVersion (Public Method)
DESCRIPTION:
This function returns the version of the active Preferred Roaming List
(PRL) in use by the device
PARAMETERS:
pPRLVersion [ O ] - The PRL version number
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetPRLVersion( WORD * pPRLVersion )
{
// Validate arguments
if (pPRLVersion == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_PRL_VERSION;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
*pPRLVersion = pf[0].mValue.mU16;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetERIFile (Public Method)
DESCRIPTION:
This command returns the ERI file that is stored in EFS on the device
PARAMETERS:
pFileSize [I/O] - Upon input the maximum number of bytes that the file
contents array can contain. Upon successful output
the actual number of bytes written to the file contents
array
pFile [ O ] - The file contents
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetERIFile(
ULONG * pFileSize,
BYTE * pFile )
{
// Validate arguments
if (pFileSize == 0 || *pFileSize == 0 || pFile == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
ULONG maxFileSize = *pFileSize;
*pFileSize = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_READ_ERI_FILE;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
ULONG fileSz = pf[0].mValue.mU16;
if (pf.size() < 1 + fileSz)
{
return eGOBI_ERR_INVALID_RSP;
}
// Space to copy into?
if (fileSz > maxFileSize)
{
return eGOBI_ERR_BUFFER_SZ;
}
for (ULONG f = 0; f < fileSz; f++)
{
pFile[f] = pf[1 + f].mValue.mU8;
}
*pFileSize = fileSz;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ActivateAutomatic (Public Method)
DESCRIPTION:
This function requests the device to perform automatic service activation
PARAMETERS:
pActivationCode [ I ] - Activation code (maximum string length of 12)
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::ActivateAutomatic( CHAR * pActivationCode )
{
// Validate arguments
if ( (pActivationCode == 0)
|| (pActivationCode[0] == 0) )
{
return eGOBI_ERR_INVALID_ARG;
}
std::string ac( pActivationCode );
if (ac.size() > 12)
{
return eGOBI_ERR_INVALID_ARG;
}
WORD msgID = (WORD)eQMI_DMS_ACTIVATE_AUTOMATIC;
std::vector <sDB2PackingInput> piv;
std::ostringstream tmp;
tmp << (ULONG)ac.size() << " \"" << ac << "\"";
sProtocolEntityKey pek( eDB2_ET_QMI_DMS_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_DMS, pRequest, 300000 );
}
/*===========================================================================
METHOD:
ActivateManual (Public Method)
DESCRIPTION:
This function requests the device perform manual service activation,
after a successful request the device is then asked to reset
PARAMETERS:
pSPC [ I ] - NULL terminated string representing the six digit
service programming code
sid [ I ] - System identification number
pMDN [ I ] - Mobile Directory Number string
pMIN [ I ] - Mobile Identification Number string
prlSize [ I ] - (Optional) Size of PRL file array
pPRL [ I ] - (Optional) The PRL file contents
pMNHA [ I ] - (Optional) MN-HA string
pMNAAA [ I ] - (Optional) MN-AAA string
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::ActivateManual(
CHAR * pSPC,
WORD sid,
CHAR * pMDN,
CHAR * pMIN,
ULONG prlSize,
BYTE * pPRL,
CHAR * pMNHA,
CHAR * pMNAAA )
{
// Validate arguments
if ( (pSPC == 0)
|| (pSPC[0] == 0)
|| (pMDN == 0)
|| (pMDN[0] == 0)
|| (pMIN == 0)
|| (pMIN[0] == 0)
|| (prlSize > QMI_DMS_MAX_PRL_SIZE) )
{
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;
}
std::string theMDN( pMDN );
if (theMDN.size() > 16)
{
return eGOBI_ERR_INVALID_ARG;
}
nNonDigit = theMDN.find_first_not_of( "0123456789" );
std::string digitMDN = theMDN.substr( 0, nNonDigit );
if (digitMDN.size() != theMDN.size())
{
return eGOBI_ERR_INVALID_ARG;
}
std::string theMIN( pMIN );
if (theMIN.size() > 16)
{
return eGOBI_ERR_INVALID_ARG;
}
nNonDigit = theMIN.find_first_not_of( "0123456789" );
std::string digitMIN = theMIN.substr( 0, nNonDigit );
if (digitMIN.size() != theMIN.size())
{
return eGOBI_ERR_INVALID_ARG;
}
std::string theMNHA;
if (pMNHA != 0 && pMNHA[0] != 0)
{
theMNHA = pMNHA;
if (theMNHA.size() > 16)
{
return eGOBI_ERR_INVALID_ARG;
}
}
std::string theMNAAA;
if (pMNAAA != 0 && pMNAAA[0] != 0)
{
theMNAAA = pMNAAA;
if (theMNAAA.size() > 16)
{
return eGOBI_ERR_INVALID_ARG;
}
}
WORD msgID = (WORD)eQMI_DMS_ACTIVATE_MANUAL;
std::vector <sDB2PackingInput> piv;
// "%s %u %d %s %d %s"
std::ostringstream tmp;
tmp << spc << " " << (UINT)sid << " " << theMDN.size() << " " << theMDN
<< " " << theMIN.size() << " " << theMIN;
sProtocolEntityKey pek( eDB2_ET_QMI_DMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi );
if (theMNHA.size() > 0)
{
sProtocolEntityKey pek1( eDB2_ET_QMI_DMS_REQ, msgID, 17 );
std::ostringstream tmp;
tmp << (int)theMNHA.size() << " \"" << theMNHA << "\"";
sDB2PackingInput pi1( pek1, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi1 );
}
if (theMNAAA.size() > 0)
{
sProtocolEntityKey pek1( eDB2_ET_QMI_DMS_REQ, msgID, 18 );
std::ostringstream tmp;
tmp << (int)theMNAAA.size() << " \"" << theMNAAA << "\"";
sDB2PackingInput pi1( pek1, (LPCSTR)tmp.str().c_str() );
piv.push_back( pi1 );
}
// Do we need to go through the anguish of the segmented PRL?
if (prlSize > 0)
{
ULONG blockSz = QMI_DMS_MAX_PRL_BLOCK;
// Determine number of writes
ULONG writes = prlSize / blockSz;
if ((prlSize % blockSz) != 0)
{
writes++;
}
ULONG offset = 0;
ULONG to = DEFAULT_GOBI_QMI_TIMEOUT;
// Generate and send requests
eGobiError err = eGOBI_ERR_NONE;
for (ULONG w = 0; w < writes; w++)
{
if (w == writes - 1)
{
to = 300000;
if ((prlSize % blockSz) != 0)
{
blockSz = prlSize % blockSz;
}
}
std::vector <sDB2PackingInput> pivLocal = piv;
// "%u %u %u"
std::ostringstream tmp2;
tmp2 << (UINT)prlSize << " " << (UINT)blockSz
<< " " << (UINT)w;
for (ULONG p = 0; p < blockSz; p++)
{
tmp2 << " " << (UINT)pPRL[offset + p];
}
sProtocolEntityKey pek( eDB2_ET_QMI_DMS_REQ, msgID, 19 );
sDB2PackingInput pi( pek, (LPCSTR)tmp2.str().c_str() );
pivLocal.push_back( pi );
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, pivLocal );
// Send the QMI request, check result, and return
err = SendAndCheckReturn( eQMI_SVC_DMS, pRequest, to );
if (err != eGOBI_ERR_NONE)
{
break;
}
else
{
offset += blockSz;
}
}
if (err != eGOBI_ERR_NONE)
{
return err;
}
}
else
{
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
// Send the QMI request, check result, and return
eGobiError rc = SendAndCheckReturn( eQMI_SVC_DMS, pRequest, 300000 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
}
// Ask device to power down
eGobiError rc = SetPower( 5 );
if (rc != eGOBI_ERR_NONE)
{
return eGOBI_ERR_RESET;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ResetToFactoryDefaults (Public Method)
DESCRIPTION:
This function requests the device reset configuration to factory defaults,
after a successful request the device is then asked to reset
PARAMETERS:
pSPC [ I ] - NULL terminated string representing the six digit
service programming code
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::ResetToFactoryDefaults( CHAR * pSPC )
{
// 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_DMS_FACTORY_DEFAULTS;
std::vector <sDB2PackingInput> piv;
sProtocolEntityKey pek( eDB2_ET_QMI_DMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)spc.c_str() );
piv.push_back( pi );
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
// Send the QMI request and check result
eGobiError rc = SendAndCheckReturn( eQMI_SVC_DMS, pRequest, 300000 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Ask device to power down
rc = SetPower( 5 );
if (rc != eGOBI_ERR_NONE)
{
return eGOBI_ERR_RESET;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetActivationState (Public Method)
DESCRIPTION:
This function returns the device activation state
PARAMETERS:
pActivationState [ O ] - Service activation state
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetActivationState( ULONG * pActivationState )
{
// Validate arguments
if (pActivationState == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_ACTIVATED_STATE;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
*pActivationState = pf[0].mValue.mU32;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
SetPower (Public Method)
DESCRIPTION:
This function sets the operating mode of the device
PARAMETERS:
powerMode [ I ] - Selected operating mode
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::SetPower( ULONG powerMode )
{
WORD msgID = (WORD)eQMI_DMS_SET_OPERATING_MODE;
std::vector <sDB2PackingInput> piv;
std::ostringstream tmp;
tmp << (UINT)powerMode;
sProtocolEntityKey pek( eDB2_ET_QMI_DMS_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_DMS, pRequest );
}
/*===========================================================================
METHOD:
GetPower (Public Method)
DESCRIPTION:
This function returns the operating mode of the device
PARAMETERS:
pPowerMode [ O ] - Current operating mode
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetPower( ULONG * pPowerMode )
{
// Validate arguments
if (pPowerMode == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pPowerMode = ULONG_MAX;
ULONG reasonMask = 0;
ULONG bPlatform = 0;
eGobiError rc = GetPowerInfo( pPowerMode, &reasonMask, &bPlatform );
return rc;
}
/*===========================================================================
METHOD:
GetPowerInfo (Public Method)
DESCRIPTION:
This function returns operating mode info from the device
PARAMETERS:
pPowerMode [ O ] - Current operating mode
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetPowerInfo(
ULONG * pPowerMode,
ULONG * pReasonMask,
ULONG * pbPlatform )
{
// Validate arguments
if (pPowerMode == 0 || pReasonMask == 0 || pbPlatform == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pPowerMode = ULONG_MAX;
*pReasonMask = 0;
*pbPlatform = 0;
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_OPERTAING_MODE;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
*pPowerMode = pf[0].mValue.mU32;
// Parse the TLV we want (by DB key)
tlvKey = sProtocolEntityKey( eDB2_ET_QMI_DMS_RSP, msgID, 16 );
pf = ParseTLV( db, rsp, tlvs, tlvKey );
// Convert back to a bitmask
ULONG fieldCount = (ULONG)pf.size();
if (fieldCount > 16)
{
fieldCount = 16;
}
for (ULONG f = 0; f < fieldCount; f++)
{
ULONG val = (ULONG)pf[f].mValue.mU8 & 0x00000001;
*pReasonMask |= (val << f);
}
// Parse the TLV we want (by DB key)
tlvKey = sProtocolEntityKey( eDB2_ET_QMI_DMS_RSP, msgID, 17 );
pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() >= 1)
{
*pbPlatform = (ULONG)pf[0].mValue.mU8;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
GetOfflineReason
DESCRIPTION:
This function returns the reason why the operating mode of the device
is currently offline
PARAMETERS:
pReasonMask [ O ] - Bitmask of offline reasons
pbPlatform [ O ] - Offline due to being platform retricted?
RETURN VALUE:
ULONG - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetOfflineReason(
ULONG * pReasonMask,
ULONG * pbPlatform )
{
// Validate arguments
if (pReasonMask == 0 || pbPlatform == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pReasonMask = 0;
*pbPlatform = 0;
ULONG powerMode = 0;
eGobiError rc = GetPowerInfo( &powerMode, pReasonMask, pbPlatform );
return rc;
}
/*===========================================================================
METHOD:
GetNetworkTime (Public Method)
DESCRIPTION:
This function returns the current time of the device
PARAMETERS:
pTimeStamp [ O ] - Count of 1.25ms that have elapsed from the start
of GPS time (Jan 6, 1980)
pTimeSource [ O ] - Source of the timestamp
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetNetworkTime(
ULONGLONG * pTimeCount,
ULONG * pTimeSource )
{
// Validate arguments
if (pTimeCount == 0 || pTimeSource == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Generate and send the QMI request
WORD msgID = (WORD)eQMI_DMS_GET_TIME;
sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, 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_DMS_RSP, msgID, 1 );
cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
if (pf.size() < 1)
{
return eGOBI_ERR_INVALID_RSP;
}
*pTimeCount = pf[0].mValue.mU64;
*pTimeSource = pf[1].mValue.mU32;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ValidateSPC (Public Method)
DESCRIPTION:
This function validates the service programming code
PARAMETERS:
pSPC [ I ] - Six digit service programming code
RETURN VALUE:
eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::ValidateSPC( CHAR * pSPC )
{
// 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_DMS_VALIDATE_SPC;
std::vector <sDB2PackingInput> piv;
sProtocolEntityKey pek( eDB2_ET_QMI_DMS_REQ, msgID, 1 );
sDB2PackingInput pi( pek, (LPCSTR)spc.c_str() );
piv.push_back( pi );
// Pack up the QMI request
const cCoreDatabase & db = GetDatabase();
sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );
// Send the QMI request and check result
return SendAndCheckReturn( eQMI_SVC_DMS, pRequest );
}