/*===========================================================================
FILE: 
   GobiQMICore.cpp

DESCRIPTION:
   QUALCOMM Gobi QMI Based API Core

PUBLIC CLASSES AND FUNCTIONS:
   cGobiQMICore

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 "GobiQMICore.h"

#include "QMIBuffers.h"
#include "ProtocolNotification.h"
#include "CoreUtilities.h"

//---------------------------------------------------------------------------
// Definitions
//---------------------------------------------------------------------------

// Default timeout for Gobi QMI requests
const ULONG DEFAULT_GOBI_QMI_TIMEOUT = 2000;

/*=========================================================================*/
// Free Methods
/*=========================================================================*/

/*===========================================================================
METHOD:
   FindTLV (Free Method)

DESCRIPTION:
   Find the given TLV

PARAMETERS:
   tlvs        [ I ] - TLV parsing input vector
   tlvKey      [ I ] - Key of the TLV that is to be found

RETURN VALUE:
   cDataParser::tParsedFields
===========================================================================*/
sDB2NavInput FindTLV( 
   const std::vector <sDB2NavInput> &  tlvs, 
   const sProtocolEntityKey &          tlvKey )
{
   sDB2NavInput retNI;

   // We need some TLVs to parse and a valid QMI DB key
   ULONG tlvCount = (ULONG)tlvs.size();
   if (tlvCount == 0 || tlvKey.mKey.size() < 3)
   {
      return retNI;
   }
   
   for (ULONG t = 0; t < tlvCount; t++)
   {
      const sDB2NavInput & ni = tlvs[t];
      if (tlvKey.mKey == ni.mKey)
      {
         retNI = ni;
         break;
      }
   }

   return retNI;
}

/*===========================================================================
METHOD:
   ParseTLV (Free Method)

DESCRIPTION:
   Parse the given TLV to fields

PARAMETERS:
   db             [ I ] - Database to use
   qmiBuf         [ I ] - Original buffer containing TLV (locks data)
   tlvs           [ I ] - TLV parsing input vector
   tlvKey         [ I ] - Key of the TLV that is to be parsed
   bFieldStrings  [ I ] - Generate field value strings?

RETURN VALUE:
   cDataParser::tParsedFields
===========================================================================*/
cDataParser::tParsedFields ParseTLV( 
   const cCoreDatabase &               db,
   const sProtocolBuffer &             qmiBuf,
   const std::vector <sDB2NavInput> &  tlvs, 
   const sProtocolEntityKey &          tlvKey,
   bool                                bFieldStrings )
{
   cDataParser::tParsedFields retFields;
   
   // We need some TLVs to parse and a valid QMI DB key
   ULONG tlvCount = (ULONG)tlvs.size();
   if (tlvCount == 0 || tlvKey.mKey.size() < 3)
   {
      return retFields;
   }
   
   for (ULONG t = 0; t < tlvCount; t++)
   {
      const sDB2NavInput & ni = tlvs[t];
      if (tlvKey.mKey == ni.mKey)
      {
         cDataParser dp( db, qmiBuf, tlvKey, ni.mpPayload, ni.mPayloadLen );
         dp.Parse( bFieldStrings, false );

         retFields = dp.GetFields();
         break;
      }
   }

   return retFields;
}

/*=========================================================================*/
// cGobiQMICore Methods
/*=========================================================================*/

/*===========================================================================
METHOD:
   cGobiQMICore (Public Method)

DESCRIPTION:
   Constructor
  
RETURN VALUE:
   None
===========================================================================*/
cGobiQMICore::cGobiQMICore()
   :  mbFailOnMultipleDevices( false ),
      mDeviceNode( "" ),
      mDeviceKey( "" ),
      mLastError( eGOBI_ERR_NONE ),
      mRequests( 16 ),
      mLastNetStartID( (WORD)INVALID_QMI_TRANSACTION_ID ),
      mVid(0xBAADBEEF), mPid(0xCAFEBABE)
{
   // Nothing to do
}

/*===========================================================================
METHOD:
   ~cGobiQMICore (Public Method)

DESCRIPTION:
   Destructor
  
RETURN VALUE:
   BOOL
===========================================================================*/
cGobiQMICore::~cGobiQMICore()
{
   Cleanup();
}

/*===========================================================================
METHOD:
   Initialize (Public Method)

DESCRIPTION:
   Initialize the object
  
RETURN VALUE:
   bool
===========================================================================*/
bool cGobiQMICore::Initialize()
{
   // Initialize database
   mDB.Initialize();
   
   // Allocate configured QMI servers
   bool bOK = true;
   std::set <tServerConfig>::const_iterator pIter = mServerConfig.begin();
   while (pIter != mServerConfig.end())
   {
      cQMIProtocolServer * pSvr = 0;
      pSvr = new cQMIProtocolServer( pIter->first, 8192, 512 );
      if (pSvr == 0)
      {
         if (pIter->second == true)
         {
            bOK = false;
            break;
         }
      }
      else
      {
         mServers[pIter->first] = pSvr;
      }
  
      pIter++;
   }

   if (bOK == false)
   {
      Cleanup(); 
   }

   return bOK;
}

/*===========================================================================
METHOD:
   Cleanup (Public Method)

DESCRIPTION:
   Cleanup the object
  
RETURN VALUE:
   bool
===========================================================================*/
bool cGobiQMICore::Cleanup()
{
   Disconnect();

   // Free allocated QMI servers
   std::map <eQMIService, cQMIProtocolServer *>::const_iterator pIter;
   pIter = mServers.begin();

   while (pIter != mServers.end())
   {
      cQMIProtocolServer * pSvr = pIter->second;
      if (pSvr != 0)
      {
         delete pSvr;
      }

      pIter++;
   }

   mServers.clear();

   return true;
}

GobiType cGobiQMICore::GetDeviceType()
{
   return ::GetDeviceType(mVid, mPid);
}

/*===========================================================================
METHOD:
   GetAvailableDevices (Public Method)

DESCRIPTION:
   Return the set of available Gobi network devices

RETURN VALUE:
   std::vector <tDeviceID> - Vector of device ID and device key pairs
===========================================================================*/
std::vector <cGobiQMICore::tDeviceID>
cGobiQMICore::GetAvailableDevices()
{
   std::vector <tDeviceID> devices;

   std::string path = "/sys/bus/usb/devices/";
   char buf[PATH_MAX];
   char *s;

   std::vector <std::string> files;
   DepthSearch( path,
                3,
                "qcqmi",
                files );

   int fileNum = files.size();
   for (int i = 0; i < fileNum; i++)
   {
      // Example "/sys/bus/usb/devices/8-1/8-1:1.0/GobiQMI/qcqmi0"
      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 two directories to the interface level
      std::string curPath = nodePath.substr( 0, lastSlash );
      curPath = curPath.substr( 0, curPath.find_last_of( "/" ) );

      // 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)
      {
         ret = strncmp( buff, "00", 2 );
         if (ret == 0)
         {
            bFound = true;
         }

         ret = strncmp( buff, "05", 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, "gobi"))
         continue;

      // Device node success!

      // Get MEID of device node (via ioctl) to use as key
      std::string deviceStr = "/dev/" + deviceNode;
      std::string key = cQMIProtocolServer::GetDeviceMEID( deviceStr );

      tDeviceID device;
      device.first = deviceNode;
      device.second = key;

      devices.push_back( device );
   }

   return devices;
}

static unsigned int getvidpid(const char *devname)
{
	char buf[PATH_MAX + 1];
	char nbuf[PATH_MAX + 1];
	char idproduct[16];
	char idvendor[16];
	int fd;

	snprintf(buf, sizeof(buf), "/sys/class/QCQMI/%s/../../..", devname);
	memset(nbuf, 0, sizeof(nbuf));
	if (!realpath(buf, nbuf)) {
		return 0;
	}

	snprintf(buf, sizeof(buf), "%s/idVendor", nbuf);
	fd = open(buf, O_RDONLY);
	if (fd < 0) {
		return 0;
	}
	if (read(fd, idvendor, sizeof(idvendor)) <= 0) {
		return 0;
	}
	close(fd);

	snprintf(buf, sizeof(buf), "%s/idProduct", nbuf);
	fd = open(buf, O_RDONLY);
	if (fd < 0) {
		return 0;
	}
	if (read(fd, idproduct, sizeof(idproduct)) <= 0) {
		return 0;
	}
	close(fd);

	return (strtoul(idvendor, NULL, 16) << 16) | strtoul(idproduct, NULL, 16);
}

/*===========================================================================
METHOD:
   Connect (Public Method)

DESCRIPTION:
   Connect to the specified (or first detected) Gobi device

   Both device node and key are case sensitive

PARAMETERS:
   pDeviceNode   [ I ] - The device node
   pDeviceKey    [ I ] - The device key (unique, stored on-device)
  
RETURN VALUE:
   bool
===========================================================================*/
bool cGobiQMICore::Connect(
   LPCSTR                     pDeviceNode,
   LPCSTR                     pDeviceKey )
{
   // Assume failure
   bool bRC = false;

   // Clear last error recorded
   ClearLastError();

   // If you specify a device key then you have to specify a device ID
   if (pDeviceNode == 0 && pDeviceKey != 0)
   {
      mLastError = eGOBI_ERR_INVALID_ARG;
      return bRC;
   }

   // First we terminate the current connection
   Disconnect();

   // Query system for list of active Gobi devices
   std::vector <tDeviceID> devices = GetAvailableDevices();

   // Did we find any devices?
   ULONG deviceCount = (ULONG)devices.size();
   if (deviceCount == 0)
   {
      mLastError = eGOBI_ERR_NO_DEVICE;
      return bRC;
   }

   std::string deviceKey = "";
   if (pDeviceKey != 0)
   {
      deviceKey = pDeviceKey;
   }

   // Filter that list to include only the specified device?
   if (pDeviceNode != 0)
   {
      std::vector <tDeviceID>::iterator current = devices.begin();
      while (current != devices.end())
      {
         // Remove if device node doesn't match
         if (current->first.compare( pDeviceNode ) != 0)
         {
            // Erase current element and update ourself to point to next
            current = devices.erase( current );
         }
         // Remove if invalid key is specified
         else if (deviceKey.size() != 0
              &&  current->second.compare( deviceKey ) != 0)
         {
            current = devices.erase( current );
         }
         // All necessary parameters match
         else
         {
            current++;
         }
      }
   }

   // Anything left after filtering?
   deviceCount = (ULONG)devices.size();
   if (deviceCount == 0)
   {
      mLastError = eGOBI_ERR_NO_DEVICE;
      return bRC;
   }

   // Too many to choose from?
   if (deviceCount > 1 && mbFailOnMultipleDevices == true)
   {
      mLastError = eGOBI_ERR_MULTIPLE_DEVICES;
      return bRC;
   }

   // Store device ID/key strings
   mDeviceNode = devices[0].first;
   mDeviceKey = devices[0].second;

   unsigned int vidpid = getvidpid(mDeviceNode.c_str());
   mVid = (vidpid >> 16) & 0xFFFF;
   mPid = vidpid & 0xFFFF;

   // Initalize/connect all configured QMI servers
   std::map <eQMIService, cQMIProtocolServer *>::const_iterator pIter;
   pIter = mServers.begin();

   while (pIter != mServers.end())
   {
      cQMIProtocolServer * pSvr = pIter->second;
      if (pSvr != 0)
      {
         // 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)
         pSvr->Initialize();

         std::string deviceStr = "/dev/" + mDeviceNode;
         bRC = pSvr->Connect( deviceStr.c_str() );
         if (bRC == false)
         {
            tServerConfig tsc( pIter->first, true );
            if (mServerConfig.find( tsc ) != mServerConfig.end())
            {
               // Failure on essential server
               break;
            }
            else
            {
               // QMI server non-essential (ignore failure)
               bRC = true;
            }
         }
      }

      pIter++;
   }

   // Any server fail?
   if (bRC == false)
   {
      // Yes, disconnect them all
      Disconnect();

      // ... and set the error code
      mLastError = eGOBI_ERR_CONNECT;
   }

   return bRC;
}

/*===========================================================================
METHOD:
   Disconnect (Public Method)

DESCRIPTION:
   Disconnect from the currently connected Gobi device
  
RETURN VALUE:
   bool
===========================================================================*/
bool cGobiQMICore::Disconnect()
{
   // Clear last error recorded
   ClearLastError();
   
   // Assume failure
   bool bRC = false;
   if (mDeviceNode.size() > 0)
   {
      mDeviceNode.clear();
      mDeviceKey.clear();
      bRC = true;
   }
   else 
   {
      mLastError = eGOBI_ERR_NO_CONNECTION;
   }

   // Disconnect/clean-up all configured QMI servers
   std::map <eQMIService, cQMIProtocolServer *>::const_iterator pIter;
   pIter = mServers.begin();

   while (pIter != mServers.end())
   {
      cQMIProtocolServer * pSvr = pIter->second;
      if (pSvr != 0)
      {
         pSvr->Disconnect();
         pSvr->Exit();
      }

      pIter++;
   }

   mVid = 0xDEADD00D;
   mPid = 0xDEADD00D;

   return bRC;
}

/*===========================================================================
METHOD:
   GetConnectedDeviceID (Public Method)

DESCRIPTION:
   Get the device node/key of the currently connected Gobi device  

PARAMETERS:
   devNode     [ O ] - Device node (IE: qcqmi0)
   devKey      [ O ] - Device key (may be empty)

RETURN VALUE:
   bool
===========================================================================*/
bool cGobiQMICore::GetConnectedDeviceID(
   std::string &                 devNode,
   std::string &                 devKey )
{
   // Clear last error recorded
   ClearLastError();

   // Assume failure
   bool bFound = false;
   devNode.clear();
   devKey.clear();

   // Are all required servers connected?
   bool bAllConnected = true;

   std::map <eQMIService, cQMIProtocolServer *>::const_iterator pIter;
   pIter = mServers.begin();

   while (pIter != mServers.end())
   {
      tServerConfig tsc( pIter->first, true );
      cQMIProtocolServer * pSvr = pIter->second;

      if (mServerConfig.find( tsc ) != mServerConfig.end() && pSvr != 0)
      {
         if (pSvr->IsConnected() == false)
         {
            // Failure on essential server
            bAllConnected = false;
            break;
         }
      }

      pIter++;
   }

   // Were we once connected?
   if (mDeviceNode.size() > 0 && bAllConnected == true)
   {
      // Yes, but is our device still present?
      // NOTE: This does not guarantee the device did not leave and come back
      std::vector <tDeviceID> devices = GetAvailableDevices();
      ULONG deviceCount = (ULONG)devices.size();

      for (ULONG a = 0; a < deviceCount; a++)
      {
         if (devices[a].first == mDeviceNode)
         {
            // If there is a device key specified, it must match.
            if (mDeviceKey.size() > 0)
            {
               if (devices[a].second == mDeviceKey)
               {
                  devNode = devices[a].first;
                  devKey = devices[a].second;

                  bFound = true;
                  break;
               }
            }
            else
            {
               devNode = devices[a].first;

               bFound = true;
               break;
            }
         }
      }

      if (bFound == false)
      {
         mLastError = eGOBI_ERR_NO_DEVICE;
      }
   }
   else
   {
      // We are not connected
      mLastError = eGOBI_ERR_NO_CONNECTION;
   }

   return bFound;
}

/*===========================================================================
METHOD:
   Send (Public Method)

DESCRIPTION:
   Send a request using the specified QMI protocol server and wait for (and
   then return) the response

PARAMETERS:
   svc         [ I ] - QMI service type
   pRequest    [ I ] - Request to schedule
   to          [ I ] - Timeout value (in milliseconds)

RETURN VALUE:
   sProtocolBuffer - The response (invalid when no response was received)
===========================================================================*/
sProtocolBuffer cGobiQMICore::Send(
   eQMIService                svc,
   sSharedBuffer *            pRequest,
   ULONG                      to )
{
   // 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, to, 1, 1, &pn );
   if (to == 0)
   {
      mLastError = eGOBI_ERR_INTERNAL;
      return rsp;
   }

   // Grab the server
   cQMIProtocolServer * pSvr = GetServer( svc );
   if (pSvr == 0)
   {
      mLastError = eGOBI_ERR_INTERNAL;
      return rsp;
   }

   // Are we connected?
   if (mDeviceNode.size() <= 0 || pSvr->IsConnected() == false)
   {
      mLastError = eGOBI_ERR_NO_CONNECTION;
      return rsp;
   }

   // Grab the log from the server
   const cProtocolLog & protocolLog = pSvr->GetLog();

   // Schedule the request
   ULONG reqID = pSvr->AddRequest( req );
   if (reqID == INVALID_REQUEST_ID)
   {
      mLastError = eGOBI_ERR_REQ_SCHEDULE;
      return rsp;
   }   

   // Store for external cancel
   tServiceRequest sr( svc, reqID );
   mRequests.AddElement( sr ); 

   bool bReq = false;
   bool bExit = false;
   DWORD idx;

   // Process up to the indicated timeout
   while (bExit == false)
   {
      int wc = sigEvt.Wait( to, 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:
         {
            // Are we doing WDS business?
            if (svc == eQMI_SVC_WDS)
            {
               // Grab the as-sent request
               DWORD id = evt.mParam2;
               sProtocolBuffer tmpReq = protocolLog.GetBuffer( id );
               sSharedBuffer * pTmpRequest = tmpReq.GetSharedBuffer();
               if (pTmpRequest != 0)
               {
                  // Check the message ID
                  sQMIServiceBuffer actualReq( pTmpRequest );
                  ULONG msgID = actualReq.GetMessageID();
                  if (msgID == (ULONG)eQMI_WDS_START_NET)
                  {
                     // Grab the transaction ID
                     mLastNetStartID = actualReq.GetTransactionID();
                  }
               }
            }

            bReq = 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
      pSvr->RemoveRequest( reqID );
   }

   // Check that the device is still there?
   if ( (mLastError == eGOBI_ERR_REQUEST)
   ||   (mLastError == eGOBI_ERR_RESPONSE)
   ||   (mLastError == eGOBI_ERR_REQUEST_TO)
   ||   (mLastError == eGOBI_ERR_RESPONSE_TO) )
   {
      eGobiError tmp = mLastError;

      std::string dummy;
      GetConnectedDeviceID( dummy, dummy );
      if (mLastError == eGOBI_ERR_NONE)
      {
         mLastError = tmp;
      }
   }

   return rsp;
}

/*===========================================================================
METHOD:
   SendAndCheckReturn (Public Method)

DESCRIPTION:
   Send a request using the specified QMI protocol server and wait for (and
   then validate) the response

PARAMETERS:
   svc         [ I ] - QMI service type
   pRequest    [ I ] - Request to schedule
   to          [ I ] - Timeout value (in milliseconds)

RETURN VALUE:
   eGobiError - Corrected error code
===========================================================================*/
eGobiError cGobiQMICore::SendAndCheckReturn(
   eQMIService                svc,
   sSharedBuffer *            pRequest,
   ULONG                      to )
{
   sProtocolBuffer rsp = Send( svc, pRequest, to );
   if (rsp.IsValid() == false)
   {
      return GetCorrectedLastError();
   }

   // Did we receive a valid QMI response?
   sQMIServiceBuffer qmiRsp( rsp.GetSharedBuffer() );
   if (qmiRsp.IsValid() == false)
   {
      mLastError = eGOBI_ERR_MALFORMED_RSP;
      return mLastError;
   }
            
   // Check the mandatory QMI result TLV for success
   ULONG rc = 0;
   ULONG ec = 0;
   bool bResult = qmiRsp.GetResult( rc, ec );
   if (bResult == false)
   {
      mLastError = eGOBI_ERR_MALFORMED_RSP;
      return mLastError;
   }
   else if (rc != 0)
   {
      return GetCorrectedQMIError( ec );
   }

   // Success!
   return eGOBI_ERR_NONE;
}

/*===========================================================================
METHOD:
   SendSimple (Public Method)

DESCRIPTION:
   Generate/send a request using the specified QMI protocol server and 
   wait for (and then return) the response

PARAMETERS:
   svc         [ I ] - QMI service type
   msgID       [ I ] - QMI message ID of the request to generate
   to          [ I ] - Timeout value (in milliseconds)

   NOTE: The request has to be a single byte in length, i.e. just a
         command code, in order for success

RETURN VALUE:
   sProtocolBuffer - The response (invalid when no response was received)
===========================================================================*/
sProtocolBuffer cGobiQMICore::SendSimple(
   eQMIService                svc,
   WORD                       msgID,
   ULONG                      to )
{
   // Clear last error recorded
   ClearLastError();

   sProtocolBuffer rsp;
   
   sSharedBuffer * pReq = 0;
   pReq = sQMIServiceBuffer::BuildBuffer( svc, msgID );
   if (pReq == 0)
   {
      mLastError = eGOBI_ERR_MEMORY;
      return rsp;
   }

   rsp = Send( svc, pReq, to );
   return rsp;
}

/*===========================================================================
METHOD:
   CancelSend (Public Method)

DESCRIPTION:
   Cancel the most recent in-progress Send() based operation

RETURN VALUE:
   eGobiError
===========================================================================*/
eGobiError cGobiQMICore::CancelSend()
{
   ULONG reqs = mRequests.GetTotalCount();
   if (reqs == 0)
   {
      return eGOBI_ERR_NO_CANCELABLE_OP;
   }

   tServiceRequest elem( eQMI_SVC_ENUM_BEGIN, INVALID_REQUEST_ID );
   bool bElem = mRequests.GetElement( --reqs, elem );
   if (bElem == false)
   {
      return eGOBI_ERR_INTERNAL;
   }

   cQMIProtocolServer * pSvr = GetServer( elem.first );
   if (pSvr == 0)
   {
      return eGOBI_ERR_INTERNAL;
   }


   bool bRemove = pSvr->RemoveRequest( elem.second );
   if (bRemove == false)
   {
      return eGOBI_ERR_CANCEL_OP;
   }

   return eGOBI_ERR_NONE;
}
