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:
parent
97bf8b09ad
commit
65e0bd5536
@ -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
|
||||
|
374
drivers/include/netdev/base.h
Normal file
374
drivers/include/netdev/base.h
Normal 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_ */
|
||||
/**
|
||||
* @}
|
||||
*/
|
30
drivers/include/netdev/default.h
Normal file
30
drivers/include/netdev/default.h
Normal 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_ */
|
16
drivers/include/netdev/doc.txt
Normal file
16
drivers/include/netdev/doc.txt
Normal 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.
|
||||
*/
|
5
drivers/netdev/base/Makefile
Normal file
5
drivers/netdev/base/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
MODULE := netdev_base
|
||||
|
||||
INCLUDES += -I$(RIOTBASE)/drivers/include
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
42
drivers/netdev/base/base.c
Normal file
42
drivers/netdev/base/base.c
Normal 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
Loading…
Reference in New Issue
Block a user