/*****************************************************************************
* Copyright (c) 1990-98 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/


// ServiceIsdn.cpp: implementation of the CServiceIsdn class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ServiceIsdn.h"
#include "ObjectFactory.h"
#include "Adapter.h"

#ifdef NT5
#include "DriverServices.h"
#endif

#include "Resource.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC(CServiceIsdn, CService)

CServiceIsdn::CServiceIsdn(HKEY const hKeyRoot, CString const strRegPath, CConfigObject const * const pParent) : CService(hKeyRoot, strRegPath, pParent)
{
   try
   {
      // Get parameters
      AffirmThrow(GetParameters());

      // Solve our identity crisis
      SetIdentity(DXB_REGVAL_LINE_SERVICE_ISDN);

      // Set our display name
      CString strDisplayName;
      AffirmThrow(strDisplayName.LoadString(IDS_DisplayName_ISDN));
      SetDisplayName(strDisplayName);

      // Set what we can do
      SetAbility(CConfigObject::NOABILITIES);

      // Get our static config data
      AffirmThrow(GetConfigData());

      // Give birth to our children
      for (int i = 0; i < m_cMaxPorts; i++)
      {
         AffirmThrow(AddChild(i));
      }
   }
   catch (CAffirmException ae)
   {
   }
}

CServiceIsdn::~CServiceIsdn()
{
   try
   {
   }
   catch (CAffirmException ae)
   {
   }
}

BOOL CServiceIsdn::AddChild(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      for (int i = 0; i < m_cMaxPorts; i++)
      {
         BOOL fChildAlreadyExists = FALSE;

         for (int j = 0; j < m_apChildren.GetSize(); j++)
         {
            AffirmThrow(m_apChildren[j] != NULL);
            CPort * pChild = (CPort *)m_apChildren[j];

            if (i == pChild->GetPortNumber())
            {
               fChildAlreadyExists = TRUE;
               break;
            }
         }

         if (!fChildAlreadyExists)
         {
            AffirmThrow(AddChild(i));
            fSuccess = TRUE;
            break;
         }
      }
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL CServiceIsdn::AddChild(int const nChild)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(nChild >= 0);

      INT_PTR iNewChild = m_apChildren.Add(NULL);

      // This registry path thingie needs a little explanation!
      //    Here's the layout so far:
      //       ...\DigiDxb?\Parameters\XXXX\N         (where ? = the adapter instance, and
      //                                                     N = 0, 1, ... # of lines, and
      //                                                     XXXX = the service name)
      //    The port parameters reside at:
      //       ...\DigiDxb?\Parameters\XXXX\N\n       (where n = 0, 1, 2, ... # of ports)
      //    So, pass in the our current hKey, and the port number sub-key.

      CString strPort;
      strPort.Format(TEXT("%d"), nChild);
      AffirmThrow(NewConfigObject(&m_apChildren[iNewChild], CConfigObject::PORT, DXB_REGVAL_PORT_TYPE_BCHANNEL, m_hKey, strPort, this));      // always serial ports
      AffirmThrow(m_apChildren[iNewChild] != NULL);

      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

//////////////////////////////////////////////////////////////////////
// Get/Set parameters
//////////////////////////////////////////////////////////////////////

BOOL CServiceIsdn::GetParameters(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(CService::GetParameters());
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL CServiceIsdn::SetParameters(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(CService::SetParameters());

      INT_PTR cEndPoints = m_apChildren.GetSize();
      AffirmThrow(RegWriteIntValue(m_hKey, DXB_REGVAL_ENDPOINTS, int(cEndPoints)));
#ifdef NT5

#define E1_BCHANNELS 30
#define T1_BCHANNELS 23
#define BRI_BCHANNELS 2

	  CString strHdwId;
	  switch(cEndPoints)
	  {
	  case E1_BCHANNELS: strHdwId = DXB_HDWID_ISDNE1;break;
	  case T1_BCHANNELS: strHdwId = DXB_HDWID_ISDNT1;break;
	  case BRI_BCHANNELS: strHdwId = DXB_HDWID_ISDNBRI;break;
	  }
	  
	  AffirmThrow(RegWriteStrValue(m_hKey, DXB_REGVAL_PDO_HDWID, strHdwId));
	  AffirmThrow(RegWriteDWordValue(m_hKey, DXB_REGVAL_PDO_DEVTYPE, DXB_DEVICE_NETCARD));
#endif
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL CServiceIsdn::RemoveParameters(BOOL fRemoveKey /* = FALSE */)
{
   BOOL fSuccess = FALSE;

   try
   {
#ifdef NT5
	  CString strInstance;
	  // this value would have been written by the coinstaller for the client
	  // driver, when the driver got installed.
	  RegReadStrValue(m_hKey, DXB_REGVAL_REGINSTANCE, strInstance);

	  if (!strInstance.IsEmpty())
	  {
		DeleteService(strInstance);
		strInstance.Empty();
		RegWriteStrValue(m_hKey, DXB_REGVAL_REGINSTANCE, strInstance);
	  }

	  AffirmThrow(RegDelValue(m_hKey, DXB_REGVAL_PDO_HDWID));
	  AffirmThrow(RegDelValue(m_hKey, DXB_REGVAL_PDO_DEVTYPE));
#endif
      AffirmThrow(RegDelValue(m_hKey, DXB_REGVAL_ENDPOINTS));
      AffirmThrow(CService::RemoveParameters(fRemoveKey));

      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

//////////////////////////////////////////////////////////////////////
// Config data
//////////////////////////////////////////////////////////////////////

BOOL CServiceIsdn::GetConfigData(void)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(CService::GetConfigData());
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

//////////////////////////////////////////////////////////////////////
// UI config methods
//////////////////////////////////////////////////////////////////////

BOOL CServiceIsdn::AddWizardPages(CConfigWizSheet * const pSheet)
{
   BOOL fSuccess = FALSE;

   try
   {
      for (int i = 0; i < GetChildCount(); i++)
      {
         CConfigObject * pChild = GetChild(i);
         AffirmThrow(pChild != NULL);
         AffirmThrow(pChild->AddWizardPages(pSheet));
      }

      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL CServiceIsdn::NextWizardPage(int const nState)
{
   BOOL fSuccess = FALSE;

   try
   {
      AffirmThrow(FALSE);
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL CServiceIsdn::DoProperties(void)
{
   BOOL fThingsHaveChanged = FALSE;

   try
   {
      AffirmThrow(FALSE);
   }
   catch (CAffirmException ae)
   {
   }

   return fThingsHaveChanged;
}
