1# TCP Echo Client Demo for MPS2 Cortex-M3 AN385 emulated using QEMU with User Mode Networking
2
3## Setup Description
4The demo requires 2 components -
51. Echo Client - The demo in this repository.
61. Echo Server - An echo server.
7
8```
9+--------------------------------------------------------+
10|  Host Machine                                          |
11|  OS - Any                                              |
12|  Runs - Echo Server                                    |
13|                          +--------------------------+  |
14|                          |                          |  |
15|                          | QEMU                     |  |
16|                          | Runs - Echo Client       |  |
17|                          |                          |  |
18|  +----------------+      |    +----------------+    |  |
19|  |                |      |    |                |    |  |
20|  |                |      |    |                |    |  |
21|  |  Echo Server   | <-------> |   Echo Client  |    |  |
22|  |                |      |    |                |    |  |
23|  |                |      |    |                |    |  |
24|  |                |      |    |                |    |  |
25|  +----------------+      |    +----------------+    |  |
26|                          |                          |  |
27|                          +--------------------------+  |
28+--------------------------------------------------------+
29```
30
31## PreRequisites
32
331. Install the following tools in the Host Machine:
34   * [GNU Arm Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads).
35   * [qemu-arm-system](https://www.qemu.org/download).
36   * Make (Version 4.3):
37     ```
38     sudo apt install make
39     ```
402.  Clone the source code:
41     ```
42      git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules --depth 1
43     ```
44
45## Launch Echo Server
46Launch Echo Server on the host machine.
47
48### Host OS is Linux
49* Install `netcat`:
50   ```
51   sudo apt install netcat
52   ```
53* Start an Echo Server on port 7:
54   ```shell
55   sudo nc -l 7
56   ```
57
58### Host OS is Windows
59* Install [Npcap/Nmap](https://nmap.org/download.html#windows).
60* Start an Echo Server on port 7:
61    ```shell
62    ncat -l 7
63    ```
64
65### Host OS is Mac
66* Install `netcat`:
67   ```shell
68   brew install netcat
69   ```
70* Start an Echo Server on port 7:
71    ```shell
72    nc -l -p 7
73    ```
74
75## Enable User Mode Networking in QEMU
76
77The User Mode Networking is implemented using *slirp*, which provides a full
78TCP/IP stack within QEMU and uses it to implement a virtual NAT network. It does
79not require Administrator privileges.
80
81User Mode Networking has the following limitations:
82
83 - The performance is not very good because of the overhead involved..
84 - ICMP does not work out of the box i.e. you cannot use ping within the guest.
85   Linux hosts require one time setup by root to make ICMP work within the
86   guest.
87 - The guest is not directly accessible from the host or the external network.
88
89
90## Build and Run
91Do the following steps on the host machine:
92
931. The echo server is assumed to be on port 7, which is the standard echo
94protocol port. You can change the port to any other listening port (e.g. 3682 ).
95Set `echoECHO_PORT` to the value of this port.
96
97```c
98#define echoECHO_PORT          ( 7 )
99```
100
1012. Build:
102```shell
103   make
104```
105
1063. Run:
107```shell
108   sudo qemu-system-arm -machine mps2-an385 -cpu cortex-m3 \
109   -kernel ./build/freertos_tcp_mps2_demo.axf \
110   -monitor null -semihosting -semihosting-config enable=on,target=native -serial stdio -nographic \
111   -netdev user,id=mynet0, -net nic,model=lan9118,netdev=mynet0
112
113```
114
1156. You should see that following output on the terminal of the Echo Server (which
116is running `sudo nc -l 7` or `netcat -l 7` or `nc -l -p 7` depending on your OS):
117```
1180FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=> ?
119@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=>?
120@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0123456789:;<=>?
121@ABCDEFGHIJKLM
122```
123
124## Debug
1251. Build with debugging symbols:
126```
127   make DEBUG=1
128```
129
1302. Start QEMU in the paused state waiting for GDB connection:
131```shell
132   sudo qemu-system-arm -machine mps2-an385 -cpu cortex-m3 -s -S \
133   -kernel ./build/freertos_tcp_mps2_demo.axf \
134   -monitor null -semihosting -semihosting-config enable=on,target=native -serial stdio -nographic \
135   -netdev user,id=mynet0, -net nic,model=lan9118,netdev=mynet0 \
136   -object filter-dump,id=tap_dump,netdev=mynet0,file=/tmp/qemu_tap_dump
137```
138
1393. Run GDB:
140```shell
141sudo arm-none-eabi-gdb -q ./build/freertos_tcp_mps2_demo.axf
142
143(gdb) target remote :1234
144(gdb) break main
145(gdb) c
146```
147
1484. The above QEMU command creates a network packet dump in the file
149`/tmp/qemu_tap_dump` which you can examine using `tcpdump` or WireShark:
150```shell
151sudo tcpdump -r /tmp/qemu_tap_dump  | less
152```
153