-
Notifications
You must be signed in to change notification settings - Fork 221
Examples
picoTCP comes with a handful of examples that run with the help of the picoapp executable. In this section we explore these applications and explain how they work. Since they require picoapp, the code of these examples can not be run standalone and so are solely to give you some insight in featureset of picoTCP.
- In the /build/test folder you’ll find picoapp.elf and its IPv6 equivalent picoapp6.elf. To build the binary, do
$sudo make test
- You can run examples from the ./test/examples/ folder with a TUN device. Try ping with
$sudo ./picoapp.elf --tun myTUN:192.168.13.37:255.255.255.0 --app ping:192.168.13.37
- You can use VDE (Virtual Distributed Ethernet) as well, try the udp echo example with
$./picoapp.elf --vde pic0:/tmp/pic0.ctl:10.40.0.3:255.255.255.0 -a udpecho:10.40.0.3:6667:6667:1400
When looking at the source code of the examples bear in mind they support on picoapp.c for basic functionality. To see how the stack is initialized and how the loop is maintained take a closer look at picoapp.c as well!
Run the ping example with
$sudo build/test/picoapp.elf --tun myTUN:192.168.13.37:255.255.255.0 --app ping:192.168.13.37
Let’s take a look at what’s happening behind the scenes in a (simplified version) of ping.c
Since ping uses the ICMPv4 protocol, we need to add the proper header file. While we’re at it, we define the amount of times we’d like to ping a given IPv4 address.
#include "utils.h"
#include <pico_icmp4.h>
#define NUM_PING 5
We define a destination IP address and a timeout. All we have to do then is call pico_icmp4_ping(dest, NUM_PING, 1000, 10000, 64, cb_ping);
to initiate the pinging. We pass the function an IPv4 destination address, a number of pings, the interval between them, the timeout, a payload size and a callback function.
For the timeout to take effect, we need to create a timer with pico_timer_add(timeout * 1000, ping_abort_timer, &id);
to be able to handle the situation where a ping times out.
All of this can be done as follows:
void app_ping(char *arg)
{
static int id;
char *dest = "192.168.1.5";
int timeout = 20;
id = pico_icmp4_ping(dest, NUM_PING, 1000, 10000, 64, cb_ping);
if (timeout > 0) {
printf("Adding abort timer after %d seconds for id %d\n", timeout, id);
pico_timer_add(timeout * 1000, ping_abort_timer, &id);
}
}
We still need to handle both callbacks! Let’s take a look at the ping callback function
void cb_ping(struct pico_icmp4_stats *s)
{
char host[30];
pico_ipv4_to_string(host, s->dst.addr);
if (s->err == 0) {
dbg("%lu bytes from %s: icmp_req=%lu ttl=%lu time=%lu ms\n", s->size, host, s->seq, s->ttl, s->time);
if (s->seq >= NUM_PING)
exit(0);
} else {
dbg("PING %lu to %s: Error %d\n", s->seq, host, s->err);
exit(1);
}
}
What happens here? The library will call this function and pass it a struct with some statistics. To print the IPv4 address we need to convert it to a readable format with pico_ipv4_to_string(host, s->dst.addr);
Once we’ve got the amount of pings we requested, we exit the application.
The last thing to do is write the timeout callback. This function is called when it takes too long for a ping reply to be received.
void ping_abort_timer(pico_time now, void *_id)
{
int *id = (int *) _id;
printf("Ping: aborting...\n");
pico_icmp4_ping_abort(*id);
}
When a timeout happens, we want to stop pinging. An abort can be done with pico_icmp4_ping_abort(*id);
This will tell the library to stop pinging the address we’ve supplied.
Questions or remarks? Please contact us!
[email protected] | picotcp.altran.be | Twitter | Facebook
Getting Started
- Setting up the environment
- Testing
- Configuring and compiling
- Running picoTCP on Linux - Deprecated (see setting up)
- Running picoTCP on Windows
Porting
- Build process explained
- Porting the build to another compiler or IDE
- Porting picoTCP to your favorite embedded target
- Porting picoTCP to your favorite Operating System
- Example device driver
Development