1.1 --- a/DJMFix.cpp Sun Dec 20 01:00:15 2020 +0100
1.2 +++ b/DJMFix.cpp Sun Dec 20 01:56:47 2020 +0100
1.3 @@ -36,11 +36,13 @@
1.4 std::recursive_mutex midiMutex;
1.5 std::atomic<bool> running{false};
1.6 std::atomic<bool> stopped{false};
1.7 + std::atomic<bool> sendKeepAlive{false};
1.8 + Bytes seed2;
1.9
1.10 void run() {
1.11 while (!stopped) {
1.12 std::cerr << "DJMFixImpl::run()" << std::endl; // TODO: do not mess STDIO
1.13 - // TODO: send keep-alive messages
1.14 + if (sendKeepAlive) send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x50, 0x01, 0xf7});
1.15 std::this_thread::sleep_for(std::chrono::milliseconds(200));
1.16 }
1.17 }
1.18 @@ -64,6 +66,16 @@
1.19 return result;
1.20 }
1.21
1.22 + Bytes denormalize(const Bytes& data) {
1.23 + Bytes result;
1.24 + result.reserve(data.size()*2);
1.25 + for (size_t i = 0; i < data.size(); i++) {
1.26 + result.push_back(data[i] >> 4);
1.27 + result.push_back(data[i] & 0x0F);
1.28 + }
1.29 + return result;
1.30 + }
1.31 +
1.32 uint32_t fnv32hash(const Bytes& buff) {
1.33 uint32_t hash = 0x811c9dc5;
1.34 for (uint8_t b : buff) hash = ((b^hash) * 0x1000193);
1.35 @@ -124,7 +136,7 @@
1.36 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});
1.37 } else if (midiMessage.size() == 54 && midiMessage[9] == 0x13 && midiMessage[33] == 0x04 && midiMessage[43] == 0x03) {
1.38 Bytes hash1(midiMessage.begin() + 35, midiMessage.begin() + 35 + 8);
1.39 - Bytes seed2(midiMessage.begin() + 45, midiMessage.begin() + 45 + 8);
1.40 + seed2 = Bytes(midiMessage.begin() + 45, midiMessage.begin() + 45 + 8);
1.41 hash1 = normalize(hash1);
1.42 seed2 = normalize(seed2);
1.43 std::cerr << "DJMFixImpl::receive(): got message with hash1 = " << toString(hash1) << " and seed2 = " << toString(seed2) << std::endl; // TODO: do not mess STDIO
1.44 @@ -135,10 +147,23 @@
1.45 Bytes hash1check = toBytes(fnv32hash(concat(seed1, xOR(seed0, seed2))));
1.46
1.47 if (equals(hash1, hash1check)) {
1.48 - std::cerr << "DJMFixImpl::receive(): hash1 verification: OK" << std::endl;
1.49 + std::cerr << "DJMFixImpl::receive(): hash1 verification: OK" << std::endl; // TODO: do not mess STDIO
1.50 + Bytes hash2 = toBytes(fnv32hash(concat(seed2, xOR(seed0, seed2))));
1.51 + 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})));
1.52 } else {
1.53 - std::cerr << "DJMFixImpl::receive(): hash1 verification: ERROR: check = " << toString(hash1check) << std::endl;
1.54 + std::cerr
1.55 + << "DJMFixImpl::receive(): hash1 verification failed: "
1.56 + << " midiMessage = " << toString(midiMessage)
1.57 + << " seed0 = " << toString(seed0)
1.58 + << " seed1 = " << toString(seed1)
1.59 + << " seed2 = " << toString(seed2)
1.60 + << " hash1 = " << toString(hash1)
1.61 + << " hash1check = " << toString(hash1check)
1.62 + << std::endl;
1.63 + // TODO: graceful death
1.64 }
1.65 + } else if (midiMessage.size() == 12 && midiMessage[9] == 0x15) {
1.66 + sendKeepAlive = true;
1.67 }
1.68
1.69 }