2 # -*- coding: utf-8 -*-
4 # (c) Copyright 2003-2008 Hewlett-Packard Development Company, L.P.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 __title__ = "Services and Status System Tray Device I/O Child Process"
26 __doc__ = "Provides device I/O process isolation for system tray application."
36 from cPickle import dumps, HIGHEST_PROTOCOL
40 from base.codes import *
41 from base import utils, device, status, models
45 from dbus import lowlevel, SessionBus
47 log.error("dbus failed to load (python-dbus ver. 0.80+ required). Exiting...")
54 devices = {} # { 'device_uri' : device.Device(), ... }
57 def send_message(device_uri, event_code, bytes_written=0):
58 args = [device_uri, '', event_code, prop.username, 0, '', '', bytes_written]
59 msg = lowlevel.SignalMessage('/', 'com.hplip.StatusService', 'Event')
60 msg.append(signature='ssisissi', *args)
61 SessionBus().send_message(msg)
64 def run(read_pipe2=None, # pipe from hpssd
65 write_pipe3=None): # pipe to hpssd
72 log.set_module("hp-systray(hpdio)")
73 log.debug("PID=%d" % os.getpid())
75 r2, w3 = read_pipe2, write_pipe3
77 fmt = "80s80sI32sI80sf" # TODO: Move to Event class
78 fmt_size = struct.calcsize(fmt)
85 r, w, e = select.select([r2], [], [r2], 1.0)
86 except KeyboardInterrupt:
88 except select.error, e:
89 if e[0] == errno.EINTR:
97 m = ''.join([m, os.read(r2, fmt_size)])
102 while len(m) >= fmt_size:
104 event = device.Event(*struct.unpack(fmt, m[:fmt_size]))
107 action = event.event_code
108 device_uri = event.device_uri
110 log.debug("Handling event...")
113 send_message(device_uri, EVENT_DEVICE_UPDATE_ACTIVE)
115 if action in (EVENT_DEVICE_UPDATE_REQUESTED, EVENT_POLLING_REQUEST):
118 #log.debug("%s starting for %s" % (ACTION_NAMES[action], device_uri))
121 dev = devices[device_uri]
123 dev = devices[device_uri] = device.Device(device_uri, disable_dbus=True)
126 #print "Device.open()"
130 response = {'error-state': ERROR_STATE_ERROR,
131 'device-state': DEVICE_STATE_NOT_FOUND,
132 'status-code' : EVENT_ERROR_DEVICE_IO_ERROR}
134 if dev.device_state == DEVICE_STATE_NOT_FOUND:
135 dev.error_state = ERROR_STATE_ERROR
137 if action == EVENT_DEVICE_UPDATE_REQUESTED:
139 #print "Device.queryDevice()"
143 log.error("Query device error (%s)." % e.msg)
144 dev.error_state = ERROR_STATE_ERROR
145 dev.status_code = EVENT_ERROR_DEVICE_IO_ERROR
150 log.debug("Device state = %d" % dev.device_state)
151 log.debug("Status code = %d" % dev.status_code)
152 log.debug("Error state = %d" % dev.error_state)
154 else: # EVENT_POLLING_REQUEST
159 log.error("Poll device error (%s)." % e.msg)
160 dev.error_state = ERROR_STATE_ERROR
163 response = {'test' : 1}
170 #thread_activity_lock.release()
172 elif action == EVENT_USER_CONFIGURATION_CHANGED:
175 elif action == EVENT_SYSTEMTRAY_EXIT:
179 send_message(device_uri, EVENT_DEVICE_UPDATE_INACTIVE)
181 if action == EVENT_DEVICE_UPDATE_REQUESTED:
183 data = dumps(response, HIGHEST_PROTOCOL)
185 log.debug("Sending data through pipe to hpssd...")
188 total_written += os.write(w3, data[:PIPE_BUF])
189 data = data[PIPE_BUF:]
193 log.debug("Wrote %d bytes" % total_written)
195 send_message(device_uri, EVENT_DEVICE_UPDATE_REPLY, total_written)
197 elif action == EVENT_POLLING_REQUEST:
198 # TODO: Translate into event: scan requested, copy requested, etc.. send as event
204 except KeyboardInterrupt:
205 log.debug("Ctrl-C: Exiting...")