first working version (still dirty, but working) v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sun, 20 Dec 2020 01:56:47 +0100
branchv_0
changeset 8 87dfa7c89294
parent 7 889b4b8737bd
child 9 ee976a1d1f0a
first working version (still dirty, but working)
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<bool> running{false};
 	std::atomic<bool> stopped{false};
+	std::atomic<bool> 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;
 		}
 
 	}