1 /*___________________________________  epson-usb.c   ___________________________________*/
2 
3 /*       1         2         3         4         5         6         7         8        */
4 /*34567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/
5 /*******************************************|********************************************/
6 /*
7  *   Copyright (c) 2009  Seiko Epson Corporation   All rights reserved.
8  *
9  *   Copyright protection claimed includes all forms and matters of copyrightable
10  *   material and information now allowed by statutory or judicial law or hereinafter
11  *   granted, including without limitation, material generated from the software
12  *   programs which are displayed on the screen such as icons, screen display looks,
13  *   etc.
14  */
15 /*******************************************|********************************************/
16 /*                                                                                      */
17 /*                                   Epson USB Module                                   */
18 /*                                                                                      */
19 /*                                Public Function Calls                                 */
20 /*                              --------------------------                              */
21 /*		EPS_ERR_CODE usbFind            (protocol                                    );	*/
22 /*	    EPS_ERR_CODE usbProbePrinterByID(modelNameTgt, protocol, printer             );	*/
23 /*	    EPS_ERR_CODE usbStartJob		(printer                                     );	*/
24 /*	    EPS_ERR_CODE usbStartPage		(                                            );	*/
25 /*	    EPS_ERR_CODE usbEndJob          (printer                                     );	*/
26 /*	    EPS_ERR_CODE usbGetInfo         (printer, pString, bufSize	                 );	*/
27 /*      EPS_ERR_CODE usbGetStatus       (printer, status, ioStatus                   );	*/
28 /*      EPS_ERR_CODE usbGetJobStatus    (pstInfo							         );	*/
29 /*	    EPS_ERR_CODE usbWritePrintData  (Buffer, BuffLen, sentSize                   );	*/
30 /*	    EPS_ERR_CODE usbResetPrinter    (void                                        );	*/
31 /*	    EPS_ERR_CODE usbMechCommand     (Command                                     );	*/
32 /*                                                                                      */
33 /*******************************************|********************************************/
34 
35 /*------------------------------------  Includes   -------------------------------------*/
36 /*******************************************|********************************************/
37 #include "epson-escpr-pvt.h"
38 #include "epson-escpr-err.h"
39 #include "epson-escpr-services.h"
40 #include "epson-escpr-mem.h"
41 #include "epson-protocol.h"
42 #include "epson-cbt.h"
43 #include "epson-usb.h"
44 
45 /*--------------------------------  Local Definition   ---------------------------------*/
46 /*******************************************|********************************************/
47 #ifdef EPS_LOG_MODULE_USB
48 #define EPS_LOG_MODULE	EPS_LOG_MODULE_USB
49 #else
50 #define EPS_LOG_MODULE	0
51 #endif
52 
53 /* USB protocol */
54 #define EPS_USBP_UNK		(0)		/* unknown */
55 #define EPS_USBP_CBT		(1)
56 #define EPS_USBP_ND4		(2)
57 #define EPS_USBP_UNI		(3)
58 
59 #define EPS_IS_CBT			(EPS_USBP_CBT == ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol)
60 
61 /*---------------------------  Data Structure Declarations   ---------------------------*/
62 /*******************************************|********************************************/
63 typedef struct _tagEPS_USB_PRINTER_INFO_ {
64 	EPS_USB_DEVICE	dev;
65 	EPS_BOOL		bCheckDataChannel;
66 	EPS_UINT32		usbProtocol;
67 }EPS_USB_PRINTER_INFO;
68 
69 typedef struct _tagEPS_PRINT_JOB_USB_ {
70 	EPS_FILEDSC	fd;							/* usb file descriptor                      */
71 	EPS_BOOL    resetRequest;				/* recv reset request & yet not reset       */
72 } EPS_PRINT_JOB_USB;
73 
74 
75 /*--------------------------  ESC/P-R USB Lib Global Variables  ------------------------*/
76 /*******************************************|********************************************/
77 
78 	/*** Extern Function                                                                */
79 	/*** -------------------------------------------------------------------------------*/
80 extern EPS_USB_FUNC    epsUsbFnc;
81 extern EPS_CMN_FUNC    epsCmnFnc;
82 
83     /*** Print Job Structure                                                            */
84     /*** -------------------------------------------------------------------------------*/
85 extern EPS_PRINT_JOB   printJob;
86 
87 	/*** Find                                                                           */
88 	/*** -------------------------------------------------------------------------------*/
89 extern EPS_BOOL     g_FindBreak;							/* Find printer end flag    */
90 
91     /*** I/O Channel                                                                    */
92     /*** -------------------------------------------------------------------------------*/
93 extern EPS_BOOL    ioOpenState;             /* Open state of I/O port (Bi-Directional)  */
94 extern EPS_BOOL    ioDataChState;           /* Open state of Data Channel               */
95 extern EPS_BOOL    ioControlChState;        /* Open state of Control Channel            */
96 extern EPS_BOOL    ioOpenUniDirect;         /* Open state of I/O port (Uni-Directional) */
97 
98 /*--------------------------------  Local Functions   ----------------------------------*/
99 /*******************************************|********************************************/
100 static EPS_ERR_CODE ProbePrinterByName	(const EPS_INT8*, EPS_BOOL, EPS_UINT32,
101 										 EPS_USB_PRINTER_INFO*, EPS_INT8*, EPS_INT8*,
102 										 EPS_INT32*, EPS_UINT32*                        );
103 static EPS_ERR_CODE ProbeESCPR			(EPS_USB_PRINTER_INFO*, EPS_INT8*, EPS_INT8*,
104 										 EPS_INT32*, EPS_UINT32*                        );
105 static EPS_ERR_CODE CreatePrinterInfo	(EPS_USB_PRINTER_INFO*, const EPS_INT8*,
106 										 const EPS_INT8*, const EPS_INT8*, EPS_INT32,
107 										 EPS_UINT32, EPS_PRINTER_INN**                  );
108 static EPS_ERR_CODE PortResolution		(const EPS_PRINTER_INN*, EPS_FILEDSC*           );
109 static EPS_ERR_CODE GetBinaryStatus		(EPS_FILEDSC, EPS_UINT32, EPS_UINT32, EPS_STATUS_INFO*);
110 static EPS_ERR_CODE InfoCommand			(EPS_FILEDSC, EPS_UINT32, EPS_INT32, EPS_UINT8**, EPS_INT32*);
111 static EPS_ERR_CODE CbtInfoCommand		(EPS_FILEDSC, EPS_INT32, EPS_UINT8**, EPS_INT32*);
112 static EPS_ERR_CODE RmtInfoCommand		(EPS_FILEDSC, EPS_INT32, EPS_UINT8**, EPS_INT32*);
113 
114 static EPS_ERR_CODE nd4WritePortal      (EPS_FILEDSC fd, const EPS_UINT8* buff, EPS_INT32* buffSize);
115 static EPS_ERR_CODE nd4ReadPortal       (EPS_FILEDSC fd, EPS_UINT8* buff, EPS_INT32* buffSize);
116 static EPS_ERR_CODE OpenPortal          (EPS_USB_PRINTER_INFO *usbInfo, EPS_FILEDSC	*fd );
117 static EPS_ERR_CODE	ClosePortal         (EPS_UINT32	usbProtocol, EPS_FILEDSC fd         );
118 static void         ParseUsbProtocol    (EPS_INT8* deviceIDString, EPS_INT32 strlength,
119 	                                     EPS_UINT32* usbProtocol                        );
120 static EPS_ERR_CODE GetSerialNumber     (EPS_USB_PRINTER_INFO*, EPS_INT8* serialNo      );
121 
122 
123 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
124 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
125 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/
126 /*--------------------              Public Functions               ---------------------*/
127 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/
128 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
129 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
130 
131 /*******************************************|********************************************/
132 /*                                                                                      */
133 /* Function name:     usbFind()	        	                                            */
134 /*                                                                                      */
135 /* Arguments                                                                            */
136 /* ---------                                                                            */
137 /* Name:        Type:               Description:                                        */
138 /* timeout      EPS_UINT32          I: find timeout                                     */
139 /* protocol	    EPS_INT32           I: communication mode                               */
140 /*                                                                                      */
141 /* Return value:                                                                        */
142 /*      EPS_ERR_NONE                - Success Printer found                             */
143 /*      EPS_ERR_PRINTER_NOT_FOUND	- Printer not found (or error occur)		        */
144 /*      EPS_ERR_MEMORY_ALLOCATION   - memory allocation failed                          */
145 /*      EPS_ERR_NOT_OPEN_IO         - Cannot Open I/O Portal                            */
146 /*                                                                                      */
147 /* Description:                                                                         */
148 /*      find all USB printer.                                                           */
149 /*                                                                                      */
150 /*******************************************|********************************************/
usbFind(EPS_UINT32 * timeout,EPS_INT32 protocol)151 EPS_ERR_CODE usbFind (
152 
153         EPS_UINT32*         timeout,
154 		EPS_INT32           protocol
155 
156 ){
157 /*** Declare Variable Local to Routine                                                  */
158     EPS_ERR_CODE		ret = EPS_ERR_NONE;			 /* Return status of internal calls */
159 	EPS_FILEDSC			fd = EPS_INVALID_FILEDSC;
160 	EPS_PRINTER_INN*	printer = NULL;
161 	EPS_USB_PRINTER_INFO usbInfo;
162 	EPS_INT8			manufacturer[EPS_NAME_BUFFSIZE];    /* Manufacturer name        */
163 	EPS_INT8			modelName[EPS_NAME_BUFFSIZE];       /* Printer model name       */
164 	EPS_INT8			serialNo[EPS_ADDR_BUFFSIZE];        /* Printer serial number    */
165 	EPS_UINT32			tmStart, tmNow, tmSpan;
166     EPS_INT32           cmdLevel = 0;
167 	EPS_UINT32			egID = 0;
168 
169 	EPS_LOG_FUNCIN;
170 
171 	memset(&usbInfo, 0, sizeof(usbInfo));
172 	memset(manufacturer, 0, sizeof(manufacturer));
173 	memset(modelName, 0, sizeof(modelName));
174 	memset(serialNo, 0, sizeof(serialNo));
175 
176 /***------------------------------------------------------------------------------------*/
177 /*** Bi-Directional Communication Mode                                                  */
178 /***------------------------------------------------------------------------------------*/
179     if ( EPS_IS_BI_PROTOCOL(protocol) ) {
180 		fd = epsUsbFnc.findFirst( &usbInfo.dev );
181 		if(EPS_INVALID_FILEDSC != fd){
182 			if(epsCmnFnc.getTime){
183 				tmStart = epsCmnFnc.getTime();
184 			} else{
185 				*timeout = tmStart = tmNow = tmSpan = 0;
186 			}
187 
188 			do{
189 			/*** Validate this is an Epson ESC/PR Printer                                   */
190 				ret = ProbeESCPR(&usbInfo, manufacturer, modelName, &cmdLevel, &egID);
191 
192 				if(EPS_ERR_NONE == ret){
193 					/*retStatus = */GetSerialNumber(&usbInfo, serialNo);
194 					ret = CreatePrinterInfo(&usbInfo, manufacturer, modelName, serialNo,
195 											cmdLevel, egID, &printer);
196 					if( EPS_ERR_NONE == ret ){
197 						ret = prtRegPrinter( printer, TRUE );
198 					}
199 
200 					if( EPS_ERR_NONE != ret ){
201 						break;
202 					}
203 
204 					if(*timeout > 0){
205 						tmNow = epsCmnFnc.getTime();
206 						tmSpan = (EPS_UINT32)(tmNow - tmStart);
207 						/*EPS_DBGPRINT( ("TM %u - %u <> %u\n", tmNow, tmStart, tmSpan) )*/
208 						if( tmSpan >= *timeout ){
209 							break;
210 						}
211 					}
212 					if( epsCmnFnc.lockSync && epsCmnFnc.unlockSync ){
213 						if( 0 == epsCmnFnc.lockSync() ){
214 							if( g_FindBreak ){
215 								epsCmnFnc.unlockSync();
216 								break;
217 							}
218 							epsCmnFnc.unlockSync();
219 						}
220 					}
221 				}
222 			}while( epsUsbFnc.findNext( fd, &usbInfo.dev ) );
223 
224 			epsUsbFnc.findClose(fd);
225 
226 			if(*timeout > 0){
227 				/* calculate elapsed time */
228 				tmNow = epsCmnFnc.getTime();
229 				tmSpan = (EPS_UINT32)(tmNow - tmStart);
230 				if(tmSpan < *timeout){
231 					*timeout -= tmSpan;
232 				} else{
233 					*timeout = 1;
234 				}
235 			}
236 
237 		} else{
238 			ret = EPS_ERR_PRINTER_NOT_FOUND;
239 		}
240 
241 /***------------------------------------------------------------------------------------*/
242 /*** Uni-Directional Communication Mode                                                 */
243 /***------------------------------------------------------------------------------------*/
244 	} else{
245     /*** Open Portal check                                                              */
246         fd = epsUsbFnc.openPortal(NULL);
247 		if(EPS_INVALID_FILEDSC != fd){
248 			epsUsbFnc.closePortal(fd);
249 
250 			/*** Create printer info structure                                          */
251 			usbInfo.usbProtocol = EPS_USBP_UNI;
252 			ret = CreatePrinterInfo(&usbInfo, "", "", "", 0, 0, &printer);
253 			if( EPS_ERR_NONE == ret ){
254 				ret = prtRegPrinter( printer, TRUE );
255 			}
256 		} else{
257             ret = EPS_ERR_PRINTER_NOT_FOUND;
258         }
259 	}
260 
261 	EPS_RETURN( ret );
262 }
263 
264 
265 /*******************************************|********************************************/
266 /*                                                                                      */
267 /* Function name:   usbProbePrinterByID()                                               */
268 /*                                                                                      */
269 /* Arguments                                                                            */
270 /* ---------                                                                            */
271 /* Name:        Type:               Description:                                        */
272 /* printerUUID EPS_INT8*            I: ID String of probe target                        */
273 /* timeout      EPS_UINT32          I: find timeout                                     */
274 /* printer		EPS_PRINTER_INN**   O: pointer for found printer structure              */
275 /*                                                                                      */
276 /* Return value:                                                                        */
277 /*      EPS_ERR_NONE                    - Success (printer found)                       */
278 /*      EPS_ERR_PRINTER_NOT_FOUND       - printer not found                             */
279 /*      EPS_ERR_MEMORY_ALLOCATION       - Fail to memory allocation                     */
280 /*      EPS_ERR_NOT_OPEN_IO             - Cannot Open I/O Portal                        */
281 /*                                                                                      */
282 /* Description:                                                                         */
283 /*     looks for specified printer.                                                     */
284 /*                                                                                      */
285 /*******************************************|********************************************/
usbProbePrinterByID(EPS_INT8 * printerUUID,EPS_UINT32 timeout,EPS_PRINTER_INN ** printer)286 EPS_ERR_CODE   usbProbePrinterByID (
287 
288 		EPS_INT8*			printerUUID,
289         EPS_UINT32			timeout,
290 		EPS_PRINTER_INN**   printer
291 
292 ){
293 /*** Declare Variable Local to Routine                                                  */
294     EPS_ERR_CODE	ret = EPS_ERR_NONE;				 /* Return status of internal calls */
295 	EPS_FILEDSC		fd = EPS_INVALID_FILEDSC;
296 	EPS_USB_PRINTER_INFO usbInfo;
297 	EPS_INT8		manufacturer[EPS_NAME_BUFFSIZE];    /* Manufacturer name            */
298 	EPS_INT8		modelName[EPS_NAME_BUFFSIZE];       /* Printer model name           */
299 	EPS_INT8		serialNo[EPS_ADDR_BUFFSIZE];        /* Printer serial number        */
300     EPS_INT8*       pPos = NULL;
301     EPS_INT32       nSegCnt = 0;
302     EPS_UINT32      nTmp = 0;
303 	EPS_INT8		modelNameTgt[EPS_NAME_BUFFSIZE];    /* target printer model name    */
304 	EPS_BOOL		enableBreak = FALSE;
305 	EPS_INT32       cmdLevel = 0;
306 	EPS_UINT32      egID = 0;
307 
308 	EPS_LOG_FUNCIN;
309 
310 /*** Parse definition String                                                        */
311 	pPos = strtok(printerUUID, EPS_USBID_SEP);
312     for(nSegCnt = 0; pPos != NULL && nSegCnt < EPS_USBID_SEGNUM; nSegCnt++){
313 		switch(nSegCnt){
314 		case 0:			/* Get VID */
315 		case 1:			/* Get PID */
316 			sscanf(pPos, "%x", &nTmp);
317 			if(nTmp == 0){
318 				EPS_RETURN( EPS_ERR_INV_ARG_PRINTER_ID );
319 			}
320 			/* lib do not use VID, PID */
321 			break;
322 
323 		case 2:			/* Get model name */
324 			strcpy(modelNameTgt, pPos);
325 			break;
326 		}
327 
328 		pPos = strtok(NULL, EPS_USBID_SEP);
329     }
330 	if(nSegCnt < EPS_USBID_SEGNUM){
331 		EPS_RETURN( EPS_ERR_INV_ARG_PRINTER_ID );
332 	}
333 
334 	memset(&usbInfo, 0, sizeof(usbInfo));
335 
336 /***------------------------------------------------------------------------------------*/
337 /*** Bi-Directional Communication Mode                                                  */
338 /***------------------------------------------------------------------------------------*/
339     if ( EPS_IS_BI_PROTOCOL(printJob.commMode) ) {
340 		enableBreak = (epsCmnFnc.lockSync && epsCmnFnc.unlockSync );
341 		memset(manufacturer, 0, sizeof(manufacturer));
342 		memset(modelName, 0, sizeof(modelName));
343 		memset(serialNo, 0, sizeof(serialNo));
344 		ret = ProbePrinterByName(modelNameTgt, enableBreak, timeout,
345 			                     &usbInfo, manufacturer, modelName, &cmdLevel, &egID);
346 		if(EPS_ERR_NONE == ret){
347 			/*retStatus = */GetSerialNumber(&usbInfo, serialNo);
348 
349 			/*** Create printer info structure                                          */
350 			ret = CreatePrinterInfo(&usbInfo, manufacturer, modelName, serialNo,
351 									cmdLevel, egID, printer);
352 		}
353 /***------------------------------------------------------------------------------------*/
354 /*** Uni-Directional Communication Mode                                                 */
355 /***------------------------------------------------------------------------------------*/
356     } else{
357     /*** Open Portal check                                                              */
358         fd = epsUsbFnc.openPortal(NULL);
359 		if(EPS_INVALID_FILEDSC != fd){
360 			epsUsbFnc.closePortal(fd);
361 
362 			/*** Create printer info structure                                          */
363 			usbInfo.usbProtocol = EPS_USBP_UNI;
364 			ret = CreatePrinterInfo(&usbInfo, "", "", "", 0, 0, printer);
365 
366 		} else{
367             ret = EPS_ERR_PRINTER_NOT_FOUND;
368         }
369     }
370 
371 /*** Return to Caller                                                                   */
372     EPS_RETURN( ret );
373 }
374 
375 
376 /*******************************************|********************************************/
377 /*                                                                                      */
378 /* Function name:     usbStartJob()                                                     */
379 /*                                                                                      */
380 /* Arguments                                                                            */
381 /* ---------                                                                            */
382 /* Name:            Type:                   Description:                                */
383 /* printer          EPS_PRINTER_INN*        I: Pointer to a PrinterInfo                 */
384 /*                                                                                      */
385 /* Return value:                                                                        */
386 /*      << Normal >>                                                                    */
387 /*      EPS_ERR_NONE                    - Success                                       */
388 /*      << Error >>                                                                     */
389 /*      (Uni/Bi-Directional)                                                            */
390 /*      EPS_ERR_LIB_NOT_INITIALIZED     - ESC/P-R Lib is NOT initialized                */
391 /*      EPS_ERR_NOT_OPEN_IO             - Failed to open I/O                            */
392 /*      (Bi-Directional Only)                                                           */
393 /*      EPS_ERR_PRINTER_ERR_OCCUR       - Printer Error happened                        */
394 /*                                                                                      */
395 /* Description:                                                                         */
396 /*      Creates a new print job.                                                        */
397 /*                                                                                      */
398 /*******************************************|********************************************/
usbStartJob(void)399 EPS_ERR_CODE    usbStartJob (
400 
401         void
402 
403 ){
404 /*** Declare Variable Local to Routine                                                  */
405 	EPS_ERR_CODE		retStatus = EPS_ERR_NONE;   /* Return status of internal calls  */
406 	const EPS_PRINTER_INN* printer = printJob.printer;
407 	EPS_PRINT_JOB_USB	*usbPrintJob = NULL;
408 
409 	EPS_LOG_FUNCIN;
410 
411 /*** Create USB Job data                                                                */
412 	usbPrintJob = (EPS_PRINT_JOB_USB*)EPS_ALLOC( sizeof(EPS_PRINT_JOB_USB) );
413 	if( NULL == usbPrintJob ){
414 		EPS_RETURN( EPS_ERR_MEMORY_ALLOCATION );
415 	}
416 	memset(usbPrintJob, 0, sizeof(EPS_PRINT_JOB_USB));
417 	usbPrintJob->fd = EPS_INVALID_FILEDSC;
418 	usbPrintJob->resetRequest = FALSE;
419 
420 /***------------------------------------------------------------------------------------*/
421 /*** Bi-Directional Communication Mode                                                  */
422 /***------------------------------------------------------------------------------------*/
423 	if( EPS_IS_BI_PROTOCOL(printer->protocol) ){
424 	/*** Resolve present port number. And Open the I/O Port for communication           */
425 		retStatus = PortResolution(printer, &usbPrintJob->fd);
426         if (retStatus != EPS_ERR_NONE) {
427  			cbtCommClose(usbPrintJob->fd);
428 			retStatus = (EPS_ERR_CODE)EPS_ERR_NOT_OPEN_IO;
429             goto epsStartJob_END;
430         }
431 
432 		if( EPS_IS_CBT ){
433 		/*** Open the command channel                                                   */
434 			retStatus = cbtCommChannelOpen(usbPrintJob->fd, EPS_CBTCHANNEL_CTRL, TRUE);
435 			if (retStatus != EPS_ERR_NONE) {
436 				retStatus = cbtCommClose(usbPrintJob->fd);
437 				retStatus = (EPS_ERR_CODE)EPS_ERR_NOT_OPEN_IO;
438 				goto epsStartJob_END;
439 			}
440 
441 		/*** Open Data Channel                                                          */
442 			retStatus = cbtCommChannelOpen(usbPrintJob->fd, EPS_CBTCHANNEL_DATA, TRUE);
443 			if (retStatus != EPS_ERR_NONE) {
444 				retStatus = cbtCommChannelClose(usbPrintJob->fd, EPS_CBTCHANNEL_CTRL);
445 				retStatus = cbtCommClose(usbPrintJob->fd);
446 				retStatus = (EPS_ERR_CODE)EPS_ERR_PRINTER_ERR_OCCUR/*EPS_ERR_CANNOT_PRINT*/;
447 				goto epsStartJob_END;
448 			}
449 		}
450 		((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->bCheckDataChannel = FALSE;
451 
452 /***------------------------------------------------------------------------------------*/
453 /*** Uni-Directional Communication Mode                                                 */
454 /***------------------------------------------------------------------------------------*/
455     } else{
456     /*** Open Portal                                                                    */
457         if (ioOpenUniDirect == EPS_IO_OPEN) {
458             retStatus = EPS_ERR_2ND_OPEN_IO;
459 			goto epsStartJob_END;
460         } else {
461             usbPrintJob->fd = epsUsbFnc.openPortal( NULL );
462             if (EPS_INVALID_FILEDSC == usbPrintJob->fd) {
463                 retStatus = EPS_ERR_NOT_OPEN_IO;
464 				goto epsStartJob_END;
465             }
466             ioOpenUniDirect = EPS_IO_OPEN;
467         }
468     }
469 
470 	printJob.hProtInfo = (EPS_HANDLE)usbPrintJob;
471 
472 epsStartJob_END:
473 	if(EPS_ERR_NONE != retStatus){
474 		EPS_SAFE_RELEASE(usbPrintJob);
475 	}
476 
477 /*** Return to Caller                                                                   */
478     EPS_RETURN( retStatus );
479 }
480 
481 
482 /*******************************************|********************************************/
483 /*                                                                                      */
484 /* Function name:     usbRestartJob()                                                   */
485 /*                                                                                      */
486 /* Arguments                                                                            */
487 /* ---------                                                                            */
488 /* Name:            Type:                   Description:                                */
489 /* N/A                                                                                  */
490 /*                                                                                      */
491 /* Return value:                                                                        */
492 /*      << Normal >>                                                                    */
493 /*      EPS_ERR_NONE                    - Success                                       */
494 /*      << Error >>                                                                     */
495 /*      (Uni/Bi-Directional)                                                            */
496 /*      EPS_ERR_JOB_NOT_INITIALIZED     - JOB is NOT initialized						*/
497 /*      EPS_ERR_NOT_OPEN_IO             - Failed to open I/O                            */
498 /*      (Bi-Directional Only)                                                           */
499 /*      EPS_ERR_PRINTER_ERR_OCCUR       - Printer Error happened                        */
500 /*                                                                                      */
501 /* Description:                                                                         */
502 /*      The port shut by usbResetPrinter() is opened again.                             */
503 /*                                                                                      */
504 /*******************************************|********************************************/
usbRestartJob(void)505 EPS_ERR_CODE    usbRestartJob (
506 
507         void
508 
509 ){
510 
511 /*** Declare Variable Local to Routine                                                  */
512 	EPS_ERR_CODE		retStatus = EPS_ERR_NONE;   /* Return status of internal calls  */
513 	const EPS_PRINTER_INN* printer = printJob.printer;
514 	EPS_PRINT_JOB_USB* usbPrintJob = (EPS_PRINT_JOB_USB*)printJob.hProtInfo;
515 
516 	EPS_LOG_FUNCIN;
517 
518  	if( !usbPrintJob ){
519 		EPS_RETURN( EPS_ERR_JOB_NOT_INITIALIZED );
520 	}
521 
522 /***------------------------------------------------------------------------------------*/
523 /*** Bi-Directional(CBT) Communication Mode                                             */
524 /***------------------------------------------------------------------------------------*/
525 	if( EPS_IS_BI_PROTOCOL(printer->protocol) && EPS_IS_CBT){
526 		if(EPS_IO_NOT_OPEN == ioDataChState){
527 		/*if( EPS_RESET_SENT == printJob.resetSent ){*/
528 		/* If pre page canceled, Re open data channel */
529 			retStatus = cbtCommChannelOpen(usbPrintJob->fd, EPS_CBTCHANNEL_DATA, TRUE);
530 			if (retStatus == EPS_ERR_NONE) {
531 				((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->bCheckDataChannel = FALSE;
532 			} else{
533 				retStatus = (EPS_ERR_CODE)EPS_ERR_PRINTER_ERR_OCCUR/*EPS_ERR_CANNOT_PRINT*/;
534 			}
535 		}
536 /***------------------------------------------------------------------------------------*/
537 /*** END4 or Uni-Directional Communication Mode                                         */
538 /***------------------------------------------------------------------------------------*/
539 /*   } else{
540 		no operation*/
541     }
542 
543 /*** Return to Caller                                                                   */
544     EPS_RETURN( retStatus );
545 }
546 
547 
548 /*******************************************|********************************************/
549 /*                                                                                      */
550 /* Function name:   usbEndJob()                                                         */
551 /*                                                                                      */
552 /* Arguments                                                                            */
553 /* ---------                                                                            */
554 /* Name:            Type:                   Description:                                */
555 /* N/A                                                                                  */
556 /*                                                                                      */
557 /* Return value:                                                                        */
558 /*      << Normal >>                                                                    */
559 /*      EPS_ERR_NONE                    - Success                                       */
560 /*      << Error >>                                                                     */
561 /*      EPS_ERR_JOB_NOT_INITIALIZED     - JOB is NOT initialized                        */
562 /*      EPS_ERR_NOT_CLOSE_IO            - Cannot close I/O portal                       */
563 /*                                                                                      */
564 /* Description:                                                                         */
565 /*      Ends the current print job.                                                     */
566 /*                                                                                      */
567 /*******************************************|********************************************/
usbEndJob(void)568 EPS_ERR_CODE    usbEndJob (
569 
570         void
571 
572 ){
573     EPS_ERR_CODE    retStatus = EPS_ERR_NONE;       /* Return status of internal calls  */
574 	const EPS_PRINTER_INN* printer = printJob.printer;
575 	EPS_PRINT_JOB_USB* usbPrintJob = (EPS_PRINT_JOB_USB*)printJob.hProtInfo;
576 
577 EPS_LOG_FUNCIN;
578 
579 	if( !usbPrintJob ){
580 		EPS_RETURN( EPS_ERR_JOB_NOT_INITIALIZED );
581 	}
582 
583 /***------------------------------------------------------------------------------------*/
584 /*** Bi-Directional(CBT) Communication Mode                                             */
585 /***------------------------------------------------------------------------------------*/
586 	if( EPS_IS_BI_PROTOCOL(printer->protocol) ){
587 		if( EPS_IS_CBT ){
588 		/*** Close communication                                                            */
589 			retStatus = cbtCommChannelClose(usbPrintJob->fd, EPS_CBTCHANNEL_DATA);
590 			retStatus = cbtCommChannelClose(usbPrintJob->fd, EPS_CBTCHANNEL_CTRL);
591 			retStatus = cbtCommClose(usbPrintJob->fd);
592 		} else{
593 			retStatus = ClosePortal( ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol, usbPrintJob->fd );
594 		}
595 		if (retStatus != EPS_ERR_NONE) {
596 			retStatus = EPS_ERR_NOT_CLOSE_IO;
597 		}
598 /***------------------------------------------------------------------------------------*/
599 /*** END4 or Uni-Directional Communication Mode                                         */
600 /***------------------------------------------------------------------------------------*/
601 	} else{
602 		/*** Close Portal                                                               */
603 		if (ioOpenUniDirect == EPS_IO_OPEN) {
604 			retStatus = epsUsbFnc.closePortal(usbPrintJob->fd);
605 			if (retStatus != 0) {
606 				EPS_RETURN( EPS_ERR_NOT_CLOSE_IO );
607 			}
608 			ioOpenUniDirect = EPS_IO_NOT_OPEN;
609 		}
610     }
611 
612 	EPS_SAFE_RELEASE( printJob.hProtInfo );
613 
614 	EPS_RETURN( retStatus );
615 }
616 
617 
618 
619 /*******************************************|********************************************/
620 /*                                                                                      */
621 /* Function name:   usbWritePrintData()                                                 */
622 /*                                                                                      */
623 /* Arguments                                                                            */
624 /* ---------                                                                            */
625 /* Name:        Type:               Description:                                        */
626 /* Buffer       const EPS_UINT8*    I: Buffer Pointer for Write Data                    */
627 /* BuffLen      EPS_UINT32          I: Write Data Buffer Length (bytes)                 */
628 /* sentSize     EPS_UINT32*         O: Actuall Write Size                               */
629 /*                                                                                      */
630 /* Return value:                                                                        */
631 /*      EPCBT_ERR_NONE                  - Success                                       */
632 /*      EPS_ERR_JOB_NOT_INITIALIZED     - JOB is NOT initialized						*/
633 /*      EPS_ERR_COMM_ERROR              - Communication Error                           */
634 /*                                                                                      */
635 /* Description:                                                                         */
636 /*      Write the data to printer Data Channel.                                         */
637 /*                                                                                      */
638 /*******************************************|********************************************/
usbWritePrintData(const EPS_UINT8 * Buffer,EPS_UINT32 BuffLen,EPS_UINT32 * sentSize)639 EPS_ERR_CODE   usbWritePrintData (
640 
641 		const EPS_UINT8*    Buffer,
642         EPS_UINT32          BuffLen,
643         EPS_UINT32*         sentSize
644 
645 ){
646     EPS_INT32		   retCom;
647 	const EPS_PRINTER_INN* printer = printJob.printer;
648 	EPS_PRINT_JOB_USB* usbPrintJob = (EPS_PRINT_JOB_USB*)printJob.hProtInfo;
649 
650 EPS_LOG_FUNCIN;
651 
652 	if( !usbPrintJob ){
653 		EPS_RETURN( EPS_ERR_JOB_NOT_INITIALIZED );
654 	}
655 
656 /***------------------------------------------------------------------------------------*/
657 /*** Bi-Directional(CBT) Communication Mode                                             */
658 /***------------------------------------------------------------------------------------*/
659 	if( EPS_IS_BI_PROTOCOL(printJob.printer->protocol) && EPS_IS_CBT ){
660 		retCom = cbtCommWriteData(usbPrintJob->fd, EPS_CBTCHANNEL_DATA, Buffer, (EPS_INT32)BuffLen, (EPS_INT32*)sentSize);
661 		if(EPCBT_ERR_NONE == retCom){
662 			EPS_RETURN( EPS_ERR_NONE );
663 		} else if(EPSCBT_ERR_FNCDISABLE == retCom){
664 			EPS_RETURN( EPS_COM_TINEOUT );
665 		}else{
666 			EPS_RETURN( EPS_ERR_COMM_ERROR );
667 		}
668 
669 /***------------------------------------------------------------------------------------*/
670 /*** END4 or Uni-Directional Communication Mode                                         */
671 /***------------------------------------------------------------------------------------*/
672 	} else{
673 		retCom = epsUsbFnc.writePortal(usbPrintJob->fd, Buffer, (EPS_INT32)BuffLen, (EPS_INT32*)sentSize);
674 		if(0 == retCom){
675 			EPS_RETURN( EPS_ERR_NONE );
676 		} else{
677 			EPS_RETURN( EPS_ERR_COMM_ERROR );
678 		}
679 	}
680 }
681 
682 
683 /*******************************************|********************************************/
684 /*                                                                                      */
685 /* Function name:   usbResetPrinter()                                                   */
686 /*                                                                                      */
687 /* Arguments                                                                            */
688 /* ---------                                                                            */
689 /* Name:        Type:               Description:                                        */
690 /* void         -                   -                                                   */
691 /*                                                                                      */
692 /* Return value:                                                                        */
693 /*      EPS_ERR_NONE                    - Success                                       */
694 /*      EPS_ERR_JOB_NOT_INITIALIZED     - JOB is NOT initialized						*/
695 /*      EPS_ERR_COMM_ERROR              - Failed to send command                        */
696 /*      EPS_ERR_CAN_NOT_RESET           - Failed to reset printer                       */
697 /*      EPS_ERR_NOT_CLOSE_IO            - Cannot Close I/O Portal                       */
698 /*                                                                                      */
699 /* Description:                                                                         */
700 /*      Send "rj" command and reset printer.                                            */
701 /*                                                                                      */
702 /*******************************************|********************************************/
usbResetPrinter(void)703 EPS_ERR_CODE   usbResetPrinter (
704 
705         void
706 
707 ){
708 /*** Declare Variable Local to Routine                                                  */
709 #define EPS_RSREPLY_SIZE	(32)
710     EPS_ERR_CODE    Ret;
711     EPS_INT32       ComSize = 0;
712     EPS_INT32       retBufSize;                         /* Size of buffer written       */
713     EPS_INT32       retryComm;
714     EPS_INT32       retryReset;
715     EPS_INT32       Size = EPS_RSREPLY_SIZE;
716     EPS_INT32       lSize;
717     EPS_UINT8       pResult[EPS_RSREPLY_SIZE];
718 	EPS_PRINT_JOB_USB* usbPrintJob = (EPS_PRINT_JOB_USB*)printJob.hProtInfo;
719 	const EPS_PRINTER_INN* printer = printJob.printer;
720 
721     EPS_UINT8 CBTcmd_rj[] = { 'r',   'j', 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722                          /* E   , S   , C   , P   , R   , L   , i   , b    */
723                             0x45, 0x53, 0x43, 0x50, 0x52, 0x4c, 0x69, 0x62 };
724 #if 0  /* Not use "rs" command */
725     EPS_UINT8 CBTcmd_rs[] = {'r', 's', 0x01, 0x00, 0x01};
726 #endif
727 
728 
729 EPS_LOG_FUNCIN;
730 
731 	if( !EPS_IS_CBT ){
732 		Ret = epsUsbFnc.softReset(usbPrintJob->fd);
733 		if(0 == Ret){
734 			EPS_RETURN( EPS_ERR_NONE );
735 		} else{
736 			EPS_RETURN( EPS_ERR_COMM_ERROR );
737 		}
738 	}
739 
740 /*** Initialize Local Variables                                                         */
741     retBufSize = 0;
742     memset(pResult, 0, 32);
743 
744 	if( !usbPrintJob ){
745 		EPS_RETURN( EPS_ERR_JOB_NOT_INITIALIZED );
746 	}
747 
748 /*** If we already successfully called this function once for a given print job,        */
749     if( printJob.resetSent == EPS_RESET_SENT
750 		|| FALSE == printJob.transmittable
751 		|| FALSE == printJob.sendJS ){
752         EPS_RETURN( EPS_ERR_NONE );/*  no need to send an "rj" command again. Therefore,   */
753                                    /*  return EPS_ERR_NONE and exit gracefully.            */
754     }
755 
756 	EPS_DBGPRINT((">>>> Send Printer Reset Command.\r\n"));
757 	serDelayThread(500, &epsCmnFnc);				/* wait printer 500ms */
758 
759     retryReset = 5;  /* 5 times time out */
760     do{
761 /*** Send "rj" command                                                                  */
762         retryComm = 5;
763         do{
764             Ret = cbtCommWriteData(usbPrintJob->fd, EPS_CBTCHANNEL_CTRL, (const EPS_UINT8*)CBTcmd_rj, sizeof(CBTcmd_rj), &ComSize);
765 
766             if ( Ret != EPCBT_ERR_NONE){
767                 if (Ret != EPSCBT_ERR_FNCDISABLE){
768                     EPS_DBGPRINT(("CBT Command Write Failed [%d]\r\n",Ret));
769                     EPS_RETURN( EPS_ERR_COMM_ERROR );
770                 }
771                 retryComm--;
772                 if (!retryComm) {
773                     EPS_DBGPRINT(("CBT Command Write Retry Failed \r\n"));
774                     EPS_RETURN( EPS_ERR_COMM_ERROR );
775                 }
776                 serDelayThread(1*_SECOND_, &epsCmnFnc);        /* retry command after 1 seconds*/
777             }
778         }while (Ret == EPSCBT_ERR_FNCDISABLE);
779 
780 /*** Read "rj" Reply                                                                    */
781         retryComm = 5;
782         lSize = Size-1;
783         do{
784             if ((Ret = cbtCommReadData(usbPrintJob->fd, EPS_CBTCHANNEL_CTRL, pResult, lSize, &Size)) != EPCBT_ERR_NONE){
785                 if (Ret != EPSCBT_ERR_FNCDISABLE){
786                     EPS_DBGPRINT(("CBT Command Write Reply Failed [%d]\r\n",Ret));
787                     EPS_RETURN( EPS_ERR_COMM_ERROR );
788                 }
789             }else if (Size != 0){
790                 break;
791             }
792 
793             retryComm--;
794             if (!retryComm){
795                 EPS_DBGPRINT(("CBT Command Write Reply Retry Failed \r\n"));
796                 EPS_RETURN( EPS_ERR_COMM_ERROR );
797             }
798             serDelayThread(1*_SECOND_, &epsCmnFnc);        /* retry command after 1 seconds*/
799         }while(retryComm > 0);
800 
801 /*** Make sure we received a correct reply in response to the reset command we sent.    */
802 		pResult[EPS_RSREPLY_SIZE-1] = '\0';
803 		EPS_DUMP(pResult, Size);
804 		if (strstr((EPS_INT8*)pResult, "rj:OK;") == NULL) {
805             retryReset--;
806             if (!retryReset) {
807                 EPS_DBGPRINT(("Failed to <rj> reset \r\n"));
808                 EPS_RETURN( EPS_ERR_CAN_NOT_RESET );
809             }
810             serDelayThread(500, &epsCmnFnc);        /* retry command after 500m seconds*/
811         } else{
812             break;
813         }
814 
815     }while(retryReset > 0);
816 
817 	/*** Close Data Channel after sent "rj" command                                     */
818 	Ret = cbtCommChannelClose(usbPrintJob->fd, EPS_CBTCHANNEL_DATA);
819     if (Ret != EPS_ERR_NONE) {
820         EPS_RETURN( EPS_ERR_NOT_CLOSE_IO );
821     }
822 	if(printJob.printer && printJob.printer->protocolInfo){
823 		((EPS_USB_PRINTER_INFO*)printJob.printer->protocolInfo)->bCheckDataChannel = TRUE;
824 	}
825 
826 	usbPrintJob->resetRequest = FALSE;
827 
828 /*** Return to Caller                                                                   */
829     EPS_RETURN( EPS_ERR_NONE );
830 }
831 
832 
833 /*******************************************|********************************************/
834 /*                                                                                      */
835 /* Function name:   usbGetInfo()                                                        */
836 /*                                                                                      */
837 /* Arguments                                                                            */
838 /* ---------                                                                            */
839 /* Name:            Type:                   Description:                                */
840 /* printer          EPS_PRINTER_INN*        I: Pointer to a PrinterInfo                 */
841 /* type 			EPS_INT32				I: PM kind 1 or 2                           */
842 /* pString			EPS_UINT8*				O: Pointer to PM String                     */
843 /* bufSize			EPS_INT32				I: pString buffer size                      */
844 /*                                                                                      */
845 /* Return value:                                                                        */
846 /*      EPS_ERR_NONE                    - Success                                       */
847 /*      EPS_ERR_JOB_NOT_INITIALIZED     - JOB is NOT initialized						*/
848 /*      EPS_ERR_OPR_FAIL                - Internal Error                                */
849 /*      EPS_ERR_MEMORY_ALLOCATION       - Failed to allocate memory                     */
850 /*      EPS_ERR_NOT_OPEN_IO             - Cannot Open I/O Portal                        */
851 /*      EPS_ERR_COMM_ERROR              - Info command execution error                  */
852 /*                                                                                      */
853 /* Description:                                                                         */
854 /*      Get PM string from usb printer.                                                 */
855 /*                                                                                      */
856 /*******************************************|********************************************/
usbGetInfo(const EPS_PRINTER_INN * printer,EPS_INT32 type,EPS_UINT8 ** pString,EPS_INT32 * bufSize)857 EPS_ERR_CODE     usbGetInfo (
858 
859 		const EPS_PRINTER_INN*	printer,
860 		EPS_INT32               type,
861 		EPS_UINT8**             pString,
862 		EPS_INT32*              bufSize
863 
864 ){
865 /*** Declare Variable Local to Routine                                                  */
866     EPS_ERR_CODE		ret = EPS_ERR_NONE;     /* Return status of internal calls      */
867 	EPS_FILEDSC			fd = EPS_INVALID_FILEDSC;
868 	EPS_PRINT_JOB_USB*	usbPrintJob = (EPS_PRINT_JOB_USB*)printJob.hProtInfo;
869 	EPS_BOOL            selfOpened = FALSE;
870 
871 EPS_LOG_FUNCIN;
872 
873 	if ( EPS_IO_NOT_OPEN == ioOpenState) {
874 	/*** Resolve present port number. And Open the I/O Port for communication           */
875 		ret = PortResolution(printer, &fd);
876         if (ret != EPS_ERR_NONE) {
877 			ClosePortal(((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol, fd);
878 			EPS_RETURN( EPS_ERR_NOT_OPEN_IO );
879 		}
880 
881 		if( EPS_IS_CBT ){
882 			/*** Open the control channel                                               */
883 			ret = cbtCommChannelOpen(fd, EPS_CBTCHANNEL_CTRL, TRUE);
884 			if (ret != EPS_ERR_NONE) {
885 				cbtCommChannelClose(fd, EPS_CBTCHANNEL_CTRL);
886 				ClosePortal(((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol, fd);
887 				EPS_RETURN( EPS_ERR_NOT_OPEN_IO );
888 			}
889 		}
890 		selfOpened = TRUE;
891 
892     } else{ /* Job running now */
893  		if( !usbPrintJob ){
894 			EPS_RETURN( EPS_ERR_OPR_FAIL );
895 		}
896 		fd = usbPrintJob->fd;
897 	}
898 
899 /*** Get PM from Printer                                                                */
900 	ret = InfoCommand(fd, ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol,
901 						type, pString, bufSize);
902 	if( TRUE == selfOpened ){
903 		/* Close Port */
904 		if( EPS_IS_CBT ){
905 			cbtCommChannelClose(fd, EPS_CBTCHANNEL_CTRL);
906 		}
907 		ClosePortal(((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol, fd);
908 	}
909 
910 /*** Return to Caller                                                                   */
911     EPS_RETURN( ret );
912 }
913 
914 
915 /*******************************************|********************************************/
916 /*                                                                                      */
917 /* Function name:   usbGetStatus()                                                      */
918 /*                                                                                      */
919 /* Arguments                                                                            */
920 /* ---------                                                                            */
921 /* Name:        Type:               Description:                                        */
922 /* printer		EPS_PRINTER_INN*    I: Pointer to a PrinterInfo                         */
923 /* status       EPS_STATUS_INFO*    O: Pointer to the printer status.                   */
924 /* ioStatus		EPS_INT32*      	O: It is possible to communicate				    */
925 /* canceling	EPS_BOOL*      		O: Cancel processing            				    */
926 /*                                                                                      */
927 /* Return value:                                                                        */
928 /*      << Normal >>                                                                    */
929 /*      EPS_ERR_NONE                    - Success                                       */
930 /*      << Error >>                                                                     */
931 /*      EPS_ERR_OPR_FAIL                - Internal Error                                */
932 /*      EPS_ERR_COMM_ERROR              - Info command execution error                  */
933 /*      EPS_ERR_NOT_OPEN_IO             - Cannot Open I/O Portal                        */
934 /*      EPS_ERR_NOT_CLOSE_IO            - Cannot Close I/O Portal                       */
935 /*                                                                                      */
936 /* Description:                                                                         */
937 /*      Gets the printer status.                                                        */
938 /*                                                                                      */
939 /*******************************************|********************************************/
usbGetStatus(EPS_STATUS_INFO * pstInfo,EPS_BOOL * pIoStatus,EPS_BOOL * pCancelling)940 EPS_ERR_CODE    usbGetStatus (
941 
942 		EPS_STATUS_INFO*		pstInfo,
943 		EPS_BOOL*				pIoStatus,
944 		EPS_BOOL*				pCancelling
945 
946 ){
947 
948 /*** Declare Variable Local to Routine                                                  */
949 	EPS_ERR_CODE		ret;                    /* Return status of internal calls      */
950 	EPS_FILEDSC			fd = EPS_INVALID_FILEDSC;
951 	EPS_PRINTER_INN*	printer = printJob.printer;
952 	EPS_PRINT_JOB_USB*	usbPrintJob = (EPS_PRINT_JOB_USB*)printJob.hProtInfo;
953 	EPS_BOOL			selfOpend = FALSE;
954 
955 EPS_LOG_FUNCIN;
956 
957 /*** Initialize Local Variables                                                         */
958     ret           = EPS_ERR_NONE;
959     memset(pstInfo, -1, sizeof(EPS_STATUS_INFO));
960 
961     if ( EPS_IO_NOT_OPEN == ioOpenState) {
962 		selfOpend = TRUE;
963 
964 		/*** Resolve present port number. And Open the I/O Port for communication       */
965 		ret = PortResolution(printer, &fd);
966         if (ret != EPS_ERR_NONE) {
967             ret = EPS_ERR_NOT_OPEN_IO;
968 			goto usbGetStatus_END;
969         }
970 
971 		if( EPS_IS_CBT ){
972             /*** Open the control channel                                               */
973 			ret = cbtCommChannelOpen(fd, EPS_CBTCHANNEL_CTRL, TRUE);
974 			if (ret != EPS_ERR_NONE) {
975 				ret = EPS_ERR_NOT_OPEN_IO;
976 				goto usbGetStatus_END;
977 			}
978 		}
979 
980     } else{ /* Job running now */
981  		if( !usbPrintJob ){
982 			EPS_RETURN( EPS_ERR_OPR_FAIL );
983 		}
984 		fd = usbPrintJob->fd;
985 	}
986 
987 
988     /*** Get Printer Status                                                         */
989 	ret = GetBinaryStatus(fd, ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol,
990 							printer->egID, pstInfo);
991     if (ret != EPS_ERR_NONE) {
992 		goto usbGetStatus_END;
993     }
994 
995 	if(NULL != pIoStatus && NULL != pCancelling){
996 		/*** Check I/O status                                                       */
997 		if( EPS_IS_CBT ){
998 			*pCancelling = FALSE;
999 			if(EPS_CAREQ_CANCEL == pstInfo->nCancel
1000 				|| (usbPrintJob && TRUE == usbPrintJob->resetRequest)){
1001 				*pIoStatus = FALSE;
1002 				*pCancelling = TRUE;
1003 				if(usbPrintJob){
1004 					/* Because EPS_CAREQ_CANCEL can be acquired only once, it memorizes. */
1005 					usbPrintJob->resetRequest = TRUE;
1006 				}
1007 			} else if(EPS_IO_OPEN == ioDataChState && FALSE == selfOpend){
1008 				*pIoStatus = TRUE;	/* Evidence */
1009 			} else if(EPS_ST_IDLE == pstInfo->nState){
1010 				if( ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->bCheckDataChannel ){
1011 					if( EPS_IS_CBT ){
1012 						/*** Open Data Channel                                              */
1013 						if (cbtCommChannelOpen(fd, EPS_CBTCHANNEL_DATA, FALSE) == EPS_ERR_NONE) {
1014 							((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->bCheckDataChannel = FALSE;
1015 							*pIoStatus = TRUE;
1016 						} else{
1017 							*pIoStatus = FALSE;
1018 							*pCancelling = TRUE;
1019 						}
1020 						cbtCommChannelClose(fd, EPS_CBTCHANNEL_DATA);
1021 					}
1022 				} else{
1023 					*pIoStatus = TRUE;
1024 				}
1025 			} else{
1026 				*pIoStatus = FALSE;
1027 				if( ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->bCheckDataChannel ){
1028 					*pCancelling = TRUE;
1029 				}
1030 			}
1031 
1032 		} else{
1033 			*pIoStatus = TRUE;      /* Evidence */
1034 			*pCancelling = FALSE;   /* cannot distinguish */
1035 		}
1036 	}
1037 
1038 usbGetStatus_END:
1039 	if(selfOpend){
1040 		/* Close Port */
1041 		if( EPS_IS_CBT ){
1042 			ret = cbtCommChannelClose(fd, EPS_CBTCHANNEL_CTRL);
1043 		}
1044 
1045 		/*ret = */ClosePortal(((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol, fd);
1046 	}
1047 
1048 /*** Return to Caller                                                                   */
1049     EPS_RETURN( ret );
1050 }
1051 
1052 
1053 /*******************************************|********************************************/
1054 /*                                                                                      */
1055 /* Function name:   usbGetJobStatus()                                                   */
1056 /*                                                                                      */
1057 /* Arguments                                                                            */
1058 /* ---------                                                                            */
1059 /* Name:        Type:               Description:                                        */
1060 /* pstInfo      EPS_STATUS_INFO*    O: Printer Status information                       */
1061 /*                                                                                      */
1062 /* Return value:                                                                        */
1063 /*      EPS_ERR_NONE                    - Success                                       */
1064 /*      EPS_ERR_JOB_NOT_INITIALIZED     - JOB is NOT initialized						*/
1065 /*      EPS_ERR_COMM_ERROR              - Communication Error                           */
1066 /*                                                                                      */
1067 /* Description:                                                                         */
1068 /*      Get the printer status and analyze the status string.                           */
1069 /*                                                                                      */
1070 /*******************************************|********************************************/
usbGetJobStatus(EPS_STATUS_INFO * pstInfo)1071 EPS_ERR_CODE    usbGetJobStatus (
1072 
1073         EPS_STATUS_INFO*    pstInfo
1074 
1075 ){
1076 	EPS_ERR_CODE		ret = EPS_ERR_NONE;
1077  	EPS_PRINT_JOB_USB*	usbPrintJob = (EPS_PRINT_JOB_USB*)printJob.hProtInfo;
1078 
1079 EPS_LOG_FUNCIN;
1080 
1081 	if( !usbPrintJob ){
1082 		EPS_RETURN( EPS_ERR_JOB_NOT_INITIALIZED );
1083 	}
1084 
1085 	ret = GetBinaryStatus(usbPrintJob->fd,
1086 			((EPS_USB_PRINTER_INFO*)printJob.printer->protocolInfo)->usbProtocol,
1087 			printJob.printer->egID, pstInfo);
1088 	if(EPS_ERR_NONE == ret
1089 		&& EPS_CAREQ_CANCEL == pstInfo->nCancel){
1090 		usbPrintJob->resetRequest = TRUE;
1091 	}
1092 
1093 	EPS_RETURN( ret );
1094 }
1095 
1096 
1097 /*******************************************|********************************************/
1098 /*                                                                                      */
1099 /* Function name:   usbMechCommand()                                                    */
1100 /*                                                                                      */
1101 /* Arguments                                                                            */
1102 /* ---------                                                                            */
1103 /* Name:        Type:               Description:                                        */
1104 /* Command      EPS_INT32           I: Command Code                                     */
1105 /*                                                                                      */
1106 /* Return value:                                                                        */
1107 /*      EPS_ERR_NONE                    - Mech command executed successfully            */
1108 /*      EPS_ERR_JOB_NOT_INITIALIZED     - JOB is NOT initialized						*/
1109 /*      EPS_ERR_COMM_ERROR              - Mech command execution error                  */
1110 /*                                                                                      */
1111 /* Description:                                                                         */
1112 /*      Sends mechanincal commands to the printer.                                      */
1113 /*                                                                                      */
1114 /*******************************************|********************************************/
usbMechCommand(EPS_INT32 Command)1115 EPS_ERR_CODE    usbMechCommand (
1116 
1117         EPS_INT32   Command
1118 
1119 ){
1120 /*** Declare Variable Local to Routine                                                  */
1121     static EPS_UINT8 stCom[] = {'x', 'x', 0x01, 0x00, 0x01};
1122     EPS_INT8        Reply[32];
1123     EPS_INT32       Size = 32;
1124     EPS_INT32       Retry;
1125     EPS_INT32       ComSize = 0;
1126     EPS_INT32       Ret;
1127     EPS_UINT8*      Com;
1128     EPS_INT32       cSize;
1129 	EPS_PRINT_JOB_USB* usbPrintJob = (EPS_PRINT_JOB_USB*)printJob.hProtInfo;
1130 
1131 EPS_LOG_FUNCIN;
1132 
1133 	if( !usbPrintJob ){
1134 		EPS_RETURN( EPS_ERR_JOB_NOT_INITIALIZED );
1135 	}
1136 
1137 /*** Initialize Local Variables                                                         */
1138     memset(Reply, 0, 32);
1139 
1140 /*** Select Command                                                                     */
1141     switch(Command){
1142     case EPS_CBTCOM_XIA:
1143         stCom[0] = 'x'; stCom[1] = 'i';
1144         break;
1145     case EPS_CBTCOM_XIA2:
1146         stCom[0] = 'x'; stCom[1] = 'i'; stCom[4] = 0x03;
1147         break;
1148     case EPS_CBTCOM_XIA3:
1149         stCom[0] = 'x'; stCom[1] = 'i'; stCom[4] = 0x04;
1150         break;
1151     case EPS_CBTCOM_XIB:
1152         stCom[0] = 'x'; stCom[1] = 'i';stCom[4] = 0x80;
1153         break;
1154     case EPS_CBTCOM_CH:
1155         stCom[0] = 'c'; stCom[1] = 'h';
1156         break;
1157     case EPS_CBTCOM_NC:
1158         stCom[0] = 'n'; stCom[1] = 'c'; stCom[4] = 0x00;
1159         break;
1160     case EPS_CBTCOM_EI:
1161         stCom[0] = 'e'; stCom[1] = 'i'; stCom[4] = 0x00;
1162         break;
1163     case EPS_CBTCOM_PE:
1164         stCom[0] = 'p'; stCom[1] = 'e';
1165         break;
1166     case EPS_CBTCOM_PJ:
1167         stCom[0] = 'p'; stCom[1] = 'j';
1168         break;
1169     }
1170 
1171 /*** Send Command                                                                       */
1172     Retry = 5;
1173     do{
1174         Com   = stCom;
1175         cSize = 5;
1176 
1177         EPS_DBGPRINT(("EPS SER : Sending CHANNEL_COMMAND %c%c\r\n", Com[0], Com[1]));
1178 		if ((Ret = cbtCommWriteData(usbPrintJob->fd, EPS_CBTCHANNEL_CTRL, Com, cSize, &ComSize)) != EPCBT_ERR_NONE){
1179             if (Ret != EPSCBT_ERR_FNCDISABLE){
1180                 EPS_RETURN( EPS_ERR_COMM_ERROR );
1181             }
1182             Retry--;
1183             if (!Retry) {
1184                 EPS_RETURN( EPS_ERR_COMM_ERROR );
1185             }
1186             serDelayThread(2*_SECOND_, &epsCmnFnc);        /* retry command after 2 seconds */
1187         }
1188     }while (Ret == EPSCBT_ERR_FNCDISABLE);
1189 
1190 /*** Read Reply                                                                         */
1191     Retry = 5;
1192     do{
1193         if ((Ret = cbtCommReadData(usbPrintJob->fd, EPS_CBTCHANNEL_CTRL, (EPS_UINT8 *)Reply, 32, &Size)) != EPCBT_ERR_NONE){
1194             if (Ret != EPSCBT_ERR_FNCDISABLE){
1195                 EPS_DBGPRINT(("EPS SER : CBT Command Write Reply Failed [%d]\r\n",Ret));
1196                 EPS_RETURN( EPS_ERR_COMM_ERROR );
1197             }
1198         }else if (Size != 0){
1199             break;
1200         }
1201 
1202         Retry--;
1203         if (!Retry){
1204             EPS_DBGPRINT(("EPS SER : CBT Command Write Reply Retry Failed \r\n"));
1205             EPS_RETURN( EPS_ERR_COMM_ERROR );
1206         }
1207         serDelayThread(2*_SECOND_, &epsCmnFnc);        /* retry command after 2 seconds*/
1208     }while(Retry > 0);
1209 
1210 /*** Check Reply                                                                        */
1211     EPS_DBGPRINT(("EPS SER : Mech Command reply -> %s\r\n", Reply));
1212     if (strstr(Reply,"OK") == NULL){
1213         EPS_RETURN( EPS_ERR_COMM_ERROR );
1214     }
1215 
1216 /*** Return to Caller                                                                   */
1217     EPS_RETURN( EPS_ERR_NONE );
1218 }
1219 
1220 
usbInfoCommand(const EPS_PRINTER_INN * printer,EPS_INT32 command,EPS_UINT8 ** buffer,EPS_INT32 * bufSize)1221 EPS_ERR_CODE   usbInfoCommand (
1222 
1223 		const EPS_PRINTER_INN*	printer,
1224 		EPS_INT32   command,
1225         EPS_UINT8** buffer,
1226         EPS_INT32*  bufSize
1227 
1228 ){
1229 	EPS_ERR_CODE	ret = EPS_ERR_NONE;
1230 	EPS_FILEDSC		fd = EPS_INVALID_FILEDSC;
1231 
1232 	ret = OpenPortal((EPS_USB_PRINTER_INFO*)printer->protocolInfo, &fd );
1233 	if( EPS_ERR_NONE == ret ){
1234 		if( EPS_IS_CBT ){
1235 			ret = cbtCommChannelOpen(fd, EPS_CBTCHANNEL_CTRL, TRUE);
1236 		}
1237 
1238 		if( EPS_ERR_NONE == ret ){
1239 			ret = InfoCommand(fd, ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol,
1240 							command, buffer, bufSize);
1241 
1242 			if( EPS_IS_CBT ){
1243 				cbtCommChannelClose(fd, EPS_CBTCHANNEL_CTRL);
1244 			}
1245 		}
1246 
1247 		ClosePortal(((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol, fd);
1248 	}
1249 
1250 	return ret;
1251 }
1252 
1253 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1254 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1255 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/
1256 /*--------------------               Local Functions               ---------------------*/
1257 /*%%%%%%%%%%%%%%%%%%%%                                             %%%%%%%%%%%%%%%%%%%%%*/
1258 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1259 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
1260 
1261 /*******************************************|********************************************/
1262 /*                                                                                      */
1263 /* Function name:   GetBinaryStatus()                                                   */
1264 /*                                                                                      */
1265 /* Arguments                                                                            */
1266 /* ---------                                                                            */
1267 /* Name:        Type:               Description:                                        */
1268 /* fd			EPS_FILEDSC		    I: file discripter                                  */
1269 /* usbProtocol  EPS_UINT32          I: usb protocol kind                                */
1270 /* egID         EPS_UINT32          I: printer error group id                           */
1271 /* pstInfo      EPS_STATUS_INFO*    O: Printer Status information                       */
1272 /*                                                                                      */
1273 /* Return value:                                                                        */
1274 /*      EPS_ERR_NONE                    - Success                                       */
1275 /*      EPS_ERR_COMM_ERROR              - Communication Error                           */
1276 /*                                                                                      */
1277 /* Description:                                                                         */
1278 /*      Get the printer status and analyze the status string.                           */
1279 /*                                                                                      */
1280 /*******************************************|********************************************/
GetBinaryStatus(EPS_FILEDSC fd,EPS_UINT32 usbProtocol,EPS_UINT32 egID,EPS_STATUS_INFO * pstInfo)1281 static EPS_ERR_CODE    GetBinaryStatus (
1282 
1283 		EPS_FILEDSC         fd,
1284         EPS_UINT32          usbProtocol,
1285 		EPS_UINT32          egID,
1286         EPS_STATUS_INFO*    pstInfo
1287 
1288 ){
1289     EPS_UINT8   Status[_STATUS_REPLY_BUF];
1290 	EPS_INT32   Size = _STATUS_REPLY_BUF;
1291 	EPS_INT32   ret = 0;
1292 	EPS_UINT8*	pStatus = &Status[0];
1293 
1294 EPS_LOG_FUNCIN;
1295 
1296 	memset(Status, 0x00, _STATUS_REPLY_BUF);
1297 
1298 	ret = InfoCommand(fd, usbProtocol, EPS_CBTCOM_ST, &pStatus, &Size);
1299 	if( EPS_ERR_NONE != ret ){
1300 		EPS_DBGPRINT(("EPS SER: Get Stat -> CBT Com Failed\r\n"));
1301 		EPS_RETURN( EPS_ERR_COMM_ERROR );
1302 	}
1303 
1304     EPS_RETURN( serAnalyzeStatus((EPS_INT8*)Status, egID, pstInfo) );
1305 }
1306 
1307 
1308 /*******************************************|********************************************/
1309 /*                                                                                      */
1310 /* Function name:   ProbeESCPR()                                                        */
1311 /*                                                                                      */
1312 /* Arguments                                                                            */
1313 /* ---------                                                                            */
1314 /* Name:        Type:               Description:                                        */
1315 /* dev			EPS_USB_DEVICE*     I: Pointer to a usb device infomatio                */
1316 /* manufacturer EPS_INT8*           O: Pointer to a 64-byte buffer for the manufacturer */
1317 /*                                     name.                                            */
1318 /* modelName    EPS_INT8*           O: Pointer to a 64-byte buffer for the printer      */
1319 /*                                     model name.                                      */
1320 /*                                                                                      */
1321 /* Return value:                                                                        */
1322 /*      EPS_ERR_NONE                    - Success                                       */
1323 /*      EPS_ERR_OPR_FAIL                - Internal Error                                */
1324 /*      EPS_ERR_MEMORY_ALLOCATION       - Failed to allocate memory                     */
1325 /*      EPS_ERR_NOT_OPEN_IO             - Cannot Open I/O Portal                        */
1326 /*      EPS_ERR_COMM_ERROR              - Communication Error                           */
1327 /*      EPS_ERR_PRINTER_NOT_FOUND       - Connected printer is not supported            */
1328 /*                                                                                      */
1329 /* Description:                                                                         */
1330 /*      Opens the portal, gets the printer's DeviceString, parses it.                   */
1331 /*                                                                                      */
1332 /*******************************************|********************************************/
ProbeESCPR(EPS_USB_PRINTER_INFO * usbInfo,EPS_INT8 * manufacturer,EPS_INT8 * modelName,EPS_INT32 * cmdLevel,EPS_UINT32 * egID)1333 static EPS_ERR_CODE     ProbeESCPR (
1334 
1335 		EPS_USB_PRINTER_INFO*	usbInfo,
1336         EPS_INT8*				manufacturer,
1337         EPS_INT8*				modelName,
1338 		EPS_INT32*              cmdLevel,
1339 		EPS_UINT32*				egID
1340 
1341 ){
1342 /*** Declare Variable Local to Routine                                                  */
1343     EPS_ERR_CODE    retStatus = EPS_ERR_NONE;
1344 	EPS_INT32		ret = 0;
1345 	EPS_FILEDSC		fd = EPS_INVALID_FILEDSC;
1346     EPS_INT8*       tmpDeviceIdBuf = NULL;
1347 	EPS_INT32		bufSizeOrg = 0;
1348 	EPS_INT32		bufSize = EPS_DI_MAXSIZE-1;
1349     EPS_INT32       found_dev;
1350 
1351 EPS_LOG_FUNCIN;
1352 
1353 /*** Initialize Local Variables                                                         */
1354     retStatus = EPS_ERR_NONE;
1355     found_dev = FALSE;
1356 
1357 	EPS_DBGPRINT(("PROT=%d / PID=%04X / VID=%04X\n", usbInfo->dev.port, usbInfo->dev.pid, usbInfo->dev.vid))
1358 
1359     if ( EPS_IO_OPEN != ioOpenState  ) {
1360         if ( (fd = epsUsbFnc.openPortal(&usbInfo->dev)) == EPS_INVALID_FILEDSC){
1361             EPS_RETURN( EPS_ERR_NOT_OPEN_IO );
1362 		}
1363 	} else{
1364 		EPS_RETURN( EPS_ERR_2ND_OPEN_IO );
1365 	}
1366 
1367 	do{
1368 		bufSizeOrg = bufSize + 1; /* +1=NULL terminate */
1369 
1370 		/* Allocate temp buffer */
1371 		EPS_SAFE_RELEASE(tmpDeviceIdBuf);
1372 		tmpDeviceIdBuf = (EPS_INT8*)EPS_ALLOC(bufSizeOrg);
1373 		if (tmpDeviceIdBuf == NULL) {
1374 			EPS_RETURN( EPS_ERR_MEMORY_ALLOCATION );
1375 		}
1376 		memset(tmpDeviceIdBuf, 0, bufSizeOrg);
1377 
1378 		/* Get deviceID string */
1379 		ret = epsUsbFnc.getDeviceID(fd, tmpDeviceIdBuf, &bufSize);
1380 	}while(bufSize > bufSizeOrg && 0 != ret);
1381 
1382 	if( 0 == ret ){
1383 		found_dev = (serParseDeviceID(tmpDeviceIdBuf, bufSize, manufacturer, modelName, cmdLevel, NULL, egID) > 0);
1384 		if(found_dev <= 0) {
1385 			retStatus = EPS_ERR_PRINTER_NOT_FOUND;
1386 		}
1387 
1388 	} else{
1389 		retStatus = EPS_ERR_COMM_ERROR;
1390 	}
1391 
1392 	if( EPS_ERR_NONE == retStatus ){
1393 		ParseUsbProtocol(tmpDeviceIdBuf, bufSize, &usbInfo->usbProtocol);
1394 	}
1395 
1396 	EPS_SAFE_RELEASE(tmpDeviceIdBuf);
1397 
1398     if ( EPS_IO_OPEN != ioOpenState  ) {
1399 		epsUsbFnc.closePortal(fd);
1400     }
1401 
1402     EPS_RETURN( retStatus );
1403 }
1404 
1405 
1406 /*******************************************|********************************************/
1407 /*                                                                                      */
1408 /* Function name:   CreatePrinterInfo()                                                 */
1409 /*                                                                                      */
1410 /* Arguments                                                                            */
1411 /* ---------                                                                            */
1412 /* Name:        Type:               Description:                                        */
1413 /* dev			EPS_USB_DEVICE*     I: Pointer to a usb device infomatio                */
1414 /* manufacturer EPS_INT8*           I: Pointer to a 64-byte buffer for the manufacturer */
1415 /*                                     name.                                            */
1416 /* modelName    EPS_INT8*           I: Pointer to a 64-byte buffer for the printer      */
1417 /*                                     model name.                                      */
1418 /* printer		EPS_PRINTER_INN**   O: pointer for found printer structure              */
1419 /*                                                                                      */
1420 /* Return value:                                                                        */
1421 /*      EPS_ERR_NONE                    - Success                                       */
1422 /*      EPS_ERR_OPR_FAIL                - Internal Error                                */
1423 /*      EPS_ERR_MEMORY_ALLOCATION       - Failed to allocate memory                     */
1424 /*                                                                                      */
1425 /* Description:                                                                         */
1426 /*      Create Printer info structure and setup data.                                   */
1427 /*                                                                                      */
1428 /*******************************************|********************************************/
CreatePrinterInfo(EPS_USB_PRINTER_INFO * usbInfo,const EPS_INT8 * manufacturer,const EPS_INT8 * modelName,const EPS_INT8 * serialNo,EPS_INT32 cmdLevel,EPS_UINT32 egID,EPS_PRINTER_INN ** printer)1429 static EPS_ERR_CODE     CreatePrinterInfo (
1430 
1431 		EPS_USB_PRINTER_INFO*	usbInfo,
1432         const EPS_INT8*			manufacturer,
1433         const EPS_INT8*			modelName,
1434         const EPS_INT8*			serialNo,
1435 		EPS_INT32               cmdLevel,
1436 		EPS_UINT32              egID,
1437 		EPS_PRINTER_INN**		printer
1438 
1439 ){
1440 /*** Declare Variable Local to Routine                                                  */
1441     EPS_ERR_CODE    retStatus;
1442     EPS_INT8		usbIDString[EPS_NAME_BUFFSIZE];
1443 	EPS_USB_PRINTER_INFO*	pUsbPrinter = NULL;
1444 
1445 EPS_LOG_FUNCIN;
1446 
1447 /*** Initialize Local Variables                                                         */
1448     retStatus = EPS_ERR_NONE;
1449 
1450 /*** Create printer info structure                                                      */
1451 	*printer = (EPS_PRINTER_INN*)EPS_ALLOC( sizeof(EPS_PRINTER_INN) );
1452 	if(NULL == *printer){
1453 		retStatus = EPS_ERR_MEMORY_ALLOCATION;
1454 		goto CreatePrinterInfo_ERROR;
1455 	}
1456 	memset( *printer, 0, sizeof(EPS_PRINTER_INN) );
1457 
1458 	pUsbPrinter = (EPS_USB_PRINTER_INFO*)EPS_ALLOC( sizeof(EPS_USB_PRINTER_INFO) );
1459 	if(NULL == pUsbPrinter){
1460 		retStatus = EPS_ERR_MEMORY_ALLOCATION;
1461 		goto CreatePrinterInfo_ERROR;
1462 	}
1463 	memcpy(pUsbPrinter, usbInfo, sizeof(EPS_USB_PRINTER_INFO));
1464 	(*printer)->protocolInfo = pUsbPrinter;
1465 
1466     strcpy( (*printer)->location, EPS_USB_NAME );
1467 	strcpy( (*printer)->manufacturerName, manufacturer );
1468 	strcpy( (*printer)->modelName, modelName );
1469 	strcpy( (*printer)->serialNo, serialNo );
1470 	(*printer)->protocol = EPS_PROTOCOL_USB;
1471 	(*printer)->protocol |= EPS_PRT_DIRECTION(printJob.commMode);
1472 	(*printer)->language = EPS_LANG_ESCPR; /* ESC/P-R only via USB */
1473 	(*printer)->egID = egID;
1474 
1475 	if(0 == cmdLevel){
1476 		cmdLevel = 0xFFFFFFFF;	/* Support all. For Uin communication  */
1477 	}
1478 	(*printer)->supportFunc |= EPS_SPF_RGBPRINT; /* RGB print */
1479 	if(cmdLevel & 0x0002){
1480 		(*printer)->supportFunc |= EPS_SPF_JPGPRINT; /* Jpeg print */
1481 	}
1482 
1483 	sprintf(usbIDString, EPS_USB_IDPRM_STR, usbInfo->dev.vid, usbInfo->dev.pid, modelName);
1484 	prtSetIdStr(*printer, usbIDString);
1485 
1486 CreatePrinterInfo_ERROR:
1487 	if(EPS_ERR_NONE != retStatus){
1488 		EPS_SAFE_RELEASE( pUsbPrinter );
1489 		EPS_SAFE_RELEASE( *printer );
1490 	}
1491 
1492     EPS_RETURN( retStatus );
1493 }
1494 
1495 
1496 /*******************************************|********************************************/
1497 /*                                                                                      */
1498 /* Function name:   PortResolution()                                                    */
1499 /*                                                                                      */
1500 /* Arguments                                                                            */
1501 /* ---------                                                                            */
1502 /* Name:        Type:               Description:                                        */
1503 /* printer		EPS_PRINTER_INN*    I: pointer for found printer structure              */
1504 /*                                                                                      */
1505 /* Return value:                                                                        */
1506 /*      EPS_ERR_NONE                    - Success                                       */
1507 /*      EPS_ERR_MEMORY_ALLOCATION       - Failed to allocate memory                     */
1508 /*      EPS_ERR_NOT_OPEN_IO             - Cannot Open I/O Portal                        */
1509 /*      EPS_ERR_PRINTER_NOT_FOUND	    - Printer not found (or error occur)	        */
1510 /*                                                                                      */
1511 /* Description:                                                                         */
1512 /*      Resolve present port number.                                                    */
1513 /*                                                                                      */
1514 /*******************************************|********************************************/
PortResolution(const EPS_PRINTER_INN * printer,EPS_FILEDSC * pFd)1515 static EPS_ERR_CODE   PortResolution(
1516 
1517 		const EPS_PRINTER_INN*		printer,
1518 		EPS_FILEDSC*				pFd
1519 
1520 ){
1521 
1522 /*** Declare Variable Local to Routine                                                  */
1523     EPS_ERR_CODE	ret = EPS_ERR_NONE;			 /* Return status of internal calls */
1524     EPS_BOOL		bNeedResolve = TRUE;
1525 	EPS_FILEDSC		fdInt = EPS_INVALID_FILEDSC;
1526 	EPS_INT8		modelName[EPS_NAME_BUFFSIZE];       /* Printer model name       */
1527 
1528 EPS_LOG_FUNCIN;
1529 
1530 	*pFd = EPS_INVALID_FILEDSC;
1531 
1532     if( !EPS_IS_BI_PROTOCOL(printer->protocol) ){
1533 		EPS_RETURN( EPS_ERR_NEED_BIDIRECT );
1534 	}
1535 
1536 	/*** Validate this is an Epson ESC/PR Printer                                       */
1537 	ret = ProbeESCPR((EPS_USB_PRINTER_INFO*)printer->protocolInfo,
1538 						NULL, modelName, NULL, NULL);
1539 	if(EPS_ERR_NONE == ret){
1540 		/*** Printer names compare.                                                     */
1541 		if( 0 == strcmp(modelName, printer->modelName) ){
1542 			bNeedResolve = FALSE;
1543 		}
1544 	}
1545 
1546 	if(bNeedResolve){
1547 		if(EPS_INVALID_FILEDSC != fdInt){
1548 			ClosePortal( ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol, fdInt);
1549 			fdInt = EPS_INVALID_FILEDSC;
1550 		}
1551 
1552 		/* Probe other port */
1553 		ret = ProbePrinterByName(printer->modelName, FALSE, 0, (EPS_USB_PRINTER_INFO*)printer->protocolInfo,
1554 								NULL, modelName, NULL, NULL);
1555 	}
1556 
1557 	/* open portal */
1558 	if( EPS_ERR_NONE == ret ){
1559 		ret = OpenPortal((EPS_USB_PRINTER_INFO*)printer->protocolInfo, &fdInt);
1560 	}
1561 
1562 	if( EPS_ERR_NONE == ret ){
1563 		*pFd = fdInt;
1564 	} else{
1565 		if(EPS_INVALID_FILEDSC != fdInt){
1566 			ClosePortal( ((EPS_USB_PRINTER_INFO*)printer->protocolInfo)->usbProtocol, fdInt);
1567 		}
1568 	}
1569 
1570 	EPS_RETURN( ret );
1571 }
1572 
1573 
1574 /*******************************************|********************************************/
1575 /*                                                                                      */
1576 /* Function name:   ProbePrinterByName()                                                */
1577 /*                                                                                      */
1578 /* Arguments                                                                            */
1579 /* ---------                                                                            */
1580 /* Name:        Type:               Description:                                        */
1581 /* modelNameTgt EPS_INT8*           I: target printer modelname                         */
1582 /* enableBreak	EPS_BOOL            I: enable break                                     */
1583 /* timeout      EPS_UINT32          I: find timeout                                     */
1584 /* dev			EPS_USB_DEVICE*     O: Pointer to a usb device infomatio                */
1585 /* manufacturer EPS_INT8*           O: Pointer to a 64-byte buffer for the manufacturer */
1586 /*                                     name.                                            */
1587 /* modelName    EPS_INT8*           O: Pointer to a 64-byte buffer for the printer      */
1588 /*                                     model name.                                      */
1589 /*                                                                                      */
1590 /* Return value:                                                                        */
1591 /*      EPS_ERR_NONE                    - Success (printer found)                       */
1592 /*      EPS_ERR_PRINTER_NOT_FOUND       - printer not found                             */
1593 /*      EPS_ERR_MEMORY_ALLOCATION       - Fail to memory allocation                     */
1594 /*      EPS_ERR_NOT_OPEN_IO             - Cannot Open I/O Portal                        */
1595 /*                                                                                      */
1596 /* Description:                                                                         */
1597 /*     looks for specified printer.                                                     */
1598 /*                                                                                      */
1599 /*******************************************|********************************************/
ProbePrinterByName(const EPS_INT8 * modelNameTgt,EPS_BOOL enableBreak,EPS_UINT32 timeout,EPS_USB_PRINTER_INFO * usbInfo,EPS_INT8 * manufacturer,EPS_INT8 * modelName,EPS_INT32 * cmdLevel,EPS_UINT32 * egID)1600 static EPS_ERR_CODE   ProbePrinterByName (
1601 
1602 		const EPS_INT8*	modelNameTgt,
1603 		EPS_BOOL		enableBreak,
1604         EPS_UINT32      timeout,
1605 		EPS_USB_PRINTER_INFO*	usbInfo,
1606 		EPS_INT8*		manufacturer,
1607 		EPS_INT8*		modelName,
1608 		EPS_INT32*      cmdLevel,
1609 		EPS_UINT32*		egID
1610 
1611 ){
1612 /*** Declare Variable Local to Routine                                                  */
1613     EPS_ERR_CODE	ret = EPS_ERR_NONE;			 /* Return status of internal calls     */
1614     EPS_BOOL		found = FALSE;
1615 	EPS_FILEDSC		fd = EPS_INVALID_FILEDSC;
1616 	EPS_UINT32		tmStart, tmNow, tmSpan;
1617 
1618 EPS_LOG_FUNCIN;
1619 
1620 	if(NULL != modelName)*modelName = '\0';
1621 	if(NULL != manufacturer)*manufacturer = '\0';
1622 
1623 	fd = epsUsbFnc.findFirst( &usbInfo->dev );
1624 	if(EPS_INVALID_FILEDSC != fd){
1625 		if(epsCmnFnc.getTime){
1626 			tmStart = epsCmnFnc.getTime();
1627 		} else{
1628 			timeout = tmStart = tmNow = tmSpan = 0;
1629 		}
1630 
1631 		do{
1632 			/*** Validate this is an Epson ESC/PR Printer                               */
1633 			ret = ProbeESCPR(usbInfo, manufacturer, modelName, cmdLevel, egID);
1634 
1635 			if(EPS_ERR_NONE == ret){
1636 				if( 0 == strcmp(modelNameTgt, modelName) ){
1637 					/* Found target printer */
1638 					found = TRUE;
1639 					break;
1640 				}
1641 			} else if(EPS_ERR_PRINTER_NOT_FOUND != ret){
1642 				break;
1643 			}
1644 
1645 			if(timeout > 0){
1646 				tmNow = epsCmnFnc.getTime();
1647 				tmSpan = (EPS_UINT32)(tmNow - tmStart);
1648 				EPS_DBGPRINT( ("TM %u - %u <> %u\n", tmNow, tmStart, tmSpan) )
1649 				if( tmSpan >= timeout ){
1650 					break;
1651 				}
1652 			}
1653 			if( enableBreak ){
1654 				if( 0 == epsCmnFnc.lockSync() ){
1655 					if( g_FindBreak ){
1656 						epsCmnFnc.unlockSync();
1657 						break;
1658 					}
1659 					epsCmnFnc.unlockSync();
1660 				}
1661 			}
1662 		}while( epsUsbFnc.findNext( fd, &usbInfo->dev ) );
1663 
1664 		epsUsbFnc.findClose(fd);
1665 	}
1666 
1667 	if(EPS_ERR_NONE == ret){
1668 		ret = (found?EPS_ERR_NONE:EPS_ERR_PRINTER_NOT_FOUND);
1669 	}
1670 
1671 	EPS_RETURN( ret );
1672 }
1673 
1674 
1675 /*******************************************|********************************************/
1676 /*                                                                                      */
1677 /* Function name:   InfoCommand()                                                       */
1678 /*                                                                                      */
1679 /* Arguments                                                                            */
1680 /* ---------                                                                            */
1681 /* Name:        Type:               Description:                                        */
1682 /* Command      EPS_INT32           I: Command Code                                     */
1683 /* pResult      EPS_UINT8*          O: Result of Info command                           */
1684 /* Size         EPS_INT32*          I/O: size of buffer                                 */
1685 /*                                                                                      */
1686 /* Return value:                                                                        */
1687 /*      EPS_ERR_NONE                    - Info command executed successfully            */
1688 /*      EPS_ERR_COMM_ERROR              - Info command execution error                  */
1689 /*                                                                                      */
1690 /* Description:                                                                         */
1691 /*      Sends Information commands to the printer.                                      */
1692 /*                                                                                      */
1693 /*******************************************|********************************************/
InfoCommand(EPS_FILEDSC fd,EPS_UINT32 usbProtocol,EPS_INT32 Command,EPS_UINT8 ** pResult,EPS_INT32 * Size)1694 static EPS_ERR_CODE   InfoCommand (
1695 
1696 		EPS_FILEDSC	fd,
1697         EPS_UINT32  usbProtocol,
1698         EPS_INT32   Command,
1699         EPS_UINT8** pResult,
1700         EPS_INT32*  Size
1701 
1702 ){
1703     EPS_ERR_CODE    ret = EPS_ERR_NONE;
1704 
1705 	EPS_LOG_FUNCIN;
1706 
1707 	if(EPS_USBP_CBT == usbProtocol){
1708 		ret = CbtInfoCommand(fd, Command, pResult, Size);
1709 	} else /* END4 */ {
1710 		ret = RmtInfoCommand(fd, Command, pResult, Size);
1711 	}
1712 
1713     EPS_RETURN( ret );
1714 }
1715 
1716 
CbtInfoCommand(EPS_FILEDSC fd,EPS_INT32 Command,EPS_UINT8 ** pResult,EPS_INT32 * Size)1717 static EPS_ERR_CODE   CbtInfoCommand (
1718 
1719 		EPS_FILEDSC	fd,
1720         EPS_INT32   Command,
1721         EPS_UINT8** pResult,
1722         EPS_INT32*  Size
1723 
1724 ){
1725     static EPS_UINT8 stCom[5] = {'x', 'x', 0x01,0x00,0x01};
1726     EPS_INT32        ComSize  = 0;
1727     EPS_INT32        Retry;
1728     EPS_INT32        Ret;
1729     EPS_INT32        lSize;
1730 
1731 	EPS_LOG_FUNCIN;
1732 
1733 	if(NULL == *pResult && 0 == *Size){
1734 		*pResult = (EPS_UINT8*)EPS_ALLOC(EPS_PM_BASESIZE);
1735 		if(NULL == *pResult){
1736 			EPS_RETURN( EPS_ERR_MEMORY_ALLOCATION )
1737 		}
1738 		*Size = EPS_PM_BASESIZE;
1739 	}
1740 
1741 	switch(Command){
1742     case EPS_CBTCOM_DI:
1743         stCom[0] = 'd'; stCom[1] = 'i'; stCom[4] = 0x01;
1744         break;
1745     case EPS_CBTCOM_ST:
1746         stCom[0] = 's'; stCom[1] = 't'; stCom[4] = 0x01;
1747         break;
1748     case EPS_CBTCOM_PM:
1749         stCom[0] = 'p'; stCom[1] = 'm'; stCom[4] = 0x01;
1750         break;
1751     case EPS_CBTCOM_PM2:
1752         stCom[0] = 'p'; stCom[1] = 'm'; stCom[4] = 0x02;
1753         break;
1754     case EPS_CBTCOM_PM3:
1755         stCom[0] = 'p'; stCom[1] = 'm'; stCom[4] = 0x03;
1756         break;
1757     case EPS_CBTCOM_CD:
1758         stCom[0] = 'c'; stCom[1] = 'd'; stCom[4] = 0x00;
1759         break;
1760 	case EPS_CBTCOM_VI5:
1761         stCom[0] = 'v'; stCom[1] = 'i'; stCom[4] = 0x05;
1762         break;
1763 	default:
1764 		EPS_RETURN( EPS_ERR_OPR_FAIL );
1765     }
1766 
1767     Retry = 5;
1768     do{
1769         if ((Ret = cbtCommWriteData(fd, EPS_CBTCHANNEL_CTRL, stCom, 5, &ComSize)) != EPCBT_ERR_NONE){
1770             EPS_DBGPRINT(("EPS SER : CBT Command Write Failed [%d]\r\n",Ret));
1771             if (Ret != EPSCBT_ERR_FNCDISABLE && Ret != EPSCBT_ERR_WRITEERROR){
1772                 EPS_RETURN( EPS_ERR_COMM_ERROR );
1773             }
1774 
1775             Retry--;
1776             if (!Retry) {
1777                 EPS_DBGPRINT(("EPS SER : CBT Command Write Retry Failed \r\n"));
1778                 EPS_RETURN( EPS_ERR_COMM_ERROR );
1779             }
1780             serDelayThread(2*_SECOND_, &epsCmnFnc);       /* retry command after 2 seconds*/
1781         }
1782     }while (Ret == EPSCBT_ERR_FNCDISABLE);
1783 
1784     Retry = 5;
1785     lSize = *Size;
1786     do{
1787         if ((Ret = cbtCommReadData(fd, EPS_CBTCHANNEL_CTRL, *pResult, lSize, Size)) != EPCBT_ERR_NONE){
1788             EPS_DBGPRINT(("EPS SER : CBT Command Read Reply Failed [%d]\r\n",Ret));
1789             if (Ret != EPSCBT_ERR_FNCDISABLE && Ret != EPSCBT_ERR_READERROR){
1790 				EPS_SAFE_RELEASE(*pResult);
1791 				*Size = 0;
1792                 EPS_RETURN( EPS_ERR_COMM_ERROR );
1793             }
1794         }else if (*Size != 0){
1795             break;
1796         }
1797 
1798         Retry--;
1799         if (!Retry){
1800             EPS_DBGPRINT(("EPS SER : CBT Command Read Reply Retry Failed \r\n"));
1801 			EPS_SAFE_RELEASE(*pResult);
1802 			*Size = 0;
1803             EPS_RETURN( EPS_ERR_COMM_ERROR );
1804         }
1805         serDelayThread(2*_SECOND_, &epsCmnFnc);       /* retry command after 2 seconds*/
1806     }while(Retry > 0);
1807 
1808 	if( *Size < 5 || 0 == memcmp(&(*pResult)[3], "NA", 2) ){
1809 		EPS_SAFE_RELEASE(*pResult);
1810 		*Size = 0;
1811 		EPS_RETURN( EPS_ERR_PRINTER_NOT_SUPPORTED );
1812 	}
1813 
1814     (*pResult)[*Size] = '\0';
1815 
1816     EPS_RETURN( EPS_ERR_NONE );
1817 }
1818 
1819 
RmtInfoCommand(EPS_FILEDSC fd,EPS_INT32 Command,EPS_UINT8 ** pResult,EPS_INT32 * Size)1820 static EPS_ERR_CODE   RmtInfoCommand (
1821 
1822 		EPS_FILEDSC	fd,
1823         EPS_INT32   Command,
1824         EPS_UINT8** pResult,
1825         EPS_INT32*  Size
1826 
1827 ){
1828     EPS_UINT8 stCom[27] = {0x1B, 0x28, 0x52, 0x08, 0x00, 0x00, 'R', 'E', 'M', 'O', 'T', 'E', '1',
1829 							'P', 'I', 0x06,0x00,0x01, 0x00, 0x00,0x00, 0x00,0x00,
1830 							0x1B, 0x00, 0x00, 0x00};
1831     const EPS_INT8 *rsp = "@BDC PI\x0D\x0A";
1832     EPS_UINT8 rspBuff[EPS_PM_BASESIZE];
1833     EPS_INT32 rspSize = sizeof(rspBuff);
1834     EPS_INT32 ComSize = sizeof(stCom);
1835     EPS_INT32 ret = 0;
1836  	EPS_INT32 retry = 0;
1837     EPS_INT32 packetSize = 0;
1838     EPS_INT32 packetNum = 0;
1839     EPS_INT32 totalRespSize = 0;
1840     EPS_INT32 n = 0;
1841     EPS_BOOL  rcvResponce = FALSE;
1842 	EPS_STATUS_INFO stInfo;
1843 
1844 	EPS_LOG_FUNCIN;
1845 
1846 	if(NULL == *pResult && 0 == *Size){
1847 		*pResult = (EPS_UINT8*)EPS_ALLOC(EPS_PM_BASESIZE);
1848 		if(NULL == *pResult){
1849 			EPS_RETURN( EPS_ERR_MEMORY_ALLOCATION )
1850 		}
1851 		*Size = EPS_PM_BASESIZE;
1852 	}
1853 
1854 	/* step 0: dummy(ST) read */
1855 	for(retry = 0; retry < EPS_STAT_RETRY; retry++){
1856 		rspSize = *Size;
1857 		ret = nd4ReadPortal(fd, *pResult, &rspSize);
1858 		/*EPS_DUMP(*pResult, rspSize)*/
1859 		if( EPS_ERR_NONE != ret ){
1860 			EPS_RETURN( EPS_ERR_COMM_ERROR );
1861 		}
1862 		if( 0 == memcmp(*pResult, "@BDC ST2\x0D\x0A", 10) ){
1863 			break;
1864 		}
1865 	}
1866 	if(EPS_CBTCOM_ST == Command){
1867 	    EPS_RETURN( EPS_ERR_NONE );
1868 	}
1869 
1870 	/* check IDLE */
1871 	ret = serAnalyzeStatus((EPS_INT8*)*pResult, 0, &stInfo);
1872 	if( EPS_ERR_NONE != ret ){
1873 		EPS_RETURN( EPS_ERR_COMM_ERROR );
1874 	}
1875 	if( EPS_ST_IDLE != stInfo.nState ){
1876 		EPS_RETURN( EPS_ERR_COMM_ERROR );
1877 	}
1878 
1879 	/* set command parameter */
1880 	rspSize = sizeof(rspBuff);
1881 	stCom[21] = rspSize & 0x000000FF;
1882 	stCom[22] = (rspSize & 0x0000FF00) >> 8;
1883 	switch(Command){
1884     case EPS_CBTCOM_PM:
1885 		stCom[18] = 0x80;
1886 		strcpy((EPS_INT8*)*pResult, "@BDC PM\x0D\x0A");
1887 		totalRespSize = 9;
1888         break;
1889     case EPS_CBTCOM_PM2:
1890 		stCom[18] = 0x81;
1891 		strcpy((EPS_INT8*)*pResult, "@BDC PM\x0D\x0A");
1892 		totalRespSize = 9;
1893         break;
1894     case EPS_CBTCOM_PM3:
1895 		stCom[18] = 0x82;
1896 		totalRespSize = 0;
1897         break;
1898     case EPS_CBTCOM_CD:
1899 		stCom[18] = 0x00;
1900         break;
1901 	default:
1902 		EPS_RETURN( EPS_ERR_OPR_FAIL );
1903     }
1904 
1905 	/* step 1: get reply size */
1906 	/*EPS_DUMP(stCom, ComSize)*/
1907 	ret = nd4WritePortal(fd, stCom, &ComSize);
1908 	if( EPS_ERR_NONE != ret ){
1909 		EPS_RETURN( EPS_ERR_COMM_ERROR );
1910 	}
1911 
1912 	for(retry = 0; retry < EPS_STAT_RETRY; retry++){
1913 		rspSize = sizeof(rspBuff);
1914 		ret = nd4ReadPortal(fd, rspBuff, &rspSize);
1915 		/*EPS_DUMP(rspBuff, rspSize)*/
1916 
1917 		if( EPS_ERR_NONE != ret ){
1918 			EPS_RETURN( EPS_ERR_COMM_ERROR );
1919 		}
1920 		if( 0 == memcmp(rsp, rspBuff, strlen(rsp)) ){
1921 			rcvResponce = TRUE;
1922 			break;
1923 		}
1924 	}
1925 	if( FALSE == rcvResponce){
1926 		EPS_RETURN( EPS_ERR_COMM_ERROR );
1927 	}
1928 	if( 0 == memcmp(&rspBuff[21], "NA", 2) ){
1929 		EPS_RETURN( EPS_ERR_PRINTER_NOT_SUPPORTED );
1930 	} else if( rspSize < 24 || 0 == memcmp(&rspBuff[21], "BUSY", 4)){
1931 		EPS_RETURN( EPS_ERR_COMM_ERROR );
1932 	}
1933 
1934 	packetNum = rspBuff[21] + (rspBuff[22]<<8);
1935 	packetSize= rspBuff[23] + (rspBuff[24]<<8);
1936 
1937 	EPS_MEM_GROW(EPS_UINT8*, *pResult, Size, packetNum*packetSize )
1938 	if(NULL == *pResult){
1939 		EPS_RETURN( EPS_ERR_MEMORY_ALLOCATION )
1940 	}
1941 
1942 	/* step 2: send command */
1943 	for(n = 1; n <= packetNum; n++ ){
1944 		ComSize = sizeof(stCom);
1945 		stCom[19] = n & 0x000000FF;
1946 		stCom[20] = n >> 8;
1947 
1948 		/*EPS_DUMP(stCom, ComSize)*/
1949 		ret = nd4WritePortal(fd, stCom, &ComSize);
1950 		if( EPS_ERR_NONE != ret ){
1951 			EPS_RETURN( EPS_ERR_COMM_ERROR );
1952 		}
1953 
1954 		for(retry = 0; retry < EPS_STAT_RETRY; retry++){
1955 			rspSize = sizeof(rspBuff);
1956 			ret = nd4ReadPortal(fd, rspBuff, &rspSize);
1957 			/*EPS_DUMP(rspBuff, rspSize)*/
1958 
1959 			if( EPS_ERR_NONE != ret ){
1960 				EPS_RETURN( EPS_ERR_COMM_ERROR );
1961 			}
1962 			if( 0 == memcmp(rsp, rspBuff, strlen(rsp)) ){
1963 				rcvResponce = TRUE;
1964 				break;
1965 			}
1966 		}
1967 		if( 0 == memcmp(&rspBuff[21], "NA", 2) ){
1968 			EPS_RETURN( EPS_ERR_PRINTER_NOT_SUPPORTED );
1969 		} else if( 0 == memcmp(&rspBuff[21], "BUSY", 4)){
1970 			EPS_RETURN( EPS_ERR_COMM_ERROR );
1971 		}
1972 
1973 		rspSize = rspBuff[29] + (rspBuff[30]<<8);
1974 		if(*Size < rspSize + totalRespSize){
1975 			EPS_RETURN( EPS_ERR_OPR_FAIL ); /* buffer not enough */
1976 		}
1977 
1978 		memcpy(*pResult+totalRespSize, rspBuff+35, rspSize);
1979 		totalRespSize += rspSize;
1980 	}
1981 	*Size = totalRespSize;
1982 
1983     EPS_RETURN( EPS_ERR_NONE );
1984 }
1985 
1986 
1987 /*******************************************|********************************************/
1988 /*                                                                                      */
1989 /* Function name:   nd4WritePortal()                                                    */
1990 /*                                                                                      */
1991 /* Arguments                                                                            */
1992 /* ---------                                                                            */
1993 /* Name:        Type:               Description:                                        */
1994 /* fd           EPS_FILEDSC*        I: usb file descriptor                              */
1995 /* buff         EPS_UINT8*          I: write data                                       */
1996 /* buffSize     EPS_INT32*          I/O: write data size                                */
1997 /*                                                                                      */
1998 /* Return value:                                                                        */
1999 /*      EPS_ERR_NONE                - Info command executed successfully                */
2000 /*      EPS_ERR_COMM_ERROR              - Communication Error                           */
2001 /*                                                                                      */
2002 /* Description:                                                                         */
2003 /*      Write portal via CBT or END4.                                                   */
2004 /*                                                                                      */
2005 /*******************************************|********************************************/
nd4WritePortal(EPS_FILEDSC fd,const EPS_UINT8 * buff,EPS_INT32 * buffSize)2006 static EPS_ERR_CODE  nd4WritePortal (
2007 
2008 		EPS_FILEDSC		fd,
2009 		const EPS_UINT8	*buff,
2010 		EPS_INT32		*buffSize
2011 
2012 ){
2013 	EPS_INT32 ret = 0;
2014 	EPS_INT32 retry = 0;
2015 	EPS_INT32 writeSize = 0;
2016 	EPS_INT32 writeTotal = 0;
2017 
2018 	EPS_LOG_FUNCIN;
2019 
2020 	for(retry = 0; retry < EPS_STAT_RETRY; retry++){
2021 		ret = epsUsbFnc.writePortal(fd, buff+writeTotal, *buffSize, &writeSize);
2022 		if( EPS_ERR_NONE != ret ){
2023 			EPS_RETURN( EPS_ERR_COMM_ERROR );
2024 		}
2025 		writeTotal += writeSize;
2026 		*buffSize -=  writeSize;
2027 
2028 		if(0 >= *buffSize){
2029 			break;
2030 		}
2031 		serDelayThread(2*_SECOND_, &epsCmnFnc);       /* retry command after 2 seconds*/
2032 	}
2033 	*buffSize = writeTotal;
2034 
2035 	if(retry >= EPS_STAT_RETRY){
2036 		EPS_RETURN( EPS_ERR_COMM_ERROR );
2037 	}
2038 
2039 	EPS_RETURN( ret );
2040 }
2041 
2042 
2043 /*******************************************|********************************************/
2044 /*                                                                                      */
2045 /* Function name:   nd4ReadPortal()                                                     */
2046 /*                                                                                      */
2047 /* Arguments                                                                            */
2048 /* ---------                                                                            */
2049 /* Name:        Type:               Description:                                        */
2050 /* fd           EPS_FILEDSC*        I: usb file descriptor                              */
2051 /* buff         EPS_UINT8*          I: read buffer                                      */
2052 /* buffSize     EPS_INT32*          I/O: buffer size                                    */
2053 /*                                                                                      */
2054 /* Return value:                                                                        */
2055 /*      EPS_ERR_NONE                - Info command executed successfully                */
2056 /*      EPS_ERR_COMM_ERROR              - Communication Error                           */
2057 /*                                                                                      */
2058 /* Description:                                                                         */
2059 /*      Read portal via CBT or END4.                                                    */
2060 /*                                                                                      */
2061 /*******************************************|********************************************/
nd4ReadPortal(EPS_FILEDSC fd,EPS_UINT8 * buff,EPS_INT32 * buffSize)2062 static EPS_ERR_CODE  nd4ReadPortal (
2063 
2064 		EPS_FILEDSC		fd,
2065 		EPS_UINT8		*buff,
2066 		EPS_INT32		*buffSize
2067 
2068 ){
2069 	EPS_INT32 ret = 0;
2070 	EPS_INT32 retry = 0;
2071 	EPS_INT32 readSize = 0;
2072 	EPS_INT32 readTotal = 0;
2073 	EPS_INT32 buffRemain = *buffSize;
2074 	EPS_UINT8 *dataSizePos = 0;
2075 	EPS_INT32 dataSize = 0;
2076 
2077 	EPS_LOG_FUNCIN;
2078 
2079 	for(retry = 0; retry < EPS_STAT_RETRY; ){
2080 		ret = epsUsbFnc.readPortal(fd, buff+readTotal, buffRemain, &readSize);
2081 		if( EPS_ERR_NONE != ret ){
2082 			EPS_DBGPRINT(("read error %d", ret));
2083 			EPS_RETURN( EPS_ERR_COMM_ERROR );
2084 		}
2085 		if(readSize <= 0){
2086 			retry++;
2087 			serDelayThread(500, &epsCmnFnc);       /* retry command after 500 milli seconds*/
2088 			continue;
2089 		}
2090 		readTotal += readSize;
2091 		buffRemain -=  readSize;
2092 
2093 		if( 0 >= dataSize){
2094 			/* get data size */
2095 			if( (dataSizePos = (EPS_UINT8*)strstr((EPS_INT8*)buff, "\x0D\x0A")) != NULL ){
2096 				if( (dataSizePos-buff) + 4 < readTotal){
2097 					dataSize  = *(dataSizePos+2);
2098 					dataSize += *(dataSizePos+3) << 8;
2099 					dataSize += dataSizePos - buff + 4;
2100 					if(*buffSize < dataSize){
2101 						EPS_RETURN( EPS_ERR_OPR_FAIL ); /* buffer not enough */
2102 					}
2103 				}
2104 			}
2105 		}
2106 
2107 		if( 0 < dataSize && dataSize <= readTotal){
2108 			break;
2109 		}
2110 	}
2111 	*buffSize = readTotal;
2112 
2113 	if(retry >= EPS_STAT_RETRY){
2114 		EPS_RETURN( EPS_ERR_COMM_ERROR );
2115 	}
2116 
2117 	EPS_RETURN( ret );
2118 }
2119 
2120 /*******************************************|********************************************/
2121 /*                                                                                      */
2122 /* Function name:   OpenPortal()                                                        */
2123 /*                                                                                      */
2124 /* Arguments                                                                            */
2125 /* ---------                                                                            */
2126 /* Name:        Type:               Description:                                        */
2127 /* usbInfo      EPS_USB_PRINTER_INFO* I: usb protocol info                              */
2128 /* fd           EPS_FILEDSC*        O: usb file descriptor                              */
2129 /*                                                                                      */
2130 /* Return value:                                                                        */
2131 /*      EPS_ERR_NONE                - Info command executed successfully                */
2132 /*      EPS_ERR_NOT_OPEN_IO         - Cannot Open I/O Portal                            */
2133 /*                                                                                      */
2134 /* Description:                                                                         */
2135 /*      Open portal via CBT or END4.                                                    */
2136 /*                                                                                      */
2137 /*******************************************|********************************************/
OpenPortal(EPS_USB_PRINTER_INFO * usbInfo,EPS_FILEDSC * fd)2138 static EPS_ERR_CODE  OpenPortal (
2139 
2140 	EPS_USB_PRINTER_INFO    *usbInfo,
2141 	EPS_FILEDSC             *fd
2142 
2143 ){
2144 	EPS_INT32 ret = 0;
2145 
2146 	EPS_LOG_FUNCIN;
2147 
2148 	if(EPS_USBP_CBT == usbInfo->usbProtocol){
2149 		ret = cbtCommOpen( &usbInfo->dev, fd );
2150 	} else{
2151 		*fd = epsUsbFnc.openPortal(&usbInfo->dev);
2152 		if( EPS_INVALID_FILEDSC == *fd ){
2153 			ret = EPS_ERR_NOT_OPEN_IO;
2154 		} else{
2155 			ioOpenState = EPS_IO_OPEN;
2156 		}
2157 	}
2158 
2159 	if(0 == ret){
2160 		EPS_RETURN( EPS_ERR_NONE );
2161 	} else{
2162 		EPS_RETURN( EPS_ERR_NOT_OPEN_IO );
2163 	}
2164 }
2165 
2166 
2167 /*******************************************|********************************************/
2168 /*                                                                                      */
2169 /* Function name:   ClosePortal()                                                       */
2170 /*                                                                                      */
2171 /* Arguments                                                                            */
2172 /* ---------                                                                            */
2173 /* Name:        Type:               Description:                                        */
2174 /* usbProtocol  EPS_UINT32          I: usb protocol kind                                */
2175 /* fd           EPS_FILEDSC*        I: usb file descriptor                              */
2176 /*                                                                                      */
2177 /* Return value:                                                                        */
2178 /*      EPS_ERR_NONE                - Info command executed successfully                */
2179 /*      EPS_ERR_NOT_CLOSE_IO        - Cannot close I/O portal                           */
2180 /*                                                                                      */
2181 /* Description:                                                                         */
2182 /*      Open portal via CBT or END4.                                                    */
2183 /*                                                                                      */
2184 /*******************************************|********************************************/
ClosePortal(EPS_UINT32 usbProtocol,EPS_FILEDSC fd)2185 static EPS_ERR_CODE  ClosePortal (
2186 
2187 	EPS_UINT32	usbProtocol,
2188 	EPS_FILEDSC	fd
2189 
2190 ){
2191 	EPS_INT32 ret = 0;
2192 
2193 	EPS_LOG_FUNCIN;
2194 
2195 	if(EPS_USBP_CBT == usbProtocol){
2196 		ret = cbtCommClose(fd);
2197 	} else{
2198 		ret = epsUsbFnc.closePortal(fd);
2199 		ioOpenState = EPS_IO_NOT_OPEN;
2200 	}
2201 
2202 	if(0 == ret){
2203 		EPS_RETURN( EPS_ERR_NONE );
2204 	} else{
2205 		EPS_RETURN( EPS_ERR_NOT_CLOSE_IO );
2206 	}
2207 }
2208 
2209 
2210 /*******************************************|********************************************/
2211 /*                                                                                      */
2212 /* Function name:   ParseUsbProtocol()                                                  */
2213 /*                                                                                      */
2214 /* Arguments                                                                            */
2215 /* ---------                                                                            */
2216 /* Name:        Type:               Description:                                        */
2217 /* deviceIDString EPS_INT8*         I: deviceID string                                  */
2218 /* strlength    EPS_INT32           I: string length                                    */
2219 /* usbProtocol  EPS_UINT32*         O: usb protocol kind                                */
2220 /*                                                                                      */
2221 /* Return value:                                                                        */
2222 /*      N/A                                                                             */
2223 /*                                                                                      */
2224 /* Description:                                                                         */
2225 /*      Get the epson usb protocol from DeviceID string.                                */
2226 /*                                                                                      */
2227 /*******************************************|********************************************/
ParseUsbProtocol(EPS_INT8 * deviceIDString,EPS_INT32 strlength,EPS_UINT32 * usbProtocol)2228 static void   ParseUsbProtocol (
2229 
2230         EPS_INT8*   deviceIDString,
2231 		EPS_INT32   strlength,
2232         EPS_UINT32* usbProtocol
2233 
2234 ){
2235     EPS_INT8*       i = NULL;
2236     EPS_INT8*       j = NULL;
2237     EPS_INT8*       k = NULL;
2238 
2239 	EPS_LOG_FUNCIN;
2240 
2241 	*usbProtocol = EPS_USBP_CBT; /* default */
2242 
2243 	if(strlength < 2){
2244 		EPS_RETURN_VOID;
2245 	}
2246     if(deviceIDString[0] == 0x00 || deviceIDString[1] == 0x00){
2247         deviceIDString += 2;
2248 	}
2249 
2250     if((i = strstr(deviceIDString, "CMD:")) == NULL) {
2251 		EPS_RETURN_VOID;
2252 	}
2253 	i += 4;
2254 
2255     if((j = strstr(i, ";")) == NULL) {
2256 		EPS_RETURN_VOID;
2257 	}
2258 	*j = '\0';
2259 
2260 	while( NULL != i ){
2261 		if((k = strstr(i, ",")) != NULL) {
2262 			*k = '\0';
2263 		}
2264 
2265 /*		if( strncmp(i, "D4", 4) == 0 ){
2266 			*usbProtocol = EPS_USBP_CBT;
2267 			break;
2268 		}
2269 */
2270 		if( strncmp(i, "END4", 4) == 0 ){
2271 			*usbProtocol = EPS_USBP_ND4;
2272 			break;
2273 		}
2274 
2275 		if(k){
2276 			*k = ',';
2277 			i = k+1;
2278 			if(i >= j){
2279 				break;
2280 			}
2281 		} else{
2282 			break;
2283 		}
2284 	}
2285 	if(k)*k = ',';
2286 
2287 	*j = ';';
2288 
2289     EPS_RETURN_VOID;
2290 }
2291 
2292 
2293 /*******************************************|********************************************/
2294 /*                                                                                      */
2295 /* Function name:   GetSerialNumber()                                                   */
2296 /*                                                                                      */
2297 /* Arguments                                                                            */
2298 /* ---------                                                                            */
2299 /* Name:        Type:               Description:                                        */
2300 /* usbInfo      EPS_USB_PRINTER_INFO* I: usb protocol info                              */
2301 /* deviceIDString EPS_INT8*         I: deviceID string                                  */
2302 /*                                                                                      */
2303 /* Return value:                                                                        */
2304 /*      EPS_ERR_NONE                - Info command executed successfully                */
2305 /*                                                                                      */
2306 /* Description:                                                                         */
2307 /*      Get the epson usb protocol from DeviceID string.                                */
2308 /*                                                                                      */
2309 /*******************************************|********************************************/
GetSerialNumber(EPS_USB_PRINTER_INFO * usbInfo,EPS_INT8 * serialNo)2310 static EPS_ERR_CODE   GetSerialNumber (
2311 
2312         EPS_USB_PRINTER_INFO    *usbInfo,
2313 		EPS_INT8*               serialNo
2314 
2315 ){
2316 	EPS_ERR_CODE ret = EPS_ERR_NONE;
2317 	EPS_FILEDSC fd;
2318 	EPS_UINT8*  tmpBuff = NULL;
2319 	EPS_INT32   tmpBuffSize = EPS_DI_MAXSIZE;
2320 
2321 	EPS_LOG_FUNCIN;
2322 
2323 	ret = OpenPortal( usbInfo, &fd );
2324 	if(EPS_ERR_NONE != ret){
2325 		EPS_RETURN( ret );
2326 	}
2327 
2328 	tmpBuff = (EPS_UINT8*)EPS_ALLOC(tmpBuffSize);
2329 	if (tmpBuff == NULL) {
2330 		EPS_RETURN( EPS_ERR_MEMORY_ALLOCATION );
2331 	}
2332 	memset(tmpBuff, 0, tmpBuffSize);
2333 
2334 	if( EPS_USBP_CBT == usbInfo->usbProtocol ){
2335 		ret = cbtCommChannelOpen(fd, EPS_CBTCHANNEL_CTRL, TRUE);
2336 		if (EPS_ERR_NONE == ret ) {
2337 			ret = InfoCommand(fd, usbInfo->usbProtocol, EPS_CBTCOM_CD, &tmpBuff, &tmpBuffSize);
2338 			if (EPS_ERR_NONE == ret ) {
2339 				/*retStatus = */serGetSerialNo((EPS_INT8*)tmpBuff, tmpBuffSize, serialNo);
2340 			} else{
2341 				ret = EPS_ERR_NONE; /* ignoure */
2342 			}
2343 		} else{
2344 			ret = (EPS_ERR_CODE)EPS_ERR_NOT_OPEN_IO;
2345 		}
2346 
2347 		cbtCommChannelClose(fd, EPS_CBTCHANNEL_CTRL);
2348 	} else{
2349 		ret = RmtInfoCommand(fd, EPS_CBTCOM_ST, &tmpBuff, &tmpBuffSize);
2350 		if (EPS_ERR_NONE == ret ) {
2351 			/*retStatus = */serGetSerialNoFormST((EPS_INT8*)tmpBuff, serialNo, EPS_ADDR_BUFFSIZE);
2352 		} else{
2353 			ret = EPS_ERR_NONE; /* ignoure */
2354 		}
2355 	}
2356 
2357 	EPS_SAFE_RELEASE(tmpBuff);
2358 
2359 	ClosePortal(usbInfo->usbProtocol, fd);
2360 
2361 	EPS_RETURN( ret );
2362 }
2363 
2364 /*___________________________________  epson-usb.c  ____________________________________*/
2365 
2366 /*34567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/
2367 /*       1         2         3         4         5         6         7         8        */
2368 /*******************************************|********************************************/
2369 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2370 /***** End of File *** End of File *** End of File *** End of File *** End of File ******/
2371 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2372