Retrieve UDP Notifications on the Border Router#

Note that this part is executed on the Linux Border Router.

If the application flashed on the Wi-SUN devices is sending notification messages to the Border Router, a convenient way to retrieve them from the Border Router is via a python script such as udp_notification_receiver.py.

Setup IPV6 addresses#

The Node Monitoring application running on the SoC is aware of the Border Router's address. However, it is designed to simulate a real-world scenario, where it can send status messages outside the Wi-SUN mesh network.

So by default, the UDP destination address is set to:

#define UDP_NOTIFICATION_DEST  "fd00:6172:6d00::1" // fixed IPv6 string

To receive UDP message on linux border router, fd00:6172:6d00::1 must be added:

  • Get and run Node Monitoring border router script wsbrd_add.sh

git clone https://github.com/SiliconLabs/wisun_applications.git
cd wisun_applications/wisun_node_monitoring/linux_border_router_wsbrd

This folder contains useful script for Node Monitoring application, some script shall be made executable:

chmod a+x coap_all
chmod a+x ipv6s
chmod a+x *.sh

To set BR linux address accordingly to Node Monitoring default UDP destination address:

wsbrd_add.sh
  • Or open a bash and run below command:

sudo ip address add fd00:6172:6d00::1/64 dev eth0

Call the Script#

 python udp_notification_receiver.py 1237 " "
  • The first parameter is the UDP port to listen to, rcv_port in the script.

  • The second parameter is an optional newline parameter used to replace the newline characters from the incoming message. It's useful to display one message per line, since otherwise they would be displayed in json format on multiple lines. You can use a different character as a separator.

  • The script is also suppressing all spaces from the incoming message, for a more compact display.

Script Output#

python udp_notification_receiver.py 1237 " "
Receiving on ::/1237...
[2023-08-18 14:07:28] Rx 1237:   { "device":"a901", "chip":"xG25", "parent":"333a", "running":"0:22:47:30", "connected":"0:22:46:35", "disconnected":"no", "connections":"1", "availability":"100.00", "connected_total":"0:22:46:35", "disconnected_total":"0:00:00:00" }
[2023-08-18 14:07:44] Rx 1237:   { "device":"8486", "chip":"xG25", "parent":"333a", "running":"1:01:47:22", "connected":"1:01:46:40", "disconnected":"no", "connections":"1", "availability":"100.00", "connected_total":"1:01:46:40", "disconnected_total":"0:00:00:00" }
[2023-08-18 14:07:46] Rx 1237:   { "device":"a51d", "chip":"xG25", "parent":"a901", "running":"0:19:04:32", "connected":"0:19:03:30", "disconnected":"no", "connections":"1", "availability":"100.00", "connected_total":"0:19:03:30", "disconnected_total":"0:00:00:00" }
[2023-08-18 14:07:58] Rx 1237:   { "device":"a51c", "chip":"xG25", "parent":"333a", "running":"8:01:41:33", "connected":"1:20:54:38", "disconnected":"no", "connections":"6", "availability":"97.34", "connected_total":"7:20:32:26", "disconnected_total":"0:05:08:36" }
[2023-08-18 14:08:03] Rx 1237:   { "device":"2191", "chip":"xG25", "parent":"333a", "running":"1:01:54:45", "connected":"1:01:53:41", "disconnected":"no", "connections":"1", "availability":"100.00", "connected_total":"1:01:53:41", "disconnected_total":"0:00:00:00" }
[2023-08-18 14:08:04] Rx 1237:   { "device":"2853", "chip":"xG25", "parent":"333a", "running":"1:01:54:47", "connected":"0:01:14:48", "disconnected":"no", "connections":"2", "availability":"99.88", "connected_total":"1:01:51:49", "disconnected_total":"0:00:01:52" }

Code Walkthrough#

The script is as follows:

# Used to receive UDP notifications strings
# Call with
# python udp_notification_receiver.py 1237 " "

import socket
import sys
import datetime

HOST_IP = "::" # Host own address (tun0 IPv6 address)

rcv_port = int(sys.argv[1])
newline = " "

if (len(sys.argv) > 2):
  newline = sys.argv[2]
  space = ""

PORT = rcv_port # Port used by the peer

sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.bind((HOST_IP, PORT))

print(f"Receiving on {HOST_IP}/{PORT}...")

while True:
  data, addr = sock.recvfrom(2048) # buffer size is 2048 bytes
  now = datetime.datetime.now()
  now_str = str(now.strftime('%Y-%m-%d %H:%M:%S'))

  try:
    message_string = data.decode("utf-8").replace(" ", space).replace("\n", newline)
  except Exception as e:
    print(f"Exception {e} (from {addr})")

  print (f"[{now_str}] Rx {PORT}: {newline}", message_string)

It goes through:

  • Import of the required python packages

  • Retrieving the rcv_port value from the first argument

  • Retrieving the newline replacement, if any, from the second argument

  • Opening a socket to listen to the rcv_port on all IPv6 addresses

  • Infinite loop with:

    • Reception from the UDP socket

    • Formatting the current date and time

    • Removing all spaces from the received message

    • Replacing all \n from the received message by newline

    • Printing the modified string