
/*
**	SANA-II extended device query test
**	Written by Timm S. Mueller
*/

#include <stdio.h>
#include <stdlib.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <devices/sana2.h>
#include <devices/sana2devqueryext.h>
#include <devices/newstyle.h>



struct MsgPort *devport = NULL;
struct IOSana2Req *ioreq = NULL;
struct Device *device = NULL;
BOOL devopen = FALSE;


static void g_exit(void)
{
	if (ioreq)
	{
		if (devopen)
			CloseDevice((struct IORequest *) ioreq);
		DeleteIORequest((struct IORequest *) ioreq);
	}
	if (devport)
		DeleteMsgPort(devport);
}


static BOOL g_init(void)
{
	for (;;)
	{
		devport = CreateMsgPort();
		if (!devport)
			break;
		ioreq = (struct IOSana2Req *) CreateIORequest(devport, 
			sizeof(struct IOSana2Req));
		if (!ioreq)
			break;
		devopen = OpenDevice("x-surf-100.device", 0,
			(struct IORequest *) ioreq, 0) == 0;
		if (!devopen)
		{
			printf("cannot open device\n");
			break;
		}
		return TRUE;
	}
	g_exit();
	return FALSE;
}


static BOOL findcmd(struct NSDeviceQueryResult *nsdqr, UWORD cmd)
{
	UWORD *p;
	for (p = nsdqr->SupportedCommands; (*p); ++p)
		if (*p == cmd)
			return TRUE;
	return FALSE;
}


int main(int argc, char **argv)
{
	int res = RETURN_FAIL;
	if (!g_init())
		return res;
	
	for (;;)
	{
		char vendorname[128], productname[128];
		ULONG link, speed;
		struct NSDeviceQueryResult nsdqr;
		struct IOStdReq *stdreq = (struct IOStdReq *) ioreq;
		struct S2DevQueryExtParam pproductname;
		struct S2DevQueryExtParam pvendorname;
		struct S2DevQueryExtParam plink;
		struct S2DevQueryExtParam pspeed;
		struct TagItem tags[5];
		
		res = RETURN_ERROR;
		
		stdreq->io_Command = NSCMD_DEVICEQUERY;
		stdreq->io_Flags = 0;
		stdreq->io_Data = &nsdqr;
		stdreq->io_Length = sizeof nsdqr;
		
		if (DoIO((struct IORequest *) ioreq) != 0)
		{
			printf("I/O error\n");
			break;
		}
		
		if (nsdqr.DeviceType != NSDEVTYPE_SANA2)
		{
			printf("device not of required type: %u\n", nsdqr.DeviceType);
			break;
		}
		
		ioreq->ios2_Req.io_Command = S2_GETSTATIONADDRESS;
		if (DoIO((struct IORequest *) ioreq) == 0)
		{
			unsigned char *p = ioreq->ios2_SrcAddr;
			printf("current: %02x:%02x:%02x:%02x:%02x:%02x\n", 
				(int) p[0], (int) p[1], (int) p[2], (int) p[3],
				(int) p[4], (int) p[5]);
			p = ioreq->ios2_DstAddr;
			printf("default: %02x:%02x:%02x:%02x:%02x:%02x\n", 
				(int) p[0], (int) p[1], (int) p[2], (int) p[3],
				(int) p[4], (int) p[5]);
		}
		else
		{
			printf("I/O error\n");
			break;
		}

		res = RETURN_WARN;
		
		if (!findcmd(&nsdqr, S2_DEVICEQUERYEXT))
		{
			printf("extended command not supported\n");
			break;
		}
		
		pvendorname.Data = vendorname;
		pvendorname.Length = sizeof vendorname;
		pvendorname.Actual = 0;
		pproductname.Data = productname;
		pproductname.Length = sizeof productname;
		pproductname.Actual = 0;
		plink.Data = &link;
		plink.Length = sizeof link;
		plink.Actual = 0;
		pspeed.Data = &speed;
		pspeed.Length = sizeof speed;
		pspeed.Actual = 0;
		
		tags[0].ti_Tag = S2_DevQueryExtVendorName;
		tags[0].ti_Data = (ULONG) &pvendorname;
		tags[1].ti_Tag = S2_DevQueryExtProductName;
		tags[1].ti_Data = (ULONG) &pproductname;
		tags[2].ti_Tag = S2_DevQueryExtLinkStatus;
		tags[2].ti_Data = (ULONG) &plink;
		tags[3].ti_Tag = S2_DevQueryExtLinkSpeed;
		tags[3].ti_Data = (ULONG) &pspeed;
		tags[4].ti_Tag = TAG_DONE;
		
		ioreq->ios2_Req.io_Command = S2_DEVICEQUERYEXT;
		ioreq->ios2_Data = tags;
		ioreq->ios2_DataLength = sizeof tags;
		
		if (DoIO((struct IORequest *) ioreq) == 0)
		{
			if (pvendorname.Actual != 0)
			{
				vendorname[sizeof(vendorname) - 1] = 0;
				printf("vendorname: %s\n", vendorname);
			}
			if (pproductname.Actual != 0)
			{
				productname[sizeof(productname) - 1] = 0;
				printf("productname: %s\n", productname);
			}
			if (plink.Actual == sizeof link)
				printf("link: %lu\n", link);
			if (pspeed.Actual == sizeof speed)
				printf("speed: %lu\n", speed);
			
			res = RETURN_OK;
		}
		else
			printf("error getting extended attributes\n");
		
		break;
	}

	g_exit();

	return res;
}
