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