/*****************************************************************************
 * Copyright (C) Gemalto M2M GmbH
 *****************************************************************************
 * Project: IMC-RIL-Driver
 *****************************************************************************
 * Author : Wireless Modules RD SW A2
 *****************************************************************************
 * $Workfile: Y:/z_ms-d/src/working/Quinn/RilDrv/commain.cpp $
 * $Revision: /main/ms-d/6 $
 *     $Date: 2011-08-30 14:18:15 $
 *   $Author: ctna0256 $
 *****************************************************************************
 * Target:
 *  Microsoft Windows Mobile 5.0
 *****************************************************************************
 * Description:
 *  Gemalto IMC RIL
 *****************************************************************************
 *
 * $Log: Y:/z_ms-d/src/working/Quinn/RilDrv/commain.cpp$ 
 * 
 * /main/ms-d/6   2011-08-30 14:18:15   ctna0256 
 * Allow configurable GPS port (IPIS100074573)
 *
 * /main/ms-d/5   2011-07-27 09:19:54   ctna0256
 * Registry key for GPS COM port
 *
 * /main/ms-d/4   2008-08-22 10:23:03   ctna0256
 * Set Cinterion copyright text
 *
 * /main/ms-d/3   2008-08-21 09:34:07   ctna0256
 * Prepared for new disclaimer handling
 *
 * /main/ms-d/2   2008-04-03 14:41:27   mp49210
 * Introduction of new debug zones
 *
 * /main/ms-d/1   2006-10-25 16:53:05   wm36264
 * First transformation from classic RIL
 *
*/

//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2008 Gemalto M2M GmbH
// Copyright (C) 2006-2008 Siemens AG
// Copyright (C) 2003 Intrinsyc Europe Ltd.
//
// Version: 1.0
// Date:    dummy
//
//////////////////////////////////////////////////////////////////////////////

/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-1999  Microsoft Corporation
--*/

#include "precomp.h"

//
//
//
static BOOL ValidateOpenData(const DWORD dwOpenData, CComHandle*& rpDevice) {
CComInstanceHandle* pHandle = NULL;

  pHandle = (CComInstanceHandle*)dwOpenData;
  if (pHandle) {
    rpDevice = pHandle->GetDevice();
    if (rpDevice) {
      if (rpDevice->FHandleIsOwner(pHandle)) {
        return TRUE;
      }
    }
  }

  return FALSE;
}

//
//
// COM driver initialization
//
DWORD VDA_Init(DWORD dwInfo) {
  return (DWORD)g_ComManager.CreatePortDevice((LPWSTR)dwInfo);
}

//
// COM driver de-initialization
//
BOOL VDA_Deinit(DWORD dwData) {
  return g_ComManager.DestroyPortDevice((CComHandle*)dwData);
}

//
// Open a COM driver instance
//
DWORD VDA_Open(DWORD dwData, DWORD dwAccess, DWORD /*dwShareMode*/) {
CComInstanceHandle*  pHandle = NULL;
CComHandle*          pDevice = (CComHandle*)dwData;

  if (!pDevice) {
    RILRetailTraceZone(ZONE_ERROR, (TEXT("RilDrv: Failed to open application virtual data port (invalid port handle)\r\n")));
    return 0;
  }

  if (!pDevice->IsDownstreamPortOpen()) {
    RILRetailTraceZone(ZONE_ERROR, (TEXT("RilDrv: Failed to open application virtual data port (port not open)\r\n")));
    return 0;
  }

  RILRetailTraceZone(ZONE_INFO, (TEXT("RilDrv: Open application virtual data port \"%s\" (%s)\r\n"), g_ComManager.GetPortName(pDevice->GetPortType()), g_ComManager.GetDebugName(pDevice->GetPortType())));

  pHandle = new CComInstanceHandle;
  if (!pHandle || !pHandle->Init(pDevice, dwAccess)) {
    RILRetailTraceZone(ZONE_ERROR, (TEXT("RilDrv: Failed to open application virtual data port (falied to create CComInstanceHandle)\r\n")));
    if (pHandle) {
      delete pHandle;
    }
    return 0;
  }

  return (DWORD)pHandle;
}

//
// Close a COM driver instance
//
BOOL VDA_Close(DWORD dwOpenData) {
CComInstanceHandle*  pHandle = NULL;

  RILRetailTraceZone(ZONE_INFO, (TEXT("RilDrv: Close application virtual data port\r\n")));

  pHandle = (CComInstanceHandle*)dwOpenData;
  if (pHandle) {
    delete pHandle;
    return TRUE;
  }

  return FALSE;
}

//
// COM read
//
DWORD VDA_Read(DWORD dwOpenData, LPVOID pBuf, DWORD len) {
CComHandle* pDevice = NULL;

  if (!ValidateOpenData(dwOpenData, pDevice)) {
    return 0;
  }

  return g_ComManager.ExternalRead(pDevice->GetPortType(), pBuf, len);
}

//
// COM write
//
DWORD VDA_Write(DWORD dwOpenData, LPCVOID pBuf, DWORD len) {
CComHandle* pDevice = NULL;

  if (!ValidateOpenData(dwOpenData, pDevice)) {
    return 0;
  }

  return g_ComManager.ExternalWrite(pDevice->GetPortType(), pBuf, len);
}

//
// COM IO-control
//
BOOL VDA_IOControl(DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut) {
CComHandle* pDevice = NULL;

  if (!ValidateOpenData(dwOpenData, pDevice)) {
    return FALSE;
  }

  return g_ComManager.ExternalIoControl(pDevice->GetPortType(), dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
}

//
// Unimplemented standard interface functions
//
DWORD VDA_Seek(DWORD /*dwOpenData*/, long /*pos*/, DWORD /*type*/) { return (DWORD)-1; }
void VDA_PowerDown(DWORD /*dwData*/) { }
void VDA_PowerUp(DWORD /*dwData*/) { }

//
// COM driver initialization
//
DWORD COM_Init(DWORD /*dwInfo*/) {
  // Nothing to do -> simply return our global GPS handling
  return (DWORD)(&g_GpsHandling);
}

//
// COM driver de-initialization
//
BOOL COM_Deinit(DWORD dwData) {
  // Really nothing to do
  if (!dwData) return FALSE;
  return TRUE;
}

//
// Open a COM driver instance
//
DWORD COM_Open(DWORD dwData, DWORD /*dwAccess*/, DWORD /*dwShareMode*/) {
CGpsInstanceHandle* pInstance;
DWORD dwEnableGPS = 1;

  (void)GetRegistryDWORD(HKEY_LOCAL_MACHINE, g_tszRegKeyRIL, TEXT("EnableGPSPort"), &dwEnableGPS);
  if (dwEnableGPS != 1) return 0;
  if (!dwData) return 0;
  pInstance = new CGpsInstanceHandle();
  if (!pInstance) return 0;
  if (!pInstance->Open()) {
    delete pInstance;
    return 0;
  }
  return (DWORD)(pInstance);
}

//
// Close a COM driver instance
//
BOOL COM_Close(DWORD dwOpenData) {
BOOL fRet = TRUE;

  if (!dwOpenData) return FALSE;
  if (!((CGpsInstanceHandle*)dwOpenData)->Close()) fRet = FALSE;
  delete (CGpsInstanceHandle*)dwOpenData;
  return fRet;
}

//
// COM read
//
DWORD COM_Read(DWORD dwOpenData, LPVOID pBuf, DWORD len) {
  if (!dwOpenData) return (DWORD)-1;
  return ((CGpsInstanceHandle*)dwOpenData)->Read(pBuf, len);
}

//
// COM write
//
DWORD COM_Write(DWORD dwOpenData, LPCVOID pBuf, DWORD len) {
  if (!dwOpenData) return (DWORD)-1;
  return ((CGpsInstanceHandle*)dwOpenData)->Write(pBuf, len);
}

//
// COM IO-control
//
BOOL COM_IOControl(DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut) {
  if (!dwOpenData) return FALSE;
  return ((CGpsInstanceHandle*)dwOpenData)->IoControl(dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
}

//
// Unimplemented standard interface functions
//
DWORD COM_Seek(DWORD /*dwOpenData*/, long /*pos*/, DWORD /*type*/) { return (DWORD)-1; }
void COM_PowerDown(DWORD /*dwData*/) { }
void COM_PowerUp(DWORD /*dwData*/) { }


////////////////////////////////////////////////////////////////////////////
//
// If the DEVFLAGS_NAKEDENTRIES flag is set in the registry for the COM port,
// the OS will call the naked entries for this port (eg. Init() instead of COM_Init()).
//
////////////////////////////////////////////////////////////////////////////

#define DllExport    __declspec ( dllexport )

//
// COM driver initialization
//
extern "C" DllExport DWORD Init(DWORD dwInfo) {
  return COM_Init(dwInfo);
}

//
// COM driver de-initialization
//
extern "C" DllExport BOOL Deinit(DWORD dwData) {
  return COM_Deinit(dwData);
}

//
// Open a COM driver instance
//
extern "C" DllExport DWORD Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {
  return COM_Open(dwData, dwAccess, dwShareMode);
}

//
// Close a COM driver instance
//
extern "C" DllExport BOOL Close(DWORD dwOpenData) {
  return COM_Close(dwOpenData);
}

//
// COM read
//
extern "C" DllExport DWORD Read(DWORD dwOpenData, LPVOID pBuf, DWORD len) {
  return COM_Read(dwOpenData, pBuf, len);
}

//
// COM write
//
extern "C" DllExport DWORD Write(DWORD dwOpenData, LPCVOID pBuf, DWORD len) {
  return COM_Write(dwOpenData, pBuf, len);
}

//
// COM IO-control
//
extern "C" DllExport BOOL IOControl(DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut) {
  return COM_IOControl(dwOpenData, dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
}

//
// Unimplemented standard interface functions
//
extern "C" DllExport DWORD Seek(DWORD /*dwOpenData*/, long /*pos*/, DWORD /*type*/) { return (DWORD)-1; }
extern "C" DllExport void PowerDown(DWORD /*dwData*/) { }
extern "C" DllExport void PowerUp(DWORD /*dwData*/) { }

