/*===========================================================================
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
//---------------------------------------------------------------------------
#if defined(linux)
#include <unistd.h>
#endif

#include "StdAfx.h"
#include "GobiQDLCore.h"

#include "QDLBuffers.h"
#include "ProtocolNotification.h"
#include "CoreUtilities.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];

   std::vector <std::string> files;
   DepthSearch( path,
                2,
                "ttyUSB",
                files );

   int fileNum = files.size();
   for (int i = 0; i < fileNum; i++)
   {
      // Example "/sys/bus/usb/devices/8-1/8-1:1.1/ttyUSB0"
      std::string nodePath = files[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;
      int 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';
      char *s = strrchr(buf, '/');
      s = s ? s + 1 : buf;

      if (strcmp(s, "qcserial") && strcmp(s, "QCSerial2k")
          && strcmp(s, "GobiSerial"))
         continue;

      // Success!
      devices.push_back( deviceNode );
   }

   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;
}
