1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers: Provide basic interface for all network devices

This commit is contained in:
Martine Lenders 2014-07-29 18:05:57 +02:00
parent 97bf8b09ad
commit 65e0bd5536
6 changed files with 470 additions and 0 deletions

View File

@ -40,5 +40,8 @@ endif
ifneq (,$(filter pir,$(USEMODULE)))
DIRS += pir
endif
ifneq (,$(filter netdev_base,$(USEMODULE)))
DIRS += netdev/base
endif
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,374 @@
/*
* Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* 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.
*/
/**
* @addtogroup netdev
* @{
*
* @file netdev/base.h
* @brief Basic network device driver interface definitions.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef __NETDEV_BASE_H_
#define __NETDEV_BASE_H_
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include "clist.h"
/**
* @brief Type for @ref msg_t if device fired an event.
*/
#define NETDEV_MSG_EVENT_TYPE (0x0100)
/**
* @brief Definition of device families.
*/
typedef enum {
NETDEV_TYPE_UNKNOWN = 0, /**< Type was not specified and may not
understand this API */
NETDEV_TYPE_BASE, /**< Device understands this API */
} netdev_type_t;
/**
* @brief Definition of protocol families to determine which frame types a
* device or protocol layer (see @ref netapi) can handle
*
* @note XXX: The concrete definition of the values is necessary to work
* with super-flexible devices as e.g. @ref native_net. It was also
* decided not to use ethertype since protocols not supplied by it
* might be supported
*/
typedef enum {
NETDEV_PROTO_UNKNOWN = 0x0000, /**< Type was not specified */
/**
* @brief Radio frame protocol
*
* @detail Sends frames as defined by radio_packet_t.
*/
NETDEV_PROTO_RADIO = 0x0001,
/**
* @brief IEEE 802.15.4
*
* @detail Sends frames as defined by ieee802154_frame_t
*/
NETDEV_PROTO_802154 = 0x0002,
NETDEV_PROTO_6LOWPAN = 0x0003, /**< 6LoWPAN. */
NETDEV_PROTO_IPV6 = 0x0004, /**< IPv6. */
NETDEV_PROTO_UDP = 0x0005, /**< UDP. */
NETDEV_PROTO_TCP = 0x0006, /**< TCP. */
NETDEV_PROTO_CCNL = 0x0007, /**< CCN lite. */
} netdev_proto_t;
/**
* @brief Definition of basic network device options.
* @note Feel free to expand if your device needs/supports more.
*/
typedef enum {
/**
* @brief Communication type for the device as defined by @ref netdev_proto_t
*
* @detail If a driver does not support the type (but the setting of the
* option is supported) it @ref netdev_driver_t::set_option() shall result
* with -EPROTONOSUPPORT.
*
* *value_len* for @ref netdev_driver_t::get_option() must always be at
* least `sizeof(netdev_proto_t)`.
*/
NETDEV_OPT_PROTO = 0,
NETDEV_OPT_CHANNEL, /**< Channel for the device as unsigned value
in host byte order */
NETDEV_OPT_ADDRESS, /**< Hardware address for the device as
unsigned value in host byte order */
NETDEV_OPT_NID, /**< Network ID (e.g. PAN ID in IEEE 802.15.4)
for the device as unsigned value in
host byte order */
NETDEV_OPT_ADDRESS_LONG, /**< Longer hardware address for the device
(e.g. EUI-64) for the device as
unsigned value in host byte order */
NETDEV_OPT_TX_POWER, /**< The output of the device in dB as
signed value in host byte order */
NETDEV_OPT_MAX_PACKET_SIZE, /**< Maximum packet size the device supports
unsigned value in host byte order */
} netdev_opt_t;
/**
* @brief Definition of basic network device.
* @note Feel free to expand if your device needs/supports more
*/
typedef enum {
NETDEV_STATE_POWER_OFF = 0, /**< Device is powered off */
NETDEV_STATE_POWER_SLEEP, /**< Device is sleeping */
NETDEV_STATE_POWER_IDLE, /**< Device is idle */
NETDEV_STATE_RX_MODE, /**< Device is in receive mode */
NETDEV_STATE_PROMISCUOUS_MODE, /**< Device is in receive mode and
accepts all packets without regard
for their destination */
} netdev_state_t;
/**
* @brief Circular list type to store a number of protocol headers of
* unspecified type to work with @ref clist.h.
*
* @extends clist_node_t
*/
typedef struct __attribute__((packed)) netdev_hlist_t {
struct netdev_hlist_t *next; /**< next element in list */
struct netdev_hlist_t *prev; /**< previous element in list */
void *header; /**< the header stored in here */
size_t header_len; /**< the length of the header in byte */
} netdev_hlist_t;
/**
* @brief Definition of the network device type
*
* @see struct netdev_t
*
* @note Forward definition to use in @ref netdev_driver_t
*/
typedef struct netdev_t netdev_t;
/**
* Receive data callback for data frames from given network device.
*
* @param[in] dev the network device the frame came from.
* @param[in] src the (hardware) source address of the frame in host
* byte order.
* @param[in] src_len the length of *src* in byte
* @param[in] dest the (hardware) destination address of the frame in
* host byte order.
* @param[in] dest_len the length of *dest* in byte
* @param[in] payload the payload of the frame.
* @param[in] payload_len the length of *payload* in byte
*
* @return the number of bytes in payload actually processed by the callback,
* on success
* @return a fitting negative errno on failure
*/
typedef int (*netdev_rcv_data_cb_t)(netdev_t *dev, void *src, size_t src_len,
void *dest, size_t dest_len, void *payload,
size_t payload_len);
/**
* @brief Network device API definition.
*
* @details This is a set of functions that must be implemented by any driver
* for a network device.
*/
typedef struct {
/**
* @brief Initialize a given network device.
*
* @param[in] dev the device to initialize
*
* @return 0 on success
* @return -ENODEV if *dev* can not be initialized
*/
int (*init)(netdev_t *dev);
/**
* @brief Send data via a given network device
*
* @param[in] dev the network device
* @param[in] dest the (hardware) destination address for the data
* in host byte order.
* @param[in] dest_len the length of *dest* in byte
* @param[in] upper_layer_hdrs header data from higher network layers from
* highest to lowest layer. Must be prepended to
* the data stream by the network device. May be
* NULL if there are none.
* @param[in] data the data to send
* @param[in] data_len the length of *data* in byte
*
* @return the number of byte actually send on success
* @return -EAFNOSUPPORT if address of length dest_len is not supported
* by the device *dev*
* @return -ENODEV if *dev* is not recognized
* @return -EMSGSIZE if the total frame size is too long to fit in a frame
* of the device *dev*
* @return a fitting negative other errno on other failure
*/
int (*send_data)(netdev_t *dev, void *dest, size_t dest_len,
netdev_hlist_t *upper_layer_hdrs, void *data,
size_t data_len);
/**
* @brief Registers a receive data callback to a given network device.
*
* @param[in] dev the network device.
* @param[in] cb the callback.
*
* @return 0, on success
* @return -ENODEV, if *dev* is not recognized
* @return -ENOBUFS, if maximum number of registrable callbacks is exceeded
*/
int (*add_receive_data_callback)(netdev_t *dev, netdev_rcv_data_cb_t cb);
/**
* @brief Unregisters a receive data callback to a given network device.
*
* @param[in] dev the network device.
* @param[in] cb the callback.
*
* @return 0, on success
* @return -ENODEV, if *dev* is not recognized
*/
int (*rem_receive_data_callback)(netdev_t *dev, netdev_rcv_data_cb_t cb);
/**
* @brief Get an option value from a given network device.
*
* @param[in] dev the network device
* @param[in] opt the option type
* @param[out] value pointer to store the gotten value in
* @param[in,out] value_len the length of *value*. Must be initialized to the
* available space in value on call.
* @return 0, on success
* @return -ENODEV, if *dev* is not recognized
* @return -ENOTSUP, if *opt* is not supported for the device with this
* operation
* @return -EOVERFLOW, if length of *value* is longer then *value_len*.
* @return any other fitting negative errno if the ones stated above
* are not sufficient
*/
int (*get_option)(netdev_t *dev, netdev_opt_t opt, void *value,
size_t *value_len);
/**
* @brief Set an option value for a given network device.
*
* @param[in] dev the network device
* @param[in] opt the option type
* @param[in] value the value to set
* @param[in] value_len the length of *value*
*
* @return 0, on success
* @return -EINVAL, if *value* is not in a required format
* @return -ENODEV, if *dev* is not recognized
* @return -ENOTSUP, if *opt* is not supported for the device with this
* operation
* @return -EOVERFLOW, if *value_len* is larger then the device expects.
* @return -EPROTONOSUPPORT, if *opt* was NETDEV_OPT_PROTO and type is
* not supported.
* @return any other fitting negative errno if the ones stated above
* are not sufficient
*/
int (*set_option)(netdev_t *dev, netdev_opt_t opt, void *value,
size_t value_len);
/**
* @brief Get state from a given network device.
*
* @param[in] dev the network device
* @param[out] state the network device
*
* @return 0, on success
* @return -ENODEV, if *dev* is not recognized
* @return -ETIME, if device timed out on trying to acquire state
*/
int (*get_state)(netdev_t *dev, netdev_state_t *state);
/**
* @brief Set state from a given network device.
*
* @param[in] dev the network device
* @param[in] state the network device
*
* @return 0, on success
* @return -ENODEV, if *dev* is not recognized
* @return -ENOTSUP, if *state* is not supported
* @return -ETIME, if device timed out on trying to change state
*/
int (*set_state)(netdev_t *dev, netdev_state_t state);
/**
* @brief Must be called by a controlling thread if a message of type
* NETDEV_MSG_EVENT_TYPE was received
*
* @param[in] dev the network device that fired the event.
* @param[in] event_type Event type. Values are free to choose for the
* driver. Must be given in the @ref msg_t::content::value
* of the received message
*/
void (*event)(netdev_t *dev, uint32_t event_type);
} netdev_driver_t;
/**
* @brief Definition of the network device type
*
* @note Your driver may overload this with additional information (e.g.
* how the device is connected)
*/
struct netdev_t {
netdev_type_t type; /**< The type of this device */
const netdev_driver_t *driver; /**< The driver for this device */
void *more; /**< Pointer to device dependent
additional information. E.g. the
low-level device(s) to
communiticate with this device. */
};
/**
* @brief Helper function to calculate the total length of the headers in
* *hlist*.
*
* @param[in] hlist The header list.
*
* @return Length in number of bytes of all headers in *hlist*.
*/
size_t netdev_get_hlist_len(const netdev_hlist_t *hlist);
/**
* @brief Advance the header list
*
* @see clist_advance
*
* @param[in,out] list The list to work upon.
*/
static inline void netdev_hlist_advance(netdev_hlist_t **list)
{
clist_advance((clist_node_t **)list);
}
/**
* @brief Add *node* to list start of *list*
*
* @param[in,out] list The list to add *node* to
* @param[in] node The node to add to the list
*/
static inline void netdev_hlist_add(netdev_hlist_t **list,
netdev_hlist_t *node)
{
clist_add((clist_node_t **)list, (clist_node_t *)node);
*list = node;
}
/**
* @brief Removes *node* from list *list*
*
* @see clist_remove
*
* @param[in,out] list The list to remove *node* from
* @param[in] node The node to remove from the list
*/
static inline void netdev_hlist_remove(netdev_hlist_t **list,
netdev_hlist_t *node)
{
clist_remove((clist_node_t **)list, (clist_node_t *)node);
}
#endif /* __NETDEV_BASE_H_ */
/**
* @}
*/

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* 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.
*/
/**
* @addtogroup netdev
* @{
*
* @file netdev/default.h
* @brief Supplies the users with default values for the use of
* @ref netdev
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef __NETDEV_DEFAULT_H_
#define __NETDEV_DEFAULT_H_
#include "netdev/base.h"
/**
* @def NETDEV_DEFAULT
*
* @brief Default device as a pointer of netdev_t.
*/
#endif /* __NETDEV_DEFAULT_H_ */

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the LGPLv2 License.
* See the file LICENSE in the top level directory for more details.
*/
/**
* @defgroup netdev Network device interface
* @ingroup drivers
* @brief Network device drivers
*
* The module the network device drivers. It consists of a set of device
* independent interface definitions and specific implementations for every
* device.
*/

View File

@ -0,0 +1,5 @@
MODULE := netdev_base
INCLUDES += -I$(RIOTBASE)/drivers/include
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2014 Martin Lenders <mlenders@inf.fu-berlin.de>
*
* 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.
*/
/**
* @addtogroup netdev
* @{
*
* @file base.c
* @brief Provides helper functions to the API in @ref netdev/base.h.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#include "clist.h"
#include "netdev/base.h"
size_t netdev_get_hlist_len(const netdev_hlist_t *hlist)
{
netdev_hlist_t *ptr = (netdev_hlist_t *)hlist;
size_t length = 0;
if (ptr == NULL) {
return 0;
}
do {
length += ptr->header_len;
clist_advance((clist_node_t **)&ptr);
} while (ptr != hlist);
return length;
}
/**
* @}
*/