-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbluetooth_server.py
More file actions
91 lines (69 loc) · 2.78 KB
/
bluetooth_server.py
File metadata and controls
91 lines (69 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/python3
"""
Bluetooth HID keyboard emulator DBUS Service
Original idea taken from: http://yetanotherpointlesstechblog.blogspot.com/2016/04/emulating-bluetooth-keyboard-with.html
Rewritten and improved by: https://gist.github.com/ukBaz/a47e71e7b87fbc851b27cde7d1c0fcf0
Simplified and shortened by @MsmCode
"""
import os
import dbus
import time
import socket
from socket import AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP
from keycodes import char_to_keycode
from pathlib import Path
PROFILE_DBUS_PATH = "/bluez/msm/bluekeyboard" # Profile path
P_CTRL = 17 # Control port (configured in SDP record)
P_INTR = 19 # Interrupt port (Configured in SDP record#Interrrupt port)
# UUID for HID service (1124)
# https://www.bluetooth.com/specifications/assigned-numbers/service-discovery
UUID = "00001124-0000-1000-8000-00805f9b34fb"
def send_char(char, cinterrupt):
keycode, shift = char_to_keycode(char)
modkey = (1 << 6) if shift else 0
cinterrupt.send(bytes([0xA1, 1, modkey, 0, keycode, 0, 0, 0, 0, 0]))
time.sleep(0.01)
cinterrupt.send(bytes([0xA1, 1, 0, 0, 0, 0, 0, 0, 0, 0]))
time.sleep(0.01)
def bluetooth_connect():
bus = dbus.SystemBus()
print("Registering the profile...")
opts = {
"Role": "server",
"RequireAuthentication": False,
"RequireAuthorization": False,
"AutoConnect": True,
"ServiceRecord": (Path(__file__).parent / "service.xml").read_text(),
}
bluez = bus.get_object("org.bluez", "/org/bluez")
manager = dbus.Interface(bluez, "org.bluez.ProfileManager1")
manager.RegisterProfile(PROFILE_DBUS_PATH, UUID, opts)
print("Waiting for connections...")
hci0 = bus.get_object("org.bluez", "/org/bluez/hci0")
adapter_property = dbus.Interface(hci0, "org.freedesktop.DBus.Properties")
address = adapter_property.Get("org.bluez.Adapter1", "Address")
scontrol = socket.socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)
scontrol.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
scontrol.bind((address, P_CTRL))
scontrol.listen(1)
sinterrupt = socket.socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)
sinterrupt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sinterrupt.bind((address, P_INTR))
sinterrupt.listen(1)
scontrol, sinfo = scontrol.accept()
print(f"Connected on the control socket {sinfo[0]}")
cinterrupt, cinfo = sinterrupt.accept()
print(f"Connected on the interrupt channel {cinfo[0]}")
return cinterrupt
def main():
assert os.geteuid() == 0 # This won't work without root
cinterrupt = bluetooth_connect()
try:
while True:
text = input()
for c in text + "\n":
send_char(c, cinterrupt)
finally:
cinterrupt.close()
if __name__ == "__main__":
main()