from flask import Response from flask import Flask from flask import render_template from flask import request import threading import argparse import datetime import time import json from hidkeycodes import hidkeycodes from jskeycodes import jskeycodes lock = threading.Lock() # initialize a flask object app = Flask(__name__) NULL = chr(0) hiddev = None def hid_init(): global hiddev hiddev=open('/dev/hidg0', 'rb+') def hid_write(data): if hiddev is None: return False hiddev.write(data.encode()) hiddev.flush() def send_key(hidkey, shift, alt, ctlr, superkey): # TODO handle mod keys hid_write(NULL*2+chr(hidkey)+NULL*5) hid_write(NULL*8) def get_hid_by_jscode(rawkeycode): hidkeycode = None hidkeyname = None if rawkeycode in jskeycodes.values(): hidkeyname = list(jskeycodes.keys())[list(jskeycodes.values()).index(rawkeycode)] 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)) print ("JS key: {} HID key: {}({})".format(rawkeycode, hidkeyname, hidkeycode)) return hidkeycode @app.route("/") def index(): return render_template("hid.html") @app.route("/hid/keyboard", methods=["POST"]) def keypress(): keyevent = json.loads(request.data) print ("Raw data: {}".format(request.data)) rawkeycode = keyevent['code'] hidkeycode = get_hid_by_jscode(rawkeycode) if hidkeycode is not None: try: send_key( hidkeycode, keyevent['shiftKey'], keyevent['altKey'], keyevent['ctrlKey'], False) except Exception as e: print("Error sending HID message", e) return Response("Press {}".format(hidkeycode), mimetype = "text/plain") # check to see if this is the main thread of execution if __name__ == '__main__': # 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()) hid_init() app.run(host=args["ip"], port=args["port"], debug=True, threaded=True, use_reloader=False) # Clean up if hiddev is not None: print("Closing hid") hiddev.close()