first work at detecting failed sdr devices

This commit is contained in:
Jakob Ketterl 2019-10-12 20:19:34 +02:00
parent 8541f79ebc
commit fce8c294d3
2 changed files with 44 additions and 17 deletions

View File

@ -119,11 +119,14 @@ class ServiceScheduler(object):
if time is not None: if time is not None:
delta = time - datetime.utcnow() delta = time - datetime.utcnow()
seconds = delta.total_seconds() seconds = delta.total_seconds()
if self.selectionTimer: self.cancelTimer()
self.selectionTimer.cancel()
self.selectionTimer = threading.Timer(seconds, self.selectProfile) self.selectionTimer = threading.Timer(seconds, self.selectProfile)
self.selectionTimer.start() self.selectionTimer.start()
def cancelTimer(self):
if self.selectionTimer:
self.selectionTimer.cancel()
def isActive(self): def isActive(self):
return self.active return self.active
@ -133,6 +136,9 @@ class ServiceScheduler(object):
def onSdrUnavailable(self): def onSdrUnavailable(self):
self.scheduleSelection() self.scheduleSelection()
def onSdrFailed(self):
self.cancelTimer()
def selectProfile(self): def selectProfile(self):
self.active = False self.active = False
if self.source.hasActiveClients(): if self.source.hasActiveClients():
@ -183,6 +189,10 @@ class ServiceHandler(object):
logger.debug("sdr source becoming unavailable; stopping services.") logger.debug("sdr source becoming unavailable; stopping services.")
self.stopServices() self.stopServices()
def onSdrFailed(self):
logger.debug("sdr source failed; stopping services.")
self.stopServices()
def isSupported(self, mode): def isSupported(self, mode):
return mode in PropertyManager.getSharedInstance()["services_decoders"] return mode in PropertyManager.getSharedInstance()["services_decoders"]

View File

@ -75,10 +75,11 @@ class SdrService(object):
@staticmethod @staticmethod
def getSource(id=None): def getSource(id=None):
SdrService.loadProps() SdrService.loadProps()
sources = SdrService.getSources()
if id is None: if id is None:
# TODO: configure default sdr in config? right now it will pick the first one off the list. # TODO: configure default sdr in config? right now it will pick the first one off the list.
id = list(SdrService.sdrProps.keys())[0] id = list(sources.keys())[0]
sources = SdrService.getSources()
return sources[id] return sources[id]
@staticmethod @staticmethod
@ -90,11 +91,7 @@ class SdrService(object):
className = "".join(x for x in props["type"].title() if x.isalnum()) + "Source" className = "".join(x for x in props["type"].title() if x.isalnum()) + "Source"
cls = getattr(sys.modules[__name__], className) cls = getattr(sys.modules[__name__], className)
SdrService.sources[id] = cls(id, props, SdrService.getNextPort()) SdrService.sources[id] = cls(id, props, SdrService.getNextPort())
return SdrService.sources return {key: s for key, s in SdrService.sources.items() if not s.isFailed()}
class SdrSourceException(Exception):
pass
class SdrSource(object): class SdrSource(object):
@ -120,6 +117,7 @@ class SdrSource(object):
self.spectrumThread = None self.spectrumThread = None
self.process = None self.process = None
self.modificationLock = threading.Lock() self.modificationLock = threading.Lock()
self.failed = False
# override this in subclasses # override this in subclasses
def getCommand(self): def getCommand(self):
@ -224,17 +222,23 @@ class SdrSource(object):
except: except:
time.sleep(0.1) time.sleep(0.1)
if not available:
self.failed = True
self.modificationLock.release() self.modificationLock.release()
if not available:
raise SdrSourceException("rtl source failed to start up")
for c in self.clients: for c in self.clients:
c.onSdrAvailable() if self.failed:
c.onSdrFailed()
else:
c.onSdrAvailable()
def isAvailable(self): def isAvailable(self):
return self.monitor is not None return self.monitor is not None
def isFailed(self):
return self.failed
def stop(self): def stop(self):
for c in self.clients: for c in self.clients:
c.onSdrUnavailable() c.onSdrUnavailable()
@ -305,6 +309,9 @@ class Resampler(SdrSource):
super().__init__(None, props, port) super().__init__(None, props, port)
def start(self): def start(self):
if self.isFailed():
return
self.modificationLock.acquire() self.modificationLock.acquire()
if self.monitor: if self.monitor:
self.modificationLock.release() self.modificationLock.release()
@ -364,13 +371,16 @@ class Resampler(SdrSource):
except: except:
time.sleep(0.1) time.sleep(0.1)
if not available:
self.failed = True
self.modificationLock.release() self.modificationLock.release()
if not available:
raise SdrSourceException("resampler source failed to start up")
for c in self.clients: for c in self.clients:
c.onSdrAvailable() if self.failed:
c.onSdrFailed()
else:
c.onSdrAvailable()
def activateProfile(self, profile_id=None): def activateProfile(self, profile_id=None):
pass pass
@ -504,6 +514,9 @@ class SpectrumThread(csdr.output):
def onSdrUnavailable(self): def onSdrUnavailable(self):
self.dsp.stop() self.dsp.stop()
def onSdrFailed(self):
self.dsp.stop()
class DspManager(csdr.output): class DspManager(csdr.output):
def __init__(self, handler, sdrSource): def __init__(self, handler, sdrSource):
@ -638,6 +651,10 @@ class DspManager(csdr.output):
logger.debug("received onSdrUnavailable, shutting down DspSource") logger.debug("received onSdrUnavailable, shutting down DspSource")
self.dsp.stop() self.dsp.stop()
def onSdrFailed(self):
logger.debug("received onSdrFailed, shutting down DspSource")
self.dsp.stop()
class CpuUsageThread(threading.Thread): class CpuUsageThread(threading.Thread):
sharedInstance = None sharedInstance = None