diff --git a/.env b/.env index cdb7254..2c5407e 100755 --- a/.env +++ b/.env @@ -1,16 +1,14 @@ +# Base params +BASE_SUBNET=192.168.1 +XBEE_INDEX=1 + +# Default params +DEFAULT_GATEWAY=192.168.1.1 +DEFAULT_IPVLAN_IP=192.168.1.20 # Required only when running ipvlan net (look in docker compose) +DEFAULT_MACVLAN_IP=192.168.1.30 # Required only when running macvlan net (look in docker compose) + # Configuration for xbnet0 -XBEE0_PORT=/dev/ttyUSB0 -XBEE0_BAUDRATE=230400 -XBEE0_NET_SRC_IP=192.168.1.10 # Ensure this IP matches the macvlan network in Docker Compose -XBEE0_NET_DST_IP=192.168.1.11 # Ensure this IP matches the network range -XBEE0_NET_IFACE_NAME=xbnet0 - -# Configuration for xbnet1 -XBEE1_PORT=/dev/ttyUSB1 -XBEE1_BAUDRATE=230400 -XBEE1_NET_SRC_IP=192.168.1.11 # Note: This requires the subnet 192.168.1... (to match with the default gateway, or use Masquerade if changing the subnet) -XBEE1_NET_DST_IP=192.168.1.10 # Note: This requires the subnet 192.168.1... (to match with the default gateway, or use Masquerade if changing the subnet) -XBEE1_NET_IFACE_NAME=xbnet1 - -# Default Gateway -DEFAULT_GATEWAY=192.168.1.1 \ No newline at end of file +XBEE_PORT=/dev/ttyUSB0 +XBEE_BAUDRATE=230400 +XBEE_NET_SRC_IP=192.168.1.201 # Ensure this IP matches the network range +XBEE_NET_IFACE_NAME=xbnet0 diff --git a/.gitignore b/.gitignore index e69de29..f198160 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +workspace \ No newline at end of file diff --git a/README.md b/README.md index 9058598..4a5bdc4 100644 --- a/README.md +++ b/README.md @@ -23,14 +23,14 @@   -# SERVICES-XBEE-NET +# SERVICES-XBEE_NET This project contains a Dockerized setup to create and manage an XBee network using the `xbnet` utility. The network interface is bridged with a host Wi-Fi interface, enabling internet access for connected devices. ##### Note: This project uses the `tap` xbnet protocol, which is a layer 2 protocol. This supports full ethernet pipeline. For a simple IP level protocol support, the `tun` xbnet protocol can be used. ## File Structure -``` -services-xbee-net/ +```bash +services-xbee_net/ ├── scripts/ │ ├── entrypoint.sh # Entrypoint script for Docker container │ ├── get_connected_wifi_info.sh # Script to fetch connected Wi-Fi device information @@ -55,40 +55,54 @@ Ensure Docker and Docker Compose are installed on your machine. ## Getting Started -### 1. Clone the Repository +#### 1. Clone the Repository ```bash -git clone https://github.com/your-username/services-xbee_net.git +git clone https://git.spirirobotics.com/Spiri/services-xbee_net cd services-xbee_net ``` -### 2. Modify the `.env` File +#### 2. Modify `.env-...` File based on running single or multiple xbnets The `.env` file contains the configuration parameters for the XBee network. You may need to update these parameters according to your specific setup. -- For a single xbnet setup, modify all the `XBEE0` params only -- For multi xbnet setup, add similar config chunks like `XBEE1` +- For a single xbnet setup, modify params in the `.env-run-single` +- For multi xbnet setup, modify params in the `.env-run-multiple` #### (Note: Multi node xbnet setup is currently under progress) +--- +##### a. Sample `.env-run-single` config: ```bash # Configuration for xbnet0 -XBEE0_PORT=/dev/ttyUSB0 # The serial port for the XBee device -XBEE0_BAUDRATE=230400 # Baud rate for the XBee device -XBEE0_NET_SRC_IP=192.168.1.10 # Source IP for the XBee network -XBEE0_NET_DST_IP=192.168.1.11 # Destination IP for the XBee network -XBEE0_NET_IFACE_NAME=xbnet0 # Interface name for the XBee network - -# Configuration for xbnet1 -XBEE1_PORT=/dev/ttyUSB1 -XBEE1_BAUDRATE=230400 -XBEE1_NET_SRC_IP=192.168.1.11 -XBEE1_NET_DST_IP=192.168.1.10 -XBEE1_NET_IFACE_NAME=xbnet1 +XBEE_PORT=/dev/ttyUSB0 +XBEE_BAUDRATE=230400 +XBEE_NET_SRC_IP=192.168.1.100 # Ensure this IP matches the network range +XBEE_NET_IFACE_NAME=xbnet0 # Default Gateway DEFAULT_GATEWAY=192.168.1.1 ``` -### 3. Build and Start the Docker Container +##### b. Sample `.env-run-multiple` config: +```bash +# Configuration for xbnet0 (REQUIRED: minimum config to run a single xbnet node) +XBEE0_PORT=/dev/ttyUSB0 # The serial port for the XBee device +XBEE0_BAUDRATE=230400 # Baud rate for the XBee device +XBEE0_NET_SRC_IP=192.168.1.100 # Source IP for the XBee network +XBEE0_NET_IFACE_NAME=xbnet0 # Interface name for the XBee network + +# Configuration for xbnet1 (OPTIONAL: only required for multi node xbnets) +XBEE1_PORT=/dev/ttyUSB1 +XBEE1_BAUDRATE=230400 +XBEE1_NET_SRC_IP=192.168.1.101 +XBEE1_NET_IFACE_NAME=xbnet1 + +# Default Gateway (REQUIRED: part of minimum concifg to run a single xbnet node) +DEFAULT_GATEWAY=192.168.1.1 +``` +--- + + +#### 3. Build and Start the Docker Container To build the Docker image and start the container, run: @@ -98,14 +112,15 @@ 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 +#### 4. 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. +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 +#### 5. Troubleshooting -Ensure the XBee devices are connected to the correct serial ports. -Verify the network interfaces using ip a inside the container. +Ensure the XBee devices are connected to the correct serial ports.\ +Verify the network interfaces using ip a inside the container.\ The container logs can be viewed using: ```bash diff --git a/docker-compose-run-multiple.yml b/docker-compose-run-multiple.yml index a0264fa..5872d42 100644 --- a/docker-compose-run-multiple.yml +++ b/docker-compose-run-multiple.yml @@ -10,7 +10,7 @@ services: container_name: xbnet0 privileged: true env_file: - - .env + - .env-run-multiple devices: - "${XBEE0_PORT}:${XBEE0_PORT}" command: > diff --git a/docker-compose.yml b/docker-compose-run-single.yml similarity index 67% rename from docker-compose.yml rename to docker-compose-run-single.yml index ee275e5..2baaaa0 100644 --- a/docker-compose.yml +++ b/docker-compose-run-single.yml @@ -1,18 +1,18 @@ version: '3.8' services: - xbee-node: + xbnet-node: build: . - container_name: xbee_node + container_name: xbnet_node privileged: true - env_file: .env + env_file: .env networks: # xbee_net: # ipv4_address: ${XBEE0_NET_SRC_IP} # Ensure this IP belongs to the xbee_net subnet ipvlan_net: - ipv4_address: 192.168.1.20 # Assign an IP within the same range as your host's Wi-Fi + ipv4_address: ${DEFAULT_IPVLAN_IP} # Assign an IP within the same range as your host's Wi-Fi # macvlan_net: - # ipv4_address: 192.168.1.20 # Assign an IP within the same range as your host's Wi-Fi + # ipv4_address: ${DEFAULT_MACVLAN_IP} # Assign an IP within the same range as your host's Wi-Fi networks: @@ -31,15 +31,15 @@ networks: parent: wlp0s20f3 # This should be your host's Wi-Fi or Ethernet interface ipam: config: - - subnet: 192.168.1.0/24 # Match the Wi-Fi network range - gateway: 192.168.1.1 # Your router's gateway + - subnet: ${BASE_SUBNET}.0/24 # Match the Wi-Fi network range + gateway: ${DEFAULT_GATEWAY} # Your router's gateway # 3. macvlan not working for some reason - macvlan_net: + # macvlan_net: # driver: macvlan # driver_opts: # parent: wlp0s20f3 # This should be your host's Wi-Fi interface # ipam: # config: - # - subnet: 192.168.1.0/24 # Match the Wi-Fi network range + # - subnet: ${BASE_SUBNET}.0/24 # Match the Wi-Fi network range # gateway: ${DEFAULT_GATEWAY} # Your router's gateway diff --git a/run-single.sh b/run-single.sh new file mode 100755 index 0000000..ee69577 --- /dev/null +++ b/run-single.sh @@ -0,0 +1,60 @@ +# run-single.sh +# +# This script sets up the environment for running a Docker Compose configuration with XBee networks. +# It accepts an optional --index= argument to specify the XBEE_INDEX value. +# If no index is provided, it defaults to 1. +# +# Usage: +# ./run-single.sh # Runs with default index (1) +# ./run-single.sh --index=2 # Runs with index 2 +# +# IPs assigned: +# BASE_SUBNET: eg.: 192.168.1 +# DEFAULT_GATEWAY: ${BASE_SUBNET}.1, eg.: 192.168.1.1 +# DEFAULT_IPVLAN_IP: ${BASE_SUBNET}.20 eg.: 192.168.1.20 +# DEFAULT_MACVLAN_IP: ${BASE_SUBNET}.30 eg.: 192.168.1.30 +# XBEE_NET_SRC_IP: ${BASE_SUBNET}.20${index} eg.: 192.168.1.201 (all Xbnets will be in the 200+ range) + +#!/bin/bash + +# Default index value +index=1 + +# Parse command-line arguments +for arg in "$@" +do + case $arg in + --index=*) + index="${arg#*=}" + shift # Remove --index= from processing + ;; + *) + ;; + esac +done + +# Set BASE_SUBNET +BASE_SUBNET="192.168.1" + +# Create a .env file with the specified parameters +cat < .env +# Base params +BASE_SUBNET=${BASE_SUBNET} +XBEE_INDEX=${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) + +# Configuration for xbnet0 +XBEE_PORT=/dev/ttyUSB0 +XBEE_BAUDRATE=230400 +XBEE_NET_SRC_IP=${BASE_SUBNET}.20${index} # Ensure this IP matches the network range +XBEE_NET_IFACE_NAME=xbnet0 +EOF + + +# Restart Docker Composes services +docker compose -f docker-compose-run-single.yml down +docker compose -f docker-compose-run-single.yml up --build diff --git a/scripts/enable_host_macvlan.sh b/scripts/enable_host_macvlan.sh index 0edb74a..7168a90 100755 --- a/scripts/enable_host_macvlan.sh +++ b/scripts/enable_host_macvlan.sh @@ -1,7 +1,30 @@ #!/bin/bash +# enable_host_macvlan.sh +# +# This script enables IP forwarding, deletes any existing `macvlan0` interface, and creates a new `macvlan0` interface +# on the dynamically detected Wi-Fi interface. It allows the Docker container to have its own IP address on the local subnet. +# +# Usage: +# ./enable_host_macvlan.sh +# +# The script will automatically determine the Wi-Fi interface name and assign an IP address to the `macvlan0` interface. +# Modify the assigned IP address if your network setup differs. + +# Source the get_connected_wifi_info.sh script to use its functions +source ./get_connected_wifi_info.sh + +# Get the Wi-Fi interface name dynamically +WIFI_DEVICE=$(get_connected_wifi_device) + +# Check if a Wi-Fi device was found +if [ -z "$WIFI_DEVICE" ]; then + echo "Error: No connected Wi-Fi device found. Exiting..." + exit 1 +fi + # Enable IP forwarding -sudo sysctl net.ipv4.ip_forward +sudo sysctl net.ipv4.ip_forward=1 # Delete the existing macvlan0 interface if it exists if ip link show macvlan0 &> /dev/null; then @@ -9,10 +32,14 @@ if ip link show macvlan0 &> /dev/null; then sudo ip link delete macvlan0 fi -# Create a new macvlan0 interface -echo "Creating macvlan0 interface..." -sudo ip link add link wlp0s20f3 macvlan0 type macvlan mode bridge -sudo ip addr add 192.168.1.100/24 dev macvlan0 # Use an IP in the same range as the container network but different from any assigned IP +# Create a new macvlan0 interface linked to the detected Wi-Fi interface +echo "Creating macvlan0 interface on $WIFI_DEVICE..." +sudo ip link add link $WIFI_DEVICE macvlan0 type macvlan mode bridge + +# Assign an IP address to the macvlan0 interface (ensure it’s unique within your network) +sudo ip addr add 192.168.1.100/24 dev macvlan0 + +# Bring the macvlan0 interface up sudo ip link set macvlan0 up -echo "macvlan0 interface created and set up successfully." +echo "macvlan0 interface created and set up successfully on $WIFI_DEVICE." diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index eef6765..219dda5 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -1,5 +1,16 @@ #!/bin/bash +# entrypoint.sh +# +# This script is responsible for setting up and maintaining an XBee network interface within a Docker container. +# It performs several key tasks, including checking for root privileges, setting up the XBee network interface, +# configuring network bridges, and monitoring both the XBee device and Wi-Fi interface for connectivity. +# The script runs in a loop to ensure continuous operation, retrying the setup process if any steps fail. +# +# Usage: +# - This script is intended to be run as the entrypoint for a Docker container. +# - Ensure that the script has executable permissions (`chmod +x entrypoint.sh`) before running it. + # Source the get_connected_wifi_info.sh script source /scripts/get_connected_wifi_info.sh @@ -18,27 +29,27 @@ check_root() { # - xbnet interface cleanup() { echo "Cleaning up resources..." - pkill -f "xbnet -d --serial-speed $XBEE0_BAUDRATE $XBEE0_PORT tap" + pkill -f "xbnet -d --serial-speed $XBEE_BAUDRATE $XBEE_PORT tap" if ip link show br0 > /dev/null 2>&1; then ip link set br0 down brctl delbr br0 fi - if ip link show $XBEE0_NET_IFACE_NAME > /dev/null 2>&1; then - ip link set $XBEE0_NET_IFACE_NAME down - ip link delete $XBEE0_NET_IFACE_NAME + 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 fi } # Function to check if the XBee device is connected # - Ensures that the XBee device is present at the specified port before proceeding check_xbee_device() { - if [ -e "$XBEE0_PORT" ]; then - echo "XBee device found at $XBEE0_PORT. Proceeding with setup..." + if [ -e "$XBEE_PORT" ]; then + echo "XBee device found at $XBEE_PORT. Proceeding with setup..." return 0 else - echo "Error: No XBee device found at $XBEE0_PORT. Please connect the device." + echo "Error: No XBee device found at $XBEE_PORT. Please connect the device." return 1 fi } @@ -48,38 +59,38 @@ check_xbee_device() { # - Verifies if the interface is successfully created and returns the appropriate status code start_xbnet_interface() { echo "Starting XBee network interface..." - xbnet -d --serial-speed $XBEE0_BAUDRATE $XBEE0_PORT tap & + xbnet -d --serial-speed $XBEE_BAUDRATE $XBEE_PORT tap & # Wait until the xbnet interface is created - while [ ! -d "/sys/class/net/$XBEE0_NET_IFACE_NAME" ]; do - echo "Waiting for interface $XBEE0_NET_IFACE_NAME to be created..." + while [ ! -d "/sys/class/net/$XBEE_NET_IFACE_NAME" ]; do + echo "Waiting for interface $XBEE_NET_IFACE_NAME to be created..." sleep 1 done # Get the xbnet interface name (e.g., xbnet0) automatically - XBEE0_NET_IFACE_NAME=$(ls /sys/class/net | grep 'xbnet') + XBEE_NET_IFACE_NAME=$(ls /sys/class/net | grep 'xbnet') # Check if the xbnet interface is found - if [ -z "$XBEE0_NET_IFACE_NAME" ]; then + if [ -z "$XBEE_NET_IFACE_NAME" ]; then echo "Error: No XBee network interface found. Retrying setup..." cleanup return 1 else - echo "XBee network interface $XBEE0_NET_IFACE_NAME created successfully." + echo "XBee network interface $XBEE_NET_IFACE_NAME created successfully." return 0 fi } # Configure the network interface and bridge -# - Creates the network interface with the name specified by XBEE0_NET_IFACE_NAME in .env file +# - Creates the network interface with the name specified by XBEE_NET_IFACE_NAME in .env file # - Creates a bridge interface and attaches the xbnet interface to it # - Brings up the bridge interface configure_network_and_bridge() { - ip addr add $XBEE0_NET_SRC_IP/24 dev $XBEE0_NET_IFACE_NAME - ip link set dev $XBEE0_NET_IFACE_NAME up + ip addr add $XBEE_NET_SRC_IP/24 dev $XBEE_NET_IFACE_NAME + ip link set dev $XBEE_NET_IFACE_NAME up brctl addbr br0 - brctl addif br0 $XBEE0_NET_IFACE_NAME + brctl addif br0 $XBEE_NET_IFACE_NAME ip link set dev br0 up } @@ -92,7 +103,7 @@ monitor_and_bridge_wifi() { HOST_WIFI_IFACE=$(get_connected_wifi_device) if [ -n "$HOST_WIFI_IFACE" ]; then - echo "Wi-Fi interface found: $HOST_WIFI_IFACE. Bridging with $XBEE0_NET_IFACE_NAME..." + echo "Wi-Fi interface found: $HOST_WIFI_IFACE. Bridging with $XBEE_NET_IFACE_NAME..." brctl addif br0 $HOST_WIFI_IFACE iptables -t nat -A POSTROUTING -o $HOST_WIFI_IFACE -j MASQUERADE @@ -112,11 +123,11 @@ monitor_and_bridge_wifi() { # - Periodically checks if the XBee device is still connected # - If the device is disconnected, triggers cleanup and restarts the setup process monitor_xbee_device() { - while [ -e "$XBEE0_PORT" ]; do + while [ -e "$XBEE_PORT" ]; do sleep 5 done - echo "XBee device at $XBEE0_PORT was removed. Cleaning up..." + echo "XBee device at $XBEE_PORT was removed. Cleaning up..." cleanup }