threebrooks / UniversalController

Bluetooth-connected keyboard via Android app
20 stars 0 forks source link

Failed to start blutooth keyboard #2

Open mcpeixoto opened 5 years ago

mcpeixoto commented 5 years ago

Hello there! First of all, love your project!

I'm having this issue: whatsapp image 2018-12-17 at 9 29 42 pm

The script went into some problems, I had to install python-uinput with this mini tutorial: https://stackoverflow.com/questions/29766818/cannot-install-uinput-on-raspberry-pi

But I fanally manage to do a clean run of the script: ``pi@retropie:~/UniversalController/linux $ sudo ./install.sh

Installing dependencies

Reading package lists... Done Building dependency tree Reading state information... Done Note, selecting 'python-bluez' instead of 'python-bluetooth' bluez-tools is already the newest version (0.2.0~20140808-5). python-bluez is already the newest version (0.22-1). bluetooth is already the newest version (5.43-2+rpt2+deb9u2). bluez is already the newest version (5.43-2+rpt2+deb9u2). bluez-firmware is already the newest version (1.2-3+rpt6). python-pip is already the newest version (9.0.1-2+rpt2). 0 upgraded, 0 newly installed, 0 to remove and 11 not upgraded. Requirement already satisfied: python-uinput in /usr/local/lib/python2.7/dist-packages

Enabling bluetooth service

Synchronizing state of bluetooth.service with SysV service script with /lib/systemd/systemd-sysv-install. Executing: /lib/systemd/systemd-sysv-install enable bluetooth Created symlink /etc/systemd/system/dbus-org.bluez.service → /lib/systemd/system/bluetooth.service.

Stopping bluetooth service

Patching bluez service to be backward compatible

Adding SP

Serial Port service registered

Restarting bluetooth service

Adding modules to /etc/modules

Installing BluetoothKeyboard service

``

Well, what do I do?

ghost commented 5 years ago

Hi acujl,

what does "systemctl status BluetoothKeyboard.service" report when you run it?

mcpeixoto commented 5 years ago

Hello there, thanks for the reply!!

Here's the output: `pi@retropie:~ $ systemctl status BluetoothKeyboard.service ● BluetoothKeyboard.service - Bluetooth keyboard Loaded: loaded (/lib/systemd/system/BluetoothKeyboard.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Fri 2018-12-21 22:59:04 UTC; 1min 49s ago Process: 604 ExecStart=/usr/bin/python /usr/bin/BluetoothKeyboard.py (code=exited, status=1/FAILURE) Main PID: 604 (code=exited, status=1/FAILURE)

Dec 21 22:59:04 retropie systemd[1]: BluetoothKeyboard.service: Failed with result 'exit-code'. Dec 21 22:59:04 retropie systemd[1]: BluetoothKeyboard.service: Service hold-off time over, scheduling restart. Dec 21 22:59:04 retropie systemd[1]: Stopped Bluetooth keyboard. Dec 21 22:59:04 retropie systemd[1]: BluetoothKeyboard.service: Start request repeated too quickly. Dec 21 22:59:04 retropie systemd[1]: Failed to start Bluetooth keyboard. Dec 21 22:59:04 retropie systemd[1]: BluetoothKeyboard.service: Unit entered failed state. Dec 21 22:59:04 retropie systemd[1]: BluetoothKeyboard.service: Failed with result 'exit-code'.`

And even when I try to manually start it.. :/

`pi@retropie:~ $ sudo systemctl start BluetoothKeyboard.service pi@retropie:~ $ systemctl status BluetoothKeyboard.service ● BluetoothKeyboard.service - Bluetooth keyboard Loaded: loaded (/lib/systemd/system/BluetoothKeyboard.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Fri 2018-12-21 23:01:51 UTC; 6s ago Process: 880 ExecStart=/usr/bin/python /usr/bin/BluetoothKeyboard.py (code=exited, status=1/FAILURE) Main PID: 880 (code=exited, status=1/FAILURE)

Dec 21 23:01:50 retropie systemd[1]: BluetoothKeyboard.service: Failed with result 'exit-code'. Dec 21 23:01:51 retropie systemd[1]: BluetoothKeyboard.service: Service hold-off time over, scheduling restart. Dec 21 23:01:51 retropie systemd[1]: Stopped Bluetooth keyboard. Dec 21 23:01:51 retropie systemd[1]: BluetoothKeyboard.service: Start request repeated too quickly. Dec 21 23:01:51 retropie systemd[1]: Failed to start Bluetooth keyboard. Dec 21 23:01:51 retropie systemd[1]: BluetoothKeyboard.service: Unit entered failed state. Dec 21 23:01:51 retropie systemd[1]: BluetoothKeyboard.service: Failed with result 'exit-code'.`

ghost commented 5 years ago

Hi there, sorry for the delay.

I just had a look at the script, but it will be hard for me to figure out where exactly it craps out without debugging information.

Can you try to run the script manually via sudo /usr/bin/python /usr/bin/BluetoothKeyboard.py

and see what line it fails at?

mcpeixoto commented 5 years ago

Here you go:

pi@retropie:~ $ sudo /usr/bin/python /usr/bin/BluetoothKeyboard.py
Traceback (most recent call last):
  File "/usr/bin/BluetoothKeyboard.py", line 3, in <module>
    import uinput
  File "/usr/local/lib/python2.7/dist-packages/uinput/__init__.py", line 42, in <module>
    _ABS_CNT = ABS_MAX[1] + 1
NameError: name 'ABS_MAX' is not defined

Also tried with python 3

pi@retropie:~ $ sudo python3 /usr/bin/BluetoothKeyboard.py
  File "/usr/bin/BluetoothKeyboard.py", line 114
    print "Emitting mouse move "+str(js['x'])+","+str(js['y'])
                               ^
SyntaxError: invalid syntax

Tried to install uinput via pip (again) and same error that I got previouslly:

pi@retropie:~ $ pip install uinput
Collecting uinput
Exception:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 353, in run
    wb.build(autobuilding=True)
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 749, in build
    self.requirement_set.prepare_files(self.finder)
  File "/usr/lib/python2.7/dist-packages/pip/req/req_set.py", line 380, in prepare_files
    ignore_dependencies=self.ignore_dependencies))
  File "/usr/lib/python2.7/dist-packages/pip/req/req_set.py", line 554, in _prepare_file
    require_hashes
  File "/usr/lib/python2.7/dist-packages/pip/req/req_install.py", line 278, in populate_link
    self.link = finder.find_requirement(self, upgrade)
  File "/usr/lib/python2.7/dist-packages/pip/index.py", line 465, in find_requirement
    all_candidates = self.find_all_candidates(req.name)
  File "/usr/lib/python2.7/dist-packages/pip/index.py", line 423, in find_all_candidates
    for page in self._get_pages(url_locations, project_name):
  File "/usr/lib/python2.7/dist-packages/pip/index.py", line 568, in _get_pages
    page = self._get_page(location)
  File "/usr/lib/python2.7/dist-packages/pip/index.py", line 683, in _get_page
    return HTMLPage.get_page(link, session=self.session)
  File "/usr/lib/python2.7/dist-packages/pip/index.py", line 792, in get_page
    "Cache-Control": "max-age=600",
  File "/usr/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 501, in get
    return self.request('GET', url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/pip/download.py", line 386, in request
    return super(PipSession, self).request(method, url, *args, **kwargs)
  File "/usr/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/sessions.py", line 609, in send
    r = adapter.send(request, **kwargs)
  File "/usr/share/python-wheels/CacheControl-0.11.7-py2.py3-none-any.whl/cachecontrol/adapter.py", line 47, in send
    resp = super(CacheControlAdapter, self).send(request, **kw)
  File "/usr/share/python-wheels/requests-2.12.4-py2.py3-none-any.whl/requests/adapters.py", line 423, in send
    timeout=timeout
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/connectionpool.py", line 643, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/share/python-wheels/urllib3-1.19.1-py2.py3-none-any.whl/urllib3/util/retry.py", line 315, in increment
    total -= 1
TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'
mcpeixoto commented 5 years ago

So here's what I did.

Installed pip3 sudo apt-get install python3-pip Installed uinput and pybluez, maybe you will need a proxy too! sudo pip3 install python-uinput pybluez

Transformed the /usr/bin/BluetoothKeyboard.py from python2 to python3 Here's the code:

#!/usr/bin/python

import uinput
import subprocess
import sys, inspect
import json
import subprocess
import time
from bluetooth import *

APP_VERSION = "1.0.0"

uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"

time.sleep(5)

def getAllKeys():
  out = []
  for name, obj in inspect.getmembers(uinput):
    if ((name.upper() == name) and (not name.startswith("_")) and (not name.startswith("ABS_"))):
      out.append(obj)
  out.append(uinput.ABS_X+(0, 255, 0, 0))
  out.append(uinput.ABS_Y+(0, 255, 0, 0))
  return out

device = uinput.Device(getAllKeys())

subprocess.call(['systemctl','restart','bluetooth'])

server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)

port = server_sock.getsockname()[1]

advertise_service( server_sock, "RetroPieController",
        service_id = uuid,
        service_classes = [ uuid, SERIAL_PORT_CLASS ],
        profiles = [ SERIAL_PORT_PROFILE ],
        #                   protocols = [ OBEX_UUID ]
        )

client_sock = None
client_info = None

xAccum = 0
yAccum = 0
lastXInt = 0
lastYInt = 0
while True:
    try:
        print("Making discoverable")
        ps = subprocess.Popen(('bluetoothctl'), stdin=subprocess.PIPE)
        ps.communicate('power on\npairable on\ndiscoverable on\nagent NoInputNoOutput\ndefault-agent\n\nexit\n')
        print("Waiting for connection")
        server_sock.settimeout(60)
        client_sock, client_info = server_sock.accept()
        print(("Accepted connection from "+ str(client_info)))

        client_sock.send(APP_VERSION)

        while True:
            msgLengthString = ""
            while True:
              c = client_sock.recv(1)
              if len(c) == 0: continue
              if (c[0] == ":"): break
              msgLengthString += c[0]
            #print "Msg: '"+msgLengthString+"'"
            msgLength = int(msgLengthString)
            pulledMsgLength = 0
            data = []
            while True:
              c = client_sock.recv(msgLength-pulledMsgLength)
              if len(c) == 0: continue
              data += c
              pulledMsgLength = pulledMsgLength + len(c)
              if (pulledMsgLength == msgLength): break
            msg = "".join(data)
            for msgString in msg.split("@@@"):
              if (msgString == ""): continue
            #print msgString
              js = json.loads(msgString)
              type = js['type']
              if (type == "KEY"):
                if (js['pressed'] == "true"):
                  press = 1
                else:
                  press = 0
                for keyStringEl in js['keylist'].split("|"):
                  if (keyStringEl == "HEARTBEAT"): continue
                  key = getattr(uinput, keyStringEl);
                  #print "Emitting "+keyStringEl
                  device.emit(key, press)
              elif (type == "MOUSE"):
                #print str(js['absrel'])
                if (js['absrel'] == "REL"):
                  xAccum += js['dx']
                  yAccum += js['dy']
                  xError = xAccum-lastXInt
                  yError = yAccum-lastYInt
                  if (abs(xError) > 0.5 or abs(yError) > 0.5):
                    newX = int(round(xAccum))
                    newY = int(round(yAccum))
                    deltaX = newX-lastXInt
                    deltaY = newY-lastYInt
                    if (deltaX != 0 or deltaY != 0):
                      #print "Emitting mouse move "+str(deltaX)+","+str(deltaY)
                      device.emit(uinput.REL_X, newX-lastXInt, syn=False)
                      device.emit(uinput.REL_Y, newY-lastYInt)
                      lastXInt = newX
                      lastYInt = newY
                elif (js['absrel'] == "ABS"):
                  print("Emitting mouse move "+str(js['x'])+","+str(js['y']))
                  device.emit(uinput.ABS_X, int(js['x']), syn=False)
                  device.emit(uinput.ABS_Y, int(js['y']))

    except:
        print(("Lost connection\n"+str(sys.exc_info()[0])+"\n"+str(sys.exc_info()[2].tb_lineno)))
        if (client_sock != None): client_sock.close()
        #sys.exit(-1)
        continue

server_sock.close()

Tried to run it andddd............

pi@retropie:~ $ sudo python3 /usr/bin/BluetoothKeyboard.py
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/bluetooth/bluez.py", line 240, in advertise_service
    protocols)
_bluetooth.error: (111, 'Connection refused')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/BluetoothKeyboard.py", line 39, in <module>
    profiles = [ SERIAL_PORT_PROFILE ],
  File "/usr/local/lib/python3.5/dist-packages/bluetooth/bluez.py", line 242, in advertise_service
    raise BluetoothError (str (e))
bluetooth.btcommon.BluetoothError: (111, 'Connection refused')