Skip to content

Commit 99a369f

Browse files
Martin Lendersmiri64
authored andcommitted
sys: net: Initial import of a basic MAC protocol layer
1 parent c7226e4 commit 99a369f

File tree

7 files changed

+357
-0
lines changed

7 files changed

+357
-0
lines changed

sys/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ endif
4646
ifneq (,$(filter net_if,$(USEMODULE)))
4747
DIRS += net/link_layer/net_if
4848
endif
49+
ifneq (,$(filter basic_mac,$(USEMODULE)))
50+
DIRS += net/link_layer/basic_mac
51+
endif
4952
ifneq (,$(filter destiny,$(USEMODULE)))
5053
DIRS += net/transport_layer/destiny
5154
endif

sys/Makefile.include

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
ifneq (,$(filter basic_mac,$(USEMODULE)))
2+
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
3+
endif
14
ifneq (,$(filter destiny,$(USEMODULE)))
25
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
36
endif

sys/auto_init/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@ ifneq (,$(filter net_if,$(USEMODULE)))
22
INCLUDES += -I$(RIOTBASE)/sys/net/include/
33
endif
44

5+
ifneq (,$(filter basic_mac,$(USEMODULE)))
6+
INCLUDES += -I$(RIOTBASE)/sys/net/include/
7+
endif
8+
59
include $(RIOTBASE)/Makefile.base

sys/auto_init/auto_init.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959
#include "destiny.h"
6060
#endif
6161

62+
#ifdef MODULE_BASIC_MAC
63+
#include "basic_mac.h"
64+
#endif
65+
6266
#ifdef MODULE_NET_IF
6367
#include "net_if.h"
6468
#include "transceiver.h"
@@ -112,6 +116,10 @@ void auto_init(void)
112116
DEBUG("Auto init mci module.\n");
113117
MCI_initialize();
114118
#endif
119+
#ifdef MODULE_BASIC_MAC
120+
DEBUG("Auto init basic_mac module.\n");
121+
basic_mac_init_module();
122+
#endif
115123
#ifdef MODULE_NET_IF
116124
int iface;
117125
DEBUG("Auto init net_if module.\n");

sys/net/include/basic_mac.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (C) 2014 Freie Universität Berlin
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser General
5+
* Public License. See the file LICENSE in the top level directory for more
6+
* details.
7+
*/
8+
9+
/**
10+
* @defgroup basic_mac Dummy MAC
11+
* @ingroup net
12+
* @brief Basic link layer protocol to speak with any transceiver driver
13+
* in some manner.
14+
* @{
15+
*
16+
* @file basic_mac.h
17+
* @brief Basic link layer protocol to speak with any transceiver driver
18+
* in some manner.
19+
*
20+
* @author Martine Lenders <[email protected]>
21+
*/
22+
23+
#ifndef __BASIC_MAC_H_
24+
#define __BASIC_MAC_H_
25+
26+
#include <stdlib.h>
27+
28+
#include "netdev/base.h"
29+
#include "netapi.h"
30+
31+
#ifndef BASIC_MAC_REGISTRY_SIZE
32+
/**
33+
* @brief The size of dummy MAC's recipant registry.
34+
*/
35+
#define BASIC_MAC_REGISTRY_SIZE (1)
36+
#endif
37+
38+
/**
39+
* @brief The minimal required stack size for a
40+
* dummy MAC thread
41+
* TODO: determine real minimal size based on variable used in C file
42+
*/
43+
#define BASIC_MAC_MINIMAL_STACK_SIZE (32)
44+
45+
/**
46+
* @brief Basic configuration types
47+
*
48+
* @extends netapi_conf_type_t
49+
*/
50+
typedef enum {
51+
BASIC_MAC_PROTO = NETAPI_CONF_PROTO, /**< Set or get protocol */
52+
BASIC_MAC_CHANNEL = NETAPI_CONF_CARRIER, /**< Set or get channel */
53+
BASIC_MAC_ADDRESS = NETAPI_CONF_ADDRESS, /**< Set or get address */
54+
BASIC_MAC_NID = NETAPI_CONF_SUBNETS, /**< Set or get network id
55+
(e.g. PAN ID in 802.15.4)*/
56+
BASIC_MAC_ADDRESS2 = NETDEV_OPT_ADDRESS_LONG, /**< Set or get alternative
57+
address format (e.g
58+
EUI-64 in 802.15.4) */
59+
} basic_mac_conf_type_t;
60+
61+
/**
62+
* @brief Initializes the module
63+
*/
64+
void basic_mac_init_module(void);
65+
66+
/**
67+
* @brief Initialize new dummy MAC layer.
68+
*
69+
* @param[in] stack Stack for the control thread
70+
* @param[in] stacksize Size of *stack*
71+
* @param[in] priority Priority for the control thread
72+
* @param[in] flags Flags for the control thread
73+
* @param[in] name Name for the control thread
74+
* @param[in] dev An *initialized* network device to use with this MAC
75+
* layer
76+
*
77+
* @see @ref thread_create
78+
*
79+
* @return PID of dummy MAC control thread on success
80+
* @return -EINVAL if priority is invalid
81+
* @return -EOVERFLOW if no slot for the new thread is available
82+
*/
83+
kernel_pid_t basic_mac_init(char *stack, int stacksize, char priority, int flags,
84+
const char *name, netdev_t *dev);
85+
86+
#endif /* __BASIC_MAC_H_ */

sys/net/link_layer/basic_mac/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include $(RIOTBASE)/Makefile.base
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/*
2+
* Copyright (C) 2014 Freie Universität Berlin
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser General
5+
* Public License. See the file LICENSE in the top level directory for more
6+
* details.
7+
*/
8+
#include <errno.h>
9+
#include <string.h>
10+
11+
#include "netapi.h"
12+
#include "msg.h"
13+
#include "netdev/base.h"
14+
#include "thread.h"
15+
16+
#include "basic_mac.h"
17+
18+
#define ENABLE_DEBUG (0)
19+
#if ENABLE_DEBUG
20+
#define DEBUG_ENABLED
21+
#endif
22+
#include "debug.h"
23+
24+
#define BASIC_MAC_MSG_QUEUE_SIZE (16)
25+
26+
static struct {
27+
kernel_pid_t registrar_pid;
28+
kernel_pid_t recipant_pid;
29+
} _basic_mac_registry[BASIC_MAC_REGISTRY_SIZE];
30+
31+
static int _basic_mac_recv_cb(netdev_t *dev, void *src, size_t src_len,
32+
void *dest, size_t dest_len, void *payload,
33+
size_t payload_len)
34+
{
35+
(void)dev;
36+
kernel_pid_t current_pid = thread_getpid();
37+
size_t offset;
38+
netapi_rcv_pkt_t packet;
39+
netapi_ack_t ack_mem;
40+
msg_t msg_pkt, msg_ack;
41+
42+
packet.type = NETAPI_CMD_RCV;
43+
packet.ack = &ack_mem;
44+
packet.src = src;
45+
packet.src_len = src_len;
46+
packet.dest = dest;
47+
packet.dest_len = dest_len;
48+
msg_pkt.type = NETAPI_MSG_TYPE;
49+
msg_pkt.content.ptr = (char *)(&packet);
50+
51+
for (int i = 0; i < BASIC_MAC_REGISTRY_SIZE; i++) {
52+
if (_basic_mac_registry[i].registrar_pid == current_pid) {
53+
netapi_ack_t *ack;
54+
offset = 0;
55+
56+
while (offset < payload_len) {
57+
packet.data = (void *)(((char *)payload) + offset);
58+
packet.data_len = payload_len - offset;
59+
60+
msg_send_receive(&msg_pkt, &msg_ack,
61+
_basic_mac_registry[i].recipant_pid);
62+
ack = (netapi_ack_t *)(msg_ack.content.ptr);
63+
64+
if (msg_ack.type == NETAPI_MSG_TYPE &&
65+
ack->type == NETAPI_CMD_ACK &&
66+
ack->orig == NETAPI_CMD_RCV) {
67+
if (ack->result > 0) {
68+
offset += (ack->result);
69+
}
70+
else {
71+
DEBUG("Error code received for registrar \"%s\" with "
72+
"recipant \"%s\": %d",
73+
thread_getname(_basic_mac_registry[i].registrar_pid),
74+
thread_getname(_basic_mac_registry[i].recipant_pid),
75+
-ack->result);
76+
77+
return ack->result;
78+
}
79+
}
80+
else {
81+
DEBUG("Unexpected msg instead of ACK. Abort for registrar "
82+
"\"%s\" with recipant \"%s\": msg.type = %d, "
83+
84+
"ack->type = %d, ack->orig = %d",
85+
thread_getname(_basic_mac_registry[i].registrar_pid),
86+
thread_getname(_basic_mac_registry[i].recipant_pid),
87+
msg_ack->type, ack->type, ack->orig);
88+
89+
return -ENOMSG;
90+
}
91+
92+
}
93+
}
94+
}
95+
96+
return payload_len;
97+
}
98+
99+
static inline int _basic_mac_send(netdev_t *dev, netapi_snd_pkt_t *pkt)
100+
{
101+
return dev->driver->send_data(dev, pkt->dest, pkt->dest_len, pkt->ulh,
102+
pkt->data, pkt->data_len);
103+
}
104+
105+
static int _basic_mac_get_option(netdev_t *dev, netapi_conf_t *conf)
106+
{
107+
int res;
108+
109+
switch ((basic_mac_conf_type_t)conf->param) {
110+
case BASIC_MAC_PROTO:
111+
case BASIC_MAC_CHANNEL:
112+
case BASIC_MAC_ADDRESS:
113+
case BASIC_MAC_NID:
114+
case BASIC_MAC_ADDRESS2:
115+
if ((res = dev->driver->get_option(dev, (netdev_opt_t)conf->param, conf->data,
116+
&(conf->data_len))) == 0) {
117+
return (int)conf->data_len;
118+
}
119+
else {
120+
return res;
121+
}
122+
123+
default:
124+
break;
125+
}
126+
127+
return -ENOTSUP;
128+
}
129+
130+
static int _basic_mac_set_option(netdev_t *dev, netapi_conf_t *conf)
131+
{
132+
switch ((basic_mac_conf_type_t)(conf->param)) {
133+
case BASIC_MAC_PROTO:
134+
case BASIC_MAC_CHANNEL:
135+
case BASIC_MAC_ADDRESS:
136+
case BASIC_MAC_NID:
137+
case BASIC_MAC_ADDRESS2:
138+
return dev->driver->set_option(dev, (netdev_opt_t)conf->param,
139+
conf->data, conf->data_len);
140+
141+
default:
142+
break;
143+
}
144+
145+
return -ENOTSUP;
146+
}
147+
148+
static void *_basic_mac_runner(void *args)
149+
{
150+
netdev_t *dev = (netdev_t *)args;
151+
msg_t msg_cmd, msg_ack, msg_queue[BASIC_MAC_MSG_QUEUE_SIZE];
152+
153+
netapi_cmd_t *cmd;
154+
netapi_ack_t *ack;
155+
156+
msg_ack.type = NETAPI_MSG_TYPE;
157+
158+
msg_init_queue(msg_queue, BASIC_MAC_MSG_QUEUE_SIZE);
159+
160+
while (1) {
161+
msg_receive(&msg_cmd);
162+
163+
if (msg_cmd.type == NETDEV_MSG_EVENT_TYPE) {
164+
dev->driver->event(dev, msg_cmd.content.value);
165+
}
166+
else if (msg_cmd.type == NETAPI_MSG_TYPE) {
167+
cmd = (netapi_cmd_t *)(msg_cmd.content.ptr);
168+
ack = cmd->ack;
169+
msg_ack.content.ptr = (char *)ack;
170+
171+
switch (cmd->type) {
172+
case NETAPI_CMD_SND:
173+
ack->result = _basic_mac_send(dev, (netapi_snd_pkt_t *)cmd);
174+
175+
break;
176+
177+
case NETAPI_CMD_GET:
178+
ack->result = _basic_mac_get_option(dev,
179+
(netapi_conf_t *)cmd);
180+
break;
181+
182+
case NETAPI_CMD_SET:
183+
ack->result = _basic_mac_set_option(dev,
184+
(netapi_conf_t *)cmd);
185+
break;
186+
187+
case NETAPI_CMD_REG:
188+
do {
189+
netapi_reg_t *reg = (netapi_reg_t *)cmd;
190+
ack->result = -ENOBUFS;
191+
192+
for (int i = 0; i < BASIC_MAC_REGISTRY_SIZE; i++) {
193+
if (_basic_mac_registry[i].registrar_pid == KERNEL_PID_UNDEF) {
194+
_basic_mac_registry[i].registrar_pid = thread_getpid();
195+
_basic_mac_registry[i].recipant_pid = reg->reg_pid;
196+
ack->result = NETAPI_STATUS_OK;
197+
break;
198+
}
199+
200+
}
201+
} while (0);
202+
203+
break;
204+
205+
case NETAPI_CMD_UNREG:
206+
do {
207+
netapi_reg_t *reg = (netapi_reg_t *)cmd;
208+
ack->result = NETAPI_STATUS_OK;
209+
210+
for (int i = 0; i < BASIC_MAC_REGISTRY_SIZE; i++) {
211+
if (_basic_mac_registry[i].registrar_pid == thread_getpid() &&
212+
_basic_mac_registry[i].recipant_pid == reg->reg_pid) {
213+
_basic_mac_registry[i].recipant_pid = KERNEL_PID_UNDEF;
214+
break;
215+
}
216+
217+
}
218+
} while (0);
219+
220+
break;
221+
222+
default:
223+
ack->result = -ENOTSUP;
224+
break;
225+
}
226+
227+
ack->type = NETAPI_CMD_ACK;
228+
ack->orig = cmd->type;
229+
msg_reply(&msg_cmd, &msg_ack);
230+
}
231+
}
232+
233+
/* never reached */
234+
return NULL;
235+
}
236+
237+
void basic_mac_init_module(void)
238+
{
239+
for (int i = 0; i < BASIC_MAC_REGISTRY_SIZE; i++) {
240+
_basic_mac_registry[i].registrar_pid = KERNEL_PID_UNDEF;
241+
_basic_mac_registry[i].recipant_pid = KERNEL_PID_UNDEF;
242+
}
243+
}
244+
245+
kernel_pid_t basic_mac_init(char *stack, int stacksize, char priority, int flags,
246+
const char *name, netdev_t *dev)
247+
{
248+
dev->driver->add_receive_data_callback(dev, _basic_mac_recv_cb);
249+
250+
return thread_create(stack, stacksize, priority, flags, _basic_mac_runner,
251+
(void *)dev, name);
252+
}

0 commit comments

Comments
 (0)