Network: L2: remove IPSP
Remove IPSP support from the tree. It has no maintainers, and is regularly broken. The fact that it's nontrivial to set-up in linux makes it hard to fix reported issues. Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
This commit is contained in:
parent
5997815352
commit
e3ff993000
54 changed files with 20 additions and 2046 deletions
|
@ -1,9 +0,0 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(ipsp)
|
||||
|
||||
target_sources(app PRIVATE
|
||||
src/main.c
|
||||
)
|
|
@ -1,216 +0,0 @@
|
|||
.. _bluetooth-ipsp-sample:
|
||||
|
||||
Bluetooth: IPSP Sample
|
||||
######################
|
||||
|
||||
Overview
|
||||
********
|
||||
Application demonstrating the IPSP (Internet Protocol Support Profile) Node
|
||||
role. IPSP is the Bluetooth profile that underneath utilizes 6LoWPAN, i.e. gives
|
||||
you IPv6 connectivity over BLE.
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
This sample can be found under :zephyr_file:`samples/bluetooth/ipsp` in the
|
||||
Zephyr tree.
|
||||
Sample can be built and executed for the nRF52840 DK NRF52840 as follows:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/bluetooth/ipsp
|
||||
:board: nrf52840dk/nrf52840
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
To build a debug version, with logging and shell support, use the config file
|
||||
:file:`prj_dbg.conf`:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/bluetooth/ipsp
|
||||
:board: nrf52840dk/nrf52840
|
||||
:conf: prj_dbg.conf
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
Building and Running for Linux kernels released before 4.12
|
||||
===========================================================
|
||||
.. note::
|
||||
|
||||
For hosts using kernels released before 4.12,
|
||||
option :kconfig:option:`CONFIG_NET_L2_BT_ZEP1656`
|
||||
must be selected. For more information, see :github:`Zephyr issue #3111
|
||||
<3111>`.
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/bluetooth/ipsp
|
||||
:board: nrf52840dk/nrf52840
|
||||
:conf: "prj_zep1656.conf"
|
||||
:goals: build flash
|
||||
:compact:
|
||||
|
||||
Testing with a Linux host
|
||||
=========================
|
||||
|
||||
Make sure the Linux kernel has been built with Bluetooth 6LoWPAN module
|
||||
(CONFIG_BT_6LOWPAN=y) then proceed to enable it with with the following commands
|
||||
(as root):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# modprobe bluetooth_6lowpan
|
||||
# echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable
|
||||
|
||||
If you connected your board to a UART console, you will see an output similar to
|
||||
(may vary slightly by application and Zephyr versions):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
[bt] [WRN] set_static_addr: Using temporary static random address
|
||||
[bt] [INF] show_dev_info: Identity: cb:af:14:57:d8:6e (random)
|
||||
[bt] [INF] show_dev_info: HCI: version 5.0 (0x09) revision 0x0000, manufacturer 0xffff
|
||||
[bt] [INF] show_dev_info: LMP: version 5.0 (0x09) subver 0xffff
|
||||
[bt] [WRN] bt_pub_key_gen: ECC HCI commands not available
|
||||
[ipsp] [INF] init_app: Run IPSP sample
|
||||
[ipsp] [INF] listen: Starting to wait
|
||||
|
||||
The output above shows the BLE address assigned to your board for the
|
||||
current session; the address will be different on subsequent sessions.
|
||||
|
||||
Alternatively, you may scan for your board on the host. The modern way to do
|
||||
that is using ``bluetoothctl`` utility (included in the recent versions of
|
||||
BlueZ package) and its ``scan on`` command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ bluetoothctl
|
||||
[NEW] Controller A3:24:97:EB:D6:23 ubuntu-0 [default]
|
||||
[NEW] Device D7:5C:D6:18:14:87 Zephyr
|
||||
[NEW] Device E1:E7:F9:56:EC:06 Zephyr
|
||||
[NEW] Device C8:12:C5:08:86:E1 Zephyr
|
||||
[bluetooth]# scan on
|
||||
Discovery started
|
||||
[NEW] Device DC:98:FB:22:CA:3A Zephyr
|
||||
|
||||
When started, ``bluetoothctl`` shows all BLE (and likely, BT/EDR) devices it
|
||||
knows about. As discussed above, the IPSP uses static random addresses, so
|
||||
entries for previously connected devices, as shown above, can accumulate and
|
||||
become stale. You need to be extra careful to find an entry for the active
|
||||
address. The best approach may be to reset your board after issuing
|
||||
``scan on`` command. This way it will reinitialize with the BLE address
|
||||
which will be discovered after the command.
|
||||
|
||||
As an alternative to ``bluetoothctl``, you can use the legacy ``hcitool``
|
||||
utility which talks directly to hardware and always shows fresh scan results:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo hcitool lescan
|
||||
LE Scan ...
|
||||
CB:AF:14:57:D8:6E (unknown)
|
||||
CB:AF:14:57:D8:6E Test IPSP node
|
||||
|
||||
After you have found the board's BLE address, connect to the board (as root):
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# echo "connect <bdaddr> <type>" > /sys/kernel/debug/bluetooth/6lowpan_control
|
||||
|
||||
Where ``<bdaddr>`` is the BLE address and ``<type>`` is BLE address type:
|
||||
1 for public address and 2 for random address. As you can see from
|
||||
the IPSP sample output above, it uses a static random address. So, with the
|
||||
sample output above, the command will be:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# echo "connect CB:AF:14:57:D8:6E 2" > /sys/kernel/debug/bluetooth/6lowpan_control
|
||||
|
||||
Once connected a dedicated interface will be created, usually bt0. You can verify this
|
||||
with the following command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# ifconfig
|
||||
bt0 Link encap:UNSPEC HWaddr F8-2F-A8-FF-FE-EB-6D-8C-00-00-00-00-00-00-00-00
|
||||
inet6 addr: fe80::fa2f:a8ff:feeb:6d8c/64 Scope:Link
|
||||
UP POINTOPOINT RUNNING MULTICAST MTU:1280 Metric:1
|
||||
RX packets:2 errors:0 dropped:3 overruns:0 frame:0
|
||||
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:92 (92.0 B) TX bytes:233 (233.0 B)
|
||||
|
||||
As can be seen from the output, only a link-local IPv6 address was assigned
|
||||
to the interface.
|
||||
|
||||
At this point, you can test IPv6 connectivity (and discover your board's IPv6
|
||||
address) by pinging "All local-link nodes" IPv6 address:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# ping6 -I bt0 ff02::1
|
||||
PING ff02::1(ff02::1) from fe80::fa54:a8ff:feeb:218f bt0: 56 data bytes
|
||||
64 bytes from fe80::fa54:a8ff:feeb:218f: icmp_seq=1 ttl=64 time=0.088 ms
|
||||
64 bytes from fe80::c9af:14ff:fe57:d86e: icmp_seq=1 ttl=64 time=285 ms (DUP!)
|
||||
|
||||
For each ping packet, both your host and the BLE board send a reply. You
|
||||
can see the board's reply marked as ``(DUP!)``. You can ping the board
|
||||
directly with:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# ping6 fe80::c9af:14ff:fe57:d86e%bt0
|
||||
PING fe80::c9af:14ff:fe57:d86e%bt0(fe80::c9af:14ff:fe57:d86e) 56 data bytes
|
||||
64 bytes from fe80::c9af:14ff:fe57:d86e: icmp_seq=1 ttl=64 time=177 ms
|
||||
64 bytes from fe80::c9af:14ff:fe57:d86e: icmp_seq=2 ttl=64 time=53.0 ms
|
||||
|
||||
Note that the command uses a "scoped IPv6 address", where the scope is
|
||||
defined by the networking interface, with ``%bt0`` appended in this case.
|
||||
A specification like that is an alternative to passing ``-I bt0`` to
|
||||
``ping6`` (and works with other networking tools like ``telnet``, ``nc``,
|
||||
``curl``, etc.)
|
||||
|
||||
While we can use a link-local address, it's not very convenient, as it must be
|
||||
scoped and will change on each run. Instead, the IPSP sample is configured with
|
||||
``2001:db8::1`` static address and we'll configure the host's interface to
|
||||
access that address by configuring ``bt0`` with the complementary address
|
||||
``2001:db8::2``:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# ip address add 2001:db8::2/64 dev bt0
|
||||
|
||||
Now we can ping the board's static address with:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
# ping6 2001:db8::1
|
||||
PING 2001:db8::1(2001:db8::1) 56 data bytes
|
||||
64 bytes from 2001:db8::1: icmp_seq=1 ttl=64 time=282 ms
|
||||
|
||||
The IPSP sample includes builtin echo server for UDP and TCP on a port 4242,
|
||||
which we can test with:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ telnet 2001:db8::1 4242
|
||||
Trying 2001:db8::1...
|
||||
Connected to 2001:db8::1.
|
||||
Escape character is '^]'.
|
||||
test
|
||||
test
|
||||
test2
|
||||
test2
|
||||
^]
|
||||
telnet> quit
|
||||
Connection closed.
|
||||
|
||||
In the output above, first ``test`` line was typed, next was echoed back by
|
||||
the board. Likewise for ``test2``. To quit telnet tool, type Ctrl+], then
|
||||
"quit" at the prompt.
|
||||
|
||||
As an alternative to using well-known networking tools above, and also to
|
||||
test both TCP and UDP echo, you can use Zephyr's helper tool in the GitHub
|
||||
``zephyrproject-rtos/net-tools`` repository:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ echo-client -i bt0 <ip>
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright 2019 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&lptmr1 {
|
||||
interrupt-parent = <&intmux0_ch2>;
|
||||
};
|
||||
|
||||
&intmux0_ch2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&intmux0_ch3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&generic_fsk {
|
||||
interrupt-parent = <&intmux0_ch3>;
|
||||
status = "okay";
|
||||
};
|
|
@ -1,28 +0,0 @@
|
|||
CONFIG_BT=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_BT_SMP=y
|
||||
CONFIG_BT_PERIPHERAL=y
|
||||
CONFIG_BT_CENTRAL=y
|
||||
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
|
||||
CONFIG_BT_DEVICE_NAME="Test IPSP node"
|
||||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_IPV6=y
|
||||
CONFIG_NET_IPV4=n
|
||||
CONFIG_NET_UDP=y
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NET_L2_BT=y
|
||||
CONFIG_INIT_STACKS=y
|
||||
CONFIG_NET_PKT_RX_COUNT=10
|
||||
CONFIG_NET_PKT_TX_COUNT=10
|
||||
CONFIG_NET_BUF_RX_COUNT=20
|
||||
CONFIG_NET_BUF_TX_COUNT=20
|
||||
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3
|
||||
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
|
||||
CONFIG_NET_MAX_CONTEXTS=6
|
||||
|
||||
CONFIG_NET_CONFIG_AUTO_INIT=y
|
||||
CONFIG_NET_CONFIG_SETTINGS=y
|
||||
CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2"
|
||||
CONFIG_NET_CONFIG_BT_NODE=y
|
|
@ -1,33 +0,0 @@
|
|||
CONFIG_BT=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_BT_SMP=y
|
||||
CONFIG_BT_PERIPHERAL=y
|
||||
CONFIG_BT_CENTRAL=y
|
||||
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
|
||||
CONFIG_BT_DEVICE_NAME="Test IPSP node"
|
||||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_IPV6=y
|
||||
CONFIG_NET_IPV4=n
|
||||
CONFIG_NET_UDP=y
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NET_LOG=y
|
||||
CONFIG_NET_L2_BT=y
|
||||
CONFIG_INIT_STACKS=y
|
||||
CONFIG_NET_STATISTICS=y
|
||||
CONFIG_NET_PKT_RX_COUNT=10
|
||||
CONFIG_NET_PKT_TX_COUNT=10
|
||||
CONFIG_NET_BUF_RX_COUNT=20
|
||||
CONFIG_NET_BUF_TX_COUNT=20
|
||||
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3
|
||||
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
|
||||
CONFIG_NET_MAX_CONTEXTS=6
|
||||
|
||||
CONFIG_NET_SHELL=y
|
||||
CONFIG_BT_SHELL=y
|
||||
|
||||
CONFIG_NET_CONFIG_AUTO_INIT=y
|
||||
CONFIG_NET_CONFIG_SETTINGS=y
|
||||
CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2"
|
||||
CONFIG_NET_CONFIG_BT_NODE=y
|
|
@ -1,29 +0,0 @@
|
|||
CONFIG_BT=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_BT_SMP=y
|
||||
CONFIG_BT_PERIPHERAL=y
|
||||
CONFIG_BT_CENTRAL=y
|
||||
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
|
||||
CONFIG_BT_DEVICE_NAME="Test IPSP node"
|
||||
CONFIG_NETWORKING=y
|
||||
CONFIG_NET_IPV6=y
|
||||
CONFIG_NET_IPV4=n
|
||||
CONFIG_NET_UDP=y
|
||||
CONFIG_NET_TCP=y
|
||||
CONFIG_TEST_RANDOM_GENERATOR=y
|
||||
CONFIG_NET_L2_BT=y
|
||||
CONFIG_NET_L2_BT_ZEP1656=y
|
||||
CONFIG_INIT_STACKS=y
|
||||
CONFIG_NET_PKT_RX_COUNT=10
|
||||
CONFIG_NET_PKT_TX_COUNT=10
|
||||
CONFIG_NET_BUF_RX_COUNT=20
|
||||
CONFIG_NET_BUF_TX_COUNT=20
|
||||
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3
|
||||
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
|
||||
CONFIG_NET_MAX_CONTEXTS=6
|
||||
|
||||
CONFIG_NET_CONFIG_AUTO_INIT=y
|
||||
CONFIG_NET_CONFIG_SETTINGS=y
|
||||
CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1"
|
||||
CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2"
|
||||
CONFIG_NET_CONFIG_BT_NODE=y
|
|
@ -1,25 +0,0 @@
|
|||
sample:
|
||||
name: Bluetooth IPSP Sample
|
||||
description: IPSP (Internet Protocol Support Profile) Node role sample
|
||||
tests:
|
||||
sample.bluetooth.ipsp:
|
||||
harness: bluetooth
|
||||
platform_allow:
|
||||
- qemu_x86
|
||||
- qemu_cortex_m3
|
||||
tags:
|
||||
- bluetooth
|
||||
- net
|
||||
integration_platforms:
|
||||
- qemu_x86
|
||||
sample.bluetooth.ipsp.zep1656:
|
||||
harness: bluetooth
|
||||
extra_args: CONF_FILE="prj_zep1656.conf"
|
||||
platform_allow:
|
||||
- qemu_x86
|
||||
- qemu_cortex_m3
|
||||
tags:
|
||||
- bluetooth
|
||||
- net
|
||||
integration_platforms:
|
||||
- qemu_x86
|
|
@ -1,323 +0,0 @@
|
|||
/* main.c - Application main entry point */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
LOG_MODULE_REGISTER(ipsp);
|
||||
|
||||
/* Preventing log module registration in net_core.h */
|
||||
#define NET_LOG_ENABLED 0
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/linker/sections.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <zephyr/net/net_pkt.h>
|
||||
#include <zephyr/net/net_if.h>
|
||||
#include <zephyr/net/net_core.h>
|
||||
#include <zephyr/net/net_context.h>
|
||||
#include <zephyr/net/udp.h>
|
||||
|
||||
/* Define my IP address where to expect messages */
|
||||
#define MY_IP6ADDR { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0x1 } } }
|
||||
#define MY_PREFIX_LEN 64
|
||||
|
||||
static struct in6_addr in6addr_my = MY_IP6ADDR;
|
||||
|
||||
#define MY_PORT 4242
|
||||
|
||||
#define STACKSIZE 2000
|
||||
K_THREAD_STACK_DEFINE(thread_stack, STACKSIZE);
|
||||
static struct k_thread thread_data;
|
||||
|
||||
static uint8_t buf_tx[NET_IPV6_MTU];
|
||||
|
||||
#define MAX_DBG_PRINT 64
|
||||
|
||||
NET_PKT_TX_SLAB_DEFINE(echo_tx_tcp, 15);
|
||||
NET_PKT_DATA_POOL_DEFINE(echo_data_tcp, 30);
|
||||
|
||||
static struct k_mem_slab *tx_tcp_pool(void)
|
||||
{
|
||||
return &echo_tx_tcp;
|
||||
}
|
||||
|
||||
static struct net_buf_pool *data_tcp_pool(void)
|
||||
{
|
||||
return &echo_data_tcp;
|
||||
}
|
||||
|
||||
static struct k_sem quit_lock;
|
||||
|
||||
static inline void quit(void)
|
||||
{
|
||||
k_sem_give(&quit_lock);
|
||||
}
|
||||
|
||||
static inline void init_app(void)
|
||||
{
|
||||
LOG_INF("Run IPSP sample");
|
||||
|
||||
k_sem_init(&quit_lock, 0, K_SEM_MAX_LIMIT);
|
||||
|
||||
if (net_addr_pton(AF_INET6,
|
||||
CONFIG_NET_CONFIG_MY_IPV6_ADDR,
|
||||
&in6addr_my) < 0) {
|
||||
LOG_ERR("Invalid IPv6 address %s",
|
||||
CONFIG_NET_CONFIG_MY_IPV6_ADDR);
|
||||
}
|
||||
|
||||
do {
|
||||
struct net_if_addr *ifaddr;
|
||||
|
||||
ifaddr = net_if_ipv6_addr_add(net_if_get_default(),
|
||||
&in6addr_my, NET_ADDR_MANUAL, 0);
|
||||
} while (0);
|
||||
}
|
||||
|
||||
static inline bool get_context(struct net_context **udp_recv6,
|
||||
struct net_context **tcp_recv6)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in6 my_addr6 = { 0 };
|
||||
|
||||
my_addr6.sin6_family = AF_INET6;
|
||||
my_addr6.sin6_port = htons(MY_PORT);
|
||||
|
||||
ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, udp_recv6);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot get network context for IPv6 UDP (%d)", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = net_context_bind(*udp_recv6, (struct sockaddr *)&my_addr6,
|
||||
sizeof(struct sockaddr_in6));
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot bind IPv6 UDP port %d (%d)",
|
||||
ntohs(my_addr6.sin6_port), ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, tcp_recv6);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot get network context for IPv6 TCP (%d)", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
net_context_setup_pools(*tcp_recv6, tx_tcp_pool, data_tcp_pool);
|
||||
|
||||
ret = net_context_bind(*tcp_recv6, (struct sockaddr *)&my_addr6,
|
||||
sizeof(struct sockaddr_in6));
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot bind IPv6 TCP port %d (%d)",
|
||||
ntohs(my_addr6.sin6_port), ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = net_context_listen(*tcp_recv6, 0);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot listen IPv6 TCP (%d)", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int build_reply(const char *name,
|
||||
struct net_pkt *pkt,
|
||||
uint8_t *buf)
|
||||
{
|
||||
int reply_len = net_pkt_remaining_data(pkt);
|
||||
int ret;
|
||||
|
||||
LOG_DBG("%s received %d bytes", name, reply_len);
|
||||
|
||||
ret = net_pkt_read(pkt, buf, reply_len);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("cannot read packet: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LOG_DBG("sending %d bytes", reply_len);
|
||||
|
||||
return reply_len;
|
||||
}
|
||||
|
||||
static inline void pkt_sent(struct net_context *context,
|
||||
int status,
|
||||
void *user_data)
|
||||
{
|
||||
if (status >= 0) {
|
||||
LOG_DBG("Sent %d bytes", status);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_dst_addr(sa_family_t family,
|
||||
struct net_pkt *pkt,
|
||||
struct net_ipv6_hdr *ipv6_hdr,
|
||||
struct net_udp_hdr *udp_hdr,
|
||||
struct sockaddr *dst_addr)
|
||||
{
|
||||
net_ipv6_addr_copy_raw((uint8_t *)&net_sin6(dst_addr)->sin6_addr,
|
||||
ipv6_hdr->src);
|
||||
net_sin6(dst_addr)->sin6_family = AF_INET6;
|
||||
net_sin6(dst_addr)->sin6_port = udp_hdr->src_port;
|
||||
}
|
||||
|
||||
static void udp_received(struct net_context *context,
|
||||
struct net_pkt *pkt,
|
||||
union net_ip_header *ip_hdr,
|
||||
union net_proto_header *proto_hdr,
|
||||
int status,
|
||||
void *user_data)
|
||||
{
|
||||
struct sockaddr dst_addr;
|
||||
sa_family_t family = net_pkt_family(pkt);
|
||||
static char dbg[MAX_DBG_PRINT + 1];
|
||||
int ret;
|
||||
|
||||
snprintf(dbg, MAX_DBG_PRINT, "UDP IPv%c",
|
||||
family == AF_INET6 ? '6' : '4');
|
||||
|
||||
set_dst_addr(family, pkt, ip_hdr->ipv6, proto_hdr->udp, &dst_addr);
|
||||
|
||||
ret = build_reply(dbg, pkt, buf_tx);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot send data to peer (%d)", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
net_pkt_unref(pkt);
|
||||
|
||||
ret = net_context_sendto(context, buf_tx, ret, &dst_addr,
|
||||
family == AF_INET6 ?
|
||||
sizeof(struct sockaddr_in6) :
|
||||
sizeof(struct sockaddr_in),
|
||||
pkt_sent, K_NO_WAIT, user_data);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot send data to peer (%d)", ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_udp_recv(struct net_context *udp_recv6)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = net_context_recv(udp_recv6, udp_received, K_NO_WAIT, NULL);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot receive IPv6 UDP packets");
|
||||
}
|
||||
}
|
||||
|
||||
static void tcp_received(struct net_context *context,
|
||||
struct net_pkt *pkt,
|
||||
union net_ip_header *ip_hdr,
|
||||
union net_proto_header *proto_hdr,
|
||||
int status,
|
||||
void *user_data)
|
||||
{
|
||||
static char dbg[MAX_DBG_PRINT + 1];
|
||||
sa_family_t family;
|
||||
int ret, len;
|
||||
|
||||
if (!pkt) {
|
||||
/* EOF condition */
|
||||
return;
|
||||
}
|
||||
|
||||
family = net_pkt_family(pkt);
|
||||
len = net_pkt_remaining_data(pkt);
|
||||
|
||||
snprintf(dbg, MAX_DBG_PRINT, "TCP IPv%c",
|
||||
family == AF_INET6 ? '6' : '4');
|
||||
|
||||
ret = build_reply(dbg, pkt, buf_tx);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot send data to peer (%d)", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
(void)net_context_update_recv_wnd(context, len);
|
||||
net_pkt_unref(pkt);
|
||||
|
||||
ret = net_context_send(context, buf_tx, ret, pkt_sent,
|
||||
K_NO_WAIT, NULL);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot send data to peer (%d)", ret);
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
static void tcp_accepted(struct net_context *context,
|
||||
struct sockaddr *addr,
|
||||
socklen_t addrlen,
|
||||
int error,
|
||||
void *user_data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
NET_DBG("Accept called, context %p error %d", context, error);
|
||||
|
||||
net_context_set_accepting(context, false);
|
||||
|
||||
ret = net_context_recv(context, tcp_received, K_NO_WAIT, NULL);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot receive TCP packet (family %d)",
|
||||
net_context_get_family(context));
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_tcp_accept(struct net_context *tcp_recv6)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = net_context_accept(tcp_recv6, tcp_accepted, K_NO_WAIT, NULL);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot receive IPv6 TCP packets (%d)", ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void listen(void *p1, void *p2, void *p3)
|
||||
{
|
||||
ARG_UNUSED(p1);
|
||||
ARG_UNUSED(p2);
|
||||
ARG_UNUSED(p3);
|
||||
|
||||
struct net_context *udp_recv6 = { 0 };
|
||||
struct net_context *tcp_recv6 = { 0 };
|
||||
|
||||
if (!get_context(&udp_recv6, &tcp_recv6)) {
|
||||
LOG_ERR("Cannot get network contexts");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INF("Starting to wait");
|
||||
|
||||
setup_tcp_accept(tcp_recv6);
|
||||
setup_udp_recv(udp_recv6);
|
||||
|
||||
k_sem_take(&quit_lock, K_FOREVER);
|
||||
|
||||
LOG_INF("Stopping...");
|
||||
|
||||
net_context_put(udp_recv6);
|
||||
net_context_put(tcp_recv6);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
init_app();
|
||||
|
||||
k_thread_create(&thread_data, thread_stack, STACKSIZE,
|
||||
listen,
|
||||
NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue