2020-05-24 11:08:49 +02:00
|
|
|
from flask import Response
|
|
|
|
from flask import Flask
|
|
|
|
from flask import render_template
|
2020-05-24 12:44:34 +02:00
|
|
|
from flask import request
|
2020-06-05 16:32:24 +02:00
|
|
|
from flask_socketio import SocketIO
|
2020-05-24 11:08:49 +02:00
|
|
|
import argparse
|
2020-05-24 12:44:34 +02:00
|
|
|
import json
|
|
|
|
|
|
|
|
from hidkeycodes import hidkeycodes
|
2020-06-04 13:43:51 +02:00
|
|
|
from jskeycodes import jscodehidmap
|
2020-05-24 12:44:34 +02:00
|
|
|
|
2020-05-24 11:08:49 +02:00
|
|
|
|
|
|
|
# initialize a flask object
|
|
|
|
app = Flask(__name__)
|
2020-06-05 16:32:24 +02:00
|
|
|
socketio = SocketIO(app)
|
2020-05-24 11:08:49 +02:00
|
|
|
|
|
|
|
hiddev = None
|
2020-06-05 15:04:27 +02:00
|
|
|
hidmouseabs = None
|
2020-05-24 11:08:49 +02:00
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
|
2020-05-24 12:44:34 +02:00
|
|
|
def hid_init():
|
2020-06-05 17:17:17 +02:00
|
|
|
global hiddev, hidmouseabs
|
2020-06-04 13:50:01 +02:00
|
|
|
hiddev = open('/dev/hidg0', 'rb+')
|
2020-06-05 17:17:17 +02:00
|
|
|
hidmouseabs = open('/dev/hidg1', 'rb+')
|
2020-06-04 13:50:01 +02:00
|
|
|
|
2020-05-24 11:08:49 +02:00
|
|
|
|
2020-05-24 12:44:34 +02:00
|
|
|
def hid_write(data):
|
2020-05-24 11:08:49 +02:00
|
|
|
if hiddev is None:
|
|
|
|
return False
|
|
|
|
|
2020-05-25 02:35:41 +02:00
|
|
|
hiddev.write(data)
|
2020-05-24 11:08:49 +02:00
|
|
|
hiddev.flush()
|
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
|
2020-06-05 15:04:27 +02:00
|
|
|
def hid_mouse_writeabs(btn, x, y, wheel):
|
|
|
|
if hidmouseabs is None:
|
|
|
|
return False
|
|
|
|
|
|
|
|
data = bytearray(6)
|
|
|
|
data[0] = btn
|
|
|
|
data[1:3] = x.to_bytes(2, byteorder='little')
|
|
|
|
data[3:5] = y.to_bytes(2, byteorder='little')
|
|
|
|
data[5] = wheel
|
|
|
|
|
|
|
|
hidmouseabs.write(data)
|
|
|
|
hidmouseabs.flush()
|
|
|
|
|
|
|
|
|
2020-05-25 10:14:49 +02:00
|
|
|
def send_key(hidkey, shift, alt, ctlr, mod):
|
2020-05-25 02:35:41 +02:00
|
|
|
data = bytearray(8)
|
2020-05-24 13:09:38 +02:00
|
|
|
if shift:
|
2020-05-25 02:35:41 +02:00
|
|
|
data[0] += hidkeycodes['KEY_MOD_LSHIFT']
|
2020-05-24 13:09:38 +02:00
|
|
|
if alt:
|
2020-05-25 02:35:41 +02:00
|
|
|
data[0] += hidkeycodes['KEY_MOD_LALT']
|
2020-05-24 13:09:38 +02:00
|
|
|
if ctlr:
|
2020-05-25 02:35:41 +02:00
|
|
|
data[0] += hidkeycodes['KEY_MOD_LCTRL']
|
2020-05-25 01:29:17 +02:00
|
|
|
|
2020-05-25 10:14:49 +02:00
|
|
|
if mod and (hidkey == hidkeycodes['KEY_MOD_LMETA'] or hidkey == hidkeycodes['KEY_MOD_RMETA']):
|
2020-05-25 02:35:41 +02:00
|
|
|
data[0] += hidkey
|
2020-06-04 13:50:01 +02:00
|
|
|
hidkey = 0
|
2020-05-24 13:09:38 +02:00
|
|
|
|
2020-05-25 02:35:41 +02:00
|
|
|
data[2] = hidkey
|
|
|
|
|
|
|
|
hid_write(data)
|
|
|
|
hid_write(bytearray(8))
|
2020-05-24 12:44:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_hid_by_jscode(rawkeycode):
|
|
|
|
hidkeycode = None
|
|
|
|
hidkeyname = None
|
2020-05-24 11:08:49 +02:00
|
|
|
|
2020-06-04 13:43:51 +02:00
|
|
|
if rawkeycode in jscodehidmap:
|
|
|
|
hidkeyname = jscodehidmap[rawkeycode]
|
2020-05-24 12:44:34 +02:00
|
|
|
if hidkeyname in hidkeycodes:
|
|
|
|
hidkeycode = hidkeycodes[hidkeyname]
|
|
|
|
else:
|
|
|
|
print("Code for key {} not found in HID mapping".format(hidkeyname))
|
|
|
|
else:
|
|
|
|
print("Javascript code for key {} not found".format(rawkeycode))
|
2020-05-24 11:08:49 +02:00
|
|
|
|
2020-05-24 12:44:34 +02:00
|
|
|
print ("JS key: {} HID key: {}({})".format(rawkeycode, hidkeyname, hidkeycode))
|
|
|
|
|
2020-05-25 10:14:49 +02:00
|
|
|
return hidkeycode, (hidkeyname is not None and "MOD" in hidkeyname)
|
2020-05-24 11:08:49 +02:00
|
|
|
|
2020-06-05 17:17:17 +02:00
|
|
|
|
2020-05-24 11:08:49 +02:00
|
|
|
@app.route("/")
|
|
|
|
def index():
|
2020-06-04 13:43:51 +02:00
|
|
|
return render_template("hid.html")
|
2020-05-24 11:08:49 +02:00
|
|
|
|
2020-06-07 13:38:06 +02:00
|
|
|
@app.route("/kvm.html")
|
|
|
|
def kvm():
|
|
|
|
return render_template("kvm.html")
|
|
|
|
|
2020-05-25 01:55:31 +02:00
|
|
|
@app.route("/mouse.html")
|
2020-05-25 02:35:10 +02:00
|
|
|
def mouseindex():
|
2020-06-04 13:43:51 +02:00
|
|
|
return render_template("mouse.html")
|
2020-05-25 01:55:31 +02:00
|
|
|
|
2020-06-05 17:17:17 +02:00
|
|
|
@app.route("/keyboard.html")
|
|
|
|
def keyboardIndex():
|
|
|
|
return render_template("keyboard.html")
|
2020-06-05 15:04:27 +02:00
|
|
|
|
2020-05-24 11:08:49 +02:00
|
|
|
|
2020-06-05 16:32:24 +02:00
|
|
|
@socketio.on('mouseEvent')
|
2020-06-05 16:42:23 +02:00
|
|
|
def handle_my_custom_event(data):
|
|
|
|
mouseevent = json.loads(data)
|
2020-06-05 16:32:24 +02:00
|
|
|
print(mouseevent)
|
|
|
|
btn = mouseevent['btn']
|
|
|
|
x = mouseevent['x']
|
|
|
|
y = mouseevent['y']
|
|
|
|
wheel = mouseevent['wheel']
|
2020-06-05 17:06:08 +02:00
|
|
|
wheel = wheel if wheel >= 0 else 255-abs(wheel)
|
2020-06-05 16:32:24 +02:00
|
|
|
|
|
|
|
print("X: {}, Y: {}".format(x, y))
|
|
|
|
|
|
|
|
hid_mouse_writeabs(btn, x, y, wheel)
|
|
|
|
|
2020-06-05 17:17:17 +02:00
|
|
|
|
2020-05-24 11:08:49 +02:00
|
|
|
@app.route("/hid/keyboard", methods=["POST"])
|
|
|
|
def keypress():
|
2020-05-24 12:44:34 +02:00
|
|
|
keyevent = json.loads(request.data)
|
2020-06-04 13:50:01 +02:00
|
|
|
print("Raw data: {}".format(request.data))
|
2020-05-24 12:44:34 +02:00
|
|
|
|
|
|
|
rawkeycode = keyevent['code']
|
2020-05-25 10:14:49 +02:00
|
|
|
hidkeycode, mod = get_hid_by_jscode(rawkeycode)
|
2020-05-24 12:44:34 +02:00
|
|
|
|
|
|
|
if hidkeycode is not None:
|
|
|
|
try:
|
|
|
|
send_key(
|
|
|
|
hidkeycode,
|
|
|
|
keyevent['shiftKey'],
|
|
|
|
keyevent['altKey'],
|
2020-05-25 10:14:49 +02:00
|
|
|
keyevent['ctrlKey'],
|
|
|
|
mod)
|
2020-05-24 12:44:34 +02:00
|
|
|
except Exception as e:
|
|
|
|
print("Error sending HID message", e)
|
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
return Response("Press {}".format(hidkeycode), mimetype="text/plain")
|
2020-05-24 11:08:49 +02:00
|
|
|
|
2020-06-05 17:17:17 +02:00
|
|
|
|
2020-06-05 16:42:23 +02:00
|
|
|
hid_init()
|
2020-05-24 11:08:49 +02:00
|
|
|
|
|
|
|
# check to see if this is the main thread of execution
|
|
|
|
if __name__ == '__main__':
|
2020-05-24 12:44:34 +02:00
|
|
|
# construct the argument parser and parse command line arguments
|
|
|
|
ap = argparse.ArgumentParser()
|
|
|
|
ap.add_argument("-i", "--ip", type=str, required=True,
|
|
|
|
help="ip address of the device")
|
|
|
|
ap.add_argument("-o", "--port", type=int, required=True,
|
|
|
|
help="ephemeral port number of the server (1024 to 65535)")
|
|
|
|
ap.add_argument("-f", "--frame-count", type=int, default=32,
|
|
|
|
help="# of frames used to construct the background model")
|
|
|
|
args = vars(ap.parse_args())
|
|
|
|
|
|
|
|
app.run(host=args["ip"], port=args["port"], debug=True,
|
2020-06-05 16:32:24 +02:00
|
|
|
use_reloader=False)
|