
/*============================================================================
 Name        : zkfpi.c
 Author      :
 Date  	     : 2015.11
 Copyright   : ZKSoftware Inc.
 Description : Linux C
 ============================================================================*/
#include "serial.h"
#include "libtype.h"
#include "command_fun.h"
#include "libuserCmd.h"
#include "main.h"
#include "usb.h"
#include "zkfpi.h"

#define TIME_OUT		1000	//Instruction transmission timeout
#define MAX_COUNT		16		//max dev num

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 FAILURE;

	if(usb_find_devices() < 0)
		return FAILURE;

	DevCnt = 0;
	bus = usb_get_busses();
	while(bus)
	{
		dev = bus->devices;
		while(dev)
		{
			if(DevCnt >= MAX_COUNT)
				break;
			if ((dev->descriptor.idVendor  == VID) &&	(dev->descriptor.idProduct == PID))
			{
				devices[DevCnt++] = dev;
			}
			dev = dev->next;
		}
		bus = bus->next;
	}
	return DevCnt;
}

int ZKFPI_Open(int index)
{
	sensor_t s;
	int i = 0;
	int ret = 0;
	usb_dev_handle *device = NULL;
	struct usb_endpoint_descriptor *pEndpoint = NULL;

	memset(&s, 0, sizeof(s));
	if(index >= DevCnt) return FAILURE;
	if(devices[index] == NULL) return FAILURE;

	s.CurDev = index;
	if((device = usb_open(devices[s.CurDev])) != NULL)
	{
		if((ret = usb_set_configuration(device, 1)) < 0)
		{
			usb_close(device);
			return FAILURE;
		}
		if((ret = usb_claim_interface(device, 0)) < 0)
		{
			usb_close(device);
			return FAILURE;
		}
		pEndpoint = devices[s.CurDev] -> config -> interface -> altsetting -> endpoint;
		for(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));
		return SUCCESS;
	}
	return FAILURE;
}

int ZKFPI_Close(void)
{
	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;
	}
	free(s);
	return 0;
}

int ZKFPI_Send(unsigned 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, (char *)buffer, len, TIME_OUT)) < 0)
		{
			return -1;
		}
	}
	return ret;
}

int ZKFPI_Read(unsigned 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;
	if((ret = usb_bulk_read(s->device, s->endpoint, (char*)buffer, len, timeout)) <= 0)
	{
		return -1;
	}
	return ret;
}

usb_dervice_t usb = {
		ZKFPI_Init,
		ZKFPI_Send,
		ZKFPI_Read
};
