btk_server.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/usr/bin/python3
  2. #
  3. # thanhle Bluetooth keyboard/Mouse emulator DBUS Service
  4. #
  5. from __future__ import absolute_import, print_function
  6. from optparse import OptionParser, make_option
  7. import os
  8. import sys
  9. import uuid
  10. import dbus
  11. import dbus.service
  12. import dbus.mainloop.glib
  13. import time
  14. import socket
  15. from gi.repository import GLib
  16. from dbus.mainloop.glib import DBusGMainLoop
  17. import logging
  18. from logging import debug, info, warning, error
  19. import btk_dbus
  20. logging.basicConfig(level=logging.DEBUG)
  21. class BTKbDevice():
  22. # change these constants
  23. MY_ADDRESS = "BLUETOOTH_ADDRESS_PLACEHOLDER"
  24. MY_DEV_NAME = "DEVICE_NAME_PLACEHOLDER"
  25. # define some constants
  26. P_CTRL = 17 # Service port - must match port configured in SDP record
  27. P_INTR = 19 # Service port - must match port configured in SDP record#Interrrupt port
  28. # dbus path of the bluez profile we will create
  29. # file path of the sdp record to load
  30. SDP_RECORD_PATH = sys.path[0] + "/sdp_record.xml"
  31. UUID = "00001124-0000-1000-8000-00805f9b34fb"
  32. def __init__(self):
  33. self.init_bt_device()
  34. self.init_bluez_profile()
  35. # configure the bluetooth hardware device
  36. def init_bt_device(self):
  37. print("2. Start and config bluetooth device")
  38. # set the device class to a keybord and set the name
  39. os.system("hciconfig hci0 up")
  40. os.system("hciconfig hci0 class 0x0025C0")
  41. os.system("hciconfig hci0 name " + BTKbDevice.MY_DEV_NAME)
  42. print(" bluetooth name is: ", BTKbDevice.MY_DEV_NAME)
  43. # make the device discoverable
  44. os.system("hciconfig hci0 piscan")
  45. # set up a bluez profile to advertise device capabilities from a loaded service record
  46. def init_bluez_profile(self):
  47. print("3. Configuring Bluez Profile")
  48. # setup profile options
  49. service_record = self.read_sdp_service_record()
  50. opts = {
  51. "AutoConnect": True,
  52. "ServiceRecord": service_record
  53. }
  54. # retrieve a proxy for the bluez profile interface
  55. bus = dbus.SystemBus()
  56. manager = dbus.Interface(bus.get_object(
  57. "org.bluez", "/org/bluez"), "org.bluez.ProfileManager1")
  58. manager.RegisterProfile("/org/bluez/hci0", BTKbDevice.UUID, opts)
  59. print("5. Profile registered ")
  60. # read and return an sdp record from a file
  61. def read_sdp_service_record(self):
  62. print("4. Reading service record")
  63. try:
  64. fh = open(BTKbDevice.SDP_RECORD_PATH, "r")
  65. except:
  66. sys.exit("Could not open the sdp record. Exiting...")
  67. return fh.read()
  68. # listen for incoming client connections
  69. def listen(self):
  70. print("\033[0;33m7. Waiting for connections\033[0m")
  71. self.scontrol = socket.socket(
  72. socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP) # BluetoothSocket(L2CAP)
  73. self.sinterrupt = socket.socket(
  74. socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP) # BluetoothSocket(L2CAP)
  75. self.scontrol.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  76. self.sinterrupt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  77. # bind these sockets to a port - port zero to select next available
  78. self.scontrol.bind((socket.BDADDR_ANY, self.P_CTRL))
  79. self.sinterrupt.bind((socket.BDADDR_ANY, self.P_INTR))
  80. # Start listening on the server sockets
  81. self.scontrol.listen(5)
  82. self.sinterrupt.listen(5)
  83. self.ccontrol, cinfo = self.scontrol.accept()
  84. print (
  85. "\033[0;32mGot a connection on the control channel from %s \033[0m" % cinfo[0])
  86. self.cinterrupt, cinfo = self.sinterrupt.accept()
  87. print (
  88. "\033[0;32mGot a connection on the interrupt channel from %s \033[0m" % cinfo[0])
  89. # send a string to the bluetooth host machine
  90. def send_string(self, message):
  91. try:
  92. self.cinterrupt.send(bytes(message))
  93. except OSError as err:
  94. error(err)
  95. # main routine
  96. if __name__ == "__main__":
  97. # we an only run as root
  98. try:
  99. if not os.geteuid() == 0:
  100. sys.exit("Only root can run this script")
  101. DBusGMainLoop(set_as_default=True)
  102. print("1. Setting up BTK device")
  103. service = BTKbDevice()
  104. print("6. Register service to dbus")
  105. btk_dbus.BTKbService(service)
  106. service.listen()
  107. loop = GLib.MainLoop()
  108. loop.run()
  109. except KeyboardInterrupt:
  110. sys.exit()