Skip to content

Commit acc9d98

Browse files
committed
Added unit tests to test private functions
These functions implement the RSP protocol and deal with the string buffer.
1 parent b65770f commit acc9d98

File tree

5 files changed

+215
-60
lines changed

5 files changed

+215
-60
lines changed

src/libosd/gdbserver-private.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* Copyright 2018 The Open SoC Debug Project
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#ifndef OSD_GDBSERVER_PRIVATE_H
17+
#define OSD_GDBSERVER_PRIVATE_H
18+
19+
#include <osd/hostmod.h>
20+
#include <osd/osd.h>
21+
22+
#include <stdlib.h>
23+
24+
/**
25+
* Return packet-data from the received data buffer by validating the checksum
26+
*
27+
* @param buf_p the pointer to the received packet buffer data
28+
* @param ver_checksum '1' indicates valid checksum
29+
* @param len the length of the packet-data
30+
* @param buffer the packet-data received
31+
*
32+
*/
33+
osd_result validate_rsp_packet(char *buf_p, bool *ver_checksum, int *len,
34+
char *buffer);
35+
36+
37+
/**
38+
* Set packet-data into the RSP format: $packet-data#checksum
39+
*
40+
* @param buffer the packet-data buffer
41+
* @param len the length of the packet-data
42+
* @param packet_buffer the packet buffer in RSP format
43+
*/
44+
osd_result configure_rsp_packet(char *buffer, int len, char *packet_buffer);
45+
46+
#endif // OSD_GDBSERVER_PRIVATE_H

src/libosd/gdbserver.c

Lines changed: 68 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
#include <osd/gdbserver.h>
17+
#include "gdbserver-private.h"
1718
#include <osd/module.h>
1819
#include <osd/osd.h>
1920
#include <osd/reg.h>
@@ -128,33 +129,6 @@ osd_result osd_gdbserver_connect(struct osd_gdbserver_ctx *ctx, char *name,
128129
return OSD_ERROR_CONNECTION_FAILED;
129130
}
130131

131-
struct sockaddr_in addr_in;
132-
addr_in.sin_port = 0;
133-
socklen_t addr_in_size = sizeof(addr_in);
134-
135-
getsockname(ctx->fd, (struct sockaddr *)&addr_in, &addr_in_size);
136-
printf("server started on %s, listening on port %d\n", name,
137-
ntohs(addr_in.sin_port));
138-
139-
while (1) {
140-
ctx->client_fd =
141-
accept(ctx->fd, (struct sockaddr *)&addr_in, &addr_in_size);
142-
if (OSD_FAILED(ctx->client_fd)) {
143-
rv = close(ctx->client_fd);
144-
if (OSD_SUCCEEDED(rv)) {
145-
break;
146-
}
147-
}
148-
printf("Server got connection from client %s\n",
149-
inet_ntoa(addr_in.sin_addr));
150-
151-
if (OSD_SUCCEEDED(close(ctx->client_fd))) {
152-
break;
153-
}
154-
}
155-
156-
close(ctx->fd);
157-
158132
return OSD_OK;
159133
}
160134

@@ -185,6 +159,47 @@ void osd_gdbserver_free(struct osd_gdbserver_ctx **ctx_p)
185159
*ctx_p = NULL;
186160
}
187161

162+
API_EXPORT
163+
osd_result osd_gdbserver_start(struct osd_gdbserver_ctx *ctx)
164+
{
165+
osd_result rv;
166+
167+
struct sockaddr_in addr_in;
168+
addr_in.sin_port = 0;
169+
socklen_t addr_in_size = sizeof(addr_in);
170+
171+
getsockname(ctx->fd, (struct sockaddr *)&addr_in, &addr_in_size);
172+
printf("server started listening on port %d\n", ntohs(addr_in.sin_port));
173+
174+
while (1) {
175+
ctx->client_fd =
176+
accept(ctx->fd, (struct sockaddr *)&addr_in, &addr_in_size);
177+
if (OSD_FAILED(ctx->client_fd)) {
178+
rv = close(ctx->client_fd);
179+
if (OSD_SUCCEEDED(rv)) {
180+
break;
181+
}
182+
}
183+
184+
// At this point, connection is established between GDB client
185+
// and gdbserver, and they are ready to transfer data.
186+
// More functions to be added
187+
printf("Server got connection from client %s\n",
188+
inet_ntoa(addr_in.sin_addr));
189+
190+
if (OSD_SUCCEEDED(close(ctx->client_fd))) {
191+
break;
192+
}
193+
}
194+
return OSD_OK;
195+
}
196+
197+
API_EXPORT
198+
osd_result osd_gdbserver_stop(struct osd_gdbserver_ctx *ctx)
199+
{
200+
return close(ctx->fd);
201+
}
202+
188203
API_EXPORT
189204
osd_result osd_gdbserver_read_data(struct osd_gdbserver_ctx *ctx)
190205
{
@@ -225,8 +240,6 @@ osd_result osd_gdbserver_write_data(struct osd_gdbserver_ctx *ctx, char *data,
225240

226241
static osd_result get_char(struct osd_gdbserver_ctx *ctx, int *ch)
227242
{
228-
osd_result rv;
229-
230243
ctx->buf_p = ctx->buffer;
231244
ctx->buf_cnt--;
232245
if (OSD_FAILED(ctx->buf_cnt)) {
@@ -237,30 +250,22 @@ static osd_result get_char(struct osd_gdbserver_ctx *ctx, int *ch)
237250
return OSD_OK;
238251
}
239252

240-
static osd_result validate_rsp_packet(struct osd_gdbserver_ctx *ctx,
241-
bool *ver_checksum, int *len,
242-
char *buffer)
253+
//API_EXPORT
254+
osd_result validate_rsp_packet(char *buf_p, bool *ver_checksum, int *len,
255+
char *buffer)
243256
{
244257
unsigned char val_checksum = 0;
245258
char packet_checksum[3];
246259
int packet_char;
247260
int cnt = 0;
248-
osd_result rv;
249-
250-
char *buf_p = ctx->buf_p;
251-
int buf_cnt = ctx->buf_cnt;
261+
char *buf = buf_p;
252262

253263
// packet-format: $packet-data#checksum
254-
int i = 0;
255-
char *buf = buf_p;
256-
int done = 0;
257264
// traversing through the obtained packet till we obtained '#'
258265
while (1) {
259266
packet_char = *buf++;
260-
i++;
261267

262268
if (packet_char == '#') {
263-
done = 1;
264269
break;
265270
}
266271
/*Any escaped byte (here, '}') is transmitted as the escape
@@ -269,7 +274,6 @@ static osd_result validate_rsp_packet(struct osd_gdbserver_ctx *ctx,
269274
if (packet_char == '}') {
270275
val_checksum += packet_char & 0xff;
271276
packet_char = *buf++;
272-
i++;
273277
val_checksum += packet_char & 0xff;
274278
buffer[cnt++] = (packet_char ^ 0x20) & 0xff;
275279
} else {
@@ -278,6 +282,7 @@ static osd_result validate_rsp_packet(struct osd_gdbserver_ctx *ctx,
278282
}
279283
}
280284

285+
buffer[cnt] = '\0';
281286
*len = cnt;
282287
packet_char = *buf++;
283288
packet_checksum[0] = packet_char;
@@ -303,7 +308,7 @@ static osd_result receive_rsp_packet(struct osd_gdbserver_ctx *ctx,
303308
} while (packet_char != '$');
304309

305310
bool ver_checksum = 0;
306-
rv = validate_rsp_packet(ctx, &ver_checksum, len, buffer);
311+
rv = validate_rsp_packet(ctx->buf_p, &ver_checksum, len, buffer);
307312

308313
if (OSD_FAILED(rv)) {
309314
return rv;
@@ -320,23 +325,32 @@ static osd_result receive_rsp_packet(struct osd_gdbserver_ctx *ctx,
320325
return OSD_OK;
321326
}
322327

328+
API_EXPORT
329+
osd_result configure_rsp_packet(char *buffer, int len, char *packet_buffer)
330+
{
331+
int packet_checksum = 0;
332+
packet_buffer[0] = '$';
333+
memcpy(packet_buffer + 1, buffer, len);
334+
int j = len + 1;
335+
packet_buffer[j++] = '#';
336+
for (int i = 0; i < len; i++) {
337+
packet_checksum += buffer[i];
338+
}
339+
packet_buffer[j++] = dectohex((packet_checksum >> 4) & 0xf);
340+
packet_buffer[j++] = dectohex(packet_checksum & 0xf);
341+
packet_buffer[j] = '\0';
342+
343+
return OSD_OK;
344+
}
345+
323346
static osd_result send_rsp_packet(struct osd_gdbserver_ctx *ctx, char *buffer,
324347
int len)
325348
{
326-
char packet_buffer[len + 3];
327-
int packet_checksum = 0;
349+
char packet_buffer[len + 5];
328350
osd_result rv;
329351

330352
while (1) {
331-
packet_buffer[0] = '$';
332-
memcpy(packet_buffer + 1, buffer, len);
333-
int j = len + 1;
334-
packet_buffer[j++] = '#';
335-
for (int i = 0; i < len; i++) {
336-
packet_checksum += buffer[i];
337-
}
338-
packet_buffer[j++] = dectohex((packet_checksum >> 4) & 0xf);
339-
packet_buffer[j] = dectohex(packet_checksum & 0xf);
353+
configure_rsp_packet(buffer, len, packet_buffer);
340354

341355
rv = osd_gdbserver_write_data(ctx, packet_buffer, len + 4);
342356
if (OSD_FAILED(rv)) {
@@ -355,6 +369,4 @@ static osd_result send_rsp_packet(struct osd_gdbserver_ctx *ctx, char *buffer,
355369
return OSD_ERROR_FAILURE;
356370
}
357371
}
358-
359-
return OSD_OK;
360372
}

src/libosd/include/osd/gdbserver.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
#ifndef OSD_GDBSERVER_H
1717
#define OSD_GDBSERVER_H
1818

19-
#define OSD_GDBSERVER_PORT 5555
20-
#define OSD_GDBSERVER_BUFF_SIZE 1024
21-
2219
#include <osd/hostmod.h>
2320
#include <osd/osd.h>
2421

@@ -37,6 +34,16 @@ extern "C" {
3734

3835
struct osd_gdbserver_ctx;
3936

37+
/**
38+
* Indicates the port for connecting to GDB
39+
*/
40+
#define OSD_GDBSERVER_PORT 5555
41+
42+
/**
43+
* Indicates the size of the buffer
44+
*/
45+
#define OSD_GDBSERVER_BUFF_SIZE 1024
46+
4047
/**
4148
* Create a new context object
4249
*/
@@ -67,6 +74,16 @@ bool osd_gdbserver_is_connected(struct osd_gdbserver_ctx *ctx);
6774
*/
6875
void osd_gdbserver_free(struct osd_gdbserver_ctx **ctx_p);
6976

77+
/**
78+
* Start the connection with GDB client
79+
*/
80+
osd_result osd_gdbserver_start(struct osd_gdbserver_ctx *ctx);
81+
82+
/**
83+
* Close the connection with GDB client
84+
*/
85+
osd_result osd_gdbserver_stop(struct osd_gdbserver_ctx *ctx);
86+
7087
/**
7188
* Read data from the GDB client
7289
*

tests/unit/Makefile.am

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ check_PROGRAMS = \
1212
check_cl_cdm \
1313
check_memaccess \
1414
check_systracelogger \
15-
check_coretracelogger
15+
check_coretracelogger \
16+
check_gdbserver
1617

1718
check_hostmod_SOURCES = \
1819
check_hostmod.c \
@@ -54,6 +55,10 @@ check_coretracelogger_SOURCES = \
5455
check_coretracelogger.c \
5556
mock_host_controller.c
5657

58+
check_gdbserver_SOURCE = \
59+
check_gdbserver.c \
60+
mock_host_controller.c
61+
5762
TESTS = $(check_PROGRAMS)
5863

5964
AM_CFLAGS = \

tests/unit/check_gdbserver.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* Copyright 2018 The Open SoC Debug Project
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#define TEST_SUITE_NAME "check_gdbserver"
17+
18+
#include "testutil.h"
19+
20+
#include <../../src/libosd/gdbserver-private.h>
21+
#include <osd/osd.h>
22+
#include <osd/reg.h>
23+
24+
#include "mock_host_controller.h"
25+
26+
struct osd_gdbserver_ctx *gdbserver_ctx;
27+
struct osd_log_ctx *log_ctx;
28+
29+
const unsigned int target_subnet_addr = 0;
30+
unsigned int mock_hostmod_diaddr;
31+
unsigned int mock_scm_diaddr;
32+
33+
START_TEST(test_validate_rsp_packet)
34+
{
35+
osd_result rv;
36+
char packet_buffer[12] = "swbreak#ef";
37+
char *buf_p = "swbreak#ef";
38+
bool ver_checksum;
39+
int len;
40+
char buffer[1024];
41+
42+
rv = validate_rsp_packet(buf_p, &ver_checksum, &len, buffer);
43+
ck_assert(OSD_SUCCEEDED(rv));
44+
ck_assert_uint_eq(len, 7);
45+
ck_assert_str_eq(buffer, "swbreak");
46+
}
47+
END_TEST
48+
49+
START_TEST(test_configure_rsp_packet)
50+
{
51+
char buffer[8] = "swbreak";
52+
int packet_checksum;
53+
int len = 7;
54+
char packet_buffer[len + 5];
55+
56+
configure_rsp_packet(buffer, len, packet_buffer);
57+
ck_assert_str_eq(packet_buffer, "$swbreak#ef");
58+
}
59+
END_TEST
60+
61+
Suite *suite(void)
62+
{
63+
Suite *s;
64+
TCase *tc_testing;
65+
66+
s = suite_create(TEST_SUITE_NAME);
67+
68+
tc_testing = tcase_create("Testing");
69+
70+
tcase_add_test(tc_testing, test_validate_rsp_packet);
71+
tcase_add_test(tc_testing, test_configure_rsp_packet);
72+
suite_add_tcase(s, tc_testing);
73+
74+
return s;
75+
}

0 commit comments

Comments
 (0)