diff --git a/Makefile b/Makefile index b2accb6..a90e7ce 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,26 @@ CC=gcc CFLAGS=-Wall -O0 -g -LDFLAGS=-lm +LDFLAGS=-lm -lusb-1.0 TEX=xelatex TEXFLAGS=-file-line-error -interaction nonstopmode -all: doc +all: doc build/sniffer build/skillerctl + +-include $(wildcard build/*.d) + +build/sniffer: build/sniffer.o build/utils.o build/usb.o build/skiller.o + $(CC) $^ -o $@ $(LDFLAGS) + +build/skillerctl: build/skillerctl.o build/utils.o build/usb.o build/skiller.o + $(CC) $^ -o $@ $(LDFLAGS) + doc: doc/skiller-sgk3.pdf %.pdf: %.tex $(TEX) $(TEXFLAGS) -output-directory build $< -.c.o: - $(CC) $(CFLAGS) -MMD -c ./src/$< -o ./build/$@ +build/%.o: src/%.c + $(CC) $(CFLAGS) -MMD -c $< -o $@ clean: rm build/* diff --git a/build/skiller-sgk3.pdf b/build/skiller-sgk3.pdf deleted file mode 100644 index 4f79bae..0000000 Binary files a/build/skiller-sgk3.pdf and /dev/null differ diff --git a/doc/random.txt b/doc/random.txt new file mode 100644 index 0000000..144407a --- /dev/null +++ b/doc/random.txt @@ -0,0 +1,111 @@ +?? ?? ?? ???? ?? ?? rrggbb +04 79 01 1103 65 0100 ff0000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +04 fa 00 1103 65 0100 008000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +04 7c 01 1103 68 0100 ff0000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +?? ???? com? keyc ?? rrggbb +04 0100 0100 0000 00 000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +04 be03 1103 c000 00 fffbf0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ; a +04 0200 0200 0000 00 000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +04 0d03 11 03 0e01 00 fffbf0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ; b +04 0703 11 03 0801 00 fffbf0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ; c +04 c403 11 03 c600 00 fffbf0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ; d +04 9703 11 03 9900 00 fffbf0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ; o +04 d202 11 03 c000 00 ffff00 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ; a +04 5401 11 03 c000 00 000080 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +04 9700 11 03 0201 00 000080 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +04 5701 11 03 c300 00 000080 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +04 d000 11 03 3b01 00 000080 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +04 9400 11 03 0000 00 000080 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +04 4409 11 36 0000 00 0000fe 00800000800000800000800000800000800000800000800000800000800000800000800000000000800000800000ff000000000000 + +04 1800 06 01 0f00 00 020000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +04 4402 04 2c 0000 00 aa5502150000000000000050000000000102030405060708090a0b0c0d0e0f00101214000000000000000000000000000000000000000000 + +esc == 00, left to right, top to bottom. + +Magic Number: 0x04 +Control sum: Sum of all the other bytes +Some kind of command: 0x0311 +Some kind of address: 0x0000 +Some kind of 0x00: 0x00 + +Payload: + bbggrr: 0x800000 + + +Command types: + - 0x01 - lights off + - 0x02 - lights on + - 0x06 - change settings + - 0x00 - mode + - 0x01 - brightness + - 0x02 - pulse speed + - 0x03 - direction + - 0x04 - Is RGB + - 0x05 - color (3 bytes) + + - 0x11 - change color + +02 // number of repetitions +03 // a chuj wie + +delay ?? ?? Key code +05 A0 02 0F +05 20 02 0F +05 A0 02 12 +05 20 02 12 +05 A0 02 0F +00 20 02 0F + +6D 00 65 00 68 00 // meh + +0000 AA 55 34 00 01 00 01 00 00 00 00 00 00 00 00 00 +0010 12 00 06 00 01 03 05 A0 02 0F 05 20 02 0F 05 A0 +0020 02 12 05 20 02 12 05 A0 02 0F 00 20 02 0F 6D 00 +0030 65 00 68 00 + +0000 AA 55 +60 00 // długość +02 00 // ilość wpisów ? +01 00 +0E 00 +00 0E +32 76 +03 00 +14 00 +36 00 +06 00 + +06 00 // number of keystrokes +02 // number of repetitions +03 // ?? + +05 A0 02 0F +05 20 02 0F +05 A0 02 12 +05 20 02 12 +05 A0 02 0F +00 20 02 0F + +6D 00 65 00 68 00 // name: meh + +08 00 +01 +03 +05 A0 01 20 // 05 = delay, 05*10ms A0 - press, 0x01 - modifier 0x20 - keycode +05 A0 02 0F +05 20 02 0F +05 A0 02 12 +05 20 02 12 +05 A0 02 0F +05 20 02 0F +00 20 01 20 + +6B 00 65 00 6B 00 + diff --git a/doc/skiller-sgk3.tex b/doc/skiller-sgk3.tex index 8df389c..11c80fe 100644 --- a/doc/skiller-sgk3.tex +++ b/doc/skiller-sgk3.tex @@ -20,4 +20,7 @@ \begin{document} {\huge \noindent \textbf{\thetitle} \vspace{5mm}} \\ {\large \theauthor} \\ + + \section{Basic hardware information} + Port: USB, ID \texttt{0c45:8513} \end{document} diff --git "a/src/\\" "b/src/\\" new file mode 100644 index 0000000..efe5286 --- /dev/null +++ "b/src/\\" @@ -0,0 +1,50 @@ +#ifndef KEYS_H +#define KEYS_H + +#include + +#define SK_KEY_BAD 0xffff +#define SK_KEY_ESC 0x0000 +#define SK_KEY_F1 0x0003 +#define SK_KEY_F2 0x0006 +#define SK_KEY_F3 0x0009 +#define SK_KEY_F4 0x000C +#define SK_KEY_F5 0x000F +#define SK_KEY_F6 0x0012 +#define SK_KEY_F7 0x0015 +#define SK_KEY_F8 0x0018 +#define SK_KEY_F9 0x001B +#define SK_KEY_F10 0x001E +#define SK_KEY_F11 0x0021 +#define SK_KEY_F12 0x0024 +#define SK_KEY_PRTSC 0x002a +#define SK_KEY_SCROLL_LOCK 0x002d +#define SK_KEY_BREAK 0x0030 +#define SK_KEY_TILDE 0x003f +#define SK_KEY_1 0x003f +#define SK_KEY_2 0x003f +#define SK_KEY_3 0x003f +#define SK_KEY_4 0x003f +#define SK_KEY_5 0x003f +#define SK_KEY_6 0x003f +#define SK_KEY_7 0x003f +#define SK_KEY_8 0x003f +#define SK_KEY_9 0x003f +#define SK_KEY_0 0x003f +#define SK_KEY_MINUS 0x003f +#define SK_KEY_EQUALS 0x003f +#define SK_KEY_BACKSPACE 0x003f +#define SK_KEY_INSERT 0x003f +#define SK_KEY_HOME 0x003f +#define SK_KEY_PGUP 0x003f +#define SK_KEY_NUMLOCK 0x003f +#define SK_KEY_NUMDIV 0x003f +#define SK_KEY_NUMASTERIX 0x003f +#define SK_KEY_NUMMINUS 0x003f + +typedef uint16_t skillerctl_keyaddr_t; + +skillerctl_keyaddr_t skillerctl_keyaddr(const char* name); + +#endif /* KEYS_H */ + diff --git a/src/keys.c b/src/keys.c new file mode 100644 index 0000000..39ce8b5 --- /dev/null +++ b/src/keys.c @@ -0,0 +1,30 @@ +#include "keys.h" +#include +#include + +typedef struct { + skillerctl_keyaddr_t addr; + char* name; +} keyaddr_name_pair; + +keyaddr_name_pair keycodeLUT[] = { + SK_KEY_ESC, "esc", + SK_KEY_F1, "f1", + SK_KEY_F2, "f2", +}; + +skillerctl_keyaddr_t skillerctl_keyaddr(const char* name) +{ + size_t n = sizeof(keycodeLUT) / sizeof(keyaddr_name_pair); + keyaddr_name_pair *current; + + for (int i = 0; i < n; i++) { + current = keycodeLUT + i; + + if (strcmp(current->name, name) == 0) { + return current->addr; + } + } + + return SK_KEY_BAD; +} diff --git a/src/keys.h b/src/keys.h new file mode 100644 index 0000000..42c606b --- /dev/null +++ b/src/keys.h @@ -0,0 +1,118 @@ +#ifndef KEYS_H +#define KEYS_H + +#include + +#define SK_KEY_BAD 0xffff +#define SK_KEY_ESC 0x0000 +#define SK_KEY_F1 0x0003 +#define SK_KEY_F2 0x0006 +#define SK_KEY_F3 0x0009 +#define SK_KEY_F4 0x000C +#define SK_KEY_F5 0x000F +#define SK_KEY_F6 0x0012 +#define SK_KEY_F7 0x0015 +#define SK_KEY_F8 0x0018 +#define SK_KEY_F9 0x001B +#define SK_KEY_F10 0x001E +#define SK_KEY_F11 0x0021 +#define SK_KEY_F12 0x0024 +#define SK_KEY_PRTSC 0x002a +#define SK_KEY_SCROLL_LOCK 0x002d +#define SK_KEY_BREAK 0x0030 +#define SK_KEY_TILDE 0x003f +#define SK_KEY_1 0x0042 +#define SK_KEY_2 0x0045 +#define SK_KEY_3 0x0048 +#define SK_KEY_4 0x004b +#define SK_KEY_5 0x004e +#define SK_KEY_6 0x0051 +#define SK_KEY_7 0x0054 +#define SK_KEY_8 0x0057 +#define SK_KEY_9 0x005A +#define SK_KEY_0 0x005D +#define SK_KEY_MINUS 0x0060 +#define SK_KEY_EQUALS 0x0063 +#define SK_KEY_BACKSPACE 0x0066 +#define SK_KEY_INSERT 0x0069 +#define SK_KEY_HOME 0x006c +#define SK_KEY_PGUP 0x006f +#define SK_KEY_NUMLOCK 0x0072 +#define SK_KEY_NUMDIV 0x0075 +#define SK_KEY_NUMASTERIX 0x0078 +#define SK_KEY_NUMMINUS 0x007A +#define SK_KEY_TAB 0x007E +#define SK_KEY_Q 0x0081 +#define SK_KEY_W 0x0084 +#define SK_KEY_E 0x0087 +#define SK_KEY_R 0x008A +#define SK_KEY_T 0x008D +#define SK_KEY_Y 0x0090 +#define SK_KEY_U 0x0093 +#define SK_KEY_I 0x0096 +#define SK_KEY_O 0x0099 +#define SK_KEY_P 0x009C +#define SK_KEY_OPEN_BRACKET 0x009F +#define SK_KEY_CLOSE_BRACKET 0x00A2 +#define SK_KEY_BACKSLASH 0x00A5 +#define SK_KEY_DELETE 0x00A8 +#define SK_KEY_END 0x00AB +#define SK_KEY_PGDOWN 0x00AE +#define SK_KEY_NUM7 0x00B1 +#define SK_KEY_NUM8 0x00B4 +#define SK_KEY_NUM9 0x00B7 +#define SK_KEY_NUMPLUS 0x00BA +#define SK_KEY_CAPSLOCK 0x00BD +#define SK_KEY_A 0x00C0 +#define SK_KEY_S 0x00C3 +#define SK_KEY_D 0x00C6 +#define SK_KEY_F 0x00C9 +#define SK_KEY_G 0x00CC +#define SK_KEY_H 0x00CF +#define SK_KEY_J 0x00D2 +#define SK_KEY_K 0x00D5 +#define SK_KEY_L 0x00D8 +#define SK_KEY_COLON 0x00DB +#define SK_KEY_QUOTE 0x00DE +#define SK_KEY_ENTER 0x00E4 +#define SK_KEY_NUM4 0x00F0 +#define SK_KEY_NUM5 0x00F3 +#define SK_KEY_NUM6 0x00F6 +#define SK_KEY_LSHIFT 0x00FC +#define SK_KEY_Z 0x0102 +#define SK_KEY_X 0x0105 +#define SK_KEY_C 0x0108 +#define SK_KEY_V 0x010b +#define SK_KEY_B 0x010e +#define SK_KEY_N 0x0111 +#define SK_KEY_M 0x0114 +#define SK_KEY_COMMA 0x0117 +#define SK_KEY_DOT 0x011a +#define SK_KEY_SLASH 0x011d +#define SK_KEY_RSHIFT 0x0123 +#define SK_KEY_UP 0x0129 +#define SK_KEY_NUM1 0x012f +#define SK_KEY_NUM2 0x0132 +#define SK_KEY_NUM3 0x0135 +#define SK_KEY_NUMENTER 0x0138 +#define SK_KEY_LCTRL 0x013b +#define SK_KEY_LWIN 0x013e +#define SK_KEY_LALT 0x0141 +#define SK_KEY_SPACE 0x0144 +#define SK_KEY_ALTGR 0x0147 +#define SK_KEY_SHARKOON 0x014a +#define SK_KEY_MENU 0x014d +#define SK_KEY_RCTRL 0x0153 +#define SK_KEY_LEFT 0x0165 +#define SK_KEY_DOWN 0x0168 +#define SK_KEY_RIGHT 0x016b +#define SK_KEY_NUM0 0x0171 +#define SK_KEY_NUMDEL 0x0174 + +typedef uint16_t skillerctl_keyaddr_t; + +skillerctl_keyaddr_t skillerctl_keyaddr(const char* name); +char* skillerctl_keystr(skillerctl_keyaddr_t key); + +#endif /* KEYS_H */ + diff --git a/src/skiller.c b/src/skiller.c new file mode 100644 index 0000000..d07aeff --- /dev/null +++ b/src/skiller.c @@ -0,0 +1,84 @@ +#include "skiller.h" +#include + +skillerctl_packet_t* skillerctl_unpack(skillerctl_packet_t *packet, uint8_t *data, size_t length) { + if (*(unsigned char*)data != 0x04 || length < 1) { + return NULL; + } + + packet->magic = *(uint8_t*)(data); + packet->checksum = *(uint16_t*)(data + 1); + packet->command = *(uint8_t*)(data + 3); + packet->length = *(uint8_t*)(data + 4); + packet->address = *(uint8_t*)(data + 5); + // 1 null byte + memcpy(packet->payload, data + 8, packet->length); + + return packet; +} + +void* skillerctl_pack(skillerctl_packet_t *packet, uint8_t *data) { + memcpy(data, &packet->magic, 1); + memcpy(data + 1, &packet->checksum, 2); + memcpy(data + 3, &packet->command, 1); + memcpy(data + 4, &packet->length, 1); + memcpy(data + 5, &packet->address, 2); + // 1 null byte + memcpy(data + 8, packet->payload, SK_MAX_PAYLOAD); + + return packet; +} + +void skillerctl_make_packet(skillerctl_packet_t *packet, uint8_t command, uint16_t address, void* payload, uint8_t size) +{ + packet->magic = SK_MAGIC; + packet->address = address; + packet->command = command; + packet->length = size; + + memset(packet->payload, 0, SK_MAX_PAYLOAD); + + if (payload && size) + memcpy(packet->payload, payload, size); + + packet->checksum = skillectl_packet_checksum(packet); +} + +uint16_t skillectl_packet_checksum(skillerctl_packet_t *packet) +{ + uint16_t checksum = 0; + + checksum += (packet->command) & 0xFF; + checksum += (packet->address) & 0xFF; + checksum += (packet->address >> 8) & 0xFF; + checksum += (packet->length) & 0xFF; + + for (int i = 0; i < packet->length; i++) { + checksum += packet->payload[i]; + } + + return checksum; +} + +void skillerctl_color_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t address, uint32_t color) +{ + skillerctl_payload_color_t payload; + + payload.color[0].r = (color >> 16) & 0xFF; + payload.color[0].g = (color >> 8) & 0xFF; + payload.color[0].b = color & 0xFF; + + skillerctl_make_packet(packet, SK_CMD_COLOR, address, &payload, 3); +} + +void skillerctl_enable_command(skillerctl_packet_t *packet) +{ + skillerctl_payload_color_t payload; + skillerctl_make_packet(packet, SK_CMD_ENABLE, 0x0000, NULL, 0); +} + +void skillerctl_disable_command(skillerctl_packet_t *packet) +{ + skillerctl_payload_color_t payload; + skillerctl_make_packet(packet, SK_CMD_DISABLE, 0x0000, NULL, 0); +} diff --git a/src/skiller.h b/src/skiller.h new file mode 100644 index 0000000..f246137 --- /dev/null +++ b/src/skiller.h @@ -0,0 +1,46 @@ +#ifndef SKILLER_H +#define SKILLER_H + +#include +#include +#include "keys.h" + +#define SK_MAX_PAYLOAD 56 +#define SK_PACKET_SIZE 64 + +#define SK_MAGIC 0x04 + +#define SK_CMD_COLOR 0x11 +#define SK_CMD_ENABLE 0x01 +#define SK_CMD_DISABLE 0x02 + +typedef struct { + uint8_t magic; + uint16_t checksum; + uint8_t command; + uint16_t address; + uint8_t length; + uint8_t payload[SK_MAX_PAYLOAD]; +} skillerctl_packet_t; + +typedef struct { + struct { + uint8_t r; + uint8_t g; + uint8_t b; + } color[SK_MAX_PAYLOAD / 3]; +} skillerctl_payload_color_t; + +void skillerctl_make_packet(skillerctl_packet_t *packet, uint8_t command, uint16_t address, void* payload, uint8_t size); + +void skillerctl_color_command(skillerctl_packet_t *packet, skillerctl_keyaddr_t address, uint32_t color); +void skillerctl_enable_command(skillerctl_packet_t *packet); +void skillerctl_disable_command(skillerctl_packet_t *packet); + +skillerctl_packet_t* skillerctl_unpack(skillerctl_packet_t *packet, uint8_t *data, size_t length); +void* skillerctl_pack(skillerctl_packet_t *packet, uint8_t *data); + +uint16_t skillectl_packet_checksum(skillerctl_packet_t *packet); + +#endif /* SKILLER_H */ + diff --git a/src/skillerctl.c b/src/skillerctl.c new file mode 100644 index 0000000..83e65f6 --- /dev/null +++ b/src/skillerctl.c @@ -0,0 +1,58 @@ +#include +#include +#include "skiller.h" +#include "usb.h" +#include "utils.h" + +void stuff(libusb_device *skiller) +{ + libusb_device_handle *handle; + skillerctl_packet_t packet; + + if (skiller == NULL) { + printf("Device not found kurwa.\n"); + return; + } + + + if (libusb_open(skiller, &handle) != LIBUSB_SUCCESS) { + printf("Nie udało się nawiązać połączenia kurwa..\n"); + return; + } + + printf("Hura kurwa.\n"); + + libusb_detach_kernel_driver(handle, 1); + libusb_claim_interface(handle, 1); + +/* skillerctl_enable_command(&packet); */ +/* skillerctl_send_command(handle, &packet); */ + + skillerctl_color_command(&packet, SK_KEY_ESC, 0xFF0000); + skillerctl_send_command(handle, &packet); + skillerctl_color_command(&packet, SK_KEY_F1, 0x00FF00); + skillerctl_send_command(handle, &packet); + skillerctl_color_command(&packet, SK_KEY_F2, 0x0000FF); + skillerctl_send_command(handle, &packet); + + /* skillerctl_disable_command(&packet); */ + /* skillerctl_send_command(handle, &packet); */ + + libusb_release_interface(handle, 1); + libusb_attach_kernel_driver(handle, 1); + libusb_close(handle); +} + +int main() +{ + libusb_device **list; + + libusb_init(NULL); + size_t count = libusb_get_device_list(NULL, &list); + libusb_device *skiller = skillerctl_find_device(list, count); + + stuff(skiller); + + libusb_free_device_list(list, 1); + libusb_exit(NULL); +} diff --git a/src/sniffer.c b/src/sniffer.c new file mode 100644 index 0000000..f3e6447 --- /dev/null +++ b/src/sniffer.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include + +#include "../lib/optparse.h" +#include "utils.h" +#include "skiller.h" +#include "usb.h" + +#define USBMON_IOC_MAGIC 0x92 +#define USBMON_IOCX_GET _IOW(USBMON_IOC_MAGIC, 10, usbmon_get_t) + +typedef struct usbmon_packet { + uint64_t id; /* 0: URB ID - from submission to callback */ + uint8_t type; /* 8: Same as text; extensible. */ + uint8_t xfer_type; /* ISO (0), Intr, Control, Bulk (3) */ + uint8_t epnum; /* Endpoint number and transfer direction */ + uint8_t devnum; /* Device address */ + uint16_t busnum; /* 12: Bus number */ + char flag_setup; /* 14: Same as text */ + char flag_data; /* 15: Same as text; Binary zero is OK. */ + int64_t ts_sec; /* 16: gettimeofday */ + uint64_t ts_usec; /* 24: gettimeofday */ + int status; /* 28: */ + unsigned int length; /* 32: Length of data (submitted or actual) */ + unsigned int len_cap; /* 36: Delivered length */ + union { /* 40: */ + unsigned char setup[8]; /* Only for Control S-type */ + struct iso_rec { /* Only for ISO */ + int error_count; + int numdesc; + } iso; + } s; + int interval; /* 48: Only for Interrupt and ISO */ + int start_frame; /* 52: For ISO */ + unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */ + unsigned int ndesc; /* 60: Actual number of ISO descriptors */ +} usbmon_packet_t; /* 64 total length */ + +typedef struct usbmon_get { + usbmon_packet_t *packet; + void *data; + size_t alloc; +} usbmon_get_t; + +const char types[4] = "SICB"; + +uint8_t buffer[4096]; +usbmon_packet_t packet; + +int main(int argc, char** argv) +{ + libusb_device **list; + + libusb_init(NULL); + size_t count = libusb_get_device_list(NULL, &list); + libusb_device *skiller = skillerctl_find_device(list, count); + + if (skiller != NULL) { + uint8_t bus = libusb_get_bus_number(skiller); + uint8_t dev = libusb_get_device_address(skiller); + + printf("Keyboard found on bus %03d, device: %d\n", bus, dev); + + char* device = "/dev/usbmon0"; + + usbmon_get_t get = { + .packet = &packet, + .data = &buffer, + .alloc = sizeof buffer + }; + + int fd = open(device, O_RDONLY); + + if (fd < 0) { + printf("Cannot open device %s, maybe usbmon module is not loaded corectly?\n", device); + return 1; + } + + while (1) { + if (ioctl(fd, USBMON_IOCX_GET, &get) < 0) { + break; + } + + if (packet.devnum != dev || packet.busnum != bus) { + continue; + } + + printf("%s dev %d [%c] len: %d \n", packet.type == 'S' ? "->" : "<-", packet.devnum, types[packet.xfer_type], packet.length); + + skillerctl_packet_t ctl; + if (skillerctl_unpack(&ctl, buffer, packet.length)) { + printf("Command: 0x%02X, checksum: 0x%04X, payload length: %d, addr: 0x%04X \n", ctl.command, ctl.checksum, ctl.length, ctl.address); + hexdump(ctl.payload, ctl.length); + } else if (packet.length > 0) { + printf("Unknown packet kind! \n"); + hexdump(buffer, packet.length); + } + } + } + + + libusb_free_device_list(list, 1); + libusb_exit(NULL); +} diff --git a/src/usb.c b/src/usb.c new file mode 100644 index 0000000..8b798d2 --- /dev/null +++ b/src/usb.c @@ -0,0 +1,42 @@ +#include "usb.h" +#include "utils.h" +#include +#include +#include + +libusb_device* skillerctl_find_device(libusb_device **devices, size_t count) +{ + libusb_device *device; + struct libusb_device_descriptor descriptor; + + for (unsigned i = 0; i < count; i++) { + device = devices[i]; + + libusb_get_device_descriptor(device, &descriptor); + if (descriptor.idVendor == SK_VID && descriptor.idProduct == SK_PID) { + return device; + } + } + + return NULL; +} + +void skillerctl_send_command(libusb_device_handle *handle, skillerctl_packet_t *packet) +{ + // buffer for storing packed packet + uint8_t buffer[SK_PACKET_SIZE]; + int length; + + skillerctl_pack(packet, buffer); + printf("Sending packet to keyboard: \n"); + hexdump(buffer, SK_PACKET_SIZE); + + libusb_control_transfer(handle, 0x21, 9, 0x0204, 0x0001, buffer, SK_PACKET_SIZE, 250); + libusb_interrupt_transfer(handle, SK_PORT_STATE, buffer, sizeof(buffer), &length, 250); + + printf("State from keyboard: \n"); + hexdump(buffer, SK_PACKET_SIZE); + + // we need to pretend that we're doing important stuff + usleep(100000); +} diff --git a/src/usb.h b/src/usb.h new file mode 100644 index 0000000..c0fc658 --- /dev/null +++ b/src/usb.h @@ -0,0 +1,18 @@ +#ifndef USB_H +#define USB_H + +#include "skiller.h" +#include + +#define SK_VID 0x0C45 +#define SK_PID 0x8513 + +#define SK_PORT_STATE 0x82 +#define SK_PORT_HID 0x81 + +libusb_device* skillerctl_find_device(libusb_device **devices, size_t count); + +void skillerctl_send_command(libusb_device_handle *handle, skillerctl_packet_t *packet); + +#endif /* USB_H */ + diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..93563e0 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,17 @@ +#include "utils.h" +#include + +void hexdump(void* data, size_t length) +{ + for (size_t read = 0; read < length; read += 16) { + printf("%04zx", read); + + size_t to_read = length - read > 16 ? 16 : length - read; + for (size_t byte = 0; byte < to_read; byte++) { + printf(" %02X", ((unsigned char*)data)[read + byte]); + } + + printf("\n"); + } +} + diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..aaffe17 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,8 @@ +#ifndef UTILS_H_ +#define UTILS_H_ + +#include + +void hexdump(void* bytes, size_t length); + +#endif