1 /*
2 * Copyright 2016 Google Inc. All Rights Reserved.
3 * Author: gkalsi@google.com (Gurjant Kalsi)
4 *
5 * Use of this source code is governed by a MIT-style
6 * license that can be found in the LICENSE file or at
7 * https://opensource.org/licenses/MIT
8 *
9 *******************************************************************************
10 *
11 * This app serves as an example of how to use the high level bidirectional
12 * debugging pipe.
13 *
14 * The high level debugging protocol supports three operations:
15 *
16 * + ndebugusr_await_host(timeout);
17 * + ndebug_read_usr(buffer, timeout);
18 * + ndebug_write_usr(buffer, bytes, timeout);
19 *
20 * The client must call ndebugusr_await_host prior to using the read/write api.
21 * When a transport is connected and a remote debugger becomes available, this
22 * method will return NO_ERROR. At this point, the client is welcome to use the
23 * read/write API.
24 *
25 * Any subsequent read/write operation may return ERR_CHANNEL_CLOSED. This is
26 * because we must be able to accommodate the possibility of the device becoming
27 * disconnected.
28 * If ERR_CHANNEL_CLOSED is received, the client MUST assume that the connection
29 * has closed and will not be recovered.
30 * The client MUST NOT issue any more read or write calls.
31 * The client MUST call ndebugusr_await_host and wait for the host to become
32 * active again at which point the client will be given a new connection to a
33 * new host.
34 *
35 * The following example app implements a simple echo server that demonstrates
36 * data being read then echoed back to the host.
37 */
38
39 #include <lib/ndebug/ndebug.h>
40 #include <lib/ndebug/user.h>
41
42 #include <app.h>
43 #include <lk/debug.h>
44 #include <lk/err.h>
45 #include <string.h>
46
ndebugtest_entry(const struct app_descriptor * app,void * args)47 static void ndebugtest_entry(const struct app_descriptor *app, void *args) {
48 // Pad the buffer with one extra byte to acommodate a NULL character for
49 // printing using printf(...)
50 static uint8_t buf[NDEBUG_USR_MAX_PACKET_SIZE + 1];
51
52 while (true) {
53 // Wait for USB to connect and somebody to answer the phone on the other
54 // end of the line.
55 status_t result = ndebug_await_connection_usr(INFINITE_TIME);
56 if (result != NO_ERROR) {
57 printf("Error %d while awaiting host. Retrying...\n", result);
58 continue;
59 }
60
61 // Read bytes from the USB stack and echo them back to the host until
62 // the channel is closed. When the channel is closed, go back to waiting
63 // for the host to reopen the channel.
64 // Continue this process indefinitely.
65 while (true) {
66
67 // Read some bytes from the USB stack
68 ssize_t bytes_read =
69 ndebug_read_usr(buf, INFINITE_TIME);
70 if (bytes_read == ERR_CHANNEL_CLOSED) {
71 printf("Channel reset during read.\n");
72 break;
73 } else if (bytes_read < 0) {
74 printf("Error while reading. Retcode = %ld\n", bytes_read);
75 break;
76 }
77
78 // Tack a NULL to the end of the bytes and print them to the
79 // console.
80 buf[bytes_read] = '\0';
81 printf("%s", buf);
82
83 // Echo the bytes back the device.
84 ssize_t bytes_written =
85 ndebug_write_usr(buf, bytes_read, INFINITE_TIME);
86 if (bytes_written == ERR_CHANNEL_CLOSED) {
87 printf("Channel reset during write.\n");
88 break;
89 } else if (bytes_written < 0) {
90 printf("Error while writing. Retcode = %ld\n", bytes_written);
91 break;
92 }
93
94 }
95 }
96 }
97
98 APP_START(ndebugtest)
99 .entry = ndebugtest_entry,
100 APP_END