Commit 0c3140537a0625a8f390420b25fc53900fd9790c
1 parent
ceb4c7ca
récupération lqi rssi via pktdump
Showing
7 changed files
with
730 additions
and
3 deletions
Show diff stats
@@ -0,0 +1,64 @@ | @@ -0,0 +1,64 @@ | ||
1 | +# name of your application | ||
2 | +APPLICATION = test_lqi_rssi | ||
3 | + | ||
4 | +# If no BOARD is found in the environment, use this default: | ||
5 | +BOARD ?= native | ||
6 | + | ||
7 | +# This has to be the absolute path to the RIOT base directory: | ||
8 | +RIOTBASE ?= $(CURDIR)/../.. | ||
9 | + | ||
10 | +BOARD_INSUFFICIENT_MEMORY := airfy-beacon chronos msb-430 msb-430h nrf51dongle \ | ||
11 | + nrf6310 nucleo-f103 nucleo-f334 pca10000 pca10005 spark-core \ | ||
12 | + stm32f0discovery telosb weio wsn430-v1_3b wsn430-v1_4 \ | ||
13 | + yunjia-nrf51822 z1 nucleo-f072 nucleo-f030 nucleo-f070 \ | ||
14 | + microbit calliope-mini | ||
15 | + | ||
16 | +# Include packages that pull up and auto-init the link layer. | ||
17 | +# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present | ||
18 | +USEMODULE += gnrc_netdev_default | ||
19 | +USEMODULE += auto_init_gnrc_netif | ||
20 | +# Specify the mandatory networking modules for IPv6 and UDP | ||
21 | +USEMODULE += gnrc_ipv6_router_default | ||
22 | +USEMODULE += gnrc_udp | ||
23 | +# Add a routing protocol | ||
24 | +USEMODULE += gnrc_rpl | ||
25 | +USEMODULE += auto_init_gnrc_rpl | ||
26 | +# This application dumps received packets to STDIO using the pktdump module | ||
27 | +#USEMODULE += gnrc_pktdump | ||
28 | +# Additional networking modules that can be dropped if not needed | ||
29 | +USEMODULE += gnrc_icmpv6_echo | ||
30 | +# Add also the shell, some shell commands | ||
31 | +USEMODULE += shell | ||
32 | +USEMODULE += shell_commands | ||
33 | +USEMODULE += ps | ||
34 | +USEMODULE += netstats_l2 | ||
35 | +USEMODULE += netstats_ipv6 | ||
36 | +USEMODULE += netstats_rpl | ||
37 | +USEMODULE += at86rf231 | ||
38 | +# Comment this out to disable code in RIOT that does safety checking | ||
39 | +# which is not needed in a production environment but helps in the | ||
40 | +# development process: | ||
41 | +CFLAGS += -DDEVELHELP | ||
42 | + | ||
43 | +# Comment this out to join RPL DODAGs even if DIOs do not contain | ||
44 | +# DODAG Configuration Options (see the doc for more info) | ||
45 | +# CFLAGS += -DGNRC_RPL_DODAG_CONF_OPTIONAL_ON_JOIN | ||
46 | + | ||
47 | +# Change this to 0 show compiler invocation lines by default: | ||
48 | +QUIET ?= 1 | ||
49 | + | ||
50 | +include $(RIOTBASE)/Makefile.include | ||
51 | + | ||
52 | +# Set a custom channel if needed | ||
53 | +ifneq (,$(filter cc110x,$(USEMODULE))) # radio is cc110x sub-GHz | ||
54 | + DEFAULT_CHANNEL ?= 0 | ||
55 | + CFLAGS += -DCC110X_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL) | ||
56 | +else | ||
57 | + ifneq (,$(filter at86rf212b,$(USEMODULE))) # radio is IEEE 802.15.4 sub-GHz | ||
58 | + DEFAULT_CHANNEL ?= 5 | ||
59 | + FLAGS += -DIEEE802154_DEFAULT_SUBGHZ_CHANNEL=$(DEFAULT_CHANNEL) | ||
60 | + else # radio is IEEE 802.15.4 2.4 GHz | ||
61 | + DEFAULT_CHANNEL ?= 26 | ||
62 | + CFLAGS += -DIEEE802154_DEFAULT_CHANNEL=$(DEFAULT_CHANNEL) | ||
63 | + endif | ||
64 | +endif |
@@ -0,0 +1,142 @@ | @@ -0,0 +1,142 @@ | ||
1 | +# gnrc_networking example | ||
2 | + | ||
3 | +This example shows you how to try out the code in two different ways: Either by communicating | ||
4 | +between the RIOT machine and its Linux host, or by communicating between two RIOT instances. | ||
5 | +Note that the former only works with native, i.e. if you run RIOT on your Linux machine. | ||
6 | + | ||
7 | +## Connecting RIOT native and the Linux host | ||
8 | + | ||
9 | +> **Note:** RIOT does not support IPv4, so you need to stick to IPv6 anytime. To | ||
10 | +establish a connection between RIOT and the Linux host, you will need `netcat` | ||
11 | +(with IPv6 support). Ubuntu 14.04 comes with netcat IPv6 support pre-installed. | ||
12 | +On Debian it's available in the package `netcat-openbsd`. Be aware that many | ||
13 | +programs require you to add an option such as -6 to tell them to use IPv6, otherwise they | ||
14 | +will fail. If you're using a _Raspberry Pi_, run `sudo modprobe ipv6` before trying | ||
15 | +this example, because raspbian does not load the IPv6 module automatically. | ||
16 | +On some systems (openSUSE for example), the _firewall_ may interfere, and prevent | ||
17 | +some packets to arrive at the application (they will however show up in Wireshark, | ||
18 | +which can be confusing). So be sure to adjust your firewall rules, or turn it off | ||
19 | +(who needs security anyway). | ||
20 | + | ||
21 | +First, create a tap interface: | ||
22 | + | ||
23 | + sudo ip tuntap add tap0 mode tap user ${USER} | ||
24 | + sudo ip link set tap0 up | ||
25 | + | ||
26 | +Now you can start the `gnrc_networking` example by invoking `make term`. This should | ||
27 | +automatically connect to the `tap0` interface. If this doesn't work for any reason, | ||
28 | +run make term with the tap0 interface as the PORT environment variable: | ||
29 | + | ||
30 | + PORT=tap0 make term | ||
31 | + | ||
32 | +To verify that there is connectivity between RIOT and Linux, go to the RIOT console and run `ifconfig`: | ||
33 | + | ||
34 | + > ifconfig | ||
35 | + Iface 7 HWaddr: ce:f5:e1:c5:f7:5a | ||
36 | + inet6 addr: ff02::1/128 scope: local [multicast] | ||
37 | + inet6 addr: fe80::ccf5:e1ff:fec5:f75a/64 scope: local | ||
38 | + inet6 addr: ff02::1:ffc5:f75a/128 scope: local [multicast] | ||
39 | + | ||
40 | +Copy the [link-local address](https://en.wikipedia.org/wiki/Link-local_address) | ||
41 | +of the RIOT node (prefixed with `fe80`) and try to ping it **from the Linux node**: | ||
42 | + | ||
43 | + ping6 fe80::ccf5:e1ff:fec5:f75a%tap0 | ||
44 | + | ||
45 | +Note that the interface on which to send the ping needs to be appended to the IPv6 | ||
46 | +address, `%tap0` in the above example. When talking to the RIOT node, you always want | ||
47 | +to send to/receive from the `tap0` interface. | ||
48 | + | ||
49 | +If the pings succeed you can go on to send UDP packets. To do that, first start a | ||
50 | +UDP server on the RIOT node: | ||
51 | + | ||
52 | + > udp server start 8808 | ||
53 | + Success: started UDP server on port 8808 | ||
54 | + | ||
55 | +Now, on the Linux host, you can run netcat to connect with RIOT's UDP server: | ||
56 | + | ||
57 | + nc -6uv fe80::ccf5:e1ff:fec5:f75a%tap0 8808 | ||
58 | + | ||
59 | +The `-6` option is necessary to tell netcat to use IPv6 only, the `-u` option tells | ||
60 | +it to use UDP only, and the `-v` option makes it give more verbose output (this one is optional). | ||
61 | + | ||
62 | +You should now see that UDP messages are received on the RIOT side. Opening a UDP | ||
63 | +server on the Linux side is also possible. To do that, write down the IP address | ||
64 | +of the host (run on Linux): | ||
65 | + | ||
66 | + ifconfig tap0 | ||
67 | + tap0 Link encap:Ethernet HWaddr ce:f5:e1:c5:f7:59 | ||
68 | + inet6 addr: fe80::4049:5fff:fe17:b3ae/64 Scope:Link | ||
69 | + UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 | ||
70 | + RX packets:6 errors:0 dropped:0 overruns:0 frame:0 | ||
71 | + TX packets:36 errors:0 dropped:0 overruns:0 carrier:0 | ||
72 | + collisions:0 txqueuelen:0 | ||
73 | + RX bytes:488 (488.0 B) TX bytes:3517 (3.5 KB) | ||
74 | + | ||
75 | +Then open a UDP server on Linux (the `-l` option makes netcat listen for incoming connections): | ||
76 | + | ||
77 | + nc -6ul 8808 | ||
78 | + | ||
79 | +Now, on the RIOT side, send a UDP packet using: | ||
80 | + | ||
81 | + udp send fe80::4049:5fff:fe17:b3ae 8808 testmessage | ||
82 | + | ||
83 | +You should see `testmessage` appear in netcat. Instead of using netcat, you can of | ||
84 | +course write your own software, but you may have to bind the socket to a specific | ||
85 | +interface (tap0 in this case). For an example that shows how to do so, see | ||
86 | +[here](https://gist.github.com/backenklee/dad5e80b764b3b3d0d3e). | ||
87 | + | ||
88 | +## Connecting two RIOT instances | ||
89 | + | ||
90 | +When using native (i.e. when you're trying this on your Linux machine), you first | ||
91 | +need to set up two tap devices and a bridge that connects them. This constitutes a | ||
92 | +virtual network that the RIOT instances can use to communicate. | ||
93 | + | ||
94 | + ./../../dist/tools/tapsetup/tapsetup --create 2 | ||
95 | + | ||
96 | +Then, make sure you've compiled the application by calling `make` and start the | ||
97 | +first RIOT instance by invoking `make term`. In the RIOT shell, get to know the | ||
98 | +IP address of this node: | ||
99 | + | ||
100 | + > ifconfig | ||
101 | + Iface 7 HWaddr: ce:f5:e1:c5:f7:5a | ||
102 | + inet6 addr: ff02::1/128 scope: local [multicast] | ||
103 | + inet6 addr: fe80::ccf5:e1ff:fec5:f75a/64 scope: local | ||
104 | + inet6 addr: ff02::1:ffc5:f75a/128 scope: local [multicast] | ||
105 | + | ||
106 | +and start a UDP server. | ||
107 | + | ||
108 | + > udp server start 8808 | ||
109 | + | ||
110 | +This node is now ready to receive data on port `8808`. | ||
111 | + | ||
112 | +In a second terminal, start a second RIOT instance, this time listening on `tap1`: | ||
113 | + | ||
114 | + PORT=tap1 make term | ||
115 | + | ||
116 | +In the RIOT shell, you can now send a message to the first RIOT instance: | ||
117 | + | ||
118 | + > udp send fe80::ccf5:e1ff:fec5:f75 8808 testmessage | ||
119 | + | ||
120 | +*(Make sure to copy the actual | ||
121 | +[link-local address](https://en.wikipedia.org/wiki/Link-local_address) of your first | ||
122 | +RIOT instance into the above command)* | ||
123 | + | ||
124 | +In your first terminal, you should now see output that looks like this. | ||
125 | + | ||
126 | + > PKTDUMP: data received: | ||
127 | + ~~ SNIP 0 - size: 11 byte, type: NETTYPE_UNDEF (0) | ||
128 | + 000000 74 65 73 74 6d 65 73 73 61 67 65 | ||
129 | + ~~ SNIP 1 - size: 8 byte, type: NETTYPE_UDP (3) | ||
130 | + src-port: 8808 dst-port: 8808 | ||
131 | + length: 19 cksum: 0x4d95f | ||
132 | + ~~ SNIP 2 - size: 40 byte, type: NETTYPE_IPV6 (1) | ||
133 | + traffic class: 0x00 (ECN: 0x0, DSCP: 0x00) | ||
134 | + flow label: 0x00000 | ||
135 | + length: 19 next header: 17 hop limit: 64 | ||
136 | + source address: fe80::a08a:84ff:fe68:544f | ||
137 | + destination address: fe80::60fc:3cff:fe5e:40df | ||
138 | + ~~ SNIP 3 - size: 20 byte, type: NETTYPE_NETIF (-1) | ||
139 | + if_pid: 6 rssi: 0 lqi: 0 | ||
140 | + src_l2addr: a2:8a:84:68:54:4f | ||
141 | + dst_l2addr: 62:fc:3c:5e:40:df | ||
142 | + ~~ PKT - 4 snips, total size: 79 byte |
@@ -0,0 +1,344 @@ | @@ -0,0 +1,344 @@ | ||
1 | +/* | ||
2 | + * Copyright (C) 2015 Freie Universität Berlin | ||
3 | + * | ||
4 | + * This file is subject to the terms and conditions of the GNU Lesser | ||
5 | + * General Public License v2.1. See the file LICENSE in the top level | ||
6 | + * directory for more details. | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * @ingroup examples | ||
11 | + * @{ | ||
12 | + * | ||
13 | + * @file | ||
14 | + * @brief Example application for demonstrating the RIOT network stack | ||
15 | + * | ||
16 | + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> | ||
17 | + * | ||
18 | + * @} | ||
19 | + */ | ||
20 | + | ||
21 | +#include <stdio.h> | ||
22 | +#include <inttypes.h> | ||
23 | +#include <errno.h> | ||
24 | +#include "kernel_types.h" | ||
25 | +#include "byteorder.h" | ||
26 | +#include "thread.h" | ||
27 | +#include "net/gnrc/ipv6.h" | ||
28 | +#include "net/gnrc/udp.h" | ||
29 | +#include "net/gnrc.h" | ||
30 | +#include "net/ipv6/addr.h" | ||
31 | +#include "net/ipv6/hdr.h" | ||
32 | +#include "net/udp.h" | ||
33 | +#include "net/sixlowpan.h" | ||
34 | +#include "od.h" | ||
35 | +#include "periph/timer.h" | ||
36 | +#include "../../boards/stm32f4discovery/include/board.h" | ||
37 | +#include "../../boards/stm32f4discovery/include/periph_conf.h" | ||
38 | +#include "periph/pwm.h" | ||
39 | +#include "shell.h" | ||
40 | +#include "msg.h" | ||
41 | + | ||
42 | +#ifndef GNRC_PKTDUMP_MSG_QUEUE_SIZE | ||
43 | +#define GNRC_PKTDUMP_MSG_QUEUE_SIZE (8U) | ||
44 | +#endif | ||
45 | + | ||
46 | +/** | ||
47 | + * @brief Priority of the pktdump thread | ||
48 | + */ | ||
49 | +#ifndef GNRC_PKTDUMP_PRIO | ||
50 | +#define GNRC_PKTDUMP_PRIO (THREAD_PRIORITY_MAIN - 1) | ||
51 | +#endif | ||
52 | + | ||
53 | +/** | ||
54 | + * @brief Stack size used for the pktdump thread | ||
55 | + */ | ||
56 | +#ifndef GNRC_PKTDUMP_STACKSIZE | ||
57 | +#define GNRC_PKTDUMP_STACKSIZE (THREAD_STACKSIZE_MAIN) | ||
58 | +#endif | ||
59 | +//#define DST | ||
60 | +#define MAIN_QUEUE_SIZE (8) | ||
61 | +static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; | ||
62 | + | ||
63 | +extern int udp_cmd(int argc, char **argv); | ||
64 | +static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL, | ||
65 | + KERNEL_PID_UNDEF); | ||
66 | +unsigned rssi_dest, lqi_dest; | ||
67 | +typedef struct mon_attribute { | ||
68 | + uint8_t rssi; | ||
69 | + uint8_t lqi; | ||
70 | +} Data_quality; | ||
71 | + | ||
72 | +#ifdef DST | ||
73 | + ipv6_hdr_t* ipv6_HDR; | ||
74 | + Data_quality data_quality; | ||
75 | +#endif | ||
76 | + | ||
77 | +//uint8_t node[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x34,0x51,0x0b,0x33,0x0b,0x34,0x0a}; | ||
78 | +#ifdef DST | ||
79 | +static void reply_quality(ipv6_addr_t addr, char *port_str, Data_quality* data) | ||
80 | + | ||
81 | +{ | ||
82 | + uint16_t port; | ||
83 | + port = (uint16_t)atoi(port_str); | ||
84 | + if (port == 0) { | ||
85 | + puts("Error: unable to parse destination port"); | ||
86 | + return; | ||
87 | + } | ||
88 | + | ||
89 | + | ||
90 | + gnrc_pktsnip_t *payload, *udp, *ip; | ||
91 | + // unsigned payload_size; | ||
92 | + payload=gnrc_pktbuf_add(NULL, data, sizeof(data), GNRC_NETTYPE_UNDEF); | ||
93 | + if (payload == NULL) { | ||
94 | + puts("Error: unable to copy data to packet buffer"); | ||
95 | + return; | ||
96 | + } | ||
97 | + // store size for output | ||
98 | + //payload_size = (unsigned)payload->size; | ||
99 | + // allocate UDP header, set source port := destination port | ||
100 | + udp = gnrc_udp_hdr_build(payload, port, port); | ||
101 | + if (udp == NULL) { | ||
102 | + puts("Error: unable to allocate UDP header"); | ||
103 | + gnrc_pktbuf_release(payload); | ||
104 | + return; | ||
105 | + } | ||
106 | + // allocate IPv6 header | ||
107 | + ip = gnrc_ipv6_hdr_build(udp, NULL, &addr); | ||
108 | + if (ip == NULL) { | ||
109 | + puts("Error: unable to allocate IPv6 header"); | ||
110 | + gnrc_pktbuf_release(udp); | ||
111 | + return; | ||
112 | + } | ||
113 | + // send packet | ||
114 | + printf("RSSI %u LQI %u \n",data->rssi,data->lqi); | ||
115 | + printf("%d\n",port); | ||
116 | + if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip)) { | ||
117 | + puts("Error: unable to locate UDP thread"); | ||
118 | + gnrc_pktbuf_release(ip); | ||
119 | + return; | ||
120 | + } | ||
121 | + | ||
122 | + //printf("Success: send %u byte to [%s]:%u\n", payload_size, addr_str,port); | ||
123 | + | ||
124 | +} | ||
125 | +#endif | ||
126 | +/***************************************************************************************/ | ||
127 | +//copy pktdump | ||
128 | + | ||
129 | + | ||
130 | +/** | ||
131 | + * @brief PID of the pktdump thread | ||
132 | + */ | ||
133 | +static kernel_pid_t copy_pktd_pid = KERNEL_PID_UNDEF; | ||
134 | + | ||
135 | + | ||
136 | + | ||
137 | +/** | ||
138 | + * @brief Stack for the pktdump thread | ||
139 | + */ | ||
140 | +static char _stack[GNRC_PKTDUMP_STACKSIZE]; | ||
141 | + | ||
142 | +static void _dump_snip(gnrc_pktsnip_t *pkt) | ||
143 | +{ | ||
144 | + | ||
145 | + switch (pkt->type) { | ||
146 | + case GNRC_NETTYPE_UNDEF: | ||
147 | + printf("NETTYPE_UNDEF (%i)\n", pkt->type); | ||
148 | + //od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT); | ||
149 | + Data_quality* pkt_rcv=pkt->data; | ||
150 | + printf("MON_RSSI %d MON_LQI %d \n",pkt_rcv->rssi,pkt_rcv->lqi); | ||
151 | + /*if(strcmp((char *)pkt->data,"go")==0) | ||
152 | + { | ||
153 | + //pwm_set(PWM_DEV(0),1,25); | ||
154 | + ordre = 1; | ||
155 | + timer_set(XTIMER_DEV,0,8400); | ||
156 | + timer_clear(TIMER_DEV(1),0); | ||
157 | + } | ||
158 | + else | ||
159 | + { | ||
160 | + //pwm_set(PWM_DEV(0),1,0); | ||
161 | + ordre = 0; | ||
162 | + }*/ | ||
163 | + | ||
164 | + break; | ||
165 | +#ifdef MODULE_GNRC_NETIF | ||
166 | + case GNRC_NETTYPE_NETIF: | ||
167 | + printf("NETTYPE_NETIF (%i)\n", pkt->type); | ||
168 | + gnrc_netif_hdr_print(pkt->data); | ||
169 | +#ifdef DST | ||
170 | + gnrc_netif_hdr_t* header=(gnrc_netif_hdr_t*)pkt->data; | ||
171 | + data_quality.rssi=(uint8_t)header->rssi; | ||
172 | + data_quality.lqi=(uint8_t)header->lqi; | ||
173 | + printf("MES DATA:%u ---- %u\n",data_quality.rssi,data_quality.lqi); | ||
174 | +#endif | ||
175 | + break; | ||
176 | +#endif | ||
177 | +#ifdef MODULE_GNRC_SIXLOWPAN | ||
178 | + case GNRC_NETTYPE_SIXLOWPAN: | ||
179 | + printf("NETTYPE_SIXLOWPAN (%i)\n", pkt->type); | ||
180 | + //sixlowpan_print(pkt->data, pkt->size); | ||
181 | + break; | ||
182 | +#endif | ||
183 | +#ifdef MODULE_GNRC_IPV6 | ||
184 | + case GNRC_NETTYPE_IPV6: | ||
185 | + printf("NETTYPE_IPV6 (%i)\n", pkt->type); | ||
186 | +#ifdef DST | ||
187 | + ipv6_hdr_print(pkt->data); | ||
188 | + //ipv6_HDR= (ipv6_hdr_t*)pkt->data; | ||
189 | + //char addr_str[IPV6_ADDR_MAX_STR_LEN]; | ||
190 | + ipv6_HDR = (ipv6_hdr_t*)pkt->data; | ||
191 | + // ipv6_addr_to_str(addr_str, &ipv6_HDR->src,sizeof(addr_str)); | ||
192 | + //printf("mon-test : %s\n",addr_str); | ||
193 | + //ipv6_HDR =(ipv6_addr_t)pkt->data; | ||
194 | +#endif | ||
195 | + break; | ||
196 | +#endif | ||
197 | +#ifdef MODULE_GNRC_ICMPV6 | ||
198 | + case GNRC_NETTYPE_ICMPV6: | ||
199 | + printf("NETTYPE_ICMPV6 (%i)\n", pkt->type); | ||
200 | + break; | ||
201 | +#endif | ||
202 | +#ifdef MODULE_GNRC_TCP | ||
203 | + case GNRC_NETTYPE_TCP: | ||
204 | + printf("NETTYPE_TCP (%i)\n", pkt->type); | ||
205 | + break; | ||
206 | +#endif | ||
207 | +#ifdef MODULE_GNRC_UDP | ||
208 | + case GNRC_NETTYPE_UDP: | ||
209 | + printf("NETTYPE_UDP (%i)\n", pkt->type); | ||
210 | + udp_hdr_print(pkt->data); | ||
211 | + | ||
212 | + break; | ||
213 | +#endif | ||
214 | +#ifdef TEST_SUITES | ||
215 | + case GNRC_NETTYPE_TEST: | ||
216 | + printf("NETTYPE_TEST (%i)\n", pkt->type); | ||
217 | + //od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT); | ||
218 | + break; | ||
219 | +#endif | ||
220 | + default: | ||
221 | + printf("NETTYPE_UNKNOWN (%i)\n", pkt->type); | ||
222 | + //od_hex_dump(pkt->data, pkt->size, OD_WIDTH_DEFAULT); | ||
223 | + break; | ||
224 | + } | ||
225 | +} | ||
226 | + | ||
227 | +static void _dump(gnrc_pktsnip_t *pkt) | ||
228 | +{ | ||
229 | + int snips = 0; | ||
230 | + int size = 0; | ||
231 | + gnrc_pktsnip_t *snip = pkt; | ||
232 | + | ||
233 | + while (snip != NULL) { | ||
234 | + printf("~~ SNIP %2i - size: %3u byte, type: ", snips, | ||
235 | + (unsigned int)snip->size); | ||
236 | + _dump_snip(snip); | ||
237 | + ++snips; | ||
238 | + size += snip->size; | ||
239 | + snip = snip->next; | ||
240 | + } | ||
241 | + | ||
242 | + printf("~~ PKT - %2i snips, total size: %3i byte\n", snips, size); | ||
243 | + gnrc_pktbuf_release(pkt); | ||
244 | + #ifdef DST | ||
245 | + reply_quality(ipv6_HDR->src,"8888",&data_quality); | ||
246 | +#endif | ||
247 | +} | ||
248 | + | ||
249 | +static void *_eventloop(void *arg) | ||
250 | +{ | ||
251 | + (void)arg; | ||
252 | + msg_t msg, reply; | ||
253 | + msg_t msg_queue[GNRC_PKTDUMP_MSG_QUEUE_SIZE]; | ||
254 | + | ||
255 | + /* setup the message queue */ | ||
256 | + msg_init_queue(msg_queue, GNRC_PKTDUMP_MSG_QUEUE_SIZE); | ||
257 | + | ||
258 | + reply.content.value = (uint32_t)(-ENOTSUP); | ||
259 | + reply.type = GNRC_NETAPI_MSG_TYPE_ACK; | ||
260 | + | ||
261 | + while (1) { | ||
262 | + msg_receive(&msg); | ||
263 | + | ||
264 | + switch (msg.type) { | ||
265 | + case GNRC_NETAPI_MSG_TYPE_RCV: | ||
266 | + puts("PKTDUMP: data received:"); | ||
267 | + _dump(msg.content.ptr); | ||
268 | + break; | ||
269 | + case GNRC_NETAPI_MSG_TYPE_SND: | ||
270 | + puts("PKTDUMP: data to send:"); | ||
271 | + _dump(msg.content.ptr); | ||
272 | + break; | ||
273 | + case GNRC_NETAPI_MSG_TYPE_GET: | ||
274 | + case GNRC_NETAPI_MSG_TYPE_SET: | ||
275 | + msg_reply(&msg, &reply); | ||
276 | + break; | ||
277 | + default: | ||
278 | + puts("PKTDUMP: received something unexpected"); | ||
279 | + break; | ||
280 | + } | ||
281 | + } | ||
282 | + | ||
283 | + /* never reached */ | ||
284 | + return NULL; | ||
285 | +} | ||
286 | + | ||
287 | +kernel_pid_t gnrc_pktdump_init(void) | ||
288 | +{ | ||
289 | + if (copy_pktd_pid == KERNEL_PID_UNDEF) { | ||
290 | + copy_pktd_pid = thread_create(_stack, sizeof(_stack), GNRC_PKTDUMP_PRIO, | ||
291 | + THREAD_CREATE_STACKTEST, | ||
292 | + _eventloop, NULL, "pktdump_copy"); | ||
293 | + } | ||
294 | + return copy_pktd_pid; | ||
295 | +} | ||
296 | +//end copy pktdump | ||
297 | +/***************************************************************************************/ | ||
298 | + | ||
299 | + | ||
300 | +static void start_server(char *port_str) | ||
301 | +{ | ||
302 | + uint16_t port; | ||
303 | + | ||
304 | + /* check if server is already running */ | ||
305 | + if (server.target.pid != KERNEL_PID_UNDEF) { | ||
306 | + printf("Error: server already running on port %" PRIu32 "\n", | ||
307 | + server.demux_ctx); | ||
308 | + return; | ||
309 | + } | ||
310 | + /* parse port */ | ||
311 | + port = (uint16_t)atoi(port_str); | ||
312 | + if (port == 0) { | ||
313 | + puts("Error: invalid port specified"); | ||
314 | + return; | ||
315 | + } | ||
316 | + /* start server (which means registering pktdump for the chosen port) */ | ||
317 | + server.target.pid = copy_pktd_pid; | ||
318 | + server.demux_ctx = (uint32_t)port; | ||
319 | + gnrc_netreg_register(GNRC_NETTYPE_UDP, &server); | ||
320 | + printf("Success: started UDP server on port %" PRIu16 "\n", port); | ||
321 | +} | ||
322 | + | ||
323 | +static const shell_command_t shell_commands[] = { | ||
324 | + { "udp", "send data over UDP and listen on UDP ports", udp_cmd }, | ||
325 | + { NULL, NULL, NULL } | ||
326 | +}; | ||
327 | + | ||
328 | + | ||
329 | +int main(void) | ||
330 | +{ | ||
331 | + /* we need a message queue for the thread running the shell in order to | ||
332 | + * receive potentially fast incoming networking packets */ | ||
333 | + msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); | ||
334 | + puts("RIOT network stack example application"); | ||
335 | + gnrc_pktdump_init(); | ||
336 | + start_server("8888"); | ||
337 | + /* start shell */ | ||
338 | + puts("All up, running the shell now"); | ||
339 | + char line_buf[SHELL_DEFAULT_BUFSIZE]; | ||
340 | + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); | ||
341 | + | ||
342 | + /* should be never reached */ | ||
343 | + return 0; | ||
344 | +} |
@@ -0,0 +1,175 @@ | @@ -0,0 +1,175 @@ | ||
1 | +/* | ||
2 | + * Copyright (C) 2015 Freie Universität Berlin | ||
3 | + * | ||
4 | + * This file is subject to the terms and conditions of the GNU Lesser | ||
5 | + * General Public License v2.1. See the file LICENSE in the top level | ||
6 | + * directory for more details. | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * @ingroup examples | ||
11 | + * @{ | ||
12 | + * | ||
13 | + * @file | ||
14 | + * @brief Demonstrating the sending and receiving of UDP data | ||
15 | + * | ||
16 | + * @author Hauke Petersen <hauke.petersen@fu-berlin.de> | ||
17 | + * | ||
18 | + * @} | ||
19 | + */ | ||
20 | + | ||
21 | +#include <stdio.h> | ||
22 | +#include <inttypes.h> | ||
23 | + | ||
24 | +#include "net/gnrc.h" | ||
25 | +#include "net/gnrc/ipv6.h" | ||
26 | +#include "net/gnrc/udp.h" | ||
27 | +#include "net/gnrc/pktdump.h" | ||
28 | +#include "timex.h" | ||
29 | +#include "xtimer.h" | ||
30 | + | ||
31 | +static gnrc_netreg_entry_t server = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL, | ||
32 | + KERNEL_PID_UNDEF); | ||
33 | + | ||
34 | +static kernel_pid_t copy_pktd_pid = KERNEL_PID_UNDEF; | ||
35 | +static void send(char *addr_str, char *port_str, char *data, unsigned int num, | ||
36 | + unsigned int delay) | ||
37 | + | ||
38 | +{ | ||
39 | + uint16_t port; | ||
40 | + ipv6_addr_t addr; | ||
41 | + | ||
42 | + /* parse destination address */ | ||
43 | + if (ipv6_addr_from_str(&addr, addr_str) == NULL) { | ||
44 | + puts("Error: unable to parse destination address"); | ||
45 | + return; | ||
46 | + } | ||
47 | + /* parse port */ | ||
48 | + port = (uint16_t)atoi(port_str); | ||
49 | + if (port == 0) { | ||
50 | + puts("Error: unable to parse destination port"); | ||
51 | + return; | ||
52 | + } | ||
53 | + | ||
54 | + for (unsigned int i = 0; i < num; i++) { | ||
55 | + gnrc_pktsnip_t *payload, *udp, *ip; | ||
56 | + unsigned payload_size; | ||
57 | + /* allocate payload */ | ||
58 | + payload = gnrc_pktbuf_add(NULL, data, strlen(data), GNRC_NETTYPE_UNDEF); | ||
59 | + if (payload == NULL) { | ||
60 | + puts("Error: unable to copy data to packet buffer"); | ||
61 | + return; | ||
62 | + } | ||
63 | + /* store size for output */ | ||
64 | + payload_size = (unsigned)payload->size; | ||
65 | + /* allocate UDP header, set source port := destination port */ | ||
66 | + udp = gnrc_udp_hdr_build(payload, port, port); | ||
67 | + if (udp == NULL) { | ||
68 | + puts("Error: unable to allocate UDP header"); | ||
69 | + gnrc_pktbuf_release(payload); | ||
70 | + return; | ||
71 | + } | ||
72 | + /* allocate IPv6 header */ | ||
73 | + ip = gnrc_ipv6_hdr_build(udp, NULL, &addr); | ||
74 | + if (ip == NULL) { | ||
75 | + puts("Error: unable to allocate IPv6 header"); | ||
76 | + gnrc_pktbuf_release(udp); | ||
77 | + return; | ||
78 | + } | ||
79 | + /* send packet */ | ||
80 | + if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip)) { | ||
81 | + puts("Error: unable to locate UDP thread"); | ||
82 | + gnrc_pktbuf_release(ip); | ||
83 | + return; | ||
84 | + } | ||
85 | + /* access to `payload` was implicitly given up with the send operation above | ||
86 | + * => use temporary variable for output */ | ||
87 | + printf("Success: send %u byte to [%s]:%u\n", payload_size, addr_str, | ||
88 | + port); | ||
89 | + xtimer_usleep(delay); | ||
90 | + } | ||
91 | +} | ||
92 | + | ||
93 | +static void start_server(char *port_str) | ||
94 | +{ | ||
95 | + uint16_t port; | ||
96 | + | ||
97 | + /* check if server is already running */ | ||
98 | + if (server.target.pid != KERNEL_PID_UNDEF) { | ||
99 | + printf("Error: server already running on port %" PRIu32 "\n", | ||
100 | + server.demux_ctx); | ||
101 | + return; | ||
102 | + } | ||
103 | + /* parse port */ | ||
104 | + port = (uint16_t)atoi(port_str); | ||
105 | + if (port == 0) { | ||
106 | + puts("Error: invalid port specified"); | ||
107 | + return; | ||
108 | + } | ||
109 | + /* start server (which means registering pktdump for the chosen port) */ | ||
110 | + server.target.pid = copy_pktd_pid; | ||
111 | + server.demux_ctx = (uint32_t)port; | ||
112 | + gnrc_netreg_register(GNRC_NETTYPE_UDP, &server); | ||
113 | + printf("Success: started UDP server on port %" PRIu16 "\n", port); | ||
114 | +} | ||
115 | + | ||
116 | +static void stop_server(void) | ||
117 | +{ | ||
118 | + /* check if server is running at all */ | ||
119 | + if (server.target.pid == KERNEL_PID_UNDEF) { | ||
120 | + printf("Error: server was not running\n"); | ||
121 | + return; | ||
122 | + } | ||
123 | + /* stop server */ | ||
124 | + gnrc_netreg_unregister(GNRC_NETTYPE_UDP, &server); | ||
125 | + server.target.pid = KERNEL_PID_UNDEF; | ||
126 | + puts("Success: stopped UDP server"); | ||
127 | +} | ||
128 | + | ||
129 | +int udp_cmd(int argc, char **argv) | ||
130 | +{ | ||
131 | + if (argc < 2) { | ||
132 | + printf("usage: %s [send|server]\n", argv[0]); | ||
133 | + return 1; | ||
134 | + } | ||
135 | + | ||
136 | + if (strcmp(argv[1], "send") == 0) { | ||
137 | + uint32_t num = 1; | ||
138 | + uint32_t delay = 1000000; | ||
139 | + if (argc < 5) { | ||
140 | + printf("usage: %s send <addr> <port> <data> [<num> [<delay in us>]]\n", | ||
141 | + argv[0]); | ||
142 | + return 1; | ||
143 | + } | ||
144 | + if (argc > 5) { | ||
145 | + num = (uint32_t)atoi(argv[5]); | ||
146 | + } | ||
147 | + if (argc > 6) { | ||
148 | + delay = (uint32_t)atoi(argv[6]); | ||
149 | + } | ||
150 | + send(argv[2], argv[3], argv[4], num, delay); | ||
151 | + } | ||
152 | + else if (strcmp(argv[1], "server") == 0) { | ||
153 | + if (argc < 3) { | ||
154 | + printf("usage: %s server [start|stop]\n", argv[0]); | ||
155 | + return 1; | ||
156 | + } | ||
157 | + if (strcmp(argv[2], "start") == 0) { | ||
158 | + if (argc < 4) { | ||
159 | + printf("usage %s server start <port>\n", argv[0]); | ||
160 | + return 1; | ||
161 | + } | ||
162 | + start_server(argv[3]); | ||
163 | + } | ||
164 | + else if (strcmp(argv[2], "stop") == 0) { | ||
165 | + stop_server(); | ||
166 | + } | ||
167 | + else { | ||
168 | + puts("error: invalid command"); | ||
169 | + } | ||
170 | + } | ||
171 | + else { | ||
172 | + puts("error: invalid command"); | ||
173 | + } | ||
174 | + return 0; | ||
175 | +} |
RIOT/sys/include/net/gnrc/rpl/structs.h
@@ -74,6 +74,9 @@ extern "C" { | @@ -74,6 +74,9 @@ extern "C" { | ||
74 | * RFC6550, section 6.7.1, RPL Control Message Option Generic Format | 74 | * RFC6550, section 6.7.1, RPL Control Message Option Generic Format |
75 | * </a> | 75 | * </a> |
76 | */ | 76 | */ |
77 | + | ||
78 | + | ||
79 | + | ||
77 | typedef struct __attribute__((packed)) { | 80 | typedef struct __attribute__((packed)) { |
78 | uint8_t type; /**< Option Type */ | 81 | uint8_t type; /**< Option Type */ |
79 | uint8_t length; /**< Option Length, does not include the first two byte */ | 82 | uint8_t length; /**< Option Length, does not include the first two byte */ |
RIOT/tests/sched_testing/main.c
@@ -24,8 +24,8 @@ char snd_thread_stack[THREAD_STACKSIZE_MAIN]; | @@ -24,8 +24,8 @@ char snd_thread_stack[THREAD_STACKSIZE_MAIN]; | ||
24 | void *snd_thread(void *unused) | 24 | void *snd_thread(void *unused) |
25 | { | 25 | { |
26 | (void) unused; | 26 | (void) unused; |
27 | - puts("snd_thread running"); | ||
28 | - return NULL; | 27 | + puts("snd_thread running"); |
28 | + return NULL; | ||
29 | } | 29 | } |
30 | 30 | ||
31 | int main(void) | 31 | int main(void) |
RIOT/tests/thread_flags/Makefile