diff --git a/api/reference.html b/api/reference.html index ec7277b..f5b621e 100644 --- a/api/reference.html +++ b/api/reference.html @@ -1323,62 +1323,7 @@ address[0] is the LSB of the address, address[5] is the MSB.

Source code in bumble/hci.py -
1682
-1683
-1684
-1685
-1686
-1687
-1688
-1689
-1690
-1691
-1692
-1693
-1694
-1695
-1696
-1697
-1698
-1699
-1700
-1701
-1702
-1703
-1704
-1705
-1706
-1707
-1708
-1709
-1710
-1711
-1712
-1713
-1714
-1715
-1716
-1717
-1718
-1719
-1720
-1721
-1722
-1723
-1724
-1725
-1726
-1727
-1728
-1729
-1730
-1731
-1732
-1733
-1734
-1735
-1736
-1737
+          
1737
 1738
 1739
 1740
@@ -1464,7 +1409,62 @@ address[0] is the LSB of the address, address[5] is the MSB.

1820 1821 1822 -1823
class Address:
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
class Address:
     '''
     Bluetooth Address (see Bluetooth spec Vol 6, Part B - 1.3 DEVICE ADDRESS)
     NOTE: the address bytes are stored in little-endian byte order here, so
@@ -1641,33 +1641,33 @@ the type is set to PUBLIC_DEVICE_ADDRESS.

Source code in bumble/hci.py -
1738
-1739
-1740
-1741
-1742
-1743
-1744
-1745
-1746
-1747
-1748
-1749
-1750
-1751
-1752
-1753
-1754
-1755
-1756
-1757
-1758
-1759
-1760
-1761
-1762
-1763
-1764
def __init__(
+        
1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
def __init__(
     self, address: Union[bytes, str], address_type: int = RANDOM_DEVICE_ADDRESS
 ):
     '''
@@ -1717,15 +1717,15 @@ qualifier.

Source code in bumble/hci.py -
1800
-1801
-1802
-1803
-1804
-1805
-1806
-1807
-1808
def to_string(self, with_type_qualifier=True):
+        
1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
def to_string(self, with_type_qualifier=True):
     '''
     String representation of the address, MSB first, with an optional type
     qualifier.
@@ -1761,36 +1761,36 @@ qualifier.

Source code in bumble/hci.py -
1854
-1855
-1856
-1857
-1858
-1859
-1860
-1861
-1862
-1863
-1864
-1865
-1866
-1867
-1868
-1869
-1870
-1871
-1872
-1873
-1874
-1875
-1876
-1877
-1878
-1879
-1880
-1881
-1882
-1883
class HCI_Packet:
+          
1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
class HCI_Packet:
     '''
     Abstract Base class for HCI packets
     '''
@@ -1798,7 +1798,7 @@ qualifier.

hci_packet_type: int @staticmethod - def from_bytes(packet): + def from_bytes(packet: bytes) -> HCI_Packet: packet_type = packet[0] if packet_type == HCI_COMMAND_PACKET: @@ -1859,62 +1859,7 @@ qualifier.

Source code in bumble/hci.py -
1898
-1899
-1900
-1901
-1902
-1903
-1904
-1905
-1906
-1907
-1908
-1909
-1910
-1911
-1912
-1913
-1914
-1915
-1916
-1917
-1918
-1919
-1920
-1921
-1922
-1923
-1924
-1925
-1926
-1927
-1928
-1929
-1930
-1931
-1932
-1933
-1934
-1935
-1936
-1937
-1938
-1939
-1940
-1941
-1942
-1943
-1944
-1945
-1946
-1947
-1948
-1949
-1950
-1951
-1952
-1953
+          
1953
 1954
 1955
 1956
@@ -1955,12 +1900,91 @@ qualifier.

1991 1992 1993 -1994
class HCI_Command(HCI_Packet):
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
class HCI_Command(HCI_Packet):
     '''
     See Bluetooth spec @ Vol 2, Part E - 5.4.1 HCI Command Packet
     '''
 
     hci_packet_type = HCI_COMMAND_PACKET
+    command_names: Dict[int, str] = {}
     command_classes: Dict[int, Type[HCI_Command]] = {}
 
     @staticmethod
@@ -1971,9 +1995,9 @@ qualifier.

def inner(cls): cls.name = cls.__name__.upper() - cls.op_code = key_with_value(HCI_COMMAND_NAMES, cls.name) + cls.op_code = key_with_value(cls.command_names, cls.name) if cls.op_code is None: - raise KeyError(f'command {cls.name} not found in HCI_COMMAND_NAMES') + raise KeyError(f'command {cls.name} not found in command_names') cls.fields = fields cls.return_parameters_fields = return_parameters_fields @@ -1993,7 +2017,19 @@ qualifier.

return inner @staticmethod - def from_bytes(packet): + def command_map(symbols: Dict[str, Any]) -> Dict[int, str]: + return { + command_code: command_name + for (command_name, command_code) in symbols.items() + if command_name.startswith('HCI_') and command_name.endswith('_COMMAND') + } + + @classmethod + def register_commands(cls, symbols: Dict[str, Any]) -> None: + cls.command_names.update(cls.command_map(symbols)) + + @staticmethod + def from_bytes(packet: bytes) -> HCI_Command: op_code, length = struct.unpack_from('<HB', packet, 1) parameters = packet[4:] if len(parameters) != length: @@ -2012,11 +2048,11 @@ qualifier.

HCI_Object.init_from_bytes(self, parameters, 0, fields) return self - return cls.from_parameters(parameters) + return cls.from_parameters(parameters) # type: ignore @staticmethod def command_name(op_code): - name = HCI_COMMAND_NAMES.get(op_code) + name = HCI_Command.command_names.get(op_code) if name is not None: return name return f'[OGF=0x{op_code >> 10:02x}, OCF=0x{op_code & 0x3FF:04x}]' @@ -2025,6 +2061,16 @@ qualifier.

def create_return_parameters(cls, **kwargs): return HCI_Object(cls.return_parameters_fields, **kwargs) + @classmethod + def parse_return_parameters(cls, parameters): + if not cls.return_parameters_fields: + return None + return_parameters = HCI_Object.from_bytes( + parameters, 0, cls.return_parameters_fields + ) + return_parameters.fields = cls.return_parameters_fields + return return_parameters + def __init__(self, op_code, parameters=None, **kwargs): super().__init__(HCI_Command.command_name(op_code)) if (fields := getattr(self, 'fields', None)) and kwargs: @@ -2087,34 +2133,34 @@ qualifier.

Source code in bumble/hci.py -
1906
-1907
-1908
-1909
-1910
-1911
-1912
-1913
-1914
-1915
-1916
-1917
-1918
-1919
-1920
-1921
-1922
-1923
-1924
-1925
-1926
-1927
-1928
-1929
-1930
-1931
-1932
-1933
@staticmethod
+        
1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
@staticmethod
 def command(fields=(), return_parameters_fields=()):
     '''
     Decorator used to declare and register subclasses
@@ -2122,9 +2168,9 @@ qualifier.

def inner(cls): cls.name = cls.__name__.upper() - cls.op_code = key_with_value(HCI_COMMAND_NAMES, cls.name) + cls.op_code = key_with_value(cls.command_names, cls.name) if cls.op_code is None: - raise KeyError(f'command {cls.name} not found in HCI_COMMAND_NAMES') + raise KeyError(f'command {cls.name} not found in command_names') cls.fields = fields cls.return_parameters_fields = return_parameters_fields @@ -2171,16 +2217,16 @@ qualifier.

Source code in bumble/hci.py -
2037
-2038
-2039
-2040
-2041
-2042
-2043
-2044
-2045
-2046
@HCI_Command.command(
+          
2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
@HCI_Command.command(
     [
         ('connection_handle', 2),
         ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}),
diff --git a/downloads/zephyr/hci_usb.zip b/downloads/zephyr/hci_usb.zip
new file mode 100644
index 0000000..5e1dfc9
Binary files /dev/null and b/downloads/zephyr/hci_usb.zip differ
diff --git a/sitemap.xml.gz b/sitemap.xml.gz
index d3e3c18..450de87 100644
Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ
diff --git a/transports/ws_client.html b/transports/ws_client.html
index ab2a8ed..e9e8fd0 100644
--- a/transports/ws_client.html
+++ b/transports/ws_client.html
@@ -63,7 +63,7 @@
     
- + Skip to content @@ -1350,14 +1350,14 @@ -

UDP TRANSPORT

-

The UDP transport is a UDP socket, receiving packets on a specified port number, and sending packets to a specified host and port number.

+

WEBSOCKET CLIENT TRANSPORT

+

The WebSocket Client transport is WebSocket connection to a WebSocket server over which HCI packets +are sent and received.

Moniker

-

The moniker syntax for a UDP transport is: udp:<local-host>:<local-port>,<remote-host>:<remote-port>.

+

The moniker syntax for a WebSocket Client transport is: ws-client:<ws-url>

Example

-

udp:0.0.0.0:9000,127.0.0.1:9001 -UDP transport where packets are received on port 9000 and sent to 127.0.0.1 on port 9001

+

ws-client:ws://localhost:1234/some/path

diff --git a/transports/ws_server.html b/transports/ws_server.html index 35223f0..2413a46 100644 --- a/transports/ws_server.html +++ b/transports/ws_server.html @@ -63,7 +63,7 @@
- + Skip to content @@ -1350,14 +1350,15 @@ -

UDP TRANSPORT

-

The UDP transport is a UDP socket, receiving packets on a specified port number, and sending packets to a specified host and port number.

+

WEBSOCKET SERVER TRANSPORT

+

The WebSocket Server transport is WebSocket server that accepts connections from a WebSocket +client. HCI packets are sent and received over the connection.

Moniker

-

The moniker syntax for a UDP transport is: udp:<local-host>:<local-port>,<remote-host>:<remote-port>.

+

The moniker syntax for a WebSocket Server transport is: ws-server:<host>:<port>, +where <host> may be the address of a local network interface, or _to accept connections on all local network interfaces. <port> is the TCP port number on which to accept connections.

Example

-

udp:0.0.0.0:9000,127.0.0.1:9001 -UDP transport where packets are received on port 9000 and sent to 127.0.0.1 on port 9001

+

ws-server:_:9001