aboutsummaryrefslogtreecommitdiffstats
path: root/src/gr-fadingui/python/frame_obj.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/gr-fadingui/python/frame_obj.py77
1 files changed, 47 insertions, 30 deletions
diff --git a/src/gr-fadingui/python/frame_obj.py b/src/gr-fadingui/python/frame_obj.py
index b9dae70..136fce0 100644
--- a/src/gr-fadingui/python/frame_obj.py
+++ b/src/gr-fadingui/python/frame_obj.py
@@ -10,65 +10,82 @@ import numpy as np
from gnuradio import gr
-class frame_obj(gr.basic_block):
+class frame_obj:
"""
Frame Object: Contains informations about a data frame.
-------------------------------------------------------------------------------
| Preamble | Padding | ID | Data Length | Parity | Payload | Padding |
- | k bytes | 1 bit | 4 bits | 22 bits | 5 bits | | if necessary |
+ | k bytes | 1 bit | 5 bits | 21 bits | 5 bits | | if necessary |
-------------------------------------------------------------------------------
- | (31, 26) Hamming code EC |
- -----------------------------------
+ | (31, 26) Hamming EC code |
+ ---------------------------------
- The preamble is user defined.
- - The ID (11 bits) + Data length (22 bits) together are a 31 bits, followed
- by 26 parity bits computed using a (31,26) hamming code.
+ - The ID (5 bits) + Data length (21 bits) together are a 26 bits, followed
+ by 5 parity bits computed using a (31,26) hamming code.
- This constraints the maximum payload size to 64 MB and the number IDs to
- 1024 (i.e. max file size is 1 GB, more than enough for many thing)
+ This constraints the maximum payload size to 2 MiB and the number IDs to
+ 32, i.e. max file size is 64 MiB.
"""
def __init__(self, preamble, payload_len):
- gr.basic_block.__init__(self, name="frame_obj",
- in_sig=None, out_sig=None)
+ self._preamble = np.array(preamble, dtype=np.uint8)
- self.preamble = np.array(preamble, dtype=np.uint8)
+ self._preamble_len = len(self._preamble)
+ self._payload_len = payload_len
- self.preamble_len = len(self.preamble)
- self.payload_len = payload_len
+ @property
+ def header_length(self) -> int:
+ """Get header length in bytes"""
+ # 4 is the number of bytes for the hamming part
+ return self._preamble_len + 4
+
+ @property
+ def payload_length(self) -> int:
+ return self._payload_len
+
+ @property
+ def length(self) -> int:
+ """Get frame lenght in bytes"""
+ # 8 is the size of the hamming ECC part + 1 bit
+ return self.header_length + self.payload_length
@property
- def length(self):
- """Frame lenght in bytes"""
- return self.preamble_len + self.payload_len + 8
+ def preamble(self):
+ """Get preamble"""
+ return self._preamble
def parity(self, bits):
"""Compute the 5 parity bits for an unpacked array of 26 bits"""
assert(len(bits) == 26)
# FIXME: does not work
- # gen = np.array(
- # [[1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0],
- # [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1],
- # [0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0],
- # [0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0],
- # [0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1]],
- # dtype=np.uint8)
# return np.matmul(bits, gen) % 2
return np.array([0, 0, 0, 0, 0])
def make(self, idv, data_len, data):
"""Make a frame"""
- return np.concatenate(self.preamble, np.packbits(hamming), data)
+ # get lower 4 bits of idv
+ idv_bits = np.unpackbits([np.uint8(idv)])[:5]
+
+ # get lower 22 bits of data_len
+ data_len_bytes = list(map(np.uint8, data_len.to_bytes(4, byteorder='little')))
+ data_len_bits = np.unpackbits(data_len_bytes)[:21]
+
+ # compute 5 parity bits
+ metadata = np.concatenate([idv_bits, data_len_bits])
+ parity_bits = self.parity(metadata)
+
+ # add padding
+ hamming_bits = np.concatenate([[0], metadata, parity_bits])
+ assert(len(hamming_bits) == 32)
+
+ # pack 32 bits into 4 bytes and add the rest
+ hamming = np.packbits(hamming_bits)
+ return np.concatenate([self.preamble, hamming, data])
def syndrome(self, bits):
"""Compute the syndrome (check Hamming code) for an unpacked array of 31 bits"""
assert(len(bits) == 31)
return reduce(op.xor, [i for i, bit in enumerate(bits) if bit])
- def general_work(self, input_items, output_items):
- """
- This block has no inputs or output
- """
- return 0;
-