/*	DS_RAS.c
*
*******************************************************************************
* Copyright (c) 1996-97 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 copyright work  Digi   International *
* Inc.    Except   as   permitted   by  federal  law,  17 USC 117, copying is *
* strictly prohibited.                                                        *
*                                                                             *
* Digi  International  Inc.  CONFIDENTIAL  -   (Digi    International    Inc. *
* Confidential  when   combined   with   the   aggregated  modules  for  this *
* product) OBJECT CODE ONLY SOURCE MATERIALS                                  *
*                                                                             *
* (C) COPYRIGHT Digi International Inc. 1996-97                               *
*                                                                             *
* All Rights Reserved                                                         *
*                                                                             *
* US   Government   Users   Restricted   Rights   -   Use,   duplication   or *
* disclosure  restricted by GSA ADP Schedule Contract with Digi International *
* Inc.                                                                        *
*                                                                             *
*******************************************************************************
*
*/

#include "DS_RAS.h"
#include "span.h"
#include "Traps.h"
#include "Storage.h"
#include "Report.h"
#include "VarBind.h"
#include "Topology.h"
#include "RawRAS.h"

static size_t iMapToReturn = 0;
static ROOT_MAP const * const aprmMaps[] =
{
	&rmRawRAS
};

static void SetDebugData()
{
	HANDLE hDebug = INVALID_HANDLE_VALUE;
	char szDebugFile[MAX_PATH];
	size_t cbDebugFile = sizeof szDebugFile;

	if (GetStoredString("Debug/Log", szDebugFile, &cbDebugFile, NULL))
	{
		BOOL fAppend = FALSE;

		GetStoredNumber("Debug/Append", &fAppend, NULL);

		hDebug = CreateFile(szDebugFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, fAppend ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	}

	if (hDebug == INVALID_HANDLE_VALUE)
	{
		int const nMode = _CRTDBG_MODE_DEBUG;
	
		DebugReportMode(nMode, nMode, nMode);
	}
	else
	{
		int nMode = _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE;

		DebugReportMode(nMode, nMode, nMode);
		DebugReportFile(hDebug, hDebug, hDebug);
	}
}

void Startup(char const * const pszModule)
{
	char buffer[64];

	DebugMessage1("%s: Startup initiated\n", pszModule);

	sprintf(buffer, "DigiSNMP-%s", pszModule);
	ReportInitialize(buffer);

	sprintf(buffer, "Digi-%s", pszModule);
	StorageInitialize(buffer);

	SetDebugData();
	build_span();

	DebugMessage1("%s: Startup complete\n", pszModule);
}

void Shutdown(char const * const pszModule)
{
	DebugMessage1("%s: Shutdown initiated\n", pszModule);

	StopTrapHandler();
	DeleteCache();
	demolish_span();
	StorageTearDown();
	ReportTearDown();

	DebugMessage1("%s: Shutdown complete\n", pszModule);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	static char const szModule[] = "RAS";

	static size_t cProcesses = 0;

	switch (fdwReason)
	{
		case DLL_PROCESS_ATTACH:
		{
			if (cProcesses == 0)
				Startup(szModule);
			cProcesses++;
			break;
		}

		case DLL_PROCESS_DETACH:
		{
			cProcesses--;
			if (cProcesses == 0)
				Shutdown(szModule);
			break;
		}
	}

	return TRUE;
}  

BOOL WINAPI SnmpExtensionInitEx(AsnObjectIdentifier * /*const*/ poiaView)
{
	BOOL fReturningMap = FALSE;
	size_t const cMaps = ElementCount(aprmMaps);

	if (iMapToReturn < cMaps)
	{
		ROOT_MAP const * const prm = aprmMaps[iMapToReturn++];
/***		size_t iTrap;
***/

		/* copy the enterprise root */
		*poiaView = *(prm->poiaPartial);

		/* startup traps for this enterprise. */
/***		for (iTrap = 0; iTrap < prm->tm.cTraps; iTrap++)
		{
			TRAP_ENTRY const * const pte = &prm->tm.ate[iTrap];
			TrapData_t td = { prm->poiaPartial, pte->iaGenericType, pte->iaSpecificType };
			size_t iAdapter;
			size_t cAdapters = AdapterCount();

			for (iAdapter = 1; iAdapter <= cAdapters; iAdapter++)
			{
				TrapObject_t to = { 0 };

				to.eType = pte->eType;
				to.iBoard = iAdapter;

				if (pte->pfnMaxGeneric1 == NULL)
				{
					AddTrap(&to, &td, pte->pfnTrapHandler);
				}
				else
				{
					size_t iGeneric1;
					size_t cGeneric1s = pte->pfnMaxGeneric1(iAdapter);
					
					for (iGeneric1 = 1; iGeneric1 <= cGeneric1s; iGeneric1++)
					{
						to.iGeneric1 = iGeneric1;

						if (pte->pfnMaxGeneric2 == NULL)
						{
							AddTrap(&to, &td, pte->pfnTrapHandler);
						}
						else
						{
							size_t iGeneric2;
							size_t cGeneric2s = pte->pfnMaxGeneric2(iAdapter);
							
							for (iGeneric2 = 1; iGeneric2 <= cGeneric2s; iGeneric2++)
							{
								to.iGeneric2 = iGeneric2;
								AddTrap(&to, &td, pte->pfnTrapHandler);
							}
						}
					}
				}
			}
		}
***/

		fReturningMap = TRUE;
	}

	if (!fReturningMap)
		StartTrapHandler();

	return fReturningMap;
}
  
BOOL WINAPI SnmpExtensionInit(DWORD /*const*/ dwTimeZeroReference, HANDLE * /*const*/ phTrapEvent, AsnObjectIdentifier * /*const*/ poiaView)
{
	BOOL fSuccess = FALSE;
	HANDLE hHaveTraps = CreateEvent(NULL, FALSE, FALSE, NULL);

	if (hHaveTraps == NULL) goto Error;
	if (!InitTrapHandler(hHaveTraps)) goto Error;
	if (!SnmpExtensionInitEx(poiaView))	goto Error;

	*phTrapEvent = hHaveTraps;
	fSuccess = TRUE;

Error:

	if (!fSuccess)
	{
		if (hHaveTraps != NULL);
			CloseHandle(hHaveTraps);
	}

	return fSuccess;
}

BOOL WINAPI SnmpExtensionQuery(BYTE /*const*/ eType, RFC1157VarBindList * /*const*/ pvbl, AsnInteger * /*const*/ piaErrorStatus, AsnInteger * /*const*/ piaErrorIndex)
{
	BOOL fSuccess = FALSE;
	size_t iBinding;

	for (iBinding = 0; iBinding < pvbl->len; iBinding++)
	{
		RFC1157VarBind * const pvb = &pvbl->list[iBinding];
		size_t const cMaps = ElementCount(aprmMaps);
		size_t iMap;
		BYTE eCurrentType = eType;

		for (iMap = 0; iMap < cMaps; iMap++)
		{
			ROOT_MAP const * const prm = aprmMaps[iMap];

			if (OidPartialMatch(&pvb->name, 0, prm->poiaPartial))
			{
				if (!VarBind_Root(eCurrentType, prm, pvb, piaErrorStatus))
					goto Error;

				// That handler is done, let's see what else we can find.
				if ((*piaErrorStatus == SNMP_ERRORSTATUS_NOSUCHNAME) && 
					(eCurrentType == ASN_RFC1157_GETNEXTREQUEST))
				{
					size_t iNextMap = iMap + 1;

					*piaErrorStatus = SNMP_ERRORSTATUS_NOERROR;

					if (iNextMap == cMaps)
					{
						// That's the last one, point just past the last item in our tree.
						if (!_SnmpUtilOidCpy(&pvb->name, prm->poiaPartial)) goto Error;
						pvb->name.ids[pvb->name.idLength - 1]++;
					}
					else
					{
						// We still have more root objects, point to next OID iff it is exactly the next OID lexigraphically.
						ROOT_MAP const * const prmNext = aprmMaps[iNextMap];
						size_t iLastOid = prm->poiaPartial->idLength - 1;

						if ((iLastOid < prmNext->poiaPartial->idLength) &&
							(prmNext->poiaPartial->ids[iLastOid] == (prm->poiaPartial->ids[iLastOid] + 1)))
						{
							if (!_SnmpUtilOidCpy(&pvb->name, &prmNext->poiaPartial)) goto Error;
							continue;
						}
					}
				}
				
				break;
			}
		}

		if (iMap == cMaps)
			*piaErrorStatus = SNMP_ERRORSTATUS_NOSUCHNAME;

		if (*piaErrorStatus != SNMP_ERRORSTATUS_NOERROR)
		{
			*piaErrorIndex = iBinding + 1;
			break;
		}
	}

	if (eType == ASN_RFC1157_SETREQUEST)
		fSuccess = FlushWriteCache();
	else
		fSuccess = TRUE;

Error:

	if (!fSuccess)
	{
		if (eType == ASN_RFC1157_SETREQUEST)
			ClearWriteCache();
	}

	return fSuccess;
}
  
BOOL WINAPI SnmpExtensionTrap(AsnObjectIdentifier * /*const*/ poiaEnterprise, AsnInteger * /*const*/ piaGenericType, AsnInteger * /*const*/ piaSpecificType, AsnTimeticks * /*const*/ ptaTimeStamp, RFC1157VarBindList * /*const*/ pvblBindings)
{
	Trap_t const * const pTrap = GetNextTrap();

	if (pTrap)
	{
	}

	return (pTrap != NULL);
} 





  


