-
Notifications
You must be signed in to change notification settings - Fork 0
How to implement a `ng_netdev` enabled device
The following sections describe how to implement a ng_netdev
enabled device.
-
(implementation of
driver.add_event_callback
) -
the implementation is pretty much always the same:
if ((dev == NULL) || (dev->driver != &ng_tapnet_driver)) { return -ENODEV; }
if (dev->event_cb != NULL) { return -ENOBUFS; }
dev->event_cb = cb;
return 0;
# remove event callback
* *(implementation of `driver.rem_event_callback`)*
* the implementation is pretty much always the same:
``` {.c}
if ((dev == NULL) || (dev->driver != &ng_tapnet_driver)) {
return -ENODEV;
}
if (dev->event_cb != NULL) {
return -ENOBUFS;
}
dev->event_cb = cb;
return 0;
- in interrupt handler of driver:
-
determine event type
event_type
- value can be chosen by driver
- not necessarily bound to
ng_netdev_event_t
-
determine device
dev
-
send message
msg
todev->mac_pid
(event handler thread) with
-
msg.type == NG_NETDEV_MSG_TYPE_EVENT msg.content.value = event_type msg_send(&msg, dev->mac_pid); ```
-
in thread
dev->mac_pid
(dev
is known by event handler thread):
msg_receive(&msg);
switch (msg.type) { case NG_NETDEV_MSG_TYPE_EVENT: dev->driver->isr_event(dev, msg.content.value); break; /* ... */ }
* in `driver.isr_event(dev, event_type)`:
- check `dev` (`dev != NULL` and `dev->driver == &driver`)
- call event handlers `_event_<event_type>()` for event according to event
* **FAQ**:
- *TODO*
## RX started
*TODO*
## RX complete
* read received data `data` (of length `data_len`) from device
* add `ng_netif_hdr_t` with both source `l2src` (of length `l2src_len`) and
destination address `l2_dest` (of length `l2dst_len`) to `ng_pktbuf`
``` {.c}
ng_pktsnip_t *hdr_snip = ng_pktbuf_add(NULL, NULL,
sizeof(ng_netif_hdr_t) + l2src_len +
l2dst_len, NG_NETTYPE_UNDEF);
if (hdr_snip == NULL) {
DEBUG("Packet buffer full.\n");
return;
}
ng_netif_hdr_t *hdr = hdr_snip->data;
ng_netif_hdr_init(hdr, l2src_len, l2dst_len);
ng_netif_hdr_set_src_addr(hdr, l2src, l2src_len);
ng_netif_hdr_set_src_addr(hdr, l2dst, l2dst_len);
hdr->if_pid = thread_getpid();
hdr->rssi = l2rssi;
hdr->lqi = l2lqi;
-
determine demultiplexing type
demux_type
(e.g. via Ethertype with Ethernet devices) if available -
otherwise
demux_type
can be a fixed value (e.g.NG_NETTYPE_SIXLOWPAN
for IEEE 802.15.4 devices) -
copy payload of received packet into packet buffer
ng_nettype_t demux_type = NG_NETTYPE_UNDEF;
switch (ether_type) { #ifdef MODULE_NG_IPV6 case ETHER_TYPE_IPV6: demux_type = NG_NETTYPE_IPV6; break; #endif
default:
break;
}
pkt = ng_pktbuf_add(pkt, data + L2_HDR_LEN, data_len, demux_type);
if (pkt == NULL) { DEBUG("Packet buffer full.\n"); ng_pktbuf_release(hdr_snip); return; }
* call callback event handler with `pkt` as argument if available:
``` {.c}
if (dev->event_cb) {
dev->event_cb(NETDEV_EVENT_RX_COMPLETE, pkt);
}
else {
ng_pktbuf_release(pkt);
}
```
* release packet also in other error case, no one else will clean-up your mess :wink:
* **FAQ**:
- *TODO*
## TX started
*TODO*
## TX complete
*TODO*
# send data
* *(implementation of `driver.send_data`)*
* check if `pkt != NULL`, return `-EFAULT` on failure
* check `dev` (`dev != NULL` and `dev->driver == &driver`)
* on failure: release `pkt` return `-ENODEV`
* build device header from `netif_hdr` (is first header in `pkt`)
* put device header in out buffer
* put rest of `pkt` out buffer `out_buf` (may also be SPI buffer or similar)
```C
ng_pktsnip_t *ptr = pkt->next;
int nwrite = L2_HDR_LEN;
while (ptr) {
memcpy(out_buf + nwrite, ptr->data, ptr->size);
if (nwrite > OUT_BUF_SIZE) {
ng_pktbuf_release(pkt);
return -ENOBUFS;
}
ptr = ptr->next;
}
ng_pktbuf_release(pkt);
- send content of out buffer
- release packet also in other error case, no one else will clean-up your mess 😉
-
FAQ:
- TODO
- (implementation of
driver.get
) - check
dev
(dev != NULL
anddev->driver == &driver
), return -ENODEV on failure - check if getting of
opt
is supported, return-ENOSUP
on failure - check if
*value_len
is appropriate foropt
, return -EOVERFLOW on failure- use
*value_len < sizeof(option_type)
for array like options (like addresses) - use
*value_len != sizeof(option_type)
for primitive types
- use
- set
*value_len
tosizeof(option_type)
- copy
option_value
intovalue
- return length of parameter on success
-
FAQ:
- TODO
- (implementation of
driver.get
) - check
dev
(dev != NULL
anddev->driver == &driver
), return -ENODEV on failure - check if setting of
opt
is supported, return-ENOSUP
on failure - check if
*value_len
is appropriate foropt
, return -EOVERFLOW on failure- use
*value_len < sizeof(option_type)
for array like options (like addresses) - use
*value_len != sizeof(option_type)
for primitive types
- use
- set
*value_len
tosizeof(option_type)
- copy
option_value
intovalue
- return length of parameter on success
-
FAQ:
- TODO
RIOT - The friendly Operating System for the Internet of Things
Homepage | [GitHub] (https://github.com/RIOT-OS/) | Developers Mailing List | Users Mailing List | Twitter @RIOT_OS
- Family: ARM
- Board: Airfy Beacon
- Board: Arduino Due
- Board: CC2538DK
- Board: CC2650STK
- Board: HikoB Fox
- Board: IoT LAB M3
- Board: LimiFrog-v1
- Board: mbed_lpc1768
- Board: MSB-IoT
- Board: MSBA2
- Board: Nucleo-L1
- Board: Nucleo-F446
- Board: Nucleo-F334
- Board: Nucleo-F303
- Board: Nucleo-F091
- Board: Mulle
- Board: OpenMote
- Board: PCA1000x (nRF51822 Development Kit)
- Board: Phytec phyWAVE-KW22
- Board: RFduino
- Board: SAMR21-xpro
- Board: SAML21-xpro
- Board: Seeeduino Arch-Pro
- Board: SODAQ Autonomo
- Board: Spark Core
- Board: STM32F0discovery
- Board: STM32F3discovery
- Board: STM32F4discovery
- Board: UDOO
- Board: yunjia-nrf51822
- Board: Zolertia remote
- Family: ATmega
- Board: Arduino Mega2560
- Board: Arduino Uno
- Board: Arduino Duemilanove
- Family: MSP430
- Board: MSB-430H
- Board: TelosB
- Board: WSN430
- Board: Zolertia Z1
- Board: eZ430-Chronos
- Family: native
- Board: native
- Family: x86
- Board: Intel Galileo