usbbluetooth 0.0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- usbbluetooth-0.0.6/.gitignore +8 -0
- usbbluetooth-0.0.6/MANIFEST.in +1 -0
- usbbluetooth-0.0.6/PKG-INFO +3 -0
- usbbluetooth-0.0.6/meson.build +11 -0
- usbbluetooth-0.0.6/pyproject.toml +11 -0
- usbbluetooth-0.0.6/setup.cfg +4 -0
- usbbluetooth-0.0.6/usbbluetooth/__init__.py +4 -0
- usbbluetooth-0.0.6/usbbluetooth/_c_library.py +97 -0
- usbbluetooth-0.0.6/usbbluetooth/core.py +123 -0
- usbbluetooth-0.0.6/usbbluetooth/lib/__init__.py +0 -0
- usbbluetooth-0.0.6/usbbluetooth/lib/libusbbluetooth.dll +0 -0
- usbbluetooth-0.0.6/usbbluetooth/lib/libusbbluetooth.dylib +0 -0
- usbbluetooth-0.0.6/usbbluetooth/lib/libusbbluetooth.so +0 -0
- usbbluetooth-0.0.6/usbbluetooth/log.py +11 -0
- usbbluetooth-0.0.6/usbbluetooth.egg-info/PKG-INFO +3 -0
- usbbluetooth-0.0.6/usbbluetooth.egg-info/SOURCES.txt +16 -0
- usbbluetooth-0.0.6/usbbluetooth.egg-info/dependency_links.txt +1 -0
- usbbluetooth-0.0.6/usbbluetooth.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include usbbluetooth/lib/*.dll usbbluetooth/lib/*.so usbbluetooth/lib/*.dylib
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
python3 = import('python').find_installation('python3', required: false)
|
|
2
|
+
|
|
3
|
+
if not python3.found()
|
|
4
|
+
warning('Python bindings are disabled because Python 3 could not be found')
|
|
5
|
+
else
|
|
6
|
+
custom_target('usbbluetooth_python',
|
|
7
|
+
build_by_default: false,
|
|
8
|
+
install: false,
|
|
9
|
+
command: [python3, '-m', 'build', meson.current_source_dir(), '-o', meson.current_build_dir()],
|
|
10
|
+
output: ['usbbluetooth-'+meson.project_version()+'.tar.gz', 'usbbluetooth-'+meson.project_version()+'-py3-none-any.whl'])
|
|
11
|
+
endif
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import ctypes
|
|
5
|
+
from enum import IntEnum
|
|
6
|
+
from importlib.resources import files
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _lib_name() -> str:
|
|
10
|
+
'''
|
|
11
|
+
Returns an string with the expected library name for the current platform.
|
|
12
|
+
'''
|
|
13
|
+
lib_names = {
|
|
14
|
+
'darwin': 'libusbbluetooth.dylib',
|
|
15
|
+
'win32': 'libusbbluetooth.dll',
|
|
16
|
+
'linux': 'libusbbluetooth.so'
|
|
17
|
+
}
|
|
18
|
+
return lib_names.get(sys.platform, 'libusbbluetooth.so')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _load_lib():
|
|
22
|
+
'''
|
|
23
|
+
Attempt to load a library from package resources.
|
|
24
|
+
'''
|
|
25
|
+
library_path = files('usbbluetooth.lib').joinpath(_lib_name())
|
|
26
|
+
try:
|
|
27
|
+
return ctypes.cdll.LoadLibrary(str(library_path))
|
|
28
|
+
except OSError as e:
|
|
29
|
+
print(e)
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Attempt to load the corresponding C library...
|
|
34
|
+
_lib = _load_lib()
|
|
35
|
+
if _lib is None:
|
|
36
|
+
raise ImportError(
|
|
37
|
+
"ERROR: Failed to load the dynamic library for usbbluetooth.")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class _CStatus(IntEnum):
|
|
41
|
+
OK = 0
|
|
42
|
+
ERR_UNK = -1,
|
|
43
|
+
ERR_NOMEM = -2,
|
|
44
|
+
ERR_DEVICE_CLOSED = -3,
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class _CDevice(ctypes.Structure):
|
|
48
|
+
_fields_ = (("ref_count", ctypes.c_uint8),
|
|
49
|
+
("type", ctypes.c_int),
|
|
50
|
+
("device", ctypes.c_voidp),
|
|
51
|
+
("context", ctypes.c_voidp))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _setup_func(lib, fname, restype, argtypes) -> None:
|
|
55
|
+
'''
|
|
56
|
+
Setup function type info. Export as global.
|
|
57
|
+
'''
|
|
58
|
+
try:
|
|
59
|
+
method = getattr(lib, fname)
|
|
60
|
+
method.restype = restype
|
|
61
|
+
method.argtypes = argtypes
|
|
62
|
+
globals()[fname] = method
|
|
63
|
+
except AttributeError:
|
|
64
|
+
raise ImportError(
|
|
65
|
+
f"ERROR: Fail to setup '{fname}' function prototype. Make sure you are loading the correct library version.")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# Actual function prototypes...
|
|
69
|
+
_setup_func(_lib, "usbbluetooth_init", _CStatus, None)
|
|
70
|
+
_setup_func(_lib, "usbbluetooth_exit", None, None)
|
|
71
|
+
_setup_func(_lib, "usbbluetooth_get_device_list", _CStatus,
|
|
72
|
+
[ctypes.POINTER(ctypes.POINTER(ctypes.POINTER(_CDevice)))])
|
|
73
|
+
_setup_func(_lib, "usbbluetooth_free_device_list", None,
|
|
74
|
+
[ctypes.POINTER(ctypes.POINTER(ctypes.POINTER(_CDevice)))])
|
|
75
|
+
_setup_func(_lib, "usbbluetooth_reference_device", ctypes.POINTER(_CDevice),
|
|
76
|
+
[ctypes.POINTER(_CDevice)])
|
|
77
|
+
_setup_func(_lib, "usbbluetooth_unreference_device", None,
|
|
78
|
+
[ctypes.POINTER(ctypes.POINTER(_CDevice))])
|
|
79
|
+
_setup_func(_lib, "usbbluetooth_device_vid_pid", None,
|
|
80
|
+
[ctypes.POINTER(_CDevice), ctypes.POINTER(ctypes.c_uint16), ctypes.POINTER(ctypes.c_uint16)])
|
|
81
|
+
_setup_func(_lib, "usbbluetooth_device_manufacturer", ctypes.c_char_p,
|
|
82
|
+
[ctypes.POINTER(_CDevice)])
|
|
83
|
+
_setup_func(_lib, "usbbluetooth_device_product", ctypes.c_char_p,
|
|
84
|
+
[ctypes.POINTER(_CDevice)])
|
|
85
|
+
_setup_func(_lib, "usbbluetooth_device_serial_num", ctypes.c_char_p,
|
|
86
|
+
[ctypes.POINTER(_CDevice)])
|
|
87
|
+
_setup_func(_lib, "usbbluetooth_device_description", ctypes.c_char_p,
|
|
88
|
+
[ctypes.POINTER(_CDevice)])
|
|
89
|
+
_setup_func(_lib, "usbbluetooth_open", _CStatus,
|
|
90
|
+
[ctypes.POINTER(_CDevice)])
|
|
91
|
+
_setup_func(_lib, "usbbluetooth_close", None,
|
|
92
|
+
[ctypes.POINTER(_CDevice)])
|
|
93
|
+
_setup_func(_lib, "usbbluetooth_write", _CStatus,
|
|
94
|
+
[ctypes.POINTER(_CDevice), ctypes.POINTER(ctypes.c_uint8), ctypes.c_uint16])
|
|
95
|
+
_setup_func(_lib, "usbbluetooth_read", _CStatus,
|
|
96
|
+
[ctypes.POINTER(_CDevice), ctypes.POINTER(ctypes.c_uint8), ctypes.POINTER(ctypes.c_uint16)])
|
|
97
|
+
_setup_func(_lib, "usbbluetooth_log_set_level", None, [ctypes.c_int])
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
import ctypes
|
|
4
|
+
from usbbluetooth import _c_library
|
|
5
|
+
from usbbluetooth.log import LogLevel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _check_status(status: _c_library._CStatus):
|
|
9
|
+
'''
|
|
10
|
+
Check an status and raise error if needed
|
|
11
|
+
'''
|
|
12
|
+
if status == _c_library._CStatus.OK:
|
|
13
|
+
return
|
|
14
|
+
elif status == _c_library._CStatus.ERR_UNK:
|
|
15
|
+
raise Exception("Unknown error!")
|
|
16
|
+
elif status == _c_library._CStatus.ERR_NOMEM:
|
|
17
|
+
raise Exception("Out of memory error!")
|
|
18
|
+
elif status == _c_library._CStatus.ERR_DEVICE_CLOSED:
|
|
19
|
+
raise Exception("Device closed!")
|
|
20
|
+
else:
|
|
21
|
+
raise Exception("Undocumented error!")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class _UsbBluetoothContext():
|
|
25
|
+
'''
|
|
26
|
+
Handle USB context creation and destruction.
|
|
27
|
+
'''
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
_check_status(_c_library.usbbluetooth_init())
|
|
31
|
+
|
|
32
|
+
def __del__(self):
|
|
33
|
+
_c_library.usbbluetooth_exit()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class UsbBluetoothDevice():
|
|
37
|
+
'''
|
|
38
|
+
USB Bluetooth device.
|
|
39
|
+
'''
|
|
40
|
+
|
|
41
|
+
def __init__(self, ctx: _UsbBluetoothContext, dev: ctypes.POINTER(_c_library._CDevice)):
|
|
42
|
+
self._ctx = ctx
|
|
43
|
+
self._dev = _c_library.usbbluetooth_reference_device(dev)
|
|
44
|
+
|
|
45
|
+
def __del__(self):
|
|
46
|
+
_c_library.usbbluetooth_unreference_device(ctypes.byref(self._dev))
|
|
47
|
+
|
|
48
|
+
def open(self):
|
|
49
|
+
_check_status(_c_library.usbbluetooth_open(self._dev))
|
|
50
|
+
|
|
51
|
+
def close(self):
|
|
52
|
+
_c_library.usbbluetooth_close(self._dev)
|
|
53
|
+
|
|
54
|
+
def __enter__(self):
|
|
55
|
+
self.open()
|
|
56
|
+
return self
|
|
57
|
+
|
|
58
|
+
def __exit__(self, type, value, tb):
|
|
59
|
+
self.close()
|
|
60
|
+
|
|
61
|
+
def __repr__(self):
|
|
62
|
+
return f"UsbBluetoothDevice[{self.get_description()}]"
|
|
63
|
+
|
|
64
|
+
def write(self, data: bytearray):
|
|
65
|
+
_check_status(_c_library.usbbluetooth_write(
|
|
66
|
+
self._dev, ctypes.cast(ctypes.c_char_p(data), ctypes.POINTER(ctypes.c_uint8)), len(data)))
|
|
67
|
+
|
|
68
|
+
def read(self, bufsize=64):
|
|
69
|
+
data = (ctypes.c_uint8 * bufsize)()
|
|
70
|
+
datalen = ctypes.c_uint16(bufsize)
|
|
71
|
+
_check_status(_c_library.usbbluetooth_read(self._dev, data, datalen))
|
|
72
|
+
return bytearray(data[0:datalen.value])
|
|
73
|
+
|
|
74
|
+
def get_vid_pid(self) -> tuple[int, int]:
|
|
75
|
+
vid = ctypes.c_uint16()
|
|
76
|
+
pid = ctypes.c_uint16()
|
|
77
|
+
_c_library.usbbluetooth_device_vid_pid(
|
|
78
|
+
self._dev, ctypes.byref(vid), ctypes.byref(pid))
|
|
79
|
+
return (vid.value, pid.value)
|
|
80
|
+
|
|
81
|
+
def get_manufacturer(self) -> str:
|
|
82
|
+
manuf_c = _c_library.usbbluetooth_device_manufacturer(self._dev)
|
|
83
|
+
ret = manuf_c.decode() if manuf_c else None
|
|
84
|
+
return ret
|
|
85
|
+
|
|
86
|
+
def get_product(self) -> str:
|
|
87
|
+
prod_c = _c_library.usbbluetooth_device_product(self._dev)
|
|
88
|
+
ret = prod_c.decode() if prod_c else None
|
|
89
|
+
return ret
|
|
90
|
+
|
|
91
|
+
def get_serial_num(self) -> str:
|
|
92
|
+
sn_c = _c_library.usbbluetooth_device_serial_num(self._dev)
|
|
93
|
+
ret = sn_c.decode() if sn_c else None
|
|
94
|
+
return ret
|
|
95
|
+
|
|
96
|
+
def get_description(self) -> str:
|
|
97
|
+
desc_c = _c_library.usbbluetooth_device_description(self._dev)
|
|
98
|
+
ret = desc_c.decode() if desc_c else None
|
|
99
|
+
return ret
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def list_devices() -> list[UsbBluetoothDevice]:
|
|
103
|
+
'''
|
|
104
|
+
List all available Bluetooth devices.
|
|
105
|
+
'''
|
|
106
|
+
ctx = _UsbBluetoothContext()
|
|
107
|
+
c_list = ctypes.POINTER(ctypes.POINTER(_c_library._CDevice))()
|
|
108
|
+
dev_list = []
|
|
109
|
+
_check_status(_c_library.usbbluetooth_get_device_list(
|
|
110
|
+
ctypes.byref(c_list)))
|
|
111
|
+
i = 0
|
|
112
|
+
while True:
|
|
113
|
+
dev_ref = c_list[i]
|
|
114
|
+
i += 1
|
|
115
|
+
if not dev_ref:
|
|
116
|
+
break
|
|
117
|
+
dev_list.append(UsbBluetoothDevice(ctx, dev_ref))
|
|
118
|
+
_c_library.usbbluetooth_free_device_list(ctypes.byref(c_list))
|
|
119
|
+
return dev_list
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def set_log_level(level: LogLevel):
|
|
123
|
+
_c_library.usbbluetooth_log_set_level(level.value)
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.gitignore
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
meson.build
|
|
4
|
+
pyproject.toml
|
|
5
|
+
usbbluetooth/__init__.py
|
|
6
|
+
usbbluetooth/_c_library.py
|
|
7
|
+
usbbluetooth/core.py
|
|
8
|
+
usbbluetooth/log.py
|
|
9
|
+
usbbluetooth.egg-info/PKG-INFO
|
|
10
|
+
usbbluetooth.egg-info/SOURCES.txt
|
|
11
|
+
usbbluetooth.egg-info/dependency_links.txt
|
|
12
|
+
usbbluetooth.egg-info/top_level.txt
|
|
13
|
+
usbbluetooth/lib/__init__.py
|
|
14
|
+
usbbluetooth/lib/libusbbluetooth.dll
|
|
15
|
+
usbbluetooth/lib/libusbbluetooth.dylib
|
|
16
|
+
usbbluetooth/lib/libusbbluetooth.so
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
usbbluetooth
|