diff options
Diffstat (limited to 'gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQDLCore.cpp')
-rwxr-xr-x | gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQDLCore.cpp | 913 |
1 files changed, 913 insertions, 0 deletions
diff --git a/gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQDLCore.cpp b/gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQDLCore.cpp new file mode 100755 index 0000000..66ac29a --- /dev/null +++ b/gobi-api/fixed-GobiAPI-1.0.40/Shared/GobiQDLCore.cpp @@ -0,0 +1,913 @@ +/*=========================================================================== +FILE: + GobiQDLCore.cpp + +DESCRIPTION: + QUALCOMM Gobi QDL Based API Core + +PUBLIC CLASSES AND FUNCTIONS: + cGobiQDLCore + +Copyright (c) 2011, 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 "StdAfx.h" +#include "GobiQDLCore.h" + +#include "QDLBuffers.h" +#include "ProtocolNotification.h" + +#include <glob.h> + +//--------------------------------------------------------------------------- +// Definitions +//--------------------------------------------------------------------------- + +// Default/minimum timeout for QCWWAN QMI requests +const ULONG DEFAULT_GOBI_QDL_TIMEOUT = 4000; +const ULONG MINIMUM_GOBI_QDL_TIMEOUT = 2000; + +/*=========================================================================*/ +// cGobiQDLCore Methods +/*=========================================================================*/ + +/*=========================================================================== +METHOD: + cGobiQDLCore (Public Method) + +DESCRIPTION: + Constructor + +RETURN VALUE: + None +===========================================================================*/ +cGobiQDLCore::cGobiQDLCore() + : mQDL( 512, 512 ), + mQDLPortNode( "" ), + mQDLTimeout( DEFAULT_GOBI_QDL_TIMEOUT ) +{ + // Nothing to do +} + +/*=========================================================================== +METHOD: + ~cGobiQDLCore (Public Method) + +DESCRIPTION: + Destructor + +RETURN VALUE: + None +===========================================================================*/ +cGobiQDLCore::~cGobiQDLCore() +{ + // Nothing to do +} + +/*=========================================================================== +METHOD: + Initialize (Public Method) + +DESCRIPTION: + Initialize the object + +RETURN VALUE: + bool +===========================================================================*/ +bool cGobiQDLCore::Initialize() +{ + // Nothing to do + return true; +} + +/*=========================================================================== +METHOD: + Cleanup (Public Method) + +DESCRIPTION: + Cleanup the object + +RETURN VALUE: + bool +===========================================================================*/ +bool cGobiQDLCore::Cleanup() +{ + // Just in case + CloseQDLPort( false ); + + return true; +} + +/*=========================================================================== +METHOD: + GetAvailableQDLPorts (Public Method) + +DESCRIPTION: + Return the set of available Gobi QDL ports + +RETURN VALUE: + std::vector <sDeviceID> +===========================================================================*/ +std::vector <std::string> cGobiQDLCore::GetAvailableQDLPorts() +{ + std::vector <std::string> devices; + + std::string path = "/sys/bus/usb/devices/"; + char buf[PATH_MAX]; + + glob_t files; + int ret = glob( (path + "*/*/ttyUSB*").c_str(), + 0, + NULL, + &files ); + char *s; + if (ret != 0) + { + // Glob failure + return devices; + } + + for (int i = 0; i < files.gl_pathc; i++) + { + // Example "/sys/bus/usb/devices/8-1/8-1:1.1/ttyUSB0" + std::string nodePath = files.gl_pathv[i]; + + int lastSlash = nodePath.find_last_of( "/" ); + + // This is what we want to return if everything else matches + std::string deviceNode = nodePath.substr( lastSlash + 1 ); + + // Move down one directory to the interface level + std::string curPath = nodePath.substr( 0, lastSlash ); + + // Read bInterfaceNumber + int handle = open( (curPath + "/bInterfaceNumber").c_str(), + O_RDONLY ); + if (handle == -1) + { + continue; + } + + char buff[4]; + memset( buff, 0, 4 ); + + bool bFound = false; + ret = read( handle, buff, 2 ); + if (ret == 2) + { + // Interface 1 or 0 + ret = strncmp( buff, "01", 2 ); + if (ret == 0) + { + bFound = true; + } + ret = strncmp( buff, "00", 2 ); + if (ret == 0) + { + bFound = true; + } + + } + close( handle ); + + if (bFound == false) + { + continue; + } + + memset(buf, 0, sizeof(buf)); + if (readlink((curPath + "/driver").c_str(), buf, sizeof(buf)) < 0) + continue; + buf[sizeof(buf) - 1] = '\0'; + s = strrchr(buf, '/'); + s = s ? s + 1 : buf; + + if (strcmp(s, "qcserial") && strcmp(s, "QCSerial2k") + && strcmp(s, "GobiSerial")) + continue; + + // Success! + devices.push_back( deviceNode ); + } + globfree( &files ); + + return devices; +} + +/*=========================================================================== +METHOD: + SetQDLTimeout (Public Method) + +DESCRIPTION: + Set the timeout for all subsequent QDL transactions + +PARAMETERS: + to [ I ] - Timeout value (in milliseconds) + +RETURN VALUE: + eGobiError +===========================================================================*/ +eGobiError cGobiQDLCore::SetQDLTimeout( ULONG to ) +{ + if (to < MINIMUM_GOBI_QDL_TIMEOUT) + { + return eGOBI_ERR_INVALID_ARG; + } + + mQDLTimeout = to; + return eGOBI_ERR_NONE; +} + +/*=========================================================================== +METHOD: + OpenQDLPort (Public Method) + +DESCRIPTION: + This function opens the specified QDL port of the device + +PARAMETERS: + portID [ I ] - ID of QDL port to connect to + bBARMode [ I ] - Request boot and recovery mode feature + pMajorVersion [ O ] - Major version of the device boot downloader + pMinorVersion [ O ] - Minor version of the device boot downloader + +RETURN VALUE: + eGobiError - Return code +===========================================================================*/ +eGobiError cGobiQDLCore::OpenQDLPort( + std::string & portID, + ULONG bBARMode, + ULONG * pMajorVersion, + ULONG * pMinorVersion ) +{ + if (portID.empty() == true || pMajorVersion == 0 || pMinorVersion == 0) + { + return eGOBI_ERR_INVALID_ARG; + } + + // First disconnect from current port (if any) + CloseQDLPort( false ); + + // Validate port ID + std::string foundDevice; + std::vector <std::string> availPorts = GetAvailableQDLPorts(); + for (int index = 0; index < availPorts.size(); index++) + { + if (availPorts[index] == portID) + { + foundDevice = availPorts[index]; + break; + } + } + + if (foundDevice.empty() == true) + { + return eGOBI_ERR_INVALID_DEVID; + } + + // Initialize server (we don't care about the return code + // since the following Connect() call will fail if we are + // unable to initialize the server) + mQDL.Initialize(); + + // Connect to the port + std::string deviceStr = "/dev/" + foundDevice; + bool bOK = mQDL.Connect( deviceStr.c_str() ); + if (bOK == false) + { + return eGOBI_ERR_CONNECT; + } + + // Store port ID (we are connected) + mQDLPortNode = foundDevice; + + // Build the hello request + bool bBARFeature = bBARMode != 0; + sSharedBuffer * pHelloBuf = sQDLHello::BuildHelloReq( bBARFeature ); + if (pHelloBuf == 0) + { + return eGOBI_ERR_MEMORY; + } + + // Send the hello request and wait for the response + sProtocolBuffer rsp; + rsp = SendQDL( pHelloBuf ); + if (rsp.IsValid() == false) + { + return GetCorrectedLastError(); + } + + // Extract major and minor boot downloader versions + ULONG majVer; + ULONG minVer; + sQDLHello helloRsp( rsp.GetSharedBuffer() ); + if (helloRsp.GetBootVersionInfo( majVer, minVer ) == false) + { + sQDLError errRsp( rsp.GetSharedBuffer() ); + if (errRsp.IsValid() == true) + { + eQDLError qdlErr = errRsp.GetErrorCode(); + return GetCorrectedQDLError( qdlErr ); + } + + return eGOBI_ERR_MALFORMED_RSP; + } + + // NOTE: in the current firmware implimentation, this cannot happen. + // No hello response will be received in case of feature mismatch. + if (bBARFeature == true) + { + const sQDLRawHelloRsp * pTmpRsp = helloRsp.GetResponse(); + if (pTmpRsp == 0) + { + return eGOBI_ERR_MALFORMED_RSP; + } + + if ( (pTmpRsp->mFeatures & QDL_FEATURE_BAR_MODE) == 0) + { + return eGOBI_ERR_QDL_BAR_MODE; + } + } + + *pMajorVersion = majVer; + *pMinorVersion = minVer; + return eGOBI_ERR_NONE; +} + +/*=========================================================================== +METHOD: + CloseQDLPort (Public Method) + +DESCRIPTION: + This function closes the currently open QDL port of the device + +PARAMETERS: + bInformDevice [ I ] - Inform device that QDL port is being closed? + +RETURN VALUE: + eGobiError - Return code +===========================================================================*/ +eGobiError cGobiQDLCore::CloseQDLPort( bool bInformDevice ) +{ + // Assume success + eGobiError rc = eGOBI_ERR_NONE; + if (mQDLPortNode.empty() == true) + { + rc = eGOBI_ERR_NO_CONNECTION; + } + else if (bInformDevice == true) + { + BYTE cmd = (BYTE)eQDL_CMD_SESSION_CLOSE_REQ; + eProtocolType pt = ePROTOCOL_QDL_TX; + + sSharedBuffer * pReq = 0; + pReq = new sSharedBuffer( (const BYTE *)&cmd, 1, pt ); + if (pReq == 0) + { + rc = eGOBI_ERR_MEMORY; + } + else + { + sProtocolBuffer rsp = SendQDL( pReq, 0, 0, false ); + rc = GetLastError(); + } + } + + mQDL.Disconnect(); + mQDL.Exit(); + + mQDLPortNode.clear(); + + return rc; +} + +/*=========================================================================== +METHOD: + GetQDLImagesPreference (Public Method) + +DESCRIPTION: + This function gets the current images preference as reported by the + device boot downloader + +PARAMETERS: + pImageListSize [I/O] - Upon input the maximum number of elements that the + image info list can contain. Upon successful output + the actual number of elements in the image info list + pImageList [ O ] - The image info list + +RETURN VALUE: + eGobiError - Return code +===========================================================================*/ +eGobiError cGobiQDLCore::GetQDLImagesPreference( + ULONG * pImageListSize, + BYTE * pImageList ) +{ + if (pImageListSize == 0 || *pImageListSize == 0 || pImageList == 0) + { + return eGOBI_ERR_INVALID_ARG; + } + + BYTE cmd = (BYTE)eQDL_CMD_GET_IMAGE_PREF_REQ; + eProtocolType pt = ePROTOCOL_QDL_TX; + + sSharedBuffer * pReq = 0; + pReq = new sSharedBuffer( (const BYTE *)&cmd, 1, pt ); + if (pReq == 0) + { + return eGOBI_ERR_MEMORY; + } + + ULONG maxImages = (ULONG)*pImageListSize; + *pImageListSize = 0; + + sProtocolBuffer rsp = SendQDL( pReq ); + if (rsp.IsValid() == false) + { + return GetCorrectedLastError(); + } + + sQDLGetImagePref prefRsp( rsp.GetSharedBuffer() ); + if (prefRsp.IsValid() == false) + { + sQDLError errRsp( rsp.GetSharedBuffer() ); + if (errRsp.IsValid() == true) + { + eQDLError qdlErr = errRsp.GetErrorCode(); + return GetCorrectedQDLError( qdlErr ); + } + + return eGOBI_ERR_MALFORMED_RSP; + } + + std::list <sQDLRawImageID> imageIDs = prefRsp.GetImageIDs(); + ULONG imageCount = (ULONG)imageIDs.size(); + if (imageCount > maxImages) + { + imageCount = maxImages; + } + + sQDLRawImageID * pOutList = (sQDLRawImageID *)pImageList; + std::list <sQDLRawImageID>::const_iterator pIter = imageIDs.begin(); + for (ULONG i = 0; i < imageCount; i++) + { + *pOutList++ = *pIter++; + } + + *pImageListSize = imageCount; + return eGOBI_ERR_NONE; +} + +/*=========================================================================== +METHOD: + PrepareQDLImageWrite (Public Method) + +DESCRIPTION: + This function prepares the device boot downloader for an image write + +PARAMETERS: + imageType [ I ] - Type of image being written + imageSize [ I ] - Size of image being written + pBlockSize [I/O] - Upon input the maximum size of image block supported + by host, upon successful output the maximum size of + image block supported by device + +RETURN VALUE: + eGobiError - Return code +===========================================================================*/ +eGobiError cGobiQDLCore::PrepareQDLImageWrite( + BYTE imageType, + ULONG imageSize, + ULONG * pBlockSize ) +{ + eQDLImageType it = (eQDLImageType)imageType; + if (::IsValid( it ) == false) + { + return eGOBI_ERR_INVALID_ARG; + } + + if (pBlockSize == 0 || *pBlockSize == 0 || *pBlockSize > QDL_MAX_CHUNK_SIZE) + { + return eGOBI_ERR_INVALID_ARG; + } + + sSharedBuffer * pReq = 0; + pReq = sQDLOpenUnframed::BuildOpenUnframedReq( it, imageSize, *pBlockSize ); + if (pReq == 0) + { + return eGOBI_ERR_MEMORY; + } + + sProtocolBuffer rsp = SendQDL( pReq ); + if (rsp.IsValid() == false) + { + return GetCorrectedLastError(); + } + + ULONG tmp; + sQDLOpenUnframed openRsp( rsp.GetSharedBuffer() ); + const sQDLRawOpenUnframedRsp * pTmp = openRsp.GetResponse(); + if (pTmp == 0 || openRsp.GetChunkSize( tmp ) == false) + { + sQDLError errRsp( rsp.GetSharedBuffer() ); + if (errRsp.IsValid() == true) + { + eQDLError qdlErr = errRsp.GetErrorCode(); + return GetCorrectedQDLError( qdlErr ); + } + + return eGOBI_ERR_MALFORMED_RSP; + } + + if (openRsp.IsSuccess() == false) + { + switch ((eQDLOpenStatus)pTmp->mStatus) + { + case eQDL_OPEN_STATUS_SIZE: + return eGOBI_ERR_QDL_OPEN_SIZE; + + case eQDL_OPEN_STATUS_BAD_TYPE: + return eGOBI_ERR_QDL_OPEN_TYPE; + + case eQDL_OPEN_STATUS_PROTECTION: + return eGOBI_ERR_QDL_OPEN_PROT; + + case eQDL_OPEN_STATUS_NOT_NEEDED: + return eGOBI_ERR_QDL_OPEN_SKIP; + } + + return eGOBI_ERR_QDL_ERR_GENERAL; + } + + *pBlockSize = tmp; + return eGOBI_ERR_NONE; +} + +/*=========================================================================== +METHOD: + WriteQDLImageBlock (Public Method) + +DESCRIPTION: + This function writes the specified image block to the device + +PARAMETERS: + sequenceNumber [ I ] - Sequence number for image write + blockSize [ I ] - Size of image block + pImageBlock [ I ] - Image block + +RETURN VALUE: + eGobiError - Return code +===========================================================================*/ +eGobiError cGobiQDLCore::WriteQDLImageBlock( + USHORT sequenceNumber, + ULONG blockSize, + BYTE * pImageBlock ) +{ + if (blockSize > QDL_MAX_CHUNK_SIZE || pImageBlock == 0) + { + return eGOBI_ERR_INVALID_ARG; + } + + sSharedBuffer * pReq = 0; + pReq = sQDLWriteUnframed::BuildWriteUnframedReq( sequenceNumber, + blockSize ); + + if (pReq == 0) + { + return eGOBI_ERR_MEMORY; + } + + sProtocolBuffer rsp = SendQDL( pReq, pImageBlock, blockSize ); + if (rsp.IsValid() == false) + { + return GetCorrectedLastError(); + } + + sQDLWriteUnframed writeRsp( rsp.GetSharedBuffer() ); + const sQDLRawWriteUnframedRsp * pTmp = writeRsp.GetResponse(); + if (pTmp == 0) + { + sQDLError errRsp( rsp.GetSharedBuffer() ); + if (errRsp.IsValid() == true) + { + eQDLError qdlErr = errRsp.GetErrorCode(); + return GetCorrectedQDLError( qdlErr ); + } + + return eGOBI_ERR_MALFORMED_RSP; + } + + if (writeRsp.IsSuccess() == false) + { + switch ((eQDLWriteStatus)pTmp->mStatus) + { + case eQDL_WRITE_STATUS_CRC: + return eGOBI_ERR_QDL_CRC; + + case eQDL_WRITE_STATUS_CONTENT: + return eGOBI_ERR_QDL_PARSING; + } + + return eGOBI_ERR_QDL_ERR_GENERAL; + } + + return eGOBI_ERR_NONE; +} + +/*=========================================================================== +METHOD: + ValidateQDLImages (Public Method) + +DESCRIPTION: + This function requests the device validate the written images + +PARAMETERS: + pImageType [ O ] - Upon failure this may contain the type of the image + that failed validation + +RETURN VALUE: + eGobiError - Return code +===========================================================================*/ +eGobiError cGobiQDLCore::ValidateQDLImages( BYTE * pImageType ) +{ + if (pImageType == 0) + { + return eGOBI_ERR_INVALID_ARG; + } + + *pImageType = UCHAR_MAX; + + BYTE cmd = (BYTE)eQDL_CMD_SESSION_DONE_REQ; + eProtocolType pt = ePROTOCOL_QDL_TX; + + sSharedBuffer * pReq = 0; + pReq = new sSharedBuffer( (const BYTE *)&cmd, 1, pt ); + if (pReq == 0) + { + return eGOBI_ERR_MEMORY; + } + + sProtocolBuffer rsp = SendQDL( pReq ); + if (rsp.IsValid() == false) + { + return GetCorrectedLastError(); + } + + sQDLDone doneRsp( rsp.GetSharedBuffer() ); + const sQDLRawDoneRsp * pTmp = doneRsp.GetResponse(); + if (pTmp == 0) + { + sQDLError errRsp( rsp.GetSharedBuffer() ); + if (errRsp.IsValid() == true) + { + eQDLError qdlErr = errRsp.GetErrorCode(); + return GetCorrectedQDLError( qdlErr ); + } + + return eGOBI_ERR_MALFORMED_RSP; + } + + if (doneRsp.IsSuccess() == false) + { + *pImageType = pTmp->mImageType; + switch ((eQDLDoneStatus)pTmp->mStatus) + { + case eQDL_DONE_STATUS_AUTH: + return eGOBI_ERR_QDL_AUTH; + + case eQDL_DONE_STATUS_WRITE: + return eGOBI_ERR_QDL_WRITE; + } + + return eGOBI_ERR_QDL_ERR_GENERAL; + } + + return eGOBI_ERR_NONE; +} + +/*=========================================================================== +METHOD: + SendQDL (Public Method) + +DESCRIPTION: + Send a QDL request and wait for and return response (if needed) + +PARAMETERS: + pRequest [ I ] - Request to schedule + pAuxData [ I ] - Auxiliary data for request + auxDataSz [ I ] - Size of auxiliary data + bWaitForResponse [ I ] - Wait for a response? + +RETURN VALUE: + sProtocolBuffer - The response (invalid when no response was received) +===========================================================================*/ +sProtocolBuffer cGobiQDLCore::SendQDL( + sSharedBuffer * pRequest, + const BYTE * pAuxData, + ULONG auxDataSz, + bool bWaitForResponse ) +{ + // Clear last error recorded + ClearLastError(); + + // Returned response + sProtocolBuffer rsp; + + // Validate the arguments + if (pRequest == 0) + { + mLastError = eGOBI_ERR_MEMORY; + return rsp; + } + + // We use the event based notification approach + cSyncQueue <sProtocolNotificationEvent> evts( 12, true ); + cProtocolQueueNotification pn( &evts ); + + // Process up to the indicated timeout + cEvent & sigEvt = evts.GetSignalEvent(); + + // Build the request object + sProtocolRequest req( pRequest, 0, mQDLTimeout, 1, 1, &pn ); + req.SetAuxiliaryData( pAuxData, auxDataSz ); + if (bWaitForResponse == false) + { + req.SetTXOnly(); + } + + // Are we connected? + if ( (mQDLPortNode.empty() == true) + || (mQDL.IsConnected() == false) ) + { + mLastError = eGOBI_ERR_NO_CONNECTION; + return rsp; + } + + // Grab the log from the server + const cProtocolLog & protocolLog = mQDL.GetLog(); + + // Schedule the request + ULONG reqID = mQDL.AddRequest( req ); + if (reqID == INVALID_REQUEST_ID) + { + mLastError = eGOBI_ERR_REQ_SCHEDULE; + return rsp; + } + + bool bReq = false; + bool bExit = false; + DWORD idx; + + // Process up to the indicated timeout + while (bExit == false) + { + int wc = sigEvt.Wait( mQDLTimeout, idx ); + if (wc == ETIME) + { + if (bReq == true) + { + mLastError = eGOBI_ERR_RESPONSE_TO; + } + else + { + mLastError = eGOBI_ERR_REQUEST_TO; + } + break; + } + else if (wc != 0) + { + mLastError = eGOBI_ERR_INTERNAL; + break; + } + + sProtocolNotificationEvent evt; + bool bEvt = evts.GetElement( idx, evt ); + if (bEvt == false) + { + mLastError = eGOBI_ERR_INTERNAL; + bExit = true; + break; + } + + switch (evt.mEventType) + { + case ePROTOCOL_EVT_REQ_ERR: + mLastError = eGOBI_ERR_REQUEST; + bExit = true; + break; + + case ePROTOCOL_EVT_RSP_ERR: + mLastError = eGOBI_ERR_RESPONSE; + bExit = true; + break; + + case ePROTOCOL_EVT_REQ_SENT: + { + bReq = true; + if (bWaitForResponse == false) + { + // Success! + bExit = true; + } + } + break; + + case ePROTOCOL_EVT_RSP_RECV: + // Success! + rsp = protocolLog.GetBuffer( evt.mParam2 ); + bExit = true; + break; + } + } + + if ( (mLastError == eGOBI_ERR_INTERNAL) + || (mLastError == eGOBI_ERR_REQUEST_TO) + || (mLastError == eGOBI_ERR_RESPONSE_TO) ) + { + // Remove the request as our protocol notification object is + // about to go out of scope and hence be destroyed + mQDL.RemoveRequest( reqID ); + } + + return rsp; +} + +/*=========================================================================== +METHOD: + GetConnectedPortID (Public Method) + +DESCRIPTION: + Get the device node of the currently connected Gobi device + +PARAMETERS: + devNode [ O ] - Device node (IE: ttyUSB0) + +RETURN VALUE: + bool +===========================================================================*/ +bool cGobiQDLCore::GetConnectedPortID( std::string & devNode ) +{ + // Assume failure + bool bFound = false; + + devNode.clear(); + + // Were we once connected? + if (mQDLPortNode.size() > 0) + { + // Yes, but is our device still present? + // NOTE: This does not garantee the device did not leave and come back + std::vector <std::string> devices = GetAvailableQDLPorts(); + ULONG deviceCount = (ULONG)devices.size(); + + for (ULONG a = 0; a < deviceCount; a++) + { + if (devices[a] == mQDLPortNode) + { + devNode = devices[a]; + + bFound = true; + break; + } + } + + if (bFound == false) + { + mLastError = eGOBI_ERR_NO_DEVICE; + } + } + else + { + // We are not connected + mLastError = eGOBI_ERR_NO_CONNECTION; + } + + return bFound; +} |