1239 lines
32 KiB
C++
1239 lines
32 KiB
C++
/*===========================================================================
|
|
FILE:
|
|
GobiCMDLL.cpp
|
|
|
|
DESCRIPTION:
|
|
Simple class to load and interface to the Gobi CM DLL
|
|
|
|
PUBLIC CLASSES AND METHODS:
|
|
cGobiCMDLL
|
|
This class loads the Gobi CM DLL and then interfaces to it
|
|
|
|
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 "GobiCMDLL.h"
|
|
#include "GobiConnectionMgmtAPIStructs.h"
|
|
#include "Gobi3000Translation.h"
|
|
#include <string.h>
|
|
|
|
/*=========================================================================*/
|
|
// cGobiCMDLL Methods
|
|
/*=========================================================================*/
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetString (Internal Method)
|
|
|
|
DESCRIPTION:
|
|
Call a Gobi CM API function that returns a string
|
|
|
|
PARAMETERS:
|
|
mpFnString [ I ] - Gobi CM API function pointer
|
|
tlvID [ I ] - ID of response TLV that contains the string
|
|
strSz [ I ] - Max string size (including NULL terminator)
|
|
pStr [ O ] - Buffer to hold the string
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetString(
|
|
tFNGobiInputOutput mpFnString,
|
|
BYTE tlvID,
|
|
BYTE strSz,
|
|
CHAR * pStr )
|
|
{
|
|
// Assume failure
|
|
if (strSz > 0 && pStr != 0)
|
|
{
|
|
pStr[0] = 0;
|
|
}
|
|
|
|
// Query for string?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mpFnString == 0 || mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = mpFnString( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
std::map <UINT8, const sQMIRawContentHeader *> tlvs = GetTLVs( &rsp[0], lo );
|
|
std::map <UINT8, const sQMIRawContentHeader *>::const_iterator pIter = tlvs.find( tlvID );
|
|
if (pIter == tlvs.end())
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
const sQMIRawContentHeader * pTmp = pIter->second;
|
|
ULONG strLen = (ULONG)pTmp->mLength;
|
|
pTmp++;
|
|
|
|
if (strLen != 0 && strSz > 0 && pStr != 0)
|
|
{
|
|
ULONG needLen = strLen;
|
|
if (needLen + 1 > strSz)
|
|
{
|
|
needLen = strSz - 1;
|
|
}
|
|
|
|
memcpy( pStr, pTmp, needLen );
|
|
pStr[needLen] = 0;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
Connect (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls GobiConnect
|
|
|
|
PARAMETERS:
|
|
pInterface [ I ] - Interace to connect to
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::Connect( LPCSTR pInterface )
|
|
{
|
|
// Connect to WDS, DMS, and NAS services
|
|
ULONG svc[3] = { 1, 2, 3 };
|
|
ULONG svcCount = 3;
|
|
GOBIHANDLE handle = 0;
|
|
ULONG status = GobiConnect( pInterface, &svcCount, &svc[0], &handle );
|
|
if (status == 0)
|
|
{
|
|
if (svcCount == 3)
|
|
{
|
|
mhGobi = handle;
|
|
}
|
|
else
|
|
{
|
|
// We require WDS, DMS, and NAS services
|
|
Disconnect();
|
|
status = eGOBI_ERR_GENERAL;
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
Disconnect (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls GobiDisconnect
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::Disconnect()
|
|
{
|
|
if (mhGobi == 0)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
return GobiDisconnect( mhGobi );
|
|
}
|
|
|
|
/*===========================================================================
|
|
ETHOD:
|
|
StartDataSession (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls WDSStartNetworkInterface
|
|
|
|
PARAMETERS:
|
|
pAPN [ I ] - Access point name
|
|
pUser [ I ] - Username
|
|
pPwd [ I ] - Password
|
|
pSessionID [ O ] - Session ID
|
|
pFailureCode [ O ] - Failure code (if present)
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::StartDataSession(
|
|
LPCSTR pAPN,
|
|
LPCSTR pUser,
|
|
LPCSTR pPwd,
|
|
ULONG * pSessionID,
|
|
ULONG * pFailureCode )
|
|
{
|
|
// Assume failure
|
|
if (pSessionID != 0)
|
|
{
|
|
*pSessionID = 0xFFFFFFFF;
|
|
}
|
|
|
|
// Start a data session?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
UINT8 req[1024] = { 0 };
|
|
UINT8 * pData = (UINT8 *)&req[0];
|
|
|
|
sQMIRawContentHeader * pTLV = (sQMIRawContentHeader *)pData;
|
|
pTLV->mTypeID = 0x16;
|
|
pTLV->mLength
|
|
= (UINT16)sizeof( sWDSStartNetworkInterfaceRequest_Authentication );
|
|
pData += sizeof( sQMIRawContentHeader );
|
|
|
|
sWDSStartNetworkInterfaceRequest_Authentication * pAuth =
|
|
(sWDSStartNetworkInterfaceRequest_Authentication *)pData;
|
|
pAuth->mEnablePAP = 1;
|
|
pAuth->mEnableCHAP = 1;
|
|
pData += sizeof( sWDSStartNetworkInterfaceRequest_Authentication );
|
|
|
|
if (pAPN != 0 && pAPN[0] != 0)
|
|
{
|
|
size_t len = strnlen( pAPN, 256 );
|
|
|
|
pTLV = (sQMIRawContentHeader *)pData;
|
|
pTLV->mTypeID = 0x14;
|
|
pTLV->mLength = (UINT16)len;
|
|
pData += sizeof( sQMIRawContentHeader );
|
|
|
|
memcpy( pData, pAPN, len );
|
|
pData += len;
|
|
}
|
|
|
|
if (pUser != 0 && pUser[0] != 0)
|
|
{
|
|
size_t len = strnlen( pUser, 256 );
|
|
|
|
pTLV = (sQMIRawContentHeader *)pData;
|
|
pTLV->mTypeID = 0x17;
|
|
pTLV->mLength = (UINT16)len;
|
|
pData += sizeof( sQMIRawContentHeader );
|
|
|
|
memcpy( pData, pUser, len );
|
|
pData += len;
|
|
}
|
|
|
|
if (pPwd != 0 && pPwd[0] != 0)
|
|
{
|
|
size_t len = strnlen( pPwd, 256 );
|
|
|
|
pTLV = (sQMIRawContentHeader *)pData;
|
|
pTLV->mTypeID = 0x18;
|
|
pTLV->mLength = (UINT16)len;
|
|
pData += sizeof( sQMIRawContentHeader );
|
|
|
|
memcpy( pData, pPwd, len );
|
|
pData += len;
|
|
}
|
|
|
|
ULONG li = (ULONG)pData - (ULONG)&req[0];
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = WDSStartNetworkInterface( mhGobi, 300000, li, &req[0], &lo, &rsp[0] );
|
|
|
|
// On success pSessionID is valid, on failure pFailureCode is valid
|
|
ULONG status2 = ParseStartDataSession( lo, &rsp[0], pSessionID, pFailureCode );
|
|
|
|
if (status == eGOBI_ERR_NONE)
|
|
{
|
|
return status2;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
CancelDataSession (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls GobiCancel/WDSAbort
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::CancelDataSession()
|
|
{
|
|
// Cancel outstanding API request?
|
|
if (mhGobi == 0)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
// Cancel the request with the API
|
|
ULONG svcID = 1;
|
|
ULONG txID = 0xFFFFFFFF;
|
|
ULONG status = GobiCancel( mhGobi, svcID, &txID );
|
|
if (status != 0 || txID == 0xFFFFFFFF)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
UINT8 req[256] = { 0 };
|
|
UINT8 * pData = (UINT8 *)&req[0];
|
|
|
|
sQMIRawContentHeader * pTLV = (sQMIRawContentHeader *)pData;
|
|
pTLV->mTypeID = 0x01;
|
|
pTLV->mLength = (UINT16)sizeof( sAbortRequest_TransactionID );
|
|
pData += sizeof( sQMIRawContentHeader );
|
|
|
|
sAbortRequest_TransactionID * pID =
|
|
(sAbortRequest_TransactionID *)pData;
|
|
pID->mTransactionID = (UINT16)txID;
|
|
pData += sizeof( sAbortRequest_TransactionID );
|
|
|
|
// Cancel the request with the device
|
|
ULONG li = (ULONG)pData - (ULONG)&req[0];
|
|
status = WDSAbort( mhGobi, 2000, li, &req[0], 0, 0 );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
StopDataSession (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls WDSStopNetworkInterface
|
|
|
|
PARAMETERS:
|
|
sessionID [ I ] - Session ID
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::StopDataSession( ULONG sessionID )
|
|
{
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
UINT8 req[256] = { 0 };
|
|
ULONG li = 256;
|
|
|
|
status = PackStopDataSession( &li, &req[0], sessionID );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
// Stop data session
|
|
status = WDSStopNetworkInterface( mhGobi, 2000, li, &req[0], 0, 0 );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetSessionState (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls WDSGetPacketServiceStatus
|
|
|
|
PARAMETERS:
|
|
pSessionState [ O ] - Current session state
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetSessionState( ULONG * pSessionState )
|
|
{
|
|
// Assume failure
|
|
if (pSessionState != 0)
|
|
{
|
|
*pSessionState = 0xFFFFFFFF;
|
|
}
|
|
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = WDSGetPacketServiceStatus( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
status = ParseGetSessionState( lo, &rsp[0], pSessionState );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetSessionDuration (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls WDSGetDataSessionDuration
|
|
|
|
PARAMETERS:
|
|
pSessionDuration [ O ] - Session duration
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetSessionDuration( ULONGLONG * pSessionDuration )
|
|
{
|
|
// Assume failure
|
|
if (pSessionDuration != 0)
|
|
{
|
|
*pSessionDuration = 0xFFFFFFFF;
|
|
}
|
|
|
|
// Query for session duration
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = WDSGetDataSessionDuration( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
status = ParseGetSessionDuration( lo, &rsp[0], pSessionDuration );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetDataBearerTechnology (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls WDSGetDataBearerTechnology
|
|
|
|
PARAMETERS:
|
|
pDataBearerTech [ O ] - Data bearer technology
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetDataBearerTechnology( ULONG * pDataBearerTech )
|
|
{
|
|
// Assume failure
|
|
if (pDataBearerTech != 0)
|
|
{
|
|
*pDataBearerTech = 0xFFFFFFFF;
|
|
}
|
|
|
|
// Query for data bearer duration?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = WDSGetDataBearerTechnology( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
status = ParseGetDataBearerTechnology( lo, &rsp[0], pDataBearerTech );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetConnectionRate (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls WDSGetChannelRates
|
|
|
|
PARAMETERS:
|
|
pCurTX [ O ] - Current TX rate
|
|
pCurRX [ O ] - Current RX rate
|
|
pMaxTX [ O ] - Max TX rate
|
|
pMaxRX [ O ] - Max RX rate
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetConnectionRate(
|
|
ULONG * pCurTX,
|
|
ULONG * pCurRX,
|
|
ULONG * pMaxTX,
|
|
ULONG * pMaxRX )
|
|
{
|
|
// Assume failure
|
|
pCurTX != 0 ? *pCurTX = 0xFFFFFFFF : 0;
|
|
pCurRX != 0 ? *pCurRX = 0xFFFFFFFF : 0;
|
|
pMaxTX != 0 ? *pMaxTX = 0xFFFFFFFF : 0;
|
|
pMaxRX != 0 ? *pMaxRX = 0xFFFFFFFF : 0;
|
|
|
|
// Query for rates?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = WDSGetChannelRates( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
status = ParseGetConnectionRate( lo,
|
|
&rsp[0],
|
|
pCurTX,
|
|
pCurRX,
|
|
pMaxTX,
|
|
pMaxRX );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetFirmwareRevision (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls DMSGetDeviceRevision
|
|
|
|
PARAMETERS:
|
|
strSz [ I ] - Maximum number of characters
|
|
pStr [ O ] - Firmware revision string
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetFirmwareRevision(
|
|
BYTE strSz,
|
|
CHAR * pStr )
|
|
{
|
|
return GetString( DMSGetDeviceRevision, 0x01, strSz, pStr );
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetManufacturer (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls DMSGetDeviceManfacturer
|
|
|
|
PARAMETERS:
|
|
strSz [ I ] - Maximum string size
|
|
pStr [ O ] - Manufacturer string
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetManufacturer(
|
|
BYTE strSz,
|
|
CHAR * pStr )
|
|
{
|
|
return GetString( DMSGetDeviceManfacturer, 0x01, strSz, pStr );
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetModelID (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls GetModelID
|
|
|
|
PARAMETERS:
|
|
strSz [ I ] - Max string size
|
|
pStr [ O ] - Model ID string
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetModelID(
|
|
BYTE strSz,
|
|
CHAR * pStr )
|
|
{
|
|
return GetString( DMSGetDeviceModel, 0x01, strSz, pStr );
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetHardwareRevision (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls DMSGetHardwareRevision
|
|
|
|
PARAMETERS:
|
|
strSz [ I ] - Max size of string
|
|
pStr [ O ] - Hardware revision string
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetHardwareRevision(
|
|
BYTE strSz,
|
|
CHAR * pStr )
|
|
{
|
|
return GetString( DMSGetHardwareRevision, 0x01, strSz, pStr );
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetVoiceNumber (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls GetVoiceNumber
|
|
|
|
PARAMETERS:
|
|
voiceSz [ I ] - Max characters in voice string
|
|
pVoiceStr [ O ] - Voice number string
|
|
minSz [ I ] - Max characters in MIN string
|
|
pMINStr [ O ] - MIN string
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetVoiceNumber(
|
|
BYTE voiceSz,
|
|
CHAR * pVoiceStr,
|
|
BYTE minSz,
|
|
CHAR * pMINStr )
|
|
{
|
|
// Assume failure
|
|
if (voiceSz > 0 && pVoiceStr != 0)
|
|
{
|
|
pVoiceStr[0] = 0;
|
|
}
|
|
|
|
if (minSz > 0 && pMINStr != 0)
|
|
{
|
|
pMINStr[0] = 0;
|
|
}
|
|
|
|
// Query for voice numbers?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = DMSGetDeviceVoiceNumber( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
status = ParseGetVoiceNumber( lo,
|
|
&rsp[0],
|
|
voiceSz,
|
|
pVoiceStr,
|
|
minSz,
|
|
pMINStr );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetSerialNumbers (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls DMSGetDeviceSerialNumbers
|
|
|
|
PARAMETERS:
|
|
esnSz [ I ] - ESN size
|
|
pESNStr [ O ] - ESN string
|
|
imeiSz [ I ] - IMEI size
|
|
pIMEIStr [ O ] - IMSI string
|
|
meidSz [ I ] - MEID size
|
|
pMEIDStr [ O ] - MEID string
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetSerialNumbers(
|
|
BYTE esnSz,
|
|
CHAR * pESNStr,
|
|
BYTE imeiSz,
|
|
CHAR * pIMEIStr,
|
|
BYTE meidSz,
|
|
CHAR * pMEIDStr )
|
|
{
|
|
// Assume failure
|
|
if (esnSz > 0 && pESNStr != 0)
|
|
{
|
|
pESNStr[0] = 0;
|
|
}
|
|
|
|
if (imeiSz > 0 && pIMEIStr != 0)
|
|
{
|
|
pIMEIStr[0] = 0;
|
|
}
|
|
|
|
if (meidSz > 0 && pMEIDStr != 0)
|
|
{
|
|
pMEIDStr[0] = 0;
|
|
}
|
|
|
|
// Query for serial numbers?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = DMSGetDeviceSerialNumbers( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
status = ParseGetSerialNumbers( lo,
|
|
&rsp[0],
|
|
esnSz,
|
|
pESNStr,
|
|
imeiSz,
|
|
pIMEIStr,
|
|
meidSz,
|
|
pMEIDStr );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetIMSI (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Get IMSI
|
|
|
|
PARAMETERS:
|
|
imsiSz [ I ] - IMSI size
|
|
pIMSIStr [ O ] - IMSI string
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetIMSI(
|
|
BYTE imsiSz,
|
|
CHAR * pIMSIStr )
|
|
{
|
|
return GetString( DMSGetDeviceVoiceNumber, 0x11, imsiSz, pIMSIStr );
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetSignalStrengths (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls NASGetSignalStrength
|
|
|
|
PARAMETERS:
|
|
pSigStrengths [ O ] - Received signal strength
|
|
pRadioInterfaces [ O ] - Radio interface technology
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetSignalStrengths(
|
|
INT8 * pSigStrengths,
|
|
ULONG * pRadioInterfaces )
|
|
{
|
|
// Assume failure
|
|
for (ULONG s = 0; s < MAX_SIGNALS; s++)
|
|
{
|
|
pSigStrengths[s] = 0;
|
|
pRadioInterfaces[s] = 0xFFFFFFFF;
|
|
}
|
|
|
|
// Query for signal strengths?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 1024;
|
|
BYTE rsp[1024] = { 0 };
|
|
status = NASGetSignalStrength( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
status = ParseGetSignalStrength( lo,
|
|
&rsp[0],
|
|
pSigStrengths,
|
|
pRadioInterfaces );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetServingNetwork (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls NASGetServingSystem
|
|
|
|
PARAMETERS:
|
|
pDataCapabilities [ O ] - Data capabilities
|
|
pMCC [ O ] - Mobile country code
|
|
pMNC [ O ] - Mobile network code
|
|
nameSize [ I ] - Network name max size
|
|
pName [ O ] - Network name
|
|
pSID [ O ] - System ID
|
|
pNID [ O ] - Network ID
|
|
pRoam [ O ] - Roaming indicator
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetServingNetwork(
|
|
ULONG * pDataCapabilities,
|
|
WORD * pMCC,
|
|
WORD * pMNC,
|
|
BYTE nameSize,
|
|
CHAR * pName,
|
|
WORD * pSID,
|
|
WORD * pNID,
|
|
ULONG * pRoam )
|
|
{
|
|
// Assume failure
|
|
for (ULONG d = 0; d < MAX_DATA_CAPABILITIES; d++)
|
|
{
|
|
pDataCapabilities[d] = 0xFFFFFFFF;
|
|
}
|
|
|
|
if (nameSize > 0 && pName != 0)
|
|
{
|
|
pName[0] = 0;
|
|
}
|
|
|
|
pMCC != 0 ? *pMCC = 0xFFFF : 0;
|
|
pMNC != 0 ? *pMNC = 0xFFFF : 0;
|
|
pRoam != 0 ? *pRoam = 0xFFFFFFFF : 0;
|
|
pSID != 0 ? *pSID = 0xFFFF : 0;
|
|
pNID != 0 ? *pNID = 0xFFFF : 0;
|
|
|
|
// Query for serving system?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 8096;
|
|
BYTE rsp[8096] = { 0 };
|
|
status = NASGetServingSystem( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
std::map <UINT8, const sQMIRawContentHeader *> tlvs = GetTLVs( &rsp[0], lo );
|
|
std::map <UINT8, const sQMIRawContentHeader *>::const_iterator pIter = tlvs.find( 0x11 );
|
|
if (pIter != tlvs.end())
|
|
{
|
|
const sQMIRawContentHeader * pTmp = pIter->second;
|
|
ULONG tlvLen = (ULONG)pTmp->mLength;
|
|
ULONG dsLen = (ULONG)sizeof( sNASGetServingSystemResponse_DataServices );
|
|
if (tlvLen < dsLen)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
pTmp++;
|
|
const sNASGetServingSystemResponse_DataServices * pDS =
|
|
(const sNASGetServingSystemResponse_DataServices *)pTmp;
|
|
|
|
ULONG dcCount = (ULONG)pDS->mNumberOfDataCapabilities;
|
|
ULONG dcSz = (ULONG)sizeof( eQMINASDataServiceCapabilities2 );
|
|
dsLen += dcCount * dcSz;
|
|
if (tlvLen < dsLen)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
pDS++;
|
|
eQMINASDataServiceCapabilities2 * pCap = (eQMINASDataServiceCapabilities2 *)pDS;
|
|
if (dcCount > MAX_DATA_CAPABILITIES)
|
|
{
|
|
dcCount = MAX_DATA_CAPABILITIES;
|
|
}
|
|
|
|
for (ULONG i = 0; i < dcCount; i++)
|
|
{
|
|
pDataCapabilities[i] = (ULONG)*pCap++;
|
|
}
|
|
}
|
|
|
|
pIter = tlvs.find( 0x12 );
|
|
if (pIter != tlvs.end())
|
|
{
|
|
const sQMIRawContentHeader * pTmp = pIter->second;
|
|
ULONG tlvLen = (ULONG)pTmp->mLength;
|
|
ULONG plmnLen = (ULONG)sizeof( sNASGetServingSystemResponse_CurrentPLMN );
|
|
if (tlvLen < plmnLen)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
pTmp++;
|
|
const sNASGetServingSystemResponse_CurrentPLMN * pPLMN =
|
|
(const sNASGetServingSystemResponse_CurrentPLMN *)pTmp;
|
|
|
|
ULONG strLen = (ULONG)pPLMN->mDescriptionLength;
|
|
plmnLen += strLen;
|
|
if (tlvLen < plmnLen)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
pMCC != 0 ? *pMCC = (ULONG)pPLMN->mMobileCountryCode : 0;
|
|
pMNC != 0 ? *pMNC = (ULONG)pPLMN->mMobileNetworkCode : 0;
|
|
pPLMN++;
|
|
|
|
if (strLen != 0 && nameSize > 0 && pName != 0)
|
|
{
|
|
ULONG needLen = strLen;
|
|
if (needLen + 1 > nameSize)
|
|
{
|
|
needLen = nameSize - 1;
|
|
}
|
|
|
|
memcpy( pName, pPLMN, needLen );
|
|
pName[needLen] = 0;
|
|
}
|
|
}
|
|
|
|
pIter = tlvs.find( 0x13 );
|
|
if (pIter != tlvs.end())
|
|
{
|
|
const sQMIRawContentHeader * pTmp = pIter->second;
|
|
ULONG tlvLen = (ULONG)pTmp->mLength;
|
|
ULONG sysLen = (ULONG)sizeof( sNASGetServingSystemResponse_SystemID );
|
|
if (tlvLen < sysLen)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
pTmp++;
|
|
const sNASGetServingSystemResponse_SystemID * pSys =
|
|
(const sNASGetServingSystemResponse_SystemID *)pTmp;
|
|
|
|
pSID != 0 ? *pSID = (ULONG)pSys->mSystemID : 0;
|
|
pNID != 0 ? *pNID = (ULONG)pSys->mNetworkID : 0;
|
|
}
|
|
|
|
pIter = tlvs.find( 0x16 );
|
|
if (pIter != tlvs.end())
|
|
{
|
|
const sQMIRawContentHeader * pTmp = pIter->second;
|
|
ULONG tlvLen = (ULONG)pTmp->mLength;
|
|
ULONG roamLen = (ULONG)sizeof( sNASGetServingSystemResponse_DefaultRoaming );
|
|
if (tlvLen < roamLen)
|
|
{
|
|
return eGOBI_ERR_GENERAL;
|
|
}
|
|
|
|
pTmp++;
|
|
const sNASGetServingSystemResponse_DefaultRoaming * pDR =
|
|
(const sNASGetServingSystemResponse_DefaultRoaming *)pTmp;
|
|
|
|
pRoam != 0 ? *pRoam = (ULONG)pDR->mRoamingIndicator : 0;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
GetHomeNetwork (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls NASGetHomeNetwork
|
|
|
|
PARAMETERS:
|
|
pHomeMCC [ O ] - Mobile country code
|
|
pHomeMNC [ O ] - Mobile network code
|
|
homeNameSize [ I ] - Max name size
|
|
pHomeName [ O ] - Home network name
|
|
pSID [ O ] - System ID
|
|
pNID [ O ] - Network ID
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::GetHomeNetwork(
|
|
WORD * pHomeMCC,
|
|
WORD * pHomeMNC,
|
|
BYTE homeNameSize,
|
|
CHAR * pHomeName,
|
|
WORD * pSID,
|
|
WORD * pNID )
|
|
{
|
|
// Assume failure
|
|
if (homeNameSize > 0 && pHomeName != 0)
|
|
{
|
|
pHomeName[0] = 0;
|
|
}
|
|
|
|
pHomeMCC != 0 ? *pHomeMCC = 0xFFFF : 0;
|
|
pHomeMNC != 0 ? *pHomeMNC = 0xFFFF : 0;
|
|
pSID != 0 ? *pSID = 0xFFFF : 0;
|
|
pNID != 0 ? *pNID = 0xFFFF : 0;
|
|
|
|
// Query for home system?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
ULONG lo = 8096;
|
|
BYTE rsp[8096] = { 0 };
|
|
status = NASGetHomeNetwork( mhGobi, 2000, 0, 0, &lo, &rsp[0] );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
status = ParseGetHomeNetwork( lo,
|
|
&rsp[0],
|
|
pHomeMCC,
|
|
pHomeMNC,
|
|
homeNameSize,
|
|
pHomeName,
|
|
pSID,
|
|
pNID );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
SetWDSEventReportCB (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls WDSSetEventReport/SetGenericCallback
|
|
|
|
PARAMETERS:
|
|
pCallback [ I ] - Callback function pointer
|
|
interval [ I ] - Interval (in seconds) for transfer statistics
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::SetWDSEventReportCB(
|
|
tFNGenericCallback pCallback,
|
|
BYTE interval )
|
|
{
|
|
// Set WDS event callback?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
// Configure the QMI service
|
|
UINT8 req[1024] = { 0 };
|
|
UINT8 * pData = (UINT8 *)&req[0];
|
|
|
|
sQMIRawContentHeader * pTLV = (sQMIRawContentHeader *)pData;
|
|
pTLV->mTypeID = 0x11;
|
|
pTLV->mLength = (UINT16)sizeof( sWDSSetEventReportRequest_TransferStatisticsIndicator );
|
|
pData += sizeof( sQMIRawContentHeader );
|
|
|
|
sWDSSetEventReportRequest_TransferStatisticsIndicator * pTS =
|
|
(sWDSSetEventReportRequest_TransferStatisticsIndicator *)pData;
|
|
pTS->mTransferStatisticsIntervalSeconds = interval;
|
|
pTS->mReportTXPacketSuccesses = 0;
|
|
pTS->mReportRXPacketSuccesses = 0;
|
|
pTS->mReportTXPacketErrors = 0;
|
|
pTS->mReportRXPacketErrors = 0;
|
|
pTS->mReportTXOverflows = 0;
|
|
pTS->mReportRXOverflows = 0;
|
|
pTS->mTXByteTotal = 1;
|
|
pTS->mRXByteTotal = 1;
|
|
pData += sizeof( sWDSSetEventReportRequest_TransferStatisticsIndicator );
|
|
|
|
pTLV = (sQMIRawContentHeader *)pData;
|
|
pTLV->mTypeID = 0x12;
|
|
pTLV->mLength = (UINT16)sizeof( sWDSSetEventReportRequest_DataBearerTechnologyIndicator );
|
|
pData += sizeof( sQMIRawContentHeader );
|
|
|
|
sWDSSetEventReportRequest_DataBearerTechnologyIndicator * pTI =
|
|
(sWDSSetEventReportRequest_DataBearerTechnologyIndicator *)pData;
|
|
pTI->mReportDataBearerTechnology = 1;
|
|
pData += sizeof( sWDSSetEventReportRequest_DataBearerTechnologyIndicator );
|
|
|
|
ULONG li = (ULONG)pData - (ULONG)&req[0];
|
|
status = WDSSetEventReport( mhGobi, 2000, li, &req[0], 0, 0 );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
// Configure the callback with the API
|
|
status = SetGenericCallback( mhGobi, 1, 1, pCallback );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
SetWDSSessionStateCB (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls SetGenericCallback
|
|
|
|
PARAMETERS:
|
|
pCallback [ I ] - Callback function pointer
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::SetWDSSessionStateCB( tFNGenericCallback pCallback )
|
|
{
|
|
// Set WDS packet service status callback?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
// Configure the callback with the API
|
|
status = SetGenericCallback( mhGobi, 1, 34, pCallback );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
SetNASEventReportCB (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls NASSetEventReport/SetGenericCallback
|
|
|
|
PARAMETERS:
|
|
pCallback [ I ] - Callback function pointer
|
|
thresholdsSize [ I ] - Threshold size
|
|
pThresholds [ I ] - Array of thresholds
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::SetNASEventReportCB(
|
|
tFNGenericCallback pCallback,
|
|
BYTE thresholdsSize,
|
|
INT8 * pThresholds )
|
|
{
|
|
// Set NAS event report callback request?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if ( (mhGobi == 0)
|
|
|| (thresholdsSize > 0 && pThresholds == 0) )
|
|
{
|
|
return status;
|
|
}
|
|
|
|
// Configure the QMI service
|
|
UINT8 req[1024] = { 0 };
|
|
UINT8 * pData = (UINT8 *)&req[0];
|
|
|
|
sQMIRawContentHeader * pTLV = (sQMIRawContentHeader *)pData;
|
|
pTLV->mTypeID = 0x10;
|
|
pTLV->mLength = (UINT16)sizeof( sNASSetEventReportRequest_SignalIndicator );
|
|
pTLV->mLength += (UINT16)thresholdsSize;
|
|
pData += sizeof( sQMIRawContentHeader );
|
|
|
|
sNASSetEventReportRequest_SignalIndicator * pSI =
|
|
(sNASSetEventReportRequest_SignalIndicator *)pData;
|
|
pSI->mReportSignalStrength = 1;
|
|
pSI->mNumberOfThresholds = thresholdsSize;
|
|
pData += sizeof( sNASSetEventReportRequest_SignalIndicator );
|
|
|
|
for (UINT8 i = 0; i < thresholdsSize; i++)
|
|
{
|
|
INT8 * pThresh = (INT8 *)pData;
|
|
*pThresh = pThresholds[i];
|
|
pData++;
|
|
}
|
|
|
|
ULONG li = (ULONG)pData - (ULONG)&req[0];
|
|
status = NASSetEventReport( mhGobi, 2000, li, &req[0], 0, 0 );
|
|
if (status != 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
// Configure the callback with the API
|
|
status = SetGenericCallback( mhGobi, 3, 2, pCallback );
|
|
return status;
|
|
}
|
|
|
|
/*===========================================================================
|
|
METHOD:
|
|
SetNASServingSystemCB (Public Method)
|
|
|
|
DESCRIPTION:
|
|
Calls SetGenericCallback
|
|
|
|
PARAMETERS:
|
|
pCallback [ I ] - Callback function pointer
|
|
|
|
RETURN VALUE:
|
|
ULONG
|
|
===========================================================================*/
|
|
ULONG cGobiCMDLL::SetNASServingSystemCB( tFNGenericCallback pCallback )
|
|
{
|
|
// Set NAS serving system request?
|
|
ULONG status = eGOBI_ERR_GENERAL;
|
|
if (mhGobi == 0)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
// Configure the callback with the API
|
|
status = SetGenericCallback( mhGobi, 3, 36, pCallback );
|
|
return status;
|
|
}
|