1 # -*- coding: utf-8 -*-
3 # (c) Copyright 2003-2007 Hewlett-Packard Development Company, L.P.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 from base.codes import *
33 from base import device, utils, pml, codes
38 # **************************************************************************** #
42 PAGE_FLAG_NEW_PAGE = 0x01
43 PAGE_FLAG_END_PAGE = 0x02
44 PAGE_FLAG_NEW_DOC = 0x04
45 PAGE_FLAG_END_DOC = 0x08
46 PAGE_FLAG_END_STREAM = 0x10
51 MFPDTF_RASTER_BITMAP = 0 # Not used
52 MFPDTF_RASTER_GRAYMAP = 1 # Not used
53 MFPDTF_RASTER_MH = 2 # OfficeJets B&W Fax
54 MFPDTF_RASTER_MR = 3 # Not used
55 MFPDTF_RASTER_MMR = 4 # LaserJets B&W Fax
56 MFPDTF_RASTER_RGB = 5 # Not used
57 MFPDTF_RASTER_YCC411 = 6 # Not used
58 MFPDTF_RASTER_JPEG = 7 # Color Fax
59 MFPDTF_RASTER_PCL = 8 # Not used
60 MFPDTF_RASTER_NOT = 9 # Not used
81 # Raster data record types
90 IMAGE_VARIANT_HEADER_SIZE = 10
91 DIAL_STRINGS_VARIANT_HEADER_SIZE = 6
92 FAX_IMAGE_VARIANT_HEADER_SIZE = 74
96 RASTER_RECORD_SIZE = 4
98 DIAL_STRING_RECORD_SIZE = 51
101 PAGE_FLAG_NEW_PAGE = 0x01
102 PAGE_FLAG_END_PAGE = 0x02
103 PAGE_FLAG_NEW_DOC = 0x04
104 PAGE_FLAG_END_DOC = 0x08
105 PAGE_FLAG_END_STREAM = 0x10
107 # Fax data variant header data source
111 SRC_HOST_THEN_SCANNER = 6
112 SRC_SCANNER_THEN_HOST = 7
114 # Fax data variant header TTI header control
116 TTI_PREPENDED_TO_IMAGE = 1
117 TTI_OVERLAYED_ON_IMAGE = 2
119 RASTER_DATA_SIZE = 504
123 # **************************************************************************** #
124 class PMLFaxDevice(FaxDevice):
126 def __init__(self, device_uri=None, printer_name=None,
128 fax_type=FAX_TYPE_NONE,
131 FaxDevice.__init__(self, device_uri,
136 self.send_fax_thread = None
137 self.upload_log_thread = None
140 def setPhoneNum(self, num):
141 return self.setPML(pml.OID_FAX_LOCAL_PHONE_NUM, str(num))
143 def getPhoneNum(self):
144 return utils.printable(str(self.getPML(pml.OID_FAX_LOCAL_PHONE_NUM)[1]))
146 phone_num = property(getPhoneNum, setPhoneNum, doc="OID_FAX_LOCAL_PHONE_NUM")
149 def setStationName(self, name):
150 return self.setPML(pml.OID_FAX_STATION_NAME, str(name))
152 def getStationName(self):
153 return utils.printable(str(self.getPML(pml.OID_FAX_STATION_NAME)[1]))
155 station_name = property(getStationName, setStationName, doc="OID_FAX_STATION_NAME")
157 def setDateAndTime(self):
159 p = struct.pack("BBBBBBB", t[0]-2000, t[1], t[2], t[6]+1, t[3], t[4], t[5])
161 return self.setPML(pml.OID_DATE_AND_TIME, p)
164 if not self.isUloadLogActive():
165 self.upload_log_thread = UploadLogThread(self)
166 self.upload_log_thread.start()
171 def isUploadLogActive(self):
172 if self.upload_log_thread is not None:
173 return self.upload_log_thread.isAlive()
177 def waitForUploadLogThread(self):
178 if self.upload_log_thread is not None and \
179 self.upload_log_thread.isAlive():
181 self.upload_log_thread.join()
183 def sendFaxes(self, phone_num_list, fax_file_list, cover_message='', cover_re='',
184 cover_func=None, preserve_formatting=False, printer_name='',
185 update_queue=None, event_queue=None):
187 if not self.isSendFaxActive():
189 self.send_fax_thread = PMLFaxSendThread(self, self.service, phone_num_list, fax_file_list,
190 cover_message, cover_re, cover_func,
192 printer_name, update_queue,
195 self.send_fax_thread.start()
202 # **************************************************************************** #
203 class PMLUploadLogThread(threading.Thread):
204 def __init__(self, dev):
205 threading.Thread.__init__(self)
214 STATE_DEVICE_OPEN = 28
215 STATE_CHECK_IDLE = 30
216 STATE_REQUEST_START = 40
217 STATE_WAIT_FOR_ACTIVE = 50
218 STATE_UPLOAD_DATA = 60
219 STATE_DEVICE_CLOSE = 70
221 state = STATE_CHECK_IDLE
223 while state != STATE_DONE: # --------------------------------- Log upload state machine
224 if state == STATE_ABORT:
226 elif state == STATE_SUCCESS:
228 elif state == STATE_BUSY:
231 elif state == STATE_DEVICE_OPEN: # --------------------------------- Open device (28)
232 state = STATE_REQUEST_START
236 log.error("Unable to open device (%s)." % e.msg)
240 dev.setPML(pml.OID_UPLOAD_TIMEOUT, pml.DEFAULT_UPLOAD_TIMEOUT)
244 elif state == STATE_CHECK_IDLE: # --------------------------------- Check idle (30)
245 state = STATE_REQUEST_START
246 ul_state = self.getCfgUploadState()
248 if ul_state != pml.UPDN_STATE_IDLE:
252 elif state == STATE_REQUEST_START: # --------------------------------- Request start (40)
253 state = STATE_WAIT_FOR_ACTIVE
254 self.dev.setPML(pml.OID_FAX_CFG_UPLOAD_DATA_TYPE, pml.FAX_CFG_UPLOAD_DATA_TYPE_FAXLOGS)
255 self.dev.setPML(pml.OID_DEVICE_CFG_UPLOAD, pml.UPDN_STATE_REQSTART)
257 elif state == STATE_WAIT_FOR_ACTIVE: # --------------------------------- Wait for active state (50)
258 state = STATE_UPLOAD_DATA
263 ul_state = self.getCfgUploadState()
265 if ul_state == pml.UPDN_STATE_XFERACTIVE:
268 if ul_state in (pml.UPDN_STATE_ERRORABORT, pml.UPDN_STATE_XFERDONE):
269 log.error("Cfg upload aborted!")
275 log.error("Unable to get into active state!")
280 elif state == STATE_UPLOAD_DATA: # --------------------------------- Upload log data (60)
283 elif state == STATE_DEVICE_CLOSE: # --------------------------------- Close device (70)
288 # **************************************************************************** #
289 class PMLFaxSendThread(FaxSendThread):
290 def __init__(self, dev, service, phone_num_list, fax_file_list,
291 cover_message='', cover_re='', cover_func=None, preserve_formatting=False,
292 printer_name='', update_queue=None, event_queue=None):
294 FaxSendThread.__init__(self, dev, service, phone_num_list, fax_file_list,
295 cover_message, cover_re, cover_func, preserve_formatting,
296 printer_name, update_queue, event_queue)
300 #results = {} # {'file' : error_code,...}
306 STATE_READ_SENDER_INFO = 30
308 STATE_COUNT_PAGES = 50
309 STATE_NEXT_RECIPIENT = 60
310 STATE_COVER_PAGE = 70
311 STATE_SINGLE_FILE = 80
312 STATE_MERGE_FILES = 90
313 STATE_SINGLE_FILE = 100
318 next_recipient = self.next_recipient_gen()
320 state = STATE_READ_SENDER_INFO
321 self.rendered_file_list = []
323 while state != STATE_DONE: # --------------------------------- Fax state machine
324 if self.check_for_cancel():
325 state = STATE_ABORTED
327 log.debug("STATE=(%d, 0, 0)" % state)
329 if state == STATE_ABORTED: # --------------------------------- Aborted (10, 0, 0)
330 log.error("Aborted by user.")
331 self.write_queue((STATUS_IDLE, 0, ''))
332 state = STATE_CLEANUP
335 elif state == STATE_SUCCESS: # --------------------------------- Success (20, 0, 0)
336 log.debug("Success.")
337 self.write_queue((STATUS_COMPLETED, 0, ''))
338 state = STATE_CLEANUP
341 elif state == STATE_ERROR: # --------------------------------- Error (130, 0, 0)
342 log.error("Error, aborting.")
343 self.write_queue((STATUS_ERROR, 0, ''))
344 state = STATE_CLEANUP
347 elif state == STATE_BUSY: # --------------------------------- Busy (25, 0, 0)
348 log.error("Device busy, aborting.")
349 self.write_queue((STATUS_BUSY, 0, ''))
350 state = STATE_CLEANUP
353 elif state == STATE_READ_SENDER_INFO: # --------------------------------- Get sender info (30, 0, 0)
354 log.debug("%s State: Get sender info" % ("*"*20))
355 state = STATE_PRERENDER
360 log.error("Unable to open device (%s)." % e.msg)
364 self.sender_name = self.dev.station_name
365 log.debug("Sender name=%s" % self.sender_name)
366 self.sender_fax = self.dev.phone_num
367 log.debug("Sender fax=%s" % self.sender_fax)
369 log.error("PML get failed!")
376 elif state == STATE_PRERENDER: # --------------------------------- Pre-render non-G3 files (40, 0, 0)
377 log.debug("%s State: Pre-render non-G3 files" % ("*"*20))
378 state = self.pre_render(STATE_COUNT_PAGES)
381 elif state == STATE_COUNT_PAGES: # --------------------------------- Get total page count (50, 0, 0)
382 log.debug("%s State: Get total page count" % ("*"*20))
383 state = self.count_pages(STATE_NEXT_RECIPIENT)
386 elif state == STATE_NEXT_RECIPIENT: # --------------------------------- Loop for multiple recipients (60, 0, 0)
387 log.debug("%s State: Next recipient" % ("*"*20))
388 state = STATE_COVER_PAGE
391 recipient = next_recipient.next()
393 log.debug("Processing for recipient %s" % recipient['name'])
395 self.write_queue((STATUS_SENDING_TO_RECIPIENT, 0, recipient['name']))
397 except StopIteration:
398 state = STATE_SUCCESS
399 log.debug("Last recipient.")
402 self.recipient_file_list = self.rendered_file_list[:]
405 elif state == STATE_COVER_PAGE: # --------------------------------- Create cover page (70, 0, 0)
406 log.debug("%s State: Render cover page" % ("*"*20))
407 state = self.cover_page(recipient)
410 elif state == STATE_SINGLE_FILE: # --------------------------------- Special case for single file (no merge) (80, 0, 0)
411 log.debug("%s State: Handle single file" % ("*"*20))
412 state = self.single_file(STATE_SEND_FAX)
414 elif state == STATE_MERGE_FILES: # --------------------------------- Merge multiple G3 files (90, 0, 0)
415 log.debug("%s State: Merge multiple files" % ("*"*20))
416 state = self.merge_files(STATE_SEND_FAX)
418 elif state == STATE_SEND_FAX: # --------------------------------- Send fax state machine (110, 0, 0)
419 log.debug("%s State: Send fax" % ("*"*20))
420 state = STATE_NEXT_RECIPIENT
422 FAX_SEND_STATE_DONE = 0
423 FAX_SEND_STATE_ABORT = 10
424 FAX_SEND_STATE_ERROR = 20
425 FAX_SEND_STATE_BUSY = 25
426 FAX_SEND_STATE_SUCCESS = 30
427 FAX_SEND_STATE_DEVICE_OPEN = 40
428 FAX_SEND_STATE_SET_TOKEN = 50
429 FAX_SEND_STATE_EARLY_OPEN = 60
430 FAX_SEND_STATE_SET_PARAMS = 70
431 FAX_SEND_STATE_CHECK_IDLE = 80
432 FAX_SEND_STATE_START_REQUEST = 90
433 FAX_SEND_STATE_LATE_OPEN = 100
434 FAX_SEND_STATE_SEND_DIAL_STRINGS = 110
435 FAX_SEND_STATE_SEND_FAX_HEADER = 120
436 FAX_SEND_STATE_SEND_PAGES = 130
437 FAX_SEND_STATE_SEND_END_OF_STREAM = 140
438 FAX_SEND_STATE_WAIT_FOR_COMPLETE = 150
439 FAX_SEND_STATE_RESET_TOKEN = 160
440 FAX_SEND_STATE_CLOSE_SESSION = 170
442 monitor_state = False
443 error_state = pml.DN_ERROR_NONE
444 fax_send_state = FAX_SEND_STATE_DEVICE_OPEN
446 while fax_send_state != FAX_SEND_STATE_DONE:
448 if self.check_for_cancel():
449 log.error("Fax send aborted.")
450 fax_send_state = FAX_SEND_STATE_ABORT
453 fax_state = self.getFaxDownloadState()
454 if not fax_state in (pml.UPDN_STATE_XFERACTIVE, pml.UPDN_STATE_XFERDONE):
455 log.error("D/L error state=%d" % fax_state)
456 fax_send_state = FAX_SEND_STATE_ERROR
459 log.debug("STATE=(%d, %d, 0)" % (STATE_SEND_FAX, fax_send_state))
461 if fax_send_state == FAX_SEND_STATE_ABORT: # -------------- Abort (110, 10, 0)
462 # TODO: Set D/L state to ???
463 monitor_state = False
464 fax_send_state = FAX_SEND_STATE_RESET_TOKEN
465 state = STATE_ABORTED
467 elif fax_send_state == FAX_SEND_STATE_ERROR: # -------------- Error (110, 20, 0)
468 log.error("Fax send error.")
469 error_state = self.getFaxDownloadError()
470 log.debug("Error State=%d (%s)" % (error_state, pml.DN_ERROR_STR.get(error_state, "Unknown")))
471 monitor_state = False
473 fax_send_state = FAX_SEND_STATE_RESET_TOKEN
476 elif fax_send_state == FAX_SEND_STATE_BUSY: # -------------- Busy (110, 25, 0)
477 log.error("Fax device busy.")
478 monitor_state = False
479 fax_send_state = FAX_SEND_STATE_RESET_TOKEN
482 elif fax_send_state == FAX_SEND_STATE_SUCCESS: # -------------- Success (110, 30, 0)
483 log.debug("Fax send success.")
484 monitor_state = False
485 fax_send_state = FAX_SEND_STATE_RESET_TOKEN
486 state = STATE_NEXT_RECIPIENT
488 elif fax_send_state == FAX_SEND_STATE_DEVICE_OPEN: # -------------- Device open (110, 40, 0)
489 log.debug("%s State: Open device" % ("*"*20))
490 fax_send_state = FAX_SEND_STATE_SET_TOKEN
494 log.error("Unable to open device (%s)." % e.msg)
495 fax_send_state = FAX_SEND_STATE_ERROR
497 if self.dev.device_state == DEVICE_STATE_NOT_FOUND:
498 fax_send_state = FAX_SEND_STATE_ERROR
500 elif fax_send_state == FAX_SEND_STATE_SET_TOKEN: # -------------- Acquire fax token (110, 50, 0)
501 log.debug("%s State: Acquire fax token" % ("*"*20))
503 result_code, token = self.dev.getPML(pml.OID_FAX_TOKEN)
505 log.debug("Unable to acquire fax token (1).")
506 fax_send_state = FAX_SEND_STATE_EARLY_OPEN
508 if result_code > pml.ERROR_MAX_OK:
509 fax_send_state = FAX_SEND_STATE_EARLY_OPEN
510 log.debug("Skipping token acquisition.")
512 token = time.strftime("%d%m%Y%H:%M:%S", time.gmtime())
513 log.debug("Setting token: %s" % token)
515 self.dev.setPML(pml.OID_FAX_TOKEN, token)
517 log.error("Unable to acquire fax token (2).")
518 fax_send_state = FAX_SEND_STATE_ERROR
520 result_code, check_token = self.dev.getPML(pml.OID_FAX_TOKEN)
522 if check_token == token:
523 fax_send_state = FAX_SEND_STATE_EARLY_OPEN
525 log.error("Unable to acquire fax token (3).")
526 fax_send_state = FAX_SEND_STATE_ERROR
529 elif fax_send_state == FAX_SEND_STATE_EARLY_OPEN: # -------------- Early open (newer models) (110, 60, 0)
530 log.debug("%s State: Early open" % ("*"*20))
531 fax_send_state = FAX_SEND_STATE_CHECK_IDLE
533 if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN: # newer
534 log.debug("Opening fax channel.")
538 log.error("Unable to open channel (%s)." % e.msg)
539 fax_send_state = FAX_SEND_STATE_ERROR
541 log.debug("Skipped.")
544 elif fax_send_state == FAX_SEND_STATE_CHECK_IDLE: # -------------- Check for initial idle (110, 80, 0)
545 log.debug("%s State: Check idle" % ("*"*20))
546 fax_send_state = FAX_SEND_STATE_START_REQUEST
548 dl_state = self.getFaxDownloadState()
549 tx_status = self.getFaxJobTxStatus()
550 rx_status = self.getFaxJobRxStatus()
552 if ((dl_state == pml.UPDN_STATE_IDLE or \
553 dl_state == pml.UPDN_STATE_ERRORABORT or \
554 dl_state == pml.UPDN_STATE_XFERDONE) and \
555 (tx_status == pml.FAXJOB_TX_STATUS_IDLE or tx_status == pml.FAXJOB_TX_STATUS_DONE) and \
556 (rx_status == pml.FAXJOB_RX_STATUS_IDLE or rx_status == pml.FAXJOB_RX_STATUS_DONE)):
558 # xwas if state == pml.UPDN_STATE_IDLE:
559 if dl_state == pml.UPDN_STATE_IDLE:
560 log.debug("Starting in idle state")
562 log.debug("Resetting to idle...")
563 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE)
566 fax_send_state = FAX_SEND_STATE_BUSY
568 elif fax_send_state == FAX_SEND_STATE_START_REQUEST: # -------------- Request fax start (110, 90, 0)
569 log.debug("%s State: Request start" % ("*"*20))
570 fax_send_state = FAX_SEND_STATE_SET_PARAMS
572 dl_state = self.getFaxDownloadState()
574 if dl_state == pml.UPDN_STATE_IDLE:
576 log.debug("Setting to up/down state request start...")
577 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART)
580 log.debug("Waiting for active state...")
584 log.debug("Try: %d" % i)
586 dl_state = self.getFaxDownloadState()
588 log.error("PML/SNMP error")
589 fax_send_state = FAX_SEND_STATE_ERROR
592 if dl_state == pml.UPDN_STATE_XFERACTIVE:
596 log.debug("Setting to up/down state request start...")
597 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_REQSTART)
602 log.error("Could not get into active state!")
603 fax_send_state = FAX_SEND_STATE_BUSY
608 log.error("Could not get into idle state!")
609 fax_send_state = FAX_SEND_STATE_BUSY
612 elif fax_send_state == FAX_SEND_STATE_SET_PARAMS: # -------------- Set fax send params (110, 70, 0)
613 log.debug("%s State: Set params" % ("*"*20))
614 fax_send_state = FAX_SEND_STATE_LATE_OPEN
617 self.dev.setPML(pml.OID_DEV_DOWNLOAD_TIMEOUT, pml.DEFAULT_DOWNLOAD_TIMEOUT)
618 self.dev.setPML(pml.OID_FAXJOB_TX_TYPE, pml.FAXJOB_TX_TYPE_HOST_ONLY)
619 log.debug("Setting date and time on device.")
620 self.dev.setDateAndTime()
622 log.error("PML/SNMP error (%s)" % e.msg)
623 fax_send_state = FAX_SEND_STATE_ERROR
626 elif fax_send_state == FAX_SEND_STATE_LATE_OPEN: # -------------- Late open (older models) (110, 100, 0)
627 log.debug("%s State: Late open" % ("*"*20))
628 fax_send_state = FAX_SEND_STATE_SEND_DIAL_STRINGS
630 if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN: # older
631 log.debug("Opening fax channel.")
635 log.error("Unable to open channel.")
636 fax_send_state = FAX_SEND_STATE_ERROR
638 log.debug("Skipped.")
641 elif fax_send_state == FAX_SEND_STATE_SEND_DIAL_STRINGS: # -------------- Dial strings (110, 110, 0)
642 log.debug("%s State: Send dial strings" % ("*"*20))
643 fax_send_state = FAX_SEND_STATE_SEND_FAX_HEADER
645 log.debug("Dialing: %s" % recipient['fax'])
647 log.debug("Sending dial strings...")
648 self.create_mfpdtf_fixed_header(DT_DIAL_STRINGS, True,
649 PAGE_FLAG_NEW_DOC | PAGE_FLAG_END_DOC | PAGE_FLAG_END_STREAM) # 0x1c on Windows, we were sending 0x0c
651 dial_strings = recipient['fax'].encode('ascii')
652 log.debug(repr(dial_strings))
653 self.create_mfpdtf_dial_strings(dial_strings)
658 log.error("Channel write error.")
659 fax_send_state = FAX_SEND_STATE_ERROR
662 elif fax_send_state == FAX_SEND_STATE_SEND_FAX_HEADER: # -------------- Fax header (110, 120, 0)
663 log.debug("%s State: Send fax header" % ("*"*20))
664 fax_send_state = FAX_SEND_STATE_SEND_PAGES
667 ff = file(self.f, 'r')
669 log.error("Unable to read fax file.")
670 fax_send_state = FAX_SEND_STATE_ERROR
674 header = ff.read(FILE_HEADER_SIZE)
676 log.error("Unable to read fax file.")
677 fax_send_state = FAX_SEND_STATE_ERROR
680 magic, version, total_pages, hort_dpi, vert_dpi, page_size, \
681 resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header)
683 if magic != 'hplip_g3':
684 log.error("Invalid file header. Bad magic.")
685 fax_send_state = FAX_SEND_STATE_ERROR
687 log.debug("Magic=%s Ver=%d Pages=%d hDPI=%d vDPI=%d Size=%d Res=%d Enc=%d" %
688 (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding))
690 log.debug("Sending fax header...")
691 self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, True, PAGE_FLAG_NEW_DOC)
692 self.create_mfpdtf_fax_header(total_pages)
697 log.error("Unable to write to channel.")
698 fax_send_state = FAX_SEND_STATE_ERROR
701 elif fax_send_state == FAX_SEND_STATE_SEND_PAGES: # --------------------------------- Send fax pages state machine (110, 130, 0)
702 log.debug("%s State: Send pages" % ("*"*20))
703 fax_send_state = FAX_SEND_STATE_SEND_END_OF_STREAM
706 for p in range(total_pages):
708 if self.check_for_cancel():
709 fax_send_state = FAX_SEND_STATE_ABORT
711 if fax_send_state == FAX_SEND_STATE_ABORT:
715 header = ff.read(PAGE_HEADER_SIZE)
717 log.error("Unable to read fax file.")
718 fax_send_state = FAX_SEND_STATE_ERROR
721 page_num, ppr, rpp, bytes_to_read, thumbnail_bytes, reserved2 = \
722 self.decode_page_header(header)
724 log.debug("Page=%d PPR=%d RPP=%d BPP=%d Thumb=%d" %
725 (page_num, ppr, rpp, bytes_to_read, thumbnail_bytes))
727 page.write(ff.read(bytes_to_read))
728 thumbnail = ff.read(thumbnail_bytes) # thrown away for now (should be 0 read)
731 self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags=PAGE_FLAG_NEW_PAGE)
732 self.create_sop_record(page_num, hort_dpi, vert_dpi, ppr, rpp, encoding)
735 data = page.read(RASTER_DATA_SIZE)
737 log.error("Unable to read fax file.")
738 fax_send_state = FAX_SEND_STATE_ERROR
742 log.error("No data!")
743 fax_send_state = FAX_SEND_STATE_ERROR
746 self.create_raster_data_record(data)
747 total_read = RASTER_DATA_SIZE
750 data = page.read(RASTER_DATA_SIZE)
751 total_read += RASTER_DATA_SIZE
753 dl_state = self.getFaxDownloadState()
754 if dl_state == pml.UPDN_STATE_ERRORABORT:
755 fax_send_state = FAX_SEND_STATE_ERROR
758 if self.check_for_cancel():
759 fax_send_state = FAX_SEND_STATE_ABORT
763 self.create_eop_record(rpp)
768 log.error("Channel write error.")
769 fax_send_state = FAX_SEND_STATE_ERROR
776 log.error("Channel write error.")
777 fax_send_state = FAX_SEND_STATE_ERROR
780 status = self.getFaxJobTxStatus()
781 while status == pml.FAXJOB_TX_STATUS_DIALING:
782 self.write_queue((STATUS_DIALING, 0, recipient['fax']))
785 if self.check_for_cancel():
786 fax_send_state = FAX_SEND_STATE_ABORT
789 dl_state = self.getFaxDownloadState()
790 if dl_state == pml.UPDN_STATE_ERRORABORT:
791 fax_send_state = FAX_SEND_STATE_ERROR
794 status = self.getFaxJobTxStatus()
796 if fax_send_state not in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR):
798 while status == pml.FAXJOB_TX_STATUS_CONNECTING:
799 self.write_queue((STATUS_CONNECTING, 0, recipient['fax']))
802 if self.check_for_cancel():
803 fax_send_state = FAX_SEND_STATE_ABORT
806 dl_state = self.getFaxDownloadState()
807 if dl_state == pml.UPDN_STATE_ERRORABORT:
808 fax_send_state = FAX_SEND_STATE_ERROR
811 status = self.getFaxJobTxStatus()
813 if status == pml.FAXJOB_TX_STATUS_TRANSMITTING:
814 self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
816 self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, page_flags=0)
817 self.create_raster_data_record(data)
819 if fax_send_state in (FAX_SEND_STATE_ABORT, FAX_SEND_STATE_ERROR):
826 elif fax_send_state == FAX_SEND_STATE_SEND_END_OF_STREAM: # -------------- EOS (110, 140, 0)
827 log.debug("%s State: Send EOS" % ("*"*20))
828 fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE
829 log.debug("End of stream...")
830 self.create_mfpdtf_fixed_header(DT_FAX_IMAGES, False, PAGE_FLAG_END_STREAM)
835 log.error("Channel write error.")
836 fax_send_state = FAX_SEND_STATE_ERROR
838 monitor_state = False
841 elif fax_send_state == FAX_SEND_STATE_WAIT_FOR_COMPLETE: # -------------- Wait for complete (110, 150, 0)
842 log.debug("%s State: Wait for completion" % ("*"*20))
844 fax_send_state = FAX_SEND_STATE_WAIT_FOR_COMPLETE
847 status = self.getFaxJobTxStatus()
849 if status == pml.FAXJOB_TX_STATUS_DIALING:
850 self.write_queue((STATUS_DIALING, 0, recipient['fax']))
851 log.debug("Dialing ...")
853 elif status == pml.FAXJOB_TX_STATUS_TRANSMITTING:
854 self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
855 log.debug("Transmitting ...")
857 elif status in (pml.FAXJOB_TX_STATUS_DONE, pml.FAXJOB_RX_STATUS_IDLE):
858 fax_send_state = FAX_SEND_STATE_RESET_TOKEN
859 state = STATE_NEXT_RECIPIENT
860 log.debug("Transmitting done or idle ...")
863 self.write_queue((STATUS_SENDING, page_num, recipient['fax']))
864 log.debug("Pending ...")
867 elif fax_send_state == FAX_SEND_STATE_RESET_TOKEN: # -------------- Release fax token (110, 160, 0)
868 log.debug("%s State: Release fax token" % ("*"*20))
869 self.write_queue((STATUS_CLEANUP, 0, ''))
872 self.dev.setPML(pml.OID_FAX_TOKEN, '\x00'*16)
874 log.error("Unable to release fax token.")
876 fax_send_state = FAX_SEND_STATE_CLOSE_SESSION
879 elif fax_send_state == FAX_SEND_STATE_CLOSE_SESSION: # -------------- Close session (110, 170, 0)
880 log.debug("%s State: Close session" % ("*"*20))
881 fax_send_state = FAX_SEND_STATE_DONE
882 log.debug("Closing session...")
894 if self.dev.fax_type == FAX_TYPE_BLACK_SEND_LATE_OPEN:
895 log.debug("Closing fax channel.")
898 self.dev.setPML(pml.OID_FAX_DOWNLOAD, pml.UPDN_STATE_IDLE)
902 if self.dev.fax_type == FAX_TYPE_BLACK_SEND_EARLY_OPEN:
903 log.debug("Closing fax channel.")
909 elif state == STATE_CLEANUP: # --------------------------------- Cleanup (120, 0, 0)
910 log.debug("%s State: Cleanup" % ("*"*20))
912 if self.remove_temp_file:
913 log.debug("Removing merged file: %s" % self.f)
918 log.debug("Not found")
924 # --------------------------------- Support functions
927 def getFaxDownloadState(self):
928 result_code, state = self.dev.getPML(pml.OID_FAX_DOWNLOAD)
930 log.debug("D/L State=%d (%s)" % (state, pml.UPDN_STATE_STR.get(state, 'Unknown')))
933 return pml.UPDN_STATE_ERRORABORT
935 def getFaxDownloadError(self):
936 result_code, state = self.dev.getPML(pml.OID_FAX_DOWNLOAD_ERROR)
940 return pml.DN_ERROR_UNKNOWN
942 def getFaxJobTxStatus(self):
943 result_code, status = self.dev.getPML(pml.OID_FAXJOB_TX_STATUS)
945 log.debug("Tx Status=%d (%s)" % (status, pml.FAXJOB_TX_STATUS_STR.get(status, 'Unknown')))
948 return pml.FAXJOB_TX_STATUS_IDLE
950 def getFaxJobRxStatus(self):
951 result_code, status = self.dev.getPML(pml.OID_FAXJOB_RX_STATUS)
953 log.debug("Rx Status=%d (%s)" % (status, pml.FAXJOB_RX_STATUS_STR.get(status, 'Unknown')))
956 return pml.FAXJOB_RX_STATUS_IDLE
958 def getCfgUploadState(self):
959 result_code, state = self.dev.getPML(pml.OID_DEVICE_CFG_UPLOAD)
961 log.debug("Cfg Upload State = %d (%s)" % (state, pml.UPDN_STATE_STR.get(state, 'Unknown')))
964 return pml.UPDN_STATE_ERRORABORT
966 def create_mfpdtf_fixed_header(self, data_type, send_variant=False, page_flags=0):
967 header_len = FIXED_HEADER_SIZE
970 if data_type == DT_DIAL_STRINGS:
971 header_len += DIAL_STRINGS_VARIANT_HEADER_SIZE
973 elif data_type == DT_FAX_IMAGES:
974 header_len += FAX_IMAGE_VARIANT_HEADER_SIZE
976 self.stream.write(struct.pack("<IHBB",
977 0, header_len, data_type, page_flags))
980 def create_mfpdtf_dial_strings(self, number):
981 p = struct.pack("<BBHH51s",
982 MAJOR_VER, MINOR_VER,
988 def adjust_fixed_header_block_size(self):
989 size = self.stream.tell()
991 self.stream.write(struct.pack("<I", size))
994 def create_sop_record(self, page_num, hort_dpi, vert_dpi, ppr, rpp, encoding, bpp=1):
995 self.stream.write(struct.pack("<BBHHHIHHHHHHIHHHH",
996 RT_START_PAGE, encoding, page_num,
998 rpp, 0x00, hort_dpi, 0x00, vert_dpi,
1000 rpp, 0x00, hort_dpi, 0x00, vert_dpi))
1003 def create_eop_record(self, rpp):
1004 self.stream.write(struct.pack("<BBBBII",
1005 RT_END_PAGE, 0, 0, 0,
1009 def create_raster_data_record(self, data):
1010 assert len(data) <= RASTER_DATA_SIZE
1011 self.stream.write(struct.pack("<BBH",
1012 RT_RASTER, 0, len(data),))
1013 self.stream.write(data)
1016 def create_mfpdtf_fax_header(self, total_pages):
1017 self.stream.write(struct.pack("<BBBHBI20s20s20sI",
1018 MAJOR_VER, MINOR_VER, SRC_HOST, total_pages,
1019 TTI_PREPENDED_TO_IMAGE, 0, '', '', '', 0))
1022 def write_stream(self):
1023 self.adjust_fixed_header_block_size()
1024 self.dev.writeFax(self.stream.getvalue())
1025 self.stream.truncate(0)