about summary refs log tree commit diff
path: root/broadlink/__init__.py
diff options
context:
space:
mode:
authormajuss <biomajuss@gmail.com>2020-04-10T07·23+0200
committerGitHub <noreply@github.com>2020-04-10T07·23+0200
commita6827caaf7d796145649d3de69ee5e5bb2f43e66 (patch)
treec0411795ac7beda5dc2d837fdd70f374e71b52e6 /broadlink/__init__.py
parent2bc7b06c69487b7750792e1f913905aecd46da3c (diff)
Removed PyCRC as dependency; implemented CRC16 directly (#327)
* Removed PyCRC as dependency; implemented CRC16 directly

* replace crc16 with integrated function

* Added self to calculate crc
Diffstat (limited to 'broadlink/__init__.py')
-rw-r--r--broadlink/__init__.py40
1 files changed, 37 insertions, 3 deletions
diff --git a/broadlink/__init__.py b/broadlink/__init__.py
index c9e581fd6c78..49309c21f12f 100644
--- a/broadlink/__init__.py
+++ b/broadlink/__init__.py
@@ -701,10 +701,44 @@ class hysen(device):
     # Returns decrypted payload
     # New behaviour: raises a ValueError if the device response indicates an error or CRC check fails
     # The function prepends length (2 bytes) and appends CRC
+
+    def calculate_crc16(self, input_data):
+        from ctypes import c_ushort
+        crc16_tab = []
+        crc16_constant = 0xA001
+
+        for i in range(0, 256):
+            crc = c_ushort(i).value
+            for j in range(0, 8):
+                if (crc & 0x0001):
+                    crc = c_ushort(crc >> 1).value ^ crc16_constant
+                else:
+                    crc = c_ushort(crc >> 1).value
+            crc16_tab.append(hex(crc))
+
+        try:
+            is_string = isinstance(input_data, str)
+            is_bytes = isinstance(input_data, bytes)
+
+            if not is_string and not is_bytes:
+                raise Exception("Please provide a string or a byte sequence "
+                                "as argument for calculation.")
+
+            crcValue = 0xffff
+
+            for c in input_data:
+                d = ord(c) if is_string else c
+                tmp = crcValue ^ d
+                rotated = c_ushort(crcValue >> 8).value
+                crcValue = rotated ^ int(crc16_tab[(tmp & 0x00ff)], 0)
+
+            return crcValue
+        except Exception as e:
+            print("EXCEPTION(calculate): {}".format(e))
+
     def send_request(self, input_payload):
 
-        from PyCRC.CRC16 import CRC16
-        crc = CRC16(modbus_flag=True).calculate(bytes(input_payload))
+        crc = calculate_crc16(bytes(input_payload))
 
         # first byte is length, +2 for CRC16
         request_payload = bytearray([len(input_payload) + 2, 0x00])
@@ -728,7 +762,7 @@ class hysen(device):
         response_payload_len = response_payload[0]
         if response_payload_len + 2 > len(response_payload):
             raise ValueError('hysen_response_error', 'first byte of response is not length')
-        crc = CRC16(modbus_flag=True).calculate(bytes(response_payload[2:response_payload_len]))
+        crc = calculate_crc16(bytes(response_payload[2:response_payload_len]))
         if (response_payload[response_payload_len] == crc & 0xFF) and (
                 response_payload[response_payload_len + 1] == (crc >> 8) & 0xFF):
             return response_payload[2:response_payload_len]