Skip to content

TCP traffic with IPSP sample not working on 96Boards Nitrogen #33185

@huawei-wojciech-zmuda

Description

@huawei-wojciech-zmuda

Hello,

I'm trying to get the Bluetooth IPSP sample application working on 96Boards Nitrogen. I follow the readme and the connection itself and pings work fine, but the echo-client and telnet examples do not work. Below please find results of my debugging. I cannot narrow down the reason of the problem, but I've noticed some interesting patterns.

Hardware and software setup

I have tried the two following setups with the same results:

[ Zephyr@Nitrogen ] --- BLE --- [ Linux@Avenger96 ]
[ Zephyr@Nitrogen ] --- BLE --- [ Linux@Thinkpad P1 ]

Zephyr is built from the top of the master branch 65ac2f6d1b cmake: remove TOOLCHAIN_INCLUDES.

Avenger96 is another 96Boards board with Broadcom-based Murata 1MW BT chipset, while my Thinkpad has an Intel chipset. This does not affect the issue, so I think the problem is on Nitrogen/Zephyr side.

Thinkpad is running Ubuntu with generic 5.8.0-44-generic #50~20.04.1-Ubuntu SMP kernel. Avenger is running a custom yocto-based Linux distro with Linux stm32mp1-av96 5.4.56 #1 SMP PREEMPT kernel built from STMicro sources.

Nitrogen is v1.1 02/16/2017 revision, has no peripherals connected and I use the on-board USB port for UART and flashing.

How to reproduce

Going through the IPSP readme file

  1. Build and flash the IPSP sample onto the board
west build -p auto -b 96b_nitrogen -d build-ipsp samples/bluetooth/ipsp
west flash --hex-file build-ipsp/zephyr/zephyr.hex
  1. After the IPSP application happily started, enable 6LoWPAN on the PC and connect to Nitrogen, set IP address on the new Bluetooth interface
# modprobe bluetooth_6lowpan
# echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable
# echo "connect <bdaddr> <type>" > /sys/kernel/debug/bluetooth/6lowpan_control
# ip address add 2001:db8::2/64 dev bt0
  1. Ping Nitrogen from the PC - works
# ping6 -I bt0 2001:db8::1                      
PING 2001:db8::1(2001:db8::1) from 2001:db8::2 bt0: 56 data bytes
64 bytes from 2001:db8::1: icmp_seq=1 ttl=64 time=377 ms
64 bytes from 2001:db8::1: icmp_seq=2 ttl=64 time=367 ms
^C
  1. Try to use telnet to Nitrogen from the PC - does not work
# telnet 2001:db8::1 4242
Trying 2001:db8::1...
^C
  1. Try to use echo-client to Nitrogen from the PC - works
# ./echo-client -i bt0 2001:db8::1
Binding to 2001:db8::2
....Timeout while waiting idx 4 len 1500
..
Average round trip 126 ms
Sent 6 packets

Additional tests

  1. Try to use echo-client but in TCP mode - does not work
# ./echo-client -t -i bt0 2001:db8::1
Binding to 2001:db8::2
connect: Connection timed out
  1. Try to connect with netcat in TCP mode - does not work
# time nc 2001:db8::1 4242

real    2m9,514s
user    0m0,003s
sys     0m0,000s
  1. Try to connect with netcat in UDP mode - works
# nc -u 2001:db8::1 4242
hey
hey
this is echo
this is echo
^C

Deeper debugging

Kernel configs manipulations

I tried a couple of things that had no effect but I mention them here just in case it brings an idea to somebody's mind:

  • switching to the legacy TCP stack,
  • increasing NET_TCP_BACKLOG_SIZE,
  • enabling NET_TCP_AUTO_ACCEPT,
  • increasing NET_MAX_CONTEXTS.

Zephyr shell fun

I built Zephyr with CONFIG_NET_SHELL=y to get shell and net commands so I can do additional experiments. I also enabled additional TCP logging.

Connect from Zephyr to netcat server in TCP and UDP modes

TCP
  1. On the PC side spawn a netcat server in TCP mode
# nc -l 2001:db8::2 4242
  1. On the Nitrogen side try to connect to the server
uart:~$ net tcp connect 2001:db8::2 4242
Connecting from [2001:db8::1]:0 to [2001:db8::2]:4242
[03:36:43.755,645] <dbg> net_tcp.tcp_conn_ref: (shell_uart): conn: 0x2000c054, ref_count: 1
[03:36:43.755,645] <dbg> net_tcp.tcp_conn_alloc: (shell_uart): conn: 0x2000c054
[03:36:43.755,920] <dbg> net_tcp.net_tcp_connect: (shell_uart): context: 0x200041ac, local: 2001:db8::1, remote: 2001:db8::2
[03:36:43.755,981] <dbg> net_tcp.net_tcp_connect: (shell_uart): conn: 0x2000c054 src: 2001:db8::1, dst: 2001:db8::2
[03:36:43.756,134] <dbg> net_tcp.tcp_in: (<log_strdup alloc failed>): <log_strdup alloc failed>
[03:36:43.756,347] <dbg> net_tcp.tcp_out_ext: (<log_strdup alloc failed>): <log_strdup alloc failed>
[03:36:43.756,469] <dbg> net_tcp.tcp_send_process_no_lock: (<log_strdup alloc failed>): <log_strdup alloc failed>
[03:36:43.756,652] <dbg> net_tcp.tcp_send: (<log_strdup alloc failed>): <log_strdup alloc failed>
[03:36:43.756,958] <dbg> net_tcp.tcp_in: (<log_strdup alloc failed>): LISTEN->SYN_SENT
[03:36:43.756,988] <dbg> net_tcp.tcp_conn_unref: (<log_strdup alloc failed>): conn: 0x2000c054, ref_count=1
[03:36:43.757,019] <dbg> net_tcp.net_tcp_unref: (<log_strdup alloc failed>): context: 0x200041ac, conn: (nil)
[03:36:43.757,080] <dbg> net_tcp.net_tcp_connect: (<log_strdup alloc failed>): conn: 0x2000c054, ret=-60

See that it does not work and the connection fails immediately because of timeout. The -60 return code seems to be ret = -ETIMEDOUT set in tcp2.c:net_tcp_connect().

UDP
  1. On the PC side spawn a netcat server in UDP mode
# nc -u -l 2001:db8::2 4242
  1. On the Nitrogen side try to send a message to the server
uart:~$ net udp send 2001:db8::2 4242 "hello dear friends"
Message sent
[03:39:32.701,965] <dbg> net_tcp.net_tcp_unref: (shell_uart): context: 0x200041ac, conn: (nil)
  1. The message arrives on the PC side
# nc -u -l 2001:db8::2 4242
hello dear friends

Statistics

I built Zephyr with CONFIG_NET_STATISTICS=y to get shell access to the interface statistics. By issuing net stats multiple times I had the following observations:

  • during experiments when the TCP connection is initiated from the PC, there are no incoming or dropped packets. The counters do not increase.
  • during experiments when the TCP connection is initiated from Nitrogen using Zephyr shell, Zephyr sees incoming packets and drops them and the connrst counter increases.

Packets sniffing

I hooked up with Wireshark to the bt0 interface and captured everything I describe in this post. I'm including the zipped pcap file if you would like to inspect it yourselves. Here are my observations from the capture session:

  • UDP and ICMPv6 traffic works fine, neighbor solicitaion and advertisement packets are sent by both hosts with no issues.
  • when TCP traffic is initiated from the PC, the first SYN packet sent from the PC does not get a response from Zephyr, therefore the PC keeps retransmiting it. This is the case where interface rx/drop counters on Zephyr do not increase.
  • when TCP traffic is initiated from Zephyr, a SYN packet is received by the PC, then the PC sends a corresponding SYN,ACK packet. The SYN,ACK packet is then retransmitted and it is apparently never properly received by Zephyr. But this is the case where interface rx/drop counters on Zephyr do increase.

MQTT experiment

I also did a sniffing session with MQTT sample app with similar results, but I could also observe Zephyr sending FIN packets when it gave up connecting to a MQTT broker running on the PC. The connection was not possible from the same reason, i.e. SYN,ACK from the PC was never properly received by Zephyr. After some time Zephyr sent FIN, the PC responded with FIN,ACK and then went into rentransmission.

I will be grateful for any ideas how to proceed with debugging this issue.

Regards,
Wojciech

nitrogen-tcp-issue.zip

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions