I am trying to control multiple ANAFI drones via a single Olympe instance running on a linux computer. I use multiple WIFI USB modems to connect to every drone.
I need every drone to have a unique IP so I can send commands and receive data streams. However, seems like every drone has a hard-coded IP and I don’t know how to change it.
Question: is IP configurable on ANAFI? If not is there a work-around so multiple ANAFI drones can be controlled via Olympe?
Unfortunately no, the ANAFI IP address is not configurable through the SDK. You can’t modify it without a privileged access to the drone firmware.
Please note that each drone simulated by Sphinx gets a different IP address on its virtual ethernet interface in the 10.202.0.0/24 subnet. So for simulated drones, if you don’t need the wifi interface but just want to connect to your drones from the same host, this is the way to go.
There is a workaround but it ain’t pretty. On a recent debian/ubuntu machine, use the following “config_anafi_ip.sh” like this :
#!/bin/bash
# ANAFI interface configuration script: configure one ANAFI interface
# All ANAFIs have a default IP address set to 192.168.42.1 . Hence by default,
# multiple ANAFIs connected to a host via multiple WiFi USB dongles are not
# addressable. This script creates a new ip address (on an independent subnet) on
# a wifi interface. This new address (and it's subnet) is intended to be
# decicated to this interface and all traffic on this address is correclty
# routed to the associated ANAFI.
set -e
action=$1
interface=$2
address=$3
route_tableid=$4
# shellcheck disable=SC2046,SC2116,SC2086
address_hex=0x$(printf '%02X' $(echo ${address//./ }))
# Outbound traffic iptables rules: packets addressed to the virtual ANAFI IP
# address are marked in order to be routed on the correct interface and then get
# NATed to match the actual ANAFI IP address on this interface
OUT_RULES=$(cat <<EOF
mangle:OUTPUT --destination $address -j MARK --set-mark $address_hex
nat:OUTPUT -m mark --mark $address_hex -j DNAT --to-destination 192.168.42.1
nat:POSTROUTING -m mark --mark $address_hex -j SNAT --to-source 192.168.42.254
EOF
)
# Inbound traffic rules: equivalent to the outbound traffic rules except we are
# only NATing the traffic from the ANAFI interface to the virtual ANAFI IP address
# (there is no routing involved)
IN_RULES=$(cat <<EOF
mangle:PREROUTING --in-interface $interface -j MARK --set-mark $address_hex
nat:PREROUTING -m mark --mark $address_hex -j DNAT --to-destination $address
nat:INPUT -m mark --mark $address_hex -j SNAT --to-source $address
EOF
)
RULES=$(cat <<EOF
$OUT_RULES
$IN_RULES
EOF
)
case $action in
setup)
echo "Setup $interface $address ($address_hex) $route_tableid"
# Add the ANAFI "virtual" IP
sudo ip addr del "$address"/24 dev "$interface" > /dev/null 2>&1|| true
sudo ip addr add "$address"/24 dev "$interface"
# Don't rely on the IP the ANAFI dhcp gave us
sudo ip addr del 192.168.42.254/24 dev "$interface" > /dev/null 2>&1|| true
sudo ip addr add 192.168.42.254/24 dev "$interface"
sudo ip link set dev "$interface" down
sudo sysctl -w "net.ipv4.conf.$interface.rp_filter=0"
# FIXME: We shouldn't have to deactivate rp_filter for all interfaces
sudo sysctl -w "net.ipv4.conf.all.rp_filter=0"
while read -r rule; do
table="${rule%:*}"
rule="${rule#*:}"
# shellcheck disable=SC2086
if ! sudo iptables -t "$table" -C $rule > /dev/null 2>&1; then
# Add the rule to the table
sudo iptables --wait -t "$table" -A $rule
fi
done <<< "$RULES"
sudo ip link set dev "$interface" up
sudo ip route del default via 192.168.42.254 dev "$interface" table "$route_tableid" > /dev/null 2>&1|| true
sudo ip route add default via 192.168.42.254 dev "$interface" table "$route_tableid"
sudo ip rule del fwmark "$address_hex" table "$route_tableid" > /dev/null 2>&1|| true
sudo ip rule add fwmark "$address_hex" table "$route_tableid"
;;
cleanup)
echo "Cleanup $interface $address ($address_hex) $route_tableid"
sudo ip link set dev "$interface" up
sudo ip addr del "$address"/24 dev "$interface" || true
sudo ip addr del 192.168.42.254/24 dev "$interface" || true
while read -r rule; do
table="${rule%:*}"
rule="${rule#*:}"
# shellcheck disable=SC2086
while sudo iptables -t "$table" -D $rule > /dev/null 2>&1; do :;done
done <<< "$RULES"
# sudo sysctl -w "net.ipv4.conf.$interface.rp_filter=1"
sudo ip route del default via 192.168.42.254 dev "$interface" table "$route_tableid" > /dev/null 2>&1 || true
sudo ip rule del fwmark "$address_hex" table "$route_tableid" > /dev/null 2>&1 || true
;;
esac
If you did use the config_anafi_ip.sh script to route each wlan to a different IP address, is there a way to discover these drones and their IP addresses?
I am not sure to understand what you mean. When you execute the config_anafi_ip.sh script above, you are already connected to the drone(s) wifi access point(s) (Anafi-XXXXXXX). The ANAFI has always the 192.168.42.1/24 address assigned to its wifi interface. So once you are connected to the drone access point there is nothing more to discover. The drone runs a DHCP server but you are free to assign a static IP to your wifi interface instead. This is actually just what the script above is doing: ignore any previously (DHCP assigned) IP address and configure the 192.168.42.254 IP address instead.
I’ll try to clarify this script usage below.
The network configuration script above is merely a trick to disambiguate the 192.168.42.1 drone IP address that your linux box will see on every wifi interface once connected to multiple drones.
As far as the drone is concerned, it always has the 192.168.42.1 IP address and will respond to any DHCP request with an IP address in the 192.168.42.0/24 subnet.
Let’s say you are connected to three drones whose SSID are Anafi-0001, Anafi-0002 and Anafi-0003 respectively on your wlan0, wlan1 and wlan2 wifi interfaces. If you setup your interfaces like this:
192.168.44.1 is routed/NATed to Anafi-0001 192.168.42.1 over wlan0
192.168.45.1 is routed/NATed to Anafi-0002 192.168.42.1 over wlan1
192.168.46.1 is routed/NATed to Anafi-0003 192.168.42.1 over wlan2
Now, if you use the 192.168.44.1, 192.168.45.1 and 192.168.46.1 IP address to connect to your drones, everything is fine.
However, if you try to connect to 192.168.42.1 there is no way to tell which interface/drone will be selected.
hi @ndessart
With default setting, i can connect to the drone. Then
I tried ur script.
i had my drone connected in my USB wifi adapter in DHCP mode.
it assign me with 192.168.42.22
Then i run your script with ./config_anafi_ip.sh setup wlXXXXXXX 192.168.44.1 201
Then i tried to run the python script to connect to the 192.168.44.1. i could not get a connection in olympe. The ipconfig still shows connectin to be 192.168.42.22. So I guess all the linux box ip are hidden right? May I ask what did i do wrong?
also i tried to change the code you shared by adding sudo ip addr flush dev wlXXXXX right after setup) and make the ipconfig shows 192.168.44.1. but still i could not connect through. may i ask how you get them up?