libqmi-qmuxd/gobi-api/GobiAPI_2013-07-31-1347/Gobi3000Translation/Gobi3000TranslationDMS.cpp

1483 lines
40 KiB
C++

/*===========================================================================
FILE:
Gobi3000TranslationDMS.cpp
DESCRIPTION:
QUALCOMM Translation for Gobi 3000 (DMS Service)
Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 "Gobi3000Translation.h"
/*===========================================================================
METHOD:
ParseGetDeviceCapabilities
DESCRIPTION:
This function gets device capabilities
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
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:
ULONG - Return code
===========================================================================*/
ULONG ParseGetDeviceCapabilities(
ULONG inLen,
const BYTE * pIn,
ULONG * pMaxTXChannelRate,
ULONG * pMaxRXChannelRate,
ULONG * pDataServiceCapability,
ULONG * pSimCapability,
ULONG * pRadioIfacesSize,
BYTE * pRadioIfaces )
{
// Validate arguments
if (pIn == 0
|| 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;
const sDMSGetDeviceCapabilitiesResponse_Capabilities * pTLVx01;
ULONG structSzx01 = sizeof( sDMSGetDeviceCapabilitiesResponse_Capabilities );
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < structSzx01)
{
return eGOBI_ERR_BUFFER_SZ;
}
// Populate the variables
*pMaxTXChannelRate = pTLVx01->mMaxTXRatebps;
*pMaxRXChannelRate = pTLVx01->mMaxRXRatebps;
*pDataServiceCapability = pTLVx01->mDataServiceCapability;
// SIM capability should be treated as a boolean, even though it's not
*pSimCapability = (pTLVx01->mSIMSupported == 0 ? 0 : 1);
ULONG activeRadioIfaces = pTLVx01->mRadioInterfaceCount;
if (activeRadioIfaces > maxRadioIfaces)
{
activeRadioIfaces = maxRadioIfaces;
}
const eQMIDMSRadioInterfaces * pInRadioInterfaces;
// Verify there is room for the array in the TLV
if (outLenx01 < structSzx01
+ sizeof( eQMIDMSRadioInterfaces ) * activeRadioIfaces)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Align to the first array element
pInRadioInterfaces = (const eQMIDMSRadioInterfaces *)
((const BYTE *)pTLVx01 + structSzx01);
ULONG * pOutRadioIfaces = (ULONG *)pRadioIfaces;
for (ULONG r = 0; r < activeRadioIfaces; r++)
{
*pOutRadioIfaces = *pInRadioInterfaces;
pOutRadioIfaces++;
pInRadioInterfaces++;
}
*pRadioIfacesSize = activeRadioIfaces;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetManufacturer
DESCRIPTION:
This function returns the device manufacturer name
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetManufacturer(
ULONG inLen,
const BYTE * pIn,
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (pIn == 0 || stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Find the manufacturer
// sDMSGetDeviceManfacturerResponse_Manfacturer only contains this
const CHAR * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (stringSize < outLenx01 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pString, pTLVx01, outLenx01 );
pString[outLenx01] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetModelID
DESCRIPTION:
This function returns the device model ID
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetModelID(
ULONG inLen,
const BYTE * pIn,
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (pIn == 0 || stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Find the model
// sDMSGetDeviceModelResponse_Model only contains the model
const CHAR * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (stringSize < outLenx01 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pString, pTLVx01, outLenx01 );
pString[outLenx01] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetFirmwareRevision
DESCRIPTION:
This function returns the device firmware revision
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetFirmwareRevision(
ULONG inLen,
const BYTE * pIn,
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (pIn == 0 || stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Find the PRI revision
// sDMSGetDeviceRevisionResponse_UQCNRevision only contains this
const CHAR * pTLVx11;
ULONG outLenx11;
ULONG rc = GetTLV( inLen, pIn, 0x11, &outLenx11, (const BYTE **)&pTLVx11 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (stringSize < outLenx11 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pString, pTLVx11, outLenx11 );
pString[outLenx11] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetFirmwareRevisions
DESCRIPTION:
This function returns the device firmware (AMSS, boot, and PRI)
revisions
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
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:
ULONG - Return code
===========================================================================*/
ULONG ParseGetFirmwareRevisions(
ULONG inLen,
const BYTE * pIn,
BYTE amssSize,
CHAR * pAMSSString,
BYTE bootSize,
CHAR * pBootString,
BYTE priSize,
CHAR * pPRIString )
{
// Validate arguments
if (pIn == 0
|| 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;
// Find the AMSS version
// sDMSGetDeviceRevisionResponse_Revision only contains this
const CHAR * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (amssSize < outLenx01 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pAMSSString, pTLVx01, outLenx01 );
pAMSSString[outLenx01] = 0;
// Find the Boot version
// sDMSGetDeviceRevisionResponse_BootCodeRevision only contains this
const CHAR * pTLVx10;
ULONG outLenx10;
rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (bootSize < outLenx10 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pBootString, pTLVx10, outLenx10 );
pBootString[outLenx10] = 0;
// The PRI version is returned by ParseGetFirmwareRevision()
rc = ParseGetFirmwareRevision( inLen, pIn, priSize, pPRIString );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetVoiceNumber
DESCRIPTION:
This function returns the voice number in use by the device
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
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:
ULONG - Return code
===========================================================================*/
ULONG ParseGetVoiceNumber(
ULONG inLen,
const BYTE * pIn,
BYTE voiceNumberSize,
CHAR * pVoiceNumber,
BYTE minSize,
CHAR * pMIN )
{
// Validate arguments
if (pIn == 0
|| voiceNumberSize == 0 || pVoiceNumber == 0
|| minSize == 0 || pMIN == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pVoiceNumber = 0;
*pMIN = 0;
// Find the Voice number
// sDMSGetDeviceVoiceNumberResponse_VoiceNumber only contains this
const CHAR * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (voiceNumberSize < outLenx01 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pVoiceNumber, pTLVx01, outLenx01 );
pVoiceNumber[outLenx01] = 0;
// Find the Mobile ID (optional)
// sDMSGetDeviceVoiceNumberResponse_MobileIDNumber only contains this
const CHAR * pTLVx10;
ULONG outLenx10;
rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
if (rc == eGOBI_ERR_NONE)
{
// Space to perform the copy?
if (minSize < outLenx10 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pMIN, pTLVx10, outLenx10 );
pMIN[outLenx10] = 0;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetIMSI
DESCRIPTION:
This function returns the device IMSI
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetIMSI(
ULONG inLen,
const BYTE * pIn,
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (pIn == 0 || stringSize == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pString = 0;
// Find the IMSI
// sDMSGetDeviceVoiceNumberResponse_IMSI only contains this
const CHAR * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (stringSize < outLenx01 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pString, pTLVx01, outLenx01 );
pString[outLenx01] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetSerialNumbers
DESCRIPTION:
This command returns all serial numbers assigned to the device
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
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:
ULONG - Return code
===========================================================================*/
ULONG ParseGetSerialNumbers(
ULONG inLen,
const BYTE * pIn,
BYTE esnSize,
CHAR * pESNString,
BYTE imeiSize,
CHAR * pIMEIString,
BYTE meidSize,
CHAR * pMEIDString )
{
// Validate arguments
if (pIn == 0
|| 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;
// Find the ESN
// sDMSGetDeviceSerialNumbersResponse_ESN only contains this
const CHAR * pTLVx10;
ULONG outLenx10;
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (esnSize < outLenx10 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pESNString, pTLVx10, outLenx10 );
pESNString[outLenx10] = 0;
// Find the IMEI
// sDMSGetDeviceSerialNumbersResponse_IMEI only contains this
const CHAR * pTLVx11;
ULONG outLenx11;
rc = GetTLV( inLen, pIn, 0x11, &outLenx11, (const BYTE **)&pTLVx11 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (imeiSize < outLenx11 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pIMEIString, pTLVx11, outLenx11 );
pIMEIString[outLenx11] = 0;
// Find the MEID
// sDMSGetDeviceSerialNumbersResponse_MEID only contains this
const CHAR * pTLVx12;
ULONG outLenx12;
rc = GetTLV( inLen, pIn, 0x12, &outLenx12, (const BYTE **)&pTLVx12 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (meidSize < outLenx12 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pMEIDString, pTLVx12, outLenx12 );
pMEIDString[outLenx12] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackSetLock
DESCRIPTION:
This function sets the user lock state maintained by the device
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
state [ I ] - Desired lock state
pCurrentPIN [ I ] - Current four digit PIN string
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackSetLock(
ULONG * pOutLen,
BYTE * pOut,
ULONG state,
CHAR * pCurrentPIN )
{
// Validate arguments
if (pOut == 0 || pCurrentPIN == 0 || pCurrentPIN[0] == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
std::string thePIN( pCurrentPIN );
if (thePIN.size() > 4)
{
return eGOBI_ERR_INVALID_ARG;
}
if (thePIN.find_first_not_of( "0123456789" ) != std::string::npos )
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sDMSSetLockStateRequest_LockState );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
sDMSSetLockStateRequest_LockState * pTLVx01;
pTLVx01 = (sDMSSetLockStateRequest_LockState*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mLockState = (eQMIDMSLockStates)state;
memcpy( &pTLVx01->mLockCode[0], thePIN.c_str(), thePIN.size() );
offset += tlvx01Sz;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseQueryLock
DESCRIPTION:
This function sets the user lock state maintained by the device
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pState [ O ] - Current lock state
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseQueryLock(
ULONG inLen,
const BYTE * pIn,
ULONG * pState )
{
// Validate arguments
if (pIn == 0 || pState == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Find the state
const sDMSGetLockStateResponse_LockState * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sDMSGetLockStateResponse_LockState ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
*pState = pTLVx01->mLockState;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackChangeLockPIN
DESCRIPTION:
This command sets the user lock code maintained by the device
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
pCurrentPIN [ I ] - Current four digit PIN string
pDesiredPIN [ I ] - New four digit PIN string
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackChangeLockPIN(
ULONG * pOutLen,
BYTE * pOut,
CHAR * pCurrentPIN,
CHAR * pDesiredPIN )
{
// Validate arguments
if (pOut == 0
|| 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;
}
if (theCurPIN.find_first_not_of( "0123456789" ) != std::string::npos )
{
return eGOBI_ERR_INVALID_ARG;
}
std::string theNewPIN( pDesiredPIN );
if (theNewPIN.size() > 4)
{
return eGOBI_ERR_INVALID_ARG;
}
if (theNewPIN.find_first_not_of( "0123456789" ) != std::string::npos )
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sDMSSetLockCodeRequest_LockCode );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
sDMSSetLockCodeRequest_LockCode * pTLVx01;
pTLVx01 = (sDMSSetLockCodeRequest_LockCode*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
memcpy( &pTLVx01->mCurrentLockCode[0],
theCurPIN.c_str(),
theCurPIN.size() );
memcpy( &pTLVx01->mNewLockCode[0],
theNewPIN.c_str(),
theNewPIN.size() );
offset += tlvx01Sz;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetHardwareRevision
DESCRIPTION:
This function returns the device hardware revision
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
stringSize [ I ] - The maximum number of characters (including NULL
terminator) that the string array can contain
pString [ O ] - NULL terminated string
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetHardwareRevision(
ULONG inLen,
const BYTE * pIn,
BYTE stringSize,
CHAR * pString )
{
// Validate arguments
if (pIn == 0 || pString == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Find the hardware revision
// sDMSGetHardwareRevisionResponse_HardwareRevision only contains this
const CHAR * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
// Space to perform the copy?
if (stringSize < outLenx01 + 1)
{
return eGOBI_ERR_BUFFER_SZ;
}
memcpy( pString, pTLVx01, outLenx01 );
pString[outLenx01] = 0;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetPRLVersion
DESCRIPTION:
This function returns the version of the active Preferred Roaming List
(PRL) in use by the device
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pPRLVersion [ O ] - The PRL version number
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetPRLVersion(
ULONG inLen,
const BYTE * pIn,
WORD * pPRLVersion )
{
// Validate arguments
if (pIn == 0 || pPRLVersion == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Find the state
const sDMSGetPRLVersionResponse_PRLVersion * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sDMSGetPRLVersionResponse_PRLVersion ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
*pPRLVersion = pTLVx01->mPRLVersion;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetERIFile
DESCRIPTION:
This command returns the ERI file that is stored in EFS on the device
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
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:
ULONG - Return code
===========================================================================*/
ULONG ParseGetERIFile(
ULONG inLen,
const BYTE * pIn,
ULONG * pFileSize,
BYTE * pFile )
{
// Validate arguments
if (pIn == 0 || pFileSize == 0 || *pFileSize == 0 || pFile == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
ULONG maxFileSize = *pFileSize;
*pFileSize = 0;
// Find the state
const sDMSReadERIDataResponse_UserData * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sDMSReadERIDataResponse_UserData ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
ULONG fileSz = pTLVx01->mDataLength;
const BYTE * pInFile;
// Verify there is room for the array in the TLV
if (outLenx01 < sizeof( sDMSReadERIDataResponse_UserData )
+ sizeof( BYTE ) * fileSz)
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Space to copy into?
if (fileSz > maxFileSize)
{
return eGOBI_ERR_BUFFER_SZ;
}
// Align to the first array element
pInFile = (const BYTE *)pTLVx01
+ sizeof( sDMSReadERIDataResponse_UserData );
// Perform the copy
memcpy( pFile, pInFile, fileSz );
*pFileSize = fileSz;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackActivateAutomatic
DESCRIPTION:
This function requests the device to perform automatic service activation
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied
to pOut
pOut [ O ] - Output buffer
pActivationCode [ I ] - Activation code (maximum string length of 12)
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackActivateAutomatic(
ULONG * pOutLen,
BYTE * pOut,
CHAR * pActivationCode )
{
// Validate arguments
if (pOut == 0 || pActivationCode == 0 || pActivationCode[0] == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
std::string ac( pActivationCode );
if (ac.size() > 12)
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sDMSActivateAutomaticRequest_ActivationCode )
+ (WORD)ac.size();
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
sDMSActivateAutomaticRequest_ActivationCode * pTLVx01;
pTLVx01 = (sDMSActivateAutomaticRequest_ActivationCode*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mCodeLength = (UINT8)ac.size();
memcpy( (BYTE *)pTLVx01
+ sizeof( sDMSActivateAutomaticRequest_ActivationCode ),
ac.c_str(),
ac.size() );
offset += tlvx01Sz;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackResetToFactoryDefaults
DESCRIPTION:
This function requests the device reset configuration to factory defaults
CHANGES:
* The client must manually reset the device after this request completes
using DMSSetOperatingMode()
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied to pOut
pOut [ O ] - Output buffer
pSPC [ I ] - NULL terminated string representing the six digit
service programming code
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackResetToFactoryDefaults(
ULONG * pOutLen,
BYTE * pOut,
CHAR * pSPC )
{
// Validate arguments
if (pOut == 0 || pSPC == 0 || pSPC[0] == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
std::string spc( pSPC );
if (spc.size() > 6)
{
return eGOBI_ERR_INVALID_ARG;
}
if (spc.find_first_not_of( "0123456789" ) != std::string::npos )
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sDMSResetFactoryDefaultsRequest_SPC );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// The SPC
sDMSResetFactoryDefaultsRequest_SPC * pTLVx01;
pTLVx01 = (sDMSResetFactoryDefaultsRequest_SPC*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
memcpy( &pTLVx01->mSPC[0], spc.c_str(), spc.size() );
offset += tlvx01Sz;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetActivationState
DESCRIPTION:
This function returns the device activation state
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pActivationState [ O ] - Service activation state
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetActivationState(
ULONG inLen,
const BYTE * pIn,
ULONG * pActivationState )
{
// Validate arguments
if (pIn == 0 || pActivationState == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Find the state
const sDMSGetActivationStateResponse_ActivationState * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sDMSGetActivationStateResponse_ActivationState ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
*pActivationState = pTLVx01->mActivationState;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackSetPower
DESCRIPTION:
This function sets the operating mode of the device
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied to pOut
pOut [ O ] - Output buffer
powerMode [ I ] - Selected operating mode
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackSetPower(
ULONG * pOutLen,
BYTE * pOut,
ULONG powerMode )
{
// Validate arguments
if (pOut == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sDMSSetOperatingModeRequest_OperatingMode );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// Set the mode
sDMSSetOperatingModeRequest_OperatingMode * pTLVx01;
pTLVx01 = (sDMSSetOperatingModeRequest_OperatingMode*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
pTLVx01->mOperatingMode = (eQMIDMSOperatingModes)powerMode;
offset += tlvx01Sz;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetPower
DESCRIPTION:
This function returns the operating mode of the device
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pPowerMode [ O ] - Current operating mode
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetPower(
ULONG inLen,
const BYTE * pIn,
ULONG * pPowerMode )
{
// Validate arguments
if (pIn == 0 || pPowerMode == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pPowerMode = 0xffffffff;
// Find the mode
const sDMSGetOperatingModeResponse_OperatingMode * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sDMSGetOperatingModeResponse_OperatingMode ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
*pPowerMode = pTLVx01->mOperatingMode;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetOfflineReason
DESCRIPTION:
This function returns the reason why the operating mode of the device
is currently offline
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pReasonMask [ O ] - Bitmask of offline reasons
pbPlatform [ O ] - Offline due to being platform retricted?
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG ParseGetOfflineReason(
ULONG inLen,
const BYTE * pIn,
ULONG * pReasonMask,
ULONG * pbPlatform )
{
// Validate arguments
if (pIn == 0 || pReasonMask == 0 || pbPlatform == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Assume failure
*pReasonMask = 0;
*pbPlatform = 0;
// Find the reason mask (optional)
const sDMSGetOperatingModeResponse_OfflineReason * pTLVx10;
ULONG outLenx10;
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
if (rc == eGOBI_ERR_NONE)
{
if (outLenx10 < sizeof( sDMSGetOperatingModeResponse_OfflineReason ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Copy the bitmask to pReasonMask
*pReasonMask = *(WORD*)pTLVx10;
}
// Find the platform restriction (optional)
const sDMSGetOperatingModeResponse_PlatformRestricted * pTLVx11;
ULONG outLenx11;
rc = GetTLV( inLen, pIn, 0x11, &outLenx11, (const BYTE **)&pTLVx11 );
if (rc == eGOBI_ERR_NONE)
{
if (outLenx11 < sizeof( sDMSGetOperatingModeResponse_PlatformRestricted ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Copy the value
*pbPlatform = pTLVx11->mPlatformRestricted;
}
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
ParseGetNetworkTime
DESCRIPTION:
This function returns the current time of the device
PARAMETERS:
inLen [ I ] - Length of input buffer
pIn [ I ] - Input buffer
pTimeCount [ 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:
ULONG - Return code
===========================================================================*/
ULONG ParseGetNetworkTime(
ULONG inLen,
const BYTE * pIn,
ULONGLONG * pTimeCount,
ULONG * pTimeSource )
{
// Validate arguments
if (pIn == 0 || pTimeCount == 0 || pTimeSource == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
// Find the reason mask
const sDMSGetTimestampResponse_Timestamp * pTLVx01;
ULONG outLenx01;
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
if (rc != eGOBI_ERR_NONE)
{
return rc;
}
if (outLenx01 < sizeof( sDMSGetTimestampResponse_Timestamp ))
{
return eGOBI_ERR_MALFORMED_RSP;
}
// Get the values
*pTimeCount = pTLVx01->mTimestamp;
// mSource is of type eQMIDMSTimestampSources
*pTimeSource = pTLVx01->mSource;
return eGOBI_ERR_NONE;
}
/*===========================================================================
METHOD:
PackValidateSPC
DESCRIPTION:
This function validates the service programming code
PARAMETERS:
pOutLen [I/O] - Upon input the maximum number of BYTEs pOut can
contain, upon output the number of BYTEs copied to pOut
pOut [ O ] - Output buffer
pSPC [ I ] - Six digit service programming code
RETURN VALUE:
ULONG - Return code
===========================================================================*/
ULONG PackValidateSPC(
ULONG * pOutLen,
BYTE * pOut,
CHAR * pSPC )
{
// Validate arguments
if (pOut == 0 || pSPC == 0 || pSPC[0] == 0)
{
return eGOBI_ERR_INVALID_ARG;
}
std::string spc( pSPC );
if (spc.size() > 6)
{
return eGOBI_ERR_INVALID_ARG;
}
if (spc.find_first_not_of( "0123456789" ) != std::string::npos )
{
return eGOBI_ERR_INVALID_ARG;
}
// Check size
WORD tlvx01Sz = sizeof( sDMSValidateSPCRequest_SPC );
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
{
return eGOBI_ERR_BUFFER_SZ;
}
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)(pOut);
pHeader->mTypeID = 0x01;
pHeader->mLength = tlvx01Sz;
ULONG offset = sizeof( sQMIRawContentHeader );
// The SPC
sDMSValidateSPCRequest_SPC * pTLVx01;
pTLVx01 = (sDMSValidateSPCRequest_SPC*)(pOut + offset);
memset( pTLVx01, 0, tlvx01Sz );
// Set the values
memcpy( &pTLVx01->mSPC[0], spc.c_str(), spc.size() );
offset += tlvx01Sz;
*pOutLen = offset;
return eGOBI_ERR_NONE;
}