gnrc.h 11.2 KB
/*
 * 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.
 */

/**
 * @defgroup    net_gnrc    Generic (GNRC) network stack
 * @ingroup     net
 * @brief       RIOT's modular default IP network stack.
 * @see         [Martine Lenders' master thesis](http://doc.riot-os.org/mlenders_msc.pdf)
 *              about GNRC's design and evaluation and the slide set of
 *              [its defense](http://doc.riot-os.org/mlenders_msc_def.pdf).
 *
 * About
 * =====
 *
 * This module is currently the default network stack for RIOT and includes
 * many components ranging from a @ref net_gnrc_nomac "simple MAC protocol"
 * through a fully-featured @ref net_gnrc_ipv6 implementation with @ref
 * net_gnrc_sixlowpan "6LowPAN" extensions to an @ref net_gnrc_udp "UDP"
 * implementation and @ref net_gnrc_rpl.
 *
 * A list of all features contained in the @ref net_gnrc is available in the
 * `Modules` section above.
 *
 * Integration into RIOT
 * =====================
 *
 * From the application layer the @ref net_gnrc can be accessed through the
 * @ref net_conn, while the interface to the @ref drivers_netdev_netdev2 is
 * defined by the @ref net_gnrc_netdev2.
 *
 * Architecture
 * ============
 *
 * ![GNRC Network Stack](riot-gnrc.svg)
 *
 * Each layer of the network stack runs in its own thread and each lower layer
 * thread has a higher priority than any upper layer thread. In this regard,
 * the thread of the MAC layer implementation has the highest priority and
 * threads on the application layer have the lowest priority. The communication
 * between threads is handled by the kernel's @ref core_msg functionality and
 * by the @ref net_gnrc_netapi. Most of the times IPC will take place between
 * threads of neighboring layers for packets that traverse the network stack up
 * or down.
 *
 * Due to the design of @ref net_gnrc "GNRC" and the nature of inter-process
 * communication, it is crucial for a new module that introduces a new thread
 * to follow a certain programming construct if it desires to interact with
 * other threads without blocking the system: Utilizing an `event loop`.
 *
 * Hence, a thread for @ref net_gnrc "GNRC" will usually consist of four basic
 * steps.
 *
 * 1. Initialize a message queue (note that its size **must** be a power of two,
 *    see @ref msg_init_queue())
 * 2. register for a @ref net_gnrc_nettype
 * 3. wait for a message
 * 4. react appropriately to a message and return to 3.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
 * void *_event_loop(void *arg)
 * {
 *     static msg_t _msg_q[Q_SZ];
 *     (void)arg;
 *     msg_init_queue(_msg_q, Q_SZ);
 *     gnrc_netreg_entry me_reg = GNRC_NETREG_ENTRY_INIT_PID(
 *                                      GNRC_NETREG_DEMUX_CTX_ALL,
 *                                      sched_active_pid);
 *     gnrc_netreg_register(GNRC_NETTYPE_IPV6, &me_reg);
 *     while (1) {
 *         msg_receive(&msg);
 *         switch (msg.type) {
 *             case TYPE1:
 *                 callback1();
 *                 break;
 *             ...
 *         }
 *     }
 *
 *     return NULL;
 * }
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * @note As an example have a look at the event loops of @ref net_gnrc_ipv6 and
 * @ref net_gnrc_rpl
 *
 * Receiving / Transmitting Packets
 * ================================
 *
 * Packets can be received or transmitted by interacting with the @ref
 * net_gnrc_netapi.
 *
 * Receiving Packets
 * -----------------
 *
 * The reception of a @ref net_gnrc_pkt from another thread is handled by the
 * @ref net_gnrc_netapi module. In order to receive a @ref net_gnrc_pkt of a
 * specific type, it is necessary to register for the appropriate @ref
 * net_gnrc_nettype first. Your thread will then be able to receive certain
 * commands defined in the @ref net_gnrc_netapi module (e.g. @ref
 * net_gnrc_netapi::GNRC_NETAPI_MSG_TYPE_RCV) for all @ref net_gnrc_pkt
 * "Packets" that your thread registered for.
 *
 * The following example will sketch how to receive incoming and outgoing UDP
 * traffic on port 80.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
 * void *_event_loop(void *arg)
 * {
 *     static msg_t _msg_q[Q_SZ];
 *     msg_t msg, reply;
 *     reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
 *     reply.content.value = -ENOTSUP;
 *     msg_init_queue(_msg_q, Q_SZ);
 *     gnrc_pktsnip_t *pkt = NULL;
 *     gnrc_netreg_entry me_reg = { .demux_ctx = 80, .pid = thread_getpid() };
 *     gnrc_netreg_register(GNRC_NETTYPE_UDP, &me_reg);
 *
 *     while (1) {
 *         msg_receive(&msg);
 *         switch (msg.type) {
 *             case GNRC_NETAPI_MSG_TYPE_RCV:
 *                 pkt = msg.content.ptr;
 *                 _handle_incoming_pkt(pkt);
 *                 break;
 *             case GNRC_NETAPI_MSG_TYPE_SND:
 *                 pkt = msg.content.ptr;
 *                 _handle_outgoing_pkt(pkt);
 *                 break;
 *              case GNRC_NETAPI_MSG_TYPE_SET:
 *              case GNRC_NETAPI_MSG_TYPE_GET:
 *                 msg_reply(&msg, &reply);
 *                 break;
 *             default:
 *                 break;
 *         }
 *     }
 *
 *     return NULL;
 * }
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * @note When receiving a message of type @ref GNRC_NETAPI_MSG_TYPE_SET or
 *       @ref GNRC_NETAPI_MSG_TYPE_GET, it is necessary to acknowledge it by
 *       calling @ref msg_reply() with a message of type
 *       @ref GNRC_NETAPI_MSG_TYPE_ACK which contains the actual size of the
 *       GET message's content on success or an error code otherwise.
 *
 * @note Do not forget to unregister with @ref gnrc_netreg_unregister() if you
 *       leave the function
 *       context
 *
 * Transmitting Packets
 * --------------------
 *
 * A packet is transmitted by relaying it to threads interested in handling (and
 * dispatching) packets of its type. To do this, the @ref net_gnrc_netapi
 * offers dispatch helper functions called @ref gnrc_netapi_dispatch_send()
 * and gnrc_netapi_dispatch_receive().
 *
 * The following example sketches the usage and assumes a valid @ref
 * net_gnrc_pkt named `pkt`.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
 * gnrc_pktsnip_t *pkt;
 *
 * pkt = gnrc_pktbuf_add(NULL, data, size, GNRC_NETTYPE_UNDEF);
 * if (pkt == NULL) {
 *      puts("Error: unable to copy data to packet buffer\n");
 *      return;
 * }
 * if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, 80, pkt)) {
 *      puts("Error: no thread is interested");
 *      gnrc_pktbuf_release(pkt);
 *      return;
 * }
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * First, the data to be sent is added to the @ref net_gnrc_pktbuf "packet buffer".
 * This ensures its intactness during the sending process. After the data to be
 * sent has been added to the packet buffer, its parent data structure can safely
 * be freed or re-used.
 *
 * Then, the @ref net_gnrc_pkt "pkt" will be sent to all threads that registered
 * for @ref GNRC_NETTYPE_UDP and the demux context `80`. Every registered thread
 * will receive a @ref GNRC_NETAPI_MSG_TYPE_SND command and can access the @ref
 * net_gnrc_pkt. Note that at this point, the threads receiving pkt act as its
 * owners, so please don't modify pkt after calling any dispatch function.
 *
 * If @ref gnrc_netapi_dispatch_send() is replaced by @ref
 * gnrc_netapi_dispatch_receive() then threads will receive the @ref
 * GNRC_NETAPI_MSG_TYPE_RCV command instead, again with access to the @ref
 * net_gnrc_pkt.
 *
 * @note If the data to be sent requires extra headers to be added for successful
 *       transmission (in the example, this would be IP and UDP headers), these
 *       have to be built manually before calling @ref gnrc_netapi_dispatch_send().
 *       In the interest of conciseness, this is omitted in this tutorial;
 *       please refer to @ref gnrc_udp_hdr_build(), @ref gnrc_ipv6_hdr_build()
 *       etc. for more information.
 *
 * How To Use
 * ==========
 * @ref net_gnrc is highly modular and can be adjusted to include only the
 * desired features. In the following several of the available modules will be
 * stated that you can include in your application's Makefile.
 *
 * - To include the default network device(s) on your board:
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_netdev_default
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * - To auto-initialize these network devices as GNRC network interfaces
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += auto_init_gnrc_netif
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * - You may choose to build either as an IPv6 Node
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_ipv6_default
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *   or as an IPv6 Router
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_ipv6_router_default
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *   An IPv6 Router can forward packets, while an IPv6 Node will simply drop
 *   packets not targeted to it. If an IEEE 802.15.4 network device is present
 *   @ref net_gnrc_sixlowpan (with @ref net_gnrc_sixlowpan_frag and @ref
 *   net_gnrc_sixlowpan_iphc) will be included automatically.

 * - For basic IPv6 (and 6LoWPAN) functionalities choose instead
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_ipv6
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *   or
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_ipv6_router
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *   respectively. Those modules provide the bare minimum of IPv6
 *   functionalities (no @ref net_gnrc_icmpv6, no @ref net_gnrc_ndp). Because
 *   of that, the @ref net_gnrc_ipv6_nc needs to be configured manually. If an
 *   IEEE 802.15.4 device is present @ref net_gnrc_sixlowpan will be included
 *   automatically, but no fragmentation or header compression support will be
 *   provided.
 *
 * - For @ref net_gnrc_icmpv6_echo "ICMPv6 echo request/reply (ping)"
 *   functionality:
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_icmpv6_echo
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * - For @ref net_gnrc_udp support include
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_udp
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * - To use @ref net_conn_udp with GNRC include
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_conn_udp
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * - To include the @ref net_gnrc_rpl module
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
 *   USEMODULE += gnrc_rpl
 *   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *   This will include the @ref net_gnrc_rpl module. To provide forwarding
 *   capabilities it is necessary to build the application with
 *   `gnrc_ipv6_router_default` (or `gnrc_ipv6_router`), not
 *   `gnrc_ipv6_default` (or `gnrc_ipv6`).
 *
 * @{
 *
 * @file
 * @brief       Includes all essential GNRC network stack base modules
 *
 * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
 */

#ifndef GNRC_NETBASE_H_
#define GNRC_NETBASE_H_

#include "net/netopt.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/netreg.h"
#include "net/gnrc/nettype.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/pktbuf.h"
#include "net/gnrc/pkt.h"

#ifdef __cplusplus
extern "C" {
#endif

/* this file does not provide anything on it's own */

#ifdef __cplusplus
}
#endif

#endif /* GNRC_NETBASE_H_ */
/** @} */