From fb48677430e8ace345fc906b88868236472d0695 Mon Sep 17 00:00:00 2001 From: Denis Manherz Date: Fri, 30 Aug 2024 22:36:55 +0200 Subject: [PATCH] usb_thingy --- .vscode/settings.json | 3 +- Untitled-1 => hexdump_analysis/Untitled-1 | 0 hexdump_analysis/hexdump_analysis.txt | 7 +- macrofileappend | Bin 0 -> 153920 bytes src/Main.qml | 2 +- src/conf.cpp | 463 ++++++++++------------ src/conf.h | 23 +- src/structs.h | 21 +- src/usb_thingy.cpp | 98 ++++- src/usb_thingy.h | 67 ++-- 10 files changed, 385 insertions(+), 299 deletions(-) rename Untitled-1 => hexdump_analysis/Untitled-1 (100%) create mode 100644 macrofileappend diff --git a/.vscode/settings.json b/.vscode/settings.json index 4752a7a..0bb1edb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -67,6 +67,7 @@ "thread": "cpp", "typeinfo": "cpp", "variant": "cpp", - "cinttypes": "cpp" + "cinttypes": "cpp", + "fstream": "cpp" } } \ No newline at end of file diff --git a/Untitled-1 b/hexdump_analysis/Untitled-1 similarity index 100% rename from Untitled-1 rename to hexdump_analysis/Untitled-1 diff --git a/hexdump_analysis/hexdump_analysis.txt b/hexdump_analysis/hexdump_analysis.txt index 6784068..d7a4208 100644 --- a/hexdump_analysis/hexdump_analysis.txt +++ b/hexdump_analysis/hexdump_analysis.txt @@ -185,7 +185,10 @@ Warum zum fick kann man eine Kombination T+T+T eingeben aber das letzte T wird n 0x3a F1 ... 0x45 F12 -4 Byte 0x70 (Macro) 0x01 (Macro nummer) 0x01 (??) 0x01(??) +4 Byte 0x70 (Macro) 0x01 (Macro nummer) 0x01 (cycle) 0x01(cycle count) +(cycle) 0x01 -> cycle * cycle count +(cycle) 0x04 cycle till the key is realeased +(cycle) 0x02 cycle until any key pressed 0x70 -> Macro mod @@ -238,6 +241,8 @@ max delay 4095 bzw. 0xfff Maximal 0xa8 (168) events (keyup or down) +macro cycles are save in the conf_2 key_conf in the last byte + Macros bleiben auf der maus bis sie überschrieben werden -> so it is 3 bytes per key diff --git a/macrofileappend b/macrofileappend new file mode 100644 index 0000000000000000000000000000000000000000..0d94f8416015d7c1bd1c080ab210df8c066b5e2e GIT binary patch literal 153920 zcmeI$!EM3-6huJ`9NdmOq4boLEH7PnI3TWnHNsCmuj8@L@i;!m`}@<^4Hr1C=lAO8 z{2Zb9N*vaSh`dyg9hJ1ATC70RPA90}8f)KHwk+`hbM}ALs)P z=D_;{4)g&7E#UnD30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7Fi zK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGC zpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+ z30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puP zaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7Fi zK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGC zpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+ z30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puP zaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7Fi zK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGC zpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+ z30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puP zaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7Fi zK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGC zpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+ z30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puP zaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7Fi zK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGC zpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+ z30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puP zaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7Fi zK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGCpat{+30puPaF7FiK!QGC Lpat{+30vS7?agGw literal 0 HcmV?d00001 diff --git a/src/Main.qml b/src/Main.qml index 527bf06..9610673 100644 --- a/src/Main.qml +++ b/src/Main.qml @@ -91,7 +91,7 @@ Kirigami.ApplicationWindow { text: "test" icon.name: "gtk-quit" shortcut: StandardKey.Quit - onTriggered: Conf.readMacrosFromDevice() + onTriggered: Conf.testFunc() }, Kirigami.Action { text: "1" diff --git a/src/conf.cpp b/src/conf.cpp index d22e6a1..28e3685 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -4,39 +4,110 @@ #include #include +#define CHK(X) \ + if ((r = (X)) != 0) \ + return r; + Conf::Conf(QObject *parent) : QObject(parent) { m_conf1 = (conf_1 *)malloc(sizeof(conf_1)); m_conf2 = (conf_2 *)malloc(sizeof(conf_2)); - memset(m_conf1, 0, 520); - memset(m_conf2, 0, 520); + std::cout << std::dec << sizeof(conf_1) << "; " << sizeof(conf_2) << std::endl; + memset(m_conf1, 0, sizeof(conf_1)); + memset(m_conf2, 0, sizeof(conf_2)); - int r = libusb_init(&m_ctx); - if (r < 0) - { - std::cout << libusb_error_name(r) << std::endl; - exit(1); - } - libusb_device **list; - ssize_t cnt = libusb_get_device_list(m_ctx, &list); - - for (ssize_t i = 0; i < cnt; i++) - { - libusb_device *device = list[i]; - m_device = device; - libusb_device_descriptor desc; - libusb_get_device_descriptor(m_device, &desc); - if ((desc.idProduct == 0x2f || desc.idProduct == 0x2e) && desc.idVendor == 0x258a) - { - break; - } - } + connection = &(Connection::getInstance()); + connection->findDevice(); // read initial config from device readConfigFromDevice(m_conf1); readConfigFromDevice(m_conf2); +} - libusb_free_device_list(list, 1); +ssize_t Conf::appendMacroToFile(macro *macro, const char *filePath) +{ + FILE *outfile; + outfile = fopen(filePath, "ab"); + if (outfile == NULL) + { + fprintf(stderr, "\nError opened file\n"); + exit(1); + } + // write struct to file + int flag = 0; + flag = fwrite(macro, sizeof(struct macro), 1, outfile); + + if (flag) + { + printf("Contents of macro %d written " + "successfully %d\n", + macro->macro_nr, flag); + } + else + printf("Error Writing to File!\n"); + + fclose(outfile); + + return 0; +} + +ssize_t Conf::deleteMacroFromFile(macro *_macro, const char *filePath) +{ + FILE *infile, *tempfile; + macro temp_macro; + + // Open the original file for reading + infile = fopen(filePath, "rb"); + if (infile == NULL) + { + fprintf(stderr, "\nError opening file for reading\n"); + exit(1); + } + + // Open a temporary file for writing + tempfile = fopen("tempfile.bin", "wb"); + if (tempfile == NULL) + { + fprintf(stderr, "\nError opening temporary file for writing\n"); + fclose(infile); + exit(1); + } + + // Read each macro from the original file + while (fread(&temp_macro, sizeof(macro), 1, infile) == 1) + { + // If the macro ID does not match the one to delete, write it to the temp file + if (temp_macro.macro_nr != _macro->macro_nr) + { + fwrite(&temp_macro, sizeof(macro), 1, tempfile); + } + else + { + printf("Macro with ID %d deleted.\n", _macro->macro_nr); + } + } + + // Close both files + fclose(infile); + fclose(tempfile); + + // Replace the original file with the temp file + remove(filePath); // Delete the original file + rename("tempfile.bin", filePath); // Rename the temp file to the original file name + + return 0; + + return 0; +} + +void Conf::testFunc() +{ + macro **macros; + readMacrosFromDevice(macros, 4); + for (int i = 0; i < 4; i++) + { + appendMacroToFile(macros[i], "macrofileappend"); + } } int Conf::lightMode() @@ -53,75 +124,27 @@ void Conf::setLightMode(int mode) ssize_t Conf::restoreConfigs() { - unsigned char send_data0[8]; - memset(send_data0, 0, 8 * sizeof(unsigned char)); + unsigned char _data[8] = {0x05, 0x40, 0x01, 0, 0, 0, 0, 0}; - send_data0[0] = 0x05; - send_data0[1] = 0x40; - send_data0[2] = 0x01; // restore - - int r = 0; - libusb_device_handle *handle; - if ((r = libusb_open(m_device, &handle)) < 0) - std::cout << "libusb_open: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl; - if ((r = libusb_claim_interface(handle, 1)) < 0) - std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0) - std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_release_interface(handle, 1)) < 0) - std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl; - if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl; - - libusb_close(handle); + ssize_t r; + CHK(connection->open()); + CHK(connection->setReport(0x0305, (unsigned char *)_data, 8)); + CHK(connection->close()); return 0; } ssize_t Conf::deviceConfig() { - unsigned char dat[520]; - unsigned char send_data0[8]; - memset(send_data0, 0, 8 * sizeof(unsigned char)); - memset(dat, 0, 520 * sizeof(unsigned char)); - send_data0[0] = 0x05; - send_data0[1] = 0x90; // conf 2, wireless + unsigned char _data[8] = {0x05, 0x22, 0, 0, 0, 0, 0, 0}; + /*if(!connection->isWireless()) + _data[1] = 0x12;*/ - // get config before write new config - // conf_1 - int r = 0; - libusb_device_handle *handle; - if ((r = libusb_open(m_device, &handle)) < 0) - std::cout << "libusb_open: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl; - if ((r = libusb_claim_interface(handle, 1)) < 0) - std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl; - - // conf_2 - if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0) - std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl; - if ((r = libusb_control_transfer(handle, 0xa1, 0x01, 0x0305, 1, (unsigned char *)dat, 8, 5000)) < 0) - std::cout << "libusb_control_transfer4: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_release_interface(handle, 1)) < 0) - std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl; - if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl; - - for (int i = 0; i < 16; i++) - { - std::cout << std::hex << (int)dat[i] << "\t"; - } - std::cout << std::endl; - - libusb_close(handle); + ssize_t r; + CHK(connection->open()); + CHK(connection->setReport(0x0305, (unsigned char *)_data, 8)); + CHK(connection->getReport(0x0308, (unsigned char *)0x0, 520)); + CHK(connection->close()); return 0; } @@ -174,124 +197,53 @@ ssize_t Conf::writeConfigToFile(const char *filePath) ssize_t Conf::writeConfigToDevice(conf_2 *conf) { - int r = 0; - libusb_device_handle *handle; - if ((r = libusb_open(m_device, &handle)) < 0) - std::cout << "libusb_open: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl; - if ((r = libusb_claim_interface(handle, 1)) < 0) - std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl; - - // conf_2 + ssize_t r; + CHK(connection->open()); conf->req_type = 0x50; - if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0308, 1, (unsigned char *)conf, 520, 1000)) < 0) - std::cout << "libusb_control_transfer5: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_release_interface(handle, 1)) < 0) - std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl; - if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl; - - libusb_close(handle); + CHK(connection->setReport(0x0308, (unsigned char *)conf, 520)); + CHK(connection->close()); return 0; } ssize_t Conf::writeConfigToDevice(conf_1 *conf) { - int r = 0; - libusb_device_handle *handle; - if ((r = libusb_open(m_device, &handle)) < 0) - std::cout << "libusb_open: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl; - if ((r = libusb_claim_interface(handle, 1)) < 0) - std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl; - - // conf_1 + ssize_t r; + CHK(connection->open()); conf->req_type = 0x92; - if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0308, 1, (unsigned char *)conf, 520, 1000)) < 0) - std::cout << "libusb_control_transfer5: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_release_interface(handle, 1)) < 0) - std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl; - if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl; - - libusb_close(handle); + CHK(connection->setReport(0x0308, (unsigned char *)conf, 520)); + CHK(connection->close()); return 0; } ssize_t Conf::readConfigFromDevice(conf_2 *conf) { - unsigned char send_data0[8]; - memset(send_data0, 0, 8 * sizeof(unsigned char)); - send_data0[0] = 0x05; - send_data0[1] = 0x22; // conf 2, wireless + unsigned char _data[8] = {0x05, 0x22, 0, 0, 0, 0, 0, 0}; + /*if(!connection->isWireless()) + _data[1] = 0x12;*/ - // get config before write new config - // conf_1 - int r = 0; - libusb_device_handle *handle; - if ((r = libusb_open(m_device, &handle)) < 0) - std::cout << "libusb_open: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl; - if ((r = libusb_claim_interface(handle, 1)) < 0) - std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl; - - // conf_2 - if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0) - std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl; - if ((r = libusb_control_transfer(handle, 0xa1, 0x01, 0x0308, 1, (unsigned char *)conf, 520, 5000)) < 0) - std::cout << "libusb_control_transfer4: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_release_interface(handle, 1)) < 0) - std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl; - if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl; - - libusb_close(handle); + ssize_t r; + CHK(connection->open()); + CHK(connection->setReport(0x0305, (unsigned char *)_data, 8)); + CHK(connection->getReport(0x0308, (unsigned char *)conf, 520)); + CHK(connection->close()); return 0; } ssize_t Conf::batteryStatus() { - unsigned char dat[520]; - unsigned char send_data0[8]; - memset(send_data0, 0, 8 * sizeof(unsigned char)); - memset(dat, 0, 520 * sizeof(unsigned char)); - send_data0[0] = 0x05; - send_data0[1] = 0x90; // get battery status, wireless + unsigned char dat[8]; + memset(dat, 0, 8 * sizeof(unsigned char)); - // get config before write new config - // conf_1 - int r = 0; - libusb_device_handle *handle; - if ((r = libusb_open(m_device, &handle)) < 0) - std::cout << "libusb_open: " << libusb_error_name(r) << std::endl; + unsigned char _data[8] = {0x05, 0x90, 0, 0, 0, 0, 0, 0}; - if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl; - if ((r = libusb_claim_interface(handle, 1)) < 0) - std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl; - - // conf_2 - if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0) - std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl; - if ((r = libusb_control_transfer(handle, 0xa1, 0x01, 0x0305, 1, (unsigned char *)dat, 8, 5000)) < 0) - std::cout << "libusb_control_transfer4: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_release_interface(handle, 1)) < 0) - std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl; - if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl; + ssize_t r; + CHK(connection->open()); + CHK(connection->setReport(0x0305, (unsigned char *)_data, 8)); + CHK(connection->getReport(0x0305, (unsigned char *)dat, 8)); + CHK(connection->close()); for (int i = 0; i < 16; i++) { @@ -299,8 +251,6 @@ ssize_t Conf::batteryStatus() } std::cout << std::endl; - libusb_close(handle); - if (dat[2] == 0x10 && dat[3] == 0x01) return -1; @@ -313,6 +263,72 @@ void Conf::setBatteryStatus(ssize_t bat) Q_EMIT batteryStatusChanged(); } +ssize_t Conf::readMacroFromDevice(macro *_macro, int id) +{ + if (id > 255) + { + std::cout << "No more than 255 macros on device" << std::endl; + return -1; + } + + memset(_macro, 0, 520 * sizeof(unsigned char)); + + unsigned char _data[8] = {0x05, 0x31, id, 0, 0, 0, 0, 0}; + + ssize_t r; + CHK(connection->open()); + CHK(connection->setReport(0x0305, (unsigned char *)_data, 8)); + CHK(connection->getReport(0x0308, (unsigned char *)_macro, 520)); + CHK(connection->close()); + + std::cout << std::hex << (int)_macro->macro_nr << "\t"; + std::cout << std::endl; + + return 0; +} + +ssize_t Conf::writeMacroToDevice(macro *_macro) +{ + + // conf_1 + _macro->set_report_req[0] = 0x80; + _macro->set_report_req[1] = 0x30; + _macro->set_report_req[2] = 0x02; + ssize_t r; + CHK(connection->open()); + CHK(connection->setReport(0x0308, (unsigned char *)_macro, 520)); + CHK(connection->close()); + + return 0; +} + +ssize_t Conf::readMacrosFromDevice(macro **¯os, int cnt) +{ + if (cnt > 255) + { + std::cout << "No more than 255 macros on device" << std::endl; + return -1; + } + + macros = (macro **)malloc(cnt * sizeof(macro *)); + + connection->open(); + connection->keepConnection(true); + + for (int i = 1; i <= cnt; i++) + { + // get macro + // ist das bissl kacke weil immer neuer handle und detach und attach hmm + macros[i - 1] = (macro *)malloc(sizeof(macro)); + readMacroFromDevice(macros[i - 1], i); + } + + connection->keepConnection(false); + connection->close(); + + return 0; +} + ssize_t Conf::readAssignedMacrosFromDevice() { // check all the keys for macro mod @@ -325,84 +341,36 @@ ssize_t Conf::readAssignedMacrosFromDevice() std::cout << macroCnt << std::endl; unsigned char conf[520]; - unsigned char send_data0[8]; - memset(send_data0, 0, 8 * sizeof(unsigned char)); - send_data0[0] = 0x05; - send_data0[1] = 0x31; // macro, wireless - send_data0[2] = 0x01; // macro nr + memset(conf, 0, 520 * sizeof(unsigned char)); - int r = 0; + unsigned char _data[8] = {0x05, 0x31, 1, 0, 0, 0, 0, 0}; - libusb_device_handle *handle; - if ((r = libusb_open(m_device, &handle)) < 0) - std::cout << "libusb_open: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl; - if ((r = libusb_claim_interface(handle, 1)) < 0) - std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl; - - for (int i = 0; i < macroCnt; i++) + ssize_t r; + CHK(connection->open()); + for (int i = 1; i <= macroCnt; i++) { - send_data0[2] = i; - // get macro - - if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0) - std::cout << "libusb_control_transfer3: " << libusb_error_name(r) << std::endl; - if ((r = libusb_control_transfer(handle, 0xa1, 0x01, 0x0308, 1, (unsigned char *)conf, 520, 5000)) < 0) - std::cout << "libusb_control_transfer4: " << libusb_error_name(r) << std::endl; + _data[2] = i; + CHK(connection->setReport(0x0305, _data, 8)); + CHK(connection->getReport(0x0308, (unsigned char *)conf, 520)); } - - if ((r = libusb_release_interface(handle, 1)) < 0) - std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl; - if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl; - - for (int i = 0; i < 520; i++) - { - std::cout << std::hex << (int)conf[i] << "\t"; - } - std::cout << std::endl; - - libusb_close(handle); + CHK(connection->close()); return 0; } ssize_t Conf::readConfigFromDevice(conf_1 *conf) { - unsigned char send_data0[8]; - memset(send_data0, 0, 8 * sizeof(unsigned char)); - send_data0[0] = 0x05; - send_data0[1] = 0x21; // conf 1, wireless + unsigned char _data[8] = {0x05, 0x21, 0, 0, 0, 0, 0, 0}; + /*if(!connection->isWireless()) + _data[1] = 0x11;*/ - // get config before write new config - // conf_1 - int r = 0; - libusb_device_handle *handle; - if ((r = libusb_open(m_device, &handle)) < 0) - std::cout << "libusb_open: " << libusb_error_name(r) << std::endl; + ssize_t r; + CHK(connection->open()); + CHK(connection->setReport(0x0305, _data, 8)); + CHK(connection->getReport(0x0308, (unsigned char *)conf, 520)); + CHK(connection->close()); - if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_detach_kernel_driver: " << libusb_error_name(r) << std::endl; - if ((r = libusb_claim_interface(handle, 1)) < 0) - std::cout << "libusb_claim_interface: " << libusb_error_name(r) << std::endl; - - // get config before write new config - // conf_1 - if ((r = libusb_control_transfer(handle, 0x21, 0x09, 0x0305, 1, send_data0, 8, 5000)) < 0) - std::cout << "libusb_control_transfer1: " << libusb_error_name(r) << std::endl; - if ((r = libusb_control_transfer(handle, 0xa1, 0x01, 0x0308, 1, (unsigned char *)conf, 520, 5000)) < 0) - std::cout << "libusb_control_transfer2: " << libusb_error_name(r) << std::endl; - - if ((r = libusb_release_interface(handle, 1)) < 0) - std::cout << "libusb_release_interface: " << libusb_error_name(r) << std::endl; - if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) - std::cout << "libusb_attach_kernel_driver: " << libusb_error_name(r) << std::endl; - - libusb_close(handle); - - return 0; + return ssize_t(0); } ssize_t Conf::writeConfigToFile() @@ -461,7 +429,6 @@ ssize_t Conf::readConfigFromFile(const char *filePath, conf_1 *conf) } ssize_t Conf::readConfigFromFile(const char *filePath, conf_2 *conf) - { FILE *infile; diff --git a/src/conf.h b/src/conf.h index a4e58f5..0895c86 100644 --- a/src/conf.h +++ b/src/conf.h @@ -14,6 +14,7 @@ #include "structs.h" #include #include +#include "usb_thingy.h" #define CONF_FILE "conf.bin" @@ -35,13 +36,13 @@ public: Q_SIGNAL void lightModeChanged(); Q_INVOKABLE ssize_t restoreConfigs(); - - Q_INVOKABLE ssize_t writeConfigToFile(); - ssize_t writeConfigToFile(const char* filePath); - Q_INVOKABLE ssize_t readConfigFromFile(); - ssize_t readConfigFromFile(const char* filePath); - //all the config should be in a single file + Q_INVOKABLE ssize_t writeConfigToFile(); + ssize_t writeConfigToFile(const char *filePath); + Q_INVOKABLE ssize_t readConfigFromFile(); + ssize_t readConfigFromFile(const char *filePath); + + // all the config should be in a single file ssize_t writeConfigToFile(conf_1 *conf, const char *filePath); ssize_t writeConfigToFile(conf_2 *conf, const char *filePath); ssize_t readConfigFromFile(const char *filePath, conf_1 *conf); @@ -53,14 +54,23 @@ public: Q_INVOKABLE ssize_t readAssignedMacrosFromDevice(); + Q_INVOKABLE ssize_t readMacrosFromDevice(macro **¯os, int cnt); + Q_INVOKABLE ssize_t readMacroFromDevice(macro *_macro, int id); + Q_INVOKABLE ssize_t writeMacroToDevice(macro *_macro); + + Q_INVOKABLE ssize_t appendMacroToFile(macro *_macro, const char *filePath); + Q_INVOKABLE ssize_t deleteMacroFromFile(macro *_macro, const char *filePath); + ssize_t batteryStatus(); Q_INVOKABLE void setBatteryStatus(ssize_t bat); Q_SIGNAL void batteryStatusChanged(); + Q_INVOKABLE void testFunc(); Q_SIGNALS: private: + macro **m_macros; ssize_t m_stat; ssize_t m_bat; int m_lightMode; @@ -69,6 +79,7 @@ private: libusb_device *m_device = NULL; libusb_context *m_ctx = NULL; QString m_fileName; + Connection *connection; }; #endif diff --git a/src/structs.h b/src/structs.h index 7300a20..d6a1a1b 100644 --- a/src/structs.h +++ b/src/structs.h @@ -33,9 +33,9 @@ struct conf_1 struct key_conf { uint8_t pref; - uint8_t mod; - uint8_t keycode; - uint8_t __u1; + uint8_t mod; // or macro id + uint8_t keycode; // for macro cycle type + uint8_t macro_cycle; // for macro cycle count }; struct conf_2 @@ -45,7 +45,7 @@ struct conf_2 uint8_t __u2; // 0x02 zero uint8_t req_type; // 0x92, 0x50 maybe for if write or read 0x00 uint8_t __u3[0x8 - 0x4]; // 0x04-0x07 zeroes - key_conf mouse_buttons[6]; + key_conf mouse_buttons[7]; /*key_conf l_mouse; // 0x08-0x0b 4 Byte für linke Maustaste key_conf r_mouse; // 0x0c-0x0f 4 Byte für rechte Maustaste key_conf m_mouse; // 0x10-0x13 4 Byte für Mausrad taste @@ -59,8 +59,21 @@ struct conf_2 uint8_t __u5[0x207 - 0x47]; // 0x48-0x58 ?? 0x58-end zeros }; +struct macro_event{ + uint8_t updown_plus_delay_upper; + uint8_t delay_lower; + uint8_t keycode; +}; + struct macro { + uint8_t set_report_req[3]; //wirte macro Set_report 0x08 0x30 0x02 + uint8_t __u1[5]; + uint8_t macro_nr; + uint8_t __u2; + uint8_t event_cnt; + macro_event events[0xa8]; + uint8_t __u3[5]; }; struct conf_12 diff --git a/src/usb_thingy.cpp b/src/usb_thingy.cpp index 483ee1d..4fb1996 100644 --- a/src/usb_thingy.cpp +++ b/src/usb_thingy.cpp @@ -1,25 +1,109 @@ - #include +#include "usb_thingy.h" -/*S::S() +ssize_t logError(const std::string& errorMessage, const char* libusb_error_message, const char* file, int line, const char* function) { + std::cerr << "ERROR: " << file << ":" << line << " - " << function << ": " << errorMessage << libusb_error_message << std::endl; + return 1; +} + +Connection::Connection() { - int r = libusb_init(&ctx); - if (r < 0) + int r; + if ((r = libusb_init(&ctx)) < 0) { std::cout << libusb_error_name(r) << std::endl; exit(1); } +} + +ssize_t Connection::findDevice() +{ + // Find device by iterating through device list libusb_device **list; + libusb_device *found_device = NULL; ssize_t cnt = libusb_get_device_list(ctx, &list); for (ssize_t i = 0; i < cnt; i++) { - libusb_device *device = list[i]; + libusb_device *_device = list[i]; libusb_device_descriptor desc; - libusb_get_device_descriptor(device, &desc); + libusb_get_device_descriptor(_device, &desc); if ((desc.idProduct == 0x2f || desc.idProduct == 0x2e) && desc.idVendor == 0x258a) { + found_device = _device; + if (desc.idProduct == 0x2f) + wireless = true; + if (desc.idProduct == 0x2e) + wireless = false; break; } } -}*/ \ No newline at end of file + + libusb_free_device_list(list, 1); + + if(!found_device) + return ssize_t(1); + + device = found_device; + return ssize_t(0); +} + +void Connection::keepConnection(bool keep) +{ + keepConnectionSwitch = keep; +} + +ssize_t Connection::open() +{ + if (keepConnectionSwitch) + return 0; + + int r; + if ((r = libusb_open(device, &handle)) < 0) + return logError("ERROR: libusb_open: ", libusb_error_name(r), __FILE__, __LINE__, __func__); + if ((r = libusb_detach_kernel_driver(handle, 1)) < 0) + return logError("ERROR: libusb_detach_kernel_driver: ", libusb_error_name(r), __FILE__, __LINE__, __func__); + if ((r = libusb_claim_interface(handle, 1)) < 0) + return logError("ERROR: libusb_claim_interface: ", libusb_error_name(r), __FILE__, __LINE__, __func__); + + return ssize_t(0); +} + +ssize_t Connection::close() +{ + if (keepConnectionSwitch) + return 0; + + int r; + if ((r = libusb_release_interface(handle, 1)) < 0) + return logError("ERROR: libusb_release_interface: ", libusb_error_name(r), __FILE__, __LINE__, __func__); + if ((r = libusb_attach_kernel_driver(handle, 1)) < 0) + return logError("ERROR: libusb_attach_kernel_driver: ", libusb_error_name(r), __FILE__, __LINE__, __func__); + libusb_close(handle); + return ssize_t(0); +} + +ssize_t Connection::setReport(uint16_t wValue, unsigned char *send_data, uint16_t wLength) +{ + int r; + + if ((r = libusb_control_transfer(handle, 0x21, 0x09, wValue, 1, send_data, 8, 2000)) < 0) + return logError("ERROR: libusb_control_transfer: ", libusb_error_name(r), __FILE__, __LINE__, __func__); + + return ssize_t(0); +} + +ssize_t Connection::getReport(uint16_t wValue, unsigned char *receive_data, uint16_t wLength) +{ + int r; + + if ((r = libusb_control_transfer(handle, 0xa1, 0x01, wValue, 1, (unsigned char *)receive_data, wLength, 2000)) < 0) + return logError("ERROR: libusb_control_transfer: ", libusb_error_name(r), __FILE__, __LINE__, __func__); + + return ssize_t(0); +} + +bool Connection::isWireless() +{ + return wireless; +} diff --git a/src/usb_thingy.h b/src/usb_thingy.h index fd98b59..75c6a40 100644 --- a/src/usb_thingy.h +++ b/src/usb_thingy.h @@ -1,34 +1,39 @@ -class S -{ - public: - static S& getInstance() - { - static S instance; // Guaranteed to be destroyed. - // Instantiated on first use. - return instance; - } - private: - S() {} // Constructor? (the {} brackets) are needed here. +#ifndef CONNECTION_H +#define CONNECTION_H - // C++ 03 - // ======== - // Don't forget to declare these two. You want to make sure they - // are inaccessible(especially from outside), otherwise, you may accidentally get copies of - // your singleton appearing. - S(S const&); // Don't Implement - void operator=(S const&); // Don't implement +#include +#include - // C++ 11 - // ======= - // We can use the better technique of deleting the methods - // we don't want. - public: - S(S const&) = delete; - void operator=(S const&) = delete; +// Singleton class +class Connection { +private: + // Private constructor to prevent instantiation + Connection(); + libusb_context *ctx; + libusb_device *device; + libusb_device_handle *handle; + bool wireless; + bool keepConnectionSwitch; - // Note: Scott Meyers mentions in his Effective Modern - // C++ book, that deleted functions should generally - // be public as it results in better error messages - // due to the compilers behavior to check accessibility - // before deleted status -}; \ No newline at end of file + + // Delete the copy constructor and assignment operator to prevent copying + Connection(const Connection&) = delete; + Connection& operator=(const Connection&) = delete; + +public: + // Static method to get the single instance of the class + static Connection& getInstance() { + static Connection instance; // This line creates the instance only once + return instance; + } + + ssize_t findDevice(); + void keepConnection(bool); + ssize_t open(); + ssize_t close(); + ssize_t setReport(uint16_t, unsigned char*, uint16_t); + ssize_t getReport(uint16_t, unsigned char*, uint16_t); + bool isWireless(); +}; + +#endif \ No newline at end of file