1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using System.Text; 9 10 namespace Antmicro.Renode.Utilities.GDB 11 { 12 public class PacketBuilder 13 { PacketBuilder()14 public PacketBuilder() 15 { 16 checksum = new byte[2]; 17 } 18 AppendByte(byte b)19 public Result AppendByte(byte b) 20 { 21 switch(state) 22 { 23 case State.NoPacket: 24 switch(b) 25 { 26 case InterruptSymbol: 27 return new Result(interrupt: true); 28 case PacketStartSymbol: 29 state = State.Data; 30 packetData = new PacketData(); 31 break; 32 } 33 break; 34 case State.Data: 35 if(!escape && b == PacketStopSymbol) 36 { 37 state = State.Checksum1; 38 break; 39 } 40 escape = !packetData.AddByte(b); 41 break; 42 case State.Checksum1: 43 checksum[0] = b; 44 state = State.Checksum2; 45 break; 46 case State.Checksum2: 47 checksum[1] = b; 48 state = State.NoPacket; 49 50 var checksumValue = (byte)Convert.ToUInt32(Encoding.ASCII.GetString(checksum), 16); 51 Packet packet; 52 if(!Packet.TryCreate(packetData, checksumValue, out packet)) 53 { 54 return new Result(packet, corruptedPacket: true); 55 } 56 return new Result(packet); 57 } 58 return null; 59 } 60 61 private bool escape; 62 private State state; 63 private PacketData packetData; 64 65 private readonly byte[] checksum; 66 67 private const byte PacketStartSymbol = (byte)'$'; 68 private const byte PacketStopSymbol = (byte)'#'; 69 private const byte InterruptSymbol = 0x03; 70 71 private enum State 72 { 73 NoPacket, 74 Data, 75 Checksum1, 76 Checksum2 77 } 78 79 public class Result 80 { Result(Packet packet = null, bool corruptedPacket = false, bool interrupt = false)81 public Result(Packet packet = null, bool corruptedPacket = false, bool interrupt = false) 82 { 83 Packet = packet; 84 Interrupt = interrupt; 85 CorruptedPacket = corruptedPacket; 86 } 87 88 public Packet Packet { get; private set; } 89 public bool Interrupt { get; private set; } 90 public bool CorruptedPacket { get; private set; } 91 } 92 } 93 } 94 95