Ejemplo n.º 1
0
    def post_init(self):
        self.devices = {}

        hid = HIDService()

        advertisement = ProvideServicesAdvertisement(hid)
        advertisement.appearance = BLE_APPEARANCE_HID_KEYBOARD
        scan_response = Advertisement()
        scan_response.complete_name = 'KMK Keyboard'

        ble = BLERadio()
        if not ble.connected:
            ble.start_advertising(advertisement, scan_response)
            while not ble.connected:
                pass

        for device in hid.devices:
            us = device.usage
            up = device.usage_page

            if up == HIDUsagePage.CONSUMER and us == HIDUsage.CONSUMER:
                self.devices[HIDReportTypes.CONSUMER] = device
                continue

            if up == HIDUsagePage.KEYBOARD and us == HIDUsage.KEYBOARD:
                self.devices[HIDReportTypes.KEYBOARD] = device
                continue

            if up == HIDUsagePage.MOUSE and us == HIDUsage.MOUSE:
                self.devices[HIDReportTypes.MOUSE] = device
                continue

            if up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL:
                self.devices[HIDReportTypes.SYSCONTROL] = device
                continue
Ejemplo n.º 2
0
    def post_init(self):
        self.ble = BLERadio()
        self.ble.name = self.ble_name
        self.hid = HIDService()
        self.hid.protocol_mode = 0  # Boot protocol

        # Security-wise this is not right. While you're away someone turns
        # on your keyboard and they can pair with it nice and clean and then
        # listen to keystrokes.
        # On the other hand we don't have LESC so it's like shouting your
        # keystrokes in the air
        if not self.ble.connected or not self.hid.devices:
            self.start_advertising()
Ejemplo n.º 3
0
def main():
    hid = HIDService()
    advertisement = ProvideServicesAdvertisement(hid)
    advertisement.appearance = 961
    ble = adafruit_ble.BLERadio()
    if ble.connected:
        for c in ble.connections:
            c.disconnect()
    ble.start_advertising(advertisement)
    advertising = True
    ble_keyboard = Keyboard(hid.devices)

    matrix = Matrix()
    usb_keyboard = Keyboard(usb_hid.devices)

    while True:
        pressed_keys, released_keys, new_keys = matrix.scan()
        if released_keys:
            released_keycodes = list(map(lambda i: KEYMAP[i], released_keys))
            print('released keys {}'.format(released_keycodes))

            usb_keyboard.release(*released_keycodes)
            if ble.connected:
                advertising = False
                ble_keyboard.release(*released_keycodes)
        if new_keys:
            new_keycodes = list(map(lambda i: KEYMAP[i], new_keys))
            print('new keys {}'.format(new_keycodes))
            usb_keyboard.press(*new_keycodes)
            if ble.connected:
                advertising = False
                ble_keyboard.press(*new_keycodes)

        if not ble.connected and not advertising:
            ble.start_advertising(advertisement)
            advertising = True

        time.sleep(0.001)
Ejemplo n.º 4
0
    def post_init(self, ble_name='KMK Keyboard', **kwargs):
        self.devices = {}

        hid = HIDService()

        advertisement = ProvideServicesAdvertisement(hid)
        advertisement.appearance = BLE_APPEARANCE_HID_KEYBOARD

        ble = BLERadio()
        ble.name = ble_name
        # ble.tx_power = 2

        if not ble.connected:
            ble.start_advertising(advertisement)
            while not ble.connected:
                pass

        for device in hid.devices:
            us = device.usage
            up = device.usage_page

            if up == HIDUsagePage.CONSUMER and us == HIDUsage.CONSUMER:
                self.devices[HIDReportTypes.CONSUMER] = device
                continue

            if up == HIDUsagePage.KEYBOARD and us == HIDUsage.KEYBOARD:
                self.devices[HIDReportTypes.KEYBOARD] = device
                continue

            if up == HIDUsagePage.MOUSE and us == HIDUsage.MOUSE:
                self.devices[HIDReportTypes.MOUSE] = device
                continue

            if up == HIDUsagePage.SYSCONTROL and us == HIDUsage.SYSCONTROL:
                self.devices[HIDReportTypes.SYSCONTROL] = device
                continue
Ejemplo n.º 5
0
# import board
import sys
import time

from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS

import adafruit_ble
from adafruit_ble.advertising import Advertisement
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.standard.hid import HIDService
from adafruit_ble.services.standard.device_info import DeviceInfoService


# Use default HID descriptor
hid = HIDService()
device_info = DeviceInfoService(
    software_revision=adafruit_ble.__version__, manufacturer="Adafruit Industries"
)
advertisement = ProvideServicesAdvertisement(hid)
advertisement.appearance = 961
scan_response = Advertisement()

ble = adafruit_ble.BLERadio()
if ble.connected:
    for c in ble.connections:
        c.disconnect()

print("advertising")
ble.start_advertising(advertisement, scan_response)
Ejemplo n.º 6
0
    def run(self):
        hid = HIDService()
        advertisement = ProvideServicesAdvertisement(hid)
        advertisement.appearance = 961
        ble = adafruit_ble.BLERadio()
        if ble.connected:
            for c in ble.connections:
                c.disconnect()
        ble.start_advertising(advertisement)
        ble.advertising = True
        ble_keyboard = _Keyboard(hid.devices)
        usb_keyboard = _Keyboard(usb_hid.devices)

        def send(code):
            usb_keyboard.press(code)
            usb_keyboard.release(code)
            if ble.connected:
                ble.advertising = False
                ble_keyboard.press(code)
                ble_keyboard.release(code)

        def press(code):
            usb_keyboard.press(code)
            if ble.connected:
                ble.advertising = False
                ble_keyboard.press(code)

        def release(code):
            usb_keyboard.release(code)
            if ble.connected:
                ble.advertising = False
                ble_keyboard.release(code)

        self.setup()
        while True:
            n_events = self.scan()
            if n_events == 0:
                continue

            # detecting pair keys
            if n_events == 1 and self.pressed_count == 1:
                for mask in self.pair_keys_mask:
                    if self.pressed_mask & mask == self.pressed_mask:
                        n_events = self.wait(2, self.scan_time + 25000000)
                        break

            if n_events >= 2:
                mask = 1 << self.queue.preview(0) | 1 << self.queue.preview(1)
                if mask in self.pair_keys_mask:
                    pair_keys_index = self.pair_keys_mask.index(mask)
                    action_code = self.pair_keys_code[pair_keys_index]
                    key1 = self.queue.get()
                    key2 = self.queue.get()
                    dt = self.pressed_time[key2] - self.pressed_time[key1]
                    print('pair keys {} ({}, {}), dt = {}'.format(
                        pair_keys_index, key1, key2, dt // 1000000))

                    # only one action
                    self.keys[key1] = action_code
                    self.keys[key2] = 0

                    if action_code < 2:
                        pass
                    elif action_code < 0xFF:
                        press(action_code)
                    else:
                        kind = action_code >> 12
                        layer = ((action_code >> 8) & 0xF)
                        if kind < (ACT_MODS_TAP + 1):
                            # todo
                            mods = (action_code >> 8) & 0x1F
                        elif kind == ACT_LAYER_TAP:
                            self.layers |= 1 << layer
                            print('layers {}'.format(self.layers))

            while len(self.queue):
                event = self.queue.get()
                key = event & 0x7F
                if event & 0x80 == 0:
                    action_code = self.action_code(key)
                    self.keys[key] = action_code
                    print('{} / action_code = {}'.format(key, action_code))
                    if action_code < 2:
                        pass
                    elif action_code < 0xFF:
                        press(action_code)
                    else:
                        kind = action_code >> 12
                        layer = ((action_code >> 8) & 0xF)
                        if kind == ACT_LAYER_TAP:
                            self.layers |= 1 << layer
                            print('layers {}'.format(self.layers))
                        elif action_code == BOOTLOADER:
                            reset_into_bootloader()
                else:
                    action_code = self.keys[key]
                    dt = (self.scan_time - self.pressed_time[key]) // 1000000
                    print('{} \\ action_code = {}, dt = {}'.format(
                        key, action_code, dt))
                    if action_code < 2:
                        pass
                    elif action_code < 0xFF:
                        release(action_code)
                    else:
                        kind = action_code >> 12
                        layer = ((action_code >> 8) & 0xF)
                        if kind == ACT_LAYER_TAP:
                            self.layers &= ~(1 << layer)
                            print('layers {}'.format(self.layers))
                            keycode = action_code & 0xFF
                            if dt < 500 and keycode:
                                send(keycode)

            if not ble.connected and not ble.advertising:
                ble.start_advertising(advertisement)
                ble.advertising = True

            print((time.monotonic_ns() - self.scan_time) // 1000000)
Ejemplo n.º 7
0
    def run(self):
        hid = HIDService()
        advertisement = ProvideServicesAdvertisement(hid)
        advertisement.appearance = 961
        ble = adafruit_ble.BLERadio()
        ble.name = 'Python Keyboard'
        if ble.connected:
            for c in ble.connections:
                c.disconnect()
        ble.start_advertising(advertisement)
        ble.advertising = True
        ble_keyboard = _Keyboard(hid.devices)
        usb_keyboard = _Keyboard(usb_hid.devices)

        def send(*code):
            usb_keyboard.press(*code)
            usb_keyboard.release(*code)
            if ble.connected:
                ble.advertising = False
                ble_keyboard.press(*code)
                ble_keyboard.release(*code)

        def press(*code):
            usb_keyboard.press(*code)
            if ble.connected:
                ble.advertising = False
                ble_keyboard.press(*code)

        def release(*code):
            usb_keyboard.release(*code)
            if ble.connected:
                ble.advertising = False
                ble_keyboard.release(*code)

        self.setup()
        matrix = Matrix()
        keys = [0] * matrix.size
        while True:
            n_events = matrix.scan()
            if n_events == 0:
                # print((time.monotonic_ns() - matrix.scan_time) // 1000000)
                continue

            # detecting pair keys
            if n_events == 1 and matrix[0] in self.pair_keys:
                n_events = matrix.wait(matrix.scan_time + 10000000)

            if n_events >= 2:
                pair = {matrix[0], matrix[1]}
                if pair in self.pairs:
                    pair_index = self.pairs.index(pair)
                    key1 = matrix.get()
                    key2 = matrix.get()

                    dt = matrix.pressed_t[key2] - matrix.pressed_t[key1]
                    print('pair keys {} {}, dt = {}'.format(
                        pair_index, pair, dt // 1000000))
                    # todo
                    for c in b'pair keys':
                        send(ASCII_TO_KEYCODE[c])

            while len(matrix):
                event = matrix.get()
                key = event & 0x7F
                if event & 0x80 == 0:
                    action_code = self.action_code(key)
                    keys[key] = action_code
                    print('{} \\ action_code = {}'.format(
                        key, hex(action_code)))
                    if action_code < 0xFF:
                        press(action_code)
                    else:
                        kind = action_code >> 12
                        kind = action_code >> 12
                        if kind == ACT_MODS:
                            mods = (action_code >> 8) & 0xF
                            keycodes = mods_to_keycodes(mods)
                            keycodes.append(action_code & 0xFF)
                            press(*keycodes)
                        elif kind == ACT_MODS_TAP:
                            if matrix.length == 0:
                                matrix.wait(matrix.pressed_t[key] + 500000000)
                            if matrix.length > 0 and matrix[0] == (key | 0x80):
                                print('press & release quickly')
                                keycode = action_code & 0xFF
                                keys[key] = keycode
                                press(keycode)
                                matrix.get()
                                release(keycode)
                            else:
                                mods = (action_code >> 8) & 0xF
                                keycodes = mods_to_keycodes(mods)
                                print(keycodes)
                                press(*keycodes)
                        elif kind == ACT_LAYER_TAP:
                            layer = ((action_code >> 8) & 0xF)
                            mask = 1 << layer
                            keycode = action_code & 0xFF
                            if keycode != OP_TAP_TOGGLE:
                                if matrix.length == 0:
                                    matrix.wait(matrix.pressed_t[key] +
                                                500000000)
                                if matrix.length > 0 and matrix[0] == (key
                                                                       | 0x80):
                                    print('press & release quickly')
                                    keys[key] = keycode
                                    press(keycode)
                                    matrix.get()
                                    release(keycode)
                                else:
                                    self.layer_mask |= mask
                            else:
                                print('toggle {}'.format(self.layer_mask))
                                self.layer_mask = (self.layer_mask & ~mask) | (
                                    mask & ~self.layer_mask)

                            print('layers {}'.format(self.layer_mask))
                        elif action_code == BOOTLOADER:
                            reset_into_bootloader()
                else:
                    action_code = keys[key]
                    dt = (matrix.scan_time - matrix.pressed_t[key]) // 1000000
                    print('{} / action_code = {}, dt = {}'.format(
                        key, action_code, dt))
                    if action_code < 0xFF:
                        release(action_code)
                    else:
                        kind = action_code >> 12
                        if kind == ACT_MODS:
                            mods = (action_code >> 8) & 0xF
                            keycodes = mods_to_keycodes(mods)
                            keycodes.append(action_code & 0xFF)
                            release(*keycodes)
                        elif kind == ACT_MODS_TAP:
                            mods = (action_code >> 8) & 0xF
                            keycodes = mods_to_keycodes(mods)
                            release(*keycodes)
                        elif kind == ACT_LAYER_TAP:
                            layer = ((action_code >> 8) & 0xF)
                            keycode = action_code & 0xFF
                            if keycode != OP_TAP_TOGGLE:
                                self.layer_mask &= ~(1 << layer)
                                print('layers {}'.format(self.layer_mask))
                            # if dt < 500 and keycode:
                            # send(keycode)

            if not ble.connected and not ble.advertising:
                ble.start_advertising(advertisement)
                ble.advertising = True

            print((time.monotonic_ns() - matrix.scan_time) // 1000000)
    # b'\x81\x02'        #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    # b'\x05\x01'        #   Usage Page (Generic Desktop Ctrls)
    # b'\x15\x81'        #   Logical Minimum (-127)
    # b'\x25\x7F'        #   Logical Maximum (127)
    # b'\x09\x30'        #   Usage (X)
    # b'\x09\x31'        #   Usage (Y)
    # b'\x09\x32'        #   Usage (Z)
    # b'\x09\x35'        #   Usage (Rz)
    # b'\x75\x08'        #   Report Size (8)
    # b'\x95\x04'        #   Report Count (4)
    # b'\x81\x02'        #   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    # b'\xC0'            # End Collection
)
#pylint: enable=line-too-long

hid = HIDService(HID_DESCRIPTOR)
device_info = DeviceInfoService(software_revision=adafruit_ble.__version__,
                                manufacturer="Adafruit Industries")
print(device_info.manufacturer)
advertisement = ProvideServicesAdvertisement(hid)
advertisement.appearance = 961

ble = adafruit_ble.BLERadio()
print(to_hex(bytes(advertisement)))
if not ble.connected:
    print("advertising")
    ble.start_advertising(advertisement)
else:
    print("already connected")
    print(ble.connections)