1/*
2 * U2EC usbsock source
3 *
4 * Copyright (C) 2008 ASUSTek Corporation
5 *
6 * $Id: usbsock.c,v 1.4 2008/12/18 10:04:01 jiahao Exp $
7 */
8
9#include <stdio.h>
10#include <unistd.h>
11#include <errno.h>
12#include <string.h>
13#include <signal.h>
14#include <pthread.h>
15#include <netinet/in.h>
16#include <netinet/tcp.h>
17#include <arpa/inet.h>
18#include <net/if.h>
19#include <sys/socket.h>
20#include <sys/time.h>
21#include <sys/stat.h>
22#include <fcntl.h>
23#include <asm/param.h>
24#include <asm/byteorder.h>
25
26#ifdef	SUPPORT_LPRng
27#include <semaphore_mfp.h>
28#endif
29#if __BYTE_ORDER == __LITTLE_ENDIAN
30#include <bcmnvram.h>
31#endif
32
33#include "typeconvert.h"
34#include "usbsock.h"
35#include "wdm-MJMN.h"
36#include "usbdi.h"
37#include "usb.h"
38#include "urb64.h"
39
40void decode(char *file);
41int testusb();
42void inline ppktbuf(char *buf, int size);
43void inline print_irp(PIRP_SAVE pirp_save, int flag);
44void hotplug_print(const char *format);
45
46#if defined(U2EC_DEBUG) && defined(U2EC_ONPC)
47FILE	*fp;	// Log file pointer for debug
48#endif
49
50int 	count_bulk_write = 0;
51int 	count_bulk_read  = 0;
52int	count_bulk_read_ret0_1  = 0;
53int	count_bulk_read_ret0_2  = 0;
54int 	count_bulk_read_epson = 0;
55int 	flag_monitor_epson = 0;
56
57char EPSON_BR_STR1_09[]={0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x80, 0x00, 0x10};
58char EPSON_BR_STR2_19[]={0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x89, 0x00, 0x40, 0x45, 0x50, 0x53, 0x4f, 0x4e, 0x2d, 0x44, 0x41, 0x54, 0x41};
59char EPSON_BR_STR3_19[]={0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x89, 0x00, 0x02, 0x45, 0x50, 0x53, 0x4f, 0x4e, 0x2d, 0x43, 0x54, 0x52, 0x4c};
60
61#define USBLP_REQ_GET_STATUS	0x01	/* from src/linux/linux/driver/usb/printer.c */
62#define LP_POUTPA       	0x20  	/* from src/linux/linux/include/linux/lp.h, unchanged input, active high */
63#define LP_PSELECD      	0x10	/* from src/linux/linux/include/linux/lp.h, unchanged input, active high */
64#define LP_PERRORP      	0x08	/* from src/linux/linux/include/linux/lp.h, unchanged input, active low */
65
66//static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
67static char *usblp_messages_canon[] = { "ok", "op call", "ink low?" };
68
69int	count_err=0;
70int	timeout_control_msg, timeout_bulk_read_msg, timeout_bulk_write_msg;
71char	data_buf[MAX_BUF_LEN];
72char	data_bufrw[MAX_BUF_LEN];
73
74char	data_canon[MAX_BUF_LEN];
75int 	flag_canon_state = 0;
76int 	flag_canon_ok = 0;
77int	data_canon_done = 0;
78int 	flag_canon_monitor = 0;
79
80extern char str_product[128];
81extern int Is_HP_LaserJet;
82extern int Is_HP_OfficeJet;
83extern int Is_HP_LaserJet_MFP;
84extern int Is_Canon;
85extern int Is_EPSON;
86extern int Is_HP;
87extern int Is_Lexmark;
88extern int Is_General;
89extern int USB_Ver_N20;
90extern struct usb_bus	    *bus;
91extern struct usb_device    *dev;
92usb_dev_handle		    *udev;
93struct timeval		    tv_ref, tv_now;
94PCONNECTION_INFO	    last_busy_conn;
95
96U2EC_LIST_HEAD(conn_info_list);
97struct in_addr ip_monopoly;
98time_t time_monopoly;
99time_t time_monopoly_old;
100time_t time_add_device;
101time_t time_remove_device;
102
103char	fd_in_use[32768];
104
105/*
106 * Handle urbs in irp_saverw.Buffer.
107 */
108int handleURB(PIRP_SAVE pirp_saverw, struct u2ec_list_head *curt_pos)
109{
110	PURB		purb;
111	unsigned char*	pbuf;
112	USHORT		UrbLength;
113	int		size, i, j;
114	int		ret = 0;
115	int		length = 0;
116	int		tmpL = 0;
117	int		tmpReq = 0;
118	int		tmpReqType = 0;
119
120	u_int32_t tmp_config;
121	u_int32_t tmp_int;
122	u_int32_t tmp_alt;
123	u_int32_t tmp_ep;
124	u_int32_t tmp_intclass;
125
126	int timeout_bulk_read_msg_tmp;
127	int timeout_bulk_write_msg_tmp;
128//	unsigned char status;
129	int	err_canon;
130
131	purb = (PURB)pirp_saverw->Buffer;
132	UrbLength = purb->UrbHeader.Length;
133
134	if (Is_HP && purb->UrbHeader.Function != URB_FUNCTION_CLASS_INTERFACE)
135		((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
136	else if (	Is_Canon &&
137			purb->UrbHeader.Function != URB_FUNCTION_CLASS_INTERFACE &&
138			purb->UrbHeader.Function != URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
139	)
140		((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
141
142	// action differs to functions
143	switch (purb->UrbHeader.Function){
144	case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
145		size = pirp_saverw->BufferSize - (u_int32_t)UrbLength;
146		pbuf = pirp_saverw->Buffer + UrbLength;
147
148		pirp_saverw->Status = 0;
149		pirp_saverw->Information = 0; 
150		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
151		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
152		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
153		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
154
155		purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
156		purb->UrbHeader.UsbdFlags = 0x00000022;	
157		purb->UrbHeader.Function = 0x08;
158		purb->UrbHeader.Status = 0;
159		purb->UrbControlTransfer.PipeHandle = (void*)0x80000000+0x1000*(0+1)+0x100*(0+1)+0x10*(0+1)+0x1*1;
160		purb->UrbControlTransfer.TransferFlags = 0xb;
161		purb->UrbControlTransfer.hca.HcdEndpoint = (void*)0xffffffff;
162		purb->UrbControlTransfer.hca.HcdIrp = (void*)0xdeadf00d;
163		purb->UrbControlTransfer.SetupPacket[0] = (USB_TYPE_STANDARD | USB_DIR_IN | USB_RECIP_INTERFACE);
164		purb->UrbControlTransfer.SetupPacket[1] = USB_REQ_GET_DESCRIPTOR;
165		purb->UrbControlTransfer.SetupPacket[6] = (unsigned char )(purb->UrbControlDescriptorRequest.TransferBufferLength&0x00ff);
166		purb->UrbControlTransfer.SetupPacket[7] = (unsigned char )((purb->UrbControlDescriptorRequest.TransferBufferLength&0xff00)>>8);
167		purb->UrbControlDescriptorRequest.TransferBuffer = pbuf;
168//		purb->UrbControlDescriptorRequest.Reserved1 = 0x0680;
169//		purb->UrbControlDescriptorRequest.Reserved2 = size; // transferBufferLength;
170
171		if (dev) {
172			ret = 0;
173			udev = usb_open(dev);
174			if (udev) {
175				ret = usb_control_msg(udev,	(USB_TYPE_STANDARD | USB_DIR_IN | USB_RECIP_INTERFACE),
176								USB_REQ_GET_DESCRIPTOR,
177								(USB_DT_REPORT << 8),
178								purb->UrbControlGetInterfaceRequest.Interface-1,
179								(char*)pbuf,
180								purb->UrbControlDescriptorRequest.TransferBufferLength,
181								timeout_control_msg);
182				usb_close(udev);
183			}
184		}
185		else
186			break;
187
188		if (ret >= 0) {
189			purb->UrbControlDescriptorRequest.TransferBufferLength = ret;
190			pirp_saverw->BufferSize = purb->UrbControlDescriptorRequest.TransferBufferLength + purb->UrbHeader.Length;
191		}
192		break; // URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
193
194	case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:    //  0x000B , get Device OR Configuration descriptors
195		size = pirp_saverw->BufferSize - (u_int32_t)UrbLength; 
196		pbuf = pirp_saverw->Buffer + UrbLength;
197
198		pirp_saverw->Status = 0;
199		pirp_saverw->Information = 0; 
200		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
201		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
202		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
203		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
204
205		purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
206		purb->UrbHeader.UsbdFlags = 0x00000022;
207		purb->UrbHeader.Function = 0x08;
208		purb->UrbHeader.Status = 0;
209		purb->UrbControlTransfer.PipeHandle = (void*)0x80000000+0x1000*(0+1)+0x100*(0+1)+0x10*(0+1)+0x1*1;
210		purb->UrbControlTransfer.hca.HcdEndpoint = (void*)0xffffffff;
211		purb->UrbControlTransfer.hca.HcdIrp = (void*)0xdeadf00d;
212		purb->UrbControlDescriptorRequest.Reserved1 = 0x0680;
213		purb->UrbControlDescriptorRequest.Reserved2 = size;
214		purb->UrbControlDescriptorRequest.TransferBuffer = pbuf;
215
216		if (purb->UrbControlDescriptorRequest.DescriptorType == 1) {		// device descriptor
217			bzero(pbuf, size);
218			if (dev) {
219				udev = usb_open(dev);
220				if (udev) {
221					ret = usb_get_descriptor(udev, USB_DT_DEVICE, purb->UrbControlDescriptorRequest.Index,
222								pbuf, purb->UrbControlDescriptorRequest.TransferBufferLength);
223					usb_close(udev);
224				}
225			}
226			else
227				break;
228
229			if (ret > 0)
230				purb->UrbControlDescriptorRequest.TransferBufferLength = ret;
231			else
232				purb->UrbControlDescriptorRequest.TransferBufferLength = 0;
233
234			pirp_saverw->BufferSize = purb->UrbControlDescriptorRequest.TransferBufferLength + purb->UrbHeader.Length;
235		}
236		else if (purb->UrbControlDescriptorRequest.DescriptorType == 2) {	// configuration descriptor
237			purb->UrbControlTransfer.TransferFlags = 0xb;
238			bzero(pbuf, size);
239			if (dev) {
240				udev = usb_open(dev);
241				if (udev) {
242					ret = usb_get_descriptor(udev, USB_DT_CONFIG, purb->UrbControlDescriptorRequest.Index,
243								pbuf, purb->UrbControlDescriptorRequest.TransferBufferLength);
244					usb_close(udev);
245				}
246			}
247			else
248				break;
249
250			if (ret > 0)
251				purb->UrbControlDescriptorRequest.TransferBufferLength = ret;
252			else
253				purb->UrbControlDescriptorRequest.TransferBufferLength = 0;
254
255			pirp_saverw->BufferSize = purb->UrbControlDescriptorRequest.TransferBufferLength + purb->UrbHeader.Length;
256		}
257		else if (purb->UrbControlDescriptorRequest.DescriptorType == 3){		// string descriptor
258//			purb->UrbControlTransfer.TransferFlags = 0x0b;
259			ret = 0;
260			if (dev) {
261				udev = usb_open(dev);
262				if (udev) {
263					ret = usb_get_string(udev, purb->UrbControlDescriptorRequest.Index,
264								   purb->UrbControlDescriptorRequest.LanguageId, (char*)pbuf,
265								   purb->UrbControlDescriptorRequest.TransferBufferLength);
266					usb_close(udev);
267				}
268			}
269			else
270				break;
271
272			if (ret > 0)
273				purb->UrbControlDescriptorRequest.TransferBufferLength = ret;
274			else
275				purb->UrbControlDescriptorRequest.TransferBufferLength = 0;
276
277			pirp_saverw->BufferSize = purb->UrbControlDescriptorRequest.TransferBufferLength + purb->UrbHeader.Length;
278		}
279		else 
280			PDEBUG("handleURB: descriptor type =  0x%x , not supported\n", purb->UrbControlDescriptorRequest.DescriptorType);
281		break; // URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
282
283	case URB_FUNCTION_SELECT_CONFIGURATION:     //  0x0000
284		// we must set configurationHandle & interfaceHandle & pipeHandle
285		pirp_saverw->BufferSize = purb->UrbHeader.Length;
286		pirp_saverw->Status = 0;
287		pirp_saverw->Information = 0; 
288		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
289		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
290		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
291		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
292
293		if (dev) {
294			if (purb->UrbSelectConfiguration.ConfigurationDescriptor == 0x0)
295				break;
296			else {
297				purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
298
299				tmp_config = *(pirp_saverw->Buffer + UrbLength + 5) - 1;
300				// *(pirp_saverw->Buffer + UrbLength + 5) is bConfigurationVaule field of Configuration Descriptor
301				purb->UrbSelectConfiguration.ConfigurationHandle = (void*)0x80000000+0x1000*(tmp_config+1);
302
303				char *tmp = (char*)&(purb->UrbSelectConfiguration.Interface);
304				int tmp_len = purb->UrbHeader.Length - 24;
305				
306				for (i = 0; tmp_len > 0; i++) {
307					int tmp_int = (*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceNumber;
308					int tmp_alt = (*(USBD_INTERFACE_INFORMATION*)tmp).AlternateSetting;
309
310//					(*(USBD_INTERFACE_INFORMATION*)tmp).Length = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bLength;
311//					(*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceNumber = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceNumber;
312//					(*(USBD_INTERFACE_INFORMATION*)tmp).AlternateSetting = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bAlternateSetting;
313					(*(USBD_INTERFACE_INFORMATION*)tmp).Class = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceClass;
314					(*(USBD_INTERFACE_INFORMATION*)tmp).SubClass = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceSubClass;
315					(*(USBD_INTERFACE_INFORMATION*)tmp).Protocol = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceProtocol;
316//					(*(USBD_INTERFACE_INFORMATION*)tmp).Reserved = 0x00;
317					(*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle = (void*)0x80000000+0x1000*(tmp_config+1)+0x100*(tmp_int+1)+0x10*(tmp_alt+1);
318//					(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bNumEndpoints;
319					for (j = 0; j < (*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes; j++) {
320						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].wMaxPacketSize;
321						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].EndpointAddress = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bEndpointAddress;
322						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].Interval = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bInterval;
323						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeType = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bmAttributes & USB_ENDPOINT_TYPE_MASK;
324						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle = (void*)0x80000000+0x1000*(tmp_config+1)+0x100*(tmp_int+1)+0x10*(tmp_alt+1)+0x1*(j+2);
325						if ((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize > MAX_BUFFER_SIZE)
326							(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize = MAX_BUFFER_SIZE;
327						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags = 0;
328					}
329					tmp_len -= (*(USBD_INTERFACE_INFORMATION*)tmp).Length;
330					tmp += (*(USBD_INTERFACE_INFORMATION*)tmp).Length;
331				}
332			}
333		}
334		break; // URB_FUNCTION_SELECT_CONFIGURATION  
335
336	case 0x2a: // _URB_OS_FEATURE_DESCRIPTOR_REQUEST_FULL, added in U2EC, it's the same size as _URB_CONTROL_DESCRIPTOR_REQUEST, 
337		// so we can handle it as URB_CONTROL_DESCRIPTOR_REQUEST
338		pirp_saverw->BufferSize = purb->UrbHeader.Length;
339		pirp_saverw->Status = 0xc0000010;
340		pirp_saverw->Information = 0; 
341		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
342		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
343		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
344		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
345
346		purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
347		purb->UrbHeader.Status = 0x80000300;
348		purb->UrbControlDescriptorRequest.TransferBufferLength = 0;
349		// it's MS_FeatureDescriptorIndex in _URB_OS_FEATURE_DESCRIPTOR_REQUEST_FULL
350//		purb->UrbControlDescriptorRequest.LanguageId = 0x0004;
351		break; // 0x2a
352
353	case URB_FUNCTION_SELECT_INTERFACE:     // 0x0001
354		pirp_saverw->BufferSize = purb->UrbHeader.Length;
355		pirp_saverw->Status = 0;
356		pirp_saverw->Information = 0; 
357		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
358		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
359		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
360		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
361
362		if (dev) {
363			purb->UrbHeader.Status = 0;
364			purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
365			purb->UrbHeader.UsbdFlags = 0;
366
367			tmp_config = (((u_int32_t)purb->UrbSelectInterface.ConfigurationHandle)<<16)>>28;
368			tmp_config--;
369			char *tmp = (char*)&(purb->UrbSelectInterface.Interface);
370			int tmp_int = (*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceNumber;
371			int tmp_alt = (*(USBD_INTERFACE_INFORMATION*)tmp).AlternateSetting;
372
373//			purb->UrbSelectInterface.ConfigurationHandle = 0x80000000+0x1000*(tmp_config+1);
374
375//			(*(USBD_INTERFACE_INFORMATION*)tmp).Length = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bLength;
376//			(*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceNumber = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceNumber;
377//			(*(USBD_INTERFACE_INFORMATION*)tmp).AlternateSetting = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bAlternateSetting;
378			(*(USBD_INTERFACE_INFORMATION*)tmp).Class = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceClass;
379			(*(USBD_INTERFACE_INFORMATION*)tmp).SubClass = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceSubClass;
380			(*(USBD_INTERFACE_INFORMATION*)tmp).Protocol = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceProtocol;
381			(*(USBD_INTERFACE_INFORMATION*)tmp).Reserved = 0x00;
382			(*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle = (void*)0x80000000+0x1000*(tmp_config+1)+0x100*(tmp_int+1)+0x10*(tmp_alt+1);
383			(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bNumEndpoints;
384
385			for (j = 0; j < (*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes; j++) {
386				(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].wMaxPacketSize;
387				(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].EndpointAddress = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bEndpointAddress;
388				(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].Interval = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bInterval;
389				(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeType = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bmAttributes & USB_ENDPOINT_TYPE_MASK;
390				(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle = (void*)0x80000000+0x1000*(tmp_config+1)+0x100*(tmp_int+1)+0x10*(tmp_alt+1)+0x1*(j+2);
391				if ((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize > MAX_BUFFER_SIZE)
392					(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize = MAX_BUFFER_SIZE;
393				(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags = 0;
394			}
395		}
396		break; // URB_FUNCTION_SELECT_INTERFACE                0x0001
397
398	case URB_FUNCTION_CLASS_OTHER:      //        0x001F
399		length = tmpL = tmpReq = tmpReqType = 0;
400
401		if (dev) {
402			udev = usb_open(dev);
403			if (udev) {
404				tmpL = purb->UrbControlVendorClassRequest.TransferBufferLength;
405				tmpReq = purb->UrbControlVendorClassRequest.Request;
406				if (USBD_TRANSFER_DIRECTION_OUT == USBD_TRANSFER_DIRECTION(purb->UrbBulkOrInterruptTransfer.TransferFlags)) {
407					tmpReqType = (USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_OTHER);
408					pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
409					memset(pbuf, 0x0, purb->UrbControlVendorClassRequest.TransferBufferLength);
410					ret = usb_control_msg(udev, (USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_OTHER),
411							purb->UrbControlVendorClassRequest.Request,
412							purb->UrbControlVendorClassRequest.Value,
413							purb->UrbControlVendorClassRequest.Index, (char*)pbuf,
414							purb->UrbControlVendorClassRequest.TransferBufferLength,
415							timeout_control_msg);
416//					PDEBUG("usb_control_msg(), direction: out, return: %d\n", ret);
417				} else {
418					tmpReqType = (USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_OTHER);
419					pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
420					memset(pbuf, 0x0, purb->UrbControlVendorClassRequest.TransferBufferLength);
421					ret = usb_control_msg(udev, (USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_OTHER),
422							purb->UrbControlVendorClassRequest.Request,
423							purb->UrbControlVendorClassRequest.Value,
424							purb->UrbControlVendorClassRequest.Index, (char*)pbuf,
425							purb->UrbControlVendorClassRequest.TransferBufferLength,
426							timeout_control_msg);
427//					PDEBUG("usb_control_msg(), direction: in, return: %d\n", ret);
428				}
429				usb_close(udev);
430				if (ret < 0)
431					break;
432				else length = ret;
433			}
434			else
435				break;
436		}
437		else
438			break;
439
440		pbuf = pirp_saverw->Buffer + UrbLength;
441		pirp_saverw->Status = 0;
442		pirp_saverw->Information = 0; 
443		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
444		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
445		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
446		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
447
448		purb->UrbHeader.Function = 0x08;
449		purb->UrbHeader.Status = 0;
450		purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
451		purb->UrbHeader.UsbdFlags = 0x22;
452		
453		purb->UrbControlTransfer.PipeHandle = (void*)0x80000000+0x1000*(0+1)+0x100*(0+1)+0x10*(0+1)+0x1*1;
454		purb->UrbControlTransfer.TransferFlags = 0x0a;
455		purb->UrbControlTransfer.TransferBufferLength = length;
456		purb->UrbControlTransfer.UrbLink = 0;
457		purb->UrbControlTransfer.SetupPacket[0] = tmpReqType;
458		purb->UrbControlTransfer.SetupPacket[1] = tmpReq;
459		purb->UrbControlTransfer.SetupPacket[6] = (unsigned char )(tmpL&0x00ff);
460		purb->UrbControlTransfer.SetupPacket[7] = (unsigned char )((tmpL&0xff00)>>8);
461		pirp_saverw->BufferSize = purb->UrbControlTransfer.TransferBufferLength + purb->UrbHeader.Length;
462		break; // URB_FUNCTION_CLASS_OTHER
463
464	case URB_FUNCTION_CLASS_INTERFACE:
465		length = tmpL = tmpReq = tmpReqType = 0;
466		ret = -1;
467
468		if (dev) {
469			udev = usb_open(dev);
470			if (udev) {
471				tmpL = purb->UrbControlVendorClassRequest.TransferBufferLength;
472				tmpReq = purb->UrbControlVendorClassRequest.Request;
473				if (USBD_TRANSFER_DIRECTION_OUT == USBD_TRANSFER_DIRECTION(purb->UrbBulkOrInterruptTransfer.TransferFlags)) {
474
475					PDEBUG("OUT ");
476					PDEBUG("req: %x ", purb->UrbControlVendorClassRequest.Request);
477					PDEBUG("value: %x ", purb->UrbControlVendorClassRequest.Value);
478					PDEBUG("index: %x ", purb->UrbControlVendorClassRequest.Index);
479					PDEBUG("len: %x\n", purb->UrbControlVendorClassRequest.TransferBufferLength);
480
481					if (Is_Canon && flag_canon_state != 0)
482					{
483						if (	purb->UrbControlVendorClassRequest.Request == 0x2 &&
484							purb->UrbControlVendorClassRequest.Value == 0x0 &&
485							purb->UrbControlVendorClassRequest.Index == 0x100
486						)
487						{
488							PDEBUG("user cancel printing...\n");
489							flag_canon_state = 0;
490							flag_canon_ok = 0;
491						}
492					}
493
494					tmpReqType = (USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE);
495					pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
496					memset(pbuf, 0x0, purb->UrbControlVendorClassRequest.TransferBufferLength);
497					ret = usb_control_msg(udev, tmpReqType, purb->UrbControlVendorClassRequest.Request,
498							purb->UrbControlVendorClassRequest.Value,
499							purb->UrbControlVendorClassRequest.Index, (char*)pbuf,
500							purb->UrbControlVendorClassRequest.TransferBufferLength,
501							timeout_control_msg);
502//					PDEBUG("usb_control_msg() out return: %d\n", ret);
503					((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
504				} else {
505
506					PDEBUG("IN ");
507					PDEBUG("req: %x ", purb->UrbControlVendorClassRequest.Request);
508					PDEBUG("value: %x ", purb->UrbControlVendorClassRequest.Value);
509					PDEBUG("index: %x ", purb->UrbControlVendorClassRequest.Index);
510					PDEBUG("len: %x\n", purb->UrbControlVendorClassRequest.TransferBufferLength);
511
512					pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
513					memset(pbuf, 0x0, purb->UrbControlVendorClassRequest.TransferBufferLength);
514					tmpReqType = (USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE);
515					ret = usb_control_msg(udev, tmpReqType, purb->UrbControlVendorClassRequest.Request,
516							purb->UrbControlVendorClassRequest.Value,
517							purb->UrbControlVendorClassRequest.Index, (char*)pbuf,
518							purb->UrbControlVendorClassRequest.TransferBufferLength,
519							timeout_control_msg);
520
521					if (	Is_Canon &&
522						purb->UrbControlVendorClassRequest.Request == 0x0 &&
523						purb->UrbControlVendorClassRequest.Value == 0x0 &&
524						purb->UrbControlVendorClassRequest.Index == 0x100
525					)
526						flag_canon_monitor = 1;
527					else if (Is_Canon)
528					{
529						flag_canon_monitor = 0;
530						((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
531					}
532					else if (Is_HP && ((PCONNECTION_INFO)curt_pos)->count_class_int_in < 3)	// HP Deskjet 3920 
533						((PCONNECTION_INFO)curt_pos)->count_class_int_in++;
534
535/*
536					if (	Is_Canon &&
537						purb->UrbControlVendorClassRequest.Request == USBLP_REQ_GET_STATUS &&
538						purb->UrbControlVendorClassRequest.Value == 0x0 &&
539						purb->UrbControlVendorClassRequest.TransferBufferLength == 0x1
540					)
541					{
542						status = *pbuf;
543						err_canon = 0;
544						if (~status & LP_PERRORP)
545							err_canon = 3;
546						if (status & LP_POUTPA)
547							err_canon = 1;
548						if (~status & LP_PSELECD)
549							err_canon = 2;
550
551						PDEBUG("state: %d err: %d\n", flag_canon_state, err_canon);
552
553						if (flag_canon_state == 1 && err_canon != 0)
554							flag_canon_state = 2;		// "out of paper"
555						else if (flag_canon_state == 1 && flag_canon_ok++ > 4 && err_canon == 0)
556							flag_canon_state = 3;		// warm-up
557						else if (flag_canon_state == 2 && err_canon == 0)
558						{					// "out of paper" => "ok"
559							flag_canon_state = 3;
560							flag_canon_ok = 0;
561						}
562						else if (flag_canon_state == 3 && err_canon == 0)
563							flag_canon_ok++;	
564
565						PDEBUG("status: %s, ok:%d\n", usblp_messages[err_canon], flag_canon_ok);
566					}
567*/
568
569//					PDEBUG("usb_control_msg() in return: %d\n", ret);
570				}
571				usb_close(udev);
572				if (ret < 0)
573					break;	
574				else length = ret;
575			}
576			else
577				break;
578		}
579		else
580			break;
581
582		pbuf = pirp_saverw->Buffer + UrbLength;
583		pirp_saverw->Status = 0;
584		pirp_saverw->Information = 0; 
585		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
586		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
587		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
588		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
589
590		purb->UrbHeader.Function = 0x08;
591		purb->UrbHeader.Status = 0;
592		purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
593		purb->UrbHeader.UsbdFlags = 0x22;
594		
595		purb->UrbControlTransfer.PipeHandle = (void*)0x80000000+0x1000*(0+1)+0x100*(0+1)+0x10*(0+1)+0x1*1;
596		purb->UrbControlTransfer.TransferFlags = 0x0b;
597		purb->UrbControlTransfer.TransferBufferLength = length;
598		purb->UrbControlTransfer.UrbLink = 0;
599		purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint = (void*)0xffffffff;
600		purb->UrbBulkOrInterruptTransfer.hca.HcdIrp = (void*)0xdeadf00d;
601		purb->UrbControlTransfer.SetupPacket[0] = tmpReqType;
602		purb->UrbControlTransfer.SetupPacket[1] = tmpReq;
603		purb->UrbControlTransfer.SetupPacket[6] = (unsigned char )(tmpL&0x00ff);
604		purb->UrbControlTransfer.SetupPacket[7] = (unsigned char )((tmpL&0xff00)>>8);
605		pirp_saverw->BufferSize = purb->UrbControlTransfer.TransferBufferLength + purb->UrbHeader.Length;
606		break; // URB_FUNCTION_CLASS_INTERFACE
607
608	case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:    //    0x0009
609		pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
610
611		pirp_saverw->Status = 0;
612		pirp_saverw->Information = 0; 
613		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
614		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
615		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
616		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
617
618		purb->UrbHeader.Status = 0;
619		purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
620		purb->UrbHeader.UsbdFlags = 0x22;
621		purb->UrbBulkOrInterruptTransfer.UrbLink = 0;
622		purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint = (void*)0xffffffff;
623		purb->UrbBulkOrInterruptTransfer.hca.HcdIrp = (void*)0xdeadf00d;
624		purb->UrbControlDescriptorRequest.TransferBuffer = pbuf;
625
626//		PDEBUG("PipeHandle: 0x%x\n", purb->UrbBulkOrInterruptTransfer.PipeHandle);
627		tmp_config = (((u_int32_t)purb->UrbBulkOrInterruptTransfer.PipeHandle)<<16)>>28;
628		tmp_int = (((u_int32_t)purb->UrbBulkOrInterruptTransfer.PipeHandle)<<20)>>28;
629		tmp_alt = (((u_int32_t)purb->UrbBulkOrInterruptTransfer.PipeHandle)<<24)>>28;
630		tmp_ep = (((u_int32_t)purb->UrbBulkOrInterruptTransfer.PipeHandle)<<28)>>28;
631		tmp_config--;
632		tmp_int--;
633		tmp_alt--;
634		tmp_ep -= 2;
635//		PDEBUG("config, int, alt, ep: %x %x %x %x\n", tmp_config, tmp_int, tmp_alt, tmp_ep);
636
637		if (dev) {
638			tmp_intclass = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceClass;
639			if (tmp_intclass == 8) {
640				timeout_bulk_read_msg_tmp = 1000;
641				timeout_bulk_write_msg_tmp = 1000;
642			} else if (Is_EPSON && tmp_intclass != 7)
643			{
644				timeout_bulk_read_msg_tmp = timeout_bulk_read_msg;
645				timeout_bulk_write_msg_tmp = 30000;
646			}
647			else
648			{
649				timeout_bulk_read_msg_tmp = timeout_bulk_read_msg;
650				timeout_bulk_write_msg_tmp = timeout_bulk_write_msg;
651			}
652
653			if (Is_Canon && tmp_intclass != 7)
654			{
655				flag_canon_state = 0;
656				flag_canon_ok = 0;
657			}
658
659			udev = usb_open(dev);
660			if (udev) {	
661				if ((USB_ENDPOINT_TYPE_MASK & dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bmAttributes) == USB_ENDPOINT_TYPE_BULK) {
662					if ((USB_ENDPOINT_DIR_MASK & dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress) == USB_ENDPOINT_OUT) {
663						purb->UrbBulkOrInterruptTransfer.TransferFlags = 2;
664						gettimeofday(&tv_ref, NULL);
665						alarm(0);
666						if (purb->UrbBulkOrInterruptTransfer.TransferBufferLength > MAX_BUFFER_SIZE)
667							purb->UrbBulkOrInterruptTransfer.TransferBufferLength = MAX_BUFFER_SIZE;
668						if (Is_Canon && tmp_intclass == 7)
669						{
670							if (flag_canon_state == 3)
671							{
672								PDEBUG("remain: %d\n", purb->UrbBulkOrInterruptTransfer.TransferBufferLength - data_canon_done);
673								ret = usb_bulk_write(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)(pbuf + data_canon_done), purb->UrbBulkOrInterruptTransfer.TransferBufferLength - data_canon_done, 30000);
674								if (ret > 0)
675								{
676									ret += data_canon_done;
677									data_canon_done = 0;
678								}
679								else
680									flag_canon_ok = 0;
681							}
682							else
683							{
684								data_canon_done = 0;
685								ret = usb_bulk_write_sp(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, 5000, &data_canon_done,USB_Ver_N20?128:512);
686								if (ret < 0 && data_canon_done > 0)
687									PDEBUG("done: %d\n", data_canon_done);
688							}
689						}
690						else if (Is_HP && (Is_HP_LaserJet || Is_HP_LaserJet_MFP) && tmp_intclass == 7)
691							ret = usb_bulk_write(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, 500);
692						else
693							ret = usb_bulk_write(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, timeout_bulk_write_msg_tmp);
694						alarm(1);
695						gettimeofday(&tv_now, NULL);
696
697						if (Is_EPSON)
698						{
699							if (ret == 0 && purb->UrbBulkOrInterruptTransfer.TransferBufferLength == 2)
700							{
701								PDEBUG("retry...");
702								ret = usb_bulk_write(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, timeout_bulk_write_msg_tmp);
703							}
704							else if (ret >= 4096)
705							{
706								count_bulk_read_epson = 0;
707								flag_monitor_epson = 0;
708							}
709						}
710
711						PDEBUG("usb_bulk_write() return: %d\n", ret);
712
713						count_bulk_write ++;
714						count_bulk_read_ret0_1 = 0;
715
716						if (ret < 0) {
717							if ((tv_now.tv_usec - tv_ref.tv_usec) >= 0)
718								PDEBUG("sec: %ld, msec: %ld\n", tv_now.tv_sec-tv_ref.tv_sec, (tv_now.tv_usec-tv_ref.tv_usec)/1000);
719							else
720								PDEBUG("sec: %ld, msec: %ld\n", tv_now.tv_sec-tv_ref.tv_sec-1, (1000000+tv_now.tv_usec-tv_ref.tv_usec)/1000);
721
722							if (Is_Canon && tmp_intclass == 7)
723							{
724								if (flag_canon_state == 0 && ret == -ETIMEDOUT)
725								{
726									PDEBUG("copy data_buf !!!\n");
727
728									flag_canon_state = 1;
729									flag_canon_ok = 0;
730									memcpy(data_canon, data_buf, MAX_BUF_LEN);
731
732									usb_close(udev);
733									pirp_saverw->BufferSize = purb->UrbHeader.Length;
734									pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
735									return 0;
736								}
737								else if (flag_canon_state != 1)
738								{
739									PDEBUG("skip...\n");
740	
741									usb_close(udev);
742									pirp_saverw->BufferSize = purb->UrbHeader.Length;
743									pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
744									return 0;
745								}
746							}
747						}
748						else if (Is_Canon && tmp_intclass == 7)	// ret >= 0
749						{
750							flag_canon_state = 0;
751							flag_canon_ok = 0;
752							((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
753						}
754					} else {
755						purb->UrbBulkOrInterruptTransfer.TransferFlags=3;
756						gettimeofday(&tv_ref, NULL);
757						alarm(0);
758						if (purb->UrbBulkOrInterruptTransfer.TransferBufferLength > MAX_BUFFER_SIZE)
759							purb->UrbBulkOrInterruptTransfer.TransferBufferLength = MAX_BUFFER_SIZE;
760						if (Is_HP && Is_HP_LaserJet_MFP && tmp_intclass == 7)
761							ret = usb_bulk_read(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, 500);
762						else
763							ret = usb_bulk_read(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, timeout_bulk_read_msg_tmp);
764						alarm(1);
765						gettimeofday(&tv_now, NULL);						
766
767						if (	Is_Canon && tmp_intclass == 7 &&
768							ret > 64 && ret < 256 &&
769							memcmp(pbuf+2, "BST:", 4) == 0
770						)
771						{
772							if (flag_canon_monitor == 1 && ((PCONNECTION_INFO)curt_pos)->count_class_int_in < 3)
773							{
774								flag_canon_monitor = 0;
775								((PCONNECTION_INFO)curt_pos)->count_class_int_in++;
776
777								PDEBUG("mon: [%d] ", ((PCONNECTION_INFO)curt_pos)->count_class_int_in);
778							}
779
780							if (*(pbuf+7) == '0')			// ok
781								err_canon = 0;
782							else if (*(pbuf+7) == '8')		// operation call
783								err_canon = 1;
784							else					// unknown error
785								err_canon = 2;
786
787//							if (flag_canon_state == 1 && err_canon != 0)
788							if (flag_canon_state == 1 && err_canon == 1)
789							{					// "out of paper"
790								flag_canon_state = 2;
791								flag_canon_ok = 0;
792							}
793//							else if (flag_canon_state == 1 && err_canon == 0 && ++flag_canon_ok > 5)
794							else if (flag_canon_state == 1 && err_canon != 1 && ++flag_canon_ok > 5)
795								flag_canon_state = 3;		// warm-up
796//							else if (flag_canon_state == 2 && err_canon == 0)
797							else if (flag_canon_state == 2 && err_canon != 1)
798							{					// "out of paper" => "ok"
799								flag_canon_state = 3;
800								flag_canon_ok = 0;
801							}
802//							else if (flag_canon_state == 3 && err_canon == 0)
803							else if (flag_canon_state == 3 && err_canon != 1)
804								flag_canon_ok++;	
805
806							PDEBUG("status:[%s] state:[%d] ok:[%d] ", usblp_messages_canon[err_canon], flag_canon_state, flag_canon_ok);
807						}
808						else
809						{
810							flag_canon_monitor = 0;
811							((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
812						}
813
814						PDEBUG("usb_bulk_read() return: %d\n", ret);
815
816						if (Is_HP) {  	// HP, if this connection only includes HP ToolBox
817							if (ret == 0) {
818								count_bulk_read_ret0_1 ++;
819								if (count_bulk_read_ret0_1 >= 30) {
820									count_bulk_write = 0;
821									count_bulk_read  = 0;
822									count_bulk_read_ret0_1 = 0;
823									count_bulk_read_ret0_2 = 0;
824								}
825								if (Is_HP_LaserJet) {						// laserjet 33xx series
826									if (count_bulk_write == 1 && count_bulk_read == 1)
827										count_bulk_read_ret0_2 ++;
828								}
829								else if (Is_HP_OfficeJet) {					// officejet 56xx series
830									if (count_bulk_write == 2 && count_bulk_read == 2)
831										count_bulk_read_ret0_2 ++;
832								}
833							}
834							else if(ret > 0){
835								count_bulk_read ++;
836								count_bulk_read_ret0_1 = 0;
837							}
838						}
839						else if (Is_EPSON) {
840							if (ret == 9 && count_bulk_read_epson == 0 && memcmp(EPSON_BR_STR1_09, pbuf, 9) == 0)
841								count_bulk_read_epson = 1;
842							else if(ret == 19) {
843								if (count_bulk_read_epson == 1 && memcmp(EPSON_BR_STR2_19, pbuf, 19) == 0)
844									count_bulk_read_epson = 2;
845								else if (count_bulk_read_epson == 2 && memcmp(EPSON_BR_STR3_19, pbuf, 19) == 0)
846									count_bulk_read_epson = 3;
847							}
848						}
849
850						if (ret < 0) {
851							count_bulk_read_epson = -1;
852							flag_monitor_epson = 0;
853
854							if ((tv_now.tv_usec - tv_ref.tv_usec) >= 0)
855								PDEBUG("sec: %ld, msec: %ld\n", tv_now.tv_sec-tv_ref.tv_sec, (tv_now.tv_usec-tv_ref.tv_usec)/1000);
856							else
857								PDEBUG("sec: %ld, msec: %ld\n", tv_now.tv_sec-tv_ref.tv_sec-1, (1000000+tv_now.tv_usec-tv_ref.tv_usec)/1000);
858						}
859
860/*							if (purb->UrbBulkOrInterruptTransfer.TransferBufferLength != 0 && ret == 0)
861								pirp_saverw->Status = 0xC0000004;	// STATUS_INFO_LENGTH_MISMATCH
862							else if (ret < 0)
863								pirp_saverw->Status = 0xC00000AE;	// STATUS_PIPE_BUSY
864*/
865					}
866				} else {
867					usb_close(udev);
868					pirp_saverw->BufferSize = purb->UrbHeader.Length;
869					pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
870					return 0;
871				}
872
873				if (ret < 0) {
874					ret = 0;
875					count_err++;
876				}
877				else
878					count_err = 0;
879
880				if (count_err > 255)
881					pirp_saverw->Status = 0xC00000AD;	// STATUS_INVALID_PIPE_STATE
882
883				usb_close(udev);
884			}
885			else
886				ret = 0;
887		}
888		else
889			ret = 0;
890
891		purb->UrbBulkOrInterruptTransfer.TransferBufferLength = ret;
892
893		if ((USB_ENDPOINT_DIR_MASK & dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress) == USB_ENDPOINT_OUT)
894			pirp_saverw->BufferSize = purb->UrbHeader.Length;
895		else
896			pirp_saverw->BufferSize = purb->UrbHeader.Length + purb->UrbBulkOrInterruptTransfer.TransferBufferLength;
897		break;   // URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER      0x0009
898
899	case URB_FUNCTION_ABORT_PIPE:
900		PDEBUG("\n\t URB_FUNCTION_ABORT_PIPE");
901
902		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
903		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
904		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
905		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
906
907		purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;   // according to packet
908		purb->UrbHeader.UsbdFlags = 0x10;
909
910//		PDEBUG("\n\t PipeHandle: 0x%x", purb->UrbPipeRequest.PipeHandle);
911		tmp_config = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<16)>>28;
912		tmp_int = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<20)>>28;
913		tmp_alt = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<24)>>28;
914		tmp_ep = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<28)>>28;
915		tmp_config--;
916		tmp_int--;
917		tmp_alt--;
918		tmp_ep -= 2;
919//		PDEBUG("\n\t config, int, alt, ep: %x %x %x %x", tmp_config, tmp_int, tmp_alt, tmp_ep);
920
921		if (dev) {
922			udev = usb_open(dev);
923			if (udev) {
924				usb_clear_halt(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress);
925				usb_close(udev);
926			}
927		}
928		break;
929
930	case URB_FUNCTION_RESET_PIPE:
931		PDEBUG("\n\t URB_FUNCTION_RESET_PIPE");
932
933		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
934		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
935		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
936		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
937
938		purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;   // according to packet
939		purb->UrbHeader.UsbdFlags = 0x10;
940
941//		PDEBUG("\n\t PipeHandle: 0x%x", purb->UrbPipeRequest.PipeHandle);
942		tmp_config = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<16)>>28;
943		tmp_int = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<20)>>28;
944		tmp_alt = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<24)>>28;
945		tmp_ep = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<28)>>28;
946		tmp_config--;
947		tmp_int--;
948		tmp_alt--;
949		tmp_ep -= 2;
950//		PDEBUG("\n\t config, int, alt, ep: %x %x %x %x", tmp_config, tmp_int, tmp_alt, tmp_ep);
951
952		if (dev) {
953			udev = usb_open(dev);
954			if (udev) {
955				usb_resetep(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress);
956				usb_close(udev);
957			}
958		}
959		break;
960
961	default:
962		PDEBUG("\n !!! Unsupported URB_FUNCTION: 0x%x\n\n", purb->UrbHeader.Function);
963		break;
964	} // end of switch urb function
965
966	pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize ;
967	return 1;
968
969} // end of handleURB32
970
971/*
972 * Handle urbs in irp_saverw.Buffer.
973 */
974int handleURB_64(PIRP_SAVE pirp_saverw, struct u2ec_list_head *curt_pos)
975{
976	PURB_64		purb;
977	unsigned char*	pbuf;
978	USHORT		UrbLength;
979	int		size, i, j;
980	int		ret = 0;
981	int		length = 0;
982	int		tmpL = 0;
983	int		tmpReq = 0;
984	int		tmpReqType = 0;
985
986	u_int64_t tmp_config;
987	u_int64_t tmp_int;
988	u_int64_t tmp_alt;
989	u_int64_t tmp_ep;
990	u_int64_t tmp_intclass;
991
992	int timeout_bulk_read_msg_tmp;
993	int timeout_bulk_write_msg_tmp;
994//	unsigned char status;
995	int	err_canon;
996
997	purb = (PURB_64)pirp_saverw->Buffer;
998	UrbLength = purb->UrbHeader.Length;
999
1000	PDEBUG("\n into handleURB_64\n");
1001
1002	if (Is_HP && purb->UrbHeader.Function != URB_FUNCTION_CLASS_INTERFACE)
1003		((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
1004	else if (	Is_Canon &&
1005			purb->UrbHeader.Function != URB_FUNCTION_CLASS_INTERFACE &&
1006			purb->UrbHeader.Function != URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
1007	)
1008		((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
1009
1010	// action differs to functions
1011	switch (purb->UrbHeader.Function){
1012	case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
1013		size = pirp_saverw->BufferSize - (u_int32_t)UrbLength;
1014		pbuf = pirp_saverw->Buffer + UrbLength;
1015
1016		pirp_saverw->Status = 0;
1017		pirp_saverw->Information = 0; 
1018		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1019		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1020		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1021		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1022
1023		purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1024		purb->UrbHeader.UsbdFlags = 0x00000022;	
1025		purb->UrbHeader.Function = 0x08;
1026		purb->UrbHeader.Status = 0;
1027		purb->UrbControlTransfer.PipeHandle = (u_int64_t)0x80000000+0x1000*(0+1)+0x100*(0+1)+0x10*(0+1)+0x1*1;
1028		purb->UrbControlTransfer.TransferFlags = 0xb;
1029//		purb->UrbControlTransfer.hca.HcdEndpoint = (u_int64_t)0xffffffff;
1030//		purb->UrbControlTransfer.hca.HcdIrp = (u_int64_t)0xdeadf00d;
1031		purb->UrbControlTransfer.SetupPacket[0] = (USB_TYPE_STANDARD | USB_DIR_IN | USB_RECIP_INTERFACE);
1032		purb->UrbControlTransfer.SetupPacket[1] = USB_REQ_GET_DESCRIPTOR;
1033		purb->UrbControlTransfer.SetupPacket[6] = (unsigned char )(purb->UrbControlDescriptorRequest.TransferBufferLength&0x00ff);
1034		purb->UrbControlTransfer.SetupPacket[7] = (unsigned char )((purb->UrbControlDescriptorRequest.TransferBufferLength&0xff00)>>8);
1035		purb->UrbControlDescriptorRequest.TransferBuffer = (u_int64_t)(u_int32_t)pbuf;
1036//		purb->UrbControlDescriptorRequest.Reserved1 = 0x0680;
1037//		purb->UrbControlDescriptorRequest.Reserved2 = size; // transferBufferLength;
1038
1039		if (dev) {
1040			ret = 0;
1041			udev = usb_open(dev);
1042			if (udev) {
1043				ret = usb_control_msg(udev,	(USB_TYPE_STANDARD | USB_DIR_IN | USB_RECIP_INTERFACE),
1044								USB_REQ_GET_DESCRIPTOR,
1045								(USB_DT_REPORT << 8),
1046								purb->UrbControlGetInterfaceRequest.Interface-1,
1047								(char*)pbuf,
1048								purb->UrbControlDescriptorRequest.TransferBufferLength,
1049								timeout_control_msg);
1050				usb_close(udev);
1051			}
1052		}
1053		else
1054			break;
1055
1056		if (ret >= 0) {
1057			purb->UrbControlDescriptorRequest.TransferBufferLength = ret;
1058			pirp_saverw->BufferSize = purb->UrbControlDescriptorRequest.TransferBufferLength + purb->UrbHeader.Length;
1059		}
1060		break; // URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
1061
1062	case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:    //  0x000B , get Device OR Configuration descriptors
1063		size = pirp_saverw->BufferSize - (u_int32_t)UrbLength; 
1064		pbuf = pirp_saverw->Buffer + UrbLength;
1065
1066		pirp_saverw->Status = 0;
1067		pirp_saverw->Information = 0; 
1068		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1069		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1070		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1071		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1072
1073		purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1074		purb->UrbHeader.UsbdFlags = 0x00000022;
1075		purb->UrbHeader.Function = 0x08;
1076		purb->UrbHeader.Status = 0;
1077		purb->UrbControlTransfer.PipeHandle = (u_int64_t)0x80000000+0x1000*(0+1)+0x100*(0+1)+0x10*(0+1)+0x1*1;
1078//		purb->UrbControlTransfer.hca.HcdEndpoint = (u_int64_t)0xffffffff;
1079//		purb->UrbControlTransfer.hca.HcdIrp = (u_int64_t)0xdeadf00d;
1080		purb->UrbControlDescriptorRequest.Reserved1 = 0x0680;
1081		purb->UrbControlDescriptorRequest.Reserved2 = size;
1082		purb->UrbControlDescriptorRequest.TransferBuffer = (u_int64_t)(u_int32_t)pbuf;
1083
1084		if (purb->UrbControlDescriptorRequest.DescriptorType == 1) {		// device descriptor
1085			bzero(pbuf, size);
1086			if (dev) {
1087				udev = usb_open(dev);
1088				if (udev) {
1089					ret = usb_get_descriptor(udev, USB_DT_DEVICE, purb->UrbControlDescriptorRequest.Index,
1090								pbuf, purb->UrbControlDescriptorRequest.TransferBufferLength);
1091					usb_close(udev);
1092				}
1093			}
1094			else
1095				break;
1096
1097			if (ret > 0)
1098				purb->UrbControlDescriptorRequest.TransferBufferLength = ret;
1099			else
1100				purb->UrbControlDescriptorRequest.TransferBufferLength = 0;
1101
1102			pirp_saverw->BufferSize = purb->UrbControlDescriptorRequest.TransferBufferLength + purb->UrbHeader.Length;
1103		}
1104		else if (purb->UrbControlDescriptorRequest.DescriptorType == 2) {	// configuration descriptor
1105			purb->UrbControlTransfer.TransferFlags = 0xb;
1106			bzero(pbuf, size);
1107			if (dev) {
1108				udev = usb_open(dev);
1109				if (udev) {
1110					ret = usb_get_descriptor(udev, USB_DT_CONFIG, purb->UrbControlDescriptorRequest.Index,
1111								pbuf, purb->UrbControlDescriptorRequest.TransferBufferLength);
1112					usb_close(udev);
1113				}
1114			}
1115			else
1116				break;
1117
1118			if (ret > 0)
1119				purb->UrbControlDescriptorRequest.TransferBufferLength = ret;
1120			else
1121				purb->UrbControlDescriptorRequest.TransferBufferLength = 0;
1122
1123			pirp_saverw->BufferSize = purb->UrbControlDescriptorRequest.TransferBufferLength + purb->UrbHeader.Length;
1124		}
1125		else if (purb->UrbControlDescriptorRequest.DescriptorType == 3){		// string descriptor
1126//			purb->UrbControlTransfer.TransferFlags = 0x0b;
1127			ret = 0;
1128			if (dev) {
1129				udev = usb_open(dev);
1130				if (udev) {
1131					ret = usb_get_string(udev, purb->UrbControlDescriptorRequest.Index,
1132								   purb->UrbControlDescriptorRequest.LanguageId, (char*)pbuf,
1133								   purb->UrbControlDescriptorRequest.TransferBufferLength);
1134					usb_close(udev);
1135				}
1136			}
1137			else
1138				break;
1139
1140			if (ret > 0)
1141				purb->UrbControlDescriptorRequest.TransferBufferLength = ret;
1142			else
1143				purb->UrbControlDescriptorRequest.TransferBufferLength = 0;
1144
1145			pirp_saverw->BufferSize = purb->UrbControlDescriptorRequest.TransferBufferLength + purb->UrbHeader.Length;
1146		}
1147		else 
1148			PDEBUG("handleURB64: descriptor type =  0x%x , not supported\n", purb->UrbControlDescriptorRequest.DescriptorType);
1149		break; // URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
1150
1151	case URB_FUNCTION_SELECT_CONFIGURATION:     //  0x0000
1152		// we must set configurationHandle & interfaceHandle & pipeHandle
1153		pirp_saverw->BufferSize = purb->UrbHeader.Length;
1154		pirp_saverw->Status = 0;
1155		pirp_saverw->Information = 0; 
1156		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1157		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1158		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1159		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1160		pbuf = pirp_saverw->Buffer + UrbLength;
1161
1162		if (dev) {
1163			if (purb->UrbSelectConfiguration.ConfigurationDescriptor == 0x0)
1164				break;
1165			else {
1166				purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1167
1168				tmp_config = (*(USB_CONFIGURATION_DESCRIPTOR_64*)pbuf).bConfigurationValue- 1;
1169				// *(pirp_saverw->Buffer + UrbLength + 5) is bConfigurationVaule field of Configuration Descriptor
1170
1171				purb->UrbSelectConfiguration.ConfigurationHandle = (u_int64_t)0x80000000+0x1000*(tmp_config+1);
1172
1173				char *tmp = (char*)&(purb->UrbSelectConfiguration.Interface);
1174				int tmp_len = purb->UrbHeader.Length - 0x28;
1175
1176				for (i = 0; tmp_len > 0; i++) {
1177					int tmp_int=(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceNumber;
1178					int tmp_alt=(*(USBD_INTERFACE_INFORMATION_64*)tmp).AlternateSetting;
1179
1180//					(*(USBD_INTERFACE_INFORMATION_64*)tmp).Length = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bLength;
1181//					(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceNumber = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceNumber;
1182//					(*(USBD_INTERFACE_INFORMATION_64*)tmp).AlternateSetting = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bAlternateSetting;
1183					(*(USBD_INTERFACE_INFORMATION_64*)tmp).Class = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceClass;
1184					(*(USBD_INTERFACE_INFORMATION_64*)tmp).SubClass = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceSubClass;
1185					(*(USBD_INTERFACE_INFORMATION_64*)tmp).Protocol = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceProtocol;
1186//					(*(USBD_INTERFACE_INFORMATION*)tmp).Reserved = 0x00;
1187					(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle = (u_int64_t)0x80000000+0x1000*(tmp_config+1)+0x100*(tmp_int+1)+0x10*(tmp_alt+1);
1188//					(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bNumEndpoints;
1189					for (j = 0; j < (*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes; j++) {
1190						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].wMaxPacketSize;
1191						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].EndpointAddress = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bEndpointAddress;
1192						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].Interval = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bInterval;
1193						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bmAttributes & USB_ENDPOINT_TYPE_MASK;
1194						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle = (u_int64_t)0x80000000+0x1000*(tmp_config+1)+0x100*(tmp_int+1)+0x10*(tmp_alt+1)+0x1*(j+2);
1195						if ((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize > MAX_BUFFER_SIZE)
1196							(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize = MAX_BUFFER_SIZE;
1197						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags = 0;
1198					}
1199					tmp_len -= (*(USBD_INTERFACE_INFORMATION_64*)tmp).Length;
1200					tmp += (*(USBD_INTERFACE_INFORMATION_64*)tmp).Length;
1201				}
1202			}
1203		}
1204		break; // URB_FUNCTION_SELECT_CONFIGURATION  
1205
1206	case 0x2a: // _URB_OS_FEATURE_DESCRIPTOR_REQUEST_FULL, added in U2EC, it's the same size as _URB_CONTROL_DESCRIPTOR_REQUEST, 
1207		// so we can handle it as URB_CONTROL_DESCRIPTOR_REQUEST
1208		pirp_saverw->BufferSize = purb->UrbHeader.Length;
1209		pirp_saverw->Status = 0xc0000010;
1210		pirp_saverw->Information = 0; 
1211		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1212		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1213		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1214		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1215
1216		purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1217		purb->UrbHeader.Status = 0x80000300;
1218		purb->UrbControlDescriptorRequest.TransferBufferLength = 0;
1219		// it's MS_FeatureDescriptorIndex in _URB_OS_FEATURE_DESCRIPTOR_REQUEST_FULL
1220//		purb->UrbControlDescriptorRequest.LanguageId = 0x0004;
1221		break; // 0x2a
1222
1223	case URB_FUNCTION_SELECT_INTERFACE:     // 0x0001
1224		pirp_saverw->BufferSize = purb->UrbHeader.Length;
1225		pirp_saverw->Status = 0;
1226		pirp_saverw->Information = 0; 
1227		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1228		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1229		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1230		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1231
1232		if (dev) {
1233			purb->UrbHeader.Status = 0;
1234			purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1235			purb->UrbHeader.UsbdFlags = 0;
1236
1237			tmp_config = (((u_int32_t)purb->UrbSelectInterface.ConfigurationHandle)<<16)>>28;
1238			tmp_config--;
1239			char *tmp = (char*)&(purb->UrbSelectInterface.Interface);
1240			int tmp_int = (*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceNumber;
1241			int tmp_alt = (*(USBD_INTERFACE_INFORMATION_64*)tmp).AlternateSetting;
1242
1243//			purb->UrbSelectInterface.ConfigurationHandle = 0x80000000+0x1000*(tmp_config+1);
1244
1245//			(*(USBD_INTERFACE_INFORMATION_64*)tmp).Length = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bLength;
1246//			(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceNumber = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceNumber;
1247//			(*(USBD_INTERFACE_INFORMATION_64*)tmp).AlternateSetting = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bAlternateSetting;
1248			(*(USBD_INTERFACE_INFORMATION_64*)tmp).Class = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceClass;
1249			(*(USBD_INTERFACE_INFORMATION_64*)tmp).SubClass = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceSubClass;
1250			(*(USBD_INTERFACE_INFORMATION_64*)tmp).Protocol = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceProtocol;
1251			(*(USBD_INTERFACE_INFORMATION_64*)tmp).Reserved = 0x00;
1252			(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle = (u_int64_t)0x80000000+0x1000*(tmp_config+1)+0x100*(tmp_int+1)+0x10*(tmp_alt+1);
1253			(*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bNumEndpoints;
1254
1255			for (j = 0; j < (*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes; j++) {
1256				(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].wMaxPacketSize;
1257				(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].EndpointAddress = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bEndpointAddress;
1258				(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].Interval = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bInterval;
1259				(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[j].bmAttributes & USB_ENDPOINT_TYPE_MASK;
1260				(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle = (u_int64_t)0x80000000+0x1000*(tmp_config+1)+0x100*(tmp_int+1)+0x10*(tmp_alt+1)+0x1*(j+2);
1261				if ((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize > MAX_BUFFER_SIZE)
1262					(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize = MAX_BUFFER_SIZE;
1263				(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags = 0;
1264			}
1265		}
1266		break; // URB_FUNCTION_SELECT_INTERFACE                0x0001
1267
1268	case URB_FUNCTION_CLASS_OTHER:      //        0x001F
1269		length = tmpL = tmpReq = tmpReqType = 0;
1270
1271		if (dev) {
1272			udev = usb_open(dev);
1273			if (udev) {
1274				tmpL = purb->UrbControlVendorClassRequest.TransferBufferLength;
1275				tmpReq = purb->UrbControlVendorClassRequest.Request;
1276				if (USBD_TRANSFER_DIRECTION_OUT == USBD_TRANSFER_DIRECTION(purb->UrbBulkOrInterruptTransfer.TransferFlags)) {
1277					tmpReqType = (USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_OTHER);
1278					pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
1279					memset(pbuf, 0x0, purb->UrbControlVendorClassRequest.TransferBufferLength);
1280					ret = usb_control_msg(udev, (USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_OTHER),
1281							purb->UrbControlVendorClassRequest.Request,
1282							purb->UrbControlVendorClassRequest.Value,
1283							purb->UrbControlVendorClassRequest.Index, (char*)pbuf,
1284							purb->UrbControlVendorClassRequest.TransferBufferLength,
1285							timeout_control_msg);
1286//					PDEBUG("usb_control_msg(), direction: out, return: %d\n", ret);
1287				} else {
1288					tmpReqType = (USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_OTHER);
1289					pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
1290					memset(pbuf, 0x0, purb->UrbControlVendorClassRequest.TransferBufferLength);
1291					ret = usb_control_msg(udev, (USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_OTHER),
1292							purb->UrbControlVendorClassRequest.Request,
1293							purb->UrbControlVendorClassRequest.Value,
1294							purb->UrbControlVendorClassRequest.Index, (char*)pbuf,
1295							purb->UrbControlVendorClassRequest.TransferBufferLength,
1296							timeout_control_msg);
1297//					PDEBUG("usb_control_msg(), direction: in, return: %d\n", ret);
1298				}
1299				usb_close(udev);
1300				if (ret < 0)
1301					break;
1302				else length = ret;
1303			}
1304			else
1305				break;
1306		}
1307		else
1308			break;
1309
1310		pbuf = pirp_saverw->Buffer + UrbLength;
1311		pirp_saverw->Status = 0;
1312		pirp_saverw->Information = 0; 
1313		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1314		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1315		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1316		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1317
1318		purb->UrbHeader.Function = 0x08;
1319		purb->UrbHeader.Status = 0;
1320		purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1321		purb->UrbHeader.UsbdFlags = 0x22;
1322		
1323		purb->UrbControlTransfer.PipeHandle = (u_int64_t)0x80000000+0x1000*(0+1)+0x100*(0+1)+0x10*(0+1)+0x1*1;
1324		purb->UrbControlTransfer.TransferFlags = 0x0a;
1325		purb->UrbControlTransfer.TransferBufferLength = length;
1326		purb->UrbControlTransfer.UrbLink = 0;
1327		purb->UrbControlTransfer.SetupPacket[0] = tmpReqType;
1328		purb->UrbControlTransfer.SetupPacket[1] = tmpReq;
1329		purb->UrbControlTransfer.SetupPacket[6] = (unsigned char )(tmpL&0x00ff);
1330		purb->UrbControlTransfer.SetupPacket[7] = (unsigned char )((tmpL&0xff00)>>8);
1331		pirp_saverw->BufferSize = purb->UrbControlTransfer.TransferBufferLength + purb->UrbHeader.Length;
1332		break; // URB_FUNCTION_CLASS_OTHER
1333
1334	case URB_FUNCTION_CLASS_INTERFACE:
1335		length = tmpL = tmpReq = tmpReqType = 0;
1336		ret = -1;
1337
1338		if (dev) {
1339			udev = usb_open(dev);
1340			if (udev) {
1341				tmpL = purb->UrbControlVendorClassRequest.TransferBufferLength;
1342				tmpReq = purb->UrbControlVendorClassRequest.Request;
1343				if (USBD_TRANSFER_DIRECTION_OUT == USBD_TRANSFER_DIRECTION(purb->UrbBulkOrInterruptTransfer.TransferFlags)) {
1344/*
1345					PDEBUG("OUT ");
1346					PDEBUG("req: %x ", purb->UrbControlVendorClassRequest.Request);
1347					PDEBUG("value: %x ", purb->UrbControlVendorClassRequest.Value);
1348					PDEBUG("index: %x ", purb->UrbControlVendorClassRequest.Index);
1349					PDEBUG("len: %x\n", purb->UrbControlVendorClassRequest.TransferBufferLength);
1350*/
1351					if (Is_Canon && flag_canon_state != 0)
1352					{
1353						if (	purb->UrbControlVendorClassRequest.Request == 0x2 &&
1354							purb->UrbControlVendorClassRequest.Value == 0x0 &&
1355							purb->UrbControlVendorClassRequest.Index == 0x100
1356						)
1357						{
1358							PDEBUG("user cancel printing...\n");
1359							flag_canon_state = 0;
1360							flag_canon_ok = 0;
1361						}
1362					}
1363
1364					tmpReqType = (USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE);
1365					pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
1366					memset(pbuf, 0x0, purb->UrbControlVendorClassRequest.TransferBufferLength);
1367					ret = usb_control_msg(udev, tmpReqType, purb->UrbControlVendorClassRequest.Request,
1368							purb->UrbControlVendorClassRequest.Value,
1369							purb->UrbControlVendorClassRequest.Index, (char*)pbuf,
1370							purb->UrbControlVendorClassRequest.TransferBufferLength,
1371							timeout_control_msg);
1372//					PDEBUG("usb_control_msg() out return: %d\n", ret);
1373					((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
1374				} else {
1375/*
1376					PDEBUG("IN ");
1377					PDEBUG("req: %x ", purb->UrbControlVendorClassRequest.Request);
1378					PDEBUG("value: %x ", purb->UrbControlVendorClassRequest.Value);
1379					PDEBUG("index: %x ", purb->UrbControlVendorClassRequest.Index);
1380					PDEBUG("len: %x\n", purb->UrbControlVendorClassRequest.TransferBufferLength);
1381*/
1382					pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
1383					memset(pbuf, 0x0, purb->UrbControlVendorClassRequest.TransferBufferLength);
1384					tmpReqType = (USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE);
1385					ret = usb_control_msg(udev, tmpReqType, purb->UrbControlVendorClassRequest.Request,
1386							purb->UrbControlVendorClassRequest.Value,
1387							purb->UrbControlVendorClassRequest.Index, (char*)pbuf,
1388							purb->UrbControlVendorClassRequest.TransferBufferLength,
1389							timeout_control_msg);
1390
1391					if (	Is_Canon &&
1392						purb->UrbControlVendorClassRequest.Request == 0x0 &&
1393						purb->UrbControlVendorClassRequest.Value == 0x0 &&
1394						purb->UrbControlVendorClassRequest.Index == 0x100
1395					)
1396						flag_canon_monitor = 1;
1397					else if (Is_Canon)
1398					{
1399						flag_canon_monitor = 0;
1400						((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
1401					}
1402					else if (Is_HP && ((PCONNECTION_INFO)curt_pos)->count_class_int_in < 3)	// HP Deskjet 3920 
1403						((PCONNECTION_INFO)curt_pos)->count_class_int_in++;
1404
1405//					PDEBUG("usb_control_msg() in return: %d\n", ret);
1406				}
1407				usb_close(udev);
1408				if (ret < 0)
1409					break;	
1410				else length = ret;
1411			}
1412			else
1413				break;
1414		}
1415		else
1416			break;
1417
1418		pbuf = pirp_saverw->Buffer + UrbLength;
1419		pirp_saverw->Status = 0;
1420		pirp_saverw->Information = 0; 
1421		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1422		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1423		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1424		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1425
1426		purb->UrbHeader.Function = 0x08;
1427		purb->UrbHeader.Status = 0;
1428		purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1429		purb->UrbHeader.UsbdFlags = 0x22;
1430		
1431		purb->UrbControlTransfer.PipeHandle = (u_int64_t)0x80000000+0x1000*(0+1)+0x100*(0+1)+0x10*(0+1)+0x1*1;
1432		purb->UrbControlTransfer.TransferFlags = 0x0b;
1433		purb->UrbControlTransfer.TransferBufferLength = length;
1434		purb->UrbControlTransfer.UrbLink = 0;
1435		//purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint = (u_int64_t)0xffffffff;
1436		//purb->UrbBulkOrInterruptTransfer.hca.HcdIrp = (u_int64_t)0xdeadf00d;
1437		purb->UrbControlTransfer.SetupPacket[0] = tmpReqType;
1438		purb->UrbControlTransfer.SetupPacket[1] = tmpReq;
1439		purb->UrbControlTransfer.SetupPacket[6] = (unsigned char )(tmpL&0x00ff);
1440		purb->UrbControlTransfer.SetupPacket[7] = (unsigned char )((tmpL&0xff00)>>8);
1441		pirp_saverw->BufferSize = purb->UrbControlTransfer.TransferBufferLength + purb->UrbHeader.Length;
1442		break; // URB_FUNCTION_CLASS_INTERFACE
1443
1444	case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:    //    0x0009
1445		pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
1446
1447		pirp_saverw->Status = 0;
1448		pirp_saverw->Information = 0; 
1449		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1450		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1451		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1452		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1453
1454		purb->UrbHeader.Status = 0;
1455		purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1456		purb->UrbHeader.UsbdFlags = 0x22;
1457		purb->UrbBulkOrInterruptTransfer.UrbLink = 0;
1458		//purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint = (u_int64_t)0xffffffff;
1459		//purb->UrbBulkOrInterruptTransfer.hca.HcdIrp = (u_int64_t)0xdeadf00d;
1460		purb->UrbControlDescriptorRequest.TransferBuffer = (u_int64_t)(u_int32_t)pbuf;
1461
1462//		PDEBUG("PipeHandle: 0x%x\n", purb->UrbBulkOrInterruptTransfer.PipeHandle);
1463		tmp_config = (((u_int32_t)purb->UrbBulkOrInterruptTransfer.PipeHandle)<<16)>>28;
1464		tmp_int = (((u_int32_t)purb->UrbBulkOrInterruptTransfer.PipeHandle)<<20)>>28;
1465		tmp_alt = (((u_int32_t)purb->UrbBulkOrInterruptTransfer.PipeHandle)<<24)>>28;
1466		tmp_ep = (((u_int32_t)purb->UrbBulkOrInterruptTransfer.PipeHandle)<<28)>>28;
1467		tmp_config--;
1468		tmp_int--;
1469		tmp_alt--;
1470		tmp_ep -= 2;
1471//		PDEBUG("config, int, alt, ep: %x %x %x %x\n", tmp_config, tmp_int, tmp_alt, tmp_ep);
1472
1473		if (dev) {
1474			tmp_intclass = dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].bInterfaceClass;
1475			if (tmp_intclass == 8) {
1476				timeout_bulk_read_msg_tmp = 1000;
1477				timeout_bulk_write_msg_tmp = 1000;
1478			} else if (Is_EPSON && tmp_intclass != 7)
1479			{
1480				timeout_bulk_read_msg_tmp = timeout_bulk_read_msg;
1481				timeout_bulk_write_msg_tmp = 30000;
1482			}
1483			else
1484			{
1485				timeout_bulk_read_msg_tmp = timeout_bulk_read_msg;
1486				timeout_bulk_write_msg_tmp = timeout_bulk_write_msg;
1487			}
1488
1489			if (Is_Canon && tmp_intclass != 7)
1490			{
1491				flag_canon_state = 0;
1492				flag_canon_ok = 0;
1493			}
1494
1495			udev = usb_open(dev);
1496			if (udev) {	
1497				if ((USB_ENDPOINT_TYPE_MASK & dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bmAttributes) == USB_ENDPOINT_TYPE_BULK) {
1498					if ((USB_ENDPOINT_DIR_MASK & dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress) == USB_ENDPOINT_OUT) {
1499						purb->UrbBulkOrInterruptTransfer.TransferFlags = 2;
1500						gettimeofday(&tv_ref, NULL);
1501						alarm(0);
1502						if (purb->UrbBulkOrInterruptTransfer.TransferBufferLength > MAX_BUFFER_SIZE)
1503							purb->UrbBulkOrInterruptTransfer.TransferBufferLength = MAX_BUFFER_SIZE;
1504						if (Is_Canon && tmp_intclass == 7)
1505						{
1506							if (flag_canon_state == 3)
1507							{
1508								PDEBUG("remain: %d\n", purb->UrbBulkOrInterruptTransfer.TransferBufferLength - data_canon_done);
1509								ret = usb_bulk_write(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)(pbuf + data_canon_done), purb->UrbBulkOrInterruptTransfer.TransferBufferLength - data_canon_done, 30000);
1510								if (ret > 0)
1511								{
1512									ret += data_canon_done;
1513									data_canon_done = 0;
1514								}
1515								else
1516									flag_canon_ok = 0;
1517							}
1518							else
1519							{
1520								data_canon_done = 0;
1521								ret = usb_bulk_write_sp(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, 5000, &data_canon_done, USB_Ver_N20?128:512);
1522								if (ret < 0 && data_canon_done > 0)
1523									PDEBUG("done: %d\n", data_canon_done);
1524							}
1525						}
1526						else if (Is_HP && (Is_HP_LaserJet || Is_HP_LaserJet_MFP) && tmp_intclass == 7)
1527							ret = usb_bulk_write(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, 500);
1528						else
1529							ret = usb_bulk_write(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, timeout_bulk_write_msg_tmp);
1530						alarm(1);
1531						gettimeofday(&tv_now, NULL);
1532
1533						if (Is_EPSON)
1534						{
1535							if (ret == 0 && purb->UrbBulkOrInterruptTransfer.TransferBufferLength == 2)
1536							{
1537								PDEBUG("retry...");
1538								ret = usb_bulk_write(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, timeout_bulk_write_msg_tmp);
1539							}
1540							if (ret >= 4096)
1541							{
1542								count_bulk_read_epson = 0;
1543								flag_monitor_epson = 0;
1544							}
1545						}
1546
1547						PDEBUG("usb_bulk_write() return: %d\n", ret);
1548
1549						count_bulk_write ++;
1550						count_bulk_read_ret0_1 = 0;
1551
1552						if (Is_EPSON) {
1553
1554						}
1555
1556						if (ret < 0) {
1557							if ((tv_now.tv_usec - tv_ref.tv_usec) >= 0)
1558								PDEBUG("sec: %ld, msec: %ld\n", tv_now.tv_sec-tv_ref.tv_sec, (tv_now.tv_usec-tv_ref.tv_usec)/1000);
1559							else
1560								PDEBUG("sec: %ld, msec: %ld\n", tv_now.tv_sec-tv_ref.tv_sec-1, (1000000+tv_now.tv_usec-tv_ref.tv_usec)/1000);
1561
1562							if (Is_Canon && tmp_intclass == 7)
1563							{
1564								if (flag_canon_state == 0 && ret == -ETIMEDOUT)
1565								{
1566									PDEBUG("copy data_buf !!!\n");
1567
1568									flag_canon_state = 1;
1569									flag_canon_ok = 0;
1570									memcpy(data_canon, data_buf, MAX_BUF_LEN);
1571
1572									usb_close(udev);
1573									pirp_saverw->BufferSize = purb->UrbHeader.Length;
1574									pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
1575									return 0;
1576								}
1577								else if (flag_canon_state != 1)
1578								{
1579									PDEBUG("skip...\n");
1580	
1581									usb_close(udev);
1582									pirp_saverw->BufferSize = purb->UrbHeader.Length;
1583									pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
1584									return 0;
1585								}
1586							}
1587						}
1588						else if (Is_Canon && tmp_intclass == 7)	// ret >= 0
1589						{
1590							flag_canon_state = 0;
1591							flag_canon_ok = 0;
1592							((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
1593						}
1594					} else {
1595						purb->UrbBulkOrInterruptTransfer.TransferFlags = 3;
1596						gettimeofday(&tv_ref, NULL);
1597						alarm(0);
1598						if (purb->UrbBulkOrInterruptTransfer.TransferBufferLength > MAX_BUFFER_SIZE)
1599							purb->UrbBulkOrInterruptTransfer.TransferBufferLength = MAX_BUFFER_SIZE;
1600						if (Is_HP && Is_HP_LaserJet_MFP && tmp_intclass == 7)
1601							ret = usb_bulk_read(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, 500);
1602						else
1603							ret = usb_bulk_read(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress, (char*)pbuf, purb->UrbBulkOrInterruptTransfer.TransferBufferLength, timeout_bulk_read_msg_tmp);
1604						alarm(1);
1605						gettimeofday(&tv_now, NULL);
1606
1607						if (	Is_Canon && tmp_intclass == 7 &&
1608							ret > 64 && ret < 256 &&
1609							memcmp(pbuf+2, "BST:", 4) == 0
1610						)
1611						{
1612							if (flag_canon_monitor == 1 && ((PCONNECTION_INFO)curt_pos)->count_class_int_in < 3)
1613							{
1614								flag_canon_monitor = 0;
1615								((PCONNECTION_INFO)curt_pos)->count_class_int_in++;
1616
1617								PDEBUG("mon: [%d] ", ((PCONNECTION_INFO)curt_pos)->count_class_int_in);
1618							}
1619
1620							if (*(pbuf+7) == '0')			// ok
1621								err_canon = 0;
1622							else if (*(pbuf+7) == '8')		// operation call
1623								err_canon = 1;
1624							else					// unknown error
1625								err_canon = 2;
1626
1627//							if (flag_canon_state == 1 && err_canon != 0)
1628							if (flag_canon_state == 1 && err_canon == 1)
1629							{					// "out of paper"
1630								flag_canon_state = 2;
1631								flag_canon_ok = 0;
1632							}
1633//							else if (flag_canon_state == 1 && err_canon == 0 && ++flag_canon_ok > 5)
1634							else if (flag_canon_state == 1 && err_canon != 1 && ++flag_canon_ok > 5)
1635								flag_canon_state = 3;		// warm-up
1636//							else if (flag_canon_state == 2 && err_canon == 0)
1637							else if (flag_canon_state == 2 && err_canon != 1)
1638							{					// "out of paper" => "ok"
1639								flag_canon_state = 3;
1640								flag_canon_ok = 0;
1641							}
1642//							else if (flag_canon_state == 3 && err_canon == 0)
1643							else if (flag_canon_state == 3 && err_canon != 1)
1644								flag_canon_ok++;	
1645
1646							PDEBUG("status:[%s] state:[%d] ok:[%d] ", usblp_messages_canon[err_canon], flag_canon_state, flag_canon_ok);
1647						}
1648						else
1649						{
1650							flag_canon_monitor = 0;
1651							((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
1652						}
1653
1654						PDEBUG("usb_bulk_read() return: %d\n", ret);
1655
1656						if (Is_HP) {  	// HP, if this connection only includes HP ToolBox
1657							if (ret == 0) {
1658								count_bulk_read_ret0_1 ++;
1659								if (count_bulk_read_ret0_1 >= 30) {
1660									count_bulk_write = 0;
1661									count_bulk_read  = 0;
1662									count_bulk_read_ret0_1 = 0;
1663									count_bulk_read_ret0_2 = 0;
1664								}
1665								if (Is_HP_LaserJet) {						// laserjet 33xx series 
1666									if (count_bulk_write == 1 && count_bulk_read == 1)
1667										count_bulk_read_ret0_2 ++;
1668								}
1669								else if (Is_HP_OfficeJet) {					// officejet 56xx series
1670									if (count_bulk_write == 2 && count_bulk_read == 2)
1671										count_bulk_read_ret0_2 ++;
1672								}
1673							}
1674							else if(ret > 0){
1675								count_bulk_read ++;
1676								count_bulk_read_ret0_1 = 0;
1677							}
1678						}
1679						else if (Is_EPSON) {
1680							if (ret == 9 && count_bulk_read_epson == 0 && memcmp(EPSON_BR_STR1_09, pbuf, 9) == 0)
1681								count_bulk_read_epson = 1;
1682							else if(ret == 19) {
1683								if (count_bulk_read_epson == 1 && memcmp(EPSON_BR_STR2_19, pbuf, 19) == 0)
1684									count_bulk_read_epson = 2;
1685								else if (count_bulk_read_epson == 2 && memcmp(EPSON_BR_STR3_19, pbuf, 19) == 0)
1686									count_bulk_read_epson = 3;
1687							}
1688						}
1689
1690						if (ret < 0) {
1691							count_bulk_read_epson = -1;
1692							flag_monitor_epson = 0;
1693
1694							if ((tv_now.tv_usec - tv_ref.tv_usec) >= 0)
1695								PDEBUG("sec: %ld, msec: %ld\n", tv_now.tv_sec-tv_ref.tv_sec, (tv_now.tv_usec-tv_ref.tv_usec)/1000);
1696							else
1697								PDEBUG("sec: %ld, msec: %ld\n", tv_now.tv_sec-tv_ref.tv_sec-1, (1000000+tv_now.tv_usec-tv_ref.tv_usec)/1000);
1698							}
1699
1700/*							if (purb->UrbBulkOrInterruptTransfer.TransferBufferLength != 0 && ret == 0)
1701								pirp_saverw->Status = 0xC0000004;	// STATUS_INFO_LENGTH_MISMATCH
1702							else if (ret < 0)
1703								pirp_saverw->Status = 0xC00000AE;	// STATUS_PIPE_BUSY
1704*/
1705					}
1706				} else {
1707					usb_close(udev);
1708					pirp_saverw->BufferSize = purb->UrbHeader.Length;
1709					pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
1710					return 0;
1711				}
1712
1713				if (ret < 0) {
1714					ret = 0;
1715					count_err++;
1716				} else
1717					count_err = 0;
1718
1719				if (count_err > 255)
1720					pirp_saverw->Status = 0xC00000AD;	// STATUS_INVALID_PIPE_STATE
1721
1722				usb_close(udev);
1723			}
1724			else
1725				ret = 0;
1726		}
1727		else
1728			ret = 0;
1729
1730		purb->UrbBulkOrInterruptTransfer.TransferBufferLength = ret;
1731
1732		if ((USB_ENDPOINT_DIR_MASK & dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress) == USB_ENDPOINT_OUT)
1733			pirp_saverw->BufferSize = purb->UrbHeader.Length;
1734		else
1735			pirp_saverw->BufferSize = purb->UrbHeader.Length + purb->UrbBulkOrInterruptTransfer.TransferBufferLength;
1736		break;   // URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER      0x0009
1737
1738	case URB_FUNCTION_ABORT_PIPE:
1739		PDEBUG("\n\t URB_FUNCTION_ABORT_PIPE");
1740
1741		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1742		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1743		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1744		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1745
1746		purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;   // according to packet
1747		purb->UrbHeader.UsbdFlags = 0x10;
1748
1749//		PDEBUG("\n\t PipeHandle: 0x%x", purb->UrbPipeRequest.PipeHandle);
1750		tmp_config = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<16)>>28;
1751		tmp_int = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<20)>>28;
1752		tmp_alt = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<24)>>28;
1753		tmp_ep = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<28)>>28;
1754		tmp_config--;
1755		tmp_int--;
1756		tmp_alt--;
1757		tmp_ep -= 2;
1758//		PDEBUG("\n\t config, int, alt, ep: %lld %lld %lld %lld in Dec", tmp_config, tmp_int, tmp_alt, tmp_ep);
1759
1760		if (dev) {
1761			udev = usb_open(dev);
1762			if (udev) {
1763				usb_clear_halt(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress);
1764				usb_close(udev);
1765			}
1766		}
1767		break;
1768
1769	case URB_FUNCTION_RESET_PIPE:
1770		PDEBUG("\n\t URB_FUNCTION_RESET_PIPE");
1771
1772		pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1773		pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1774		pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1775		pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1776
1777		purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;   // according to packet
1778		purb->UrbHeader.UsbdFlags = 0x10;
1779
1780//		PDEBUG("\n\t PipeHandle: 0x%x", purb->UrbPipeRequest.PipeHandle);
1781		tmp_config = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<16)>>28;
1782		tmp_int = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<20)>>28;
1783		tmp_alt = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<24)>>28;
1784		tmp_ep = (((u_int32_t)purb->UrbPipeRequest.PipeHandle)<<28)>>28;
1785		tmp_config--;
1786		tmp_int--;
1787		tmp_alt--;
1788		tmp_ep -= 2;
1789//		PDEBUG("\n\t config, int, alt, ep: %lld %lld %lld %lld in Dec", tmp_config, tmp_int, tmp_alt, tmp_ep);
1790
1791		if (dev) {
1792			udev = usb_open(dev);
1793			if (udev) {
1794				usb_resetep(udev, dev->config[tmp_config].interface[tmp_int].altsetting[tmp_alt].endpoint[tmp_ep].bEndpointAddress);
1795				usb_close(udev);
1796			}
1797		}
1798		break;
1799
1800	default:
1801		PDEBUG("\n !!! Unsupported URB_FUNCTION: 0x%x\n\n", purb->UrbHeader.Function);
1802		break;
1803	} // end of switch urb function
1804
1805	pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize ;
1806	return 1;
1807
1808} // end of handleURB64
1809
1810/*
1811 * Handle urbs in irp_saverw.Buffer for free (non-busy) clients
1812 */
1813void handleURB_fake(PIRP_SAVE pirp_saverw)
1814{
1815	PURB		purb;
1816	unsigned char*	pbuf;
1817
1818	purb = (PURB)pirp_saverw->Buffer;
1819	pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
1820
1821	pirp_saverw->Status = 0;
1822	pirp_saverw->Information = 0; 
1823	pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1824	pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1825	pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1826	pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1827
1828	purb->UrbHeader.Status = 0;
1829	purb->UrbHeader.UsbdDeviceHandle = (void*)0x80000000;
1830	purb->UrbHeader.UsbdFlags = 0x22;
1831	purb->UrbBulkOrInterruptTransfer.UrbLink = 0;
1832	purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint = (void*)0xffffffff;
1833	purb->UrbBulkOrInterruptTransfer.hca.HcdIrp = (void*)0xdeadf00d;
1834	purb->UrbControlDescriptorRequest.TransferBuffer = pbuf;
1835
1836	purb->UrbBulkOrInterruptTransfer.TransferBufferLength = 0;
1837	pirp_saverw->BufferSize = purb->UrbHeader.Length;
1838	pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize ;
1839	pirp_saverw->Status = 0xC00000AE;	// STATUS_PIPE_BUSY
1840}
1841
1842/*
1843 * Handle urbs in irp_saverw.Buffer for free (non-busy) clients
1844 */
1845void handleURB_64_fake(PIRP_SAVE pirp_saverw)
1846{
1847	PURB_64		purb;
1848	unsigned char*	pbuf;
1849
1850	purb = (PURB_64)pirp_saverw->Buffer;
1851	pbuf = pirp_saverw->Buffer + purb->UrbHeader.Length;
1852
1853	pirp_saverw->Status = 0;
1854	pirp_saverw->Information = 0; 
1855	pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1856	pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1857	pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1858	pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1859
1860	purb->UrbHeader.Status = 0;
1861	purb->UrbHeader.UsbdDeviceHandle = (u_int64_t)0x80000000;
1862	purb->UrbHeader.UsbdFlags = 0x22;
1863	purb->UrbBulkOrInterruptTransfer.UrbLink = 0;
1864	purb->UrbControlDescriptorRequest.TransferBuffer = (u_int64_t)(u_int32_t)pbuf;
1865
1866	purb->UrbBulkOrInterruptTransfer.TransferBufferLength = 0;
1867	pirp_saverw->BufferSize = purb->UrbHeader.Length;
1868	pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize ;
1869	pirp_saverw->Status = 0xC00000AE;	// STATUS_PIPE_BUSY
1870}
1871
1872/*
1873 * Do actions according to MJ function and MN function.
1874 */
1875int exchangeIRP(PIRP_SAVE pirp_saver, PIRP_SAVE pirp_saverw, struct u2ec_list_head *curt_pos)
1876{
1877	WCHAR		wcbuf[256];
1878	char		pbuf[256];
1879	int		i, n, ret;
1880
1881	bzero(wcbuf, sizeof(wcbuf));
1882	bzero(pbuf, 256);
1883
1884	if (pirp_saver->StackLocation.MajorFunction != IRP_MJ_INTERNAL_DEVICE_CONTROL)
1885		((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
1886
1887	switch(pirp_saver->StackLocation.MajorFunction) {
1888	case IRP_MJ_PNP:
1889		switch (pirp_saver->StackLocation.MinorFunction) {
1890		case IRP_MN_QUERY_ID:				//13
1891			switch (pirp_saver->StackLocation.Parameters.Others.Argument1) {
1892			case 0x0:
1893				if (dev)
1894					sprintf(pbuf, "USB\\Vid_%04x&Pid_%04x", dev->descriptor.idVendor, dev->descriptor.idProduct);
1895				else break;
1896
1897				for(n = 0; n < 23; n++)
1898#if __BYTE_ORDER == __LITTLE_ENDIAN
1899					wcbuf[n] = (WCHAR)*(pbuf + n);
1900#else
1901					wcbuf[n] = SWAP_BACK16((WCHAR)*(pbuf + n));
1902#endif
1903				memcpy(pirp_saverw->Buffer, wcbuf, 2*n);
1904				
1905				pirp_saverw->BufferSize = 2*n;
1906				pirp_saverw->Status = 0;
1907				pirp_saverw->Information = ((u_int64_t)(unsigned int)pirp_saverw->Buffer)<<32; 
1908				pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
1909				break;
1910
1911			case 0x1:
1912			case (u_int64_t)4294967296://0x00100000:
1913				if (dev) {					
1914					sprintf(pbuf, "USB\\Vid_%04x&Pid_%04x&Rev_%04x",
1915						dev->descriptor.idVendor, dev->descriptor.idProduct, dev->descriptor.bcdDevice);
1916					sprintf(pbuf+strlen(pbuf)+1, "USB\\Vid_%04x&Pid_%04x",
1917						dev->descriptor.idVendor, dev->descriptor.idProduct);
1918				}
1919				else break;
1920			
1921				for(n = 0; n < 54; n++)
1922#if __BYTE_ORDER == __LITTLE_ENDIAN
1923					wcbuf[n] = (WCHAR)*(pbuf + n);
1924#else
1925					wcbuf[n] = SWAP_BACK16((WCHAR)*(pbuf + n));
1926#endif
1927				memcpy(pirp_saverw->Buffer, wcbuf, 2*n);
1928				
1929				pirp_saverw->BufferSize = 2*n ;
1930				pirp_saverw->Status = 0;
1931				pirp_saverw->Information = ((u_int64_t)(unsigned int)pirp_saverw->Buffer)<<32; 
1932				pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
1933				pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1934				pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1935				pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1936				pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1937				break;
1938
1939			case 0x2:
1940			case (u_int64_t)8589934592://0x00020000:
1941				if (dev) {
1942					if (dev->config[0].bNumInterfaces > 1) 	{
1943						strcpy(pbuf, "USB\\DevClass_00&SubClass_00&Prot_00");	//pbuf 0~35
1944						strcpy(pbuf + 36, "USB\\DevClass_00&SubClass_00");	//pbuf 36~63 
1945						strcpy(pbuf + 64, "USB\\DevClass_00");			//pbuf 64~79
1946						strcpy(pbuf + 80, "USB\\COMPOSITE");			//pbuf 80~93
1947						*(pbuf + 94) = 0;
1948					} else {	// ex: "USB\\Class_07&SubClass_01&Prot_02 USB\\Class_07&SubClass_01 USB\\Class_07"
1949						sprintf(pbuf, "USB\\Class_%02x&SubClass_%02x&Prot_%02x",
1950							dev->config[0].interface[0].altsetting[0].bInterfaceClass,
1951							dev->config[0].interface[0].altsetting[0].bInterfaceSubClass,
1952							dev->config[0].interface[0].altsetting[0].bInterfaceProtocol);	//pbuf 0~32
1953						sprintf(pbuf + 33, "USB\\Class_%02x&SubClass_%02x",
1954							dev->config[0].interface[0].altsetting[0].bInterfaceClass,
1955							dev->config[0].interface[0].altsetting[0].bInterfaceSubClass);	//pbuf 33~57
1956						sprintf(pbuf + 58, "USB\\Class_%02x",
1957							dev->config[0].interface[0].altsetting[0].bInterfaceClass);	//pbuf 58~70
1958						*(pbuf + 71) = 0;
1959					}
1960				}
1961				else break;
1962
1963				if (!(dev->config[0].bNumInterfaces > 1))
1964					i = 72;
1965				else
1966					i = 95;
1967
1968				for(n = 0; n < i; n++)
1969#if __BYTE_ORDER == __LITTLE_ENDIAN
1970					wcbuf[n] = (WCHAR)*(pbuf + n);
1971#else
1972					wcbuf[n] = SWAP_BACK16((WCHAR)*(pbuf + n));
1973#endif
1974				memcpy(pirp_saverw->Buffer, wcbuf, 2*n);
1975				
1976				pirp_saverw->BufferSize = 2*n;
1977				pirp_saverw->Status = 0;
1978				pirp_saverw->Information = ((u_int64_t)(unsigned int)pirp_saverw->Buffer)<<32; 
1979				pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
1980				pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
1981				pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
1982				pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
1983				pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
1984				break;
1985
1986			case 0x3:
1987			case (u_int64_t)12884901888://0x00030000:
1988				if (dev) {
1989					ret = 0;
1990					udev = usb_open(dev);
1991					if (udev) {
1992						if (dev->descriptor.iSerialNumber)
1993							ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, pbuf, 256);
1994						ret++;
1995    						usb_close(udev);
1996    					}
1997				}
1998				else break;
1999			
2000				for(n = 0; n < ret; n++)
2001#if __BYTE_ORDER == __LITTLE_ENDIAN
2002					wcbuf[n] = *(pbuf + n);
2003#else
2004					wcbuf[n] = SWAP_BACK16(*(pbuf + n));
2005#endif
2006				memcpy(pirp_saverw->Buffer, wcbuf, 2*n);
2007				
2008				pirp_saverw->BufferSize = 2*n;
2009				pirp_saverw->Status = 0;
2010				pirp_saverw->Information = ((u_int64_t)(unsigned int)pirp_saverw->Buffer)<<32; 
2011				pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
2012				pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
2013				pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
2014				pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
2015				pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
2016				break;
2017			
2018			default:
2019				PDEBUG("IRP_MN_QUERY_ID: argument not supported.\n");
2020				return -1;
2021				break;
2022			}
2023			break;//end of query id
2024
2025		case IRP_MN_QUERY_DEVICE_TEXT:			// 0c
2026			switch (pirp_saver->StackLocation.Parameters.Others.Argument1) {
2027			case 0x0:
2028				if (dev) {
2029					ret = 0;
2030					udev = usb_open(dev);
2031					if (udev) {
2032						if (dev->descriptor.iProduct)
2033							ret = usb_get_string_simple(udev, dev->descriptor.iProduct, pbuf, 256);
2034						ret++;
2035    						usb_close(udev);
2036    					}
2037				}
2038				else break;
2039
2040				for(n = 0; n < ret; n++)
2041#if __BYTE_ORDER == __LITTLE_ENDIAN
2042					wcbuf[n] = *(pbuf + n);
2043#else
2044					wcbuf[n] = SWAP_BACK16(*(pbuf + n));
2045#endif
2046				memcpy(pirp_saverw->Buffer, wcbuf, 2*n);
2047				
2048				pirp_saverw->BufferSize = 2*n;
2049				pirp_saverw->Status = 0;
2050				pirp_saverw->Information = ((u_int64_t)(unsigned int)pirp_saverw->Buffer)<<32; 
2051				pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
2052				pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
2053				pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
2054				pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
2055				pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
2056				break;
2057
2058			case 0x1:
2059			case 0x100000000:
2060//			case (u_int64_t)4294967296://0x00001000:
2061				if (dev) {
2062					ret=0;
2063					udev = usb_open(dev);
2064					if (udev) {
2065						if (dev->descriptor.iProduct)
2066							ret = usb_get_string_simple(udev, dev->descriptor.iProduct, pbuf, 256);
2067						ret++;
2068    						usb_close(udev);
2069    					}
2070				}
2071				else break;
2072
2073				for(n = 0; n < ret; n++)
2074#if __BYTE_ORDER == __LITTLE_ENDIAN
2075					wcbuf[n] = *(pbuf + n);
2076#else
2077					wcbuf[n] = SWAP_BACK16(*(pbuf + n));
2078#endif
2079				memcpy(pirp_saverw->Buffer, wcbuf, 2*n);
2080				
2081				pirp_saverw->BufferSize = 2*n;
2082				pirp_saverw->Status = 0;
2083				pirp_saverw->Information = ((u_int64_t)(unsigned int)pirp_saverw->Buffer)<<32; 
2084				pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
2085				pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
2086				pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
2087				pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
2088				pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;
2089				break;
2090			
2091			default:
2092				PDEBUG("IRP_MN_QUERY_DEVICE_TEXT: argument not supported.\n");
2093				return -1;
2094			}
2095			break; //end of query device text
2096		
2097		case IRP_MN_QUERY_CAPABILITIES:			// 09
2098			*pbuf = 0x40;
2099			*(pbuf + 2) = 0x01;
2100			*(pbuf + 4) = 0x50;
2101//			*(pbuf + 8) = 0x02;	// for Lexmark X5470
2102			*(pbuf + 8) = 0x01;	// for HP Officejet 5610, EPSON TX200
2103			*(pbuf + 20) = 0x01;
2104			*(pbuf + 24) = 0x04;
2105			*(pbuf + 28) = 0x04;
2106			*(pbuf + 32) = 0x04;
2107			*(pbuf + 36) = 0x04;
2108			*(pbuf + 40) = 0x04;
2109//			*(pbuf + 44) = 0x04;	// for Lexmark X5470, HP Officejet 5610
2110			*(pbuf + 44) = 0x01;	// for EPSON TX200
2111			*(pbuf + 48) = 0x01;
2112
2113			n = 64;
2114			memcpy(pirp_saverw->Buffer, pbuf, n);
2115			pirp_saverw->BufferSize = n;
2116			pirp_saverw->Status = 0;
2117			pirp_saverw->Information = 0; 
2118			pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize;
2119			pirp_saverw->StackLocation.Parameters.Others.Argument1 = (u_int64_t)0;
2120			pirp_saverw->StackLocation.Parameters.Others.Argument2 = (u_int64_t)0;
2121			pirp_saverw->StackLocation.Parameters.Others.Argument3 = (u_int64_t)0;
2122			pirp_saverw->StackLocation.Parameters.Others.Argument4 = (u_int64_t)0;					
2123			break;
2124
2125		case 0x18:   
2126		case IRP_MN_QUERY_RESOURCES:			// 0a
2127		case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:	// 0x0D
2128			pirp_saverw->BufferSize = 0;
2129			pirp_saverw->Information = 0; 
2130			pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize ; // 104
2131			break;
2132
2133		case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:	// 0b
2134		case IRP_MN_START_DEVICE:			// 0x00
2135			pirp_saverw->BufferSize = 0;
2136			pirp_saverw->Status = 0;
2137			pirp_saverw->Information = 0; 
2138			pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize ; // 104
2139			break; 
2140
2141		case IRP_MN_QUERY_PNP_DEVICE_STATE:		// 0x14
2142			pirp_saverw->Status = 0;
2143			pirp_saverw->Information = 0; 
2144//			pirp_saverw->Reserv = 0x50;   
2145			break;
2146
2147		case IRP_MN_QUERY_DEVICE_RELATIONS:		// 0x07
2148			pirp_saverw->Status = 0;
2149			pirp_saverw->Information = 0; 
2150			break; 
2151
2152		case IRP_MN_QUERY_BUS_INFORMATION:		// 15
2153			*pbuf = 0xbc;
2154			*(pbuf + 1) = 0xeb;
2155			*(pbuf + 2) = 0x7d;
2156			*(pbuf + 3) = 0x9d;
2157			*(pbuf + 4) = 0x5d;
2158			*(pbuf + 5) = 0xc8;
2159			*(pbuf + 6) = 0xd1;
2160			*(pbuf + 7) = 0x11;
2161			*(pbuf + 8) = 0x9e;
2162			*(pbuf + 9) = 0xb4;
2163			*(pbuf + 10) = 0x00;
2164			*(pbuf + 11) = 0x60;
2165			*(pbuf + 12) = 0x08;
2166			*(pbuf + 13) = 0xc3;
2167			*(pbuf + 14) = 0xa1;
2168			*(pbuf + 15) = 0x9a;
2169			*(pbuf + 16) = 0x0f;
2170
2171			n = 24;
2172			memcpy(pirp_saverw->Buffer, pbuf, n);
2173
2174			pirp_saverw->BufferSize = n ; 
2175			pirp_saverw->Status = 0;
2176			pirp_saverw->Information = ((u_int64_t)(unsigned int)pirp_saverw->Buffer)<<32; 
2177			pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize ;
2178			break;
2179
2180		case IRP_MN_QUERY_INTERFACE:	// 0x08
2181			PDEBUG("\n\t IRP_MN_QUERY_INTERFACE");	// for Lexmark X5470
2182			pirp_saverw->BufferSize = 0;
2183			pirp_saverw->Status = 0xC0000022;
2184			pirp_saverw->Information = 0; 
2185			pirp_saverw->NeedSize = sizeof(IRP_SAVE) + pirp_saverw->BufferSize ; // 104
2186			break;
2187
2188		default:
2189			PDEBUG("Mirnor function not supported.\n");
2190		}//end of switch MN
2191		break;
2192
2193	case IRP_MJ_INTERNAL_DEVICE_CONTROL:			// 0x0f
2194		// handle urbs in irp_saverw.Buffer
2195		if (pirp_saver->Is64 == 0) {
2196			if (pirp_saver->NeedSize < sizeof(IRP_SAVE) - 8 + sizeof(struct _URB_HEADER))
2197				return 1;
2198			if (handleURB(pirp_saverw, (struct u2ec_list_head *)curt_pos) != 1) {
2199				PDEBUG("HandleURB not successed.\n");
2200				return 0;
2201			}
2202		} else {
2203			if (pirp_saver->NeedSize < sizeof(IRP_SAVE) - 8 + sizeof(struct _URB_HEADER_64))
2204				return 1;
2205			if (handleURB_64(pirp_saverw, (struct u2ec_list_head *)curt_pos) != 1) {
2206				PDEBUG("HandleURB_64 not successed.\n");
2207				return 0;
2208			}
2209		}
2210		break;
2211
2212	default:
2213		PDEBUG("\n!!! Unsupported IRP major: %x\n", pirp_saver->StackLocation.MinorFunction);
2214	}//end of switch MJ
2215
2216#if defined(U2EC_DEBUG)
2217	if (pirp_saver->StackLocation.MajorFunction != IRP_MJ_INTERNAL_DEVICE_CONTROL)
2218		PDEBUG("\n");
2219#endif
2220
2221	return 1;
2222}//end of exchangeIRP
2223
2224/*
2225 * Initialize a Datagram listener
2226 * for find_all.
2227 */
2228int dgram_sock_init(int port)
2229{
2230	int		    sockfd;
2231	struct sockaddr_in  serv_addr;
2232	int		    broadcast = 1;;
2233	int		    yes = 1;
2234
2235	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
2236		PERROR("socket");
2237		return -1;
2238	}
2239
2240#ifdef	SUPPORT_LPRng
2241	struct ifreq	    ifr;
2242	bzero((char *)&ifr, sizeof(ifr));
2243#if __BYTE_ORDER == __LITTLE_ENDIAN
2244	strncpy(ifr.ifr_name, nvram_safe_get("lan_ifname"), strlen(nvram_safe_get("lan_ifname")));
2245#else
2246	strncpy(ifr.ifr_name, "br0", strlen("br0"));
2247#endif
2248
2249	if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifr, sizeof(ifr)) < 0) {
2250		perror("setsockopt: bind to device");
2251		return -1;
2252	}
2253#endif
2254
2255	if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)) < 0) {
2256		perror("setsockopt: bin to broadcast");
2257		return -1;
2258	}
2259
2260	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
2261		PERROR("setsockopt");
2262		return -1;
2263	}
2264
2265	bzero((char *)&serv_addr, sizeof(serv_addr));
2266	serv_addr.sin_family	    = AF_INET;
2267	serv_addr.sin_addr.s_addr   = INADDR_ANY;
2268	serv_addr.sin_port	    = htons(port);
2269
2270	if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
2271		perror("bind");
2272		return -1;
2273	}
2274
2275	return sockfd;
2276}
2277
2278/*
2279 * Initialize a stream listener
2280 * for add_remote_device and establish_connection.
2281 */
2282int stream_sock_init(int port)
2283{
2284	int		    sockfd;
2285	struct sockaddr_in  serv_addr;
2286	int		    yes = 1;
2287	int		    no_delay = 1;
2288
2289	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
2290		PERROR("socket");
2291		return -1;
2292	}
2293
2294	if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay)) < 0) {
2295		PERROR("setsockopt");
2296		return -1;
2297	}
2298
2299	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
2300		PERROR("setsockopt");
2301		return -1;
2302	}
2303
2304	bzero((char *)&serv_addr, sizeof(serv_addr));
2305	serv_addr.sin_family	    = AF_INET;
2306	serv_addr.sin_addr.s_addr   = INADDR_ANY;
2307	serv_addr.sin_port	    = htons(port);
2308
2309	if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
2310		PERROR("bind");
2311		return -1;
2312	}
2313
2314	if (listen(sockfd, BACKLOG) < 0) {
2315		PERROR("listen");
2316		return -1;
2317	}
2318
2319	return sockfd;
2320}
2321
2322/*
2323 * Response GETIP GETCONFIG and GETNAME from client.
2324 */
2325void add_remote_device()
2326{
2327	int		    find_fd, conf_fd, new_fd;
2328	fd_set		    master_fds, read_fds;
2329	int		    fdmax, ret;
2330	struct sockaddr_in  cli_addr;
2331	int		    addr_len = sizeof(cli_addr);
2332	char		    message[192];
2333
2334	FD_ZERO(&master_fds);
2335	FD_ZERO(&read_fds);
2336
2337	/* The listener for find all. */
2338	if ((find_fd = dgram_sock_init(uTcpUdp)) < 0) {
2339		PERROR("find all: can't bind to any address\n");
2340		return;
2341	}
2342
2343	/* The listener for get config & get name. */
2344	if ((conf_fd = stream_sock_init(uTcpPortConfig)) < 0) {
2345		PERROR("get config and name: can't bind to any address\n");
2346		return;
2347	}
2348
2349	FD_SET(find_fd, &master_fds);
2350	FD_SET(conf_fd, &master_fds);
2351	fdmax = find_fd > conf_fd ? find_fd : conf_fd;
2352
2353	for (;;) {
2354		read_fds = master_fds;
2355		while((ret = select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) && (errno == EINTR));
2356		if (ret == -1) {
2357			PERROR("select");
2358			return;
2359		}
2360
2361		/* handle GETIP. */
2362		if (FD_ISSET(find_fd, &read_fds)) {
2363			bzero(message, 192);
2364			if ((recvfrom(find_fd, message, 5, 0, (struct sockaddr*)&cli_addr, &addr_len) == 5) &&
2365			    (strncmp(message, "GETIP", 5) == 0)) {
2366				cli_addr.sin_port = htons(uTcpUdp+1);	
2367				if (sendto(find_fd, message, 5, 0, (struct sockaddr*)&cli_addr, addr_len) < 0)
2368					perror("sendto");
2369			}
2370		}
2371		/* handle GETCONFIG & GETNAME. */
2372		if (FD_ISSET(conf_fd, &read_fds)) {
2373			if ((new_fd = accept(conf_fd, (struct sockaddr *)&cli_addr, &addr_len)) < 0) {
2374				PERROR("accept");
2375				continue;
2376			}
2377	
2378			bzero(message, 192);
2379			if ((ret = recv(new_fd, message, 9, 0)) <= 0) {
2380				PERROR("recv");
2381				goto next;
2382			}
2383			message[ret] = '\0';
2384			PSNDRECV("add_remote_device from fd: %d received: %s\n", new_fd, message);
2385			if (strncmp(message, "GETCONFIG", 9) == 0) {
2386				sprintf(message, "RootHub#1|Port1:%d!", uTCPUSB);
2387				if (send(new_fd, message, strlen(message), 0) < 0) {
2388					PERROR("send");
2389					goto next;
2390				}
2391				PSNDRECV("add_remote_device GETCONFIG sent: %s\n", message);
2392			}
2393			else if (strncmp(message, "GETNAME", 7) == 0) {
2394				if (dev)
2395	      				sprintf(message, "RootHub#1|Port1(%s)!", str_product);
2396				else
2397	      				sprintf(message, "RootHub#1|Port1!");
2398				if (send(new_fd, message, strlen(message), 0) < 0) {
2399					PERROR("send");
2400					goto next;
2401				}
2402				PSNDRECV("add_remote_device GETNAME sent: %s\n", message);
2403			}
2404			else
2405				PDEBUG("get: unknown command:%s\n", message);
2406next:
2407			usleep(100000);
2408			close(new_fd);
2409		}
2410	}
2411}
2412
2413/*
2414 * Synchronize nvram "MFP_busy" as a flag.
2415 * @param	state	MFP_GET_STATE: get the flag from nvram, othere: set state to nvram.
2416 * @return	value of get from nvram or set to nvram.
2417 */
2418int MFP_state(int state)
2419{
2420	static int MFP_is_busy = MFP_IS_IDLE;
2421	if (state == MFP_GET_STATE) {
2422#ifdef	SUPPORT_LPRng
2423		char *value = nvram_safe_get("MFP_busy");
2424		if (strcmp(value, "0") == 0)
2425			return MFP_is_busy = MFP_IS_IDLE;
2426		else if (strcmp(value, "1") == 0)
2427			return MFP_is_busy = MFP_IN_LPRNG;
2428		else if (strcmp(value, "2") == 0)
2429			return MFP_is_busy = MFP_IN_U2EC;
2430		else
2431#endif
2432			return MFP_is_busy;
2433	} else {
2434#ifdef	SUPPORT_LPRng
2435		if (state == MFP_IS_IDLE)
2436			nvram_set("MFP_busy", "0");
2437		else if (state == MFP_IN_U2EC)
2438			nvram_set("MFP_busy", "2");
2439#endif
2440		return MFP_is_busy = state;
2441	}
2442	return -1;
2443}
2444
2445/*
2446 * Handle exceptional device.
2447 * Set the connection state to CONN_IS_WAITING, move it to tail, and then reset the connection.
2448 * @return	0: nothing, 1: force to ignore the pkg.
2449 */
2450int except(struct u2ec_list_head *curt_pos, PIRP_SAVE pirp_save, int flag_test)
2451{
2452	PURB		purb = (PURB)pirp_save->Buffer;
2453	PURB_64		purb_64 = (PURB_64)pirp_save->Buffer;
2454	static time_t	toolbox_time = 0;
2455	static u_long	except_ip = 0;
2456	static u_long	except_ip_epson = 0;
2457
2458	if (Is_HP) {
2459		if (except_ip == ((PCONNECTION_INFO)curt_pos)->ip.s_addr && time((time_t*)NULL) - toolbox_time < 2) {
2460			((PCONNECTION_INFO)curt_pos)->busy = CONN_IS_WAITING;
2461			return 1;
2462		}
2463	
2464		if (count_bulk_read_ret0_2 >= 29) {
2465			count_bulk_read = 0;
2466			count_bulk_write = 0;
2467			if (Is_HP_LaserJet) {			// HP LaserJet 33xx series
2468				PDEBUG("HP LaserJet 3390 minotor pkt: detecting...\n");
2469				except_ip = ((PCONNECTION_INFO)curt_pos)->ip.s_addr;
2470				toolbox_time = time((time_t*)NULL);
2471	
2472				if (!flag_test)
2473				{
2474					((PCONNECTION_INFO)curt_pos)->busy = CONN_IS_WAITING;
2475					u2ec_list_del(curt_pos);
2476					u2ec_list_add_tail(curt_pos, &conn_info_list);
2477	
2478					int u2ec_fifo = open(U2EC_FIFO, O_WRONLY|O_NONBLOCK);
2479					write(u2ec_fifo, "c", 1);
2480					close(u2ec_fifo);
2481				}
2482	
2483				return 1;
2484			}
2485			else if (Is_HP_OfficeJet) {		// HP OfficeJet 56xx series
2486				count_bulk_read_ret0_1 = 0;
2487				count_bulk_read_ret0_2 = 0;
2488				return 3;
2489			}
2490		}
2491	}
2492
2493	if (	pirp_save->StackLocation.MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL &&
2494		(	(	pirp_save->Is64 == 0 &&
2495				purb->UrbHeader.Function == URB_FUNCTION_CLASS_INTERFACE &&
2496				USBD_TRANSFER_DIRECTION(purb->UrbBulkOrInterruptTransfer.TransferFlags) == USBD_TRANSFER_DIRECTION_IN
2497			)	||
2498			(	pirp_save->Is64 == 1 &&
2499				purb_64->UrbHeader.Function == URB_FUNCTION_CLASS_INTERFACE &&
2500				USBD_TRANSFER_DIRECTION(purb_64->UrbBulkOrInterruptTransfer.TransferFlags) == USBD_TRANSFER_DIRECTION_IN
2501			)
2502		)
2503	) {
2504		if (((PCONNECTION_INFO)curt_pos)->count_class_int_in >= 3) {
2505			if (Is_HP)	// HP DeskJet 39xx series
2506			{
2507				PDEBUG("bypass class int. in pkt!\n");
2508				return 4;
2509			}
2510			else if (Is_Canon)
2511			{
2512				PDEBUG("Canon minotor pkt: got it!\n");
2513				flag_canon_monitor = 0;
2514				((PCONNECTION_INFO)curt_pos)->count_class_int_in = 0;
2515
2516				if (!flag_test)
2517				{
2518					((PCONNECTION_INFO)curt_pos)->busy = CONN_IS_WAITING;
2519					u2ec_list_del(curt_pos);
2520					u2ec_list_add_tail(curt_pos, &conn_info_list);
2521
2522					int u2ec_fifo = open(U2EC_FIFO, O_WRONLY|O_NONBLOCK);
2523					write(u2ec_fifo, "c", 1);
2524					close(u2ec_fifo);
2525				}
2526
2527				return 1;
2528			}
2529		}
2530
2531		if (Is_EPSON && count_bulk_read_epson == 3) {
2532			if (((PCONNECTION_INFO)curt_pos)->busy != CONN_IS_BUSY)
2533				return 0;
2534			if (except_ip_epson != ((PCONNECTION_INFO)curt_pos)->ip.s_addr) {
2535				except_ip_epson = ((PCONNECTION_INFO)curt_pos)->ip.s_addr;
2536				count_bulk_read_epson = 0;
2537				flag_monitor_epson = -1;
2538			}
2539			PDEBUG("EPSON minotor pkt: detecting...\n");
2540			if (++flag_monitor_epson == 4) {
2541				PDEBUG("EPSON minotor pkt: got it!\n");
2542				count_bulk_read_epson = 0;
2543				flag_monitor_epson = 0;
2544
2545				if (!flag_test)
2546				{
2547					((PCONNECTION_INFO)curt_pos)->busy = CONN_IS_WAITING;
2548					u2ec_list_del(curt_pos);
2549					u2ec_list_add_tail(curt_pos, &conn_info_list);
2550
2551					int u2ec_fifo = open(U2EC_FIFO, O_WRONLY|O_NONBLOCK);
2552					write(u2ec_fifo, "c", 1);
2553					close(u2ec_fifo);
2554				}
2555
2556				return 1;
2557			}
2558		} else
2559			count_bulk_read_epson = 0;
2560	}
2561	else if ( 	(Is_HP || Is_Canon) &&
2562			pirp_save->StackLocation.MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL &&
2563			(	(pirp_save->Is64 == 0 && purb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) ||
2564				(pirp_save->Is64 == 1 && purb_64->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER)
2565			)
2566	)	return 2;
2567
2568	return 0;
2569}
2570
2571/*
2572 * Response USB connections from client.
2573 * TCP protocol.
2574 */
2575int usb_connection(int sockfd)
2576{
2577	TCP_PACKAGE		tcp_pack;
2578	PIRP_SAVE		pirp_save, pirp_saverw;
2579	PCONNECTION_INFO	conn_curt, conn_busy;
2580	struct u2ec_list_head	*pos;
2581	int			i, j, except_flag = 0, except_flag_1client = 0, u2ec_fifo;
2582#if __BYTE_ORDER == __BIG_ENDIAN
2583	PURB		purb;
2584	PURB_64		purb_64;
2585
2586	char *tmp;
2587	int tmp_len;
2588#endif
2589
2590	if (!sockfd || !fd_in_use[sockfd])
2591	{
2592		PDEBUG("closed connection, return\n");
2593		return -1;
2594	}
2595
2596	conn_curt = conn_busy = (PCONNECTION_INFO)&conn_info_list;
2597	u2ec_list_for_each(pos, &conn_info_list) {
2598		if (((PCONNECTION_INFO)pos)->sockfd == sockfd)
2599			conn_curt = (PCONNECTION_INFO)pos;
2600		if (((PCONNECTION_INFO)pos)->busy == CONN_IS_BUSY)
2601			conn_busy = (PCONNECTION_INFO)pos;
2602	}
2603
2604	if (conn_curt->ip.s_addr == 0)
2605	{
2606		PDEBUG("empty connection, ip:%s\n", inet_ntoa(conn_curt->ip));
2607		return -sockfd;
2608	}
2609
2610	/* Recv tcp_pack and close the socket if necessary. */
2611	bzero(&tcp_pack, sizeof(tcp_pack));
2612	if ((i = recv(sockfd, (char *)&tcp_pack, sizeof(tcp_pack), 0)) == sizeof(tcp_pack)) {
2613#if __BYTE_ORDER == __BIG_ENDIAN
2614		tcp_pack.Type = SWAP32(tcp_pack.Type);
2615		tcp_pack.SizeBuffer = SWAP32(tcp_pack.SizeBuffer);
2616#endif
2617		PSNDRECV("\nReceived from fd: %d tcp_pack: type %d , size %d.\n", sockfd, tcp_pack.Type, tcp_pack.SizeBuffer);
2618	} else {	// got error or connection closed by client
2619		if (i < 0)
2620			PERROR("recv");
2621		else if (i == 0)  // connection closed
2622			PDEBUG("usb_connection: socket %d hung up\n", sockfd);
2623		goto CLOSE_CONN;
2624	}
2625
2626	switch (tcp_pack.Type) {
2627	case ControlPing:
2628		break;
2629	case IrpToTcp:
2630		bzero(data_buf, MAX_BUF_LEN);
2631		pirp_save = (PIRP_SAVE)data_buf;
2632		for (i = 0, j = 0; i < tcp_pack.SizeBuffer; i += j)
2633			j = recv(sockfd, (char *)pirp_save + i, tcp_pack.SizeBuffer - i, 0);
2634
2635#if __BYTE_ORDER == __BIG_ENDIAN
2636		pirp_save->Size = SWAP32(pirp_save->Size);
2637		pirp_save->NeedSize = SWAP32(pirp_save->NeedSize);
2638		pirp_save->Device = SWAP64(pirp_save->Device);
2639		pirp_save->Irp = SWAP32(pirp_save->Irp);
2640		pirp_save->Status = SWAP32(pirp_save->Status);
2641		pirp_save->Information = SWAP64(pirp_save->Information);
2642		pirp_save->Cancel = SWAP32(pirp_save->Cancel);
2643		pirp_save->StackLocation.empty = SWAP64(pirp_save->StackLocation.empty);
2644		pirp_save->StackLocation.Parameters.Others.Argument1 = SWAP64(pirp_save->StackLocation.Parameters.Others.Argument1);
2645		pirp_save->StackLocation.Parameters.Others.Argument2 = SWAP64(pirp_save->StackLocation.Parameters.Others.Argument2);
2646		pirp_save->StackLocation.Parameters.Others.Argument3 = SWAP64(pirp_save->StackLocation.Parameters.Others.Argument3);
2647		pirp_save->StackLocation.Parameters.Others.Argument4 = SWAP64(pirp_save->StackLocation.Parameters.Others.Argument4);
2648		pirp_save->BufferSize = SWAP32(pirp_save->BufferSize);
2649		pirp_save->Reserv = SWAP32(pirp_save->Reserv);
2650
2651		if (pirp_save->StackLocation.MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
2652		{
2653			if (pirp_save->Is64 == 0)
2654			{
2655				purb = (PURB)pirp_save->Buffer;
2656				purb->UrbHeader.Length = SWAP16(purb->UrbHeader.Length);
2657				purb->UrbHeader.Function = SWAP16(purb->UrbHeader.Function);
2658				purb->UrbHeader.Status = SWAP32(purb->UrbHeader.Status);
2659				purb->UrbHeader.UsbdDeviceHandle = SWAP32(purb->UrbHeader.UsbdDeviceHandle);
2660				purb->UrbHeader.UsbdFlags = SWAP32(purb->UrbHeader.UsbdFlags);
2661
2662				if (purb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE ||
2663				    purb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE ||
2664				    purb->UrbHeader.Function ==  0x2a	// _URB_OS_FEATURE_DESCRIPTOR_REQUEST_FULL
2665				)
2666				{
2667					purb->UrbControlDescriptorRequest.Reserved = SWAP32(purb->UrbControlDescriptorRequest.Reserved);
2668					purb->UrbControlDescriptorRequest.Reserved0 = SWAP32(purb->UrbControlDescriptorRequest.Reserved0);
2669					purb->UrbControlDescriptorRequest.TransferBufferLength = SWAP32(purb->UrbControlDescriptorRequest.TransferBufferLength);
2670					purb->UrbControlDescriptorRequest.TransferBuffer = SWAP32(purb->UrbControlDescriptorRequest.TransferBuffer);
2671					purb->UrbControlDescriptorRequest.TransferBufferMDL = SWAP32(purb->UrbControlDescriptorRequest.TransferBufferMDL);
2672					purb->UrbControlDescriptorRequest.UrbLink = SWAP32(purb->UrbControlDescriptorRequest.UrbLink);
2673
2674					purb->UrbControlDescriptorRequest.hca.HcdEndpoint = SWAP32(purb->UrbControlDescriptorRequest.hca.HcdEndpoint);
2675					purb->UrbControlDescriptorRequest.hca.HcdIrp = SWAP32(purb->UrbControlDescriptorRequest.hca.HcdIrp);
2676					purb->UrbControlDescriptorRequest.hca.HcdListEntry.Flink = SWAP32(purb->UrbControlDescriptorRequest.hca.HcdListEntry.Flink);
2677					purb->UrbControlDescriptorRequest.hca.HcdListEntry.Blink = SWAP32(purb->UrbControlDescriptorRequest.hca.HcdListEntry.Blink);
2678					purb->UrbControlDescriptorRequest.hca.HcdListEntry2.Flink = SWAP32(purb->UrbControlDescriptorRequest.hca.HcdListEntry2.Flink);
2679					purb->UrbControlDescriptorRequest.hca.HcdListEntry2.Blink = SWAP32(purb->UrbControlDescriptorRequest.hca.HcdListEntry2.Blink);
2680					purb->UrbControlDescriptorRequest.hca.HcdCurrentIoFlushPointer = SWAP32(purb->UrbControlDescriptorRequest.hca.HcdCurrentIoFlushPointer);
2681					purb->UrbControlDescriptorRequest.hca.HcdExtension = SWAP32(purb->UrbControlDescriptorRequest.hca.HcdExtension);
2682
2683					purb->UrbControlDescriptorRequest.Reserved1 = SWAP16(purb->UrbControlDescriptorRequest.Reserved1);
2684					purb->UrbControlDescriptorRequest.Reserved2 = SWAP16(purb->UrbControlDescriptorRequest.Reserved2);
2685					purb->UrbControlDescriptorRequest.LanguageId = SWAP16(purb->UrbControlDescriptorRequest.LanguageId);
2686				}
2687				else if (purb->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
2688				{
2689					purb->UrbSelectConfiguration.ConfigurationDescriptor = SWAP32(purb->UrbSelectConfiguration.ConfigurationDescriptor);
2690					purb->UrbSelectConfiguration.ConfigurationHandle = SWAP32(purb->UrbSelectConfiguration.ConfigurationHandle);
2691
2692					if (purb->UrbSelectConfiguration.ConfigurationDescriptor != 0x0)
2693					{
2694						tmp = (char*)&(purb->UrbSelectConfiguration.Interface);
2695						tmp_len = purb->UrbHeader.Length - 24;
2696				
2697						for (i = 0; tmp_len > 0; i++) {
2698							(*(USBD_INTERFACE_INFORMATION*)tmp).Length = SWAP16((*(USBD_INTERFACE_INFORMATION*)tmp).Length);
2699							(*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle);
2700							(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes);
2701
2702							for (j = 0; j < (*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes; j++) {
2703								(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize = SWAP16((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize);
2704								(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle);
2705								(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize);
2706								(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags);
2707							}
2708							tmp_len -= (*(USBD_INTERFACE_INFORMATION*)tmp).Length;
2709							tmp += (*(USBD_INTERFACE_INFORMATION*)tmp).Length;
2710						}
2711					}
2712				}
2713				else if (purb->UrbHeader.Function == URB_FUNCTION_SELECT_INTERFACE)
2714				{
2715					purb->UrbSelectInterface.ConfigurationHandle = SWAP32(purb->UrbSelectInterface.ConfigurationHandle);
2716					tmp = (char*)&(purb->UrbSelectInterface.Interface);
2717
2718					(*(USBD_INTERFACE_INFORMATION*)tmp).Length = SWAP16((*(USBD_INTERFACE_INFORMATION*)tmp).Length);
2719					(*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle);
2720					(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes);
2721
2722					for (j = 0; j < (*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes; j++) {
2723						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize = SWAP16((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize);
2724						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle);
2725						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize);
2726						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags);
2727					}
2728				}
2729				else if (purb->UrbHeader.Function == URB_FUNCTION_CLASS_INTERFACE ||
2730					 purb->UrbHeader.Function == URB_FUNCTION_CLASS_OTHER
2731				)
2732				{
2733					purb->UrbControlVendorClassRequest.Reserved = SWAP32(purb->UrbControlVendorClassRequest.Reserved);
2734					purb->UrbControlVendorClassRequest.TransferFlags = SWAP32(purb->UrbControlVendorClassRequest.TransferFlags);
2735					purb->UrbControlVendorClassRequest.TransferBufferLength = SWAP32(purb->UrbControlVendorClassRequest.TransferBufferLength);
2736					purb->UrbControlVendorClassRequest.TransferBuffer = SWAP32(purb->UrbControlVendorClassRequest.TransferBuffer);
2737					purb->UrbControlVendorClassRequest.TransferBufferMDL = SWAP32(purb->UrbControlVendorClassRequest.TransferBufferMDL);
2738					purb->UrbControlVendorClassRequest.UrbLink = SWAP32(purb->UrbControlVendorClassRequest.UrbLink);
2739
2740					purb->UrbControlVendorClassRequest.hca.HcdEndpoint = SWAP32(purb->UrbControlVendorClassRequest.hca.HcdEndpoint);
2741					purb->UrbControlVendorClassRequest.hca.HcdIrp = SWAP32(purb->UrbControlVendorClassRequest.hca.HcdIrp);
2742					purb->UrbControlVendorClassRequest.hca.HcdListEntry.Flink = SWAP32(purb->UrbControlVendorClassRequest.hca.HcdListEntry.Flink);
2743					purb->UrbControlVendorClassRequest.hca.HcdListEntry.Blink = SWAP32(purb->UrbControlVendorClassRequest.hca.HcdListEntry.Blink);
2744					purb->UrbControlVendorClassRequest.hca.HcdListEntry2.Flink = SWAP32(purb->UrbControlVendorClassRequest.hca.HcdListEntry2.Flink);
2745					purb->UrbControlVendorClassRequest.hca.HcdListEntry2.Blink = SWAP32(purb->UrbControlVendorClassRequest.hca.HcdListEntry2.Blink);
2746					purb->UrbControlVendorClassRequest.hca.HcdCurrentIoFlushPointer = SWAP32(purb->UrbControlVendorClassRequest.hca.HcdCurrentIoFlushPointer);
2747					purb->UrbControlVendorClassRequest.hca.HcdExtension = SWAP32(purb->UrbControlVendorClassRequest.hca.HcdExtension);
2748
2749					purb->UrbControlVendorClassRequest.Value = SWAP16(purb->UrbControlVendorClassRequest.Value);
2750					purb->UrbControlVendorClassRequest.Index = SWAP16(purb->UrbControlVendorClassRequest.Index);
2751					purb->UrbControlVendorClassRequest.Reserved1 = SWAP16(purb->UrbControlVendorClassRequest.Reserved1);
2752				}
2753				else if (purb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER)
2754				{
2755					purb->UrbBulkOrInterruptTransfer.PipeHandle = SWAP32(purb->UrbBulkOrInterruptTransfer.PipeHandle);
2756					purb->UrbBulkOrInterruptTransfer.TransferFlags = SWAP32(purb->UrbBulkOrInterruptTransfer.TransferFlags);
2757					purb->UrbBulkOrInterruptTransfer.TransferBufferLength = SWAP32(purb->UrbBulkOrInterruptTransfer.TransferBufferLength);
2758					purb->UrbBulkOrInterruptTransfer.TransferBuffer = SWAP32(purb->UrbBulkOrInterruptTransfer.TransferBuffer);
2759					purb->UrbBulkOrInterruptTransfer.TransferBufferMDL = SWAP32(purb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
2760					purb->UrbBulkOrInterruptTransfer.UrbLink = SWAP32(purb->UrbBulkOrInterruptTransfer.UrbLink);
2761					purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint = SWAP32(purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint);
2762					purb->UrbBulkOrInterruptTransfer.hca.HcdIrp = SWAP32(purb->UrbBulkOrInterruptTransfer.hca.HcdIrp);
2763					purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry.Flink = SWAP32(purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry.Flink);
2764					purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry.Blink = SWAP32(purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry.Blink);
2765					purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry2.Flink = SWAP32(purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry2.Flink);
2766					purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry2.Blink = SWAP32(purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry2.Blink);
2767					purb->UrbBulkOrInterruptTransfer.hca.HcdCurrentIoFlushPointer = SWAP32(purb->UrbBulkOrInterruptTransfer.hca.HcdCurrentIoFlushPointer);
2768					purb->UrbBulkOrInterruptTransfer.hca.HcdExtension = SWAP32(purb->UrbBulkOrInterruptTransfer.hca.HcdExtension);
2769				}
2770				else if (purb->UrbHeader.Function == URB_FUNCTION_ABORT_PIPE ||
2771					 purb->UrbHeader.Function == URB_FUNCTION_RESET_PIPE
2772				)
2773				{
2774					purb->UrbPipeRequest.PipeHandle = SWAP32(purb->UrbPipeRequest.PipeHandle);
2775				}
2776			}
2777			else
2778			{
2779				purb_64 = (PURB_64)pirp_save->Buffer;
2780
2781				purb_64->UrbHeader.Length = SWAP16(purb_64->UrbHeader.Length);
2782				purb_64->UrbHeader.Function = SWAP16(purb_64->UrbHeader.Function);
2783				purb_64->UrbHeader.Status = SWAP32(purb_64->UrbHeader.Status);
2784				purb_64->UrbHeader.UsbdDeviceHandle = SWAP64(purb_64->UrbHeader.UsbdDeviceHandle);
2785				purb_64->UrbHeader.UsbdFlags = SWAP32(purb_64->UrbHeader.UsbdFlags);
2786
2787				if (purb_64->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE ||
2788				    purb_64->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE ||
2789				    purb_64->UrbHeader.Function == 0x2a	// _URB_OS_FEATURE_DESCRIPTOR_REQUEST_FULL
2790				)
2791				{
2792					purb_64->UrbControlDescriptorRequest.Reserved = SWAP64(purb_64->UrbControlDescriptorRequest.Reserved);
2793					purb_64->UrbControlDescriptorRequest.Reserved0 = SWAP32(purb_64->UrbControlDescriptorRequest.Reserved0);
2794					purb_64->UrbControlDescriptorRequest.TransferBufferLength = SWAP32(purb_64->UrbControlDescriptorRequest.TransferBufferLength);
2795					purb_64->UrbControlDescriptorRequest.TransferBuffer = SWAP64(purb_64->UrbControlDescriptorRequest.TransferBuffer);
2796					purb_64->UrbControlDescriptorRequest.TransferBufferMDL = SWAP64(purb_64->UrbControlDescriptorRequest.TransferBufferMDL);
2797					purb_64->UrbControlDescriptorRequest.UrbLink = SWAP64(purb_64->UrbControlDescriptorRequest.UrbLink);
2798
2799					purb_64->UrbControlDescriptorRequest.hca.Reserved8[0] = SWAP64(purb_64->UrbControlDescriptorRequest.hca.Reserved8[0]);
2800					purb_64->UrbControlDescriptorRequest.hca.Reserved8[1] = SWAP64(purb_64->UrbControlDescriptorRequest.hca.Reserved8[1]);
2801					purb_64->UrbControlDescriptorRequest.hca.Reserved8[2] = SWAP64(purb_64->UrbControlDescriptorRequest.hca.Reserved8[2]);
2802					purb_64->UrbControlDescriptorRequest.hca.Reserved8[3] = SWAP64(purb_64->UrbControlDescriptorRequest.hca.Reserved8[3]);
2803					purb_64->UrbControlDescriptorRequest.hca.Reserved8[4] = SWAP64(purb_64->UrbControlDescriptorRequest.hca.Reserved8[4]);
2804					purb_64->UrbControlDescriptorRequest.hca.Reserved8[5] = SWAP64(purb_64->UrbControlDescriptorRequest.hca.Reserved8[5]);
2805					purb_64->UrbControlDescriptorRequest.hca.Reserved8[6] = SWAP64(purb_64->UrbControlDescriptorRequest.hca.Reserved8[6]);
2806					purb_64->UrbControlDescriptorRequest.hca.Reserved8[7] = SWAP64(purb_64->UrbControlDescriptorRequest.hca.Reserved8[7]);
2807
2808					purb_64->UrbControlDescriptorRequest.Reserved1 = SWAP16(purb_64->UrbControlDescriptorRequest.Reserved1);
2809					purb_64->UrbControlDescriptorRequest.Reserved2 = SWAP16(purb_64->UrbControlDescriptorRequest.Reserved2);
2810					purb_64->UrbControlDescriptorRequest.LanguageId = SWAP16(purb_64->UrbControlDescriptorRequest.LanguageId);
2811				}
2812				else if (purb_64->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
2813				{
2814					purb_64->UrbSelectConfiguration.ConfigurationDescriptor = SWAP64(purb_64->UrbSelectConfiguration.ConfigurationDescriptor);
2815					purb_64->UrbSelectConfiguration.ConfigurationHandle = SWAP64(purb_64->UrbSelectConfiguration.ConfigurationHandle);
2816
2817					if (purb_64->UrbSelectConfiguration.ConfigurationDescriptor != 0x0)
2818					{
2819						tmp = (char*)&(purb_64->UrbSelectConfiguration.Interface);
2820						tmp_len = purb_64->UrbHeader.Length - 0x28;
2821
2822						for (i = 0; tmp_len > 0; i++) {
2823							(*(USBD_INTERFACE_INFORMATION_64*)tmp).Length = SWAP16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Length);
2824							(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle = SWAP64((*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle);
2825							(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes);
2826							for (j = 0; j < (*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes; j++) {
2827								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize = SWAP16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize);
2828								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType = SWAP32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType);
2829								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle = SWAP64((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle);
2830								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize = SWAP32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize);
2831								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags = SWAP32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags);
2832							}
2833							tmp_len -= (*(USBD_INTERFACE_INFORMATION_64*)tmp).Length;
2834							tmp += (*(USBD_INTERFACE_INFORMATION_64*)tmp).Length;
2835						}
2836					}
2837				}
2838				else if (purb_64->UrbHeader.Function == URB_FUNCTION_SELECT_INTERFACE)
2839				{
2840					purb_64->UrbSelectInterface.ConfigurationHandle = SWAP64(purb_64->UrbSelectInterface.ConfigurationHandle);
2841					tmp = (char*)&(purb_64->UrbSelectInterface.Interface);
2842
2843					(*(USBD_INTERFACE_INFORMATION_64*)tmp).Length = SWAP16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Length);
2844					(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle = SWAP64((*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle);
2845					(*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes = SWAP32((*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes);
2846
2847					for (j = 0; j < (*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes; j++) {
2848						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize = SWAP16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize);
2849						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType = SWAP32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType);
2850						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle = SWAP64((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle);
2851						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize = SWAP32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize);
2852						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags = SWAP32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags);
2853					}
2854				}
2855				else if (purb_64->UrbHeader.Function == URB_FUNCTION_CLASS_INTERFACE ||
2856					 purb_64->UrbHeader.Function == URB_FUNCTION_CLASS_OTHER
2857				)
2858				{
2859					purb_64->UrbControlVendorClassRequest.Reserved = SWAP64(purb_64->UrbControlVendorClassRequest.Reserved);
2860					purb_64->UrbControlVendorClassRequest.TransferFlags = SWAP32(purb_64->UrbControlVendorClassRequest.TransferFlags);
2861					purb_64->UrbControlVendorClassRequest.TransferBufferLength = SWAP32(purb_64->UrbControlVendorClassRequest.TransferBufferLength);
2862					purb_64->UrbControlVendorClassRequest.TransferBuffer = SWAP64(purb_64->UrbControlVendorClassRequest.TransferBuffer);
2863					purb_64->UrbControlVendorClassRequest.TransferBufferMDL = SWAP64(purb_64->UrbControlVendorClassRequest.TransferBufferMDL);
2864					purb_64->UrbControlVendorClassRequest.UrbLink = SWAP64(purb_64->UrbControlVendorClassRequest.UrbLink);
2865
2866					purb_64->UrbControlVendorClassRequest.hca.Reserved8[0] = SWAP64(purb_64->UrbControlVendorClassRequest.hca.Reserved8[0]);
2867					purb_64->UrbControlVendorClassRequest.hca.Reserved8[1] = SWAP64(purb_64->UrbControlVendorClassRequest.hca.Reserved8[1]);
2868					purb_64->UrbControlVendorClassRequest.hca.Reserved8[2] = SWAP64(purb_64->UrbControlVendorClassRequest.hca.Reserved8[2]);
2869					purb_64->UrbControlVendorClassRequest.hca.Reserved8[3] = SWAP64(purb_64->UrbControlVendorClassRequest.hca.Reserved8[3]);
2870					purb_64->UrbControlVendorClassRequest.hca.Reserved8[4] = SWAP64(purb_64->UrbControlVendorClassRequest.hca.Reserved8[4]);
2871					purb_64->UrbControlVendorClassRequest.hca.Reserved8[5] = SWAP64(purb_64->UrbControlVendorClassRequest.hca.Reserved8[5]);
2872					purb_64->UrbControlVendorClassRequest.hca.Reserved8[6] = SWAP64(purb_64->UrbControlVendorClassRequest.hca.Reserved8[6]);
2873					purb_64->UrbControlVendorClassRequest.hca.Reserved8[7] = SWAP64(purb_64->UrbControlVendorClassRequest.hca.Reserved8[7]);
2874
2875					purb_64->UrbControlVendorClassRequest.Value = SWAP16(purb_64->UrbControlVendorClassRequest.Value);
2876					purb_64->UrbControlVendorClassRequest.Index = SWAP16(purb_64->UrbControlVendorClassRequest.Index);
2877					purb_64->UrbControlVendorClassRequest.Reserved1 = SWAP16(purb_64->UrbControlVendorClassRequest.Reserved1);
2878				}
2879				else if (purb_64->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER)
2880				{
2881					purb_64->UrbBulkOrInterruptTransfer.PipeHandle = SWAP64(purb_64->UrbBulkOrInterruptTransfer.PipeHandle);
2882					purb_64->UrbBulkOrInterruptTransfer.TransferFlags = SWAP32(purb_64->UrbBulkOrInterruptTransfer.TransferFlags);
2883					purb_64->UrbBulkOrInterruptTransfer.TransferBufferLength = SWAP32(purb_64->UrbBulkOrInterruptTransfer.TransferBufferLength);
2884					purb_64->UrbBulkOrInterruptTransfer.TransferBuffer = SWAP64(purb_64->UrbBulkOrInterruptTransfer.TransferBuffer);
2885					purb_64->UrbBulkOrInterruptTransfer.TransferBufferMDL = SWAP64(purb_64->UrbBulkOrInterruptTransfer.TransferBufferMDL);
2886					purb_64->UrbBulkOrInterruptTransfer.UrbLink = SWAP64(purb_64->UrbBulkOrInterruptTransfer.UrbLink);					
2887					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[0] = SWAP64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[0]);
2888					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[1] = SWAP64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[1]);
2889					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[2] = SWAP64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[2]);
2890					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[3] = SWAP64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[3]);
2891					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[4] = SWAP64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[4]);
2892					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[5] = SWAP64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[5]);
2893					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[6] = SWAP64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[6]);
2894					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[7] = SWAP64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[7]);
2895				}
2896				else if (purb_64->UrbHeader.Function == URB_FUNCTION_ABORT_PIPE ||
2897					 purb_64->UrbHeader.Function == URB_FUNCTION_RESET_PIPE
2898				)
2899				{
2900					purb_64->UrbPipeRequest.PipeHandle = SWAP64(purb_64->UrbPipeRequest.PipeHandle);
2901				}
2902			}
2903		}
2904#endif
2905
2906		PDEBUG("(%d/%d) ", sockfd, pirp_save->Irp);
2907
2908		conn_curt->irp = pirp_save->Irp;
2909
2910		if (ip_monopoly.s_addr)
2911		{
2912			if (conn_curt->ip.s_addr == ip_monopoly.s_addr)
2913			{
2914				time_monopoly = time((time_t*)NULL);
2915				if (conn_busy != conn_curt)
2916				{
2917					last_busy_conn = conn_curt;
2918					conn_busy->busy = CONN_IS_IDLE;
2919					conn_curt->busy = CONN_IS_BUSY;
2920					nvram_set("u2ec_busyip", inet_ntoa(conn_curt->ip));
2921					conn_busy = conn_curt;
2922				}
2923			}
2924			else
2925			{
2926				PDEBUG("ignore pkt for monopoly\n");
2927
2928				u2ec_list_for_each(pos, &conn_info_list)
2929				{
2930					if (ip_monopoly.s_addr && ip_monopoly.s_addr == ((PCONNECTION_INFO)pos)->ip.s_addr)
2931						PDEBUG("ip %s, sock %d, busy %d. Monopoly.\n", inet_ntoa(((PCONNECTION_INFO)pos)->ip), ((PCONNECTION_INFO)pos)->sockfd, ((PCONNECTION_INFO)pos)->busy);
2932					else
2933						PDEBUG("ip %s, sock %d, busy %d.\n", inet_ntoa(((PCONNECTION_INFO)pos)->ip), ((PCONNECTION_INFO)pos)->sockfd, ((PCONNECTION_INFO)pos)->busy);
2934				}
2935				PDEBUG("\n");
2936
2937				conn_curt->busy = CONN_IS_WAITING;
2938				return 0;
2939			}
2940		}
2941
2942		if (conn_info_list.next->next != &conn_info_list && !ip_monopoly.s_addr) {
2943			if ((except_flag = except((struct u2ec_list_head *)conn_curt, pirp_save, 0)) == 1)
2944				return 0;
2945			else if (except_flag == 4)
2946				goto EXCHANGE_IRP;
2947		}
2948		else if ((except_flag = except((struct u2ec_list_head *)conn_curt, pirp_save, 1)) == 1 || except_flag == 4)
2949		{
2950			except_flag_1client = 1;
2951			except_flag = 0;
2952		}
2953		else
2954			except_flag = 0;
2955
2956		conn_curt->time = time((time_t*)NULL);
2957		semaphore_wait();
2958		if (conn_busy != conn_curt) {
2959			if ((i = MFP_state(MFP_GET_STATE))) {
2960				semaphore_post();
2961				if (i == MFP_IN_LPRNG)
2962					alarm(1);
2963				if (except_flag == 2) {
2964					conn_curt->busy = CONN_IS_RETRY;
2965					except_flag += 100;
2966					goto EXCHANGE_IRP;
2967				}
2968				if (conn_curt->busy != CONN_IS_RETRY)
2969					conn_curt->busy = CONN_IS_WAITING;
2970				return 0;
2971			} else {
2972				last_busy_conn = conn_curt;
2973				conn_curt->busy = CONN_IS_BUSY;
2974				nvram_set("u2ec_busyip", inet_ntoa(conn_curt->ip));
2975				if ((struct u2ec_list_head*)conn_busy != &conn_info_list)
2976					conn_busy->busy = CONN_IS_IDLE;
2977			}
2978		}
2979		if (!MFP_state(MFP_GET_STATE) && pirp_save->Irp > 0) {
2980			if (!except_flag_1client)
2981			{				
2982				MFP_state(MFP_IN_U2EC);
2983				nvram_set("u2ec_busyip", inet_ntoa(conn_curt->ip));
2984			}
2985			semaphore_post();
2986			alarm(1);
2987		} else if (MFP_state(MFP_GET_STATE) == MFP_IN_U2EC && except_flag_1client) {
2988			MFP_state(MFP_IS_IDLE);
2989			nvram_set("u2ec_busyip", "");
2990			semaphore_post();
2991		} else
2992			semaphore_post();
2993EXCHANGE_IRP:
2994		/* Fill pirp_save depend on mj & mn function in IRP. */
2995		pirp_saverw = (PIRP_SAVE)data_bufrw;
2996		memcpy(pirp_saverw, pirp_save, MAX_BUF_LEN);
2997
2998		PDECODE_IRP(pirp_save, 0);
2999		if (except_flag < 100) {
3000			if ((i = exchangeIRP(pirp_save, pirp_saverw, (struct u2ec_list_head *)conn_curt)) == 0)
3001				return 0;
3002			else if (i == -1)
3003				goto CLOSE_CONN;
3004		}
3005		else if (except_flag == 102) {
3006			if (pirp_save->Is64 == 0)
3007				handleURB_fake(pirp_saverw);
3008			else
3009				handleURB_64_fake(pirp_saverw);
3010			usleep(20000);
3011		}
3012		PDECODE_IRP(pirp_saverw, 1);
3013
3014		if (except_flag == 3)
3015			pirp_saverw->Status = 0xC00000AE;	// STATUS_PIPE_BUSY
3016
3017		/* Send tcp_pack IrpAnswerTcp. */
3018#if __BYTE_ORDER == __LITTLE_ENDIAN
3019		tcp_pack.Type = IrpAnswerTcp;
3020		tcp_pack.SizeBuffer = pirp_saverw->NeedSize;
3021#else
3022		tcp_pack.Type = SWAP_BACK32(IrpAnswerTcp);
3023		tcp_pack.SizeBuffer = SWAP_BACK32(pirp_saverw->NeedSize);
3024#endif
3025		send(sockfd, (char *)&tcp_pack, sizeof(tcp_pack), 0);
3026		PSNDRECV("usb_connection: sent tcp pack, size:%d.\n", sizeof(tcp_pack));
3027
3028		/* Send irp_save. */
3029#if __BYTE_ORDER == __LITTLE_ENDIAN
3030		send(sockfd, (char *)pirp_saverw, pirp_saverw->NeedSize, 0);
3031		PSNDRECV("usb_connection: sent pirp_saverw, size:%d.\n", pirp_saverw->NeedSize);
3032#else
3033		pirp_saverw->Size = SWAP_BACK32(pirp_saverw->Size);
3034		pirp_saverw->NeedSize = SWAP_BACK32(pirp_saverw->NeedSize);
3035		pirp_saverw->Device = SWAP_BACK64(pirp_saverw->Device);
3036		pirp_saverw->Irp = SWAP_BACK32(pirp_saverw->Irp);
3037		pirp_saverw->Status = SWAP_BACK32(pirp_saverw->Status);
3038		pirp_saverw->Information = SWAP_BACK64(pirp_saverw->Information);
3039		pirp_saverw->Cancel = SWAP_BACK32(pirp_saverw->Cancel);
3040		pirp_saverw->StackLocation.Parameters.Others.Argument1 = SWAP_BACK64(pirp_saverw->StackLocation.Parameters.Others.Argument1);
3041		pirp_saverw->StackLocation.Parameters.Others.Argument2 = SWAP_BACK64(pirp_saverw->StackLocation.Parameters.Others.Argument2);
3042		pirp_saverw->StackLocation.Parameters.Others.Argument3 = SWAP_BACK64(pirp_saverw->StackLocation.Parameters.Others.Argument3);
3043		pirp_saverw->StackLocation.Parameters.Others.Argument4 = SWAP_BACK64(pirp_saverw->StackLocation.Parameters.Others.Argument4);
3044		pirp_saverw->BufferSize = SWAP_BACK32(pirp_saverw->BufferSize);
3045		pirp_saverw->Reserv = SWAP_BACK32(pirp_saverw->Reserv);
3046
3047		if (pirp_save->StackLocation.MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
3048		{
3049			if (pirp_save->Is64 == 0)
3050			{
3051				purb = (PURB)pirp_saverw->Buffer;
3052				purb->UrbHeader.Length = SWAP_BACK16(purb->UrbHeader.Length);
3053				purb->UrbHeader.Function = SWAP_BACK16(purb->UrbHeader.Function);
3054				purb->UrbHeader.Status = SWAP_BACK32(purb->UrbHeader.Status);
3055				purb->UrbHeader.UsbdDeviceHandle = SWAP_BACK32(purb->UrbHeader.UsbdDeviceHandle);
3056				purb->UrbHeader.UsbdFlags = SWAP_BACK32(purb->UrbHeader.UsbdFlags);
3057
3058				if (((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE ||
3059				    ((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE ||
3060				    ((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_CLASS_INTERFACE ||
3061				    ((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_CLASS_OTHER ||
3062				    ((PURB)pirp_save->Buffer)->UrbHeader.Function == 0x2a	// _URB_OS_FEATURE_DESCRIPTOR_REQUEST_FULL
3063				)
3064				{
3065					purb->UrbControlTransfer.PipeHandle = SWAP_BACK32(purb->UrbControlTransfer.PipeHandle);
3066					purb->UrbControlTransfer.TransferFlags = SWAP_BACK32(purb->UrbControlTransfer.TransferFlags);
3067					purb->UrbControlTransfer.TransferBufferLength = SWAP_BACK32(purb->UrbControlTransfer.TransferBufferLength);
3068					purb->UrbControlTransfer.TransferBuffer = SWAP_BACK32(purb->UrbControlTransfer.TransferBuffer);
3069					purb->UrbControlTransfer.TransferBufferMDL = SWAP_BACK32(purb->UrbControlTransfer.TransferBufferMDL);
3070					purb->UrbControlTransfer.UrbLink = SWAP_BACK32(purb->UrbControlTransfer.UrbLink);
3071
3072					purb->UrbControlTransfer.hca.HcdEndpoint = SWAP_BACK32(purb->UrbControlTransfer.hca.HcdEndpoint);
3073					purb->UrbControlTransfer.hca.HcdIrp = SWAP_BACK32(purb->UrbControlTransfer.hca.HcdIrp);
3074					purb->UrbControlTransfer.hca.HcdListEntry.Flink = SWAP_BACK32(purb->UrbControlTransfer.hca.HcdListEntry.Flink);
3075					purb->UrbControlTransfer.hca.HcdListEntry.Blink = SWAP_BACK32(purb->UrbControlTransfer.hca.HcdListEntry.Blink);
3076					purb->UrbControlTransfer.hca.HcdListEntry2.Flink = SWAP_BACK32(purb->UrbControlTransfer.hca.HcdListEntry2.Flink);
3077					purb->UrbControlTransfer.hca.HcdListEntry2.Blink = SWAP_BACK32(purb->UrbControlTransfer.hca.HcdListEntry2.Blink);
3078					purb->UrbControlTransfer.hca.HcdCurrentIoFlushPointer = SWAP_BACK32(purb->UrbControlTransfer.hca.HcdCurrentIoFlushPointer);
3079					purb->UrbControlTransfer.hca.HcdExtension = SWAP_BACK32(purb->UrbControlTransfer.hca.HcdExtension);
3080
3081					purb->UrbControlDescriptorRequest.Reserved1 = SWAP_BACK16(purb->UrbControlDescriptorRequest.Reserved1);
3082					purb->UrbControlDescriptorRequest.Reserved2 = SWAP_BACK16(purb->UrbControlDescriptorRequest.Reserved2);
3083					purb->UrbControlDescriptorRequest.LanguageId = SWAP_BACK16(purb->UrbControlDescriptorRequest.LanguageId);
3084				}
3085				else if (((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
3086				{
3087					purb->UrbSelectConfiguration.ConfigurationDescriptor = SWAP_BACK32(purb->UrbSelectConfiguration.ConfigurationDescriptor);
3088					purb->UrbSelectConfiguration.ConfigurationHandle = SWAP_BACK32(purb->UrbSelectConfiguration.ConfigurationHandle);
3089
3090					if (SWAP32(purb->UrbSelectConfiguration.ConfigurationDescriptor) != 0x0)
3091					{
3092						tmp = (char*)&(purb->UrbSelectConfiguration.Interface);
3093						tmp_len = SWAP16(purb->UrbHeader.Length) - 24;
3094
3095						for (i = 0; tmp_len > 0; i++) {
3096							(*(USBD_INTERFACE_INFORMATION*)tmp).Length = SWAP_BACK16((*(USBD_INTERFACE_INFORMATION*)tmp).Length);
3097							(*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle);
3098							(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes);
3099
3100							for (j = 0; j < SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes); j++) {
3101								(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize = SWAP_BACK16((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize);
3102								(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle);
3103								(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize);
3104								(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags);
3105							}
3106							tmp_len -= SWAP16((*(USBD_INTERFACE_INFORMATION*)tmp).Length);
3107							tmp += SWAP16((*(USBD_INTERFACE_INFORMATION*)tmp).Length);
3108						}
3109					}
3110				}
3111				else if (((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_SELECT_INTERFACE)
3112				{
3113					purb->UrbSelectInterface.ConfigurationHandle = SWAP_BACK32(purb->UrbSelectInterface.ConfigurationHandle);
3114					tmp = (char*)&(purb->UrbSelectInterface.Interface);
3115
3116					(*(USBD_INTERFACE_INFORMATION*)tmp).Length = SWAP_BACK16((*(USBD_INTERFACE_INFORMATION*)tmp).Length);
3117					(*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).InterfaceHandle);
3118					(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes);
3119
3120					for (j = 0; j < SWAP32((*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes); j++) {
3121						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize = SWAP_BACK16((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumPacketSize);
3122						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeHandle);
3123						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].MaximumTransferSize);
3124						(*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).Pipes[j].PipeFlags);
3125					}
3126				}
3127				else if (((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER)
3128				{
3129					purb->UrbBulkOrInterruptTransfer.PipeHandle = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.PipeHandle);
3130					purb->UrbBulkOrInterruptTransfer.TransferFlags = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.TransferFlags);
3131					purb->UrbBulkOrInterruptTransfer.TransferBufferLength = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.TransferBufferLength);
3132					purb->UrbBulkOrInterruptTransfer.TransferBuffer = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.TransferBuffer);
3133					purb->UrbBulkOrInterruptTransfer.TransferBufferMDL = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
3134					purb->UrbBulkOrInterruptTransfer.UrbLink = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.UrbLink);
3135					purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.hca.HcdEndpoint);
3136					purb->UrbBulkOrInterruptTransfer.hca.HcdIrp = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.hca.HcdIrp);
3137					purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry.Flink = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry.Flink);
3138					purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry.Blink = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry.Blink);
3139					purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry2.Flink = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry2.Flink);
3140					purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry2.Blink = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.hca.HcdListEntry2.Blink);					
3141					purb->UrbBulkOrInterruptTransfer.hca.HcdCurrentIoFlushPointer = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.hca.HcdCurrentIoFlushPointer);
3142					purb->UrbBulkOrInterruptTransfer.hca.HcdExtension = SWAP_BACK32(purb->UrbBulkOrInterruptTransfer.hca.HcdExtension);
3143				}
3144				else if (((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_ABORT_PIPE ||
3145					 ((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_RESET_PIPE
3146				)
3147				{
3148					purb->UrbPipeRequest.PipeHandle = SWAP_BACK32(purb->UrbPipeRequest.PipeHandle);
3149				}
3150			}
3151			else
3152			{
3153				purb_64 = (PURB_64)pirp_saverw->Buffer;
3154
3155				purb_64->UrbHeader.Length = SWAP_BACK16(purb_64->UrbHeader.Length);
3156				purb_64->UrbHeader.Function = SWAP_BACK16(purb_64->UrbHeader.Function);
3157				purb_64->UrbHeader.Status = SWAP_BACK32(purb_64->UrbHeader.Status);
3158				purb_64->UrbHeader.UsbdDeviceHandle = SWAP_BACK64(purb_64->UrbHeader.UsbdDeviceHandle);
3159				purb_64->UrbHeader.UsbdFlags = SWAP_BACK32(purb_64->UrbHeader.UsbdFlags);
3160
3161				if (((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE ||
3162				    ((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE ||
3163				    ((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_CLASS_INTERFACE ||
3164				    ((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_CLASS_OTHER ||
3165				    ((PURB_64)pirp_save->Buffer)->UrbHeader.Function == 0x2a	// _URB_OS_FEATURE_DESCRIPTOR_REQUEST_FULL
3166				)
3167				{
3168					purb_64->UrbControlTransfer.PipeHandle = SWAP_BACK64(purb_64->UrbControlTransfer.PipeHandle);
3169					purb_64->UrbControlTransfer.TransferFlags = SWAP_BACK32(purb_64->UrbControlTransfer.TransferFlags);
3170					purb_64->UrbControlTransfer.TransferBufferLength = SWAP_BACK32(purb_64->UrbControlTransfer.TransferBufferLength);
3171					purb_64->UrbControlTransfer.TransferBuffer = SWAP_BACK64(purb_64->UrbControlTransfer.TransferBuffer);
3172					purb_64->UrbControlTransfer.TransferBufferMDL = SWAP_BACK64(purb_64->UrbControlTransfer.TransferBufferMDL);
3173					purb_64->UrbControlTransfer.UrbLink = SWAP_BACK64(purb_64->UrbControlTransfer.UrbLink);
3174
3175					purb_64->UrbControlTransfer.hca.Reserved8[0] = SWAP_BACK64(purb_64->UrbControlTransfer.hca.Reserved8[0]);
3176					purb_64->UrbControlTransfer.hca.Reserved8[1] = SWAP_BACK64(purb_64->UrbControlTransfer.hca.Reserved8[1]);
3177					purb_64->UrbControlTransfer.hca.Reserved8[2] = SWAP_BACK64(purb_64->UrbControlTransfer.hca.Reserved8[2]);
3178					purb_64->UrbControlTransfer.hca.Reserved8[3] = SWAP_BACK64(purb_64->UrbControlTransfer.hca.Reserved8[3]);
3179					purb_64->UrbControlTransfer.hca.Reserved8[4] = SWAP_BACK64(purb_64->UrbControlTransfer.hca.Reserved8[4]);
3180					purb_64->UrbControlTransfer.hca.Reserved8[5] = SWAP_BACK64(purb_64->UrbControlTransfer.hca.Reserved8[5]);
3181					purb_64->UrbControlTransfer.hca.Reserved8[6] = SWAP_BACK64(purb_64->UrbControlTransfer.hca.Reserved8[6]);
3182					purb_64->UrbControlTransfer.hca.Reserved8[7] = SWAP_BACK64(purb_64->UrbControlTransfer.hca.Reserved8[7]);
3183				}
3184				else if (((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
3185				{
3186					purb_64->UrbSelectConfiguration.ConfigurationDescriptor = SWAP_BACK64(purb_64->UrbSelectConfiguration.ConfigurationDescriptor);
3187					purb_64->UrbSelectConfiguration.ConfigurationHandle = SWAP_BACK64(purb_64->UrbSelectConfiguration.ConfigurationHandle);
3188
3189					if (purb_64->UrbSelectConfiguration.ConfigurationDescriptor != 0x0)
3190					{
3191						tmp = (char*)&(purb_64->UrbSelectConfiguration.Interface);
3192						tmp_len = SWAP16(purb_64->UrbHeader.Length) - 0x28;
3193
3194						for (i = 0; tmp_len > 0; i++) {
3195							(*(USBD_INTERFACE_INFORMATION_64*)tmp).Length = SWAP_BACK16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Length);
3196							(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle = SWAP_BACK64((*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle);
3197							(*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION*)tmp).NumberOfPipes);
3198							for (j = 0; j < SWAP32((*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes); j++) {
3199								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize = SWAP_BACK16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize);
3200								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType);
3201								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle = SWAP_BACK64((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle);
3202								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize);
3203								(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags);
3204							}
3205							tmp_len -= SWAP16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Length);
3206							tmp += SWAP16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Length);
3207						}
3208					}
3209				}
3210				else if (((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_SELECT_INTERFACE)
3211				{
3212					purb_64->UrbSelectInterface.ConfigurationHandle = SWAP_BACK64(purb_64->UrbSelectInterface.ConfigurationHandle);
3213					tmp = (char*)&(purb_64->UrbSelectInterface.Interface);
3214
3215					(*(USBD_INTERFACE_INFORMATION_64*)tmp).Length = SWAP_BACK16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Length);
3216					(*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle = SWAP_BACK64((*(USBD_INTERFACE_INFORMATION_64*)tmp).InterfaceHandle);
3217					(*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes);
3218
3219					for (j = 0; j < (*(USBD_INTERFACE_INFORMATION_64*)tmp).NumberOfPipes; j++) {
3220						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize = SWAP_BACK16((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumPacketSize);
3221						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeType);
3222						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle = SWAP_BACK64((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeHandle);
3223						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].MaximumTransferSize);
3224						(*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags = SWAP_BACK32((*(USBD_INTERFACE_INFORMATION_64*)tmp).Pipes[j].PipeFlags);
3225					}
3226				}
3227				else if (((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER)
3228				{
3229					purb_64->UrbBulkOrInterruptTransfer.PipeHandle = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.PipeHandle);
3230					purb_64->UrbBulkOrInterruptTransfer.TransferFlags = SWAP_BACK32(purb_64->UrbBulkOrInterruptTransfer.TransferFlags);
3231					purb_64->UrbBulkOrInterruptTransfer.TransferBufferLength = SWAP_BACK32(purb_64->UrbBulkOrInterruptTransfer.TransferBufferLength);
3232					purb_64->UrbBulkOrInterruptTransfer.TransferBuffer = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.TransferBuffer);
3233					purb_64->UrbBulkOrInterruptTransfer.TransferBufferMDL = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.TransferBufferMDL);
3234					purb_64->UrbBulkOrInterruptTransfer.UrbLink = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.UrbLink);					
3235					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[0] = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[0]);
3236					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[1] = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[1]);
3237					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[2] = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[2]);
3238					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[3] = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[3]);
3239					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[4] = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[4]);
3240					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[5] = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[5]);
3241					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[6] = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[6]);
3242					purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[7] = SWAP_BACK64(purb_64->UrbBulkOrInterruptTransfer.hca.Reserved8[7]);
3243				}
3244				else if (((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_ABORT_PIPE ||
3245					 ((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_RESET_PIPE
3246				)
3247				{
3248					purb_64->UrbPipeRequest.PipeHandle = SWAP_BACK32(purb_64->UrbPipeRequest.PipeHandle);
3249				}
3250			}
3251		}
3252
3253		send(sockfd, (char *)pirp_saverw, SWAP32(pirp_saverw->NeedSize), 0);
3254		PSNDRECV("usb_connection: sent pirp_saverw, size:%d.\n", SWAP32(pirp_saverw->NeedSize));
3255#endif
3256
3257		if (	Is_Canon && flag_canon_state == 3 && flag_canon_ok > 3 &&
3258			pirp_save->StackLocation.MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL &&
3259			(	(	pirp_save->Is64 == 0 &&
3260					((PURB)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
3261				)	||
3262				(	pirp_save->Is64 == 1 &&
3263					((PURB_64)pirp_save->Buffer)->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
3264				)
3265			)
3266		)
3267		{
3268			memcpy(pirp_save, data_canon, MAX_BUF_LEN);
3269			PDEBUG("retry...\n");
3270			goto EXCHANGE_IRP;
3271		}
3272
3273		break;
3274	}
3275	return 1;
3276
3277CLOSE_CONN:
3278	if (ip_monopoly.s_addr && conn_curt->ip.s_addr == ip_monopoly.s_addr)
3279	{
3280		PDEBUG("disable monopoly for closing connection\n");
3281		ip_monopoly.s_addr = 0;
3282	}
3283
3284	if (conn_busy == conn_curt) {
3285		alarm(0);
3286
3287		count_bulk_read = 0;
3288		count_bulk_write = 0;
3289		count_bulk_read_ret0_1 = 0;
3290		count_bulk_read_ret0_2 = 0;
3291		count_bulk_read_epson = 0;
3292		flag_monitor_epson = 0;
3293		flag_canon_state = 0;
3294		flag_canon_ok = 0;
3295
3296		u2ec_fifo = open(U2EC_FIFO, O_WRONLY|O_NONBLOCK);
3297		write(u2ec_fifo, "c", 1);
3298		close(u2ec_fifo);
3299	}
3300
3301	conn_curt->ip.s_addr = 0;
3302	conn_curt->count_class_int_in = 0;
3303	conn_curt->irp = 0;
3304	conn_curt->sockfd = 0;
3305
3306	u2ec_list_del((struct u2ec_list_head*)conn_curt);
3307	free(conn_curt);
3308	close(sockfd); // bye!
3309	fd_in_use[sockfd] = 0;
3310	return -sockfd;
3311}
3312
3313/*
3314 * Handle new connections.
3315 * accept them.
3316 */
3317int establish_connection(int sockfd)
3318{
3319	int		    new_fd;
3320	struct sockaddr_in  cli_addr;
3321	int		    addr_len = sizeof(cli_addr);
3322	PCONNECTION_INFO    new_conn;
3323
3324	if ((new_fd = accept(sockfd, (struct sockaddr *)&cli_addr, &addr_len)) < 0) {
3325		PERROR("accept");
3326		return -1;
3327	}
3328
3329	if (send(new_fd, "\0\0", 2, 0) < 0) {
3330		PERROR("send");
3331		return -1;
3332	}
3333	PSNDRECV("establish_connection sent successful.\n");
3334
3335	new_conn = malloc(sizeof(CONNECTION_INFO));
3336	bzero((char *)new_conn, sizeof(CONNECTION_INFO));
3337	new_conn->sockfd = new_fd;
3338	new_conn->busy = CONN_IS_IDLE;
3339	new_conn->time = time((time_t*)NULL);
3340	new_conn->ip = cli_addr.sin_addr;
3341	new_conn->count_class_int_in = 0;
3342	new_conn->irp = 0;
3343
3344	u2ec_list_add_tail((struct u2ec_list_head*)new_conn, &conn_info_list);
3345
3346	PDEBUG("establish_connection: new connection from %s on socket %d\n",
3347		inet_ntoa(cli_addr.sin_addr), new_fd);
3348
3349	return new_fd;
3350}
3351
3352static void update_device()
3353{
3354	int i;
3355	int single_interface = 1;
3356
3357	testusb();
3358
3359	if (dev) {
3360		for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
3361			if (dev->config[i].bNumInterfaces > 1) {
3362				single_interface = 0;
3363				break;
3364			}
3365#if __BYTE_ORDER == __LITTLE_ENDIAN
3366#ifdef	SUPPORT_LPRng
3367		if (nvram_match("usr_timeout", "1")) {
3368			int timeout;
3369			timeout = atoi(nvram_safe_get("usr_timeout_ctrl"));
3370			timeout_control_msg = timeout <= 0 ? 1000 : timeout;
3371			timeout = atoi(nvram_safe_get("usr_timeout_br"));
3372			timeout_bulk_read_msg = timeout <= 0 ? 5000 : timeout;
3373			timeout = atoi(nvram_safe_get("usr_timeout_bw"));
3374			timeout_bulk_write_msg = timeout <= 0 ? 5000 : timeout;
3375		} else
3376#endif
3377#endif
3378		if (Is_EPSON) {					// EPSON
3379			timeout_control_msg = 100;
3380			if (single_interface)
3381				timeout_bulk_read_msg = 5000;
3382			else
3383				timeout_bulk_read_msg = 30000;
3384			timeout_bulk_write_msg = 5000;
3385		}
3386		else if (Is_Lexmark) {				// Lexmark
3387			timeout_control_msg = 10;
3388			timeout_bulk_read_msg = 100;
3389			timeout_bulk_write_msg = 100;
3390		}
3391		else if (Is_HP) {				// HP
3392			timeout_control_msg = 1000;
3393			if (dev->descriptor.idProduct == 0x4117)// HP LaserJet 1018 
3394				timeout_bulk_read_msg =1000;
3395			else if (single_interface)
3396				timeout_bulk_read_msg = 5000;
3397			else
3398				timeout_bulk_read_msg = 15000;
3399
3400//			timeout_bulk_write_msg = 5000;
3401			timeout_bulk_write_msg = 32767;		// magic number for no timeout
3402		}
3403		else if (Is_Canon) {				// Canon
3404			timeout_control_msg = 100;
3405			timeout_bulk_read_msg = 30000;
3406			timeout_bulk_write_msg = 1000;
3407		}
3408		else {						// for general printers
3409			timeout_control_msg = 1000;
3410			if (single_interface)
3411				timeout_bulk_read_msg = 5000;
3412			else
3413				timeout_bulk_read_msg = 10000;
3414			timeout_bulk_write_msg = 5000;
3415		}
3416	}
3417	PDEBUG("\ntimeout_control_msg:%d\ntimeout_bulk_read_msg:%d\ntimeout_bulk_write_msg:%d\n",
3418		  timeout_control_msg,    timeout_bulk_read_msg,    timeout_bulk_write_msg);
3419}
3420
3421/*
3422 * alarm handle.
3423 * Only there is a busy connection, the alarm runs.
3424 */
3425static void mulit_client()
3426{
3427	struct u2ec_list_head	*pos;
3428	u2ec_list_for_each(pos, &conn_info_list)
3429	{
3430		if (ip_monopoly.s_addr && ip_monopoly.s_addr == ((PCONNECTION_INFO)pos)->ip.s_addr)
3431			PDEBUG("ip %s, sock %d, busy %d. Monopoly.\n", inet_ntoa(((PCONNECTION_INFO)pos)->ip), ((PCONNECTION_INFO)pos)->sockfd, ((PCONNECTION_INFO)pos)->busy);
3432		else
3433			PDEBUG("ip %s, sock %d, busy %d.\n", inet_ntoa(((PCONNECTION_INFO)pos)->ip), ((PCONNECTION_INFO)pos)->sockfd, ((PCONNECTION_INFO)pos)->busy);
3434	}
3435	PDEBUG("\n");
3436
3437	alarm(1);
3438	if (time((time_t*)NULL) - last_busy_conn->time > U2EC_TIMEOUT) {
3439		PDEBUG(" U2EC TIMEOUT!\n");
3440
3441		alarm(0);
3442		int u2ec_fifo = open(U2EC_FIFO, O_WRONLY|O_NONBLOCK);
3443		write(u2ec_fifo, "c", 1);
3444		close(u2ec_fifo);
3445	}
3446}
3447
3448/*
3449 * Handle fifo used by hotplug_usb and mulit_client.
3450 * modify fd_set master_fds if necessary.
3451 */
3452static int handle_fifo(int *fd, fd_set *pfds, int *pfdm, int conn_fd)
3453{
3454	struct u2ec_list_head	*pos, *tmp;
3455	char			c;
3456	int			rtvl = 0;
3457	int			need_to_udpate_device = 0;
3458
3459	/* Read & reset fifo. */
3460	read(*fd, &c, 1);
3461	close(*fd);
3462	FD_CLR(*fd, pfds);
3463
3464	semaphore_wait();
3465	/* Handle hotplug usb. */
3466	if (c == 'a') {		// add usb device.
3467		if (time((time_t*)NULL) - time_add_device < 1)
3468		{
3469			PDEBUG("time interval for updating is too small!\n");
3470			goto CANCEL;
3471		}
3472		else
3473			time_add_device = time((time_t*)NULL);
3474
3475		hotplug_debug("u2ec adding...\n");
3476		MFP_state(MFP_IS_IDLE);
3477		nvram_set("u2ec_busyip", "");
3478		update_device();
3479		FD_SET(conn_fd, pfds);
3480		*pfdm = conn_fd > *pfdm ? conn_fd : *pfdm;
3481		rtvl = 1;
3482	}
3483	else if (c == 'r') {	// remove usb device.
3484		if (time((time_t*)NULL) - time_remove_device < 1)
3485		{
3486			PDEBUG("time interval for updating is too small!\n");
3487			goto CANCEL;
3488		}
3489		else
3490			time_remove_device = time((time_t*)NULL);
3491
3492		hotplug_debug("u2ec removing...\n");
3493		alarm(0);
3494		MFP_state(MFP_IS_IDLE);
3495		nvram_set("u2ec_busyip", "");
3496		update_device();
3497		if (!dev)
3498		{
3499			PDEBUG("\nReset connection for removing\n");
3500			u2ec_list_for_each_safe(pos, tmp, &conn_info_list) {
3501				close(((PCONNECTION_INFO)pos)->sockfd);
3502				fd_in_use[((PCONNECTION_INFO)pos)->sockfd] = 0;
3503				((PCONNECTION_INFO)pos)->sockfd = 0;
3504				((PCONNECTION_INFO)pos)->ip.s_addr = 0;
3505				u2ec_list_del(pos);
3506				free(pos);
3507			}
3508		}
3509		FD_ZERO(pfds);
3510		*pfdm = 0;
3511		rtvl = 1;
3512	}
3513	/* Handle mulit client. */
3514	else if (c == 'c') {	// connect reset.
3515		switch(MFP_state(MFP_GET_STATE)) {
3516		case MFP_IN_LPRNG:
3517			alarm(1);
3518			break;
3519		case MFP_IN_U2EC:
3520			MFP_state(MFP_IS_IDLE);
3521			nvram_set("u2ec_busyip", "");
3522			u2ec_list_for_each(pos, &conn_info_list) {
3523				if (((PCONNECTION_INFO)pos)->busy == CONN_IS_BUSY)
3524					((PCONNECTION_INFO)pos)->busy = CONN_IS_IDLE;
3525			}
3526		case MFP_IS_IDLE:
3527			u2ec_list_for_each_safe(pos, tmp, &conn_info_list) {
3528				if (((PCONNECTION_INFO)pos)->busy == CONN_IS_RETRY) {
3529					last_busy_conn = (PCONNECTION_INFO)pos;
3530					((PCONNECTION_INFO)pos)->busy = CONN_IS_BUSY;
3531					nvram_set("u2ec_busyip", inet_ntoa(((PCONNECTION_INFO)pos)->ip));
3532					break;
3533				}
3534				else if (((PCONNECTION_INFO)pos)->busy == CONN_IS_WAITING) {
3535					PDEBUG("\nReset connection.\n");
3536					count_bulk_read = 0;
3537					count_bulk_write = 0;
3538					count_bulk_read_ret0_1 = 0;
3539					count_bulk_read_ret0_2 = 0;
3540					count_bulk_read_epson = 0;
3541					flag_monitor_epson = 0;
3542					flag_canon_state = 0;
3543					flag_canon_ok = 0;
3544					((PCONNECTION_INFO)pos)->count_class_int_in = 0;
3545					((PCONNECTION_INFO)pos)->ip.s_addr = 0;
3546					((PCONNECTION_INFO)pos)->irp = 0;
3547					FD_CLR(((PCONNECTION_INFO)pos)->sockfd, pfds);
3548					close(((PCONNECTION_INFO)pos)->sockfd);
3549					fd_in_use[((PCONNECTION_INFO)pos)->sockfd] = 0;
3550					((PCONNECTION_INFO)pos)->sockfd = 0;
3551					u2ec_list_del(pos);
3552					free(pos);
3553					break;
3554				}
3555			}
3556		}
3557
3558		u2ec_list_for_each_safe(pos, tmp, &conn_info_list) {
3559			if (((PCONNECTION_INFO)pos)->irp == 0xc && (time((time_t*)NULL) - ((PCONNECTION_INFO)pos)->time) > U2EC_TIMEOUT) {
3560				if (!need_to_udpate_device)
3561					need_to_udpate_device = 1;
3562
3563				PDEBUG("\nReset connection for irp number 0xc.\n");
3564				count_bulk_read = 0;
3565				count_bulk_write = 0;
3566				count_bulk_read_ret0_1 = 0;
3567				count_bulk_read_ret0_2 = 0;
3568				count_bulk_read_epson = 0;
3569				flag_monitor_epson = 0;
3570				flag_canon_state = 0;
3571				flag_canon_ok = 0;
3572				((PCONNECTION_INFO)pos)->count_class_int_in = 0;
3573				((PCONNECTION_INFO)pos)->ip.s_addr = 0;
3574				((PCONNECTION_INFO)pos)->irp = 0;
3575				FD_CLR(((PCONNECTION_INFO)pos)->sockfd, pfds);
3576				close(((PCONNECTION_INFO)pos)->sockfd);
3577				fd_in_use[((PCONNECTION_INFO)pos)->sockfd] = 0;
3578				((PCONNECTION_INFO)pos)->sockfd = 0;
3579				u2ec_list_del(pos);
3580				free(pos);
3581			}
3582		}
3583		if (need_to_udpate_device)
3584		{
3585			hotplug_debug("u2ec updating device for irp number 0xc...\n");
3586			update_device();
3587		}
3588	}
3589	/* Requeue such that the connection from specific ip address could be next busy one. */
3590#ifdef	SUPPORT_LPRng
3591	else if (c == 'q') {
3592		int count_move = 0;
3593		struct in_addr ip_requeue;
3594		struct u2ec_list_head	*pos_tmp, *pos_first = NULL, *pos_with_specific_ip = NULL;
3595	
3596		if (nvram_match("mfp_ip_requeue", ""))
3597			PDEBUG("ip for requeuing: invalid ip address!\n");
3598		else {
3599			PDEBUG("ip for requeuing: %s\n", nvram_safe_get("mfp_ip_requeue"));
3600			inet_aton(nvram_safe_get("mfp_ip_requeue"), &ip_requeue);
3601		}
3602	
3603		u2ec_list_for_each(pos, &conn_info_list) {
3604			if (((PCONNECTION_INFO)pos)->ip.s_addr == ip_requeue.s_addr) {
3605				pos_with_specific_ip = pos;
3606				break;
3607			}
3608		}
3609	
3610		if (pos_with_specific_ip != NULL) {
3611			u2ec_list_for_each(pos, &conn_info_list) {
3612				if (++count_move == 1) {
3613					pos_first = pos;
3614					if (((PCONNECTION_INFO)pos)->ip.s_addr == ip_requeue.s_addr)
3615						break;
3616				}
3617				else if (pos_first == pos)
3618					break;
3619	
3620				if (((PCONNECTION_INFO)pos)->busy != CONN_IS_BUSY &&
3621				    ((PCONNECTION_INFO)pos)->ip.s_addr != ip_requeue.s_addr) {	// requeue
3622					pos_tmp = pos->next;
3623					u2ec_list_del(pos);
3624					u2ec_list_add_tail(pos, &conn_info_list);
3625					pos = pos_tmp->prev;
3626				}
3627			}
3628	
3629			PDEBUG("************* new list *************\n");
3630			u2ec_list_for_each(pos, &conn_info_list) {
3631				PDEBUG("ip %s\n", inet_ntoa(((PCONNECTION_INFO)pos)->ip));
3632				PDEBUG("busy %d\n", ((PCONNECTION_INFO)pos)->busy);
3633			}
3634		}
3635	}
3636	else if (c == 'm') {
3637		if (time((time_t*)NULL) - time_monopoly_old < 3)
3638		{
3639			PDEBUG("time interval is too small!\n");
3640			goto CANCEL;
3641		}
3642
3643		if (nvram_match("mfp_ip_monopoly", ""))
3644			PDEBUG("ip for monopoly: invalid ip address!\n");
3645		else {
3646			PDEBUG("ip for monopoly: %s\n", nvram_safe_get("mfp_ip_monopoly"));
3647			inet_aton(nvram_safe_get("mfp_ip_monopoly"), &ip_monopoly);
3648			time_monopoly = time_monopoly_old = time((time_t*)NULL);
3649		}
3650
3651		if (MFP_state(MFP_GET_STATE) == MFP_IN_U2EC)
3652		{
3653			MFP_state(MFP_IS_IDLE);
3654			nvram_set("u2ec_busyip", "");
3655		}
3656
3657		alarm(0);
3658
3659		u2ec_list_for_each_safe(pos, tmp, &conn_info_list) 
3660			if (((PCONNECTION_INFO)pos)->ip.s_addr != ip_monopoly.s_addr || ((PCONNECTION_INFO)pos)->irp <= 0xc)
3661			{
3662				PDEBUG("\nReset connection for monopoly, ip: %s, socket: %d\n", inet_ntoa(((PCONNECTION_INFO)pos)->ip), ((PCONNECTION_INFO)pos)->sockfd);
3663				count_bulk_read = 0;
3664				count_bulk_write = 0;
3665				count_bulk_read_ret0_1 = 0;
3666				count_bulk_read_ret0_2 = 0;
3667				count_bulk_read_epson = 0;
3668				flag_monitor_epson = 0;
3669				flag_canon_state = 0;
3670				flag_canon_ok = 0;
3671				((PCONNECTION_INFO)pos)->count_class_int_in = 0;
3672				((PCONNECTION_INFO)pos)->ip.s_addr = 0;
3673				((PCONNECTION_INFO)pos)->irp = 0;
3674				FD_CLR(((PCONNECTION_INFO)pos)->sockfd, pfds);
3675				close(((PCONNECTION_INFO)pos)->sockfd);
3676				fd_in_use[((PCONNECTION_INFO)pos)->sockfd] = 0;
3677				((PCONNECTION_INFO)pos)->sockfd = 0;
3678				u2ec_list_del(pos);
3679				free(pos);
3680			}
3681	}
3682CANCEL:
3683#endif
3684	semaphore_post();
3685
3686	*fd = open(U2EC_FIFO, O_RDONLY|O_NONBLOCK);
3687	FD_SET(*fd, pfds);
3688	*pfdm = *fd > *pfdm ? *fd : *pfdm;
3689
3690	return rtvl;
3691}
3692
3693
3694int main(int argc, char *argv[])
3695{
3696	pthread_t	find_thread;		// a thread for get config and get name
3697	int		fifo_fd;		// fifo fd
3698	int		conn_fd, new_fd;	// socket fd
3699	fd_set		master_fds;		// master file descriptor list
3700	fd_set		read_fds;		// temp file descriptor list for select()
3701	int		fdmax;			// maximum file descriptor number
3702	int		index, rtvl;
3703
3704#if defined(U2EC_DEBUG) && defined(U2EC_ONPC)
3705	/* Decode packets. */
3706	if (argc > 1) {
3707		if (argc > 2)
3708			freopen(argv[2], "w", stdout);
3709		decode(argv[1]);
3710		return 0;
3711	}
3712
3713	/* Open log file. */
3714	if ((fp = fopen("U2EC_log.txt", "w")) == NULL) {
3715		printf("U2EC: can't open log file!\n");
3716		fp = stderr;
3717	} else
3718		PDEBUG(" ***** U2EC_log.txt *****\n\n");
3719#endif
3720	printf("U2EC start ...\n");
3721
3722	nvram_set("u2ec_device", "");
3723	nvram_set("u2ec_busyip", "");
3724	semaphore_create();
3725#ifdef	SUPPORT_LPRng
3726	semaphore_wait();
3727	nvram_set("MFP_busy", "0");
3728	semaphore_post();
3729#endif
3730	FD_ZERO(&master_fds);
3731	FD_ZERO(&read_fds);
3732
3733	hotplug_debug("u2ec self updating...\n");
3734	update_device();
3735
3736	signal(SIGALRM, mulit_client);
3737
3738	/* Handle get ip, get config and get name. */
3739	pthread_create(&find_thread, NULL, (void *)add_remote_device, NULL);
3740
3741	/* Fifo used by service_ex.c:hotplug_usb(). */
3742	unlink(U2EC_FIFO);
3743#if __BYTE_ORDER == __BIG_ENDIAN
3744	umask(0000);
3745#endif
3746	mkfifo(U2EC_FIFO, 0666);
3747	fifo_fd = open(U2EC_FIFO, O_RDONLY|O_NONBLOCK);
3748	FD_SET(fifo_fd, &master_fds);
3749	fdmax = fifo_fd;
3750	fd_in_use[fifo_fd] = 1;
3751	ip_monopoly.s_addr = 0;
3752
3753	/* The listener for establish_connection. */
3754	if ((conn_fd = stream_sock_init(uTCPUSB)) < 0) {
3755		PERROR("connection: can't bind to any address\n");
3756		return 1;
3757	}
3758	else
3759		fd_in_use[conn_fd] = 1;
3760
3761	if (dev) {
3762		FD_SET(conn_fd, &master_fds);
3763		fdmax = conn_fd > fdmax ? conn_fd : fdmax;
3764	}
3765
3766	PDEBUG("\nU2EC initialized, listening...\n");
3767
3768	for(;;) {
3769		read_fds = master_fds;
3770		while((rtvl = select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) && (errno == EINTR));
3771		if (rtvl == -1) {
3772			PERROR("select");
3773			return 1;
3774		}
3775
3776		if (ip_monopoly.s_addr && (time((time_t*)NULL) - time_monopoly) > U2EC_TIMEOUT_MONO)
3777		{
3778			PDEBUG("disable monopoly for timeout\n");
3779			ip_monopoly.s_addr = 0;
3780
3781			int u2ec_fifo = open(U2EC_FIFO, O_WRONLY|O_NONBLOCK);
3782			write(u2ec_fifo, "c", 1);
3783			close(u2ec_fifo);
3784		}
3785
3786		// run through the existing connections looking for data to read
3787		for (index = 0; index <= fdmax; index++) {
3788			if (!FD_ISSET(index, &read_fds))
3789				continue;
3790			if (index == fifo_fd) {
3791				if (handle_fifo(&fifo_fd, &master_fds, &fdmax, conn_fd) == 1)
3792					break;
3793			}
3794			else if (index == conn_fd) {
3795				if ((new_fd = establish_connection(conn_fd)) < 0)
3796					continue;
3797				fd_in_use[new_fd] = 1;
3798				FD_SET(new_fd, &master_fds);
3799				fdmax = new_fd > fdmax ? new_fd : fdmax;
3800			}
3801			else {
3802				if (!fd_in_use[index] || usb_connection(index) < 0)
3803					FD_CLR(index, &master_fds); // remove from master set
3804			}
3805		}
3806	}
3807
3808#if defined(U2EC_DEBUG) && defined(U2EC_ONPC)
3809	fclose(fp);
3810#endif
3811
3812	return 0;
3813}
3814
3815void hotplug_print(const char *format)
3816{
3817	FILE *fp;
3818
3819#if __BYTE_ORDER == __LITTLE_ENDIAN
3820	if ((fp = fopen("/tmp/hotplug_usb", "a")))
3821#else
3822	if ((fp = fopen("/var/hotplug_usb", "a")))
3823#endif
3824	{
3825		fprintf(fp, format);
3826		fclose(fp);
3827	}
3828}
3829