home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / hplip / fax / marvellfax.py < prev    next >
Encoding:
Python Source  |  2011-12-02  |  34.5 KB  |  866 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2010 Hewlett-Packard Development Company, L.P.
  4. #
  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.
  9. #
  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.
  14. #
  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
  18. #
  19. # Author: Suma Byrappa
  20. #
  21.  
  22. # Std Lib
  23. import sys
  24. import os
  25. import os.path
  26. import struct
  27. import time
  28. import threading
  29. import cStringIO
  30.  
  31. from stat import *
  32.  
  33. # Local
  34. from base.g import *
  35. from base.codes import *
  36. from base import device, utils, pml, codes
  37. from prnt import cups
  38. from fax import *
  39. import hpmudext
  40.  
  41. try:
  42.     from ctypes import cdll
  43.     from ctypes import *
  44.     import ctypes.util as cu
  45. except ImportError:
  46.     log.error("Marvell fax support requires python-ctypes module. Exiting!")
  47.     sys.exit(1)
  48.  
  49.  
  50. # **************************************************************************** #
  51. # Marvell Message Types
  52. START_FAX_JOB = 0
  53. END_FAX_JOB = 1
  54. SEND_FAX_JOB = 2
  55. GET_FAX_LOG_ENTRY = 5
  56. GET_FAX_SETTINGS = 9
  57. SET_FAX_SETTINGS = 10
  58. CLEAR_FAX_STATUS = 11
  59. REQUEST_FAX_STATUS = 12
  60. FAX_DATA_BLOCK = 13
  61.  
  62. SUCCESS = 0
  63. FAILURE = 1
  64.  
  65. FAX_DATA_BLOCK_SIZE = 4096
  66.  
  67. # Fax data variant header TTI header control
  68. TTI_NONE = 0
  69. TTI_PREPENDED_TO_IMAGE = 1
  70. TTI_OVERLAYED_ON_IMAGE = 2
  71.  
  72. # **************************************************************************** #
  73. class MarvellFaxDevice(FaxDevice):
  74.  
  75.     def __init__(self, device_uri=None, printer_name=None,
  76.                  callback=None,
  77.                  fax_type=FAX_TYPE_NONE,
  78.                  disable_dbus=False):
  79.  
  80.         FaxDevice.__init__(self, device_uri,
  81.                            printer_name,
  82.                            callback, fax_type,
  83.                            disable_dbus)
  84.  
  85.         self.send_fax_thread = None
  86.         self.upload_log_thread = None
  87.  
  88.         try:
  89.             sendfax_path = utils.which('hp-sendfax')
  90.             sendfax_a_path = os.readlink(sendfax_path+"/hp-sendfax")
  91.             if not os.path.isabs(sendfax_a_path):
  92.                    sendfax_f_path = os.path.join(sendfax_path, sendfax_a_path)
  93.             else:
  94.                    sendfax_f_path = sendfax_a_path
  95.  
  96.             sendfax_abs_path = os.path.realpath(sendfax_f_path)
  97.             (head, tail) = os.path.split(sendfax_abs_path)  
  98.  
  99.             lib_name = head+"/fax/plugins/fax_marvell.so"
  100.             log.debug("Load the library %s\n" % lib_name)
  101.             self.libfax_marvell = cdll.LoadLibrary(lib_name)
  102.         except Error, e:
  103.             log.error("Loading fax_marvell failed (%s)\n" % e.msg);
  104.             sys.exit(1)
  105.  
  106.  
  107.     # Creates a message packet for message type given in argument, and sends it to device
  108.     #
  109.     # 1. Gets the message packet using fax_marvell.so
  110.     # 2. Writes the packets to device
  111.     # 3. Returns the result of send operation
  112.     def send_packet_for_message(self, msg_type, param1=0, param2=0, status=0, data_len=0):
  113.         int_array_8 = c_int * 8
  114.         i_buf = int_array_8(0, 0, 0, 0, 0, 0, 0, 0)
  115.  
  116.         result = self.libfax_marvell.create_packet(msg_type, param1, param2, status, data_len, byref(i_buf))
  117.         buf = buffer(i_buf)
  118.         log.log_data(buf, 32)
  119.         self.writeMarvellFax(buf)
  120.         self.closeMarvellFax()
  121.  
  122.         return result
  123.  
  124.  
  125.     # Reads response message packet from the device for message type given in argument.
  126.     #       Reads the response from device, and sends the data read to the caller of this method
  127.     #       No Marvell specific code or info
  128.     def read_response_for_message(self, msg_type):
  129.         ret_buf = cStringIO.StringIO()
  130.         while self.readMarvellFax(32, ret_buf, timeout=10):
  131.                             pass
  132.  
  133.         ret_buf = ret_buf.getvalue()
  134.         self.closeMarvellFax()
  135.  
  136.         log.debug("response_for_message (%d): response packet is\n" % msg_type)
  137.         log.log_data(ret_buf, 32)
  138.  
  139.         return ret_buf
  140.  
  141.  
  142.     def setPhoneNum(self, num):
  143.         log.debug("************************* setPhoneNum (%s) START **************************" % num)
  144.  
  145.         set_buf = cStringIO.StringIO()
  146.  
  147.         int_array = c_int * 8
  148.         i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0)
  149.  
  150.         char_array = c_char * 308
  151.         c_buf = char_array()
  152.  
  153.         date_array = c_char * 15
  154.         date_buf = date_array()
  155.         t = time.localtime()
  156.         date_buf = "%4d%02d%02d%02d%02d%02d" % (t[0], t[1], t[2], t[3], t[4], t[5])
  157.         log.debug("Date and Time string is ==>")
  158.         log.debug(date_buf)
  159.  
  160.         result = self.libfax_marvell.create_packet(SET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf))
  161.         result = self.libfax_marvell.create_fax_settings_packet(self.station_name, str(num), date_buf, byref(c_buf))
  162.  
  163.         msg_buf = buffer(i_buf)
  164.         msg_c_buf = buffer(c_buf)
  165.  
  166.         for i in range(0, 32):
  167.             set_buf.write(msg_buf[i])
  168.         for i in range(0, 308):
  169.             set_buf.write(msg_c_buf[i])
  170.  
  171.         set_buf = set_buf.getvalue()
  172.         log.debug("setPhoneNum: send SET_FAX_SETTINGS message and data ===> ")
  173.         log.log_data(set_buf, 340)
  174.  
  175.         self.writeMarvellFax(set_buf)
  176.         ret_buf = cStringIO.StringIO()
  177.         while self.readMarvellFax(32, ret_buf, timeout=10):
  178.                             pass
  179.         ret_buf = ret_buf.getvalue()
  180.         self.closeMarvellFax()
  181.  
  182.         response = self.libfax_marvell.extract_response(ret_buf) 
  183.         log.debug("setPhoneNum: response is %d" % response)
  184.  
  185.         log.debug("************************* setPhoneNum END **************************")
  186.         return response
  187.  
  188.  
  189.     def getPhoneNum(self):
  190.         int_array_8 = c_int * 8
  191.         i_buf = int_array_8(0, 0, 0, 0, 0, 0, 0, 0)
  192.         ph_buf = int_array_8(0, 0, 0, 0, 0, 0, 0, 0)
  193.  
  194.         log.debug("******************** getPhoneNum START **********************")
  195.  
  196.         result = self.libfax_marvell.create_packet(GET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf))
  197.  
  198.         buf = buffer(i_buf)
  199.         self.writeMarvellFax(buf)
  200.         self.closeMarvellFax()
  201.         ret_buf = cStringIO.StringIO()
  202.         while self.readMarvellFax(512, ret_buf, timeout=10):
  203.                             pass
  204.         ret_buf = ret_buf.getvalue()
  205.         self.closeMarvellFax()
  206.  
  207.         response = self.libfax_marvell.extract_response(ret_buf) 
  208.         log.debug("create_packet: response is %d" % response)
  209.  
  210.         response = self.libfax_marvell.extract_phone_number(ret_buf, ph_buf) 
  211.         ph_num_buf = cStringIO.StringIO()
  212.         for i in range(0, 7):
  213.             if ph_buf[i]:
  214.                ph_num_buf.write(str(ph_buf[i]))
  215.  
  216.         ph_num_buf = ph_num_buf.getvalue()
  217.         log.debug("getPhoneNum: ph_num_buf=%s " % (ph_num_buf))
  218.  
  219.         log.debug("******************** getPhoneNum END **********************")
  220.         return ph_num_buf
  221.  
  222.  
  223.     # Note down the fax (phone) number
  224.     phone_num = property(getPhoneNum, setPhoneNum)
  225.  
  226.  
  227.     # Set the station name in the device's settings
  228.     #
  229.     def setStationName(self, name):
  230.         log.debug("************************* setStationName(%s) START **************************" % name)
  231.  
  232.         int_array = c_int * 8
  233.         i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0)
  234.         set_buf = cStringIO.StringIO()
  235.  
  236.         char_array = c_char * 308
  237.         c_buf = char_array()
  238.  
  239.         date_array = c_char * 15
  240.         date_buf = date_array()
  241.         t = time.localtime()
  242.         date_buf = "%4d%02d%02d%02d%02d%02d" % (t[0], t[1], t[2], t[3], t[4], t[5])
  243.         log.debug("Date and Time string is ==>")
  244.         log.debug(date_buf)
  245.  
  246.         result = self.libfax_marvell.create_packet(SET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf))
  247.         result = self.libfax_marvell.create_fax_settings_packet(str(name), self.phone_num, date_buf, byref(c_buf))
  248.  
  249.         msg_buf = buffer(i_buf)
  250.         msg_c_buf = buffer(c_buf)
  251.  
  252.         for i in range(0, 32):
  253.             set_buf.write(msg_buf[i])
  254.         for i in range(0, 308):
  255.             set_buf.write(msg_c_buf[i])
  256.         set_buf = set_buf.getvalue()
  257.         log.debug("setStationName: SET_FAX_SETTINGS message and data ===> ")
  258.         log.log_data(set_buf, 340)
  259.  
  260.         self.writeMarvellFax(set_buf)
  261.         ret_buf = cStringIO.StringIO()
  262.         while self.readMarvellFax(32, ret_buf, timeout=10):
  263.                             pass
  264.         ret_buf = ret_buf.getvalue()
  265.         self.closeMarvellFax()
  266.  
  267.         response = self.libfax_marvell.extract_response(ret_buf) 
  268.         log.debug("setStationName: response is %d" % response)
  269.  
  270.         log.debug("************************* setStationName END **************************")
  271.         return response
  272.  
  273.  
  274.     def getStationName(self):
  275.         int_array = c_int * 8
  276.         i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0)
  277.         st_buf = create_string_buffer(128)
  278.  
  279.         log.debug("************************* getStationName START **************************")
  280.  
  281.         result = self.libfax_marvell.create_packet(GET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf))
  282.  
  283.         buf = buffer(i_buf)
  284.         self.writeMarvellFax(buf)
  285.         self.closeMarvellFax()
  286.  
  287.         ret_buf = cStringIO.StringIO()
  288.         while self.readMarvellFax(512, ret_buf, timeout=10):
  289.                             pass
  290.  
  291.         ret_buf = ret_buf.getvalue()
  292.         self.closeMarvellFax()
  293.  
  294.         response = self.libfax_marvell.extract_response(ret_buf)
  295.         log.debug("getStationName: response is %d" % response)
  296.  
  297.         result = self.libfax_marvell.extract_station_name(ret_buf, st_buf) 
  298.         log.debug("getStationName: station_name=%s ; result is %d" % (st_buf.value, result))
  299.  
  300.         log.debug("************************* getStationName END **************************")
  301.         return st_buf.value
  302.  
  303.  
  304.    # Note down the station-name
  305.     station_name = property(getStationName, setStationName)
  306.  
  307.  
  308.     # Set date and time in the device's settings
  309.     #
  310.     # 1. Gets the message packet and fax_settings packet using fax_marvell.so 
  311.     # 2. Writes the packets to the device; Reads response from the device
  312.     # 3. Extracts the status from the device's response
  313.     def setDateAndTime(self):
  314.         int_array = c_int * 8
  315.         i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0)
  316.  
  317.         log.debug("************************* setDateAndTime START **************************")
  318.  
  319.         c_buf = create_string_buffer(308)
  320.         set_buf = cStringIO.StringIO()
  321.         ret_buf = cStringIO.StringIO()
  322.         date_array = c_char * 15
  323.         date_buf = date_array()
  324.  
  325.         t = time.localtime()
  326.  
  327.         date_buf = "%4d%02d%02d%02d%02d%02d" % (t[0], t[1], t[2], t[3], t[4], t[5])
  328.         log.debug("Date and Time string is ==>")
  329.         log.debug(date_buf)
  330.  
  331.         result = self.libfax_marvell.create_packet(SET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf))
  332.         result = create_marvell_faxsettings_pkt(self.phone_num, self.station_name, date_buf, c_buf)
  333.  
  334.         msg_buf = buffer(i_buf)
  335.         for i in range(0, 31):
  336.             set_buf.write(msg_buf[i])
  337.  
  338.         set_buf.write(c_buf.raw)
  339.         set_buf = set_buf.getvalue()
  340.         self.dev.writeMarvellFax(set_buf)
  341.         while self.dev.readMarvellFax(32, ret_buf, timeout=5):
  342.                             pass
  343.         ret_buf = ret_buf.getvalue()
  344.         self.closeMarvellFax()
  345.  
  346.         response = self.libfax_marvell.extract_response(ret_buf)
  347.         log.debug("setDateAndTime: response is %d" % response)
  348.  
  349.         return response
  350.  
  351.  
  352.     # Get the state of the device 
  353.     #
  354.     # 1. Gets the message packet using fax_marvell.so 
  355.     # 2. Writes the packet to the device; Reads response from the device
  356.     # 3. Extracts the response status and device status from the device's response
  357.     def getFaxDeviceState(self):
  358.         log.debug("************************* getFaxDeviceState: START **************************")
  359.  
  360.         int_array = c_int * 8
  361.         i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0)
  362.         param1 = c_int(0)
  363.  
  364.         result = self.libfax_marvell.create_packet(REQUEST_FAX_STATUS, 0, 0, 0, 0, byref(i_buf))
  365.         buf = buffer(i_buf)
  366.         self.writeMarvellFax(buf)
  367.  
  368.         ret_buf = cStringIO.StringIO()
  369.         while self.readMarvellFax(32, ret_buf, timeout=5):
  370.                             pass
  371.         ret_buf = ret_buf.getvalue()
  372.         self.closeMarvellFax()
  373.  
  374.         response = self.libfax_marvell.extract_response(ret_buf)
  375.         log.debug("getFaxDeviceState: response is %d" % response)
  376.  
  377.         return response
  378.  
  379.  
  380.     # Creates a thread which does actual Fax submission the state of the device 
  381.     #
  382.     def sendFaxes(self, phone_num_list, fax_file_list, cover_message='', cover_re='',
  383.                   cover_func=None, preserve_formatting=False, printer_name='',
  384.                   update_queue=None, event_queue=None):
  385.  
  386.         if not self.isSendFaxActive():
  387.  
  388.             self.send_fax_thread = MarvellFaxSendThread(self, self.service, phone_num_list, fax_file_list,
  389.                                                     cover_message, cover_re, cover_func,
  390.                                                     preserve_formatting,
  391.                                                     printer_name, update_queue,
  392.                                                     event_queue)
  393.  
  394.             self.send_fax_thread.start()
  395.             return True
  396.         else:
  397.             return False
  398.  
  399.  
  400.  
  401. # **************************************************************************** #
  402. # Does the actual Fax transmission
  403. # **************************************************************************** #
  404. class MarvellFaxSendThread(FaxSendThread):
  405.     def __init__(self, dev, service, phone_num_list, fax_file_list,
  406.                  cover_message='', cover_re='', cover_func=None, preserve_formatting=False,
  407.                  printer_name='', update_queue=None, event_queue=None):
  408.  
  409.         FaxSendThread.__init__(self, dev, service, phone_num_list, fax_file_list,
  410.              cover_message, cover_re, cover_func, preserve_formatting,
  411.              printer_name, update_queue, event_queue)
  412.  
  413.  
  414.     def run(self):
  415.  
  416.         STATE_DONE = 0
  417.         STATE_ABORTED = 10
  418.         STATE_SUCCESS = 20
  419.         STATE_BUSY = 25
  420.         STATE_READ_SENDER_INFO = 30
  421.         STATE_PRERENDER = 40
  422.         STATE_COUNT_PAGES = 50
  423.         STATE_NEXT_RECIPIENT = 60
  424.         STATE_COVER_PAGE = 70
  425.         STATE_SINGLE_FILE = 80
  426.         STATE_MERGE_FILES = 90
  427.         STATE_SINGLE_FILE = 100
  428.         STATE_SEND_FAX = 110
  429.         STATE_CLEANUP = 120
  430.         STATE_ERROR = 130
  431.  
  432.         next_recipient = self.next_recipient_gen()
  433.  
  434.         rec_name = None
  435.         rec_num = None
  436.  
  437.         state = STATE_READ_SENDER_INFO
  438.         self.rendered_file_list = []
  439.  
  440.         while state != STATE_DONE: # --------------------------------- Fax state machine
  441.             if self.check_for_cancel():
  442.                 log.debug("***** Job is Cancelled.")
  443.                 state = STATE_ABORTED
  444.  
  445.             log.debug("*************** STATE=(%d, 0, 0)" % state)
  446.  
  447.             if state == STATE_ABORTED: # --------------------------------- Aborted 
  448.                 log.error("Aborted by user.")
  449.                 self.write_queue((STATUS_IDLE, 0, ''))
  450.                 state = STATE_CLEANUP
  451.  
  452.  
  453.             elif state == STATE_SUCCESS: # --------------------------------- Success 
  454.                 log.debug("Success.")
  455.                 self.write_queue((STATUS_COMPLETED, 0, ''))
  456.                 state = STATE_CLEANUP
  457.  
  458.  
  459.             elif state == STATE_ERROR: # --------------------------------- Error 
  460.                 log.error("Error, aborting.")
  461.                 self.write_queue((STATUS_ERROR, 0, ''))
  462.                 state = STATE_CLEANUP
  463.  
  464.  
  465.             elif state == STATE_BUSY: # --------------------------------- Busy 
  466.                 log.error("Device busy, aborting.")
  467.                 self.write_queue((STATUS_BUSY, 0, ''))
  468.                 state = STATE_CLEANUP
  469.  
  470.  
  471.             elif state == STATE_READ_SENDER_INFO: # --------------------------------- Get sender info 
  472.                 log.debug("%s State: Get sender info" % ("*"*20))
  473.                 state = STATE_PRERENDER
  474.                 try:
  475.                     try:
  476.                         self.dev.open()
  477.                     except Error, e:
  478.                         log.error("Unable to open device (%s)." % e.msg)
  479.                         state = STATE_ERROR
  480.                     else:
  481.                         try:
  482.                             self.sender_name = self.dev.station_name
  483.                             self.sender_fax = self.dev.phone_num
  484.                         except Error:
  485.                             log.error("Getting station-name and phone_num failed!")
  486.                             state = STATE_ERROR
  487.  
  488.                 finally:
  489.                     self.dev.close()
  490.  
  491.  
  492.             elif state == STATE_PRERENDER: # --------------------------------- Pre-render non-G3 files 
  493.                 log.debug("%s State: Pre-render non-G3 files" % ("*"*20))
  494.                 state = self.pre_render(STATE_COUNT_PAGES)
  495.  
  496.  
  497.             elif state == STATE_COUNT_PAGES: # --------------------------------- Get total page count 
  498.                 log.debug("%s State: Get total page count" % ("*"*20))
  499.                 state = self.count_pages(STATE_NEXT_RECIPIENT)
  500.  
  501.  
  502.             elif state == STATE_NEXT_RECIPIENT: # --------------------------------- Loop for multiple recipients
  503.                 log.debug("%s State: Next recipient" % ("*"*20))
  504.                 state = STATE_COVER_PAGE
  505.  
  506.                 try:
  507.                     recipient = next_recipient.next()
  508.  
  509.                     self.write_queue((STATUS_SENDING_TO_RECIPIENT, 0, recipient['name']))
  510.                     
  511.                     rec_name = recipient['name']
  512.                     rec_num = recipient['fax'].encode('ascii')
  513.                     log.debug("recipient is %s num is %s" % (rec_name, rec_num))
  514.  
  515.                 except StopIteration:
  516.                     state = STATE_SUCCESS
  517.                     log.debug("Last recipient.")
  518.                     continue
  519.  
  520.                 self.recipient_file_list = self.rendered_file_list[:]
  521.  
  522.  
  523.             elif state == STATE_COVER_PAGE: # --------------------------------- Create cover page 
  524.                 log.debug("%s State: Render cover page" % ("*"*20))
  525.                 state = self.cover_page(recipient)
  526.  
  527.  
  528.             elif state == STATE_SINGLE_FILE: # --------------------------------- Special case for single file (no merge)
  529.                 log.debug("%s State: Handle single file" % ("*"*20))
  530.                 state = self.single_file(STATE_SEND_FAX)
  531.  
  532.             elif state == STATE_MERGE_FILES: # --------------------------------- Merge multiple G3 files 
  533.                 log.debug("%s State: Merge multiple files" % ("*"*20))
  534.                 log.debug("Not merging the files for Marvell support")
  535.                 state = STATE_SEND_FAX
  536.  
  537.             elif state == STATE_SEND_FAX: # --------------------------------- Send fax state machine 
  538.                 log.debug("%s State: Send fax" % ("*"*20))
  539.                 state = STATE_NEXT_RECIPIENT
  540.  
  541.                 next_file = self.next_file_gen()
  542.  
  543.                 FAX_SEND_STATE_DONE = 0
  544.                 FAX_SEND_STATE_SUCCESS = 10
  545.                 FAX_SEND_STATE_ABORT = 21
  546.                 FAX_SEND_STATE_ERROR = 22
  547.                 FAX_SEND_STATE_BUSY = 25
  548.                 FAX_SEND_STATE_DEVICE_OPEN = 30
  549.                 FAX_SEND_STATE_NEXT_FILE = 35
  550.                 FAX_SEND_STATE_CHECK_IDLE = 40
  551.                 FAX_SEND_STATE_START_JOB_REQUEST = 50
  552.                 FAX_SEND_STATE_SEND_JOB_REQUEST = 60
  553.                 FAX_SEND_STATE_SET_PARAMS = 70
  554.                 FAX_SEND_STATE_SEND_FAX_HEADER = 80
  555.                 FAX_SEND_STATE_SEND_FILE_DATA = 90
  556.                 FAX_SEND_STATE_END_FILE_DATA = 100
  557.                 FAX_SEND_STATE_END_JOB_REQUEST = 110
  558.                 FAX_SEND_STATE_GET_LOG_INFORMATION = 120
  559.  
  560.                 monitor_state = False
  561.                 current_state = SUCCESS
  562.                 fax_send_state = FAX_SEND_STATE_DEVICE_OPEN
  563.  
  564.                 while fax_send_state != FAX_SEND_STATE_DONE:
  565.  
  566.                     if self.check_for_cancel():
  567.                         log.error("Fax send aborted.")
  568.                         fax_send_state = FAX_SEND_STATE_ABORT
  569.  
  570.                     if monitor_state:
  571.                         fax_state = self.getFaxDeviceState()
  572.                         if fax_state != SUCCESS:
  573.                             log.error("Device is in error state=%d" % fax_state)
  574.                             fax_send_state = FAX_SEND_STATE_ERROR
  575.                             state = STATE_ERROR
  576.  
  577.  
  578.                     log.debug("*********  FAX_SEND_STATE=(%d, %d, %d)" % (STATE_SEND_FAX, fax_send_state, current_state))
  579.  
  580.                     if fax_send_state == FAX_SEND_STATE_ABORT: # -------------- Abort 
  581.                         monitor_state = False
  582.                         fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST
  583.                         state = STATE_ABORTED
  584.  
  585.                     elif fax_send_state == FAX_SEND_STATE_ERROR: # -------------- Error 
  586.                         log.error("Fax send error.")
  587.                         monitor_state = False
  588.  
  589.                         fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST
  590.                         state = STATE_ERROR
  591.  
  592.                     elif fax_send_state == FAX_SEND_STATE_BUSY: # -------------- Busy 
  593.                         log.error("Fax device busy.")
  594.                         monitor_state = False
  595.                         fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST
  596.                         state = STATE_BUSY
  597.  
  598.                     elif fax_send_state == FAX_SEND_STATE_SUCCESS: # -------------- Success 
  599.                         log.debug("Fax send success.")
  600.                         monitor_state = False
  601.                         fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST
  602.                         state = STATE_NEXT_RECIPIENT
  603.  
  604.                     elif fax_send_state == FAX_SEND_STATE_DEVICE_OPEN: # -------------- Device open 
  605.                         log.debug("%s State: Open device" % ("*"*20))
  606.                         fax_send_state = FAX_SEND_STATE_NEXT_FILE
  607.                         try:
  608.                             self.dev.open()
  609.                         except Error, e:
  610.                             log.error("Unable to open device (%s)." % e.msg)
  611.                             fax_send_state = FAX_SEND_STATE_ERROR
  612.                         else:
  613.                             if self.dev.device_state == DEVICE_STATE_NOT_FOUND:
  614.                                 fax_send_state = FAX_SEND_STATE_ERROR
  615.  
  616.  
  617.                     elif fax_send_state == FAX_SEND_STATE_NEXT_FILE: # -------------- Device open 
  618.                         log.debug("%s State: Open device" % ("*"*20))
  619.                         fax_send_state = FAX_SEND_STATE_CHECK_IDLE
  620.                         try:
  621.                              fax_file = next_file.next()
  622.                              self.f = fax_file[0]
  623.                              log.debug("***** file name is : %s..." % self.f)
  624.                         except StopIteration:
  625.                              log.debug("file(s) are sent to the device" )
  626.                              fax_send_state = FAX_SEND_STATE_DONE
  627.  
  628.  
  629.                     elif fax_send_state == FAX_SEND_STATE_CHECK_IDLE: # -------------- Check for initial idle
  630.                         log.debug("%s State: Check idle" % ("*"*20))
  631.                         fax_send_state = FAX_SEND_STATE_START_JOB_REQUEST
  632.  
  633.                         try:
  634.                             ff = file(self.f, 'r')
  635.                         except IOError:
  636.                             log.error("Unable to read fax file.")
  637.                             fax_send_state = FAX_SEND_STATE_ERROR
  638.                             continue
  639.  
  640.                         try:
  641.                             header = ff.read(FILE_HEADER_SIZE)
  642.                         except IOError:
  643.                             log.error("Unable to read fax file.")
  644.                             fax_send_state = FAX_SEND_STATE_ERROR
  645.                             continue
  646.  
  647.                         magic, version, total_pages, hort_dpi, vert_dpi, page_size, \
  648.                             resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header)
  649.  
  650.                         if magic != 'hplip_g3':
  651.                             log.error("Invalid file header. Bad magic.")
  652.                             fax_send_state = FAX_SEND_STATE_ERROR
  653.                         else:
  654.                             log.debug("Magic=%s Version=%d Total Pages=%d hDPI=%d vDPI=%d Size=%d Resolution=%d Encoding=%d"
  655.                             % (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding))
  656.  
  657.                         dev_state = self.dev.getFaxDeviceState()
  658.  
  659.                         if (dev_state == 0):
  660.                            log.debug("State: device status is zero ")
  661.                         else:
  662.                            log.debug("State: device status is non-zero ")
  663.                            fax_send_state = FAX_SEND_STATE_BUSY
  664.  
  665.  
  666.                     elif fax_send_state == FAX_SEND_STATE_START_JOB_REQUEST: # -------------- Request fax start
  667.                         log.debug("%s State: Request start" % ("*"*20))
  668.                         fax_send_state = FAX_SEND_STATE_SEND_JOB_REQUEST
  669.  
  670.                         file_len = os.stat(self.f)[ST_SIZE]
  671.                         tx_data_len = file_len - FILE_HEADER_SIZE - (PAGE_HEADER_SIZE*total_pages)
  672.                         log.debug("#### file_len = %d" % file_len)
  673.                         log.debug("#### tx_data_len = %d" % tx_data_len)
  674.                         ret_value = self.dev.send_packet_for_message(START_FAX_JOB, tx_data_len, 0, 0, 0)
  675.                         if ret_value:
  676.                            log.debug("Sending start fax request failed with %d" % ret_value)
  677.                            fax_send_state = FAX_SEND_STATE_ERROR
  678.                         else:
  679.                            log.debug("Successfully sent start fax request")
  680.                            ret_buf = self.dev.read_response_for_message(START_FAX_JOB)
  681.                            dev_response = self.dev.libfax_marvell.extract_response(ret_buf)
  682.                            if dev_response:
  683.                               log.debug("start-fax request failed with %d" % dev_response)
  684.                               fax_send_state = FAX_SEND_STATE_ERROR
  685.                            else:
  686.                               log.debug("start-fax request is successful")
  687.  
  688.                     elif fax_send_state == FAX_SEND_STATE_SEND_JOB_REQUEST: # -------------- Set data request 
  689.                         log.debug("%s State: Send data request" % ("*"*20))
  690.                         fax_send_state = FAX_SEND_STATE_SET_PARAMS 
  691.  
  692.                         ret_value = self.dev.send_packet_for_message(SEND_FAX_JOB)
  693.                         if ret_value:
  694.                            log.debug("Sending send-data request failed with %d" % ret_value)
  695.                            fax_send_state = FAX_SEND_STATE_ERROR
  696.                         else:
  697.                            log.debug("Successfully sent send-fax request")
  698.  
  699.  
  700.                     elif fax_send_state == FAX_SEND_STATE_SET_PARAMS: # -------------- Set fax send params 
  701.                         log.debug("%s State: Set params" % ("*"*20))
  702.                         fax_send_state = FAX_SEND_STATE_SEND_FAX_HEADER
  703.  
  704.                         c_buf = create_string_buffer(68)
  705.                         set_buf = cStringIO.StringIO()
  706.  
  707.                         no_data = None
  708.                         ret_val = self.dev.libfax_marvell.create_job_settings_packet(no_data, rec_num, c_buf)
  709.                         set_buf.write(c_buf.raw)
  710.                         set_buf = set_buf.getvalue()
  711.  
  712.                         self.dev.writeMarvellFax(set_buf)
  713.                         self.dev.closeMarvellFax()
  714.  
  715.  
  716.                     elif fax_send_state == FAX_SEND_STATE_SEND_FAX_HEADER: # -------------- Fax header 
  717.                         #   Taken care by the device
  718.                         fax_send_state = FAX_SEND_STATE_SEND_FILE_DATA
  719.  
  720.                     elif fax_send_state == FAX_SEND_STATE_SEND_FILE_DATA:  # --------------------------------- Send fax pages state machine 
  721.                         log.debug("%s State: Send pages" % ("*"*20))
  722.                         fax_send_state = FAX_SEND_STATE_END_FILE_DATA
  723.                         current_state = SUCCESS
  724.                         page = StringIO()
  725.  
  726.                         file_len = os.stat(self.f)[ST_SIZE]
  727.                         bytes_to_read = file_len - FILE_HEADER_SIZE - (PAGE_HEADER_SIZE*total_pages)
  728.  
  729.                         for p in range(total_pages):
  730.  
  731.                             if self.check_for_cancel():
  732.                                 current_state = FAILURE
  733.  
  734.                             if current_state == FAILURE:
  735.                                 break
  736.  
  737.                             try:
  738.                                 header = ff.read(PAGE_HEADER_SIZE)
  739.                             except IOError:
  740.                                 log.error("Unable to read fax file.")
  741.                                 current_state = FAILURE
  742.                                 continue
  743.  
  744.                             page_num, ppr, rpp, b_to_read, thumbnail_bytes, reserved2 = \
  745.                                 self.decode_page_header(header)
  746.  
  747.                             log.debug("Page=%d PPR=%d RPP=%d BPP=%d Thumb=%d" %
  748.                                       (page_num, ppr, rpp, b_to_read, thumbnail_bytes))
  749.  
  750.                             page.write(ff.read(b_to_read))
  751.                             thumbnail = ff.read(thumbnail_bytes) # thrown away for now (should be 0 read)
  752.                             page.seek(0)
  753.                             bytes_to_write = b_to_read
  754.                             total_read = 0
  755.                             while (bytes_to_write > 0):
  756.                                try:
  757.                                    data = page.read(FAX_DATA_BLOCK_SIZE)
  758.                                except IOError:
  759.                                    log.error("Unable to read fax file.")
  760.                                    current_state = FAILURE
  761.                                    continue
  762.  
  763.                                if data == '':
  764.                                    log.error("No data!")
  765.                                    current_state = FAILURE
  766.                                    break
  767.  
  768.                                if self.check_for_cancel():
  769.                                    current_state = FAILURE
  770.                                    log.error("Job is cancelled. Aborting...")
  771.                                    break
  772.  
  773.                                total_read += FAX_DATA_BLOCK_SIZE
  774.  
  775.                                try:
  776.                                    ret_value = self.dev.send_packet_for_message(FAX_DATA_BLOCK, 0, 0, 0, len(data))
  777.                                    if ret_value:
  778.                                       log.debug("Sending fax-data-block request failed with %d" % ret_value)
  779.                                       current_state = FAILURE
  780.                                    else:
  781.                                       log.debug("Successfully sent fax-data-block request")
  782.  
  783.                                    self.dev.writeMarvellFax(data)
  784.                                    self.dev.closeMarvellFax()
  785.                                except Error:
  786.                                    log.error("Channel write error.")
  787.                                    current_state = FAILURE
  788.                                    break
  789.  
  790.                                bytes_to_write = bytes_to_write - FAX_DATA_BLOCK_SIZE
  791.  
  792.                             page.truncate(0)
  793.                             page.seek(0)
  794.  
  795.  
  796.                     elif fax_send_state == FAX_SEND_STATE_END_FILE_DATA: # -------------- end-of-data
  797.                         log.debug("%s State: Send end-of-file-data request" % ("*"*20))
  798.                         fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST
  799.  
  800.                         ret_value = self.dev.send_packet_for_message(FAX_DATA_BLOCK, 0, 0, current_state, 0)
  801.                         if ret_value:
  802.                            log.debug("Sending fax-data-block packet failed with %d" % ret_value)
  803.                            current_state = FAILURE
  804.                         else:
  805.                            log.debug("Successfully sent fax-data-block request")
  806.                            ret_buf = self.dev.read_response_for_message(SEND_FAX_JOB)
  807.                            dev_response = self.dev.libfax_marvell.extract_response(ret_buf)
  808.                            if dev_response:
  809.                               log.debug("send-fax request failed with %d" % dev_response)
  810.                               current_state = FAILURE
  811.                            else:
  812.                               log.debug("send-fax request is successful")
  813.  
  814.                            if current_state:
  815.                               log.debug("Exiting...")
  816.                               sys.exit(1)
  817.  
  818.  
  819.                     elif fax_send_state == FAX_SEND_STATE_END_JOB_REQUEST: # -------------- Wait for complete 
  820.                         log.debug("%s State: End the job" % ("*"*20))
  821.                         fax_send_state = FAX_SEND_STATE_NEXT_FILE
  822.  
  823.                         ret_value = self.dev.send_packet_for_message(END_FAX_JOB, 0, 0, current_state, 0)
  824.                         if ret_value:
  825.                            log.debug("Sending end-fax-job packet failed with %d" % ret_value)
  826.                            current_state = FAILURE
  827.                         else:
  828.                            log.debug("Successfully sent end-fax-job request")
  829.                            ret_buf = self.dev.read_response_for_message(END_FAX_JOB)
  830.                            dev_response = self.dev.libfax_marvell.extract_response(ret_buf)
  831.                            if dev_response:
  832.                               log.debug("end-fax-job request failed with %d" % dev_response)
  833.                               current_state = FAILURE
  834.                            else:
  835.                               log.debug("end-fax-job request is successful")
  836.  
  837.                         if current_state != SUCCESS:
  838.                            # There was an error during transmission...
  839.                            log.error("An error occurred! setting fax_send_state to DONE")
  840.                            fax_send_state = FAX_SEND_STATE_DONE
  841.  
  842.                         try:
  843.                             ff.close()
  844.                         except NameError:
  845.                             pass
  846.  
  847.                         time.sleep(1)
  848.  
  849.                         self.dev.close()
  850.  
  851.  
  852.             elif state == STATE_CLEANUP: # --------------------------------- Cleanup 
  853.                 log.debug("%s State: Cleanup" % ("*"*20))
  854.  
  855.                 if self.remove_temp_file:
  856.                     log.debug("Removing merged file: %s" % self.f)
  857.                     try:
  858.                         os.remove(self.f)
  859.                         log.debug("Removed")
  860.                     except OSError:
  861.                         log.debug("Not found")
  862.  
  863.                 state = STATE_DONE
  864.  
  865.  
  866.