/*===========================================================================
FILE: 
   GobiQMICoreImg2k.cpp

DESCRIPTION:
   QUALCOMM Gobi QMI Based API Core (Image Management, G2k API)

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
//---------------------------------------------------------------------------
#include "StdAfx.h"
#include "GobiMBNMgmt.h"
#include "GobiQMICore.h"

#include "QMIBuffers.h"

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

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

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

DESCRIPTION:
   Return a compatible AMSS generic image
  
PARAMETERS:
   uqcnInfo    [ I ] - UQCN image needing a compatible AMSS generic image

RETURN VALUE:
   sImageInfo - Generic image information
===========================================================================*/
sImageInfo GetGenericImage( const sImageInfo & uqcnInfo, unsigned int vid,
                            unsigned int pid )
{
   // Validate arguments
   sImageInfo amssInfo;

   // Obtain the technology/carrier of the UQCN
   ULONG uqcnTech;
   ULONG uqcnCarrier;
   ULONG dummy;
   eGobiError rc = ::MapVersionInfo( uqcnInfo.mVersionID,
                                     (BYTE)uqcnInfo.mImageType,
                                     uqcnInfo.mVersion.c_str(),
                                     &uqcnTech,
                                     &uqcnCarrier,
                                     &dummy,
                                     &dummy );

   if (rc != eGOBI_ERR_NONE)
   {
      return amssInfo;
   }

   // Recursively enumerate all folders of the image store
   std::vector <std::string> folders;
   std::string imageStore = ::GetImageStore(vid, pid);
   EnumerateFolders( imageStore, folders );

   // Did we find any folders?
   ULONG foldersSz = (ULONG)folders.size();
   if (foldersSz == 0)
   {
      return amssInfo;
   }

   // Go through each folder searching for a compatible generic AMSS image
   for (ULONG f = 0; f < foldersSz; f++)
   {
      // Search all MBN files in the specified folder
      std::string folderSearch = folders[f];

      int folderLen = folderSearch.size();
      if (folderSearch[folderLen - 1] != '/')
      {
         folderSearch += '/';
      }

      std::vector <std::string> files;
      DepthSearch( folderSearch,
                   0,
                   ".mbn",
                   files );

      int fileNum = files.size();
      for (int i = 0; i < fileNum; i++)
      {
         std::string mbnName = files[i];

         BYTE imageType = UCHAR_MAX;
         BYTE imageID[16] = { 0 };
         ULONG versionID = ULONG_MAX;
         USHORT versionSz = MAX_PATH * 2 + 1;
         CHAR versionStr[MAX_PATH * 2 + 1] = { 0 };
         rc = ::GetImageInfo( mbnName.c_str(),
                              &imageType,
                              &imageID[0],
                              &versionID,
                              versionSz,
                              &versionStr[0] );

         if (rc == eGOBI_ERR_NONE)
         {
            if ((eGobiMBNType)imageType == eGOBI_MBN_TYPE_MODEM)
            {
               ULONG amssTech;
               ULONG amssCarrier;
               rc = ::MapVersionInfo( versionID,
                                      imageType,
                                      (LPCSTR)&versionStr[0],
                                      &amssTech,
                                      &amssCarrier,
                                      &dummy,
                                      &dummy );

               if (rc == eGOBI_ERR_NONE)
               {
                  if ( (amssTech == uqcnTech) 
                  &&   (amssCarrier == (ULONG)eGOBI_IMG_CAR_GENERIC) )
                  {
                     amssInfo.mImageType = (eGobiMBNType)imageType;
                     amssInfo.mVersionID = versionID;
                     amssInfo.mVersion = (LPCSTR)&versionStr[0];
                     memcpy( (LPVOID)&amssInfo.mImageID[0], 
                             (LPCVOID)&imageID[0], 
                             MBN_UNIQUE_ID_LEN );
                     break;
                  }
               }
            }
         }
      }
   }

   // Success
   return amssInfo;
}

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

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

DESCRIPTION:
   Returns image information obtained from the current device firmware

PARAMETERS:
   pFirmwareID    [ O ] - Firmware ID obtained from the firmware image
   pTechnology    [ O ] - Technology (0xFFFFFFFF if unknown)
   pCarrier       [ O ] - Carrier (0xFFFFFFFF if unknown)
   pRegion        [ O ] - Region (0xFFFFFFFF if unknown)
   pGPSCapability [ O ] - GPS capability (0xFFFFFFFF if unknown)

RETURN VALUE:
   eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetFirmwareInfo( 
   ULONG *                    pFirmwareID,
   ULONG *                    pTechnology,
   ULONG *                    pCarrier,
   ULONG *                    pRegion,
   ULONG *                    pGPSCapability )
{
   // Validate arguments
   if ( (pFirmwareID == 0)
   ||   (pTechnology == 0) 
   ||   (pCarrier == 0)
   ||   (pRegion == 0)
   ||   (pGPSCapability == 0) )
   {
      return eGOBI_ERR_INVALID_ARG;
   }

   // Do we have a device node?
   if (mDeviceNode.empty() == true)
   {
      return eGOBI_ERR_NO_CONNECTION;
   }

   // Generate and send the QMI request
   WORD msgID = (WORD)eQMI_DMS_GET_REV_ID;
   sProtocolBuffer rsp = SendSimple( eQMI_SVC_DMS, msgID );
   if (rsp.IsValid() == false)
   {
      return GetCorrectedLastError();
   }

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

   // Prepare TLVs for parsing
   std::vector <sDB2NavInput> tlvs = DB2ReduceQMIBuffer( qmiRsp );
   const cCoreDatabase & db = GetDatabase();

   // Parse the TLV we want (by DB key)
   sProtocolEntityKey tlvKey( eDB2_ET_QMI_DMS_RSP, msgID, 17 );
   cDataParser::tParsedFields pf = ParseTLV( db, rsp, tlvs, tlvKey );
   if (pf.size() < 1) 
   {
      return eGOBI_ERR_INVALID_RSP;
   }

   std::string uqcnIDString = pf[0].mValueString;
   LONG strLen = uqcnIDString.size();
   if (strLen != 8)
   {
      return eGOBI_ERR_INVALID_RSP;
   }

   std::string idString1 = uqcnIDString.substr( 0, 2 );
   std::string idString2 = uqcnIDString.substr( 2, 2 );
   std::string idString3 = uqcnIDString.substr( 4, 2 );
   std::string idString4 = uqcnIDString.substr( 6, 2 );

   ULONG id1 = 0;
   ULONG id2 = 0;
   ULONG id3 = 0;
   ULONG id4 = 0;
   bool bID1 = StringToULONG( idString1.c_str(), 16, id1 );
   bool bID2 = StringToULONG( idString2.c_str(), 16, id2 );
   bool bID3 = StringToULONG( idString3.c_str(), 16, id3 );
   bool bID4 = StringToULONG( idString4.c_str(), 16, id4 );

   if (bID1 == false || bID2 == false || bID3 == false || bID4 == false)
   {
      return eGOBI_ERR_INVALID_RSP;
   }

   ULONG uqcnID = (id1 << 24) | (id2 << 16) | (id3 << 8) | id4;

   // Parse the TLV we want (AMSS revision)
   tlvKey = sProtocolEntityKey( eDB2_ET_QMI_DMS_RSP, msgID, 1 );
   pf = ParseTLV( db, rsp, tlvs, tlvKey );
   if (pf.size() < 1 || pf[0].mValueString.size() <= 0) 
   {
      return eGOBI_ERR_INVALID_RSP;
   }

   *pFirmwareID = uqcnID;
   eGobiError err = ::MapVersionInfo( uqcnID,
                                      (BYTE)eGOBI_MBN_TYPE_PRI,
                                      pf[0].mValueString.c_str(),
                                      pTechnology,
                                      pCarrier,
                                      pRegion,
                                      pGPSCapability );

   return err;
}

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

DESCRIPTION:
   This function performs the following set of steps:
      a)   Verifies arguments
      b)   Updates firmware ID on device
      c)   Resets the device

   NOTE: Upon successful completion the above steps will have been completed, 
         however the actual upgrade of the firmware will necessarily then 
         follow.

PARAMETERS:
   pDestinationPath  [ I ] - The fully qualified path to the destination folder 
                             that the firmware download service will use 
  
RETURN VALUE:
   eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::UpgradeFirmware( CHAR * pDestinationPath )
{
   char *end;
   ULONG carrier;

   // Validate arguments
   if (pDestinationPath == 0 || pDestinationPath[0] == 0)
   {
      return eGOBI_ERR_INVALID_ARG;
   }

   // Do we have a device ID?
   if (mDeviceNode.empty() == true)
   {
      return eGOBI_ERR_NO_CONNECTION;
   }

   if (*pDestinationPath == '/')
      pDestinationPath++;
   carrier = strtoul(pDestinationPath, &end, 10);
   if (*end)
      return eGOBI_ERR_INVALID_ARG;

   sImageInfo amssInfo;
   sImageInfo uqcnInfo;
   std::vector <sImageInfo> images;

   WORD msgID = (WORD)eQMI_DMS_SET_FIRMWARE_ID;
   std::vector <sDB2PackingInput> piv;

   std::ostringstream tmp;
   tmp << (UINT)carrier;

   sProtocolEntityKey pek( eDB2_ET_QMI_DMS_REQ, msgID, 1 );
   sDB2PackingInput pi( pek, tmp.str().c_str() );
   piv.push_back( pi );

   // Pack up the QMI request
   const cCoreDatabase & db = GetDatabase();
   sSharedBuffer * pRequest = DB2PackQMIBuffer( db, piv );

   // Send the QMI request, check result, and return 
   eGobiError rc = SendAndCheckReturn( eQMI_SVC_DMS, pRequest );
   if (rc != eGOBI_ERR_NONE)
   {
      return rc;
   }

   // Ask device to power down
   rc = SetPower( 5 );
   if (rc != eGOBI_ERR_NONE)
   {
      return eGOBI_ERR_RESET;
   }

   return rc;
}

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

DESCRIPTION:
   Returns image information obtained from the firmware image located at the
   provided path

PARAMETERS:
   pPath          [ I ] - Location of the firmware image
   pFirmwareID    [ O ] - Firmware ID obtained from the firmware image
   pTechnology    [ O ] - Technology (0xFFFFFFFF if unknown)
   pCarrier       [ O ] - Carrier (0xFFFFFFFF if unknown)
   pRegion        [ O ] - Region (0xFFFFFFFF if unknown)
   pGPSCapability [ O ] - GPS capability (0xFFFFFFFF if unknown)

RETURN VALUE:
   eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetImageInfo( 
   CHAR *                     pPath, 
   ULONG *                    pFirmwareID,
   ULONG *                    pTechnology,
   ULONG *                    pCarrier,
   ULONG *                    pRegion,
   ULONG *                    pGPSCapability )
{
   // Validate arguments
   if ( (pPath == 0)
   ||   (pPath[0] == 0)
   ||   (pFirmwareID == 0)
   ||   (pTechnology == 0) 
   ||   (pCarrier == 0)
   ||   (pRegion == 0)
   ||   (pGPSCapability == 0) )
   {
      return eGOBI_ERR_INVALID_ARG;
   }

   // Do we have a device ID?
   if (mDeviceNode.empty() == true)
   {
      return eGOBI_ERR_NO_CONNECTION;
   }

   // Use that to validate the image store for this device
   std::string tmpPath( pPath );
   int tmpPathlen = tmpPath.size();
   if (tmpPath[tmpPathlen - 1] != '/')
   {
      tmpPath += '/';
   }

   std::string imageStore = ::GetImageStore(mVid, mPid);
   if (tmpPath.find( imageStore ) < 0)
   {
      return eGOBI_ERR_INVALID_FILE;
   }

   std::vector <sImageInfo> images;
   images = ::GetImagesInfo( tmpPath );

   ULONG imageCount = (ULONG)images.size();
   for (ULONG i = 0; i < imageCount; i++)
   {
      const sImageInfo & ii = images[i];
      if (ii.mImageType == eGOBI_MBN_TYPE_PRI)
      {
         *pFirmwareID = ii.mVersionID;
         return ::MapVersionInfo( ii.mVersionID,
                                  (BYTE)ii.mImageType,
                                  ii.mVersion.c_str(),
                                  pTechnology,
                                  pCarrier,
                                  pRegion,
                                  pGPSCapability );
      }
   }

   return eGOBI_ERR_INVALID_FILE;
}

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

DESCRIPTION:
   Returns the image store folder, i.e. the folder co-located with the
   QDL Service executable which (by default) contains one or more carrier 
   specific image subfolders

PARAMETERS:
   pathSize          [ I ] - Maximum number of characters (including NULL
                             terminator) that can be copied to the image
                             store path array
   pImageStorePath   [ O ] - The path to the image store


RETURN VALUE:
   eGobiError - Return code
===========================================================================*/
eGobiError cGobiQMICore::GetImageStore(
   WORD                       pathSize,
   CHAR *                     pImageStorePath )
{
   // Do we have a device ID?
   if (mDeviceNode.size() == true)
   {
      return eGOBI_ERR_NO_CONNECTION;
   }

   std::string imageStore = ::GetImageStore(mVid, mPid);

   // Copy over image store
   LONG strLen = imageStore.size();
   if (pathSize < (ULONG)strLen + 1)
   {
      pImageStorePath[0] = 0;
      return eGOBI_ERR_BUFFER_SZ;
   }

   memcpy( (LPVOID)pImageStorePath, 
           (LPCVOID)imageStore.c_str(), 
           (SIZE_T)strLen );

   pImageStorePath[strLen] = 0;
   return eGOBI_ERR_NONE; 
}
