#include "stdafx.h"
#include <stdio.h>
#include "usb.h"
#include "zkfpi.h"

#undef  TRACE
#define TRACE			/ ## /

#define TIME_OUT		1000	//指令传输超时时间
#define MAX_COUNT		16		//最大设备数

static struct usb_device *devices[MAX_COUNT];
static unsigned char DevCnt = 0;
static int gVID, gPID;

typedef struct sensor___{
	unsigned char CurDev;
	unsigned char endpoint;
	unsigned char outEndpoint;
	bool gCapturing;
	usb_dev_handle *device;
}sensor_t;

int ZKFPI_Init(unsigned short VID, unsigned short PID)
{
	struct usb_bus *bus;
	struct usb_device *dev;
	
	usb_init();

	if(usb_find_busses() < 0)
		return 0;

	if(usb_find_devices() < 0)
		return 0;

	DevCnt = 0;
	
	for (bus = usb_get_busses(); bus; bus = bus -> next)
	{
		for (dev = bus -> devices; dev; dev = dev -> next)
		{
			if(DevCnt >= MAX_COUNT)
				break;

			if (dev -> descriptor.idVendor  == VID &&
			 	dev -> descriptor.idProduct == PID)
			{
				devices[DevCnt++] = dev;
			}
		}
	}

	TRACE("Debug: ZKFPI_Init OK ! Found %d devices !\n", DevCnt);
	return DevCnt;
}

int ZKFPI_Open(int index, void **sensor)
{
	sensor_t s;
	int ret = -ENODEV;
	struct usb_endpoint_descriptor *pEndpoint = NULL;

	memset(&s, 0, sizeof(s));
	if(index>=DevCnt) return ret;

	if(devices[index] == NULL)
		return ret;
	usb_dev_handle *device=NULL;
	s.CurDev=index;

	if((device = usb_open(devices[s.CurDev])) != NULL)
	{
		if((ret = usb_set_configuration(device, 1)) < 0)
		{
			usb_close(device);
			return ret;
		}
		if((ret = usb_claim_interface(device, 0)) < 0)
		{
			usb_close(device);
			return ret;
		}
		pEndpoint = devices[s.CurDev] -> config -> interface -> altsetting -> endpoint;
		for(int i = 0; i< devices[s.CurDev] -> config -> interface -> altsetting -> bNumEndpoints; i++)
		{
			if(pEndpoint->bmAttributes == USB_ENDPOINT_TYPE_BULK)
			{
				if(1 == (pEndpoint->bEndpointAddress >> 7))
				{
					s.endpoint = pEndpoint->bEndpointAddress;
				}
				else
				{
					s.outEndpoint = pEndpoint->bEndpointAddress;
				}
			}
			pEndpoint++;
		}
		s.device=device;
		*sensor=malloc(sizeof(sensor_t));
		memcpy(*sensor, &s, sizeof(s));

		TRACE("Debug: ZKFPI_Open OK !\n");
		return 0;
	}
	
	TRACE("Debug: ZKFPI_Open Fail !\n");
	return ret;
}

int ZKFPI_Close(void *sensor)
{
	sensor_t *s=(sensor_t*)sensor;
	if(s==NULL) return -1;

	if(s->device != NULL)
	{
		if(0==usb_release_interface(s->device, 0)){
			usb_close(s->device);
		}
		s->device = NULL;

		TRACE("Debug: ZKFPI_Close OK !\n");
	}
	free(s);
	return 0;
}

int ZKFPI_Send(void *sensor, char *buffer, int len)
{
	int ret = 0;
	sensor_t *s=(sensor_t*)sensor;
	if(s == NULL) return -1;
	if(s->device == NULL) return -1;
	

	if(s->device != NULL)
	{
		if((ret = usb_control_msg(s->device, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, 0xFA, 0, 0, buffer, len, TIME_OUT)) < 0)
		{
			TRACE("Debug: ZKFPI_SetGPIO Fail !\n");
			return -1;
		}
		else
		{
			TRACE("Debug: ZKFPI_SetGPIO OK !\n");
		}
	}
	return ret;
}

int ZKFPI_Read(void *sensor, char *buffer, int len, int timeout)
{
	int ret = 0;
	sensor_t *s=(sensor_t*)sensor;
	if(s == NULL) return -1;
	if(s->device == NULL) return -1;
	//unsigned char endp = devices[0]->config->interface ->altsetting ->endpoint->bEndpointAddress;

	if((ret = usb_bulk_read(s->device, s->endpoint, (char*)buffer, len, timeout)) <= 0)
	{
		return -1;
	}

	return ret;
}

int ZKFPI_Write( void *sensor, char *buffer, int len, int timeout )
{
	int ret = 0;
	sensor_t *s=(sensor_t*)sensor;
	if(s == NULL) return -1;
	if(s->device == NULL) return -1;
	//unsigned char endp = devices[0]->config->interface ->altsetting ->endpoint->bEndpointAddress;
	if((ret = usb_bulk_write(s->device, s->outEndpoint, (char*)buffer, len, timeout)) <= 0)
	{
		char *str = usb_strerror();
		return -1;
	}
	return ret;
}