[FIX] hw_proxy,hw_blackbox_be: make RS-232 drivers protect their device

RS-232 drivers now need to register any device
they are handling in the hw_proxy.rs232_devices map.
This will prevent other drivers from probing them,
possibly messing up with the device.
Any update to rs232_devices must be done while holding
the hw_proxy.rs232_lock.

The hw_scale driver will be updated to use this mechanism
in the next commit, that will also handle a new RS-232
scale protocol.
This commit is contained in:
Olivier Dony 2016-11-02 13:45:41 +01:00
parent 2fd4dfca7f
commit eeadeb0d6e
No known key found for this signature in database
GPG Key ID: CD556E25E8A6D0D4
2 changed files with 32 additions and 18 deletions

View File

@ -14,6 +14,8 @@ import openerp.addons.hw_proxy.controllers.main as hw_proxy
_logger = logging.getLogger(__name__)
DRIVER_NAME = 'fiscal_data_module'
class Blackbox(Thread):
def __init__(self):
Thread.__init__(self)
@ -39,26 +41,31 @@ class Blackbox(Thread):
# request. The first device to give an answer that makes sense
# wins.
def _find_device_path_by_probing(self):
path = "/dev/serial/by-path/"
probe_message = self._wrap_low_level_message_around("S000")
with hw_proxy.rs232_lock:
path = "/dev/serial/by-path/"
probe_message = self._wrap_low_level_message_around("S000")
try:
devices = listdir(path)
except OSError:
_logger.warning(path + " doesn't exist")
else:
for device in listdir(path):
path_to_device = path + device
_logger.debug("Probing " + device)
try:
devices = listdir(path)
except OSError:
_logger.warning(path + " doesn't exist")
self.set_status("disconnected", ["No RS-232 device (or emulated ones) found"])
else:
for device in devices:
if device in hw_proxy.rs232_devices:
continue
path_to_device = path + device
_logger.debug("Probing " + device)
if self._send_to_blackbox(probe_message, 21, path_to_device, just_wait_for_ack=True):
_logger.info(device + " will be used as the blackbox")
self.set_status("connected", [device])
return path_to_device
if self._send_to_blackbox(probe_message, 21, path_to_device, just_wait_for_ack=True):
_logger.info(device + " will be used as the blackbox")
self.set_status("connected", [device])
hw_proxy.rs232_devices[device] = DRIVER_NAME
return path_to_device
_logger.warning("Blackbox could not be found")
self.set_status("error", ["Couldn't find the Fiscal Data Module"])
return ""
_logger.warning("Blackbox could not be found")
self.set_status("disconnected", ["Couldn't find the Fiscal Data Module"])
return ""
def _lrc(self, msg):
lrc = 0
@ -152,7 +159,7 @@ class Blackbox(Thread):
if isfile("/home/pi/registered_blackbox_be"):
blackbox_thread = Blackbox()
hw_proxy.drivers['fiscal_data_module'] = blackbox_thread
hw_proxy.drivers[DRIVER_NAME] = blackbox_thread
class BlackboxDriver(hw_proxy.Proxy):
@http.route('/hw_proxy/request_blackbox/', type='json', auth='none', cors='*')

View File

@ -11,6 +11,8 @@ import subprocess
import simplejson
import werkzeug
import werkzeug.wrappers
from threading import Lock
_logger = logging.getLogger(__name__)
@ -30,6 +32,11 @@ BANNED_DEVICES = set([
# so that 'status' can return the status of all active drivers
drivers = {}
# keep a list of RS-232 devices that have been recognized by a driver,
# so other drivers can skip them during probes
rs232_devices = {} # {'/path/to/device': 'driver'}
rs232_lock = Lock() # must be held to update `rs232_devices`
class Proxy(http.Controller):
def get_status(self):