From ab1e21c114465fa03d7fb1b56b3d5f8c9f56671e Mon Sep 17 00:00:00 2001
From: Jacob Gilbert <jacob.gilbert@protonmail.com>
Date: Tue, 1 Jun 2021 19:23:08 -0600
Subject: blocks: improvements to var/msg blocks

Fixes an issue where a user was feeding a dictionary into the msg_to_var
block which was then setting the variable to 'None' causing unexpected
behavior. This improves input sanitization for both blocks and adds
some extra info to the docstrings.

Signed-off-by: Jacob Gilbert <jacob.gilbert@protonmail.com>
---
 gr-blocks/python/blocks/msg_pair_to_var.py | 16 ++++++++++-----
 gr-blocks/python/blocks/var_to_msg.py      | 31 +++++++++++++++++++-----------
 2 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/gr-blocks/python/blocks/msg_pair_to_var.py b/gr-blocks/python/blocks/msg_pair_to_var.py
index 17cd7fcc38..97f73f85f8 100644
--- a/gr-blocks/python/blocks/msg_pair_to_var.py
+++ b/gr-blocks/python/blocks/msg_pair_to_var.py
@@ -13,7 +13,10 @@ import pmt
 
 class msg_pair_to_var(gr.sync_block):
     """
-    This block will take an input message pair and allow you to set a gnuradio variable.
+    This block will take an input message pair and allow you to set a flowgraph variable
+    via setter callback. If the second element the pair is a compound PMT object or not
+    of the datatype expected by the flowgraph the behavior of the flowgraph may be
+    unpredictable.
     """
     def __init__(self, callback):
         gr.sync_block.__init__(self, name="msg_pair_to_var", in_sig=None, out_sig=None)
@@ -24,13 +27,16 @@ class msg_pair_to_var(gr.sync_block):
         self.set_msg_handler(pmt.intern("inpair"), self.msg_handler)
 
     def msg_handler(self, msg):
-        try:
-            new_val = pmt.to_python(pmt.cdr(msg))
+        if not pmt.is_pair(msg) or pmt.is_dict(msg) or pmt.is_pdu(msg):
+            gr.log.warn("Input message %s is not a simple pair, dropping" % repr(msg))
+            return
 
+        new_val = pmt.to_python(pmt.cdr(msg))
+        try:
             self.callback(new_val)
-
         except Exception as e:
-            gr.log.error("Error with message conversion: %s" % str(e))
+            gr.log.error("Error when calling " + repr(self.callback.name()) + " with "
+                         + repr(new_val) + " (reason: %s)"  % repr(e))
 
     def stop(self):
         return True
diff --git a/gr-blocks/python/blocks/var_to_msg.py b/gr-blocks/python/blocks/var_to_msg.py
index 77a947ed0c..823609182c 100644
--- a/gr-blocks/python/blocks/var_to_msg.py
+++ b/gr-blocks/python/blocks/var_to_msg.py
@@ -13,7 +13,9 @@ import pmt
 
 class var_to_msg_pair(gr.sync_block):
     """
-    This block will monitor a variable, and when it changes, generate a message.
+    This block has a callback that will emit a message pair with the updated variable
+    value when called. This is useful for monitoring a GRC variable and emitting a message
+    when it is changed.
     """
     def __init__(self, pairname):
         gr.sync_block.__init__(self, name="var_to_msg_pair", in_sig=None, out_sig=None)
@@ -23,16 +25,23 @@ class var_to_msg_pair(gr.sync_block):
         self.message_port_register_out(pmt.intern("msgout"))
 
     def variable_changed(self, value):
-        if type(value) == float:
-            p = pmt.from_float(value)
-        elif type(value) == int:
-            p = pmt.from_long(value)
-        elif type(value) == bool:
-            p = pmt.from_bool(value)
-        else:
-            p = pmt.intern(value)
-
-        self.message_port_pub(pmt.intern("msgout"), pmt.cons(pmt.intern(self.pairname), p))
+        try:
+            if type(value) == float:
+                p = pmt.from_double(value)
+            elif type(value) == int:
+                p = pmt.from_long(value)
+            elif type(value) == bool:
+                p = pmt.from_bool(value)
+            elif type(value) == str:
+                p = pmt.intern(value)
+            else:
+                p = pmt.to_pmt(value)
+
+            self.message_port_pub(pmt.intern("msgout"), pmt.cons(pmt.intern(self.pairname), p))
+
+        except Exception as e:
+            gr.log.error("Unable to convert " + repr(value) + " to PDU, no message will be emitted (reason: %s)" % repr(e))
+
 
     def stop(self):
         return True
-- 
cgit v1.2.3