115 return result; |
118 return result; |
116 } |
119 } |
117 |
120 |
118 public: |
121 public: |
119 |
122 |
|
123 DJMFixImpl(djmfix::logging::Logger* logger) : logger(logger ? logger : djmfix::logging::blackhole()) { |
|
124 } |
|
125 |
120 virtual ~DJMFixImpl() override { |
126 virtual ~DJMFixImpl() override { |
121 std::cerr << "~DJMFixImpl()" << std::endl; // TODO: do not mess STDIO |
127 logger->log(L::FINE, "~DJMFixImpl()"); |
122 if (running) stop(); |
128 if (running) stop(); |
123 } |
129 } |
124 |
130 |
125 void setMidiSender(MidiSender* midiSender) { |
131 void setMidiSender(MidiSender* midiSender) { |
126 std::cerr << "DJMFixImpl::setMidiSender()" << std::endl; // TODO: do not mess STDIO |
132 logger->log(L::FINE, "DJMFixImpl::setMidiSender()"); |
127 this->midiSender = midiSender; |
133 this->midiSender = midiSender; |
128 } |
134 } |
129 |
135 |
130 virtual void receive(const MidiMessage& midiMessage) override { |
136 virtual void receive(const MidiMessage& midiMessage) override { |
131 std::cerr << "DJMFixImpl::receive(): size = " << midiMessage.size() << " data = " << toString(midiMessage) << std::endl; // TODO: do not mess STDIO |
137 logger->log(L::INFO, "received message: size = " + std::to_string(midiMessage.size()) + " data = " + toString(midiMessage)); |
132 std::lock_guard<std::recursive_mutex> lock(midiMutex); |
138 std::lock_guard<std::recursive_mutex> lock(midiMutex); |
133 |
139 |
134 |
140 |
135 if (midiMessage.size() == 12 && midiMessage[9] == 0x11) { |
141 if (midiMessage.size() == 12 && midiMessage[9] == 0x11) { |
136 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}); |
142 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}); |
137 } else if (midiMessage.size() == 54 && midiMessage[9] == 0x13 && midiMessage[33] == 0x04 && midiMessage[43] == 0x03) { |
143 } else if (midiMessage.size() == 54 && midiMessage[9] == 0x13 && midiMessage[33] == 0x04 && midiMessage[43] == 0x03) { |
138 Bytes hash1(midiMessage.begin() + 35, midiMessage.begin() + 35 + 8); |
144 Bytes hash1(midiMessage.begin() + 35, midiMessage.begin() + 35 + 8); |
139 seed2 = Bytes(midiMessage.begin() + 45, midiMessage.begin() + 45 + 8); |
145 seed2 = Bytes(midiMessage.begin() + 45, midiMessage.begin() + 45 + 8); |
140 hash1 = normalize(hash1); |
146 hash1 = normalize(hash1); |
141 seed2 = normalize(seed2); |
147 seed2 = normalize(seed2); |
142 std::cerr << "DJMFixImpl::receive(): got message with hash1 = " << toString(hash1) << " and seed2 = " << toString(seed2) << std::endl; // TODO: do not mess STDIO |
148 logger->log(L::INFO, "got message with hash1 = " + toString(hash1) + " and seed2 = " + toString(seed2)); |
143 |
149 |
144 Bytes seed0 = {0x68, 0x01, 0x31, 0xFB}; |
150 Bytes seed0 = {0x68, 0x01, 0x31, 0xFB}; |
145 Bytes seed1 = {0x29, 0x00, 0x00, 0x00, 0x23, 0x48, 0x00, 0x00}; |
151 Bytes seed1 = {0x29, 0x00, 0x00, 0x00, 0x23, 0x48, 0x00, 0x00}; |
146 |
152 |
147 Bytes hash1check = toBytes(fnv32hash(concat(seed1, xOR(seed0, seed2)))); |
153 Bytes hash1check = toBytes(fnv32hash(concat(seed1, xOR(seed0, seed2)))); |
148 |
154 |
149 if (equals(hash1, hash1check)) { |
155 if (equals(hash1, hash1check)) { |
150 std::cerr << "DJMFixImpl::receive(): hash1 verification: OK" << std::endl; // TODO: do not mess STDIO |
156 logger->log(L::INFO, "hash1 verification: OK"); |
151 Bytes hash2 = toBytes(fnv32hash(concat(seed2, xOR(seed0, seed2)))); |
157 Bytes hash2 = toBytes(fnv32hash(concat(seed2, xOR(seed0, seed2)))); |
152 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}))); |
158 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}))); |
153 } else { |
159 } else { |
154 std::cerr |
160 std::stringstream logMessage; |
155 << "DJMFixImpl::receive(): hash1 verification failed: " |
161 logMessage |
|
162 << "hash1 verification failed: " |
156 << " midiMessage = " << toString(midiMessage) |
163 << " midiMessage = " << toString(midiMessage) |
157 << " seed0 = " << toString(seed0) |
164 << " seed0 = " << toString(seed0) |
158 << " seed1 = " << toString(seed1) |
165 << " seed1 = " << toString(seed1) |
159 << " seed2 = " << toString(seed2) |
166 << " seed2 = " << toString(seed2) |
160 << " hash1 = " << toString(hash1) |
167 << " hash1 = " << toString(hash1) |
161 << " hash1check = " << toString(hash1check) |
168 << " hash1check = " << toString(hash1check); |
162 << std::endl; |
169 logger->log(L::SEVERE, logMessage.str()); |
163 // TODO: graceful death |
170 // TODO: graceful death |
164 } |
171 } |
165 } else if (midiMessage.size() == 12 && midiMessage[9] == 0x15) { |
172 } else if (midiMessage.size() == 12 && midiMessage[9] == 0x15) { |
166 sendKeepAlive = true; |
173 sendKeepAlive = true; |
167 } |
174 } |
168 |
175 |
169 } |
176 } |
170 |
177 |
171 void start() override { |
178 void start() override { |
172 std::cerr << "DJMFixImpl::start()" << std::endl; // TODO: do not mess STDIO |
179 logger->log(L::FINE, "DJMFixImpl::start()"); |
173 if (midiSender == nullptr) throw std::logic_error("need a midiSender when starting DJMFix"); |
180 if (midiSender == nullptr) throw std::logic_error("need a midiSender when starting DJMFix"); |
174 |
181 |
175 // TODO: methods for parsing and constructing messages from parts (TLV) |
182 // TODO: methods for parsing and constructing messages from parts (TLV) |
176 send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x50, 0x01, 0xf7}); |
183 send({0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x17, 0x00, 0x50, 0x01, 0xf7}); |
177 |
184 |