mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
191 lines
5.4 KiB
C++
191 lines
5.4 KiB
C++
/*
|
|
* Copyright (C) 2022 HAW Hamburg
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* @{
|
|
*
|
|
* @file
|
|
* @author José I. Álamos <jose.alamos@haw-hamburg.de>
|
|
*/
|
|
|
|
#include "opendsme/DSMEPlatform.h"
|
|
#include "opendsme/opendsme.h"
|
|
#include "mac_services/DSME_Common.h"
|
|
#include "net/gnrc/netif/hdr.h"
|
|
|
|
dsme::DSMEPlatform m_dsme;
|
|
|
|
extern "C" {
|
|
static bool _pan_coord;
|
|
extern void heap_stats(void);
|
|
static int _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
|
|
{
|
|
/* Note that there the short address is assigned by the coordinator and the
|
|
* user should not have control over it.
|
|
* Given that, and the fact the current MAC does not communicate with
|
|
* different PANs, we can always use the short address */
|
|
uint8_t bcast[2] = { 0xFF, 0xFF };
|
|
uint8_t *addr;
|
|
|
|
pkt = gnrc_pktbuf_start_write(pkt);
|
|
gnrc_netif_hdr_t *hdr = (gnrc_netif_hdr_t *)pkt->data;
|
|
|
|
if (hdr->flags &= GNRC_NETIF_HDR_FLAGS_MULTICAST) {
|
|
addr = static_cast<uint8_t *>(&bcast[0]);
|
|
}
|
|
else if (hdr->dst_l2addr_len == IEEE802154_LONG_ADDRESS_LEN) {
|
|
addr = gnrc_netif_hdr_get_dst_addr(hdr)
|
|
+ IEEE802154_LONG_ADDRESS_LEN
|
|
- IEEE802154_SHORT_ADDRESS_LEN;
|
|
}
|
|
else if (hdr->dst_l2addr_len == IEEE802154_SHORT_ADDRESS_LEN) {
|
|
addr = gnrc_netif_hdr_get_dst_addr(hdr);
|
|
}
|
|
else {
|
|
gnrc_pktbuf_release(pkt);
|
|
return -EBADMSG;
|
|
}
|
|
|
|
uint16_t _addr = byteorder_ntohs(*((network_uint16_t *)addr));
|
|
|
|
pkt = gnrc_pktbuf_remove_snip(pkt, pkt);
|
|
m_dsme.sendFrame(_addr, (iolist_t *)pkt);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif)
|
|
{
|
|
/* Not used */
|
|
return NULL;
|
|
}
|
|
|
|
static int _get(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt)
|
|
{
|
|
gnrc_netif_acquire(netif);
|
|
int res;
|
|
network_uint16_t addr;
|
|
le_uint64_t ext_addr;
|
|
uint8_t *addr_ptr = static_cast<uint8_t *>(ext_addr.u8);
|
|
|
|
switch (opt->opt) {
|
|
case NETOPT_MAX_PDU_SIZE:
|
|
*((uint16_t *)opt->data) = IEEE802154_FRAME_LEN_MAX;
|
|
res = sizeof(uint16_t);
|
|
break;
|
|
case NETOPT_ADDR_LEN:
|
|
*((uint16_t *)opt->data) = IEEE802154_SHORT_ADDRESS_LEN;
|
|
res = sizeof(uint16_t);
|
|
break;
|
|
case NETOPT_ADDRESS:
|
|
assert(opt->data_len >= IEEE802154_SHORT_ADDRESS_LEN);
|
|
m_dsme.getShortAddress(&addr);
|
|
memcpy(opt->data, &addr, IEEE802154_SHORT_ADDRESS_LEN);
|
|
res = IEEE802154_SHORT_ADDRESS_LEN;
|
|
break;
|
|
case NETOPT_ADDRESS_LONG: {
|
|
assert(opt->data_len >= IEEE802154_LONG_ADDRESS_LEN);
|
|
addr_ptr << m_dsme.getAddress();
|
|
*((be_uint64_t *)opt->data) = byteorder_ltobll(ext_addr);
|
|
res = IEEE802154_LONG_ADDRESS_LEN;
|
|
break;
|
|
}
|
|
case NETOPT_LINK:
|
|
assert(opt->data_len >= sizeof(netopt_enable_t));
|
|
*((netopt_enable_t *)opt->data) = m_dsme.isAssociated()
|
|
? NETOPT_ENABLE
|
|
: NETOPT_DISABLE;
|
|
return sizeof(netopt_enable_t);
|
|
default:
|
|
res = -ENOTSUP;
|
|
break;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static int _set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt)
|
|
{
|
|
int res;
|
|
|
|
switch (opt->opt) {
|
|
case NETOPT_LINK:
|
|
m_dsme.initialize(_pan_coord);
|
|
m_dsme.start();
|
|
assert(*(netopt_enable_t *)opt->data == NETOPT_ENABLE);
|
|
res = sizeof(netopt_enable_t);
|
|
break;
|
|
case NETOPT_PAN_COORD:
|
|
if (*((bool *)opt->data) == true) {
|
|
_pan_coord = true;
|
|
}
|
|
else {
|
|
_pan_coord = false;
|
|
}
|
|
res = sizeof(netopt_enable_t);
|
|
break;
|
|
#if IS_ACTIVE(CONFIG_IEEE802154_DSME_STATIC_GTS)
|
|
case NETOPT_GTS_ALLOC: {
|
|
ieee802154_dsme_alloc_t *alloc = (ieee802154_dsme_alloc_t *)opt->data;
|
|
uint16_t _addr = byteorder_ntohs(alloc->addr);
|
|
m_dsme.allocateGTS(alloc->superframe_id, alloc->slot_id, alloc->channel_id,
|
|
alloc->tx ? dsme::Direction::TX : dsme::Direction::RX, _addr);
|
|
res = sizeof(ieee802154_dsme_alloc_t);
|
|
break;
|
|
}
|
|
#endif
|
|
case NETOPT_PROTO:
|
|
assert(opt->data_len == sizeof(gnrc_nettype_t));
|
|
res = sizeof(gnrc_nettype_t);
|
|
break;
|
|
case NETOPT_GTS_TX:
|
|
assert(opt->data_len == sizeof(netopt_enable_t));
|
|
m_dsme.setGTSTransmission(*((netopt_enable_t *)opt->data) ? true : false);
|
|
res = sizeof(netopt_enable_t);
|
|
break;
|
|
case NETOPT_ACK_REQ:
|
|
assert(opt->data_len == sizeof(netopt_enable_t));
|
|
m_dsme.setAckReq(*((netopt_enable_t *)opt->data) ? true : false);
|
|
res = sizeof(netopt_enable_t);
|
|
break;
|
|
case NETOPT_SRC_LEN:
|
|
res = sizeof(uint16_t);
|
|
break;
|
|
default:
|
|
res = -ENOTSUP;
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static int _init(gnrc_netif_t *netif)
|
|
{
|
|
netif->flags = 0;
|
|
netif_register(&netif->netif);
|
|
return 0;
|
|
}
|
|
|
|
static const gnrc_netif_ops_t dsme_ops = {
|
|
.init = _init,
|
|
.send = _send,
|
|
.recv = _recv,
|
|
.get = _get,
|
|
.set = _set,
|
|
};
|
|
|
|
int gnrc_netif_opendsme_create(gnrc_netif_t *netif, char *stack, int stacksize,
|
|
char priority, const char *name, netdev_t *dev)
|
|
{
|
|
m_dsme.setGNRCNetif(netif);
|
|
return gnrc_netif_create(netif, stack, stacksize, priority, name, dev,
|
|
&dsme_ops);
|
|
}
|
|
}
|
|
|
|
/** @} */
|