Telepon rumah
Ponsel saya bertindak berbeda, karena semua ponsel memiliki beberapa perbedaan. Respons ping hanya terjadi jika ponsel terjaga. Jika Pi di-boot ulang dan telepon dalam mode tidur, banyak ping akan menempatkan alamat ip dan mac-nya di tabel arp, dengan paket loss 100%. Saya baru tahu bahwa arp
perintahnya sudah usang, ip neighbor
digunakan sekarang.
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
Setelah pengujian, solusi saya adalah memiliki dua loop di dalam loop selamanya. loop dalam pertama adalah melakukan ping pada berbagai alamat ip, beberapa kali, yang mungkin untuk ponsel saya. Router saya telah mencadangkan 19 alamat ip pertama dan saya mungkin memiliki sekitar setengah lusin alamat yang akan ditetapkan DHCP, termasuk telepon saya, mulai dari alamat 192.168.0.20. Saya akan ping selusin alamat ip sekali, dalam mode latar belakang, tunggu satu detik untuk respon, dan membuang hasilnya sebagai sampah. Saya akan menunggu delapan detik di tabel arp, dan menjalankan ip neighbor
perintah, ambil alamat mac untuk alamat ip. Router dan telepon akan menyimpan alamat ip yang sama ini kecuali terjadi sesuatu yang tidak biasa. Tabel arp akan tetap di Pi, tetapi akan berubah negara dari REACHABLE
, STALE
, dan FAILED
dari ping dan waktu.
Loop kedua di dalam akan melakukan ping dan memeriksa tabel arp setiap lima menit untuk menentukan apakah ponsel di rumah. Dengan tiga ping 'GAGAL' berturut-turut, telepon tidak di rumah. Satu 'REACHABLE', ketika telepon tidak di rumah, akan membuat telepon kembali ke rumah (melakukan sesuatu). Ada pemeriksaan untuk memvalidasi alamat ip dan kembali ke loop dalam pertama jika diperlukan koreksi.
#!/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