Package sparked :: Package hardware :: Module hal
[hide private]
[frames] | no frames]

Source Code for Module sparked.hardware.hal

  1  # Copyright (c) 2010 Arjan Scherpenisse 
  2  # See LICENSE for details. 
  3   
  4  """ 
  5  Hardware monitoring classes based on linux' HAL system. 
  6  """ 
  7   
  8  import os 
  9  import dbus 
 10  import glob 
 11   
 12  from twisted.application import service 
 13  from twisted.internet import reactor 
 14   
 15   
 16  DBUS_INTERFACE = "org.freedesktop.DBus" 
 17  HAL_INTERFACE = 'org.freedesktop.Hal' 
 18  HAL_DEVICE_INTERFACE = 'org.freedesktop.Hal.Device' 
 19  HAL_MANAGER_INTERFACE = 'org.freedesktop.Hal.Manager' 
 20  HAL_MANAGER_UDI = '/org/freedesktop/Hal/Manager' 
 21   
 22  # The following properties get automatically read upon device insertion. 
 23  # See http://people.freedesktop.org/~dkukawka/hal-spec-git/hal-spec.html 
 24  # 
 25  HAL_SUBSYSTEM_PROPERTIES = { 
 26      'serial': ['originating_device', 'device', 'port', 'type'], 
 27      'video4linux': ['device', 'version'], 
 28      'input': ['device'] 
 29      } 
 30   
 31   
32 -class HardwareMonitor (service.Service):
33 """ 34 A generic hardware monitor class based on HAL. Listens for device add/remove filtered on a specific subsystem. 35 36 @ivar subsystem: The HAL subsystem type to monitor. E.g. serial, video4linux, ... 37 @ivar deviceInfo: dict which will be filled with device information. Key is the HAL UDI (Unique Device Identifier). 38 @ivar uniquePath: If set, point to a directory where the symlinks to the unique devices will be made, e.g. /dev/serial/by-id/ 39 @ivar events: If set, point to a L{sparked.events.EventDispatcher} to dispatch <subsystem>-{added,removed} events to. 40 """ 41 42 subsystem = None 43 deviceInfo = None 44 uniquePath = None 45 events = None 46 47
48 - def startService(self):
49 self.deviceInfo = {} 50 self.bus = dbus.SystemBus() 51 self.bus.add_signal_receiver(self._halDeviceAdded, 52 dbus_interface=HAL_MANAGER_INTERFACE, 53 signal_name='DeviceAdded') 54 self.bus.add_signal_receiver(self._halDeviceRemoved, 55 dbus_interface=HAL_MANAGER_INTERFACE, 56 signal_name='DeviceRemoved') 57 58 self.manager = self._getHalInterface(HAL_MANAGER_UDI, HAL_MANAGER_INTERFACE) 59 60 for udi in self.manager.FindDeviceByCapability(self.subsystem): 61 reactor.callLater(0, self._halDeviceAdded, udi)
62 63
64 - def stopService(self):
65 udis = self.deviceInfo.keys() 66 for udi in udis: 67 self._halDeviceRemoved(udi)
68 69
70 - def _getHalInterface(self, udi, interface=HAL_DEVICE_INTERFACE):
71 obj = self.bus.get_object(HAL_INTERFACE, udi) 72 return dbus.Interface(obj, interface)
73 74
75 - def _halDeviceAdded(self, udi):
76 udi = str(udi) 77 if not self.manager.DeviceExists(udi): 78 # device has been removed 79 return 80 device = self._getHalInterface(udi) 81 82 if not device.QueryCapability(self.subsystem): 83 # wrong device 84 return 85 86 self.deviceInfo[udi] = {"udi": udi} 87 88 if self.subsystem in HAL_SUBSYSTEM_PROPERTIES: 89 for k in HAL_SUBSYSTEM_PROPERTIES[self.subsystem]: 90 self.deviceInfo[udi][k] = str(device.GetProperty(self.subsystem+'.'+k)) 91 92 if "device" in self.deviceInfo[udi] and self.uniquePath: 93 by_id = [p for p in glob.glob(os.path.join(self.uniquePath, "*")) 94 if os.path.realpath(p) == self.deviceInfo[udi]["device"]] 95 if by_id: 96 self.deviceInfo[udi]["unique_path"] = by_id[0] 97 98 if self.events: 99 self.events.dispatch("%s-added" % self.subsystem, info=self.deviceInfo[udi]) 100 101 self.deviceAdded(self.deviceInfo[udi]) 102 return device
103 104
105 - def _halDeviceRemoved(self, udi):
106 udi = str(udi) 107 if udi not in self.deviceInfo: 108 return 109 110 if self.events: 111 self.events.dispatch("%s-removed" % self.subsystem, info=self.deviceInfo[udi]) 112 113 self.deviceRemoved(self.deviceInfo[udi]) 114 del self.deviceInfo[udi]
115 116
117 - def deviceAdded(self, info):
118 """ 119 This method will be called when a device has been added. If 120 you subclass this class, this method can be overruled to do 121 application-specific stuff. 122 """
123 124
125 - def deviceRemoved(self, info):
126 """ 127 This method will be called when a device has been removed. If 128 you subclass this class, this method can be overruled to do 129 application-specific stuff. 130 """
131