private KmmBody TxRxKmm(KmmBody commandKmmBody) { KmmFrame commandKmmFrame = new KmmFrame(commandKmmBody); byte[] toRadio = WithPreamble ? commandKmmFrame.ToBytesWithPreamble(Mfid) : commandKmmFrame.ToBytes(); byte[] fromRadio = DeviceProtocol.PerformKmmTransfer(toRadio); KmmFrame responseKmmFrame = new KmmFrame(WithPreamble, fromRadio); return(responseKmmFrame.KmmBody); }
public void MrRunProducer() { try { while (true) { byte rx; /* RX: KEY SIGNATURE */ // currently there is no rx key signature function in the adapter // however, the key signature will appear as a 0x00 byte // the 5 second timeout should prevent most sync issues, however // a rx key signature function should be added to the adapter // to make this more robust and correct Log.Debug("in: waiting for key signature"); rx = Protocol.GetByte(TIMEOUT_NONE); Log.Trace("in: {0}", Utility.DataFormat(rx)); byte sig = 0x00; // key signature if (rx == sig) { Log.Debug("in: got key signature"); } else { string msg = string.Format("in: unexpected key signature opcode, expected ({0}) got ({1})", Utility.DataFormat(sig), Utility.DataFormat(rx)); Log.Warn(msg); continue; } /* RX: READY REQUEST */ try { Log.Debug("in: waiting for ready request opcode"); rx = Protocol.GetByte(TIMEOUT_STD); Log.Trace("in: {0}", Utility.DataFormat(rx)); } catch (Exception) { string msg = string.Format("in: timed out waiting for ready request opcode"); Log.Warn(msg); continue; } if (rx == OPCODE_READY_REQ) { Log.Debug("in: got ready request opcode"); } else { string msg = string.Format("in: unexpected ready request opcode, expected ({0}) got ({1})", Utility.DataFormat(OPCODE_READY_REQ), Utility.DataFormat(rx)); Log.Warn(msg); continue; } /* TX: READY GENERAL MODE */ Log.Debug("out: ready general mode opcode"); Log.Trace("out: {0}", Utility.DataFormat(OPCODE_READY_GENERAL_MODE)); Protocol.SendByte(OPCODE_READY_GENERAL_MODE); while (true) { /* RX: FRAME TYPE */ try { Log.Debug("in: waiting for frame type opcode"); rx = Protocol.GetByte(TIMEOUT_STD); Log.Trace("in: {0}", Utility.DataFormat(rx)); } catch (Exception) { string msg = string.Format("in: timed out waiting for frame type opcode"); Log.Warn(msg); break; } if (rx == OPCODE_KMM) { Log.Debug("in: got kmm opcode"); List <byte> rxFrame; try { rxFrame = ParseKmmFrame(); } catch (Exception ex) { Log.Warn(ex.Message); break; } KmmFrame kfdKmmFrame = null; try { kfdKmmFrame = new KmmFrame(rxFrame.ToArray()); } catch (Exception ex) { Log.Warn(ex.Message); byte[] message = rxFrame.ToArray(); if (message.Length != 0) { Log.Warn("unexpected message id: {0} (dec), {0:X} (hex)", message[0]); NegativeAcknowledgment kmm = new NegativeAcknowledgment(); kmm.AcknowledgedMessageId = (MessageId)message[0]; kmm.Status = AckStatus.InvalidMessageId; KmmFrame frame = new KmmFrame(kmm); SendKmm(frame.ToBytes()); } continue; } KmmBody kfdKmmBody = kfdKmmFrame.KmmBody; if (kfdKmmBody is InventoryCommandListActiveKsetIds) { InventoryResponseListActiveKsetIds mrKmm = new InventoryResponseListActiveKsetIds(); // do not return any keysets, to match factory Motorola SU behavior KmmFrame commandKmmFrame = new KmmFrame(mrKmm); SendKmm(commandKmmFrame.ToBytes()); } else if (kfdKmmBody is ModifyKeyCommand) { ModifyKeyCommand cmdKmm = kfdKmmBody as ModifyKeyCommand; Log.Debug("keyset id: {0} (dec), {0:X} (hex)", cmdKmm.KeysetId); Log.Debug("algorithm id: {0} (dec), {0:X} (hex)", cmdKmm.AlgorithmId); RekeyAcknowledgment rspKmm = new RekeyAcknowledgment(); rspKmm.MessageIdAcknowledged = MessageId.ModifyKeyCommand; rspKmm.NumberOfItems = cmdKmm.KeyItems.Count; for (int i = 0; i < cmdKmm.KeyItems.Count; i++) { KeyItem item = cmdKmm.KeyItems[i]; Log.Debug("* key item {0} *", i); Log.Debug("erase: {0}", item.Erase); Log.Debug("sln: {0} (dec), {0:X} (hex)", item.SLN); Log.Debug("key id: {0} (dec), {0:X} (hex)", item.KeyId); Log.Debug("key: {0}", BitConverter.ToString(item.Key)); string algName = string.Empty; if (Enum.IsDefined(typeof(AlgorithmId), (byte)cmdKmm.AlgorithmId)) { algName = ((AlgorithmId)cmdKmm.AlgorithmId).ToString(); } else { algName = "UNKNOWN"; } Status += string.Format("Keyset ID: {0} (dec), {0:X} (hex)", cmdKmm.KeysetId) + Environment.NewLine + string.Format("SLN/CKR: {0} (dec), {0:X} (hex)", item.SLN) + Environment.NewLine + string.Format("Key ID: {0} (dec), {0:X} (hex)", item.KeyId) + Environment.NewLine + string.Format("Algorithm: {0} (dec), {0:X} (hex), {1}", cmdKmm.AlgorithmId, algName) + Environment.NewLine + string.Format("Key: {0}", BitConverter.ToString(item.Key).Replace("-", string.Empty)) + Environment.NewLine + "--" + Environment.NewLine; KeyStatus status = new KeyStatus(); status.AlgorithmId = cmdKmm.AlgorithmId; status.KeyId = item.KeyId; status.Status = 0x00; // command was performed rspKmm.Keys.Add(status); } KmmFrame cmdKmmFrame = new KmmFrame(rspKmm); SendKmm(cmdKmmFrame.ToBytes()); } } else if (rx == OPCODE_TRANSFER_DONE) { Log.Debug("in: got transfer done opcode"); /* TX: TRANSFER DONE */ Log.Debug("out: transfer done opcode"); Log.Trace("out: {0}", Utility.DataFormat(OPCODE_TRANSFER_DONE)); Protocol.SendByte(OPCODE_TRANSFER_DONE); /* RX: DISCONNECT */ try { Log.Debug("in: waiting for disconnect opcode"); rx = Protocol.GetByte(TIMEOUT_STD); Log.Trace("in: {0}", Utility.DataFormat(rx)); } catch (Exception) { string msg = string.Format("in: timed out waiting for disconnect opcode"); Log.Warn(msg); break; } if (rx == OPCODE_DISCONNECT) { Log.Debug("in: got disconnect opcode"); } else { string msg = string.Format("in: unexpected disconnect opcode, expected ({0}) got ({1})", Utility.DataFormat(OPCODE_DISCONNECT), Utility.DataFormat(rx)); Log.Warn(msg); break; } /* TX: DISCONNECT ACKNOWLEDGE */ Log.Debug("out: disconnect acknowledge opcode"); Log.Trace("out: {0}", Utility.DataFormat(OPCODE_DISCONNECT_ACK)); Protocol.SendByte(OPCODE_DISCONNECT_ACK); break; } else { string msg = string.Format("in: unexpected frame type opcode ({0})", Utility.DataFormat(rx)); Log.Warn(msg); break; } } } } catch (OperationCanceledException) { Log.Debug("operation cancelled"); return; } catch (Exception ex) { Log.Warn("error in mr emulation: {0}", ex.Message); throw; } }