package com.gary.msr.hid;

import java.nio.ByteBuffer;
//import java.io.IOException;
//import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashMap;

import com.andorid.MuliModeComdemo.RFID_DEV;
import com.gary.msr.MainActivity;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
//import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;

public class USBOp {
	  public static final String LOGNAME = "ZZYLG";
	  public static final int MAX_GLOBAL_BUFF_LEN= 30*1024;
	  //public static final int USB_TRANS_TIMEOUT=500;
	  public static final int USB_TRANS_TIMEOUT=2000;
	  public static final int USB_TRANS_MAX_LEN=64;
	  public static final int USB_TRANS_MAX_DATA_LEN=USB_TRANS_MAX_LEN-2;
	  //public boolean findDeviceFlag=false;///加个标志来判断是否打开设备
	  private int availableLen;
	  private byte []globalBuf=new byte[MAX_GLOBAL_BUFF_LEN];
	  private byte []sndBuffer=new byte[USB_TRANS_MAX_LEN];
	  private byte []rcvBuffer=new byte[USB_TRANS_MAX_LEN];
	  
	  private Context mContext;
	  private String mString;
	  //private UsbManager mUsbmanager;
	  private PendingIntent mPendingIntent;
	  
	  private UsbEndpoint epOut;
	  private UsbEndpoint epIn;
	  private UsbManager myUsbManager;
	  private UsbDevice myUsbDevice;
	  private UsbInterface myInterface;
	  private UsbDeviceConnection myDeviceConnection;
	  
	  //20201010调试
	  private UsbRequest myRequest;
	  
	  private boolean BroadcastFlag = false;
	  //private boolean UsbOpenflag=false;//是否成功打开设备
	  public boolean UsbOpenflag=false;//是否成功打开设备
	  
	  private int VendorID = 0x096e;    //这里要改成自己的硬件ID
	  private int ProductID = 0x0603;
	  private int mInterfaceClass= 0x03;
	  private int mInterfaceSub= 0x01;
	  private int mInterfaceProtocol= 0x02;
	
	public USBOp(UsbManager manager, Context context, String AppName)
	{
		this.myUsbManager = manager;
	    this.mContext = context;
	    this.mString = AppName;
		
	}
	public void SetUsbConfig(int npid,int nvid,int nInterfaceClass,int nInterfaceSub,int nInterfaceProtocol)
	{
		this.ProductID=npid;
		this.VendorID=nvid;
		this.mInterfaceClass=nInterfaceClass;
		this.mInterfaceSub=nInterfaceSub;
		this.mInterfaceProtocol=nInterfaceProtocol;
		USBOpInit();	
	}
	public boolean USBOpInit()
	{
		UsbOpenflag=false;
		enumerateDevice();
		 
        findInterface();
 
        openDevice();
 
        assignEndpoint();
        return UsbOpenflag;
        
	}
	private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
	{
	    public void onReceive(Context context, Intent intent)
	    {
	      String action = intent.getAction();
	      if ("android.hardware.usb.action.USB_DEVICE_ATTACHED".equals(action)) {
	        return;
	      }
	      if (USBOp.this.mString.equals(action)) {
	        synchronized (this)
	        {
	          UsbDevice localUsbDevice = (UsbDevice)intent.getParcelableExtra("device");
	          if (intent.getBooleanExtra("permission", false))
	          {
	        	  USBOp.this.openDevice();
	          }
	          else
	          {
	            Toast.makeText(USBOp.this.mContext, "Deny USB Permission", 0).show();
	            Log.d("123456789", "permission denied");
	          }
	        }
	      }
	      if ("android.hardware.usb.action.USB_DEVICE_DETACHED".equals(action))
	      {
	        Toast.makeText(USBOp.this.mContext, "Disconnect", 0).show();
	        USBOp.this.CloseDevice();
	      }
	      else
	      {
	        Log.d("123456789", "......");
	      }
	    }
	  };
	  public synchronized void CloseDevice()
	  {
	    try
	    {
	      Thread.sleep(10L);
	    }
	    catch (Exception localException) {}
	    if (this.myDeviceConnection != null)
	    {
	      if (this.myInterface != null)
	      {
	        this.myDeviceConnection.releaseInterface(this.myInterface);
	        this.myInterface = null;
	      }
	      this.myDeviceConnection.close();
	    }
	    if (this.myUsbDevice != null) {
	      this.myUsbDevice = null;
	    }
//	    if (this.myUsbManager != null) {
//	      this.myUsbManager = null;
//	    }
	    if (this.BroadcastFlag)
	    {
	      this.mContext.unregisterReceiver(this.mUsbReceiver);
	      this.BroadcastFlag = false;
	    }
	    UsbOpenflag=false;
	  } 
	
	  private void enumerateDevice(){
		
		if (this.myUsbManager == null)
            return;
 
        HashMap<String, UsbDevice> deviceList = myUsbManager.getDeviceList();
        /*new AlertDialog.Builder(mContext).setTitle("标题" )  

        .setMessage("kaisjinrushebei" )  

        .setPositiveButton("确定" ,  null )  

        .show(); */
        if (!deviceList.isEmpty()) { // deviceList不为空
            //StringBuffer sb = new StringBuffer();
        	//Toast.makeText(MainActivity.this, "Please input card data!", Toast.LENGTH_SHORT).show();
        	
        	
        	for (UsbDevice device : deviceList.values()) {
        		/*new AlertDialog.Builder(mContext).setTitle("标题" )  

                //.setMessage(device.getDeviceName() )
        		.setMessage(String.valueOf(device.getProductId()) )

                .setPositiveButton( "确定" ,  null )  

                .show(); */
                
        
                // 枚举到设备
                if (device.getVendorId() == VendorID
                        && device.getProductId() == ProductID) {
                    this.myUsbDevice = device;
                    Log.e(LOGNAME, "枚举设备成功");
                }
            }
        }
	}
	private void findInterface() {
        if (myUsbDevice != null) {
            for (int i = 0; i < myUsbDevice.getInterfaceCount(); i++) {
                UsbInterface intf = myUsbDevice.getInterface(i);
                // 根据手上的设备做一些判断，其实这些信息都可以在枚举到设备时打印出来
                if (intf.getInterfaceClass() == mInterfaceClass
                        && intf.getInterfaceSubclass() == mInterfaceSub
                        && intf.getInterfaceProtocol() == mInterfaceProtocol) {
                    myInterface = intf;
                    Log.d(LOGNAME, "找到我的设备接口");
                }
                break;
            }
        }
    }
	
	/**
     * 打开设备
     */
    private void openDevice() {
    	////注册广播
    	this.mPendingIntent = PendingIntent.getBroadcast(this.mContext, 0, new Intent(this.mString), 0);
    	IntentFilter filter = new IntentFilter(this.mString);
    	filter.addAction("android.hardware.usb.action.USB_DEVICE_DETACHED");
    	this.mContext.registerReceiver(this.mUsbReceiver, filter);
    	this.BroadcastFlag = true;
    	////////////////////////////////////////////////////////////////////////////////
    	
        if (myInterface != null) {
            UsbDeviceConnection conn = null;
            // 在open前判断是否有连接权限；对于连接权限可以静态分配，也可以动态分配权限，可以查阅相关资料
            if (myUsbManager.hasPermission(myUsbDevice)) {
                conn = myUsbManager.openDevice(myUsbDevice);
            }
            else
            {
            	//PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
            	myUsbManager.requestPermission(myUsbDevice, mPendingIntent);
            	
            }
 
            if (conn == null) {
                return;
            }
 
            if (conn.claimInterface(myInterface, true)) {
                myDeviceConnection = conn; // 到此你的android设备已经连上HID设备
                
                UsbOpenflag=true;
                Log.d(LOGNAME, "打开设备成功");
            } else {
                conn.close();   
            }
        }
    }
    
	////////////////////////////////////////////////////////////////////////
	/**
	* 分配端点，IN | OUT，即输入输出；此处我直接用1为OUT端点，0为IN，当然你也可以通过判断
	*/
	//USB_ENDPOINT_XFER_BULK 
	/* 
	#define USB_ENDPOINT_XFER_CONTROL 0 --控制传输
	#define USB_ENDPOINT_XFER_ISOC 1 --等时传输
	#define USB_ENDPOINT_XFER_BULK 2 --块传输
	#define USB_ENDPOINT_XFER_INT 3 --中断传输 
	* */

	private void assignEndpoint() {
	if (myInterface != null) { //这一句不加的话 很容易报错  导致很多人在各大论坛问:为什么报错呀 
	
	//这里的代码替换了一下 按自己硬件属性判断吧
	
	for (int i = 0; i < myInterface.getEndpointCount(); i++) { 
	
		UsbEndpoint ep = myInterface.getEndpoint(i);
		
		if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) { 
			if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { 
			epOut = ep;
			
			} else { 
			
			epIn = ep;
			
			} 
			}
		}
	}
	
	Log.d(LOGNAME, "assignEndpoint suc");
	}
	
	public boolean UsbFeatureSupported()
	{
		
		//判断手机是否支持HOST
		boolean bool = this.mContext.getPackageManager().hasSystemFeature("android.hardware.usb.host");
		return bool;
	}
	private void initGlobalBuf(int []intArr, int arrLen) {
		availableLen = 0;
		int n;
		for(n=0;n<MAX_GLOBAL_BUFF_LEN;n++)
			globalBuf[n]=0x00;
		for (n = 0; n < arrLen; n++)
			globalBuf[n] = (byte) (intArr[n]);
		availableLen = arrLen;
	}
	
	void ucharp2jintp(int []intArr, byte []ucharp, int arrLen) {
		int n;
		for (n = 0; n < arrLen; n++)
			intArr[n] = (int)(ucharp[n]&0xFF);
	}
	
	/**
	 * 函数功能：读写MSR数据
	 * @param data
	 * @param len
	 * @return
	 */
	public int sendDataMsr(int[] data,int len)
	{
		int iRet = -1;
		int i;
		if(!UsbOpenflag)//如果U口未打开，重新试着去打开
		{
			if(!USBOpInit())
				return -1;
		}
		
		initGlobalBuf(data, len);
		byte header = globalBuf[0];
		byte cmd 	= globalBuf[1];
		int leftLen = availableLen - 2;
		int dataValidLen;
		int startIndex=2;
		while(leftLen>=0)
		{
			Log.d("gary", "leftLen= " + leftLen);
			for(i=0;i<USB_TRANS_MAX_LEN;i++)
				sndBuffer[i]=0x00;
			sndBuffer[0]=header;
			if(leftLen == (availableLen - 2))
				sndBuffer[1]=cmd;
			else
				sndBuffer[1]=(byte)(cmd|(1<<7));
				
			System.arraycopy(globalBuf, startIndex, sndBuffer, 2, USB_TRANS_MAX_DATA_LEN);
			Log.d("gary", "send: " + converB2String(sndBuffer, USB_TRANS_MAX_DATA_LEN));
			iRet=myDeviceConnection.bulkTransfer(epOut, sndBuffer, sndBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet<0)
				return iRet;
			leftLen -= USB_TRANS_MAX_DATA_LEN;
			startIndex+=USB_TRANS_MAX_DATA_LEN;	
		}
		Log.d("gary", "jies leftLen= " + leftLen);
		///接收数据
		for(i=0;i<USB_TRANS_MAX_LEN;i++)
			rcvBuffer[i]=0x00;
		//rcvBuffer
		Arrays.fill(rcvBuffer, (byte)0x00);
		Arrays.fill(globalBuf, (byte)0x00);
		iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
		if(iRet<0)
			return iRet;
		Log.d("gary", "rec: " + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
		//leftLen = rcvBuffer[2] << 8 | rcvBuffer[3];
		leftLen=(rcvBuffer[2]&0xFF)*256;
		leftLen+=(rcvBuffer[3]&0xFF);
		dataValidLen = leftLen + 4;
		leftLen -= USB_TRANS_MAX_DATA_LEN;
		startIndex=0;
		System.arraycopy(rcvBuffer,0,globalBuf, startIndex, USB_TRANS_MAX_LEN);
		startIndex+=USB_TRANS_MAX_LEN;
		while(leftLen > 0)
		{
			
			Arrays.fill(rcvBuffer,(byte)0x00);
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet>=0)
			{
				
				System.arraycopy(rcvBuffer, 2, globalBuf, startIndex, USB_TRANS_MAX_DATA_LEN);
				Log.d("gary", "rec: " + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
				leftLen=leftLen-USB_TRANS_MAX_DATA_LEN;
				startIndex+=USB_TRANS_MAX_DATA_LEN;
			}
			else	//如果读错，直接返回失败
			{
					return iRet;
				
			}
				
			
		}
		//拷贝加返回
		int max = dataValidLen > len ? dataValidLen : len;
		for(i=0;i<max;i++)
			data[i]=0;
		ucharp2jintp(data, globalBuf, dataValidLen);
		return dataValidLen;
	}
	//读RFID的有效数据
	public int readDataSubRfid(byte[]data)
	{
		
		long myStartTime;
		int iRet = -1;
		int i;
		if(!UsbOpenflag)//如果U口未打开，重新试着去打开
		{
			if(!USBOpInit())
				return -1;
		}
		byte []tmpGlobalBuf=new byte[1024];//理论上不会超过两个包
		int leftLen = 0;	///leftLen有效数据
		int dataValidLen;
		int startIndex=2;
		///接收数据
		//rcvBuffer
		
		Arrays.fill(tmpGlobalBuf, (byte)0x00);
		myStartTime=System.currentTimeMillis();
		while(true)
		{
			
			if((System.currentTimeMillis()-myStartTime)/1000>2)
				return -1002;//读数据超时
			Arrays.fill(rcvBuffer, (byte)0x00);
		
		//iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, 64, USB_TRANS_TIMEOUT);
			if(iRet>=0)
				break;
			Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
		}
		leftLen=(rcvBuffer[2]&0xFF)*256;
		leftLen+=(rcvBuffer[3]&0xFF);
		//dataValidLen = leftLen + 4;	///返回的整个包数据长度为 描述长度+ 1BYTE head +1BYTE  0x50+2BYTE长度本身
		dataValidLen = leftLen;
		leftLen -= (USB_TRANS_MAX_DATA_LEN-2);//第一个包的实际数据长度应该减去1BYTE head +1BYTE  0x50+2BYTE长度本身 也就是64-4  20190831
		startIndex=0;
		//System.arraycopy(rcvBuffer,0,tmpGlobalBuf, startIndex, USB_TRANS_MAX_LEN);
		if(dataValidLen>(USB_TRANS_MAX_DATA_LEN-2))
		{
			System.arraycopy(rcvBuffer,4,tmpGlobalBuf, startIndex, USB_TRANS_MAX_DATA_LEN-2);
			startIndex+=USB_TRANS_MAX_DATA_LEN-2;
		}
		else
		{
			System.arraycopy(rcvBuffer,4,tmpGlobalBuf, startIndex, dataValidLen);
			startIndex+=dataValidLen;
		}
		while(leftLen > 0)
		{
			
			Arrays.fill(rcvBuffer,(byte)0x00);
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet>=0)
			{
				Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
				System.arraycopy(rcvBuffer, 2, tmpGlobalBuf, startIndex, USB_TRANS_MAX_DATA_LEN);
				leftLen=leftLen-USB_TRANS_MAX_DATA_LEN;
				startIndex+=USB_TRANS_MAX_DATA_LEN;
			}
			else	//如果读错，直接返回失败
			{
				String s = String.valueOf(iRet);
				Log.d("gary", "iRet:" + s);	
				return iRet;	
			}
				
			
		}
		//拷贝加返回
		//int max = dataValidLen > len ? dataValidLen : len;
		int max=dataValidLen;
		for(i=0;i<max;i++)
			data[i]=0;
		//ucharp2jintp(data, tmpGlobalBuf, dataValidLen);
		System.arraycopy(tmpGlobalBuf, 0, data, 0, dataValidLen);
		return dataValidLen;
	}
	
	/**
	 * 函数功能：读写RFID数据
	 * @param data
	 * @param len
	 * @return
	 */
	public int sendDatarRfid(int[] data,int len)
	{
		int iRet = -1;
		int i;
		long tmpStartTime;
		byte []tmpRecBuf=new byte[1024];
		byte[] GOALBUF=new byte[9];
		int tmpRecBufLen=0;
		GOALBUF[0]=0x00;
		GOALBUF[1]=0x00;
		GOALBUF[2]=(byte)0xFF;
		GOALBUF[3]=0x00;
		GOALBUF[4]=(byte)0xFF;
		GOALBUF[5]=0x00;
		GOALBUF[6]=0x00;
		GOALBUF[7]=0x00;
		GOALBUF[8]=(byte)0xFF;
		if(!UsbOpenflag)//如果U口未打开，重新试着去打开
		{
			if(!USBOpInit())
				return -1;
		}
		//myDeviceConnection.claimInterface(myInterface, BroadcastFlag);
		//myDeviceConnection.releaseInterface(myInterface);
		//myInterface.
		//myDeviceConnection.
		initGlobalBuf(data, len);
		byte header = globalBuf[0];
		byte cmd 	= globalBuf[1];
		int leftLen = availableLen - 2;	///leftLen有效数据
		int dataValidLen;
		int startIndex=2;
		while(leftLen>=0)
		{
			
			for(i=0;i<USB_TRANS_MAX_LEN;i++)
				sndBuffer[i]=0x00;
			sndBuffer[0]=header;
			if(leftLen == (availableLen - 2))///如果是第一个包0x50不变
				sndBuffer[1]=cmd;
			else
				sndBuffer[1]=(byte)(cmd|(1<<7));
				
			System.arraycopy(globalBuf, startIndex, sndBuffer, 2, USB_TRANS_MAX_DATA_LEN);
			Log.d("gary", "send: " + converB2String(sndBuffer, USB_TRANS_MAX_DATA_LEN));
			iRet=myDeviceConnection.bulkTransfer(epOut, sndBuffer, sndBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet<0)
				return iRet;
			leftLen -= USB_TRANS_MAX_DATA_LEN;
			startIndex+=USB_TRANS_MAX_DATA_LEN;	
		}
		///接收数据
		///读ACK
		tmpStartTime=System.currentTimeMillis();
		while(true)
		{
			if((System.currentTimeMillis()-tmpStartTime)/1000>2)
				return -1002;//读数据超时
			
			for(i=0;i<USB_TRANS_MAX_LEN;i++)
				rcvBuffer[i]=0x00;
			//rcvBuffer
			Arrays.fill(tmpRecBuf, (byte)0x00);
			Arrays.fill(rcvBuffer, (byte)0x00);
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet<0)
				return iRet;
			Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
			
			leftLen=(rcvBuffer[2]&0xFF)*256;
			leftLen+=(rcvBuffer[3]&0xFF);
			if(leftLen!=6)//ACK长度固定为6
				continue;
			for(i=0;i<6;i++)
			{
				if(rcvBuffer[4+i]!=GOALBUF[i])
					break;
				
			}
			if(i<6)
				continue;
			
			dataValidLen = leftLen;
			
			if(dataValidLen<=(USB_TRANS_MAX_LEN-4))
			{
				System.arraycopy(rcvBuffer,4,tmpRecBuf, 0, dataValidLen);///这里大于60时可能有问题
				tmpRecBufLen+=dataValidLen;
				break;
			}
			else
			{
				//如果ACK的长度大于了60直接就是错误的包
				return -1;
				
			}
		}
		///读ACK完毕
		///读实际数据
		//rcvBuffer
		//读第一个包
		startIndex=0;
		Arrays.fill(globalBuf, (byte)0x00);
		Arrays.fill(rcvBuffer, (byte)0x00);
		iRet=readDataSubRfid(rcvBuffer);
		//if(iRet<0)
		if(iRet<5)//读到的第一个包长度不能小于5，或者是读失败之后返回的负数
			return iRet;
		for(i=0;i<3;i++)
		{
			if(rcvBuffer[i]!=GOALBUF[6+i])
				break;
			
		}
		if(i<3)
			return -1;
		System.arraycopy(rcvBuffer,0,globalBuf, startIndex, iRet);
		startIndex+=iRet;
		//为了防止直接取值0xFF出现负数,所以借用GOALBUF[2]
		if((rcvBuffer[3]==GOALBUF[2])&&(rcvBuffer[4]==GOALBUF[2]))//当PN模块返回的长度大于256的情况
		{
			leftLen=rcvBuffer[5]*256;
			leftLen+=rcvBuffer[6];
			leftLen+=7+3;
			
		}
		else
			leftLen=rcvBuffer[3]+7;
		leftLen-=iRet;
		while(leftLen > 0)
		{
			Arrays.fill(rcvBuffer, (byte)0x00);
			iRet=readDataSubRfid(rcvBuffer);
			if(iRet<0)
				return iRet;
			System.arraycopy(rcvBuffer,0,globalBuf, startIndex, iRet);
			startIndex+=iRet;
			leftLen-=iRet;	
		}
		//拷贝加返回
		int max = startIndex > len ? startIndex : len;
		System.arraycopy(globalBuf, 0, tmpRecBuf, tmpRecBufLen, startIndex);
		tmpRecBufLen+=startIndex;
		for(i=0;i<max;i++)
			data[i]=0;
		ucharp2jintp(data, tmpRecBuf, tmpRecBufLen);
		return tmpRecBufLen;
		
		
		
		/*
		Arrays.fill(rcvBuffer, (byte)0x00);
		Arrays.fill(globalBuf, (byte)0x00);
		//iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
		iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, 500);
		if(iRet<0)
			return iRet;
		Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
		
		//leftLen=(rcvBuffer[1]&0xFF)*256;
		//leftLen+=(rcvBuffer[2]&0xFF);
		leftLen=(rcvBuffer[2]&0xFF)*256;
		leftLen+=(rcvBuffer[3]&0xFF);
		//dataValidLen = leftLen + 4;	///返回的整个包数据长度为 描述长度+ 1BYTE head +1BYTE  0x50+2BYTE长度本身
		dataValidLen = leftLen;
		leftLen -= (USB_TRANS_MAX_DATA_LEN-2);//第一个包的实际数据长度应该减去1BYTE head +1BYTE  0x50+2BYTE长度本身 也就是64-4  20190831
		startIndex=0;
		//System.arraycopy(rcvBuffer,0,globalBuf, startIndex, USB_TRANS_MAX_LEN);
		if(dataValidLen<=(USB_TRANS_MAX_LEN-4))
		{
			System.arraycopy(rcvBuffer,4,globalBuf, startIndex, dataValidLen);///当描述长度小于60
			startIndex+=dataValidLen;
		}
		else
		{
			System.arraycopy(rcvBuffer,4,globalBuf, startIndex, USB_TRANS_MAX_LEN-4);/////当描述长度大于60
			startIndex+=(USB_TRANS_MAX_LEN-4);		
		}
		//////////////////////////////////////////////////////////////////////////////////////////
		while(leftLen > 0)
		{
			
			Arrays.fill(rcvBuffer,(byte)0x00);
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet>=0)
			{
				Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
				System.arraycopy(rcvBuffer, 2, globalBuf, startIndex, USB_TRANS_MAX_DATA_LEN);
				leftLen=leftLen-USB_TRANS_MAX_DATA_LEN;
				startIndex+=USB_TRANS_MAX_DATA_LEN;
			}
			else	//如果读错，直接返回失败
			{
				String s = String.valueOf(iRet);
				Log.d("gary", "iRet:" + s);	
				return iRet;	
			}
				
			
		}
		//拷贝加返回
		int max = dataValidLen > len ? dataValidLen : len;
		System.arraycopy(globalBuf, 0, tmpRecBuf, tmpRecBufLen, dataValidLen);
		tmpRecBufLen+=dataValidLen;
		for(i=0;i<max;i++)
			data[i]=0;
		ucharp2jintp(data, tmpRecBuf, tmpRecBufLen);
		return tmpRecBufLen;	*/
	}
	
	/**
	 * 函数功能：读写Finger数据
	 * @param data
	 * @param len
	 * @return
	 */
	public int sendDatarFinger(int[] data,int len)
	{
		int iRet = -1;
		int i;
		long tmpStartTime;
		if(!UsbOpenflag)//如果U口未打开，重新试着去打开
		{
			if(!USBOpInit())
				return -1;
		}
		initGlobalBuf(data, len); //finalize

		//myDeviceConnection.releaseInterface(myInterface);//20201009 清缓冲区
		/*int inMax = epIn.getMaxPacketSize();
		ByteBuffer byteBuffer = ByteBuffer.allocate(inMax);
		myRequest.initialize(myDeviceConnection, epIn);
		myRequest.queue(byteBuffer, inMax);
		myRequest.cancel();*/
//		myInterface.
		byte header = globalBuf[0];
		byte cmd 	= globalBuf[1];
		int leftLen = availableLen - 2;
		int dataValidLen;
		int startIndex=2;
		while(leftLen>=0)
		{
			for(i=0;i<USB_TRANS_MAX_LEN;i++)
				sndBuffer[i]=0x00;
			sndBuffer[0]=header;
			if(leftLen == (availableLen - 2))
				sndBuffer[1]=cmd;
			else
				sndBuffer[1]=(byte)(cmd|(1<<7));
				
			System.arraycopy(globalBuf, startIndex, sndBuffer, 2, USB_TRANS_MAX_DATA_LEN);
			Log.d("gary", "send: " + converB2String(sndBuffer, USB_TRANS_MAX_DATA_LEN));
			iRet=myDeviceConnection.bulkTransfer(epOut, sndBuffer, sndBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet<0)
				return iRet;
			leftLen -= USB_TRANS_MAX_DATA_LEN;
			startIndex+=USB_TRANS_MAX_DATA_LEN;	
		}
		///接收数据
		for(i=0;i<USB_TRANS_MAX_LEN;i++)
			rcvBuffer[i]=0x00;
		//rcvBuffer
		/*
		Arrays.fill(rcvBuffer, (byte)0x00);
		Arrays.fill(globalBuf, (byte)0x00);
		
		iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
		if(iRet<0)
			return iRet;
		Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));*/
		//为了兼容第一次发指令时会有滴的一声，导致数据传输慢，在读第一个包处加了循环
		tmpStartTime=System.currentTimeMillis();
		while(true)
		{
			if((System.currentTimeMillis()-tmpStartTime)/1000>2)
				return -1002;//读数据超时
			Arrays.fill(rcvBuffer, (byte)0x00);
			Arrays.fill(globalBuf, (byte)0x00);
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			if((iRet>=0)&&(rcvBuffer[1]==0x20))//只有当读成功，并且08后面跟的数据是0x20时才跳出， 20目前发现只用于指纹和RFID
				break;
		
		
		}
		//leftLen = rcvBuffer[1] << 8 | rcvBuffer[2];
		leftLen=(rcvBuffer[2]&0xFF)*256;
		leftLen+=(rcvBuffer[3]&0xFF);
		dataValidLen = leftLen + 4;
		//dataValidLen = leftLen;//改成不用填入08 20 和2个字节长度
		leftLen -= USB_TRANS_MAX_DATA_LEN;
		startIndex=0;
		System.arraycopy(rcvBuffer,0,globalBuf, startIndex, USB_TRANS_MAX_LEN);
		startIndex+=USB_TRANS_MAX_LEN;
		while(leftLen > 0)
		{
			
			Arrays.fill(rcvBuffer,(byte)0x00);
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet>=0)
			{
				Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
				System.arraycopy(rcvBuffer, 2, globalBuf, startIndex, USB_TRANS_MAX_DATA_LEN);
				leftLen=leftLen-USB_TRANS_MAX_DATA_LEN;
				startIndex+=USB_TRANS_MAX_DATA_LEN;
			}
			else	//如果读错，直接返回失败
			{
				String s = String.valueOf(iRet);
				Log.d("gary", "iRet:" + s);	
				return iRet;	
			}
				
			
		}
		//拷贝加返回
		int max = dataValidLen > len ? dataValidLen : len;
		for(i=0;i<max;i++)
			data[i]=0;
		ucharp2jintp(data, globalBuf, dataValidLen);
		return dataValidLen;	
	}
	/**
	 * 函数功能：读写Finger图片数据
	 * @param data
	 * @param len
	 * @return
	 */
	public int sendDatarFingerImage(int[] data,int len)
	{
		int iRet = -1;
		int i;
		if(!UsbOpenflag)//如果U口未打开，重新试着去打开
		{
			if(!USBOpInit())
				return -1;
		}
		initGlobalBuf(data, len);
		byte header = globalBuf[0];
		byte cmd 	= globalBuf[1];
		int leftLen = availableLen - 2;
		//int dataValidLen;
		int startIndex=2;
		int tmpbufLen=0;
		int tmpbufLen1=0;
		byte[] tmpbuf=new byte [(64*280)*2+1];//数据包大小*2
		byte[] tmpbuf1=new byte [(64*280)*2*2];//数据包大小*2
		int AReadLen=0;
		int myFlag=0;
		while(leftLen>=0)
		{
			for(i=0;i<USB_TRANS_MAX_LEN;i++)
				sndBuffer[i]=0x00;
			sndBuffer[0]=header;
			if(leftLen == (availableLen - 2))
				sndBuffer[1]=cmd;
			else
				sndBuffer[1]=(byte)(cmd|(1<<7));
				
			System.arraycopy(globalBuf, startIndex, sndBuffer, 2, USB_TRANS_MAX_DATA_LEN);
			Log.d("gary", "send: " + converB2String(sndBuffer, USB_TRANS_MAX_DATA_LEN));
			iRet=myDeviceConnection.bulkTransfer(epOut, sndBuffer, sndBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet<0)
				return iRet;
			leftLen -= USB_TRANS_MAX_DATA_LEN;
			startIndex+=USB_TRANS_MAX_DATA_LEN;	
		}
		///接收数据
		for(i=0;i<USB_TRANS_MAX_LEN;i++)
			rcvBuffer[i]=0x00;
		//rcvBuffer
		Arrays.fill(rcvBuffer, (byte)0x00);
		Arrays.fill(globalBuf, (byte)0x00);
		///图片固定去取251个包
		//for(i=0;i<251;i++)
		for(i=0;i<500;i++)//由原来的固定读251个包，改为判断是否为最后一个08大包
		{
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet<0)
				return iRet;
			else
			{
				
				if(i>=1)//跳过第一个数据包,从第二个包开始为图像数据
        		{
					AReadLen=(rcvBuffer[2]&0xFF)*256;
					AReadLen=AReadLen+(rcvBuffer[3]&0xFF);
					//if((i-1)%5==0)
					if((AReadLen==60)&&(rcvBuffer[4]==-17)&&(rcvBuffer[5]==0x01)&&(rcvBuffer[6]==-1)&&(rcvBuffer[7]==-1)&&(rcvBuffer[10]==0x02))
	        		{
	        			System.arraycopy(rcvBuffer, 13, tmpbuf, tmpbufLen, 51);
	        			tmpbufLen+=51;
	        			myFlag=0;//zzy
	        		}
					//else if((AReadLen==60)&&(rcvBuffer[4]==(byte)0xef)&&(rcvBuffer[1]==0x01)&&(rcvBuffer[2]==(byte)0xff)&&(rcvBuffer[3]==(byte)0xff)&&(rcvBuffer[6]==0x08))
					//else if((AReadLen==60)&&(rcvBuffer[4]==-17)&&(rcvBuffer[1]==0x01)&&(rcvBuffer[2]==-1)&&(rcvBuffer[3]==-1)&&(rcvBuffer[6]==0x08))
					else if((AReadLen==60)&&(rcvBuffer[4]==-17)&&(rcvBuffer[5]==0x01)&&(rcvBuffer[6]==-1)&&(rcvBuffer[7]==-1)&&(rcvBuffer[10]==0x08))
	        		{
	        			System.arraycopy(rcvBuffer, 13, tmpbuf, tmpbufLen, 51);
	        			tmpbufLen+=51;
	        			myFlag=1;//zzy
	        		}
					else if(AReadLen==60)
					{
						System.arraycopy(rcvBuffer, 4, tmpbuf, tmpbufLen, 60);
	        			tmpbufLen+=60;
	        			
					}
	        		/*else if((i-1)%5==4)
	        		{
	        			System.arraycopy(rcvBuffer, 4, tmpbuf, tmpbufLen, 25);
	        			tmpbufLen+=25;
	        			
	        		}*/
	        		else
	        		{
	        			AReadLen=AReadLen-2;//取掉最后的验证数据
	        			System.arraycopy(rcvBuffer, 4, tmpbuf, tmpbufLen, AReadLen);
	        			tmpbufLen+=AReadLen;
	        			if(myFlag!=0)//当最后一个大包的最后一个小包接收完成跳出
	                        break;
	        			
	        		}
        		}
			}
			
		}
		//if(tmpbufLen==12800)
		if((tmpbufLen==18432)||(tmpbufLen==12800))//新指纹模块修改 //兼容新老模块两种图片尺寸
		{
			
			tmpbufLen1=img_One2Two(tmpbuf,tmpbuf1,tmpbufLen);	
			ucharp2jintp(data, tmpbuf1, tmpbufLen1);
			return tmpbufLen1;
			
		}
		else
			return -1;	
	}
	
	///////////////////////////////////////////////////////////////////////////////////////
	/**
	 * 函数功能：读写RFID数据
	 * @param data
	 * @param len
	 * @return
	 */
	public int sendDatarRD07Rfid(int[] data,int len)
	{
		int iRet = -1;
		int i;
		long tmpStartTime;
		byte []tmpRecBuf=new byte[1024];
		byte[] GOALBUF=new byte[9];
		int tmpRecBufLen=0;
		if(!UsbOpenflag)//如果U口未打开，重新试着去打开
		{
			if(!USBOpInit())
				return -1;
		}
		//myDeviceConnection.claimInterface(myInterface, BroadcastFlag);
		//myDeviceConnection.releaseInterface(myInterface);
		//myInterface.
		//myDeviceConnection.
		initGlobalBuf(data, len);
		byte header = globalBuf[0];
		byte cmd 	= globalBuf[1];
		int leftLen = availableLen - 2;	///leftLen有效数据
		int dataValidLen;
		int startIndex=2;
		while(leftLen>=0)
		{
			
			for(i=0;i<USB_TRANS_MAX_LEN;i++)
				sndBuffer[i]=0x00;
			sndBuffer[0]=header;
			if(leftLen == (availableLen - 2))///如果是第一个包0x50不变
			{
				sndBuffer[1]=cmd;
				sndBuffer[2]=(byte)((availableLen-2)/256);
				sndBuffer[3]=(byte)((availableLen-2)%256);
				System.arraycopy(globalBuf, startIndex, sndBuffer, 4, USB_TRANS_MAX_DATA_LEN-2);
			}
			else
			{
				sndBuffer[1]=(byte)(cmd|(1<<7));	
				System.arraycopy(globalBuf, startIndex, sndBuffer, 2, USB_TRANS_MAX_DATA_LEN);
			}
			System.out.println("send:"+converB2String(sndBuffer, USB_TRANS_MAX_DATA_LEN));
			Log.d("gary", "send: " + converB2String(sndBuffer, USB_TRANS_MAX_DATA_LEN));
			iRet=myDeviceConnection.bulkTransfer(epOut, sndBuffer, sndBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet<0)
				return iRet;
			leftLen -= USB_TRANS_MAX_DATA_LEN;
			startIndex+=USB_TRANS_MAX_DATA_LEN;	
		}
		return 0;
	}
	
	/**
	 * 
	 * @param data
	 * @param length
	 * @return
	 */
	//读RFID的有效数据
	//public int readDataRD07Rfid(byte[]data)
	public int readDataRD07Rfid(int[]data)
	{
		
		long myStartTime;
		int iRet = -1;
		int i;
		if(!UsbOpenflag)//如果U口未打开，重新试着去打开
		{
			if(!USBOpInit())
				return -1;
		}
		byte []tmpGlobalBuf=new byte[1024];//理论上不会超过两个包
		int leftLen = 0;	///leftLen有效数据
		int dataValidLen;
		int startIndex=2;
		///接收数据
		//rcvBuffer
		System.out.println("rec:"+converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
		Arrays.fill(tmpGlobalBuf, (byte)0x00);
		myStartTime=System.currentTimeMillis();
		while(true)
		{
			
			if((System.currentTimeMillis()-myStartTime)/1000>2)
				return -1002;//读数据超时
			Arrays.fill(rcvBuffer, (byte)0x00);
		
		//iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, 64, USB_TRANS_TIMEOUT);
			if(iRet>=0)
				break;
			Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
			//System.out.println("rec:"+converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
		}
		leftLen=(rcvBuffer[2]&0xFF)*256;
		leftLen+=(rcvBuffer[3]&0xFF);
		//dataValidLen = leftLen + 4;	///返回的整个包数据长度为 描述长度+ 1BYTE head +1BYTE  0x50+2BYTE长度本身
		dataValidLen = leftLen;
		leftLen -= (USB_TRANS_MAX_DATA_LEN-2);//第一个包的实际数据长度应该减去1BYTE head +1BYTE  0x50+2BYTE长度本身 也就是64-4  20190831
		startIndex=0;
		//System.arraycopy(rcvBuffer,0,tmpGlobalBuf, startIndex, USB_TRANS_MAX_LEN);
		if(dataValidLen>(USB_TRANS_MAX_DATA_LEN-2))
		{
			System.arraycopy(rcvBuffer,4,tmpGlobalBuf, startIndex, USB_TRANS_MAX_DATA_LEN-2);
			startIndex+=USB_TRANS_MAX_DATA_LEN-2;
		}
		else
		{
			System.arraycopy(rcvBuffer,4,tmpGlobalBuf, startIndex, dataValidLen);
			startIndex+=dataValidLen;
		}
		while(leftLen > 0)
		{
			
			Arrays.fill(rcvBuffer,(byte)0x00);
			iRet=myDeviceConnection.bulkTransfer(epIn, rcvBuffer, rcvBuffer.length, USB_TRANS_TIMEOUT);
			if(iRet>=0)
			{
				Log.d("gary", "rec:" + converB2String(rcvBuffer, USB_TRANS_MAX_DATA_LEN));
				System.arraycopy(rcvBuffer, 2, tmpGlobalBuf, startIndex, USB_TRANS_MAX_DATA_LEN);
				leftLen=leftLen-USB_TRANS_MAX_DATA_LEN;
				startIndex+=USB_TRANS_MAX_DATA_LEN;
			}
			else	//如果读错，直接返回失败
			{
				String s = String.valueOf(iRet);
				Log.d("gary", "iRet:" + s);	
				return iRet;	
			}
				
			
		}
		//拷贝加返回
		//int max = dataValidLen > len ? dataValidLen : len;
		int max=dataValidLen;
		for(i=0;i<max;i++)
			data[i]=0;
		ucharp2jintp(data, tmpGlobalBuf, dataValidLen);
		//System.arraycopy(tmpGlobalBuf, 0, data, 0, dataValidLen);
		return dataValidLen;
	}
	
	
	///////////////////////////////////////////////////////////////////////////////////////
	public static String converB2String(byte data[], int length) {
		if (length < 1)
			return "";
		int tmpi;
		StringBuilder sb = new StringBuilder();
		for (int n = 0; n < length; n++) {
			tmpi=data[n];
			String hex = Integer.toHexString(tmpi & 0xFF);
			if (hex.length() == 1)
				hex = '0' + hex;

			// sb.append(hex.toUpperCase() + " ");
			sb.append(hex.toUpperCase() + "");
			if (n > 0 && (n + 1) % 16 == 0) {
				sb.append("\n");
			}
		}
		return sb.toString();
	}
	
	public static String convert2String(int data[], int length) {
		if (length < 1)
			return "";
		StringBuilder sb = new StringBuilder();
		for (int n = 0; n < length; n++) {
			String hex = Integer.toHexString(data[n] & 0xFF);
			if (hex.length() == 1)
				hex = '0' + hex;

			// sb.append(hex.toUpperCase() + " ");
			sb.append(hex.toUpperCase() + "");
			if (n > 0 && (n + 1) % 16 == 0) {
				sb.append("\n");
			}
		}
		return sb.toString();
	}

	public static int[] convertStringToIntArr(String hexString) {
		int len = 0, strLen = 0;
		strLen = hexString.length();
		len = (strLen % 2 == 0) ? (strLen / 2) : (strLen / 2 + 1);
		int data[] = new int[len];
		String tmpStr = hexString;
		if (strLen % 2 == 1)
			tmpStr += "0";
		for (int i = 0; i < len; i++) {
			String s = tmpStr.substring(2 * i, 2 * i + 2);
			try {
				data[i] = Integer.parseInt(s, 16);
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		}
		return data;

	}
	
	public static int img_One2Two(byte[] psFrom,byte[] psTo, int psFromLen)
	  {
		  int i=0;
		  byte tmpCh=0x0F;
		  for(i=0;i<psFromLen;i++)
		  {
			  
			  psTo[i*2]=(byte)((psFrom[i]&tmpCh)<<4);
			  psTo[i*2+1]=(byte)((psFrom[i])&0xF0);
			    
		  }
		  return i*2;
		  
	  }

}
