diff options
Diffstat (limited to 'fax/marvellfax.py')
-rw-r--r-- | fax/marvellfax.py | 872 |
1 files changed, 872 insertions, 0 deletions
diff --git a/fax/marvellfax.py b/fax/marvellfax.py new file mode 100644 index 0000000..4d5ced3 --- /dev/null +++ b/fax/marvellfax.py @@ -0,0 +1,872 @@ +# -*- coding: utf-8 -*- +# +# (c) Copyright 2010 Hewlett-Packard Development Company, L.P. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Author: Suma Byrappa +# + +# Std Lib +import sys +import os +import os.path +import struct +import time +import threading +import cStringIO + +from stat import * + +# Local +from base.g import * +from base.codes import * +from base import device, utils, pml, codes +from prnt import cups +from fax import * +import hpmudext + +try: + from ctypes import cdll + from ctypes import * + import ctypes.util as cu +except ImportError: + log.error("Marvell fax support requires python-ctypes module. Exiting!") + sys.exit(1) + + +# **************************************************************************** # +# Marvell Message Types +START_FAX_JOB = 0 +END_FAX_JOB = 1 +SEND_FAX_JOB = 2 +GET_FAX_LOG_ENTRY = 5 +GET_FAX_SETTINGS = 9 +SET_FAX_SETTINGS = 10 +CLEAR_FAX_STATUS = 11 +REQUEST_FAX_STATUS = 12 +FAX_DATA_BLOCK = 13 + +SUCCESS = 0 +FAILURE = 1 + +FAX_DATA_BLOCK_SIZE = 4096 + +# Fax data variant header TTI header control +TTI_NONE = 0 +TTI_PREPENDED_TO_IMAGE = 1 +TTI_OVERLAYED_ON_IMAGE = 2 + +# **************************************************************************** # +class MarvellFaxDevice(FaxDevice): + + def __init__(self, device_uri=None, printer_name=None, + callback=None, + fax_type=FAX_TYPE_NONE, + disable_dbus=False): + + FaxDevice.__init__(self, device_uri, + printer_name, + callback, fax_type, + disable_dbus) + + self.send_fax_thread = None + self.upload_log_thread = None + + try: + sendfax_path = utils.which('hp-sendfax') + sendfax_a_path = os.readlink(sendfax_path+"/hp-sendfax") + if not os.path.isabs(sendfax_a_path): + sendfax_f_path = os.path.join(sendfax_path, sendfax_a_path) + else: + sendfax_f_path = sendfax_a_path + + sendfax_abs_path = os.path.realpath(sendfax_f_path) + (head, tail) = os.path.split(sendfax_abs_path) + + lib_name = head+"/fax/plugins/fax_marvell.so" + log.debug("Load the library %s\n" % lib_name) + if not os.path.exists(lib_name): + log.error("Loading %s failed. Try after installing plugin libraries\n" %lib_name); + log.info("Run \"hp-plugin\" to installa plugin libraries if you are not automatically prompted\n") + job_id =0; + self.service.SendEvent(device_uri, printer_name, EVENT_FAX_FAILED_MISSING_PLUGIN, os.getenv('USER'), job_id, "Plugin is not installed") + sys.exit(1) + else: + self.libfax_marvell = cdll.LoadLibrary(lib_name) + except Error, e: + log.error("Loading fax_marvell failed (%s)\n" % e.msg); + sys.exit(1) + + + # Creates a message packet for message type given in argument, and sends it to device + # + # 1. Gets the message packet using fax_marvell.so + # 2. Writes the packets to device + # 3. Returns the result of send operation + def send_packet_for_message(self, msg_type, param1=0, param2=0, status=0, data_len=0): + int_array_8 = c_int * 8 + i_buf = int_array_8(0, 0, 0, 0, 0, 0, 0, 0) + + result = self.libfax_marvell.create_packet(msg_type, param1, param2, status, data_len, byref(i_buf)) + buf = buffer(i_buf) + log.log_data(buf, 32) + self.writeMarvellFax(buf) +# self.closeMarvellFax() + + return result + + + # Reads response message packet from the device for message type given in argument. + # Reads the response from device, and sends the data read to the caller of this method + # No Marvell specific code or info + def read_response_for_message(self, msg_type): + ret_buf = cStringIO.StringIO() + while self.readMarvellFax(32, ret_buf, timeout=10): + pass + + ret_buf = ret_buf.getvalue() + #self.closeMarvellFax() + + log.debug("response_for_message (%d): response packet is\n" % msg_type) + log.log_data(ret_buf, 32) + + return ret_buf + + + def setPhoneNum(self, num): + log.debug("************************* setPhoneNum (%s) START **************************" % num) + + set_buf = cStringIO.StringIO() + + int_array = c_int * 8 + i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0) + + char_array = c_char * 308 + c_buf = char_array() + + date_array = c_char * 15 + date_buf = date_array() + t = time.localtime() + date_buf = "%4d%02d%02d%02d%02d%02d" % (t[0], t[1], t[2], t[3], t[4], t[5]) + log.debug("Date and Time string is ==>") + log.debug(date_buf) + + result = self.libfax_marvell.create_packet(SET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf)) + result = self.libfax_marvell.create_fax_settings_packet(self.station_name, str(num), date_buf, byref(c_buf)) + + msg_buf = buffer(i_buf) + msg_c_buf = buffer(c_buf) + + for i in range(0, 32): + set_buf.write(msg_buf[i]) + for i in range(0, 308): + set_buf.write(msg_c_buf[i]) + + set_buf = set_buf.getvalue() + log.debug("setPhoneNum: send SET_FAX_SETTINGS message and data ===> ") + log.log_data(set_buf, 340) + + self.writeMarvellFax(set_buf) + ret_buf = cStringIO.StringIO() + while self.readMarvellFax(32, ret_buf, timeout=10): + pass + ret_buf = ret_buf.getvalue() + self.closeMarvellFax() + + response = self.libfax_marvell.extract_response(ret_buf) + log.debug("setPhoneNum: response is %d" % response) + + log.debug("************************* setPhoneNum END **************************") + return response + + + def getPhoneNum(self): + int_array_8 = c_int * 8 + i_buf = int_array_8(0, 0, 0, 0, 0, 0, 0, 0) + ph_buf = int_array_8(0, 0, 0, 0, 0, 0, 0, 0) + + log.debug("******************** getPhoneNum START **********************") + + result = self.libfax_marvell.create_packet(GET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf)) + + buf = buffer(i_buf) + self.writeMarvellFax(buf) + #self.closeMarvellFax() + ret_buf = cStringIO.StringIO() + while self.readMarvellFax(512, ret_buf, timeout=10): + pass + ret_buf = ret_buf.getvalue() + self.closeMarvellFax() + + response = self.libfax_marvell.extract_response(ret_buf) + log.debug("create_packet: response is %d" % response) + + response = self.libfax_marvell.extract_phone_number(ret_buf, ph_buf) + ph_num_buf = cStringIO.StringIO() + for i in range(0, 7): + if ph_buf[i]: + ph_num_buf.write(str(ph_buf[i])) + + ph_num_buf = ph_num_buf.getvalue() + log.debug("getPhoneNum: ph_num_buf=%s " % (ph_num_buf)) + + log.debug("******************** getPhoneNum END **********************") + return ph_num_buf + + + # Note down the fax (phone) number + phone_num = property(getPhoneNum, setPhoneNum) + + + # Set the station name in the device's settings + # + def setStationName(self, name): + log.debug("************************* setStationName(%s) START **************************" % name) + + int_array = c_int * 8 + i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0) + set_buf = cStringIO.StringIO() + + char_array = c_char * 308 + c_buf = char_array() + + date_array = c_char * 15 + date_buf = date_array() + t = time.localtime() + date_buf = "%4d%02d%02d%02d%02d%02d" % (t[0], t[1], t[2], t[3], t[4], t[5]) + log.debug("Date and Time string is ==>") + log.debug(date_buf) + + result = self.libfax_marvell.create_packet(SET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf)) + result = self.libfax_marvell.create_fax_settings_packet(str(name), self.phone_num, date_buf, byref(c_buf)) + + msg_buf = buffer(i_buf) + msg_c_buf = buffer(c_buf) + + for i in range(0, 32): + set_buf.write(msg_buf[i]) + for i in range(0, 308): + set_buf.write(msg_c_buf[i]) + set_buf = set_buf.getvalue() + log.debug("setStationName: SET_FAX_SETTINGS message and data ===> ") + log.log_data(set_buf, 340) + + self.writeMarvellFax(set_buf) + ret_buf = cStringIO.StringIO() + while self.readMarvellFax(32, ret_buf, timeout=10): + pass + ret_buf = ret_buf.getvalue() + self.closeMarvellFax() + + response = self.libfax_marvell.extract_response(ret_buf) + log.debug("setStationName: response is %d" % response) + + log.debug("************************* setStationName END **************************") + return response + + + def getStationName(self): + int_array = c_int * 8 + i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0) + st_buf = create_string_buffer(128) + + log.debug("************************* getStationName START **************************") + + result = self.libfax_marvell.create_packet(GET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf)) + + buf = buffer(i_buf) + self.writeMarvellFax(buf) + #self.closeMarvellFax() + + ret_buf = cStringIO.StringIO() + while self.readMarvellFax(512, ret_buf, timeout=10): + pass + + ret_buf = ret_buf.getvalue() + self.closeMarvellFax() + + response = self.libfax_marvell.extract_response(ret_buf) + log.debug("getStationName: response is %d" % response) + + result = self.libfax_marvell.extract_station_name(ret_buf, st_buf) + log.debug("getStationName: station_name=%s ; result is %d" % (st_buf.value, result)) + + log.debug("************************* getStationName END **************************") + return st_buf.value + + + # Note down the station-name + station_name = property(getStationName, setStationName) + + + # Set date and time in the device's settings + # + # 1. Gets the message packet and fax_settings packet using fax_marvell.so + # 2. Writes the packets to the device; Reads response from the device + # 3. Extracts the status from the device's response + def setDateAndTime(self): + int_array = c_int * 8 + i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0) + + log.debug("************************* setDateAndTime START **************************") + + c_buf = create_string_buffer(308) + set_buf = cStringIO.StringIO() + ret_buf = cStringIO.StringIO() + date_array = c_char * 15 + date_buf = date_array() + + t = time.localtime() + + date_buf = "%4d%02d%02d%02d%02d%02d" % (t[0], t[1], t[2], t[3], t[4], t[5]) + log.debug("Date and Time string is ==>") + log.debug(date_buf) + + result = self.libfax_marvell.create_packet(SET_FAX_SETTINGS, 0, 0, 0, 0, byref(i_buf)) + result = create_marvell_faxsettings_pkt(self.phone_num, self.station_name, date_buf, c_buf) + + msg_buf = buffer(i_buf) + for i in range(0, 31): + set_buf.write(msg_buf[i]) + + set_buf.write(c_buf.raw) + set_buf = set_buf.getvalue() + self.dev.writeMarvellFax(set_buf) + while self.dev.readMarvellFax(32, ret_buf, timeout=5): + pass + ret_buf = ret_buf.getvalue() + self.closeMarvellFax() + + response = self.libfax_marvell.extract_response(ret_buf) + log.debug("setDateAndTime: response is %d" % response) + + return response + + + # Get the state of the device + # + # 1. Gets the message packet using fax_marvell.so + # 2. Writes the packet to the device; Reads response from the device + # 3. Extracts the response status and device status from the device's response + def getFaxDeviceState(self): + log.debug("************************* getFaxDeviceState: START **************************") + + int_array = c_int * 8 + i_buf = int_array(0, 0, 0, 0, 0, 0, 0, 0) + param1 = c_int(0) + + result = self.libfax_marvell.create_packet(REQUEST_FAX_STATUS, 0, 0, 0, 0, byref(i_buf)) + buf = buffer(i_buf) + self.writeMarvellFax(buf) + + ret_buf = cStringIO.StringIO() + while self.readMarvellFax(32, ret_buf, timeout=5): + pass + ret_buf = ret_buf.getvalue() + self.closeMarvellFax() + + response = self.libfax_marvell.extract_response(ret_buf) + log.debug("getFaxDeviceState: response is %d" % response) + + return response + + + # Creates a thread which does actual Fax submission the state of the device + # + def sendFaxes(self, phone_num_list, fax_file_list, cover_message='', cover_re='', + cover_func=None, preserve_formatting=False, printer_name='', + update_queue=None, event_queue=None): + + if not self.isSendFaxActive(): + + self.send_fax_thread = MarvellFaxSendThread(self, self.service, phone_num_list, fax_file_list, + cover_message, cover_re, cover_func, + preserve_formatting, + printer_name, update_queue, + event_queue) + + self.send_fax_thread.start() + return True + else: + return False + + + +# **************************************************************************** # +# Does the actual Fax transmission +# **************************************************************************** # +class MarvellFaxSendThread(FaxSendThread): + def __init__(self, dev, service, phone_num_list, fax_file_list, + cover_message='', cover_re='', cover_func=None, preserve_formatting=False, + printer_name='', update_queue=None, event_queue=None): + + FaxSendThread.__init__(self, dev, service, phone_num_list, fax_file_list, + cover_message, cover_re, cover_func, preserve_formatting, + printer_name, update_queue, event_queue) + + + def run(self): + + STATE_DONE = 0 + STATE_ABORTED = 10 + STATE_SUCCESS = 20 + STATE_BUSY = 25 + STATE_READ_SENDER_INFO = 30 + STATE_PRERENDER = 40 + STATE_COUNT_PAGES = 50 + STATE_NEXT_RECIPIENT = 60 + STATE_COVER_PAGE = 70 + STATE_SINGLE_FILE = 80 + STATE_MERGE_FILES = 90 + STATE_SINGLE_FILE = 100 + STATE_SEND_FAX = 110 + STATE_CLEANUP = 120 + STATE_ERROR = 130 + + next_recipient = self.next_recipient_gen() + + rec_name = None + rec_num = None + + state = STATE_READ_SENDER_INFO + self.rendered_file_list = [] + + while state != STATE_DONE: # --------------------------------- Fax state machine + if self.check_for_cancel(): + log.debug("***** Job is Cancelled.") + state = STATE_ABORTED + + log.debug("*************** STATE=(%d, 0, 0)" % state) + + if state == STATE_ABORTED: # --------------------------------- Aborted + log.error("Aborted by user.") + self.write_queue((STATUS_IDLE, 0, '')) + state = STATE_CLEANUP + + + elif state == STATE_SUCCESS: # --------------------------------- Success + log.debug("Success.") + self.write_queue((STATUS_COMPLETED, 0, '')) + state = STATE_CLEANUP + + + elif state == STATE_ERROR: # --------------------------------- Error + log.error("Error, aborting.") + self.write_queue((STATUS_ERROR, 0, '')) + state = STATE_CLEANUP + + + elif state == STATE_BUSY: # --------------------------------- Busy + log.error("Device busy, aborting.") + self.write_queue((STATUS_BUSY, 0, '')) + state = STATE_CLEANUP + + + elif state == STATE_READ_SENDER_INFO: # --------------------------------- Get sender info + log.debug("%s State: Get sender info" % ("*"*20)) + state = STATE_PRERENDER + try: + try: + self.dev.open() + except Error, e: + log.error("Unable to open device (%s)." % e.msg) + state = STATE_ERROR + else: + try: + self.sender_name = self.dev.station_name + self.sender_fax = self.dev.phone_num + except Error: + log.error("Getting station-name and phone_num failed!") + state = STATE_ERROR + + finally: + self.dev.close() + + + elif state == STATE_PRERENDER: # --------------------------------- Pre-render non-G3 files + log.debug("%s State: Pre-render non-G3 files" % ("*"*20)) + state = self.pre_render(STATE_COUNT_PAGES) + + + elif state == STATE_COUNT_PAGES: # --------------------------------- Get total page count + log.debug("%s State: Get total page count" % ("*"*20)) + state = self.count_pages(STATE_NEXT_RECIPIENT) + + + elif state == STATE_NEXT_RECIPIENT: # --------------------------------- Loop for multiple recipients + log.debug("%s State: Next recipient" % ("*"*20)) + state = STATE_COVER_PAGE + + try: + recipient = next_recipient.next() + + self.write_queue((STATUS_SENDING_TO_RECIPIENT, 0, recipient['name'])) + + rec_name = recipient['name'] + rec_num = recipient['fax'].encode('ascii') + log.debug("recipient is %s num is %s" % (rec_name, rec_num)) + + except StopIteration: + state = STATE_SUCCESS + log.debug("Last recipient.") + continue + + self.recipient_file_list = self.rendered_file_list[:] + + + elif state == STATE_COVER_PAGE: # --------------------------------- Create cover page + log.debug("%s State: Render cover page" % ("*"*20)) + state = self.cover_page(recipient) + + + elif state == STATE_SINGLE_FILE: # --------------------------------- Special case for single file (no merge) + log.debug("%s State: Handle single file" % ("*"*20)) + state = self.single_file(STATE_SEND_FAX) + + elif state == STATE_MERGE_FILES: # --------------------------------- Merge multiple G3 files + log.debug("%s State: Merge multiple files" % ("*"*20)) + log.debug("Not merging the files for Marvell support") + state = STATE_SEND_FAX + + elif state == STATE_SEND_FAX: # --------------------------------- Send fax state machine + log.debug("%s State: Send fax" % ("*"*20)) + state = STATE_NEXT_RECIPIENT + + next_file = self.next_file_gen() + + FAX_SEND_STATE_DONE = 0 + FAX_SEND_STATE_SUCCESS = 10 + FAX_SEND_STATE_ABORT = 21 + FAX_SEND_STATE_ERROR = 22 + FAX_SEND_STATE_BUSY = 25 + FAX_SEND_STATE_DEVICE_OPEN = 30 + FAX_SEND_STATE_NEXT_FILE = 35 + FAX_SEND_STATE_CHECK_IDLE = 40 + FAX_SEND_STATE_START_JOB_REQUEST = 50 + FAX_SEND_STATE_SEND_JOB_REQUEST = 60 + FAX_SEND_STATE_SET_PARAMS = 70 + FAX_SEND_STATE_SEND_FAX_HEADER = 80 + FAX_SEND_STATE_SEND_FILE_DATA = 90 + FAX_SEND_STATE_END_FILE_DATA = 100 + FAX_SEND_STATE_END_JOB_REQUEST = 110 + FAX_SEND_STATE_GET_LOG_INFORMATION = 120 + + monitor_state = False + current_state = SUCCESS + fax_send_state = FAX_SEND_STATE_DEVICE_OPEN + + while fax_send_state != FAX_SEND_STATE_DONE: + + if self.check_for_cancel(): + log.error("Fax send aborted.") + fax_send_state = FAX_SEND_STATE_ABORT + + if monitor_state: + fax_state = self.getFaxDeviceState() + if fax_state != SUCCESS: + log.error("Device is in error state=%d" % fax_state) + fax_send_state = FAX_SEND_STATE_ERROR + state = STATE_ERROR + + + log.debug("********* FAX_SEND_STATE=(%d, %d, %d)" % (STATE_SEND_FAX, fax_send_state, current_state)) + + if fax_send_state == FAX_SEND_STATE_ABORT: # -------------- Abort + monitor_state = False + fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST + state = STATE_ABORTED + + elif fax_send_state == FAX_SEND_STATE_ERROR: # -------------- Error + log.error("Fax send error.") + monitor_state = False + + fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST + state = STATE_ERROR + + elif fax_send_state == FAX_SEND_STATE_BUSY: # -------------- Busy + log.error("Fax device busy.") + monitor_state = False + fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST + state = STATE_BUSY + + elif fax_send_state == FAX_SEND_STATE_SUCCESS: # -------------- Success + log.debug("Fax send success.") + monitor_state = False + fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST + state = STATE_NEXT_RECIPIENT + + elif fax_send_state == FAX_SEND_STATE_DEVICE_OPEN: # -------------- Device open + log.debug("%s State: Open device" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_NEXT_FILE + try: + self.dev.open() + except Error, e: + log.error("Unable to open device (%s)." % e.msg) + fax_send_state = FAX_SEND_STATE_ERROR + else: + if self.dev.device_state == DEVICE_STATE_NOT_FOUND: + fax_send_state = FAX_SEND_STATE_ERROR + + + elif fax_send_state == FAX_SEND_STATE_NEXT_FILE: # -------------- Device open + log.debug("%s State: Open device" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_CHECK_IDLE + try: + fax_file = next_file.next() + self.f = fax_file[0] + log.debug("***** file name is : %s..." % self.f) + except StopIteration: + log.debug("file(s) are sent to the device" ) + fax_send_state = FAX_SEND_STATE_DONE + + + elif fax_send_state == FAX_SEND_STATE_CHECK_IDLE: # -------------- Check for initial idle + log.debug("%s State: Check idle" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_START_JOB_REQUEST + + try: + ff = file(self.f, 'r') + except IOError: + log.error("Unable to read fax file.") + fax_send_state = FAX_SEND_STATE_ERROR + continue + + try: + header = ff.read(FILE_HEADER_SIZE) + except IOError: + log.error("Unable to read fax file.") + fax_send_state = FAX_SEND_STATE_ERROR + continue + + magic, version, total_pages, hort_dpi, vert_dpi, page_size, \ + resolution, encoding, reserved1, reserved2 = self.decode_fax_header(header) + + if magic != 'hplip_g3': + log.error("Invalid file header. Bad magic.") + fax_send_state = FAX_SEND_STATE_ERROR + else: + log.debug("Magic=%s Version=%d Total Pages=%d hDPI=%d vDPI=%d Size=%d Resolution=%d Encoding=%d" + % (magic, version, total_pages, hort_dpi, vert_dpi, page_size, resolution, encoding)) + + dev_state = self.dev.getFaxDeviceState() + + if (dev_state == 0): + log.debug("State: device status is zero ") + else: + log.debug("State: device status is non-zero ") + fax_send_state = FAX_SEND_STATE_BUSY + + + elif fax_send_state == FAX_SEND_STATE_START_JOB_REQUEST: # -------------- Request fax start + log.debug("%s State: Request start" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_SEND_JOB_REQUEST + + file_len = os.stat(self.f)[ST_SIZE] + tx_data_len = file_len - FILE_HEADER_SIZE - (PAGE_HEADER_SIZE*total_pages) + log.debug("#### file_len = %d" % file_len) + log.debug("#### tx_data_len = %d" % tx_data_len) + ret_value = self.dev.send_packet_for_message(START_FAX_JOB, tx_data_len, 0, 0, 0) + if ret_value: + log.debug("Sending start fax request failed with %d" % ret_value) + fax_send_state = FAX_SEND_STATE_ERROR + else: + log.debug("Successfully sent start fax request") + ret_buf = self.dev.read_response_for_message(START_FAX_JOB) + dev_response = self.dev.libfax_marvell.extract_response(ret_buf) + if dev_response: + log.debug("start-fax request failed with %d" % dev_response) + fax_send_state = FAX_SEND_STATE_ERROR + else: + log.debug("start-fax request is successful") + + elif fax_send_state == FAX_SEND_STATE_SEND_JOB_REQUEST: # -------------- Set data request + log.debug("%s State: Send data request" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_SET_PARAMS + + ret_value = self.dev.send_packet_for_message(SEND_FAX_JOB) + if ret_value: + log.debug("Sending send-data request failed with %d" % ret_value) + fax_send_state = FAX_SEND_STATE_ERROR + else: + log.debug("Successfully sent send-fax request") + + + elif fax_send_state == FAX_SEND_STATE_SET_PARAMS: # -------------- Set fax send params + log.debug("%s State: Set params" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_SEND_FAX_HEADER + + c_buf = create_string_buffer(68) + set_buf = cStringIO.StringIO() + + no_data = None + ret_val = self.dev.libfax_marvell.create_job_settings_packet(no_data, rec_num, c_buf) + set_buf.write(c_buf.raw) + set_buf = set_buf.getvalue() + + self.dev.writeMarvellFax(set_buf) + #self.dev.closeMarvellFax() + + + elif fax_send_state == FAX_SEND_STATE_SEND_FAX_HEADER: # -------------- Fax header + # Taken care by the device + fax_send_state = FAX_SEND_STATE_SEND_FILE_DATA + + elif fax_send_state == FAX_SEND_STATE_SEND_FILE_DATA: # --------------------------------- Send fax pages state machine + log.debug("%s State: Send pages" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_END_FILE_DATA + current_state = SUCCESS + page = StringIO() + + file_len = os.stat(self.f)[ST_SIZE] + bytes_to_read = file_len - FILE_HEADER_SIZE - (PAGE_HEADER_SIZE*total_pages) + + for p in range(total_pages): + + if self.check_for_cancel(): + current_state = FAILURE + + if current_state == FAILURE: + break + + try: + header = ff.read(PAGE_HEADER_SIZE) + except IOError: + log.error("Unable to read fax file.") + current_state = FAILURE + continue + + page_num, ppr, rpp, b_to_read, thumbnail_bytes, reserved2 = \ + self.decode_page_header(header) + + log.debug("Page=%d PPR=%d RPP=%d BPP=%d Thumb=%d" % + (page_num, ppr, rpp, b_to_read, thumbnail_bytes)) + + page.write(ff.read(b_to_read)) + thumbnail = ff.read(thumbnail_bytes) # thrown away for now (should be 0 read) + page.seek(0) + bytes_to_write = b_to_read + total_read = 0 + while (bytes_to_write > 0): + try: + data = page.read(FAX_DATA_BLOCK_SIZE) + except IOError: + log.error("Unable to read fax file.") + current_state = FAILURE + continue + + if data == '': + log.error("No data!") + current_state = FAILURE + break + + if self.check_for_cancel(): + current_state = FAILURE + log.error("Job is cancelled. Aborting...") + break + + total_read += FAX_DATA_BLOCK_SIZE + + try: + ret_value = self.dev.send_packet_for_message(FAX_DATA_BLOCK, 0, 0, 0, len(data)) + if ret_value: + log.debug("Sending fax-data-block request failed with %d" % ret_value) + current_state = FAILURE + else: + log.debug("Successfully sent fax-data-block request") + + self.dev.writeMarvellFax(data) + #self.dev.closeMarvellFax() + except Error: + log.error("Channel write error.") + current_state = FAILURE + break + + bytes_to_write = bytes_to_write - FAX_DATA_BLOCK_SIZE + + page.truncate(0) + page.seek(0) + + + elif fax_send_state == FAX_SEND_STATE_END_FILE_DATA: # -------------- end-of-data + log.debug("%s State: Send end-of-file-data request" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_END_JOB_REQUEST + + ret_value = self.dev.send_packet_for_message(FAX_DATA_BLOCK, 0, 0, current_state, 0) + if ret_value: + log.debug("Sending fax-data-block packet failed with %d" % ret_value) + current_state = FAILURE + else: + log.debug("Successfully sent fax-data-block request") + ret_buf = self.dev.read_response_for_message(SEND_FAX_JOB) + dev_response = self.dev.libfax_marvell.extract_response(ret_buf) + if dev_response: + log.debug("send-fax request failed with %d" % dev_response) + current_state = FAILURE + else: + log.debug("send-fax request is successful") + + if current_state: + log.debug("Exiting...") + sys.exit(1) + + + elif fax_send_state == FAX_SEND_STATE_END_JOB_REQUEST: # -------------- Wait for complete + log.debug("%s State: End the job" % ("*"*20)) + fax_send_state = FAX_SEND_STATE_NEXT_FILE + + ret_value = self.dev.send_packet_for_message(END_FAX_JOB, 0, 0, current_state, 0) + if ret_value: + log.debug("Sending end-fax-job packet failed with %d" % ret_value) + current_state = FAILURE + else: + log.debug("Successfully sent end-fax-job request") + ret_buf = self.dev.read_response_for_message(END_FAX_JOB) + dev_response = self.dev.libfax_marvell.extract_response(ret_buf) + if dev_response: + log.debug("end-fax-job request failed with %d" % dev_response) + current_state = FAILURE + else: + log.debug("end-fax-job request is successful") + + if current_state != SUCCESS: + # There was an error during transmission... + log.error("An error occurred! setting fax_send_state to DONE") + fax_send_state = FAX_SEND_STATE_DONE + + try: + ff.close() + except NameError: + pass + + time.sleep(1) + + self.dev.close() + + + elif state == STATE_CLEANUP: # --------------------------------- Cleanup + log.debug("%s State: Cleanup" % ("*"*20)) + + if self.remove_temp_file: + log.debug("Removing merged file: %s" % self.f) + try: + os.remove(self.f) + log.debug("Removed") + except OSError: + log.debug("Not found") + + state = STATE_DONE + + |