/*****************************************************************************
* Copyright (c) 1990-99 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
*
*****************************************************************************/
// ServiceX25Svc.cpp: implementation of the CServiceX25Svc class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "ServiceX25Svc.h"
#include "ObjectFactory.h"
#include "defs.h"
#include "DriverServices.h"
#include "ProtocolX25.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CServiceX25Svc, CServiceBase)


CServiceX25Svc::CServiceX25Svc(HKEY const hKeyRoot, CString const strRegPath, CConfigObject const * const pParent)
			:CServiceBase(hKeyRoot, strRegPath, pParent)
{
   m_nExistingEndPoints = 0;
	try
	{
		// Get adapter parameters
		AffirmThrow(GetParameters());

		// Solve our identity crisis
		SetIdentity(DXB_REGVAL_LINE_SERVICE_X25_SVC);

 		CString szDisplayName;
		AffirmThrow(szDisplayName.LoadString(IDS_X25SvcServiceName));
		SetDisplayName(szDisplayName);

		SetAbility(CConfigObject::NOABILITIES);

		// Get our static config data
		AffirmThrow(GetConfigData());
   }
   catch (CAffirmException ae)
   {
   }

}

CServiceX25Svc::~CServiceX25Svc()
{
}

BOOL CServiceX25Svc::BuildDisplayTree(CTreeNode * const pNode)
{
   TRACE("CServiceX25Svc::BuildDisplayTree: No display node added...\n");
   return FALSE; // We don't want a display not to appear for this
}

CString CServiceX25Svc::GetInformationText(void)
{
	CString strInfo;

	try
	{
		strInfo.Format(IDS_SVCINFO_FMT, GetAvailableSVCs());
	}
	catch (CAffirmException ae)
	{
	}

	return strInfo;
}

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

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

	return fSuccess;
}

BOOL CServiceX25Svc::SetParameters(void)
{
	CString szDescription = "";
	BOOL fSuccess = FALSE;
	int EndPoints = 0;

	try
	{
		EndPoints = GetAvailableSVCs();

      // Determine whether or not we're re-configuring an existing X25 config
      // Do this since RAS can't detect re-config changes (first config is OK),

      // A non-zero value for the existing endpoints means an X25 config already existed
      // And of course, check to see if we're actually changing it
      AffirmThrow(RegReadIntValue(m_hKey, DXB_REGVAL_ENDPOINTS, &m_nExistingEndPoints, 0));
      if ( (0 != m_nExistingEndPoints) && (EndPoints != m_nExistingEndPoints))
      {
         CString ConfigMessage;
         if (EndPoints < m_nExistingEndPoints)
         {
            // Lowering the number will cause RAS to think we have more TAPI devices than we really do
            ConfigMessage.LoadString(IDS_STRING_LOWERING_ENDPOINTS);
         } else {
            // Increasing the number will cause RAS to will think we have less TAPI devices than we really do
            ConfigMessage.LoadString(IDS_STRING_RAISING_ENDPOINTS);
            
         }
         // We need to look at our parent adapter...
         // Port<-Service<-Protocol<-Line<-Adapter
         CAdapter * pAdapter = (CAdapter *)(GetParent()->GetParent()->GetParent());
         AffirmThrow(pAdapter != NULL);
         // There isn't much that we can do other than inform the user of this...
         pAdapter->AddConfigMessage(ConfigMessage );
      }

      AffirmThrow(RegWriteIntValue(m_hKey, DXB_REGVAL_ENDPOINTS, EndPoints));

		if (0 == EndPoints)
		{
			// There are no available circuits or no SVC's configured on the line,
			// Remove the service.
			CString strInstance;
			// this value would have been written by the coinstaller for the client
			// driver, when the driver got installed.
			(void)RegReadStrValue(m_hKey, DXB_REGVAL_REGINSTANCE, strInstance);

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

			(void)RegDelValue(m_hKey, DXB_REGVAL_PDO_HDWID);
			(void)RegDelValue(m_hKey, DXB_REGVAL_PDO_DEVTYPE);

			(void)CService::RemoveParameters(FALSE);
			fSuccess = TRUE;
		}
		else
		{
			// Go ahead and configure the service
			szDescription.Format(IDS_X25_SVC_DESC_FMT, m_intLineNumber + 1);
			AffirmThrow(RegWriteStrValue(m_hKey, DXB_REGVAL_DESCRIPTION, szDescription));	  
			AffirmThrow(RegWriteStrValue(m_hKey, DXB_REGVAL_PDO_HDWID, DXB_HDWID_SVC));
			AffirmThrow(RegWriteDWordValue(m_hKey, DXB_REGVAL_PDO_DEVTYPE, DXB_DEVICE_NETCARD));
			AffirmThrow(CServiceBase::SetParameters());
		}

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

   return fSuccess;
}

BOOL CServiceX25Svc::RemoveParameters(BOOL fRemoveKey)
{
   BOOL fSuccess = FALSE;

   try
   {
	  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));

      AffirmThrow(CService::RemoveParameters(fRemoveKey));
      fSuccess = TRUE;
   }
   catch (CAffirmException ae)
   {
   }

   return fSuccess;
}

int CServiceX25Svc::GetAvailableSVCs(void)
{
	// This value is derived from the SVC ranges in the X.25 line settings
	// It reflects the total number of SVCs (dial in, dial out, both)
	int SVCs = ((CProtocolX25 *)(GetParent()))->GetTotalSVCs();
	// This is the number of PVCs that have been configured, it subtracts from the
	// total number available per line (256/LinesOnAdapter)
	INT_PTR PVCs = ((CProtocolX25 *)(GetParent()))->GetConfiguredPVCs();
	return ((m_cMaxPorts - PVCs) < SVCs) ? (m_cMaxPorts - PVCs) : SVCs;
}
