graycode, morse, pwm, usb_request, wiegand: cope with absent sample rate
authorGerhard Sittig <gerhard.sittig@gmx.net>
Sun, 28 Jan 2018 19:49:48 +0000 (20:49 +0100)
committerGerhard Sittig <gerhard.sittig@gmx.net>
Sun, 28 Jan 2018 19:49:48 +0000 (20:49 +0100)
Improve robustness of some more protocol decoders. Few of them never
checked for the availability of a sample rate in the first place, others
checked for the presence of a spec but would not cope with a value of 0.
Some checked the value only after processing it, which could result in
runtime errors.

This change is motivated by bug #1118.

decoders/graycode/pd.py
decoders/morse/pd.py
decoders/pwm/pd.py
decoders/usb_request/pd.py
decoders/wiegand/pd.py

index 1211c69efd88834a47cd84120cf287be5c6d4f4e..ef5d51352fe25356da1e9c47faf9c0487a5c3f4c 100644 (file)
@@ -175,7 +175,7 @@ class Decoder(srd.Decoder):
             if self.options['edges']:
                 self.turns.set(self.samplenum, self.count.get() // self.options['edges'])
 
-            if self.samplerate is not None:
+            if self.samplerate:
                 period = (curtime - prevtime) / self.samplerate
                 freq = abs(phasedelta_raw) / period
 
index a1e3c23072d6bad62a871ecfa80832ed4011349a..3048332354f4a86585ef3fc55fc16796cf2c39fb 100644 (file)
@@ -154,8 +154,6 @@ class Decoder(srd.Decoder):
         # Annotate symbols, emit symbols, handle timeout via token.
 
         timeunit = self.options['timeunit']
-        if self.samplerate is None:
-            self.samplerate = 1.0
 
         self.wait({0: 'r'})
         prevtime = self.samplenum # Time of an actual edge.
@@ -217,6 +215,15 @@ class Decoder(srd.Decoder):
                 yield None # Pass through flush of 5+ space.
 
     def decode(self):
+
+        # Strictly speaking there is no point in running this decoder
+        # when the sample rate is unknown or zero. But the previous
+        # implementation already fell back to a rate of 1 in that case.
+        # We stick with this approach, to not introduce new constraints
+        # for existing use scenarios.
+        if not self.samplerate:
+            self.samplerate = 1.0
+
         # Annotate letters, group into words.
         s0 = s1 = None
         word = ''
index 2301523c1abd06923999aff4476b3ceae9c04a62..97704450b7701f5a01387f234eea6e9d16cc0a8e 100644 (file)
@@ -20,6 +20,9 @@
 
 import sigrokdecode as srd
 
+class SamplerateError(Exception):
+    pass
+
 class Decoder(srd.Decoder):
     api_version = 3
     id = 'pwm'
@@ -52,6 +55,7 @@ class Decoder(srd.Decoder):
         self.reset()
 
     def reset(self):
+        self.samplerate = None
         self.ss_block = self.es_block = None
 
     def metadata(self, key, value):
@@ -89,6 +93,9 @@ class Decoder(srd.Decoder):
         self.put(self.ss_block, self.es_block, self.out_binary, data)
 
     def decode(self):
+        if not self.samplerate:
+            raise SamplerateError('Cannot decode without samplerate.')
+
         num_cycles = 0
         average = 0
 
index a4802845aa25681101011ce21cff17bfa1ab31cc..e77debc46d784a06372960285cea3844bfab8585 100644 (file)
@@ -171,7 +171,8 @@ class Decoder(srd.Decoder):
     def metadata(self, key, value):
         if key == srd.SRD_CONF_SAMPLERATE:
             self.samplerate = value
-            self.secs_per_sample = float(1) / float(self.samplerate)
+            if self.samplerate:
+                self.secs_per_sample = float(1) / float(self.samplerate)
 
     def start(self):
         self.out_binary = self.register(srd.OUTPUT_BINARY)
index ea873ea123a9406aac91a11689d0b2895fa2d1eb..c494789840131fb11d2b083145bc34188032596d 100644 (file)
@@ -19,6 +19,9 @@
 
 import sigrokdecode as srd
 
+class SamplerateError(Exception):
+    pass
+
 class Decoder(srd.Decoder):
     api_version = 3
     id = 'wiegand'
@@ -51,6 +54,7 @@ class Decoder(srd.Decoder):
         self.reset()
 
     def reset(self):
+        self.samplerate = None
         self._samples_per_bit = 10
 
         self._d0_prev = None
@@ -73,9 +77,11 @@ class Decoder(srd.Decoder):
     def metadata(self, key, value):
         'Receive decoder metadata about the data stream.'
         if key == srd.SRD_CONF_SAMPLERATE:
-            ms_per_sample = 1000 * (1.0 / value)
-            ms_per_bit = float(self.options['bitwidth_ms'])
-            self._samples_per_bit = int(max(1, int(ms_per_bit / ms_per_sample)))
+            self.samplerate = value
+            if self.samplerate:
+                ms_per_sample = 1000 * (1.0 / self.samplerate)
+                ms_per_bit = float(self.options['bitwidth_ms'])
+                self._samples_per_bit = int(max(1, int(ms_per_bit / ms_per_sample)))
 
     def _update_state(self, state, bit=None):
         'Update state and bit values when they change.'
@@ -106,6 +112,8 @@ class Decoder(srd.Decoder):
             self._bits = []
 
     def decode(self):
+        if not self.samplerate:
+            raise SamplerateError('Cannot decode without samplerate.')
         while True:
             # TODO: Come up with more appropriate self.wait() conditions.
             (d0, d1) = self.wait()