From d5adc2c7db59b9bfae4fc7009e7fc1344a30f5c4 Mon Sep 17 00:00:00 2001 From: Emran Billah Date: Tue, 3 Sep 2024 10:09:03 -0300 Subject: [PATCH 1/4] Testing env vars in docker compose --- .env | 12 ++-- .gitignore | 3 +- Dockerfile | 4 ++ README.md | 2 + docker-compose-run-single.yml | 12 +++- run-single.sh | 49 ++++++-------- scripts/entrypoint.sh | 124 ++++++++++++++++++---------------- scripts/set-env-vars.sh | 42 ++++++++++++ 8 files changed, 155 insertions(+), 93 deletions(-) create mode 100755 scripts/set-env-vars.sh diff --git a/.env b/.env index e73eeb0..23de14a 100755 --- a/.env +++ b/.env @@ -1,14 +1,14 @@ # Base params -BASE_SUBNET=7.7.7 +XBNET_BASE_SUBNET=3.3.3 XBEE_INDEX=1 # Default params -DEFAULT_GATEWAY=7.7.7.1 -DEFAULT_IPVLAN_IP=7.7.7.20 # Required only when running ipvlan net (look in docker compose) -DEFAULT_MACVLAN_IP=7.7.7.30 # Required only when running macvlan net (look in docker compose) +XBNET_DEFAULT_GATEWAY=3.3.3.1 +XBNET_DEFAULT_IPVLAN_IP=3.3.3.20 # Required only when running ipvlan net (look in docker compose) +XBNET_DEFAULT_MACVLAN_IP=3.3.3.30 # Required only when running macvlan net (look in docker compose) # Configuration for xbnet XBEE_PORT=/dev/ttyUSB0 XBEE_BAUDRATE=230400 -XBEE_NET_SRC_IP=7.7.7.201 # Set based on interface type -XBEE_NET_IFACE_NAME=xbnet_router_1 # Set based on interface type +XBNET_IP=3.3.3.201 # Set based on interface type +XBNET_INTERFACE_NAME=xbnet_router_1 # Set based on interface type diff --git a/.gitignore b/.gitignore index f198160..3f30cf6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -workspace \ No newline at end of file +workspace +.env diff --git a/Dockerfile b/Dockerfile index 7501696..29a0361 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,6 +30,10 @@ RUN cp target/release/xbnet /usr/local/bin/xbnet COPY ./scripts/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh +# Copy the set-env-vars.sh script to set env vars +COPY ./scripts/set-env-vars.sh /set-env-vars.sh +RUN chmod +x /set-env-vars.sh + # Copy the health check script COPY ./scripts/health_check.sh /health_check.sh RUN chmod +x /health_check.sh diff --git a/README.md b/README.md index e9983f8..2808ab1 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,8 @@ cd services-xbee_net - Router mode: `sh ./run-single.sh --subnet=7.7.7 --serial-speed=230400 --port=/dev/ttyUSB0 --interface-type=router` - Gateway mode: `sh ./run-single.sh --subnet=7.7.7 --serial-speed=230400 --port=/dev/ttyUSB0 --interface-type=gateway` +##### NOTE: This setup assumes that you have an XBee device connected to port: /dev/ttyUSB0 + #### 3. OR Manually build and Start the Docker Container diff --git a/docker-compose-run-single.yml b/docker-compose-run-single.yml index 48d6f8d..75c8583 100644 --- a/docker-compose-run-single.yml +++ b/docker-compose-run-single.yml @@ -67,8 +67,18 @@ services: build: . container_name: xbnet_node privileged: true - env_file: .env + # env_file: .env + environment: + - XBEE_INDEX=1 + - XBEE_BAUDRATE=230400 + - XBEE_PORT=/dev/ttyUSB0 + - XBNET_BASE_SUBNET=7.7.7 + - XBNET_INTERFACE_TYPE=router command: bash /entrypoint.sh + # network_mode: "host" + + + # command: /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf # command: tail -f /dev/null # networks: diff --git a/run-single.sh b/run-single.sh index 771180d..b541e77 100755 --- a/run-single.sh +++ b/run-single.sh @@ -4,43 +4,36 @@ # # This script sets up the environment for running a Docker Compose configuration with XBee networks. # It accepts optional --index=, --subnet=, --serial-speed=, --port=, and --interface-type= arguments -# to specify the XBEE_INDEX, BASE_SUBNET, XBEE_BAUDRATE, XBEE_PORT, and XBEE_INTERFACE_TYPE values. -# If no index is provided, it defaults to 1. If no subnet is provided, it defaults to 192.168.1. +# to specify the XBEE_INDEX, XBNET_BASE_SUBNET, XBEE_BAUDRATE, XBEE_PORT, and XBNET_INTERFACE_TYPE values. +# If no index is provided, it defaults to 1. If no subnet is provided, it defaults to 10.10.10. # If no serial-speed is provided, it defaults to 230400. If no port is provided, it defaults to /dev/ttyUSB0. # If no interface-type is provided, it defaults to "router". # # Usage: -# ./run-single.sh # Runs with default index (1), default subnet (192.168.1), default speed (230400), and default port (/dev/ttyUSB0) +# ./run-single.sh # Runs with default index (1), default subnet (10.10.10), default speed (230400), and default port (/dev/ttyUSB0) # ./run-single.sh --index=2 # Runs with index 2 and default values for other options # ./run-single.sh --subnet=192.168.50 # Runs with default index (1), specified subnet, and default values for other options # ./run-single.sh --index=3 --subnet=192.168.50 # Runs with specified index, specified subnet, and default values for speed and port # ./run-single.sh --serial-speed=115200 --port=/dev/ttyUSB1 # Runs with specified serial-speed and port with default values for other options # ./run-single.sh --interface-type=gateway # Runs with specified interface type as gateway -# IPs assigned: -# BASE_SUBNET: eg.: 10.10.10 -# DEFAULT_GATEWAY: ${BASE_SUBNET}.1, eg.: 10.10.10.1 -# DEFAULT_IPVLAN_IP: ${BASE_SUBNET}.20 eg.: 10.10.10.20 -# DEFAULT_MACVLAN_IP: ${BASE_SUBNET}.30 eg.: 10.10.10.30 -# XBEE_NET_SRC_IP: ${BASE_SUBNET}.20${INDEX} eg.: 10.10.10.201 (all Xbnets will be in the 200+ range) - # Default values -INDEX=1 -BASE_SUBNET="10.10.10" +XBEE_INDEX=1 +XBNET_BASE_SUBNET="10.10.10" XBEE_BAUDRATE=230400 XBEE_PORT="/dev/ttyUSB0" -XBEE_INTERFACE_TYPE="router" # Options: ["gateway", "router"] +XBNET_INTERFACE_TYPE="router" # Options: ["gateway", "router"] # Parse command-line arguments for arg in "$@" do case $arg in --index=*) - INDEX="${arg#*=}" + XBEE_INDEX="${arg#*=}" shift ;; --subnet=*) - BASE_SUBNET="${arg#*=}" + XBNET_BASE_SUBNET="${arg#*=}" shift ;; --serial-speed=*) @@ -52,7 +45,7 @@ do shift ;; --interface-type=*) - XBEE_INTERFACE_TYPE="${arg#*=}" + XBNET_INTERFACE_TYPE="${arg#*=}" shift ;; *) @@ -61,30 +54,30 @@ do done # Determine the source IP based on interface type -if [ "$XBEE_INTERFACE_TYPE" = "gateway" ]; then - XBEE_NET_SRC_IP="${BASE_SUBNET}.1" - XBEE_NET_IFACE_NAME=xbnet_gateway +if [ "$XBNET_INTERFACE_TYPE" = "gateway" ]; then + XBNET_IP="${XBNET_BASE_SUBNET}.1" + XBNET_INTERFACE_NAME="xbnet_gateway" else - XBEE_NET_SRC_IP="${BASE_SUBNET}.20${INDEX}" - XBEE_NET_IFACE_NAME=xbnet_router_${INDEX} + XBNET_IP="${XBNET_BASE_SUBNET}.20${XBEE_INDEX}" + XBNET_INTERFACE_NAME="xbnet_router_${XBEE_INDEX}" fi # Create a .env file with the specified parameters cat < .env # Base params -BASE_SUBNET=${BASE_SUBNET} -XBEE_INDEX=${INDEX} +XBNET_BASE_SUBNET=${XBNET_BASE_SUBNET} +XBEE_INDEX=${XBEE_INDEX} # Default params -DEFAULT_GATEWAY=${BASE_SUBNET}.1 -DEFAULT_IPVLAN_IP=${BASE_SUBNET}.20 # Required only when running ipvlan net (look in docker compose) -DEFAULT_MACVLAN_IP=${BASE_SUBNET}.30 # Required only when running macvlan net (look in docker compose) +XBNET_DEFAULT_GATEWAY=${XBNET_BASE_SUBNET}.1 +XBNET_DEFAULT_IPVLAN_IP=${XBNET_BASE_SUBNET}.20 # Required only when running ipvlan net (look in docker compose) +XBNET_DEFAULT_MACVLAN_IP=${XBNET_BASE_SUBNET}.30 # Required only when running macvlan net (look in docker compose) # Configuration for xbnet XBEE_PORT=${XBEE_PORT} XBEE_BAUDRATE=${XBEE_BAUDRATE} -XBEE_NET_SRC_IP=${XBEE_NET_SRC_IP} # Set based on interface type -XBEE_NET_IFACE_NAME=${XBEE_NET_IFACE_NAME} # Set based on interface type +XBNET_IP=${XBNET_IP} # Set based on interface type +XBNET_INTERFACE_NAME=${XBNET_INTERFACE_NAME} # Set based on interface type EOF # Restart Docker Compose services diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 4f35b74..d502308 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -12,6 +12,10 @@ echo "Starting entrypoint.sh" +# Set associated env vars +echo "Setting associated environment variables. Calling /set-env-vars.sh" +sh /set-env-vars.sh + # Main loop loop() { while true; do @@ -27,13 +31,14 @@ loop() { # Check if the network interface is up check_network_state if [ $? -ne 0 ]; then - echo "Network interface $XBEE_NET_IFACE_NAME not found. Creating TAP interface..." + echo "Network interface $XBNET_INTERFACE_NAME not found. Creating TAP interface..." create_tap_interface fi sleep 0.5 # Log messages sent and received over xbnet - log_xbnet_messages + # log_xbnet_messages + sleep 0.5 done } @@ -49,7 +54,7 @@ check_device_port() { # Check if the network interface is up check_network_state() { - if ip link show $XBEE_NET_IFACE_NAME > /dev/null 2>&1; then + if ip link show $XBNET_INTERFACE_NAME > /dev/null 2>&1; then return 0 else return 1 @@ -59,7 +64,7 @@ check_network_state() { # Create a TAP network interface create_tap_interface() { # Start xbnet and run it in the background - xbnet -d --serial-speed ${XBEE_BAUDRATE} ${XBEE_PORT} tap --iface-name ${XBEE_NET_IFACE_NAME} & + xbnet -d --serial-speed ${XBEE_BAUDRATE} ${XBEE_PORT} tap --iface-name ${XBNET_INTERFACE_NAME} & # Wait until the interface is created while ! check_network_state; do @@ -67,93 +72,98 @@ create_tap_interface() { done # Create and bring up xbnet interface - ip addr add $XBEE_NET_SRC_IP/24 dev $XBEE_NET_IFACE_NAME - ip link set $XBEE_NET_IFACE_NAME up + ip addr add $XBNET_IP/24 dev $XBNET_INTERFACE_NAME + ip link set $XBNET_INTERFACE_NAME up echo "-------------------------------------------" echo "********** Tap interface created **********" echo "-------------------------------------------" - echo "Name: ${XBEE_NET_IFACE_NAME}" + echo "Name: ${XBNET_INTERFACE_NAME}" echo "Gateway: ${DEFAULT_GATEWAY}" - echo "IP: ${XBEE_NET_SRC_IP}" + echo "IP: ${XBNET_IP}" echo "Device port: ${XBEE_PORT}" echo "Device baudrate: ${XBEE_BAUDRATE}" echo "-------------------------------------------" return 0 } -# Log incoming and outgoing messages from Xbees over xbnet +# Function to log messages sent and received over xbnet log_xbnet_messages() { - echo "Monitoring messages on $XBEE_NET_IFACE_NAME..." + echo "Monitoring messages on $XBNET_INTERFACE_NAME..." + if [ -z "$XBNET_INTERFACE_NAME" ]; then + echo "Error: $XBNET_INTERFACE_NAME is not set." + return 1 + fi + + # Ensure the interface exists before proceeding + if [ ! -d "/sys/class/net/$XBNET_INTERFACE_NAME" ]; then + echo "Error: Network interface $XBNET_INTERFACE_NAME does not exist." + return 1 + fi + + # Continuously monitor the interface for packet statistics while true; do - RX_PACKETS_BEFORE=$(cat /sys/class/net/$XBEE_NET_IFACE_NAME/statistics/rx_packets) - TX_PACKETS_BEFORE=$(cat /sys/class/net/$XBEE_NET_IFACE_NAME/statistics/tx_packets) + RX_PACKETS_BEFORE=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/rx_packets) + TX_PACKETS_BEFORE=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/tx_packets) sleep 1 - RX_PACKETS_AFTER=$(cat /sys/class/net/$XBEE_NET_IFACE_NAME/statistics/rx_packets) - TX_PACKETS_AFTER=$(cat /sys/class/net/$XBEE_NET_IFACE_NAME/statistics/tx_packets) + RX_PACKETS_AFTER=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/rx_packets) + TX_PACKETS_AFTER=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/tx_packets) RX_DIFF=$((RX_PACKETS_AFTER - RX_PACKETS_BEFORE)) TX_DIFF=$((TX_PACKETS_AFTER - TX_PACKETS_BEFORE)) if [[ $RX_DIFF -gt 0 ]]; then - for packet in $(seq 1 $RX_DIFF); do - SRC_MAC=$(cat /sys/class/net/$XBEE_NET_IFACE_NAME/address) - SRC_IP=$(ip -o -4 addr show $XBEE_NET_IFACE_NAME | awk '{print $4}' | cut -d/ -f1) - - # Assuming destination info is available - DST_IP=$(ip neighbor show dev $XBEE_NET_IFACE_NAME | grep -oP '((\d+\.){3}\d+)' | head -n 1) - DST_MAC=$(ip neighbor show dev $XBEE_NET_IFACE_NAME | grep -oP '([a-f0-9]{2}:){5}[a-f0-9]{2}' | head -n 1) - - # Capture payload data (in hex format for simplicity) - PAYLOAD=$(cat /proc/net/dev_snmp6/$XBEE_NET_IFACE_NAME | hexdump -C | head -n 1) - - echo "******************************************************************" - echo "$(date +'%Y-%m-%d %H:%M:%S')" - echo "$packet packets received on $XBEE_NET_IFACE_NAME" - echo "Src: { IP: $SRC_IP, MAC: $SRC_MAC }" - echo "Dst: { IP: $DST_IP, MAC: $DST_MAC }" - echo "Length: $(echo "$PAYLOAD" | wc -c) bytes" - echo "Payload: $PAYLOAD" - echo "******************************************************************" - done + echo "$(date +'%Y-%m-%d %H:%M:%S') - $RX_DIFF packets received on $XBNET_INTERFACE_NAME" + log_packet_info "received" fi if [[ $TX_DIFF -gt 0 ]]; then - for packet in $(seq 1 $TX_DIFF); do - SRC_MAC=$(cat /sys/class/net/$XBEE_NET_IFACE_NAME/address) - SRC_IP=$(ip -o -4 addr show $XBEE_NET_IFACE_NAME | awk '{print $4}' | cut -d/ -f1) - - # Assuming destination info is available - DST_IP=$(ip neighbor show dev $XBEE_NET_IFACE_NAME | grep -oP '((\d+\.){3}\d+)' | head -n 1) - DST_MAC=$(ip neighbor show dev $XBEE_NET_IFACE_NAME | grep -oP '([a-f0-9]{2}:){5}[a-f0-9]{2}' | head -n 1) - - # Capture payload data (in hex format for simplicity) - PAYLOAD=$(cat /proc/net/dev_snmp6/$XBEE_NET_IFACE_NAME | hexdump -C | head -n 1) - - echo "******************************************************************" - echo "$(date +'%Y-%m-%d %H:%M:%S')" - echo "$packet packets sent on $XBEE_NET_IFACE_NAME" - echo "Src: { IP: $SRC_IP, MAC: $SRC_MAC }" - echo "Dst: { IP: $DST_IP, MAC: $DST_MAC }" - echo "Length: $(echo "$PAYLOAD" | wc -c) bytes" - echo "Payload: $PAYLOAD" - echo "******************************************************************" - done + echo "$(date +'%Y-%m-%d %H:%M:%S') - $TX_DIFF packets sent on $XBNET_INTERFACE_NAME" + log_packet_info "sent" fi done } +# Function to log detailed packet information +log_packet_info() { + local direction=$1 + local ip_info + + # Example: Check /proc/net/arp for the associated IP and MAC addresses + ip_info=$(ip -br addr show $XBNET_INTERFACE_NAME) + src_ip=$(echo "$ip_info" | awk '{print $3}' | cut -d '/' -f 1) + src_mac=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/address) + + dst_info=$(ip neigh show dev $XBNET_INTERFACE_NAME | grep -v REACHABLE | head -n 1) + dst_ip=$(echo "$dst_info" | awk '{print $1}') + dst_mac=$(echo "$dst_info" | awk '{print $5}') + + echo "******************************************************************" + echo "$(date +'%Y-%m-%d %H:%M:%S') - Packet $direction on $XBNET_INTERFACE_NAME" + echo "Src: { IP: $src_ip, MAC: $src_mac }" + echo "Dst: { IP: $dst_ip, MAC: $dst_mac }" + + # Log packet length and a placeholder for payload (real payload extraction requires deep packet inspection) + length=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/tx_bytes) + echo "Length: ${length} bytes" + + # Placeholder for payload (not feasible to extract without raw packet inspection) + echo "Payload: [Payload extraction requires raw packet inspection tools]" + echo "******************************************************************" +} + + # Clean up resources and exit the script cleanup() { echo "Cleaning up resources..." pkill -f "xbnet -d --serial-speed $XBEE_BAUDRATE $XBEE_PORT tap" - if ip link show $XBEE_NET_IFACE_NAME > /dev/null 2>&1; then - ip link set $XBEE_NET_IFACE_NAME down - ip link delete $XBEE_NET_IFACE_NAME + if ip link show $XBNET_INTERFACE_NAME > /dev/null 2>&1; then + ip link set $XBNET_INTERFACE_NAME down + ip link delete $XBNET_INTERFACE_NAME fi } diff --git a/scripts/set-env-vars.sh b/scripts/set-env-vars.sh new file mode 100755 index 0000000..4571acb --- /dev/null +++ b/scripts/set-env-vars.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# set-env-vars.sh +# +# This script sets up the environment for running a Docker Compose configuration with XBee networks. + +# Export the values set in the Docker Compose environment +export XBEE_INDEX=${XBEE_INDEX} +export XBEE_BAUDRATE=${XBEE_BAUDRATE} +export XBEE_PORT=${XBEE_PORT} +export XBNET_BASE_SUBNET=${XBNET_BASE_SUBNET} +export XBNET_INTERFACE_TYPE=${XBNET_INTERFACE_TYPE} # Options: ["gateway", "router"] + +# Determine the source IP based on interface type +if [ "$XBNET_INTERFACE_TYPE" = "gateway" ]; then + XBNET_IP="${XBNET_BASE_SUBNET}.1" + XBNET_INTERFACE_NAME="xbnet_gateway" +else + XBNET_IP="${XBNET_BASE_SUBNET}.20${XBEE_INDEX}" + XBNET_INTERFACE_NAME="xbnet_router_${XBEE_INDEX}" +fi + +# Export the renamed variables +export XBNET_DEFAULT_GATEWAY="${XBNET_BASE_SUBNET}.1" +export XBNET_DEFAULT_IPVLAN_IP="${XBNET_BASE_SUBNET}.20" +export XBNET_DEFAULT_MACVLAN_IP="${XBNET_BASE_SUBNET}.30" +export XBNET_IP +export XBNET_INTERFACE_NAME + +# Print out values of environment variables +echo "***********************************************************" +echo "Environment variables set. " +echo "XBEE_INDEX : ${XBEE_INDEX}" +echo "XBEE_BAUDRATE : ${XBEE_BAUDRATE}" +echo "XBEE_PORT : ${XBEE_PORT}" +echo "XBNET_BASE_SUBNET : ${XBNET_BASE_SUBNET}" +echo "XBNET_IP : ${XBNET_IP}" +echo "XBNET_INTERFACE_NAME : ${XBNET_INTERFACE_NAME}" +echo "XBNET_DEFAULT_IPVLAN_IP : ${XBNET_DEFAULT_IPVLAN_IP}" +echo "XBNET_DEFAULT_MACVLAN_IP : ${XBNET_DEFAULT_MACVLAN_IP}" +echo "***********************************************************" + From 23b30416b582cfbecea5e21eb4e9b7ece3c53c53 Mon Sep 17 00:00:00 2001 From: Emran Billah Date: Wed, 4 Sep 2024 14:26:59 -0300 Subject: [PATCH 2/4] Added production quality docker compose file with environment vars set in the docker compose file, without using env vars, updated docs, separated out run-single and run-multiple --- .env | 13 +++--- Dockerfile | 6 +-- README.md | 46 ++++++++++++------- ...yml => docker-compose-run-multiple-dev.yml | 0 ...e.yml => docker-compose-run-single-dev.yml | 9 +--- docker-compose.yml | 15 ++++++ ...ate_tap_device.sh => create-tap-device.sh} | 0 ...oy_tap_device.sh => destroy-tap-device.sh} | 0 ...host_macvlan.sh => enable-host-macvlan.sh} | 0 .../debug/{host_setup.sh => host-setup.sh} | 0 scripts/entrypoint.sh | 36 ++++++++------- ...ifi_info.sh => get-connected-wifi-info.sh} | 0 scripts/{health_check.sh => health-check.sh} | 0 scripts/set-env-vars.sh | 32 +++++++------ 14 files changed, 95 insertions(+), 62 deletions(-) rename docker-compose-run-multiple.yml => docker-compose-run-multiple-dev.yml (100%) rename docker-compose-run-single.yml => docker-compose-run-single-dev.yml (92%) create mode 100644 docker-compose.yml rename scripts/debug/{create_tap_device.sh => create-tap-device.sh} (100%) rename scripts/debug/{destroy_tap_device.sh => destroy-tap-device.sh} (100%) rename scripts/debug/{enable_host_macvlan.sh => enable-host-macvlan.sh} (100%) rename scripts/debug/{host_setup.sh => host-setup.sh} (100%) rename scripts/{get_connected_wifi_info.sh => get-connected-wifi-info.sh} (100%) rename scripts/{health_check.sh => health-check.sh} (100%) diff --git a/.env b/.env index 23de14a..b686547 100755 --- a/.env +++ b/.env @@ -1,14 +1,15 @@ # Base params -XBNET_BASE_SUBNET=3.3.3 +XBNET_BASE_SUBNET=2.2.2 XBEE_INDEX=1 +XBNET_PROTO=tap # Default params -XBNET_DEFAULT_GATEWAY=3.3.3.1 -XBNET_DEFAULT_IPVLAN_IP=3.3.3.20 # Required only when running ipvlan net (look in docker compose) -XBNET_DEFAULT_MACVLAN_IP=3.3.3.30 # Required only when running macvlan net (look in docker compose) +XBNET_DEFAULT_GATEWAY=2.2.2.1 +XBNET_DEFAULT_IPVLAN_IP=2.2.2.20 # Required only when running ipvlan net (look in docker compose) +XBNET_DEFAULT_MACVLAN_IP=2.2.2.30 # Required only when running macvlan net (look in docker compose) # Configuration for xbnet XBEE_PORT=/dev/ttyUSB0 XBEE_BAUDRATE=230400 -XBNET_IP=3.3.3.201 # Set based on interface type -XBNET_INTERFACE_NAME=xbnet_router_1 # Set based on interface type +XBNET_IP=2.2.2.201 # Set based on interface type +XBNET_INTERFACE_NAME=xbnet_router_1 # Set based on interface type diff --git a/Dockerfile b/Dockerfile index 29a0361..fbcaeff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,8 +35,8 @@ COPY ./scripts/set-env-vars.sh /set-env-vars.sh RUN chmod +x /set-env-vars.sh # Copy the health check script -COPY ./scripts/health_check.sh /health_check.sh -RUN chmod +x /health_check.sh +COPY ./scripts/health-check.sh /health-check.sh +RUN chmod +x /health-check.sh # Add healthcheck -HEALTHCHECK CMD /health_check.sh || exit 1 +HEALTHCHECK CMD /health-check.sh || exit 1 diff --git a/README.md b/README.md index 2808ab1..374ee76 100644 --- a/README.md +++ b/README.md @@ -65,19 +65,30 @@ git clone https://git.spirirobotics.com/Spiri/services-xbee_net cd services-xbee_net ``` -#### 2. Run a single xbnet node using the following cmd: +#### 2. To run the project in `PRODUCTION` mode, use the following cmd: + +- `docker-compose -f docker-compose.yml up --build` + +- Configure the project for user specs, modify the `docker-compose.yml` file for the following parameters: + + ```bash + environment: + - XBEE_INDEX=1 + - XBEE_BAUDRATE=230400 + - XBEE_PORT=/dev/ttyUSB0 + - XBNET_BASE_SUBNET=2.2.2 + - XBNET_INTERFACE_TYPE=router # ["router" | "gateway"] + - XBNET_PROTO=tap # ["tap" | "tun"] + ``` + +#### 3. To run a single xbnet node in `DEVELOPEMENT` mode, use the following cmd: - Router mode: `sh ./run-single.sh --subnet=7.7.7 --serial-speed=230400 --port=/dev/ttyUSB0 --interface-type=router` - Gateway mode: `sh ./run-single.sh --subnet=7.7.7 --serial-speed=230400 --port=/dev/ttyUSB0 --interface-type=gateway` -##### NOTE: This setup assumes that you have an XBee device connected to port: /dev/ttyUSB0 +#### OR Manually build and Start the Docker Container +NOTE: This will require the config `.env` to be manually modified, based on user needs. - -#### 3. OR Manually build and Start the Docker Container - -##### NOTE: This will require the config `.env` to be manually modified, based on user needs. - ---- - Configure a single xbnet net service using: ```bash @@ -91,6 +102,14 @@ cd services-xbee_net DEFAULT_GATEWAY=192.168.1.1 ``` +#### 4. To run a multiple xbnet nodes in `DEVELOPEMENT` mode, use the following cmd: + +- Router 1: `sh ./run-multiple.sh --index=1 --subnet=7.7.7 --serial-speed=230400 --port=/dev/ttyUSB0 --interface-type=router` +- Router 2: `sh ./run-multiple.sh --index=2 --subnet=7.7.7 --serial-speed=230400 --port=/dev/ttyUSB0 --interface-type=router` +- Gateway: `sh ./run-multiple.sh --subnet=7.7.7 --serial-speed=230400 --port=/dev/ttyUSB0 --interface-type=gateway` + +NOTE: This will require the config `.env` to be manually modified, based on user needs. + - Configure multiple xbnet net services using: ```bash @@ -109,22 +128,15 @@ cd services-xbee_net # Default Gateway (REQUIRED: part of minimum concifg to run a single xbnet node) DEFAULT_GATEWAY=192.168.1.1 ``` ---- - -To build the Docker image and start the container, run: - -```bash -docker-compose -f docker-compose.yml up --build -``` This will build the Docker image and start the container with the XBee network and the required setup. -#### 4. Health Check and Container Management +#### 5. Health Check and Container Management The container includes a health check that pings the XBee network interface to ensure it is functioning properly. \ The container is configured to restart automatically if the health check fails. -#### 5. Troubleshooting +#### 6. Troubleshooting Ensure the XBee devices are connected to the correct serial ports.\ Verify the network interfaces using ip a inside the container.\ diff --git a/docker-compose-run-multiple.yml b/docker-compose-run-multiple-dev.yml similarity index 100% rename from docker-compose-run-multiple.yml rename to docker-compose-run-multiple-dev.yml diff --git a/docker-compose-run-single.yml b/docker-compose-run-single-dev.yml similarity index 92% rename from docker-compose-run-single.yml rename to docker-compose-run-single-dev.yml index 75c8583..1b1539a 100644 --- a/docker-compose-run-single.yml +++ b/docker-compose-run-single-dev.yml @@ -67,13 +67,8 @@ services: build: . container_name: xbnet_node privileged: true - # env_file: .env - environment: - - XBEE_INDEX=1 - - XBEE_BAUDRATE=230400 - - XBEE_PORT=/dev/ttyUSB0 - - XBNET_BASE_SUBNET=7.7.7 - - XBNET_INTERFACE_TYPE=router + env_file: + - .env command: bash /entrypoint.sh # network_mode: "host" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e18ddf3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3.8' + +services: + xbnet-node: + build: . + container_name: xbnet_node + privileged: true + environment: + - XBEE_INDEX=1 + - XBEE_BAUDRATE=230400 + - XBEE_PORT=/dev/ttyUSB0 + - XBNET_BASE_SUBNET=2.2.2 + - XBNET_INTERFACE_TYPE=router + - XBNET_PROTO=tap + command: bash /entrypoint.sh \ No newline at end of file diff --git a/scripts/debug/create_tap_device.sh b/scripts/debug/create-tap-device.sh similarity index 100% rename from scripts/debug/create_tap_device.sh rename to scripts/debug/create-tap-device.sh diff --git a/scripts/debug/destroy_tap_device.sh b/scripts/debug/destroy-tap-device.sh similarity index 100% rename from scripts/debug/destroy_tap_device.sh rename to scripts/debug/destroy-tap-device.sh diff --git a/scripts/debug/enable_host_macvlan.sh b/scripts/debug/enable-host-macvlan.sh similarity index 100% rename from scripts/debug/enable_host_macvlan.sh rename to scripts/debug/enable-host-macvlan.sh diff --git a/scripts/debug/host_setup.sh b/scripts/debug/host-setup.sh similarity index 100% rename from scripts/debug/host_setup.sh rename to scripts/debug/host-setup.sh diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index d502308..18b346b 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -14,10 +14,11 @@ echo "Starting entrypoint.sh" # Set associated env vars echo "Setting associated environment variables. Calling /set-env-vars.sh" -sh /set-env-vars.sh +source /set-env-vars.sh # Main loop loop() { + echo "Starting loop" while true; do # Check if the XBee device is connected check_device_port @@ -26,7 +27,6 @@ loop() { cleanup continue fi - sleep 0.5 # Check if the network interface is up check_network_state @@ -34,11 +34,10 @@ loop() { echo "Network interface $XBNET_INTERFACE_NAME not found. Creating TAP interface..." create_tap_interface fi - sleep 0.5 # Log messages sent and received over xbnet # log_xbnet_messages - + sleep 0.5 done } @@ -63,8 +62,9 @@ check_network_state() { # Create a TAP network interface create_tap_interface() { - # Start xbnet and run it in the background - xbnet -d --serial-speed ${XBEE_BAUDRATE} ${XBEE_PORT} tap --iface-name ${XBNET_INTERFACE_NAME} & + # Start xbnet and run it in the background + # - eg. xbnet -d --serial-speed 230400 /dev/ttyUSB0 tap --iface-name=xbnet_router_1 + xbnet -d --serial-speed ${XBEE_BAUDRATE} ${XBEE_PORT} ${XBNET_PROTO} --iface-name ${XBNET_INTERFACE_NAME} & # Wait until the interface is created while ! check_network_state; do @@ -75,15 +75,19 @@ create_tap_interface() { ip addr add $XBNET_IP/24 dev $XBNET_INTERFACE_NAME ip link set $XBNET_INTERFACE_NAME up - echo "-------------------------------------------" - echo "********** Tap interface created **********" - echo "-------------------------------------------" - echo "Name: ${XBNET_INTERFACE_NAME}" - echo "Gateway: ${DEFAULT_GATEWAY}" - echo "IP: ${XBNET_IP}" - echo "Device port: ${XBEE_PORT}" - echo "Device baudrate: ${XBEE_BAUDRATE}" - echo "-------------------------------------------" + echo "---------------------------------------------------------" + echo "***************** Tap interface created *****************" + echo "---------------------------------------------------------" + echo "XBEE_INDEX : ${XBEE_INDEX}" + echo "XBEE_BAUDRATE : ${XBEE_BAUDRATE}" + echo "XBEE_PORT : ${XBEE_PORT}" + echo "XBNET_BASE_SUBNET : ${XBNET_BASE_SUBNET}" + echo "XBNET_IP : ${XBNET_IP}" + echo "XBNET_INTERFACE_NAME : ${XBNET_INTERFACE_NAME}" + echo "XBNET_DEFAULT_GATEWAY : ${XBNET_DEFAULT_GATEWAY}" + echo "XBNET_DEFAULT_IPVLAN_IP : ${XBNET_DEFAULT_IPVLAN_IP}" + echo "XBNET_DEFAULT_MACVLAN_IP : ${XBNET_DEFAULT_MACVLAN_IP}" + echo "---------------------------------------------------------" return 0 } @@ -107,7 +111,7 @@ log_xbnet_messages() { RX_PACKETS_BEFORE=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/rx_packets) TX_PACKETS_BEFORE=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/tx_packets) - sleep 1 + sleep 0.5 RX_PACKETS_AFTER=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/rx_packets) TX_PACKETS_AFTER=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/tx_packets) diff --git a/scripts/get_connected_wifi_info.sh b/scripts/get-connected-wifi-info.sh similarity index 100% rename from scripts/get_connected_wifi_info.sh rename to scripts/get-connected-wifi-info.sh diff --git a/scripts/health_check.sh b/scripts/health-check.sh similarity index 100% rename from scripts/health_check.sh rename to scripts/health-check.sh diff --git a/scripts/set-env-vars.sh b/scripts/set-env-vars.sh index 4571acb..7526cc5 100755 --- a/scripts/set-env-vars.sh +++ b/scripts/set-env-vars.sh @@ -9,7 +9,8 @@ export XBEE_INDEX=${XBEE_INDEX} export XBEE_BAUDRATE=${XBEE_BAUDRATE} export XBEE_PORT=${XBEE_PORT} export XBNET_BASE_SUBNET=${XBNET_BASE_SUBNET} -export XBNET_INTERFACE_TYPE=${XBNET_INTERFACE_TYPE} # Options: ["gateway", "router"] +export XBNET_INTERFACE_TYPE=${XBNET_INTERFACE_TYPE} # Options: ["gateway", "router"] +export XBNET_PROTO=tap # Options: ["tap", "tun"] # Determine the source IP based on interface type if [ "$XBNET_INTERFACE_TYPE" = "gateway" ]; then @@ -27,16 +28,21 @@ export XBNET_DEFAULT_MACVLAN_IP="${XBNET_BASE_SUBNET}.30" export XBNET_IP export XBNET_INTERFACE_NAME -# Print out values of environment variables -echo "***********************************************************" -echo "Environment variables set. " -echo "XBEE_INDEX : ${XBEE_INDEX}" -echo "XBEE_BAUDRATE : ${XBEE_BAUDRATE}" -echo "XBEE_PORT : ${XBEE_PORT}" -echo "XBNET_BASE_SUBNET : ${XBNET_BASE_SUBNET}" -echo "XBNET_IP : ${XBNET_IP}" -echo "XBNET_INTERFACE_NAME : ${XBNET_INTERFACE_NAME}" -echo "XBNET_DEFAULT_IPVLAN_IP : ${XBNET_DEFAULT_IPVLAN_IP}" -echo "XBNET_DEFAULT_MACVLAN_IP : ${XBNET_DEFAULT_MACVLAN_IP}" -echo "***********************************************************" +# Print out environment variables +print_env_vars() { + echo "***********************************************************" + echo "Environment variables set. " + echo "XBEE_INDEX : ${XBEE_INDEX}" + echo "XBEE_BAUDRATE : ${XBEE_BAUDRATE}" + echo "XBEE_PORT : ${XBEE_PORT}" + echo "XBNET_BASE_SUBNET : ${XBNET_BASE_SUBNET}" + echo "XBNET_IP : ${XBNET_IP}" + echo "XBNET_INTERFACE_NAME : ${XBNET_INTERFACE_NAME}" + echo "XBNET_DEFAULT_IPVLAN_IP : ${XBNET_DEFAULT_IPVLAN_IP}" + echo "XBNET_DEFAULT_MACVLAN_IP : ${XBNET_DEFAULT_MACVLAN_IP}" + echo "***********************************************************" +} + +# print_env_vars + From 96c6f641b84a9b4536e5c8a3d4b78cf283e92c0c Mon Sep 17 00:00:00 2001 From: Emran Billah Date: Wed, 4 Sep 2024 14:43:25 -0300 Subject: [PATCH 3/4] Added docker run cmd to README.md for intergrating with TX2 --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 374ee76..3cf8e5a 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,20 @@ cd services-xbee_net - XBNET_PROTO=tap # ["tap" | "tun"] ``` +- This can also be run using the `docker run` cmd shown below. + + ```bash + docker run -d --name xbnet_node \ + --privileged \ + -e XBEE_INDEX=1 \ + -e XBEE_BAUDRATE=230400 \ + -e XBEE_PORT=/dev/ttyUSB0 \ + -e XBNET_BASE_SUBNET=2.2.2 \ + -e XBNET_INTERFACE_TYPE=router \ + -e XBNET_PROTO=tap \ + xbnet_node bash /entrypoint.sh + ``` + #### 3. To run a single xbnet node in `DEVELOPEMENT` mode, use the following cmd: - Router mode: `sh ./run-single.sh --subnet=7.7.7 --serial-speed=230400 --port=/dev/ttyUSB0 --interface-type=router` From 9f1319850bb100d60456e7b5926a414a983965c9 Mon Sep 17 00:00:00 2001 From: Emran Billah Date: Thu, 5 Sep 2024 10:11:34 -0300 Subject: [PATCH 4/4] Refactored environment vars into docker compose instead of using env vars, working on ssh and bridging wifi to xbnet, reviewing with Giovanni --- Dockerfile | 4 +++ docker-compose.yml | 17 ++++++++++-- scripts/debug/host-setup-docker.sh | 44 ++++++++++++++++++++++++++++++ scripts/debug/test.py | 18 ++++++++++++ scripts/entrypoint.sh | 14 ++++++---- serial | 0 subprocess | 0 7 files changed, 89 insertions(+), 8 deletions(-) create mode 100755 scripts/debug/host-setup-docker.sh create mode 100755 scripts/debug/test.py create mode 100644 serial create mode 100644 subprocess diff --git a/Dockerfile b/Dockerfile index fbcaeff..8e38399 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,5 +38,9 @@ RUN chmod +x /set-env-vars.sh COPY ./scripts/health-check.sh /health-check.sh RUN chmod +x /health-check.sh +# TEST +COPY ./scripts/debug/host-setup-docker.sh /host-setup-docker.sh +RUN chmod +x /host-setup-docker.sh + # Add healthcheck HEALTHCHECK CMD /health-check.sh || exit 1 diff --git a/docker-compose.yml b/docker-compose.yml index e18ddf3..ea5ad1b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,18 @@ services: - XBEE_INDEX=1 - XBEE_BAUDRATE=230400 - XBEE_PORT=/dev/ttyUSB0 - - XBNET_BASE_SUBNET=2.2.2 + - XBNET_BASE_SUBNET=172.18.0 - XBNET_INTERFACE_TYPE=router - - XBNET_PROTO=tap - command: bash /entrypoint.sh \ No newline at end of file + - XBNET_PROTO=tun + command: bash /entrypoint.sh + networks: + eth0: + ipv4_address: 172.18.0.100 + +networks: + # Assigning a static IP to eth0 interface, so that it stays the same everytime the container is started + eth0: + ipam: + config: + - subnet: 172.18.0.0/24 + gateway: 172.18.0.1 \ No newline at end of file diff --git a/scripts/debug/host-setup-docker.sh b/scripts/debug/host-setup-docker.sh new file mode 100755 index 0000000..dc9c2b0 --- /dev/null +++ b/scripts/debug/host-setup-docker.sh @@ -0,0 +1,44 @@ +#!/bin/sh -e +# IP forwarding and NAT rules + +# Default host IP +HOST_IP="" + +# Parse command line argument for --host-ip +for arg in "$@"; do + case $arg in + --host-ip=*) + HOST_IP="${arg#*=}" + shift + ;; + *) + echo "Unknown argument: $arg" + exit 1 + ;; + esac +done + +# If HOST_IP is not set, fetch the IP address of the eth0 interface +if [ -z "$HOST_IP" ]; then + HOST_IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') + if [ -z "$HOST_IP" ]; then + echo "Error: Could not retrieve IP from eth0" + exit 1 + fi + echo "No --host-ip provided. Using eth0 IP: $HOST_IP" +else + echo "Using provided --host-ip: $HOST_IP" +fi + +# Enable IP forwarding +echo 1 > /proc/sys/net/ipv4/ip_forward + +# Set iptables rules for NAT and forwarding +iptables -t nat -A POSTROUTING -s 2.2.2.0/24 -o eth0 -j MASQUERADE +iptables -A FORWARD -i xbnet_router_1 -o eth0 -j ACCEPT +iptables -A FORWARD -i eth0 -o xbnet_router_1 -m state --state RELATED,ESTABLISHED -j ACCEPT + +# Ensure the xbnet_router_1 interface has a default route through eth0 +ip route add default via $(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') dev xbnet_router_1 + +exit 0 diff --git a/scripts/debug/test.py b/scripts/debug/test.py new file mode 100755 index 0000000..44f54cc --- /dev/null +++ b/scripts/debug/test.py @@ -0,0 +1,18 @@ +import serial +import subprocess + +# Set up serial connection (adjust serial port to match your configuration) +ser = serial.Serial('/dev/ttyUSB0', 230400) + +# Function to send command to XBee +def send_command(command): + ser.write((command + '\r\n').encode()) + +# Function to ping from the Raspberry Pi +def ping_address(address): + response = subprocess.run(['ping', '-c', '5', address], capture_output=True) + return response.stdout.decode() + +# Example usage +send_command('Hello XBee') # Sending data to XBee +print(ping_address('8.8.8.8')) # Pinging Google DNS from Pi \ No newline at end of file diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 18b346b..a91b923 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -36,7 +36,7 @@ loop() { fi # Log messages sent and received over xbnet - # log_xbnet_messages + log_xbnet_messages sleep 0.5 done @@ -72,11 +72,14 @@ create_tap_interface() { done # Create and bring up xbnet interface + ip route add default via 172.18.0.1 dev $XBNET_INTERFACE_NAME ip addr add $XBNET_IP/24 dev $XBNET_INTERFACE_NAME ip link set $XBNET_INTERFACE_NAME up + ip link show $XBNET_INTERFACE_NAME + ip addr show $XBNET_INTERFACE_NAME echo "---------------------------------------------------------" - echo "***************** Tap interface created *****************" + echo "************ ${XBNET_PROTO} interface created ************" echo "---------------------------------------------------------" echo "XBEE_INDEX : ${XBEE_INDEX}" echo "XBEE_BAUDRATE : ${XBEE_BAUDRATE}" @@ -84,6 +87,7 @@ create_tap_interface() { echo "XBNET_BASE_SUBNET : ${XBNET_BASE_SUBNET}" echo "XBNET_IP : ${XBNET_IP}" echo "XBNET_INTERFACE_NAME : ${XBNET_INTERFACE_NAME}" + echo "XBNET_PROTO : ${XBNET_PROTO}" echo "XBNET_DEFAULT_GATEWAY : ${XBNET_DEFAULT_GATEWAY}" echo "XBNET_DEFAULT_IPVLAN_IP : ${XBNET_DEFAULT_IPVLAN_IP}" echo "XBNET_DEFAULT_MACVLAN_IP : ${XBNET_DEFAULT_MACVLAN_IP}" @@ -154,9 +158,9 @@ log_packet_info() { length=$(cat /sys/class/net/$XBNET_INTERFACE_NAME/statistics/tx_bytes) echo "Length: ${length} bytes" - # Placeholder for payload (not feasible to extract without raw packet inspection) - echo "Payload: [Payload extraction requires raw packet inspection tools]" - echo "******************************************************************" + # # Placeholder for payload (not feasible to extract without raw packet inspection) + # echo "Payload: [Payload extraction requires raw packet inspection tools]" + # echo "******************************************************************" } diff --git a/serial b/serial new file mode 100644 index 0000000..e69de29 diff --git a/subprocess b/subprocess new file mode 100644 index 0000000..e69de29