/*=========================================================================== 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: 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: 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: 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: 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: 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: 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: 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: QMIDMSGetMEIDResp (Public Method) DESCRIPTION: Parse the QMI DMS Get Serial Numbers Resp PARAMETERS pBuffer [ I ] - Buffer to be parsed buffSize [ I ] - Size of pBuffer pMEID [ O ] - Device MEID meidSize [ I ] - Size of MEID buffer (at least 14) RETURN VALUE: int - 0 for success Negative errno for error ===========================================================================*/ int QMIDMSGetMEIDResp( void * pBuffer, u16 buffSize, char * pMEID, int meidSize ) { int result; // Ignore QMUX and SDU u8 offset = sizeof( sQMUX ) + 3; if (pBuffer == 0 || buffSize < offset || meidSize < 14) { return -ENOMEM; } pBuffer = pBuffer + offset; buffSize -= offset; result = GetQMIMessageID( pBuffer, buffSize ); if (result != 0x25) { return -EFAULT; } result = ValidQMIMessage( pBuffer, buffSize ); if (result != 0) { return -EFAULT; } result = GetTLV( pBuffer, buffSize, 0x12, (void*)pMEID, 14 ); if (result != 14) { return -EFAULT; } return 0; }
/*=========================================================================== METHOD: QMICTLGetClientIDResp (Public Method) DESCRIPTION: Parse the QMI CTL Get Client ID Resp PARAMETERS pBuffer [ I ] - Buffer to be parsed buffSize [ I ] - Size of pBuffer pClientID [ 0 ] - Recieved client ID RETURN VALUE: int - 0 for success Negative errno for error ===========================================================================*/ int QMICTLGetClientIDResp( void * pBuffer, u16 buffSize, u16 * pClientID ) { int result; // Ignore QMUX and SDU // QMI CTL SDU is 2 bytes, not 3 u8 offset = sizeof( sQMUX ) + 2; if (pBuffer == 0 || buffSize < offset) { return -ENOMEM; } pBuffer = pBuffer + offset; buffSize -= offset; result = GetQMIMessageID( pBuffer, buffSize ); if (result != 0x22) { return -EFAULT; } result = ValidQMIMessage( pBuffer, buffSize ); if (result != 0) { return -EFAULT; } result = GetTLV( pBuffer, buffSize, 0x01, pClientID, 2 ); if (result != 2) { return -EFAULT; } return 0; }
/*=========================================================================== METHOD: ValidQMIMessage (Public Method) DESCRIPTION: Check mandatory TLV in a QMI message QMI Message shall NOT include SDU PARAMETERS pQMIMessage [ I ] - QMI Message buffer messageLen [ I ] - Size of QMI Message buffer RETURN VALUE: int - 0 for success (no error) Negative errno for error Positive for QMI error code ===========================================================================*/ int ValidQMIMessage( void * pQMIMessage, u16 messageLen ) { char mandTLV[4]; if (GetTLV( pQMIMessage, messageLen, 2, &mandTLV[0], 4 ) == 4) { // Found TLV if (*(u16 *)&mandTLV[0] != 0) { return *(u16 *)&mandTLV[2]; } else { return 0; } } else { return -ENOMSG; } }
/*=========================================================================== 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: QMIWDSEventResp (Public Method) DESCRIPTION: Parse the QMI WDS Set Event Report Resp/Indication or QMI WDS Get PKG SRVC Status Resp/Indication Return parameters will only be updated if value was received PARAMETERS pBuffer [ I ] - Buffer to be parsed buffSize [ I ] - Size of pBuffer pTXOk [ O ] - Number of transmitted packets without errors pRXOk [ O ] - Number of recieved packets without errors pTXErr [ O ] - Number of transmitted packets with framing errors pRXErr [ O ] - Number of recieved packets with framing errors pTXOfl [ O ] - Number of transmitted packets dropped due to overflow pRXOfl [ O ] - Number of recieved packets dropped due to overflow pTXBytesOk [ O ] - Number of transmitted bytes without errors pRXBytesOk [ O ] - Number of recieved bytes without errors pbLinkState [ 0 ] - Is the link active? pbReconfigure [ 0 ] - Must interface be reconfigured? (reset IP address) RETURN VALUE: int - 0 for success Negative errno for error ===========================================================================*/ int QMIWDSEventResp( void * pBuffer, u16 buffSize, u32 * pTXOk, u32 * pRXOk, u32 * pTXErr, u32 * pRXErr, u32 * pTXOfl, u32 * pRXOfl, u64 * pTXBytesOk, u64 * pRXBytesOk, bool * pbLinkState, bool * pbReconfigure ) { int result; u8 pktStatusRead[2]; // Ignore QMUX and SDU u8 offset = sizeof( sQMUX ) + 3; if (pBuffer == 0 || buffSize < offset || pTXOk == 0 || pRXOk == 0 || pTXErr == 0 || pRXErr == 0 || pTXOfl == 0 || pRXOfl == 0 || pTXBytesOk == 0 || pRXBytesOk == 0 || pbLinkState == 0 || pbReconfigure == 0 ) { return -ENOMEM; } pBuffer = pBuffer + offset; buffSize -= offset; // Note: Indications. No Mandatory TLV required result = GetQMIMessageID( pBuffer, buffSize ); // QMI WDS Set Event Report Resp if (result == 0x01) { // TLV's are not mandatory GetTLV( pBuffer, buffSize, 0x10, (void*)pTXOk, 4 ); GetTLV( pBuffer, buffSize, 0x11, (void*)pRXOk, 4 ); GetTLV( pBuffer, buffSize, 0x12, (void*)pTXErr, 4 ); GetTLV( pBuffer, buffSize, 0x13, (void*)pRXErr, 4 ); GetTLV( pBuffer, buffSize, 0x14, (void*)pTXOfl, 4 ); GetTLV( pBuffer, buffSize, 0x15, (void*)pRXOfl, 4 ); GetTLV( pBuffer, buffSize, 0x19, (void*)pTXBytesOk, 8 ); GetTLV( pBuffer, buffSize, 0x1A, (void*)pRXBytesOk, 8 ); } // QMI WDS Get PKG SRVC Status Resp else if (result == 0x22) { result = GetTLV( pBuffer, buffSize, 0x01, &pktStatusRead[0], 2 ); // 1 or 2 bytes may be received if (result >= 1) { if (pktStatusRead[0] == 0x02) { *pbLinkState = true; } else { *pbLinkState = false; } } if (result == 2) { if (pktStatusRead[1] == 0x01) { *pbReconfigure = true; } else { *pbReconfigure = false; } } if (result < 0) { return result; } } else { return -EFAULT; } return 0; }
/*=========================================================================== 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: 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: 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; }