1483 lines
40 KiB
C++
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;
|
|
}
|