aboutsummaryrefslogtreecommitdiff
path: root/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci
diff options
context:
space:
mode:
Diffstat (limited to 'circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci')
-rw-r--r--circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/__init__.py29
-rw-r--r--circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/codec.py76
-rw-r--r--circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/slip.py115
-rw-r--r--circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/__init__.py29
-rw-r--r--circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/test_codec.py81
5 files changed, 330 insertions, 0 deletions
diff --git a/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/__init__.py b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/__init__.py
new file mode 100644
index 0000000..8f8006e
--- /dev/null
+++ b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/__init__.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2015, Nordic Semiconductor
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of Nordic Semiconductor ASA nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Package marker file."""
diff --git a/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/codec.py b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/codec.py
new file mode 100644
index 0000000..bebd790
--- /dev/null
+++ b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/codec.py
@@ -0,0 +1,76 @@
+# Copyright (c) 2015, Nordic Semiconductor
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of Nordic Semiconductor ASA nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+UART_HEADER_OCTET_COUNT = 4
+
+
+class ThreeWireUartPacket(object):
+ """
+ This class encapsulate a three wire uart packet according to Bluetooth specification
+ version 4.0 [Vol 4] part D.
+ """
+ def __init__(self):
+ self.ack = None # Acknowledgement number
+ self.seq = None # Sequence number
+ self.di = None # Data integrity present
+ self.rp = None # Reliable packet
+ self.type = None # Packet type
+ self.length = None # Payload Length
+ self.checksum = None # Header checksum
+ self.payload = None # Payload
+
+ @staticmethod
+ def decode(packet):
+ """
+ Decodes a packet from a str encoded array
+
+ :param packet_bytes: A str encoded array
+ :return: TheeWireUartPacket
+ """
+
+ decoded_packet = ThreeWireUartPacket()
+
+ packet_bytes = bytearray(packet)
+
+ decoded_packet.ack = (packet_bytes[0] & int('38', 16)) >> 3
+ decoded_packet.seq = (packet_bytes[0] & int('07', 16))
+ decoded_packet.di = (packet_bytes[0] & int('40', 16)) >> 6
+ decoded_packet.rp = (packet_bytes[0] & int('80', 16)) >> 7
+ decoded_packet.type = (packet_bytes[1] & int('0F', 16))
+ decoded_packet.length = ((packet_bytes[1] & int('F0', 16)) >> 4) + (packet_bytes[2] * 16)
+
+ checksum = packet_bytes[0]
+ checksum = checksum + packet_bytes[1]
+ checksum = checksum + packet_bytes[2]
+ checksum &= int('FF', 16)
+ decoded_packet.checksum = (~checksum + 1) & int('FF', 16)
+
+ if decoded_packet.length > 0:
+ decoded_packet.payload = packet_bytes[UART_HEADER_OCTET_COUNT:-1]
+
+ return decoded_packet
diff --git a/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/slip.py b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/slip.py
new file mode 100644
index 0000000..e2a525f
--- /dev/null
+++ b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/slip.py
@@ -0,0 +1,115 @@
+# Copyright (c) 2015, Nordic Semiconductor
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of Nordic Semiconductor ASA nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+class Slip(object):
+ def __init__(self):
+ self.SLIP_END = '\xc0'
+ self.SLIP_ESC = '\xdb'
+ self.SLIP_ESC_END = '\xdc'
+ self.SLIP_ESC_ESC = '\xdd'
+
+ self.started = False
+ self.escaped = False
+ self.stream = ''
+ self.packet = ''
+
+ def append(self, data):
+ """
+ Append a new
+ :param data: Append a new block of data to do decoding on when calling decode.
+ The developer may add more than one SLIP packet before calling decode.
+ :return:
+ """
+ self.stream += data
+
+ def decode(self):
+ """
+ Decodes a package according to http://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol
+ :return Slip: A list of decoded slip packets
+ """
+ packet_list = list()
+
+ for char in self.stream:
+ if char == self.SLIP_END:
+ if self.started:
+ if len(self.packet) > 0:
+ self.started = False
+ packet_list.append(self.packet)
+ self.packet = ''
+ else:
+ self.started = True
+ self.packet = ''
+ elif char == self.SLIP_ESC:
+ self.escaped = True
+ elif char == self.SLIP_ESC_END:
+ if self.escaped:
+ self.packet += self.SLIP_END
+ self.escaped = False
+ else:
+ self.packet += char
+ elif char == self.SLIP_ESC_ESC:
+ if self.escaped:
+ self.packet += self.SLIP_ESC
+ self.escaped = False
+ else:
+ self.packet += char
+ else:
+ if self.escaped:
+ logging.error("Error in SLIP packet, ignoring error.")
+ self.packet = ''
+ self.escaped = False
+ else:
+ self.packet += char
+
+ self.stream = ''
+
+ return packet_list
+
+ def encode(self, packet):
+ """
+ Encode a packet according to SLIP.
+ :param packet: A str array that represents the package
+ :return: str array with an encoded SLIP packet
+ """
+ encoded = self.SLIP_END
+
+ for char in packet:
+ if char == self.SLIP_END:
+ encoded += self.SLIP_ESC + self.SLIP_ESC_END
+ elif char == self.SLIP_ESC:
+ encoded += self.SLIP_ESC + self.SLIP_ESC_ESC
+ else:
+ encoded += char
+ encoded += self.SLIP_END
+
+ return encoded
diff --git a/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/__init__.py b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/__init__.py
new file mode 100644
index 0000000..8f8006e
--- /dev/null
+++ b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/__init__.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2015, Nordic Semiconductor
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of Nordic Semiconductor ASA nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Package marker file."""
diff --git a/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/test_codec.py b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/test_codec.py
new file mode 100644
index 0000000..c7d6f26
--- /dev/null
+++ b/circuitpython/lib/nrfutil/nordicsemi/bluetooth/hci/tests/test_codec.py
@@ -0,0 +1,81 @@
+# Copyright (c) 2015, Nordic Semiconductor
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of Nordic Semiconductor ASA nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import json
+import unittest
+from nordicsemi.bluetooth.hci.slip import Slip
+from nordicsemi.bluetooth.hci import codec
+
+
+class TestInitPacket(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_decode_packet(self):
+ # TODO: extend this test, this tests only a small portion of the slip/hci decoding
+ # These are packets read from Device Monitoring Studio
+ # during communication between serializer application and firmware
+ read_packets = [
+ " C0 10 00 00 F0 C0 C0 D1 6E 00 C1 01 86 00 00 00 00 17 63 C0",
+ " C0 D2 DE 02 4E 02 1B 00 FF FF 01 17 FE B4 9A 9D E1 B0 F8 02"
+ " 01 06 11 07 1B C5 D5 A5 02 00 A9 B7 E2 11 A4 C6 00 FE E7 74"
+ " 09 09 49 44 54 57 32 31 38 48 5A BB C0",
+ " C0 D3 EE 00 3F 02 1B 00 FF FF 01 17 FE B4 9A 9D E1 AF 01 F1 62 C0",
+ " C0 D4 DE 02 4C 02 1B 00 FF FF 01 17 FE B4 9A 9D E1 B1 F8 02 01 06"
+ " 11 07 1B C5 D5 A5 02 00 A9 B7 E2 11 A4 C6 00 FE E7 74 09 09 49 44 54 57 32 31 38 48 6E C8 C0"
+ ]
+
+ slip = Slip()
+ output = list()
+
+ for uart_packet in read_packets:
+ hex_string = uart_packet.replace(" ", "")
+ hex_data = hex_string.decode("hex")
+ slip.append(hex_data)
+
+ packets = slip.decode()
+
+ for packet in packets:
+ output.append(codec.ThreeWireUartPacket.decode(packet))
+
+ self.assertEqual(len(output), 5)
+
+ packet_index = 0
+ self.assertEqual(output[packet_index].seq, 0)
+
+ packet_index += 1
+ self.assertEqual(output[packet_index].seq, 1)
+
+ packet_index += 1
+ self.assertEqual(output[packet_index].seq, 2)
+
+ packet_index += 1
+ self.assertEqual(output[packet_index].seq, 3)
+
+ packet_index += 1
+ self.assertEqual(output[packet_index].seq, 4)