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 887dfa7c89294
parent 7 889b4b8737bd
child 9 ee976a1d1f0a
first working version (still dirty, but working)
DJMFix.cpp
     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  	}