forked from RIOT-OS/RIOT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgnrc_netif_cc1xxx.c
175 lines (148 loc) · 5.28 KB
/
gnrc_netif_cc1xxx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
* Copyright (C) 2016-17 Freie Universität Berlin
* 2018 Otto-von-Guericke-Universität Magdeburg
*
* 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.
*/
/**
* @ingroup net_gnrc_netif
* @{
*
* @file
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
*
* Adapted from @ref gnrc_xbee.c with only minor modifications. So all credit
* goes to Martine Lenders <m.lenders@fu-berlin.de> and to
* Hauke Petersen <hauke.petersen@fu-berlin.de>.
*
* @}
*/
#include "assert.h"
#include "net/gnrc.h"
#include "cc1xxx_common.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define BCAST (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)
static gnrc_pktsnip_t *cc1xxx_adpt_recv(gnrc_netif_t *netif)
{
netdev_t *dev = netif->dev;
cc1xxx_rx_info_t rx_info;
int pktlen;
gnrc_pktsnip_t *payload;
gnrc_pktsnip_t *hdr;
gnrc_netif_hdr_t *netif_hdr;
cc1xxx_l2hdr_t l2hdr;
assert(dev);
/* see how much data there is to process */
pktlen = dev->driver->recv(dev, NULL, 0, &rx_info);
if (pktlen <= 0) {
DEBUG("[cc1xxx-gnrc] recv: no data available to process\n");
return NULL;
}
/* allocate space for the packet in the pktbuf */
payload = gnrc_pktbuf_add(NULL, NULL, pktlen, CC1XXX_DEFAULT_PROTOCOL);
if (payload == NULL) {
DEBUG("[cc1xxx-gnrc] recv: unable to allocate space in the pktbuf\n");
/* tell the driver to drop the packet */
dev->driver->recv(dev, NULL, pktlen, NULL);
return NULL;
}
/* copy the complete including the CC1XXX header into the packet buffer */
dev->driver->recv(dev, payload->data, pktlen, NULL);
/* The first two bytes are the layer 2 header */
l2hdr.dest_addr = ((uint8_t *)payload->data)[0];
l2hdr.src_addr = ((uint8_t *)payload->data)[1];
/* crop the layer 2 header from the payload */
hdr = gnrc_pktbuf_mark(payload, sizeof(cc1xxx_l2hdr_t), GNRC_NETTYPE_UNDEF);
if (hdr == NULL) {
DEBUG("[cc1xxx-gnrc] recv: unable to mark cc1xxx header snip\n");
gnrc_pktbuf_release(payload);
return NULL;
}
gnrc_pktbuf_remove_snip(payload, hdr);
/* create a netif hdr from the obtained data */
hdr = gnrc_netif_hdr_build(&l2hdr.src_addr, CC1XXX_ADDR_SIZE,
&l2hdr.dest_addr, CC1XXX_ADDR_SIZE);
if (hdr == NULL) {
DEBUG("[cc1xxx-gnrc] recv: unable to allocate netif header\n");
gnrc_pktbuf_release(payload);
return NULL;
}
netif_hdr = (gnrc_netif_hdr_t *)hdr->data;
gnrc_netif_hdr_set_netif(netif_hdr, netif);
netif_hdr->rssi = rx_info.rssi;
netif_hdr->lqi = rx_info.lqi;
if (l2hdr.dest_addr == CC1XXX_BCAST_ADDR) {
netif_hdr->flags = GNRC_NETIF_HDR_FLAGS_BROADCAST;
}
DEBUG("[cc1xxx-gnrc] recv: successfully parsed packet\n");
/* and append the netif header */
LL_APPEND(payload, hdr);
#ifdef MODULE_NETSTATS_L2
netif->stats.rx_count++;
netif->stats.rx_bytes += pktlen;
#endif
return payload;
}
static int cc1xxx_adpt_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
int res;
size_t size;
cc1xxx_t *cc1xxx_dev = (cc1xxx_t *)netif->dev;
gnrc_netif_hdr_t *netif_hdr;
cc1xxx_l2hdr_t l2hdr;
/* check device descriptor and packet */
assert(netif && pkt);
/* get the payload size and the dst address details */
size = gnrc_pkt_len(pkt->next);
DEBUG("[cc1xxx-gnrc] send: payload of packet is %i\n", (int)size);
netif_hdr = (gnrc_netif_hdr_t *)pkt->data;
l2hdr.src_addr = cc1xxx_dev->addr;
if (netif_hdr->flags & BCAST) {
l2hdr.dest_addr = CC1XXX_BCAST_ADDR;
DEBUG("[cc1xxx-gnrc] send: preparing to send broadcast\n");
#ifdef MODULE_NETSTATS_L2
netif->stats.tx_mcast_count++;
#endif
}
else {
/* check that destination address is valid */
assert(netif_hdr->dst_l2addr_len > 0);
uint8_t *addr = gnrc_netif_hdr_get_dst_addr(netif_hdr);
l2hdr.dest_addr = addr[0];
DEBUG("[cc1xxx-gnrc] send: preparing to send unicast %02x --> %02x\n",
(int)l2hdr.src_addr, (int)l2hdr.dest_addr);
#ifdef MODULE_NETSTATS_L2
netif->stats.tx_unicast_count++;
#endif
}
/* now let's send out the stuff */
iolist_t iolist = {
.iol_next = (iolist_t *)pkt->next,
.iol_base = &l2hdr,
.iol_len = sizeof(l2hdr),
};
DEBUG("[cc1xxx-gnrc] send: triggering the drivers send function\n");
res = netif->dev->driver->send(netif->dev, &iolist);
gnrc_pktbuf_release(pkt);
return res;
}
static const gnrc_netif_ops_t cc1xxx_netif_ops = {
.init = gnrc_netif_default_init,
.send = cc1xxx_adpt_send,
.recv = cc1xxx_adpt_recv,
.get = gnrc_netif_get_from_netdev,
.set = gnrc_netif_set_from_netdev,
};
gnrc_netif_t *gnrc_netif_cc1xxx_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev)
{
return gnrc_netif_create(stack, stacksize, priority, name,
dev, &cc1xxx_netif_ops);
}