/* * Copyright (C) 2015 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup examples * @{ * * @file * @brief Example application for demonstrating the RIOT network stack * * @author Hauke Petersen * * @} */ #include #include #include #include #include #include #include #include "net/gnrc/ipv6.h" #include "shell.h" #include "shell_commands.h" #include "msg.h" #include "thread.h" #include "sched.h" #include "thread.h" #include "kernel_types.h" #include "net/netstats.h" #include "net/ipv6/addr.h" #include "net/gnrc/ipv6/netif.h" #include "net/gnrc/netif.h" #include "net/gnrc/netapi.h" #include "net/netopt.h" #include "net/gnrc/pkt.h" #include "net/gnrc/pktbuf.h" #include "net/gnrc/netif/hdr.h" #include "net/gnrc/sixlowpan/netif.h" #include "net/fib.h" #include "net/gnrc.h" #include "net/gnrc/udp.h" #include "net/gnrc/pktdump.h" #ifdef MODULE_SCHEDSTATISTICS #include "xtimer.h" #endif #ifdef MODULE_TLSF #include "tlsf.h" #endif #define MAIN_QUEUE_SIZE (8) /** * @brief The maximal expected link layer address length in byte */ #define MAX_ADDR_LEN (8U) /** * @brief The default IPv6 prefix length if not specified. */ #define SC_NETIF_IPV6_DEFAULT_PREFIX_LEN (64) //#define _STACKSIZE (THREAD_STACKSIZE_DEFAULT + THREAD_EXTRA_STACKSIZE_PRINTF) #define MSG_TYPE_ISR (0x3456) #define PORT_UDP "1234" #define NUM_UDP (100) #define DELAY_UDP (100000) // us char stack[THREAD_STACKSIZE_MAIN]; // addr ipv6 link local node 1: fe80::3734:510e:3317:3402 uint8_t node1[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x34,0x51,0x0e,0x33,0x17,0x34,0x02}; // addr ipv6 link local node 2: fe80::3634:5110:3473:3762 uint8_t node2[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x34,0x51,0x10,0x34,0x73,0x37,0x62}; //addr ipv6 link local node 3: fe80::3634:5110:3471:3766 uint8_t node3[16]={0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x34,0x51,0x10,0x34,0x71,0x37,0x66}; static kernel_pid_t _send_pid; //Arg_snd_UDP sndudp = { .data = "go",.num = 100, .delay = 1000000 }; static void send_udp_main(char *addr_str, char *port_str, char *data, unsigned int num, unsigned int delay) { uint16_t port; ipv6_addr_t addr; /* parse destination address */ if (ipv6_addr_from_str(&addr, addr_str) == NULL) { puts("Error: unable to parse destination address"); return; } /* parse port */ port = (uint16_t)atoi(port_str); if (port == 0) { puts("Error: unable to parse destination port"); return; } for (unsigned int i = 0; i < num; i++) { gnrc_pktsnip_t *payload, *udp, *ip; //unsigned payload_size; /* allocate payload */ payload = gnrc_pktbuf_add(NULL, data, strlen(data), GNRC_NETTYPE_UNDEF); if (payload == NULL) { puts("Error: unable to copy data to packet buffer"); return; } /* store size for output */ // payload_size = (unsigned)payload->size; /* allocate UDP header, set source port := destination port */ udp = gnrc_udp_hdr_build(payload, port, port); if (udp == NULL) { puts("Error: unable to allocate UDP header"); gnrc_pktbuf_release(payload); return; } /* allocate IPv6 header */ ip = gnrc_ipv6_hdr_build(udp, NULL, &addr); if (ip == NULL) { puts("Error: unable to allocate IPv6 header"); gnrc_pktbuf_release(udp); return; } /* send packet */ if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip)) { puts("Error: unable to locate UDP thread"); gnrc_pktbuf_release(ip); return; } /* access to `payload` was implicitly given up with the send operation above * => use temporary variable for output */ //printf("Success: send %u byte to [%s]:%u\n", payload_size, addr_str,port); xtimer_usleep(delay); } } void *_send_thread(void *arg) { (void)arg; char add_dest_str[]="dead:beef::3766"; send_udp_main(add_dest_str,PORT_UDP,"go",NUM_UDP,DELAY_UDP); return &_send_pid; } static void _init_interface(void) { kernel_pid_t ifs[GNRC_NETIF_NUMOF]; ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED; ipv6_addr_t tmp_addr= IPV6_ADDR_UNSPECIFIED; uint8_t hwaddr[MAX_ADDR_LEN]; int res; //msg_t message; gnrc_netif_get(ifs); //addresses gobales addr.u8[0] = 0xde; addr.u8[1] = 0xad; addr.u8[2] = 0xbe; addr.u8[3] = 0xef; res = gnrc_netapi_get(ifs[0], NETOPT_ADDRESS, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { addr.u8[14] = *hwaddr; addr.u8[15] = *(hwaddr+1); } memcpy(tmp_addr.u8,addr.u8,IPV6_ADDR_BIT_LEN); gnrc_ipv6_netif_add_addr(ifs[0], &addr, 64, GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST); /* model ipv6 addr: dead:beef::Hwaddr */ if((addr.u8[14]==0x34)&&(addr.u8[15]==0x02)){ tmp_addr.u8[14] = 0x37; tmp_addr.u8[15] = 0x66; //fibroute dest: dead:beef::3766 via fe80::3634:5110:3473:3762 fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node2, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); tmp_addr.u8[14] = 0x37; tmp_addr.u8[15] = 0x62; //fibroute dest: dead:beef::3762 via fe80::3634:5110:3473:3762 fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node2, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); _send_pid = thread_create(stack, sizeof(stack), THREAD_PRIORITY_MAIN - 1, THREAD_CREATE_STACKTEST, _send_thread, NULL, "send_thread"); if (_send_pid <= KERNEL_PID_UNDEF) { puts("Creation of receiver thread failed"); } //msg_try_send(&message,_send_pid); }else if((addr.u8[14]==0x37)&&(addr.u8[15]==0x62)){ tmp_addr.u8[14] = 0x37; tmp_addr.u8[15] = 0x66; //fibroute dest: dead:beef::3766 via fe80::3634:5110:3471:3766 fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node3, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); tmp_addr.u8[14] = 0x34; tmp_addr.u8[15] = 0x02; //fibroute dest: dead:beef::3402 via fe80::3734:510e:3317:3402 fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node1, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); }else if((addr.u8[14]==0x37)&&(addr.u8[15]==0x66)){ tmp_addr.u8[14] = 0x34; tmp_addr.u8[15] = 0x02; //fibroute dest: dead:beef::3402 via fe80::3634:5110:3473:3762 fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node2, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); tmp_addr.u8[14] = 0x37; tmp_addr.u8[15] = 0x62; //fibroute dest: dead:beef::3762 via fe80::3634:5110:3473:3762 fib_add_entry(&gnrc_ipv6_fib_table, ifs[0],tmp_addr.u8, IN6ADDRSZ, 0,node2, IN6ADDRSZ, 0, FIB_LIFETIME_NO_EXPIRE); }else{ puts("new node ?"); } } static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; extern int udp_cmd(int argc, char **argv); static const shell_command_t shell_commands[] = { { "udp", "send data over UDP and listen on UDP ports", udp_cmd }, { NULL, NULL, NULL } }; int main(void) { msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE); puts("RIOT network stack example application"); _init_interface(); /* start shell */ puts("All up, running the shell now"); char line_buf[SHELL_DEFAULT_BUFSIZE]; shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); /* should be never reached */ return 0; }