Zuhause anrufen
Mein Telefon verhält sich anders, da alle Telefone einen Unterschied aufweisen. Eine Ping-Antwort erfolgt nur, wenn das Telefon wach ist. Wenn der Pi neu gestartet wird und sich das Telefon im Energiesparmodus befindet, werden seine IP- und Mac-Adressen mit 100% Paketverlust durch mehrere Pings in der ARP-Tabelle abgelegt. Ich habe gerade erfahren, dass der arp
Befehl veraltet ip neighbor
ist, wird jetzt verwendet.
pi@RPi0:~ $ ip neighbor
169.254.65.43 dev eth0 lladdr 64:31:00:00:00:00 REACHABLE
192.168.0.1 dev wlan0 lladdr ac:b3:00:00:00:00 STALE
fe80::aeb3:13ff:fe00:000 dev wlan0 lladdr ac:b3:00:00:00:00 router STALE
pi@RPi0:~ $ ping 192.168.0.22
PING 192.168.0.22 (192.168.0.22) 56(84) bytes of data.
From 192.168.0.10 icmp_seq=1 Destination Host Unreachable
From 192.168.0.10 icmp_seq=2 Destination Host Unreachable
From 192.168.0.10 icmp_seq=3 Destination Host Unreachable
--- 192.168.0.22 ping statistics ---
34 packets transmitted, 0 received, +3 errors, 100% packet loss, time 34303ms
pi@RPi0:~ $ ip neighbor
192.168.0.1 dev wlan0 lladdr ac:b3:00:00:00:00 REACHABLE
169.254.65.43 dev eth0 lladdr 64:31:00:00:00:00 REACHABLE
192.168.0.22 dev wlan0 lladdr ac:37:00:00:00:00 REACHABLE
fe80::aeb3:13ff:fe00:000 dev wlan0 lladdr ac:b3:00:00:00:00 router STALE
Nach dem Testen würde meine Lösung darin bestehen, zwei Schleifen in einer Endlosschleife zu haben. Die erste innere Schleife wäre, mehrmals einen Ping auf einen Bereich von IP-Adressen durchzuführen, der für mein Telefon möglich wäre. Mein Router hat die ersten 19 IP-Adressen reserviert und ich habe möglicherweise etwa ein halbes Dutzend Adressen, die von DHCP zugewiesen werden, einschließlich meines Telefons, beginnend mit der Adresse 192.168.0.20. Ich werde ein Dutzend IP-Adressen einmal im Hintergrund anpingen, eine Sekunde auf eine Antwort warten und die Ergebnisse als Müll wegwerfen. Ich werde acht Sekunden auf dem ARP-Tisch warten und den ip neighbor
Befehl ausführen, indem ich die MAC- Adresse nach der IP-Adresse durchsucht . Der Router und das Telefon behalten dieselbe IP-Adresse, sofern nichts Ungewöhnliches passiert. Die arp - Tabelle wird in dem Pi bleiben, sondern Zustände ändert aus REACHABLE
, STALE
und FAILED
von Pings und Zeit.
Die zweite interne Schleife pingt alle fünf Minuten und überprüft die Arptabelle, um festzustellen, ob das Telefon zu Hause ist. Mit drei aufeinanderfolgenden Pings 'FAILED' ist das Telefon nicht zu Hause. Wenn das Telefon nicht zu Hause ist, kann das Telefon mit der Einstellung "REACHABLE" (Erreichbar) nach Hause zurückkehren (etwas tun). Es werden Überprüfungen durchgeführt, um die IP-Adresse zu validieren und zur ersten internen Schleife zurückzukehren, wenn Korrekturen erforderlich sind.
#!/bin/bash
# A script to do something when Phone returns Home.
mac="ac:37:00:00:00:00" # Your phone mac address
ip_addr="" # Leave blank or ip for test
network="192.168.0.0" # Your network (Class C only)
range="20 32" # ip address possible range
pgm='echo "do something"' # program to exec when Phone returns Home
start=$(echo "$range" | cut -d " " -f1)
stop=$(echo "$range" | cut -d " " -f2)
network=$(echo "$network" | cut -d. -f1-3)
echo "Start $(date)"
while [ 1 ]; do
cnt=0
fail=0
[ "$ip_addr" ] || while [ ! "$ip_addr" ]; do
for x in $(seq "$start" "$stop"); do
(junk=$(ping -c1 -W1 "$network"."$x") & )
wait
done
sleep 8
ip_addr=$(ip neighbor | grep "$mac" | cut -d " " -f1)
((cnt++))
if (( $cnt > 15 )); then
cnt=0
echo "--- Phone not Home $(date)"
sleep 300 # 5 minutes
fi
if [ "$ip_addr" ]; then
echo "--- Phone is Home, Count = $cnt, Date = $(date)"
echo "Phone ip = $ip_addr mac = $mac"
fi
done
while [ "$ip_addr" ]; do
junk="$(ping -c1 -W1 $ip_addr)"
sleep 8
home_nw="$(ip neighbor | grep $ip_addr | cut -d ' ' -f 1,5,6)"
echo "$home_nw - $(date)"
is_home=$(echo "$home_nw" | cut -d " " -f3)
if [ "$is_home" == "REACHABLE" ] && (( "$fail" >= 3 )); then
echo "--- Phone returned Home - $(date)"
$pgm
fi
[ "$is_home" == "REACHABLE" ] && fail=0
mac_stat=$(echo "$home_nw" | cut -d " " -f2)
if [ "$mac_stat" == "FAILED" ]; then
(( "$fail" < 10 )) && ((fail++))
ip_test="$(ip neighbor | grep $mac | cut -d ' ' -f1)"
if [ "$ip_test" ]; then
[ "$ip_test" == "$ip_addr" ] || ip_addr=""
fi
if (( "$fail" == 3 )); then
echo "--- Phone not at Home $(date)"
fi
else
if [ "$mac_stat" != "$mac" ]; then
ip_addr=""
fi
fi
sleep 300 # 5 minutes
done
done