1170 lines
35 KiB
C++
1170 lines
35 KiB
C++
/*===========================================================================
|
|
FILE:
|
|
Gobi3000TranslationUIM.cpp
|
|
|
|
DESCRIPTION:
|
|
QUALCOMM Translation for Gobi 3000 (DMS_UIM 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:
|
|
ParseUIMUnblockControlKey
|
|
|
|
DESCRIPTION:
|
|
This function unblocks the specified facility control key
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
pUnblockRetriesLeft [ O ] - The number of unblock retries left, after
|
|
which the control key will be permanently
|
|
blocked
|
|
(0xFFFFFFFF = unknown)
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMUnblockControlKey(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG * pUnblockRetriesLeft )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0 || pUnblockRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the TLV
|
|
const sDMSUIMUnblockControlKeyResponse_Status * pTLVx10;
|
|
ULONG outLenx10;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx10 < sizeof( sDMSUIMUnblockControlKeyResponse_Status ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pUnblockRetriesLeft = pTLVx10->mRemainingUnblockRetries;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackUIMUnblockControlKey
|
|
|
|
DESCRIPTION:
|
|
This function unblocks the specified facility control key
|
|
|
|
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
|
|
id [ I ] - Facility ID
|
|
pValue [ I ] - Control key de-personalization string
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG PackUIMUnblockControlKey(
|
|
ULONG * pOutLen,
|
|
BYTE * pOut,
|
|
ULONG id,
|
|
CHAR * pValue )
|
|
{
|
|
// Validate arguments
|
|
if (pOut == 0
|
|
|| pValue == 0
|
|
|| pValue[0] == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Add arguments
|
|
std::string val( pValue );
|
|
UINT8 valSz = (UINT8)val.size();
|
|
|
|
// Check size
|
|
WORD tlvx01Sz = sizeof( sDMSUIMUnblockControlKeyRequest_Facility ) + valSz;
|
|
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
|
{
|
|
return eGOBI_ERR_BUFFER_SZ;
|
|
}
|
|
|
|
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
|
pHeader->mTypeID = 0x01;
|
|
pHeader->mLength = tlvx01Sz;
|
|
|
|
ULONG offset = sizeof( sQMIRawContentHeader );
|
|
|
|
sDMSUIMUnblockControlKeyRequest_Facility * pTLVx01;
|
|
pTLVx01 = (sDMSUIMUnblockControlKeyRequest_Facility*)(pOut + offset);
|
|
memset( pTLVx01, 0, tlvx01Sz );
|
|
|
|
// Set the values
|
|
pTLVx01->mFacility = (eQMIDMSUIMFacility)id;
|
|
pTLVx01->mControlKeyLength = valSz;
|
|
|
|
offset += sizeof( sDMSUIMUnblockControlKeyRequest_Facility );
|
|
|
|
memcpy( (pOut + offset), (LPCSTR)val.c_str(), valSz );
|
|
offset += valSz;
|
|
|
|
*pOutLen = offset;
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMSetControlKeyProtection
|
|
|
|
DESCRIPTION:
|
|
This function changes the specified facility control key
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
pVerifyRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of retries left, after which the
|
|
control key will be blocked
|
|
(0xFFFFFFFF = unknown)
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMSetControlKeyProtection(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG * pVerifyRetriesLeft )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0 || pVerifyRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the TLV
|
|
const sDMSUIMSetControlKeyProtectionResponse_Status * pTLVx10;
|
|
ULONG outLenx10;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx10 < sizeof( sDMSUIMSetControlKeyProtectionResponse_Status ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLVx10->mRemainingVerifyRetries;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackUIMSetControlKeyProtection
|
|
|
|
DESCRIPTION:
|
|
This function changes the specified facility control key
|
|
|
|
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
|
|
id [ I ] - Facility ID
|
|
status [ I ] - Control key status
|
|
pValue [ I ] - Control key de-personalization string
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG PackUIMSetControlKeyProtection(
|
|
ULONG * pOutLen,
|
|
BYTE * pOut,
|
|
ULONG id,
|
|
ULONG status,
|
|
CHAR * pValue )
|
|
{
|
|
// Validate arguments
|
|
if (pOut == 0
|
|
|| pValue == 0
|
|
|| pValue[0] == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Add arguments
|
|
std::string val( pValue );
|
|
UINT8 valSz = (UINT8)val.size();
|
|
|
|
// Check size
|
|
WORD tlvx01Sz = sizeof( sDMSUIMSetControlKeyProtectionRequest_Facility ) + valSz;
|
|
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
|
{
|
|
return eGOBI_ERR_BUFFER_SZ;
|
|
}
|
|
|
|
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
|
pHeader->mTypeID = 0x01;
|
|
pHeader->mLength = tlvx01Sz;
|
|
|
|
ULONG offset = sizeof( sQMIRawContentHeader );
|
|
|
|
sDMSUIMSetControlKeyProtectionRequest_Facility * pTLVx01;
|
|
pTLVx01 = (sDMSUIMSetControlKeyProtectionRequest_Facility*)(pOut + offset);
|
|
memset( pTLVx01, 0, tlvx01Sz );
|
|
|
|
// Set the values
|
|
pTLVx01->mFacility = (eQMIDMSUIMFacility)id;
|
|
pTLVx01->mFacilityState = (eQMIDMSUIMFacilityStates)status;
|
|
pTLVx01->mControlKeyLength = (UINT8)valSz;
|
|
|
|
offset += sizeof( sDMSUIMSetControlKeyProtectionRequest_Facility );
|
|
|
|
memcpy( (pOut + offset), val.c_str(), valSz );
|
|
offset += valSz;
|
|
|
|
*pOutLen = offset;
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMGetControlKeyBlockingStatus
|
|
|
|
DESCRIPTION:
|
|
This function returns the status of the specified facility control key
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
pStatus [ O ] - Control key status
|
|
pVerifyRetriesLeft [ O ] - The number of retries left, after which the
|
|
control key will be blocked
|
|
pUnblockRetriesLeft [ O ] - The number of unblock retries left, after
|
|
which the control key will be permanently
|
|
blocked
|
|
pbBlocking [ O ] - (Optional) Is the facility blocking?
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMGetControlKeyBlockingStatus(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG * pStatus,
|
|
ULONG * pVerifyRetriesLeft,
|
|
ULONG * pUnblockRetriesLeft,
|
|
ULONG * pbBlocking )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0
|
|
|| pStatus == 0
|
|
|| pVerifyRetriesLeft == 0
|
|
|| pUnblockRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the first arguments
|
|
const sDMSUIMGetControlKeyStatusResponse_Status * pTLVx01;
|
|
ULONG outLenx01;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx01 < sizeof( sDMSUIMGetControlKeyStatusResponse_Status ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLVx01->mRemainingVerifyRetries;
|
|
*pUnblockRetriesLeft = pTLVx01->mRemainingUnblockRetries;
|
|
*pStatus = pTLVx01->mFacilityState;
|
|
|
|
// Find the last (optional) argument
|
|
if (pbBlocking != 0)
|
|
{
|
|
const sDMSUIMGetControlKeyStatusResponse_Blocking * pTLVx10;
|
|
ULONG tlvLenx10;
|
|
rc = GetTLV( inLen, pIn, 0x10, &tlvLenx10, (const BYTE **)&pTLVx10 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (tlvLenx10 < sizeof( sDMSUIMGetControlKeyStatusResponse_Blocking ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pbBlocking = pTLVx10->mOperationBlocking;
|
|
}
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackUIMGetControlKeyBlockingStatus
|
|
|
|
DESCRIPTION:
|
|
This function returns the status of the specified facility control key
|
|
|
|
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
|
|
id [ I ] - Facility ID
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG PackUIMGetControlKeyBlockingStatus(
|
|
ULONG * pOutLen,
|
|
BYTE * pOut,
|
|
ULONG id )
|
|
{
|
|
// Validate arguments
|
|
if (pOut == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Add id
|
|
|
|
// Check size
|
|
WORD tlvx01Sz = sizeof( sDMSUIMGetControlKeyStatusRequest_Facility );
|
|
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
|
{
|
|
return eGOBI_ERR_BUFFER_SZ;
|
|
}
|
|
|
|
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
|
pHeader->mTypeID = 0x01;
|
|
pHeader->mLength = tlvx01Sz;
|
|
|
|
ULONG offset = sizeof( sQMIRawContentHeader );
|
|
|
|
sDMSUIMGetControlKeyStatusRequest_Facility * pTLVx01;
|
|
pTLVx01 = (sDMSUIMGetControlKeyStatusRequest_Facility*)(pOut + offset);
|
|
memset( pTLVx01, 0, tlvx01Sz );
|
|
|
|
// Set the values
|
|
pTLVx01->mFacility = (eQMIDMSUIMFacility)id;
|
|
|
|
offset += tlvx01Sz;
|
|
|
|
*pOutLen = offset;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMGetControlKeyStatus
|
|
|
|
DESCRIPTION:
|
|
This function returns the status of the specified facility control key
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
pStatus [ O ] - Control key status
|
|
pVerifyRetriesLeft [ O ] - The number of retries left, after which the
|
|
control key will be blocked
|
|
pUnblockRetriesLeft [ O ] - The number of unblock retries left, after
|
|
which the control key will be permanently
|
|
blocked
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMGetControlKeyStatus(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG * pStatus,
|
|
ULONG * pVerifyRetriesLeft,
|
|
ULONG * pUnblockRetriesLeft )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0
|
|
|| pStatus == 0
|
|
|| pVerifyRetriesLeft == 0
|
|
|| pUnblockRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the arguments
|
|
const sDMSUIMGetControlKeyStatusResponse_Status * pTLVx01;
|
|
ULONG outLenx01;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx01 < sizeof( sDMSUIMGetControlKeyStatusResponse_Status ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLVx01->mRemainingVerifyRetries;
|
|
*pUnblockRetriesLeft = pTLVx01->mRemainingUnblockRetries;
|
|
*pStatus = pTLVx01->mFacilityState;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackUIMGetControlKeyStatus
|
|
|
|
DESCRIPTION:
|
|
This function requests the status of the specified facility control key
|
|
|
|
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
|
|
id [ I ] - Facility ID
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG PackUIMGetControlKeyStatus(
|
|
ULONG * pOutLen,
|
|
BYTE * pOut,
|
|
ULONG id )
|
|
{
|
|
// Request is the same as PackUIMGetControlKeyBlockingStatus
|
|
return PackUIMGetControlKeyBlockingStatus( pOutLen,
|
|
pOut,
|
|
id );
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMGetICCID
|
|
|
|
DESCRIPTION:
|
|
This function returns the UIM ICCID
|
|
|
|
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 ParseUIMGetICCID(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
BYTE stringSize,
|
|
CHAR * pString )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0 || stringSize == 0 || pString == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the TLV
|
|
const sDMSUIMGetICCIDResponse_ICCID * pTLVx01;
|
|
ULONG outLenx01;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x01, &outLenx01, (const BYTE **)&pTLVx01 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx01 < sizeof( sDMSUIMGetICCIDResponse_ICCID ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
// The TLV only contains the string
|
|
|
|
// Space to perform the copy?
|
|
if (stringSize < outLenx01 + 1)
|
|
{
|
|
return eGOBI_ERR_BUFFER_SZ;
|
|
}
|
|
|
|
memcpy( pString, (const CHAR*)pTLVx01, outLenx01 );
|
|
pString[outLenx01] = 0;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMGetPINStatus
|
|
|
|
DESCRIPTION:
|
|
This function returns the status of the pin
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
id [ I ] - PIN ID (1/2)
|
|
pStatus [ O ] - PIN status (0xFFFFFFFF = unknown)
|
|
pVerifyRetriesLeft [ O ] - The number of retries left, after which the
|
|
PIN will be blocked (0xFFFFFFFF = unknown)
|
|
pUnblockRetriesLeft [ O ] - The number of unblock retries left, after
|
|
which the PIN will be permanently blocked,
|
|
i.e. UIM is unusable (0xFFFFFFFF = unknown)
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMGetPINStatus(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG id,
|
|
ULONG * pStatus,
|
|
ULONG * pVerifyRetriesLeft,
|
|
ULONG * pUnblockRetriesLeft )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0
|
|
|| id < 1
|
|
|| id > 2
|
|
|| pStatus == 0
|
|
|| pVerifyRetriesLeft == 0
|
|
|| pUnblockRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
ULONG tlvLen;
|
|
|
|
// The typeID is either 0x11 or 0x12
|
|
if (id == 1)
|
|
{
|
|
const sDMSUIMGetPINStatusResponse_PIN1Status * pTLV11;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x11, &tlvLen, (const BYTE **)&pTLV11 );
|
|
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (tlvLen < sizeof( sDMSUIMGetPINStatusResponse_PIN1Status ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLV11->mRemainingVerifyRetries;
|
|
*pUnblockRetriesLeft = pTLV11->mRemainingUnblockRetries;
|
|
*pStatus = pTLV11->mPINStatus;
|
|
}
|
|
else if (id == 2)
|
|
{
|
|
const sDMSUIMGetPINStatusResponse_PIN2Status * pTLV12;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x12, &tlvLen, (const BYTE **)&pTLV12 );
|
|
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (tlvLen < sizeof( sDMSUIMGetPINStatusResponse_PIN2Status ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLV12->mRemainingVerifyRetries;
|
|
*pUnblockRetriesLeft = pTLV12->mRemainingUnblockRetries;
|
|
*pStatus = pTLV12->mPINStatus;
|
|
}
|
|
else
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMChangePIN
|
|
|
|
DESCRIPTION:
|
|
This function changes the PIN value
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
pVerifyRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of retries left, after which the
|
|
PIN will be blocked (0xFFFFFFFF = unknown)
|
|
pUnblockRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of unblock retries left, after
|
|
which the PIN will be permanently blocked,
|
|
i.e. UIM is unusable (0xFFFFFFFF = unknown)
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMChangePIN(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG * pVerifyRetriesLeft,
|
|
ULONG * pUnblockRetriesLeft )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0 || pVerifyRetriesLeft == 0 || pUnblockRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the TLV
|
|
const sDMSUIMChangePINResponse_RetryInfo * pTLVx10;
|
|
ULONG outLenx10;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx10 < sizeof( sDMSUIMChangePINResponse_RetryInfo ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLVx10->mRemainingVerifyRetries;
|
|
*pUnblockRetriesLeft = pTLVx10->mRemainingUnblockRetries;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackUIMChangePIN
|
|
|
|
DESCRIPTION:
|
|
This function changes the PIN value
|
|
|
|
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
|
|
id [ I ] - PIN ID (1/2)
|
|
pOldValue [ I ] - Old PIN value of the PIN to change
|
|
pNewValue [ I ] - New PIN value of the PIN to change
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG PackUIMChangePIN(
|
|
ULONG * pOutLen,
|
|
BYTE * pOut,
|
|
ULONG id,
|
|
CHAR * pOldValue,
|
|
CHAR * pNewValue )
|
|
{
|
|
// Validate arguments
|
|
if (pOut == 0
|
|
|| id < 1
|
|
|| id > 2
|
|
|| pOldValue == 0
|
|
|| pOldValue[0] == 0
|
|
|| pNewValue == 0
|
|
|| pNewValue[0] == 0 )
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Add arguments
|
|
std::string oldVal( pOldValue );
|
|
ULONG oldValSz = (ULONG)oldVal.size();
|
|
std::string newVal( pNewValue );
|
|
ULONG newValSz = (ULONG)newVal.size();
|
|
|
|
// Check size
|
|
WORD tlvx01Sz = sizeof( sDMSUIMChangePINRequest_Info )
|
|
+ (WORD)oldValSz + (WORD)newValSz;
|
|
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
|
{
|
|
return eGOBI_ERR_BUFFER_SZ;
|
|
}
|
|
|
|
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
|
pHeader->mTypeID = 0x01;
|
|
pHeader->mLength = tlvx01Sz;
|
|
|
|
ULONG offset = sizeof( sQMIRawContentHeader );
|
|
|
|
// First part of the TLV
|
|
sDMSUIMChangePINRequest_Info1 * pTLVx01_1;
|
|
pTLVx01_1 = (sDMSUIMChangePINRequest_Info1*)(pOut + offset);
|
|
memset( pTLVx01_1, 0, tlvx01Sz );
|
|
|
|
pTLVx01_1->mPINID = (UINT8)id;
|
|
pTLVx01_1->mOldPINLength = (UINT8)oldValSz;
|
|
offset += sizeof( sDMSUIMChangePINRequest_Info1 );
|
|
|
|
// mOldPINValue string
|
|
memcpy( (pOut + offset), oldVal.c_str(), oldValSz );
|
|
offset += oldValSz;
|
|
|
|
// Second part of the TLV
|
|
sDMSUIMChangePINRequest_Info2 * pTLVx01_2;
|
|
pTLVx01_2 = (sDMSUIMChangePINRequest_Info2*)(pOut + offset);
|
|
|
|
pTLVx01_2->mNewPINLength = (UINT8)newValSz;
|
|
offset += sizeof( sDMSUIMChangePINRequest_Info2 );
|
|
|
|
// mNewPINValue string
|
|
memcpy( (pOut + offset), newVal.c_str(), newValSz );
|
|
offset += newValSz;
|
|
|
|
*pOutLen = offset;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMUnblockPIN
|
|
|
|
DESCRIPTION:
|
|
This function unblocks a blocked PIN
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
pVerifyRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of retries left, after which the
|
|
PIN will be blocked (0xFFFFFFFF = unknown)
|
|
pUnblockRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of unblock retries left, after
|
|
which the PIN will be permanently blocked,
|
|
i.e. UIM is unusable (0xFFFFFFFF = unknown)
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMUnblockPIN(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG * pVerifyRetriesLeft,
|
|
ULONG * pUnblockRetriesLeft )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0 || pVerifyRetriesLeft == 0 || pUnblockRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the TLV
|
|
const sDMSUIMUnblockPINResponse_RetryInfo * pTLVx10;
|
|
ULONG outLenx10;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx10 < sizeof( sDMSUIMUnblockPINResponse_RetryInfo ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLVx10->mRemainingVerifyRetries;
|
|
*pUnblockRetriesLeft = pTLVx10->mRemainingUnblockRetries;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackUIMUnblockPIN
|
|
|
|
DESCRIPTION:
|
|
This function unblocks a blocked PIN
|
|
|
|
PARAMETERS:
|
|
id [ I ] - PIN ID (1/2)
|
|
pPUKValue [ I ] - PUK value of the PIN to unblock
|
|
pNewValue [ I ] - New PIN value of the PIN to unblock
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG PackUIMUnblockPIN(
|
|
ULONG * pOutLen,
|
|
BYTE * pOut,
|
|
ULONG id,
|
|
CHAR * pPUKValue,
|
|
CHAR * pNewValue )
|
|
{
|
|
// Validate arguments
|
|
if (pOut == 0
|
|
|| id < 1
|
|
|| id > 2
|
|
|| pPUKValue == 0
|
|
|| pPUKValue[0] == 0
|
|
|| pNewValue == 0
|
|
|| pNewValue[0] == 0 )
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Add arguments
|
|
std::string oldVal( pPUKValue );
|
|
ULONG oldValSz = (ULONG)oldVal.size();
|
|
std::string newVal( pNewValue );
|
|
ULONG newValSz = (ULONG)newVal.size();
|
|
|
|
// Check size
|
|
WORD tlvx01Sz = sizeof( sDMSUIMUnblockPINRequest_Info )
|
|
+ (WORD)oldValSz + (WORD)newValSz;
|
|
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
|
{
|
|
return eGOBI_ERR_BUFFER_SZ;
|
|
}
|
|
|
|
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
|
pHeader->mTypeID = 0x01;
|
|
pHeader->mLength = tlvx01Sz;
|
|
|
|
ULONG offset = sizeof( sQMIRawContentHeader );
|
|
|
|
// First part of the TLV
|
|
sDMSUIMUnblockPINRequest_Info1 * pTLVx01_1;
|
|
pTLVx01_1 = (sDMSUIMUnblockPINRequest_Info1*)(pOut + offset);
|
|
memset( pTLVx01_1, 0, tlvx01Sz );
|
|
|
|
pTLVx01_1->mPINID = (UINT8)id;
|
|
pTLVx01_1->mPUKLength = (UINT8)oldValSz;
|
|
offset += sizeof( sDMSUIMUnblockPINRequest_Info1 );
|
|
|
|
// mPUKValue string
|
|
memcpy( (pOut + offset), oldVal.c_str(), oldValSz );
|
|
offset += oldValSz;
|
|
|
|
// Second part of the TLV
|
|
sDMSUIMUnblockPINRequest_Info2 * pTLVx01_2;
|
|
pTLVx01_2 = (sDMSUIMUnblockPINRequest_Info2*)(pOut + offset);
|
|
|
|
pTLVx01_2->mNewPINLength = (UINT8)newValSz;
|
|
offset += sizeof( sDMSUIMUnblockPINRequest_Info2 );
|
|
|
|
// mNewPINValue string
|
|
memcpy( (pOut + offset), newVal.c_str(), newValSz );
|
|
offset += newValSz;
|
|
|
|
*pOutLen = offset;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMVerifyPIN
|
|
|
|
DESCRIPTION:
|
|
This function verifies the PIN before accessing the UIM contents
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
pVerifyRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of retries left, after which the
|
|
PIN will be blocked (0xFFFFFFFF = unknown)
|
|
pUnblockRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of unblock retries left, after
|
|
which the PIN will be permanently blocked,
|
|
i.e. UIM is unusable (0xFFFFFFFF = unknown)
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMVerifyPIN(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG * pVerifyRetriesLeft,
|
|
ULONG * pUnblockRetriesLeft )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0 || pVerifyRetriesLeft == 0 || pUnblockRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the TLV
|
|
const sDMSUIMVerifyPINResponse_RetryInfo * pTLVx10;
|
|
ULONG outLenx10;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx10 < sizeof( sDMSUIMVerifyPINResponse_RetryInfo ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLVx10->mRemainingVerifyRetries;
|
|
*pUnblockRetriesLeft = pTLVx10->mRemainingUnblockRetries;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackUIMVerifyPIN
|
|
|
|
DESCRIPTION:
|
|
This function verifies the PIN before accessing the UIM contents
|
|
|
|
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
|
|
id [ I ] - PIN ID (1/2)
|
|
pValue [ I ] - PIN value of the PIN to verify
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG PackUIMVerifyPIN(
|
|
ULONG * pOutLen,
|
|
BYTE * pOut,
|
|
ULONG id,
|
|
CHAR * pValue )
|
|
{
|
|
// Validate arguments
|
|
if (pOut == 0
|
|
|| id < 1
|
|
|| id > 2
|
|
|| pValue == 0
|
|
|| pValue[0] == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Add arguments
|
|
std::string val( pValue );
|
|
UINT8 valSz = (UINT8)val.size();
|
|
|
|
// Check size
|
|
WORD tlvx01Sz = sizeof( sDMSUIMVerifyPINRequest_Info ) + valSz;
|
|
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
|
{
|
|
return eGOBI_ERR_BUFFER_SZ;
|
|
}
|
|
|
|
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
|
pHeader->mTypeID = 0x01;
|
|
pHeader->mLength = tlvx01Sz;
|
|
|
|
ULONG offset = sizeof( sQMIRawContentHeader );
|
|
|
|
sDMSUIMVerifyPINRequest_Info * pTLVx01;
|
|
pTLVx01 = (sDMSUIMVerifyPINRequest_Info*)(pOut + offset);
|
|
memset( pTLVx01, 0, tlvx01Sz );
|
|
|
|
// Set the values
|
|
pTLVx01->mPINID = (UINT8)id;
|
|
pTLVx01->mPINLength = valSz;
|
|
offset += sizeof( sDMSUIMVerifyPINRequest_Info );
|
|
|
|
// Add mPINValue
|
|
memcpy( (pOut + offset), val.c_str(), valSz );
|
|
offset += valSz;
|
|
|
|
*pOutLen = offset;
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
ParseUIMSetPINProtection
|
|
|
|
DESCRIPTION:
|
|
This function enables or disables protection of UIM contents by a
|
|
given PIN
|
|
|
|
PARAMETERS:
|
|
inLen [ I ] - Length of input buffer
|
|
pIn [ I ] - Input buffer
|
|
pVerifyRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of retries left, after which the
|
|
PIN will be blocked (0xFFFFFFFF = unknown)
|
|
pUnblockRetriesLeft [ O ] - Upon operational failure this will indicate
|
|
the number of unblock retries left, after
|
|
which the PIN will be permanently blocked,
|
|
i.e. UIM is unusable (0xFFFFFFFF = unknown)
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG ParseUIMSetPINProtection(
|
|
ULONG inLen,
|
|
const BYTE * pIn,
|
|
ULONG * pVerifyRetriesLeft,
|
|
ULONG * pUnblockRetriesLeft )
|
|
{
|
|
// Validate arguments
|
|
if (pIn == 0 || pVerifyRetriesLeft == 0 || pUnblockRetriesLeft == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Find the TLV
|
|
const sDMSUIMSetPINProtectionResponse_RetryInfo * pTLVx10;
|
|
ULONG outLenx10;
|
|
ULONG rc = GetTLV( inLen, pIn, 0x10, &outLenx10, (const BYTE **)&pTLVx10 );
|
|
if (rc != eGOBI_ERR_NONE)
|
|
{
|
|
return rc;
|
|
}
|
|
|
|
// Is the TLV large enough?
|
|
if (outLenx10 < sizeof( sDMSUIMSetPINProtectionResponse_RetryInfo ))
|
|
{
|
|
return eGOBI_ERR_MALFORMED_RSP;
|
|
}
|
|
|
|
*pVerifyRetriesLeft = pTLVx10->mRemainingVerifyRetries;
|
|
*pUnblockRetriesLeft = pTLVx10->mRemainingUnblockRetries;
|
|
|
|
return eGOBI_ERR_NONE;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
PackUIMSetPINProtection
|
|
|
|
DESCRIPTION:
|
|
This function enables or disables protection of UIM contents by a
|
|
given PIN
|
|
|
|
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
|
|
id [ I ] - PIN ID (1/2)
|
|
bEnable [ I ] - Enable/disable PIN protection (0 = disable)?
|
|
pValue [ I ] - PIN value of the PIN to be enabled/disabled
|
|
|
|
RETURN VALUE:
|
|
ULONG - Return code
|
|
===========================================================================*/
|
|
ULONG PackUIMSetPINProtection(
|
|
ULONG * pOutLen,
|
|
BYTE * pOut,
|
|
ULONG id,
|
|
ULONG bEnable,
|
|
CHAR * pValue )
|
|
{
|
|
// Validate arguments
|
|
if (pOut == 0
|
|
|| id < 1
|
|
|| id > 2
|
|
|| pValue == 0
|
|
|| pValue[0] == 0)
|
|
{
|
|
return eGOBI_ERR_INVALID_ARG;
|
|
}
|
|
|
|
// Add arguments
|
|
std::string val( pValue );
|
|
ULONG valSz = (ULONG)val.size();
|
|
|
|
// Check size
|
|
WORD tlvx01Sz = sizeof( sDMSUIMSetPINProtectionRequest_Info ) + (WORD)valSz;
|
|
if (*pOutLen < sizeof( sQMIRawContentHeader ) + tlvx01Sz)
|
|
{
|
|
return eGOBI_ERR_BUFFER_SZ;
|
|
}
|
|
|
|
sQMIRawContentHeader * pHeader = (sQMIRawContentHeader*)pOut;
|
|
pHeader->mTypeID = 0x01;
|
|
pHeader->mLength = tlvx01Sz;
|
|
|
|
ULONG offset = sizeof( sQMIRawContentHeader );
|
|
|
|
sDMSUIMSetPINProtectionRequest_Info * pTLVx01;
|
|
pTLVx01 = (sDMSUIMSetPINProtectionRequest_Info*)(pOut + offset);
|
|
memset( pTLVx01, 0, tlvx01Sz );
|
|
|
|
// Set the values
|
|
pTLVx01->mPINID = (UINT8)id;
|
|
pTLVx01->mPINEnabled = (bEnable == 0 ? 0 : 1);
|
|
pTLVx01->mPINLength = (UINT8)valSz;
|
|
|
|
offset += sizeof( sDMSUIMSetPINProtectionRequest_Info );
|
|
|
|
// Add mPINValue
|
|
memcpy( (pOut + offset), val.c_str(), valSz );
|
|
offset += valSz;
|
|
|
|
*pOutLen = offset;
|
|
return eGOBI_ERR_NONE;
|
|
}
|