aboutsummaryrefslogtreecommitdiffstats
path: root/gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationDMS.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationDMS.cpp')
-rwxr-xr-xgobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationDMS.cpp1483
1 files changed, 1483 insertions, 0 deletions
diff --git a/gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationDMS.cpp b/gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationDMS.cpp
new file mode 100755
index 0000000..d30dfed
--- /dev/null
+++ b/gobi-api/GobiAPI_2012-09-12-0719/Gobi3000Translation/Gobi3000TranslationDMS.cpp
@@ -0,0 +1,1483 @@
+/*===========================================================================
+FILE:
+ Gobi3000TranslationDMS.cpp
+
+DESCRIPTION:
+ QUALCOMM Translation for Gobi 3000 (DMS Service)
+
+Copyright (c) 2012, 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 "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;
+}