// Test_SCH311X.cpp

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

#include <winioctl.h>
#include "SCH311xIoctl.h"

typedef void VOIDFUNC();

// Prototypes
void Usage(void);
void ShowIoctlValues(void);

void Test_SCH311X_HWM_IOCTL_GET_TEMP(void);
void Test_SCH311X_HWM_IOCTL_GET_TEMP_LIMITS(void);
void Test_SCH311X_HWM_IOCTL_SET_TEMP_LIMITS(void);
void Test_SCH311X_HWM_IOCTL_GET_VOLT(void);
void Test_SCH311X_HWM_IOCTL_GET_VOLT_LIMITS(void);
void Test_SCH311X_HWM_IOCTL_SET_VOLT_LIMITS(void);
void Test_SCH311X_HWM_IOCTL_WAIT_ON_MASK(void);
void Test_SCH311X_HWM_IOCTL_GET_FAN_COUNT(void);
void Test_SCH311X_HWM_IOCTL_GET_FAN_CONFIG(void);
void Test_SCH311X_HWM_IOCTL_SET_FAN_CONFIG(void);

void CloseIfOpen(void);

// Global data


#define N_IOCODES	10

// Names of IOCTL codes
//
char *IOnames[N_IOCODES+1] =
{
	"SCH311X_HWM_IOCTL_GET_TEMP",
	"SCH311X_HWM_IOCTL_GET_TEMP_LIMITS",
	"SCH311X_HWM_IOCTL_SET_TEMP_LIMITS",
	"SCH311X_HWM_IOCTL_GET_VOLT",
	"SCH311X_HWM_IOCTL_GET_VOLT_LIMITS",
	"SCH311X_HWM_IOCTL_SET_VOLT_LIMITS",
	"SCH311X_HWM_IOCTL_WAIT_ON_MASK",
	"SCH311X_HWM_IOCTL_GET_FAN_COUNT",
	"SCH311X_HWM_IOCTL_GET_FAN_CONFIG",
	"SCH311X_HWM_IOCTL_SET_FAN_CONFIG",
	""
};

// IOCTL codes
//
int IOcodes[N_IOCODES+1] =
{
	SCH311X_HWM_IOCTL_GET_TEMP,
	SCH311X_HWM_IOCTL_GET_TEMP_LIMITS,
	SCH311X_HWM_IOCTL_SET_TEMP_LIMITS,
	SCH311X_HWM_IOCTL_GET_VOLT,
	SCH311X_HWM_IOCTL_GET_VOLT_LIMITS,
	SCH311X_HWM_IOCTL_SET_VOLT_LIMITS,
	SCH311X_HWM_IOCTL_WAIT_ON_MASK,
	SCH311X_HWM_IOCTL_GET_FAN_COUNT,
	SCH311X_HWM_IOCTL_GET_FAN_CONFIG,
	SCH311X_HWM_IOCTL_SET_FAN_CONFIG,
	0
};


// Handle to device opened in driver.
//
HANDLE	hDevice = INVALID_HANDLE_VALUE;

// Name used to open device
//
char *sLinkName = "\\\\.\\SCH311X0";


////////////////////////////////////////////////////////////////////////
// OpenByName
//
//		Open a handle to the requested device
//
HANDLE OpenByName(void)
{	
	// Create a handle to the driver
	return CreateFile(sLinkName,
					  GENERIC_READ | GENERIC_WRITE,
					  FILE_SHARE_READ,
					  NULL,
					  OPEN_EXISTING,
					  0,
					  NULL);
}


////////////////////////////////////////////////////////////////////////
// Exit
//
//		Print a message and exit
//
   void Exit(int res)
{
	printf("Exiting...\n\n");
	CloseIfOpen();
	exit(res);
}


////////////////////////////////////////////////////////////////////////
// Main entry point
//
//
int __cdecl main(int argc, char *argv[])
{
	int		nArgIndex;				// Walk through command line arguments
	int		nArgIncrement = 0;
	int		val;

	printf("Test application Test_SCH311X starting...\n");

	hDevice = OpenByName();
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		printf("ERROR opening device: (%0x) returned from CreateFile\n", GetLastError());
		Exit(1);
	}
	else
	{
		printf("Device found, handle open.\n");
	}

	// Parse the command line

	if (argc < 2) Usage();

	nArgIndex = 1;
	while (nArgIndex < argc)
	{
		// Parse ahead to determine numeric value of argument

		if (nArgIndex+1 >= argc) Usage();
		if (!isdigit(argv[nArgIndex+1][0])) Usage();
		val = atoi(argv[nArgIndex+1]);

		switch (argv[nArgIndex][0])
		{
			case 'i':
			case 'I':
				if (val >= N_IOCODES)
				{
					printf("IO control code index must be less than %d\n", N_IOCODES);
					ShowIoctlValues();
					Exit(1);
				}
				switch (IOcodes[val])
				{

					case SCH311X_HWM_IOCTL_GET_TEMP:
						Test_SCH311X_HWM_IOCTL_GET_TEMP();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_GET_TEMP_LIMITS:
						Test_SCH311X_HWM_IOCTL_GET_TEMP_LIMITS();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_SET_TEMP_LIMITS:
						Test_SCH311X_HWM_IOCTL_SET_TEMP_LIMITS();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_GET_VOLT:
						Test_SCH311X_HWM_IOCTL_GET_VOLT();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_GET_VOLT_LIMITS:
						Test_SCH311X_HWM_IOCTL_GET_VOLT_LIMITS();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_SET_VOLT_LIMITS:
						Test_SCH311X_HWM_IOCTL_SET_VOLT_LIMITS();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_WAIT_ON_MASK:
						Test_SCH311X_HWM_IOCTL_WAIT_ON_MASK();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_GET_FAN_COUNT:
						Test_SCH311X_HWM_IOCTL_GET_FAN_COUNT();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_GET_FAN_CONFIG:
						Test_SCH311X_HWM_IOCTL_GET_FAN_CONFIG();
						nArgIncrement = 2;
						break;

					case SCH311X_HWM_IOCTL_SET_FAN_CONFIG:
						Test_SCH311X_HWM_IOCTL_SET_FAN_CONFIG();
						nArgIncrement = 2;
						break;

					default:
						printf("IO control code not valid\n");
						Exit(1);

				}
				break;

			case '?':
			case 'h':
			default:
				Usage();
		}
		nArgIndex += nArgIncrement;
	}

	return 0;
}


////////////////////////////////////////////////////////////////////////
// CloseIfOpen
//
//		Close the device if we previously opened a handle to it.
//
void CloseIfOpen(void)
{
	if (hDevice != INVALID_HANDLE_VALUE)
	{
		// Close the handle to the driver
		if (!CloseHandle(hDevice))
		{
			printf("ERROR: CloseHandle returns %0x.\n", GetLastError());
		}
		hDevice = INVALID_HANDLE_VALUE;
	}
}



////////////////////////////////////////////////////////////////////////
// Usage
//
//		Print a usage message describing arguments to this program
//
void Usage(void)
{
	printf("Usage: Test_SCH311X [i n]\n");
	printf("       i initiates an IO Control Code message with specified index value\n");
	ShowIoctlValues();
	
	Exit(1);
}


////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_GET_TEMP
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_GET_TEMP(void)
{
	UCHAR	sensor;		// Input to device
	UCHAR	temp;	// Output from device
	ULONG	nOutput;						// Count written to bufOutput

	printf("Specify which sensor to read (0 :CPU, 1 :ambient,  2 :remote): ");
	scanf("%d",&sensor);

	// Call device IO Control interface (SCH311X_HWM_IOCTL_GET_TEMP) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_GET_TEMP,
						 &sensor,sizeof(sensor),
						 &temp,sizeof(temp),
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns %d bytes.\n Temperature read: %d\n",nOutput,temp);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_GET_TEMP_LIMITS
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_GET_TEMP_LIMITS(void)
{
	UCHAR	sensor;		// Input to device
	SchTempSettings ts;	// Output from device
	ULONG	nOutput;	// Count written to bufOutput

	printf("Specify the sensor to get temp limits (0 :CPU, 1 :ambient,  2 :remote): ");
	scanf("%d",&sensor);

	// Call device IO Control interface (SCH311X_HWM_IOCTL_GET_TEMP_LIMITS) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_GET_TEMP_LIMITS,
						 &sensor,sizeof(sensor),
						 &ts,sizeof(ts),
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns %d bytes\nSensor: %d, low temp: %d, high temp: %d\n",nOutput,ts.sensor,(char)ts.loTemp,(char)ts.hiTemp);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_SET_TEMP_LIMITS
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_SET_TEMP_LIMITS(void)
{
	SchTempSettings ts;		// Input to device
	ULONG	nOutput;		// Count written to bufOutput

	printf("Specify the sensor to set limits (0 :CPU, 1 :ambient,  2 :remote): ");
	scanf("%d",&(ts.sensor));
	printf("Specify low temp. limit: ");
	scanf("%d",&(ts.loTemp));
	printf("Specify high temp. limit: ");
	scanf("%d",&(ts.hiTemp));

	// Call device IO Control interface (SCH311X_HWM_IOCTL_SET_TEMP_LIMITS) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_SET_TEMP_LIMITS,
						 &ts,sizeof(ts),
						 NULL,0,
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns OK, (%d bytes)\n",nOutput);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_GET_VOLT
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_GET_VOLT(void)
{
	UCHAR	sensor;		// Input to device
	ULONG	voltage;	// Output from device
	ULONG	nOutput;						// Count written to bufOutput

	printf("Specify, which sensor to read (0-6): ");
	scanf("%d",&sensor);

	// Call device IO Control interface (SCH311X_HWM_IOCTL_GET_VOLT) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_GET_VOLT,
						 &sensor,sizeof(sensor),
						 &voltage,sizeof(voltage),
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns %d bytes.\n Voltage read: %d mV\n",nOutput,voltage);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_GET_VOLT_LIMITS
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_GET_VOLT_LIMITS(void)
{
	UCHAR	sensor;		// Input to device
	SchVoltSettings vs;	// Output from device
	ULONG	nOutput;	// Count written to bufOutput

	printf("Specify the sensor to get limits (0-6): ");
	scanf("%d",&sensor);

	// Call device IO Control interface (SCH311X_HWM_IOCTL_GET_VOLT_LIMITS) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_GET_VOLT_LIMITS,
						 &sensor,sizeof(sensor),
						 &vs,sizeof(vs),
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns %d bytes\nSensor: %d, low limit: %d mV, high limit: %d mV\n",nOutput,vs.sensor,vs.loVoltage,vs.hiVoltage);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_SET_VOLT_LIMITS
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_SET_VOLT_LIMITS(void)
{
	SchVoltSettings vs;		// Input to device
	ULONG	nOutput;		// Count written to bufOutput

	printf("Specify the sensor to set limits (0-6): ");
	scanf("%d",&(vs.sensor));
	printf("Specify low voltage limit (mV): ");
	scanf("%d",&(vs.loVoltage));
	printf("Specify high voltage limit (mV): ");
	scanf("%d",&(vs.hiVoltage));

	// Call device IO Control interface (SCH311X_HWM_IOCTL_SET_VOLT_LIMITS) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_SET_VOLT_LIMITS,
						 &vs,sizeof(vs),
						 NULL,0,
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns OK, (%d bytes)\n",nOutput);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_WAIT_ON_MASK
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_WAIT_ON_MASK(void)
{
	ULONG newMask;		// Input to device
	ULONG oldMask;		// Output from device
	ULONG	nOutput;	// Count written to bufOutput

	printf("Specify the wait mask: ");
	scanf("%x",&newMask);

	// Call device IO Control interface (SCH311X_HWM_IOCTL_WAIT_ON_MASK) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_WAIT_ON_MASK,
						 &newMask,sizeof(newMask),
						 &oldMask,sizeof(oldMask),
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns: 0x%08x, (%d bytes)\n",oldMask,nOutput);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_GET_FAN_COUNT
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_GET_FAN_COUNT(void)
{
	UCHAR	sensor;		// Input to device
	USHORT	count;		// Output from device
	ULONG	nOutput;	// Count written to bufOutput

	printf("Specify which sensor to read (0-2): ");
	scanf("%d",&sensor);

	// Call device IO Control interface (SCH311X_HWM_IOCTL_GET_FAN_COUNT) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_GET_FAN_COUNT,
						 &sensor,sizeof(sensor),
						 &count,sizeof(count),
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns %d bytes.\n Fan count read: %d\n",nOutput,count);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_GET_FAN_CONFIG
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_GET_FAN_CONFIG(void)
{
	UCHAR	sensor;		// Input to device
	SchFanSettings fs;	// Output from device
	ULONG	nOutput;	// Count written to bufOutput

	printf("Specify the sensor to get config (0-2): ");
	scanf("%d",&sensor);

	// Call device IO Control interface (SCH311X_HWM_IOCTL_GET_FAN_CONFIG) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_GET_FAN_CONFIG,
						 &sensor,sizeof(sensor),
						 &fs,sizeof(fs),
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns %d bytes\nSensor: %d, limit: %d\n",nOutput,fs.sensor,fs.limit);
}

////////////////////////////////////////////////////////////////////////
// Test_SCH311X_HWM_IOCTL_SET_FAN_CONFIG
//
//		Test one Io Control Code
//
// TODO:
//		Pass appropriate arguments to your device and check
//		the return value
//
void Test_SCH311X_HWM_IOCTL_SET_FAN_CONFIG(void)
{
	SchFanSettings	fs;		// Input to device	
	ULONG	nOutput;		// Count written to bufOutput

	printf("Specify the sensor to set limit (0-2): ");
	scanf("%d",&(fs.sensor));
	printf("Specify limit: ");
	scanf("%d",&(fs.limit));

	// Call device IO Control interface (SCH311X_HWM_IOCTL_SET_FAN_CONFIG) in driver
	printf("Issuing Ioctl to device - ");
	if (!DeviceIoControl(hDevice,SCH311X_HWM_IOCTL_SET_FAN_CONFIG,
						 &fs,sizeof(fs),
						 NULL,0,
						 &nOutput,NULL))
	{
		printf("ERROR: DeviceIoControl returns %0x.", GetLastError());
		Exit(1);
	}

	printf("DeviceIoControl returns OK, (%d bytes)\n",nOutput);
}


////////////////////////////////////////////////////////////////////////
// ShowIoctlValues
//
//		Print list of IO Control Code values for usage display
//
void ShowIoctlValues(void)
{
	int i;

	for (i=0; i<N_IOCODES; i++)
	{
		if (i==0)
			printf( "         IO control code index\n");
		printf( "           %d is code %s [%x]\n", i, IOnames[i], IOcodes[i]);

	}
}

// EOF