xref: /reactos/drivers/base/kdgdb/gdb_receive.c (revision 9393fc32)
1 /*
2  * COPYRIGHT:       GPL, see COPYING in the top level directory
3  * PROJECT:         ReactOS kernel
4  * FILE:            drivers/base/kddll/gdb_receive.c
5  * PURPOSE:         Base functions for the kernel debugger.
6  */
7 
8 #include "kdgdb.h"
9 
10 /* GLOBALS ********************************************************************/
11 CHAR gdb_input[0x1000];
12 
13 /* GLOBAL FUNCTIONS ***********************************************************/
14 char
15 hex_value(char ch)
16 {
17     if ((ch >= '0') && (ch <= '9'))
18         return (ch - '0');
19 
20     if ((ch >= 'a') && (ch <= 'f'))
21         return (ch - 'a' + 10);
22 
23     if ((ch >= 'A') && (ch <= 'F'))
24         return (ch - 'A' + 10);
25 
26     return -1;
27 }
28 
29 KDSTATUS
30 NTAPI
31 gdb_receive_packet(_Inout_ PKD_CONTEXT KdContext)
32 {
33     UCHAR* ByteBuffer;
34     UCHAR Byte;
35     KDSTATUS Status;
36     CHAR CheckSum, ReceivedCheckSum;
37 
38     do
39     {
40         Status = KdpReceiveByte(&Byte);
41         if (Status != KdPacketReceived)
42             return Status;
43     } while (Byte != '$');
44 
45 get_packet:
46     CheckSum = 0;
47     ByteBuffer = (UCHAR*)gdb_input;
48 
49     while (TRUE)
50     {
51         /* Try to get a byte from the port */
52         Status = KdpReceiveByte(&Byte);
53         if (Status != KdPacketReceived)
54             return Status;
55 
56         if (Byte == '#')
57         {
58             *ByteBuffer = '\0';
59             break;
60         }
61         CheckSum += (CHAR)Byte;
62 
63         /* See if we should escape */
64         if (Byte == 0x7d)
65         {
66             Status = KdpReceiveByte(&Byte);
67             if (Status != KdPacketReceived)
68                 return Status;
69             CheckSum += (CHAR)Byte;
70             Byte ^= 0x20;
71         }
72         *ByteBuffer++ = Byte;
73     }
74 
75     /* Get Check sum (two bytes) */
76     Status = KdpReceiveByte(&Byte);
77     if (Status != KdPacketReceived)
78         goto end;
79     ReceivedCheckSum = hex_value(Byte) << 4;
80 
81     Status = KdpReceiveByte(&Byte);
82     if (Status != KdPacketReceived)
83         goto end;
84     ReceivedCheckSum += hex_value(Byte);
85 
86 end:
87     if (ReceivedCheckSum != CheckSum)
88     {
89         /* Do not acknowledge to GDB */
90         KDDBGPRINT("Check sums don't match!");
91         KdpSendByte('-');
92         return KdPacketNeedsResend;
93     }
94 
95     /* Ensure there is nothing left in the pipe */
96     while (KdpPollByte(&Byte) == KdPacketReceived)
97     {
98         switch (Byte)
99         {
100             case '$':
101                 KDDBGPRINT("Received new packet just after %s.\n", gdb_input);
102                 goto get_packet;
103             case 0x03:
104                 KdContext->KdpControlCPending = TRUE;
105                 break;
106         }
107     }
108 
109     /* Acknowledge */
110     KdpSendByte('+');
111 
112     return KdPacketReceived;
113 }
114