aboutsummaryrefslogtreecommitdiffstats
path: root/host/python
diff options
context:
space:
mode:
authorSamuel O'Brien <sam.obrien@ni.com>2020-07-02 11:49:09 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2020-07-16 09:59:25 -0500
commit51bf7717e2fde33087055ff7c5649783e2260981 (patch)
tree99784f144d328731c2f43b3484be9e7278a1859f /host/python
parent9a75dcf3a3c0f71b49b4d2a7a7f154d008979159 (diff)
downloaduhd-51bf7717e2fde33087055ff7c5649783e2260981.tar.gz
uhd-51bf7717e2fde33087055ff7c5649783e2260981.tar.bz2
uhd-51bf7717e2fde33087055ff7c5649783e2260981.zip
python: Add payload agnostic methods to CHDR API
In the c++ api, methods like chdr_packet#set_payload() and chdr_packet#get_payload() are templated over the payload type (payload_t). For methods like set_payload, they are overloaded by the type of an argument, so in pybind we can just explicitly instaniate the template for each payload_t and register it with pybind under the same name. At runtime, pybind looks at the type of the argument and decides which to call. The problem arose with methods like get_payload, which are overloaded by return type. In C++, the compiler can infer the template type by the type of the target at the call site. In python, there is no way for the pybind to determine which variant of get_payload to call, and it would crash. Previously, the workaround for this was to declare get_payload_ctrl, get_payload_mgmt, etc, but this was rather anti-pythonic. This commit utilizes the fact that python methods don't have a constrained return type to resolve this. Now, get_payload will call a python method which looks at the chdr_packet#header#pkt_type field to determine which variant of get_payload to call and returns that type of payload_t. Signed-off-by: Samuel O'Brien <sam.obrien@ni.com>
Diffstat (limited to 'host/python')
-rw-r--r--host/python/uhd/__init__.py1
-rw-r--r--host/python/uhd/chdr.py60
2 files changed, 61 insertions, 0 deletions
diff --git a/host/python/uhd/__init__.py b/host/python/uhd/__init__.py
index 8b6a2b36c..99c10c3b1 100644
--- a/host/python/uhd/__init__.py
+++ b/host/python/uhd/__init__.py
@@ -12,4 +12,5 @@ from . import usrp
from . import filters
from . import rfnoc
from . import dsp
+from . import chdr
from .libpyuhd.paths import *
diff --git a/host/python/uhd/chdr.py b/host/python/uhd/chdr.py
new file mode 100644
index 000000000..577606cc8
--- /dev/null
+++ b/host/python/uhd/chdr.py
@@ -0,0 +1,60 @@
+#
+# Copyright 2020 Ettus Research, a National Instruments Brand
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+from . import libpyuhd as lib
+
+ChdrPacket = lib.chdr.ChdrPacket
+Endianness = lib.chdr.Endianness
+ChdrWidth = lib.chdr.ChdrWidth
+ChdrHeader = lib.chdr.ChdrHeader
+CtrlPayload = lib.chdr.CtrlPayload
+CtrlStatus = lib.chdr.CtrlStatus
+PacketType = lib.chdr.PacketType
+CtrlOpCode = lib.chdr.CtrlOpCode
+MgmtPayload = lib.chdr.MgmtPayload
+MgmtHop = lib.chdr.MgmtHop
+MgmtOp = lib.chdr.MgmtOp
+MgmtOpCode = lib.chdr.MgmtOpCode
+MgmtOpSelDest = lib.chdr.MgmtOpSelDest
+MgmtOpCfg = lib.chdr.MgmtOpCfg
+MgmtOpNodeInfo = lib.chdr.MgmtOpNodeInfo
+StrsPayload = lib.chdr.StrsPayload
+StrsStatus = lib.chdr.StrsStatus
+StrcPayload = lib.chdr.StrcPayload
+StrcOpCode = lib.chdr.StrcOpCode
+
+def __get_payload(self):
+ pkt_type = self.get_header().pkt_type
+ if pkt_type == PacketType.MGMT:
+ return self.get_payload_mgmt()
+ elif pkt_type == PacketType.CTRL:
+ return self.get_payload_ctrl()
+ elif pkt_type == PacketType.STRC:
+ return self.get_payload_strc()
+ elif pkt_type == PacketType.STRS:
+ return self.get_payload_strs()
+ elif pkt_type in {PacketType.DATA_NO_TS, PacketType.DATA_WITH_TS}:
+ raise RuntimeError("Cannot deserialize a Data Payload")
+ else:
+ raise RuntimeError("Invalid pkt_type in ChdrHeader")
+
+ChdrPacket.get_payload = __get_payload
+
+def __to_string_with_payload(self):
+ pkt_type = self.get_header().pkt_type
+ if pkt_type == PacketType.MGMT:
+ return self.to_string_with_payload_mgmt()
+ elif pkt_type == PacketType.CTRL:
+ return self.to_string_with_payload_ctrl()
+ elif pkt_type == PacketType.STRC:
+ return self.to_string_with_payload_strc()
+ elif pkt_type == PacketType.STRS:
+ return self.to_string_with_payload_strs()
+ elif pkt_type in {PacketType.DATA_NO_TS, PacketType.DATA_WITH_TS}:
+ return self.__str__()
+ else:
+ raise RuntimeError("Invalid pkt_type in ChdrHeader")
+
+ChdrPacket.to_string_with_payload = __to_string_with_payload