# HG changeset patch # User František Kučera # Date 1608425807 -3600 # Node ID 87dfa7c892946fa85e46e81f8667445258b75538 # Parent 889b4b8737bda6787537a4073ddda6720a970478 first working version (still dirty, but working) diff -r 889b4b8737bd -r 87dfa7c89294 DJMFix.cpp --- a/DJMFix.cpp Sun Dec 20 01:00:15 2020 +0100 +++ b/DJMFix.cpp Sun Dec 20 01:56:47 2020 +0100 @@ -36,11 +36,13 @@ std::recursive_mutex midiMutex; std::atomic running{false}; std::atomic stopped{false}; + std::atomic sendKeepAlive{false}; + Bytes seed2; void run() { while (!stopped) { std::cerr << "DJMFixImpl::run()" << std::endl; // TODO: do not mess STDIO - // TODO: send keep-alive messages + if (sendKeepAlive) send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x50, 0x01, 0xf7}); std::this_thread::sleep_for(std::chrono::milliseconds(200)); } } @@ -64,6 +66,16 @@ return result; } + Bytes denormalize(const Bytes& data) { + Bytes result; + result.reserve(data.size()*2); + for (size_t i = 0; i < data.size(); i++) { + result.push_back(data[i] >> 4); + result.push_back(data[i] & 0x0F); + } + return result; + } + uint32_t fnv32hash(const Bytes& buff) { uint32_t hash = 0x811c9dc5; for (uint8_t b : buff) hash = ((b^hash) * 0x1000193); @@ -124,7 +136,7 @@ send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x12, 0x2a, 0x01, 0x0b, 0x50, 0x69, 0x6f, 0x6e, 0x65, 0x65, 0x72, 0x44, 0x4a, 0x02, 0x0b, 0x72, 0x65, 0x6b, 0x6f, 0x72, 0x64, 0x62, 0x6f, 0x78, 0x03, 0x12, 0x02, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0xf7}); } else if (midiMessage.size() == 54 && midiMessage[9] == 0x13 && midiMessage[33] == 0x04 && midiMessage[43] == 0x03) { Bytes hash1(midiMessage.begin() + 35, midiMessage.begin() + 35 + 8); - Bytes seed2(midiMessage.begin() + 45, midiMessage.begin() + 45 + 8); + seed2 = Bytes(midiMessage.begin() + 45, midiMessage.begin() + 45 + 8); hash1 = normalize(hash1); seed2 = normalize(seed2); std::cerr << "DJMFixImpl::receive(): got message with hash1 = " << toString(hash1) << " and seed2 = " << toString(seed2) << std::endl; // TODO: do not mess STDIO @@ -135,10 +147,23 @@ Bytes hash1check = toBytes(fnv32hash(concat(seed1, xOR(seed0, seed2)))); if (equals(hash1, hash1check)) { - std::cerr << "DJMFixImpl::receive(): hash1 verification: OK" << std::endl; + std::cerr << "DJMFixImpl::receive(): hash1 verification: OK" << std::endl; // TODO: do not mess STDIO + Bytes hash2 = toBytes(fnv32hash(concat(seed2, xOR(seed0, seed2)))); + send(concat({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x14, 0x38, 0x01, 0x0b, 0x50, 0x69, 0x6f, 0x6e, 0x65, 0x65, 0x72, 0x44, 0x4a, 0x02, 0x0b, 0x72, 0x65, 0x6b, 0x6f, 0x72, 0x64, 0x62, 0x6f, 0x78, 0x04, 0x0a}, concat(denormalize(hash2),{0x05, 0x16, 0x05, 0x09, 0x0b, 0x05, 0x04, 0x0b, 0x0f, 0x0e, 0x0e, 0x04, 0x04, 0x0a, 0x05, 0x0a, 0x0c, 0x08, 0x0e, 0x04, 0x0c, 0x05, 0xf7}))); } else { - std::cerr << "DJMFixImpl::receive(): hash1 verification: ERROR: check = " << toString(hash1check) << std::endl; + std::cerr + << "DJMFixImpl::receive(): hash1 verification failed: " + << " midiMessage = " << toString(midiMessage) + << " seed0 = " << toString(seed0) + << " seed1 = " << toString(seed1) + << " seed2 = " << toString(seed2) + << " hash1 = " << toString(hash1) + << " hash1check = " << toString(hash1check) + << std::endl; + // TODO: graceful death } + } else if (midiMessage.size() == 12 && midiMessage[9] == 0x15) { + sendKeepAlive = true; } }