/* * Copyright (C) 2008, 2009, 2010 Kaspar Schleiser * Copyright (C) 2013 INRIA * Copyright (C) 2013 Ludwig Knüpfer * * 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 Default application that shows a lot of functionality of RIOT * * @author Kaspar Schleiser * @author Oliver Hahm * @author Ludwig Knüpfer * * @} */ #include #include #include "msg.h" #include "thread.h" #include "shell.h" #include "shell_commands.h" #include "xtimer.h" #include "net/gnrc.h" #include "net/gnrc/netreg.h" #include "net/gnrc/netif/ieee802154.h" #define SEND_INTERVAL (1) #define RCV_QUEUE_SIZE (8) #ifndef NODE_ID #error NODE_ID undefined #endif char dump_thread_stack[THREAD_STACKSIZE_MAIN]; static msg_t dump_thread_msg_queue[RCV_QUEUE_SIZE]; static kernel_pid_t dump_thread_pid; char send_thread_stack[THREAD_STACKSIZE_MAIN]; static gnrc_netif_t *ieee802154_netif = NULL; static uint16_t seq_nr = 0; static void _dump(gnrc_pktsnip_t *pkt) { gnrc_pktsnip_t *snip = pkt; uint8_t* data; gnrc_netif_hdr_t *hdr; while(snip != NULL) { switch(snip->type) { case GNRC_NETTYPE_UNDEF : data = (uint8_t*)snip->data; data[snip->size] = 0; printf("Contents: '%s'\n", data); break; case GNRC_NETTYPE_NETIF : hdr = snip->data; printf("HDR: %d %d %d\n", hdr->rssi, hdr->lqi, hdr->crc_valid); break; default : printf("snip of type %d\n", snip->type); break; } snip = snip->next; } gnrc_pktbuf_release(pkt); } void *dump_thread(void *arg) { (void) arg; msg_init_queue(dump_thread_msg_queue, RCV_QUEUE_SIZE); gnrc_netreg_entry_t me_reg = GNRC_NETREG_ENTRY_INIT_PID(GNRC_NETREG_DEMUX_CTX_ALL, sched_active_pid); gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &me_reg); msg_t msg; while(1) { msg_receive(&msg); //printf("[dump_thread] message received: %d\n", msg.type); switch(msg.type) { case GNRC_NETAPI_MSG_TYPE_RCV : _dump( msg.content.ptr ); break; default : puts("ERROR: Unknown message type???"); /// gnrc_pktbuf_release( msg.content.ptr ); break; } /* if (msg.type == MSG_TYPE_ISR) { netdev_t *dev = msg.content.ptr; dev->driver->isr(dev); } else { puts("unexpected message type"); } */ } return NULL; } static netopt_enable_t enable = true; static netopt_enable_t disable = false; void *send_thread(void *arg) { (void) arg; /* struct iovec vector[2]; uint8_t hdr[IEEE802154_MAX_HDR_LEN]; uint8_t src[2] = {1,1}; uint8_t dst[2] = {0xFF, 0xFF}; //uint8_t pan[2] = {0x12, 0x34}; le_uint16_t pan = {.u16 = 0x1234}; uint8_t seq = 0; int res = ieee802154_set_frame_hdr(hdr, src, 2, dst, 2, pan, pan, NETDEV_IEEE802154_RAW | IEEE802154_FCF_TYPE_DATA, seq); vector[0].iov_base = hdr; vector[0].iov_len = (size_t)res; vector[1].iov_base = data; vector[1].iov_len = size; */ size_t addr_len = 0; uint8_t addr[GNRC_NETIF_L2ADDR_MAXLEN]; gnrc_pktsnip_t *pkt, *hdr; gnrc_netif_hdr_t *nethdr; int ret; ret = gnrc_netapi_set(ieee802154_netif->pid, NETOPT_PROMISCUOUSMODE, 0, &enable, sizeof(netopt_enable_t)); ret = gnrc_netapi_set(ieee802154_netif->pid, NETOPT_AUTOACK, 0, &disable, sizeof(netopt_enable_t)); ret = gnrc_netapi_set(ieee802154_netif->pid, NETOPT_CSMA, 0, &disable, sizeof(netopt_enable_t)); uint8_t retrans = 0; ret = gnrc_netapi_set(ieee802154_netif->pid, NETOPT_RETRANS, 0, &retrans, sizeof(retrans)); int8_t retries = 7; ret = gnrc_netapi_set(ieee802154_netif->pid, NETOPT_CSMA_RETRIES, 0, &retries, sizeof(retries)); (void)ret; uint8_t flags = 0 | GNRC_NETIF_HDR_FLAGS_BROADCAST; uint8_t data[25]; uint8_t size; while(1) { xtimer_sleep(SEND_INTERVAL); printf("send... "); seq_nr++; size = sprintf((char*)data, "Hello from %2d (%d)", NODE_ID, seq_nr); /* put packet together */ pkt = gnrc_pktbuf_add(NULL, data, size, GNRC_NETTYPE_UNDEF); if (pkt == NULL) { puts("ERROR: packet buffer full"); return NULL; } hdr = gnrc_netif_hdr_build(NULL, 0, addr, addr_len); if (hdr == NULL) { puts("ERROR: packet buffer full"); gnrc_pktbuf_release(pkt); return NULL; } LL_PREPEND(pkt, hdr); nethdr = (gnrc_netif_hdr_t *)hdr->data; nethdr->flags = flags; /* and send it */ if (gnrc_netapi_send(ieee802154_netif->pid, pkt) < 1) { puts("ERROR: unable to send"); gnrc_pktbuf_release(pkt); } else { puts("OK"); } } return NULL; } int main(void) { dump_thread_pid = thread_create(dump_thread_stack, sizeof(dump_thread_stack), THREAD_PRIORITY_MAIN + 1, 0, dump_thread, NULL, "dump_thread"); gnrc_netif_t *netif = NULL; while((netif = gnrc_netif_iter(netif))) { puts("Found gnrc netif"); ieee802154_netif = netif; thread_create(send_thread_stack, sizeof(send_thread_stack), THREAD_PRIORITY_MAIN + 2, THREAD_CREATE_STACKTEST, send_thread, NULL, "send_thread"); } (void) puts("Welcome to RIOT!"); printf("This is node %d\n", NODE_ID); char line_buf[SHELL_DEFAULT_BUFSIZE]; shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); return 0; }