Replace 'tap' to 'spaces' to make gbs build succeed
[platform/upstream/hplip.git] / hpdio.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # (c) Copyright 2003-2008 Hewlett-Packard Development Company, L.P.
5 #
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.
10 #
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.
15 #
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
19 #
20 # Author: Don Welch
21 #
22
23 __version__ = '0.1'
24 __title__ = "Services and Status System Tray Device I/O Child Process"
25 __mod__ = 'hpdio'
26 __doc__ = "Provides device I/O process isolation for system tray application."
27
28
29 # StdLib
30 import sys
31 import struct
32 import os
33 import time
34 import Queue
35 import select
36 from cPickle import dumps, HIGHEST_PROTOCOL
37
38 # Local
39 from base.g import *
40 from base.codes import *
41 from base import utils, device, status, models
42
43 # dBus
44 try:
45     from dbus import lowlevel, SessionBus
46 except ImportError:
47     log.error("dbus failed to load (python-dbus ver. 0.80+ required). Exiting...")
48     sys.exit(1)
49
50 # Globals
51 PIPE_BUF = 4096
52 session_bus = None
53 r2, w3 = None, None
54 devices = {} # { 'device_uri' : device.Device(), ... }
55
56
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)
62
63
64 def run(read_pipe2=None,  # pipe from hpssd
65         write_pipe3=None): # pipe to hpssd
66
67     global r2, w3
68     tmp_dir = '/tmp'
69     os.umask(0111)
70
71     try:
72         log.set_module("hp-systray(hpdio)")
73         log.debug("PID=%d" % os.getpid())
74
75         r2, w3 = read_pipe2, write_pipe3
76
77         fmt = "80s80sI32sI80sf" # TODO: Move to Event class
78         fmt_size = struct.calcsize(fmt)
79
80         response = {}
81         dev = None
82         m = ''
83         while True:
84             try:
85                 r, w, e = select.select([r2], [], [r2], 1.0)
86             except KeyboardInterrupt:
87                 break
88             except select.error, e:
89                 if e[0] == errno.EINTR:
90                     continue
91                 else:
92                     break
93
94             if not r: continue
95             if e: break
96
97             m = ''.join([m, os.read(r2, fmt_size)])
98
99             if not m:
100                 break
101
102             while len(m) >= fmt_size:
103                 response.clear()
104                 event = device.Event(*struct.unpack(fmt, m[:fmt_size]))
105                 m = m[fmt_size:]
106
107                 action = event.event_code
108                 device_uri = event.device_uri
109
110                 log.debug("Handling event...")
111                 event.debug()
112
113                 send_message(device_uri, EVENT_DEVICE_UPDATE_ACTIVE)
114
115                 if action in (EVENT_DEVICE_UPDATE_REQUESTED, EVENT_POLLING_REQUEST):
116                     #try:
117                     if 1:
118                         #log.debug("%s starting for %s" % (ACTION_NAMES[action], device_uri))
119
120                         try:
121                             dev = devices[device_uri]
122                         except KeyError:
123                             dev = devices[device_uri] = device.Device(device_uri, disable_dbus=True)
124
125                         try:
126                             #print "Device.open()"
127                             dev.open()
128                         except Error, e:
129                             log.error(e.msg)
130                             response = {'error-state': ERROR_STATE_ERROR,
131                                         'device-state': DEVICE_STATE_NOT_FOUND,
132                                         'status-code' : EVENT_ERROR_DEVICE_IO_ERROR}
133
134                         if dev.device_state == DEVICE_STATE_NOT_FOUND:
135                             dev.error_state = ERROR_STATE_ERROR
136                         else:
137                             if action == EVENT_DEVICE_UPDATE_REQUESTED:
138                                 try:
139                                     #print "Device.queryDevice()"
140                                     dev.queryDevice()
141
142                                 except Error, e:
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
146
147                                 response = dev.dq
148                                 #print response
149
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)
153
154                             else: # EVENT_POLLING_REQUEST
155                                 try:
156                                     dev.pollDevice()
157
158                                 except Error, e:
159                                     log.error("Poll device error (%s)." % e.msg)
160                                     dev.error_state = ERROR_STATE_ERROR
161
162                                 else:
163                                     response = {'test' : 1}
164
165                     #finally:
166                     if 1:
167                         if dev is not None:
168                             dev.close()
169
170                     #thread_activity_lock.release()
171
172                 elif action == EVENT_USER_CONFIGURATION_CHANGED:
173                     pass
174
175                 elif action == EVENT_SYSTEMTRAY_EXIT:
176                     log.debug("Exiting")
177                     sys.exit(1)
178
179                 send_message(device_uri, EVENT_DEVICE_UPDATE_INACTIVE)
180
181                 if action == EVENT_DEVICE_UPDATE_REQUESTED:
182                     #print response
183                     data = dumps(response, HIGHEST_PROTOCOL)
184
185                     log.debug("Sending data through pipe to hpssd...")
186                     total_written = 0
187                     while True:
188                         total_written += os.write(w3, data[:PIPE_BUF])
189                         data = data[PIPE_BUF:]
190                         if not data:
191                             break
192
193                     log.debug("Wrote %d bytes" % total_written)
194
195                     send_message(device_uri, EVENT_DEVICE_UPDATE_REPLY, total_written)
196
197                 elif action == EVENT_POLLING_REQUEST:
198                     # TODO: Translate into event: scan requested, copy requested, etc.. send as event
199                     #try:
200                     #    os.write
201                     pass
202
203
204     except KeyboardInterrupt:
205         log.debug("Ctrl-C: Exiting...")