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