mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge #16158
16158: gnrc_sixlowpan_frag_sfr_congure_sfr: initial import r=miri64 a=miri64 Co-authored-by: Martine Lenders <m.lenders@fu-berlin.de>
This commit is contained in:
commit
04ef37274f
@ -236,6 +236,12 @@ PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_stats
|
|||||||
## @{
|
## @{
|
||||||
##
|
##
|
||||||
PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_congure
|
PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_congure
|
||||||
|
## @defgroup net_gnrc_sixlowpan_frag_sfr_congure_sfr gnrc_sixlowpan_frag_sfr_congure_sfr: Appendix C
|
||||||
|
## @brief Basic congestion control for 6LoWPAN SFR as proposed in Appendix C of RFC 8931
|
||||||
|
## @see [RFC 8931, Appendix C](https://tools.ietf.org/html/rfc8931#section-appendix.c)
|
||||||
|
## @{
|
||||||
|
PSEUDOMODULES += gnrc_sixlowpan_frag_sfr_congure_sfr
|
||||||
|
## @}
|
||||||
## @}
|
## @}
|
||||||
PSEUDOMODULES += gnrc_sixlowpan_iphc_nhc
|
PSEUDOMODULES += gnrc_sixlowpan_iphc_nhc
|
||||||
PSEUDOMODULES += gnrc_sixlowpan_nd_border_router
|
PSEUDOMODULES += gnrc_sixlowpan_nd_border_router
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* When included, this module enables congestion control for 6LoWPAN Selective Fragment Recovery
|
* When included, this module enables congestion control for 6LoWPAN Selective Fragment Recovery
|
||||||
* (SFR). The flavor of congestion control can be selected using the following sub-modules:
|
* (SFR). The flavor of congestion control can be selected using the following sub-modules:
|
||||||
*
|
*
|
||||||
* - TBD
|
* - @ref net_gnrc_sixlowpan_frag_sfr_congure_sfr (the default)
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
|
@ -246,6 +246,10 @@ endif
|
|||||||
|
|
||||||
ifneq (,$(filter gnrc_sixlowpan_frag_sfr_congure,$(USEMODULE)))
|
ifneq (,$(filter gnrc_sixlowpan_frag_sfr_congure,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_sixlowpan_frag_sfr
|
USEMODULE += gnrc_sixlowpan_frag_sfr
|
||||||
|
ifeq (,$(filter gnrc_sixlowpan_frag_sfr_congure_% congure_mock,$(USEMODULE)))
|
||||||
|
# pick Appendix C as default congestion control
|
||||||
|
USEMODULE += gnrc_sixlowpan_frag_sfr_congure_sfr
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_sixlowpan_frag_sfr_ecn_%,$(USEMODULE)))
|
ifneq (,$(filter gnrc_sixlowpan_frag_sfr_ecn_%,$(USEMODULE)))
|
||||||
|
115
sys/net/gnrc/network_layer/sixlowpan/frag/sfr/congure_sfr.c
Normal file
115
sys/net/gnrc/network_layer/sixlowpan/frag/sfr/congure_sfr.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Freie Universität Berlin
|
||||||
|
*
|
||||||
|
* 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 Martine Lenders <m.lenders@fu-berlin.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kernel_defines.h"
|
||||||
|
#include "congure.h"
|
||||||
|
#include "net/gnrc/sixlowpan/config.h"
|
||||||
|
|
||||||
|
#include "net/gnrc/sixlowpan/frag/sfr/congure.h"
|
||||||
|
|
||||||
|
/* This implements a very simple SFR as suggested in
|
||||||
|
* https://datatracker.ietf.org/doc/html/rfc8931#appendix-C */
|
||||||
|
|
||||||
|
typedef congure_snd_t congure_sfr_snd_t;
|
||||||
|
|
||||||
|
static void _snd_init(congure_snd_t *cong, void *ctx);
|
||||||
|
static int32_t _snd_inter_msg_interval(congure_snd_t *cong, unsigned msg_size);
|
||||||
|
static void _snd_report_msg_sent(congure_snd_t *cong, unsigned sent_size);
|
||||||
|
static void _snd_report_msg_discarded(congure_snd_t *cong, unsigned msg_size);
|
||||||
|
static void _snd_report_msgs_lost(congure_snd_t *cong, congure_snd_msg_t *msgs);
|
||||||
|
static void _snd_report_msgs_timeout(congure_snd_t *cong, congure_snd_msg_t *msgs);
|
||||||
|
static void _snd_report_msg_acked(congure_snd_t *cong, congure_snd_msg_t *msg,
|
||||||
|
congure_snd_ack_t *ack);
|
||||||
|
static void _snd_report_ecn_ce(congure_snd_t *cong, ztimer_now_t time);
|
||||||
|
|
||||||
|
static congure_sfr_snd_t _sfr_congures_sfr[CONFIG_GNRC_SIXLOWPAN_FRAG_FB_SIZE];
|
||||||
|
static const congure_snd_driver_t _driver = {
|
||||||
|
.init = _snd_init,
|
||||||
|
.inter_msg_interval = _snd_inter_msg_interval,
|
||||||
|
.report_msg_sent = _snd_report_msg_sent,
|
||||||
|
.report_msg_discarded = _snd_report_msg_discarded,
|
||||||
|
.report_msgs_timeout = _snd_report_msgs_timeout,
|
||||||
|
.report_msgs_lost = _snd_report_msgs_lost,
|
||||||
|
.report_msg_acked = _snd_report_msg_acked,
|
||||||
|
.report_ecn_ce = _snd_report_ecn_ce,
|
||||||
|
};
|
||||||
|
|
||||||
|
congure_snd_t *gnrc_sixlowpan_frag_sfr_congure_snd_get(void)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < ARRAY_SIZE(_sfr_congures_sfr); i++) {
|
||||||
|
if (_sfr_congures_sfr[i].driver == NULL) {
|
||||||
|
_sfr_congures_sfr[i].driver = &_driver;
|
||||||
|
return &_sfr_congures_sfr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _snd_init(congure_snd_t *cong, void *ctx)
|
||||||
|
{
|
||||||
|
(void)ctx;
|
||||||
|
cong->cwnd = CONFIG_GNRC_SIXLOWPAN_SFR_OPT_WIN_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t _snd_inter_msg_interval(congure_snd_t *cong, unsigned msg_size)
|
||||||
|
{
|
||||||
|
(void)cong;
|
||||||
|
(void)msg_size;
|
||||||
|
return CONFIG_GNRC_SIXLOWPAN_SFR_INTER_FRAME_GAP_US;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _snd_report_msg_sent(congure_snd_t *cong, unsigned sent_size)
|
||||||
|
{
|
||||||
|
(void)cong;
|
||||||
|
(void)sent_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _snd_report_msg_discarded(congure_snd_t *cong, unsigned msg_size)
|
||||||
|
{
|
||||||
|
(void)cong;
|
||||||
|
(void)msg_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _snd_report_msgs_lost(congure_snd_t *cong, congure_snd_msg_t *msgs)
|
||||||
|
{
|
||||||
|
/* Appendix C defines loss as timeout, so this does nothing */
|
||||||
|
(void)cong;
|
||||||
|
(void)msgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _snd_report_msgs_timeout(congure_snd_t *cong,
|
||||||
|
congure_snd_msg_t *msgs)
|
||||||
|
{
|
||||||
|
(void)msgs;
|
||||||
|
if (cong->cwnd > 1U) {
|
||||||
|
cong->cwnd /= 2U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _snd_report_msg_acked(congure_snd_t *cong, congure_snd_msg_t *msg,
|
||||||
|
congure_snd_ack_t *ack)
|
||||||
|
{
|
||||||
|
(void)cong;
|
||||||
|
(void)msg;
|
||||||
|
(void)ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _snd_report_ecn_ce(congure_snd_t *cong, ztimer_now_t time)
|
||||||
|
{
|
||||||
|
(void)time;
|
||||||
|
if (cong->cwnd > 1U) {
|
||||||
|
cong->cwnd--;
|
||||||
|
}
|
||||||
|
}
|
49
tests/gnrc_sixlowpan_frag_sfr_congure_impl/Makefile
Normal file
49
tests/gnrc_sixlowpan_frag_sfr_congure_impl/Makefile
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
USEMODULE += auto_init_gnrc_netif
|
||||||
|
USEMODULE += gnrc_ipv6_router_default
|
||||||
|
USEMODULE += gnrc_sixlowpan_frag_sfr
|
||||||
|
USEMODULE += gnrc_udp
|
||||||
|
USEMODULE += gnrc_rpl
|
||||||
|
USEMODULE += auto_init_gnrc_rpl
|
||||||
|
USEMODULE += gnrc_pktdump
|
||||||
|
USEMODULE += gnrc_icmpv6_echo
|
||||||
|
USEMODULE += shell
|
||||||
|
USEMODULE += shell_cmds_default
|
||||||
|
USEMODULE += shell_cmd_gnrc_pktbuf
|
||||||
|
USEMODULE += shell_cmd_gnrc_udp
|
||||||
|
USEMODULE += ps
|
||||||
|
USEMODULE += netstats_l2
|
||||||
|
USEMODULE += netstats_ipv6
|
||||||
|
USEMODULE += netstats_rpl
|
||||||
|
|
||||||
|
ifeq (native, $(BOARD))
|
||||||
|
USEMODULE += socket_zep
|
||||||
|
USEMODULE += socket_zep_hello
|
||||||
|
USEMODULE += netdev
|
||||||
|
TERMFLAGS = -z 127.0.0.1:17754 # Murdock has no IPv6 support
|
||||||
|
else
|
||||||
|
USEMODULE += netdev_default
|
||||||
|
# automated test only works on native
|
||||||
|
TESTS=
|
||||||
|
endif
|
||||||
|
|
||||||
|
CONGURE_IMPL ?= congure_sfr
|
||||||
|
|
||||||
|
ifeq (congure_sfr,$(CONGURE_IMPL))
|
||||||
|
USEMODULE += gnrc_sixlowpan_frag_sfr_congure_sfr
|
||||||
|
else
|
||||||
|
$(error "Unknown CongURE implementation `$(CONGURE_IMPL)`")
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: zep_dispatch
|
||||||
|
|
||||||
|
zep_dispatch:
|
||||||
|
$(Q)env -u CC -u CFLAGS $(MAKE) -C $(RIOTTOOLS) $@
|
||||||
|
|
||||||
|
TERMDEPS += zep_dispatch
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
|
|
||||||
|
# Set a custom channel if needed
|
||||||
|
include $(RIOTMAKE)/default-radio-settings.inc.mk
|
57
tests/gnrc_sixlowpan_frag_sfr_congure_impl/Makefile.ci
Normal file
57
tests/gnrc_sixlowpan_frag_sfr_congure_impl/Makefile.ci
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
BOARD_INSUFFICIENT_MEMORY := \
|
||||||
|
airfy-beacon \
|
||||||
|
arduino-duemilanove \
|
||||||
|
arduino-leonardo \
|
||||||
|
arduino-mega2560 \
|
||||||
|
arduino-nano \
|
||||||
|
arduino-uno \
|
||||||
|
atmega328p \
|
||||||
|
atmega328p-xplained-mini \
|
||||||
|
atxmega-a3bu-xplained \
|
||||||
|
b-l072z-lrwan1 \
|
||||||
|
blackpill-stm32f103c8 \
|
||||||
|
blackpill-stm32f103cb \
|
||||||
|
bluepill-stm32f030c8 \
|
||||||
|
bluepill-stm32f103c8 \
|
||||||
|
bluepill-stm32f103cb \
|
||||||
|
calliope-mini \
|
||||||
|
derfmega128 \
|
||||||
|
hifive1 \
|
||||||
|
hifive1b \
|
||||||
|
i-nucleo-lrwan1 \
|
||||||
|
im880b \
|
||||||
|
lsn50 \
|
||||||
|
microbit \
|
||||||
|
microduino-corerf \
|
||||||
|
msb-430 \
|
||||||
|
msb-430h \
|
||||||
|
nrf51dongle \
|
||||||
|
nrf6310 \
|
||||||
|
nucleo-f030r8 \
|
||||||
|
nucleo-f031k6 \
|
||||||
|
nucleo-f042k6 \
|
||||||
|
nucleo-f070rb \
|
||||||
|
nucleo-f072rb \
|
||||||
|
nucleo-f302r8 \
|
||||||
|
nucleo-f303k8 \
|
||||||
|
nucleo-f334r8 \
|
||||||
|
nucleo-l011k4 \
|
||||||
|
nucleo-l031k6 \
|
||||||
|
nucleo-l053r8 \
|
||||||
|
samd10-xmini \
|
||||||
|
saml10-xpro \
|
||||||
|
saml11-xpro \
|
||||||
|
slstk3400a \
|
||||||
|
stk3200 \
|
||||||
|
stm32f030f4-demo \
|
||||||
|
stm32f0discovery \
|
||||||
|
stm32f7508-dk \
|
||||||
|
stm32g0316-disco \
|
||||||
|
stm32l0538-disco \
|
||||||
|
stm32mp157c-dk2 \
|
||||||
|
telosb \
|
||||||
|
waspmote-pro \
|
||||||
|
yunjia-nrf51822 \
|
||||||
|
z1 \
|
||||||
|
zigduino \
|
||||||
|
#
|
8
tests/gnrc_sixlowpan_frag_sfr_congure_impl/README.md
Normal file
8
tests/gnrc_sixlowpan_frag_sfr_congure_impl/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
SFR CongURE implementation test
|
||||||
|
===============================
|
||||||
|
This test is largely based on the [`gnrc_networking`][1] example but is changed
|
||||||
|
so SFR with different CongURE implementations can be tested. When `CONGURE_IMPL`
|
||||||
|
is not set in the environment, `gnrc_sixlowpan_frag_sfr_congure_sfr` is used,
|
||||||
|
other implementations can be used with `congure_<impl>`.
|
||||||
|
|
||||||
|
[1]: https://github.com/RIOT-OS/RIOT/tree/master/examples/gnrc_networking
|
39
tests/gnrc_sixlowpan_frag_sfr_congure_impl/main.c
Normal file
39
tests/gnrc_sixlowpan_frag_sfr_congure_impl/main.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015-21 Freie Universität Berlin
|
||||||
|
*
|
||||||
|
* 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 tests
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||||
|
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "fmt.h"
|
||||||
|
#include "shell.h"
|
||||||
|
#include "msg.h"
|
||||||
|
|
||||||
|
#define MAIN_QUEUE_SIZE (8)
|
||||||
|
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
|
||||||
|
|
||||||
|
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||||
|
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||||
|
|
||||||
|
/* should be never reached */
|
||||||
|
return 0;
|
||||||
|
}
|
154
tests/gnrc_sixlowpan_frag_sfr_congure_impl/tests/01-run.py
Executable file
154
tests/gnrc_sixlowpan_frag_sfr_congure_impl/tests/01-run.py
Executable file
@ -0,0 +1,154 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (C) 2021 Benjamin Valentin
|
||||||
|
# Copyright (C) 2023 Freie Universität Berlin
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
from subprocess import Popen
|
||||||
|
from riotctrl_shell.gnrc import GNRCICMPv6Echo, GNRCICMPv6EchoParser, GNRCIPv6NIB
|
||||||
|
from riotctrl_shell.netif import Ifconfig
|
||||||
|
from riotctrl.ctrl import RIOTCtrlBoardFactory
|
||||||
|
from riotctrl_ctrl import native
|
||||||
|
from riotctrl_shell.netif import IfconfigListParser
|
||||||
|
|
||||||
|
PARSERS = {
|
||||||
|
"ping6": GNRCICMPv6EchoParser(),
|
||||||
|
"ifconfig": IfconfigListParser(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RIOTCtrlAppFactory(RIOTCtrlBoardFactory):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(board_cls={
|
||||||
|
'native': native.NativeRIOTCtrl,
|
||||||
|
})
|
||||||
|
self.ctrl_list = list()
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *exc):
|
||||||
|
for ctrl in self.ctrl_list:
|
||||||
|
ctrl.stop_term()
|
||||||
|
|
||||||
|
def get_shell(self, application_directory='.', env={'BOARD': 'native'}):
|
||||||
|
# retrieve a RIOTCtrl Object
|
||||||
|
ctrl = super().get_ctrl(
|
||||||
|
env=env,
|
||||||
|
application_directory=application_directory
|
||||||
|
)
|
||||||
|
# append ctrl to list
|
||||||
|
self.ctrl_list.append(ctrl)
|
||||||
|
# start terminal
|
||||||
|
ctrl.start_term()
|
||||||
|
ctrl.term.logfile = sys.stdout
|
||||||
|
# return ctrl with started terminal
|
||||||
|
return Shell(ctrl)
|
||||||
|
|
||||||
|
def get_shells(self, num=1):
|
||||||
|
terms = []
|
||||||
|
for i in range(num):
|
||||||
|
terms.append(self.get_shell())
|
||||||
|
return terms
|
||||||
|
|
||||||
|
|
||||||
|
class Shell(Ifconfig, GNRCICMPv6Echo, GNRCIPv6NIB):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def first_netif_and_addr_by_scope(ifconfig_out, scope):
|
||||||
|
netifs = PARSERS["ifconfig"].parse(ifconfig_out)
|
||||||
|
key = next(iter(netifs))
|
||||||
|
netif = netifs[key]
|
||||||
|
return (
|
||||||
|
key,
|
||||||
|
[addr["addr"] for addr in netif["ipv6_addrs"] if addr["scope"] == scope][0],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def global_addr(ifconfig_out):
|
||||||
|
return first_netif_and_addr_by_scope(ifconfig_out, "global")
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def rpl_nodes(factory, zep_dispatch):
|
||||||
|
# linear topology with 4 nodes
|
||||||
|
topology = ("A B\n"
|
||||||
|
"B C\n"
|
||||||
|
"C D\n")
|
||||||
|
zep_dispatch.stdin.write(topology.encode())
|
||||||
|
zep_dispatch.stdin.close()
|
||||||
|
|
||||||
|
# create native instances
|
||||||
|
nodes = factory.get_shells(4)
|
||||||
|
A, _, _, D = nodes
|
||||||
|
|
||||||
|
netifs = PARSERS["ifconfig"].parse(A.ifconfig_list())
|
||||||
|
iface = next(iter(netifs))
|
||||||
|
# add prefix to root node
|
||||||
|
A.nib_prefix_add(iface, "2001:db8::/64")
|
||||||
|
A.ifconfig_add(iface, "2001:db8::1/64")
|
||||||
|
A.cmd("rpl root 0 2001:db8::1")
|
||||||
|
root_addr = global_addr(A.ifconfig_list())[1]
|
||||||
|
|
||||||
|
# wait for the creation of the DODAG
|
||||||
|
time.sleep(10)
|
||||||
|
yield root_addr, D
|
||||||
|
for node in nodes:
|
||||||
|
node.stop_term()
|
||||||
|
|
||||||
|
|
||||||
|
def assert_result(result, exp_packet_loss, exp_responses, exp_ttl):
|
||||||
|
assert result['stats']['packet_loss'] < exp_packet_loss
|
||||||
|
assert result['stats']['rx'] >= exp_responses
|
||||||
|
assert result['replies'][0]['ttl'] == exp_ttl
|
||||||
|
|
||||||
|
|
||||||
|
def test_fragmentation(factory, zep_dispatch):
|
||||||
|
with rpl_nodes(factory, zep_dispatch) as (root_addr, D):
|
||||||
|
# ping root node from last node
|
||||||
|
parser = PARSERS["ping6"]
|
||||||
|
# test reachability
|
||||||
|
result = parser.parse(D.ping6(root_addr))
|
||||||
|
# assert packetloss is under 34% (1 packet may get lost)
|
||||||
|
# assert at least one response
|
||||||
|
# 2 intermediate hops, 64 - 2
|
||||||
|
assert_result(result, 34, 1, 64 - 2)
|
||||||
|
|
||||||
|
result = parser.parse(D.ping6(root_addr, count=100, interval=30, packet_size=500))
|
||||||
|
# assert packetloss is under 90%
|
||||||
|
# assert at least one response
|
||||||
|
# 2 intermediate hops, 64 - 2
|
||||||
|
assert_result(result, 90, 1, 64 - 2)
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def run_zep_dispatch():
|
||||||
|
zep_dispatch = Popen(
|
||||||
|
[
|
||||||
|
'../../dist/tools/zep_dispatch/bin/zep_dispatch',
|
||||||
|
'-t',
|
||||||
|
'-',
|
||||||
|
'127.0.0.1',
|
||||||
|
'17754'
|
||||||
|
],
|
||||||
|
stdin=subprocess.PIPE
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
yield zep_dispatch
|
||||||
|
finally:
|
||||||
|
zep_dispatch.terminate()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
with RIOTCtrlAppFactory() as factory, run_zep_dispatch() as zep_dispatch:
|
||||||
|
test_fragmentation(factory, zep_dispatch)
|
Loading…
Reference in New Issue
Block a user