616 lines
12 KiB
Bash
Executable File
616 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
#****************************************************************************
|
|
# tools/simwifi/sim_wifi.sh
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership. The
|
|
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance with the
|
|
# License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
#****************************************************************************
|
|
#
|
|
|
|
NUTTX_BR_IF="nuttx0"
|
|
RUN_DIR="/var/run/simwifi"
|
|
LINK_DIR="/usr/bin"
|
|
CUR_DIR=""
|
|
DBG_LEVEL=1
|
|
|
|
WPA_PID_FILE="$RUN_DIR/wpa_supplicant.pid"
|
|
WPA_CONF_FILE="$RUN_DIR/wpa_supplicant.conf"
|
|
HOSTAPD_PID_FILE="$RUN_DIR/hostapd.pid"
|
|
HOSTAPD_CONF_FILE="$RUN_DIR/hostapd.conf"
|
|
DNSMASQ_PID="$RUN_DIR/dnsmasq.pid"
|
|
DNSMASQ_CONF="$RUN_DIR/dnsmasq.conf"
|
|
UDHCPC_PID="$RUN_DIR/udhcpc.pid"
|
|
UDHCPC_SCRIPT="/var/udhcpc.script"
|
|
|
|
LOG_FILE="$RUN_DIR/simwifi.log"
|
|
STATE_FILE="$RUN_DIR/simwifi.state"
|
|
DEFCONF_FILE="$RUN_DIR/simwifi.conf"
|
|
|
|
DHCP_CLIENT=$(which udhcpc)
|
|
DNSMASQ=$(which dnsmasq)
|
|
WPA_SUPPLICANT=$(which wpa_supplicant)
|
|
HOSTAPD=$(which hostapd)
|
|
|
|
# print the debug message
|
|
sw_dbg()
|
|
{
|
|
[ $1 -ge $DBG_LEVEL ] && {
|
|
echo "$2"
|
|
}
|
|
}
|
|
|
|
# get var from the file
|
|
# $1:key $2:file
|
|
get_var()
|
|
{
|
|
cat $2 | grep $1 | awk -F':' '{print $2}'
|
|
}
|
|
|
|
check_state()
|
|
{
|
|
old_state=$(get_var state $STATE_FILE)
|
|
sw_dbg 1 "new state:$1, old_state:$old_state"
|
|
|
|
if [ "$1" = "$old_state" ]; then
|
|
sw_dbg 1 "cur_state is $1"
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# set simwifi state
|
|
set_state()
|
|
{
|
|
state=$1
|
|
wlan_if=$2
|
|
br_if=$3
|
|
wan_if=$4
|
|
sw_dbg 1 "[set_state] new state:$1"
|
|
|
|
if [ "$state" != "SW_INIT" -a "$state" != "SW_HWSIM" -a \
|
|
"$state" != "SW_NET" -a "$state" != "SW_STA" -a \
|
|
"$state" != "SW_AP" -a "$state" != "SW_STAAP" ]; then
|
|
echo "no state: $1"
|
|
exit -1
|
|
fi
|
|
|
|
sw_dbg 1 "state:$state wlan_if:$wlan_if, br_if:$br_if wan_if:$wan_if"
|
|
|
|
echo "state:$state" > $STATE_FILE
|
|
[ -n "$wlan_if" ] && echo "wlan:$wlan_if" >> $STATE_FILE
|
|
[ -n "$br_if" ] && echo "br:$br_if" >> $STATE_FILE
|
|
[ -n "$wan_if" ] && echo "wan:$wan_if" >> $STATE_FILE
|
|
}
|
|
|
|
# recover the simwifi state to SW_INIT
|
|
|
|
recovery_to_init()
|
|
{
|
|
cur_state=$(get_var state $STATE_FILE)
|
|
wlan_if=$(get_var wlan $STATE_FILE)
|
|
br_if=$(get_var br $STATE_FILE)
|
|
|
|
sw_dbg 1 "[recovery_to_init] cur_s:$cur_state"
|
|
case $cur_state in
|
|
SW_INIT) ;;
|
|
SW_HWSIM) stop_hwsim;;
|
|
SW_STAAP) stop_staap;;
|
|
SW_NET) stop_net $wlan_if;;
|
|
SW_STA) stop_sta;;
|
|
SW_AP) stop_ap $wlan_if;;
|
|
*) set_state SW_INIT;;
|
|
esac
|
|
}
|
|
|
|
# Get the absolute pathname of sim_wifi.sh
|
|
|
|
get_script_path()
|
|
{
|
|
SOURCE=$1
|
|
|
|
while [ -h "$SOURCE" ]; do
|
|
SOURCE=$(readlink $SOURCE)
|
|
done
|
|
|
|
CUR_DIR=$(cd $(dirname $SOURCE) && pwd)
|
|
}
|
|
|
|
# Copy the configure file to the $RUN_DIR
|
|
|
|
init_env()
|
|
{
|
|
sw_dbg 1 "init env"
|
|
|
|
[ -f "$STATE_FILE" ] && {
|
|
check_hwsim_mode
|
|
recovery_to_init
|
|
}
|
|
|
|
mkdir -p $RUN_DIR
|
|
touch $STATE_FILE
|
|
|
|
if [ "$1" = "hwsim" ]; then
|
|
cp -fr $CUR_DIR/hostapd_hwsim.conf $HOSTAPD_CONF_FILE
|
|
cp -fr $CUR_DIR/wpa_supplicant_hwsim.conf $WPA_CONF_FILE
|
|
else
|
|
cp -fr $CUR_DIR/hostapd.conf $HOSTAPD_CONF_FILE
|
|
cp -fr $CUR_DIR/wpa_supplicant.conf $WPA_CONF_FILE
|
|
fi
|
|
|
|
cp -fr $CUR_DIR/dnsmasq.conf $DNSMASQ_CONF
|
|
cp -fr $CUR_DIR/udhcpc.script $UDHCPC_SCRIPT
|
|
chmod +x $UDHCPC_SCRIPT
|
|
}
|
|
|
|
# Rename the interface name
|
|
|
|
rename_ifdev()
|
|
{
|
|
old_name=$1
|
|
new_name=$2
|
|
|
|
ifconfig $old_name down && ip link set $old_name name $new_name
|
|
ifconfig $new_name up
|
|
}
|
|
|
|
kill_service()
|
|
{
|
|
service_name=$(basename $1 .pid)
|
|
sw_dbg 1 "kill $service_name"
|
|
if [ -f "$1" ]; then
|
|
pid=$(cat $1)
|
|
kill -9 $pid
|
|
rm $1
|
|
else
|
|
sw_dbg 1 "$1 isn't existed."
|
|
killall $service_name
|
|
fi
|
|
}
|
|
|
|
stop_wpa()
|
|
{
|
|
kill_service $WPA_PID_FILE
|
|
}
|
|
|
|
stop_hostapd()
|
|
{
|
|
kill_service $HOSTAPD_PID_FILE
|
|
}
|
|
|
|
start_hostapd()
|
|
{
|
|
sw_dbg 1 "start ap on $1"
|
|
|
|
#Waiting 1s. If not, the hostapd starting maybe fail on switching mode.
|
|
|
|
sleep 1
|
|
$HOSTAPD -B -i$1 -P $HOSTAPD_PID_FILE $HOSTAPD_CONF_FILE -t &>>$LOG_FILE
|
|
}
|
|
|
|
start_wpa()
|
|
{
|
|
sw_dbg 1 "start sta on $1"
|
|
|
|
#Waiting 1s. If not, the wap_supplicant starting maybe fail on switching mode.
|
|
|
|
sleep 1
|
|
$WPA_SUPPLICANT -B -c $WPA_CONF_FILE -i$1 -P $WPA_PID_FILE &>>$LOG_FILE
|
|
}
|
|
|
|
start_udhcpc()
|
|
{
|
|
sw_dbg 1 "start dhcp client on $1"
|
|
|
|
[ -n "$2" ] && script_opt=" -s $UDHCPC_SCRIPT"
|
|
|
|
$DHCP_CLIENT -i $1 -p $UDHCPC_PID $script_opt &>>$LOG_FILE &
|
|
}
|
|
|
|
stop_udhcpc()
|
|
{
|
|
kill_service $UDHCPC_PID
|
|
}
|
|
|
|
start_bridge()
|
|
{
|
|
sw_dbg 1 "start bridge to $1"
|
|
$CUR_DIR/../simhostroute.sh $1 on &>>$LOG_FILE
|
|
}
|
|
|
|
stop_bridge()
|
|
{
|
|
sw_dbg 1 "stop bridge to $1"
|
|
sw_dbg 1 "Warning: The $NUTTX_BR_IF will be deleted!"
|
|
$CUR_DIR/../simhostroute.sh $1 off &>>$LOG_FILE
|
|
}
|
|
|
|
start_dhcp_server()
|
|
{
|
|
sw_dbg 1 "start dhcp server on $1"
|
|
dbg_option=$($DNSMASQ --help|grep log-debug | awk '{print $1}')
|
|
|
|
$DNSMASQ -i$1 -C $DNSMASQ_CONF $dbg_option -x $DNSMASQ_PID &>>$LOG_FILE
|
|
}
|
|
|
|
stop_dhcp_server()
|
|
{
|
|
kill_service $DNSMASQ_PID
|
|
}
|
|
|
|
check_hwsim_mode()
|
|
{
|
|
cur_state=$(get_var state $STATE_FILE)
|
|
|
|
sw_dbg 1 "[check_hwsim_mode]state: $cur_state"
|
|
if [ "$cur_state" = "SW_HWSIM" ]; then
|
|
sw_dbg 1 "cur_state is hwsim mode. \
|
|
Don't set the sta/ap mode."
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
start_hwsim()
|
|
{
|
|
sta_if=${1:-wlan0}
|
|
ap_if=${2:-wlan1}
|
|
|
|
sw_dbg 1 "start hwsim on $sta_if $ap_if"
|
|
|
|
init_env hwsim
|
|
start_hostapd $ap_if
|
|
start_wpa $sta_if
|
|
start_dhcp_server $NUTTX_BR_IF
|
|
|
|
set_state SW_HWSIM
|
|
}
|
|
|
|
stop_hwsim()
|
|
{
|
|
stop_wpa
|
|
stop_hostapd
|
|
|
|
stop_dhcp_server
|
|
|
|
set_state SW_INIT
|
|
}
|
|
|
|
start_net()
|
|
{
|
|
init_env
|
|
start_wpa $1
|
|
start_udhcpc $1
|
|
start_bridge $1
|
|
start_dhcp_server $NUTTX_BR_IF
|
|
|
|
set_state SW_NET $1 $NUTTX_BR_IF $1
|
|
}
|
|
|
|
# Warning:The function will delete nuttx0
|
|
|
|
stop_net()
|
|
{
|
|
stop_wpa
|
|
stop_udhcpc
|
|
stop_bridge $1
|
|
stop_dhcp_server
|
|
|
|
set_state SW_INIT
|
|
}
|
|
|
|
start_sta()
|
|
{
|
|
[ -z "$(ifconfig | grep "$NUTTX_BR_IF")" ] && {
|
|
sw_dbg 1 "Please ensure that the $NUTTX_BR_IF is existed."
|
|
exit -2
|
|
}
|
|
|
|
check_state SW_STA
|
|
check_state SW_STAAP
|
|
|
|
init_env
|
|
start_wpa $1
|
|
start_udhcpc $1 s
|
|
start_dhcp_server $NUTTX_BR_IF
|
|
|
|
set_state SW_STA $1 $NUTTX_BR_IF;
|
|
|
|
exit 0
|
|
}
|
|
|
|
del_gw_wlan()
|
|
{
|
|
wlan_if=$1
|
|
router=$(ip route show | grep default | grep $wlan_if)
|
|
|
|
[ -n "$router" ] && {
|
|
ip route del $router
|
|
sw_dbg 1 "del the default router on $wlan_if"
|
|
}
|
|
|
|
ifconfig $wlan_if 0.0.0.0
|
|
}
|
|
|
|
stop_sta()
|
|
{
|
|
stop_wpa
|
|
stop_udhcpc
|
|
stop_dhcp_server
|
|
|
|
#check and delete default on wlan0
|
|
|
|
wlan_if=$(get_var wlan $STATE_FILE)
|
|
del_gw_wlan $wlan_if
|
|
|
|
set_state SW_INIT
|
|
}
|
|
|
|
start_ap()
|
|
{
|
|
[ -z "$1" ] && {
|
|
echo "Missing parameter wlan interface."
|
|
exit -1
|
|
}
|
|
|
|
[ -z "$2" ] && {
|
|
[ -z "$(ifconfig | grep "$NUTTX_BR_IF")" ] && {
|
|
echo "Missing parameter wan interface."
|
|
echo "Please ensure that the $NUTTX_BR_IF is existed."
|
|
exit -2
|
|
}
|
|
|
|
wan_if=""
|
|
} || {
|
|
wan_if=$2
|
|
}
|
|
|
|
check_state SW_AP
|
|
check_state SW_STAAP
|
|
|
|
init_env
|
|
start_hostapd $1
|
|
|
|
# nuttx0 doesn't exist and wan_if is configured.
|
|
|
|
[ -z "$(ifconfig | grep "$NUTTX_BR_IF")" -a -n "$wan_if" ] && {
|
|
start_bridge $wan_if
|
|
}
|
|
|
|
ip link set dev $1 master $NUTTX_BR_IF
|
|
start_dhcp_server $NUTTX_BR_IF
|
|
|
|
set_state SW_AP $1 $wan_if;
|
|
|
|
exit 0
|
|
}
|
|
|
|
stop_ap()
|
|
{
|
|
stop_hostapd
|
|
[ -z "$2" ] || stop_bridge $2
|
|
|
|
sw_dbg 1 "stop_ap $1"
|
|
ip link set dev $1 nomaster
|
|
stop_dhcp_server
|
|
|
|
set_state SW_INIT
|
|
}
|
|
|
|
check_ifname()
|
|
{
|
|
[ -z "$(ifconfig | grep "$1")" ] && {
|
|
echo "The $1 does not exist."
|
|
exit -1
|
|
}
|
|
}
|
|
|
|
start_staap()
|
|
{
|
|
sta_if=${1:-wlan0}
|
|
ap_if=${2:-wlan1}
|
|
sw_dbg 1 "start staap $sta_if $ap_if"
|
|
|
|
for i in $sta_if $ap_if $NUTTX_BR_IF; do
|
|
check_ifname $i
|
|
done
|
|
|
|
check_state SW_STAAP
|
|
|
|
init_env
|
|
start_hostapd $ap_if
|
|
|
|
sleep 1
|
|
start_wpa $sta_if
|
|
|
|
ip link set dev $ap_if master $NUTTX_BR_IF
|
|
|
|
start_udhcpc $sta_if
|
|
start_dhcp_server $NUTTX_BR_IF
|
|
|
|
set_state SW_STAAP "$sta_if,$ap_if" $NUTTX_BR_IF
|
|
}
|
|
|
|
stop_staap()
|
|
{
|
|
stop_wpa
|
|
stop_hostapd
|
|
|
|
stop_udhcpc
|
|
stop_dhcp_server
|
|
ip link set dev wlan1 nomaster
|
|
|
|
set_state SW_INIT
|
|
}
|
|
|
|
show_process()
|
|
{
|
|
ps -ef | grep "$1 " | grep -v grep
|
|
}
|
|
|
|
show_status()
|
|
{
|
|
#1.env conf
|
|
[ -d "$RUN_DIR" ] && {
|
|
echo "$RUN_DIR"
|
|
ls $RUN_DIR
|
|
}
|
|
|
|
#2. key services
|
|
echo -e "\nservices list"
|
|
for i in wpa_supplicant hostapd dnsmasq udhcpc; do
|
|
show_process $i
|
|
done
|
|
|
|
#3. bridge nuttx0 info
|
|
[ -n "$(ifconfig | grep $NUTTX_BR_IF)" ] && {
|
|
echo -e "\nbridge $NUTTX_BR_IF"
|
|
ip link show master $NUTTX_BR_IF
|
|
}
|
|
|
|
#4.show DEFCONF_FILE
|
|
echo -e "\ndefault config"
|
|
cat $DEFCONF_FILE
|
|
|
|
#5. show state
|
|
echo ""
|
|
cat $STATE_FILE
|
|
|
|
#6. show router
|
|
echo ""
|
|
ip route show
|
|
|
|
#7. show radio state
|
|
echo "radio status"
|
|
rfkill list
|
|
|
|
#8. show networkmanager wifi status
|
|
echo "networkmanager wifi status"
|
|
nmcli radio wifi
|
|
}
|
|
|
|
# $1 is the default wan interface for start_sta
|
|
# $2 is the simwifi mode, (rnc/hwsim)
|
|
|
|
init()
|
|
{
|
|
[ -z "$1" ] && {
|
|
echo "Missing the default wan interface."
|
|
exit -1
|
|
}
|
|
|
|
[ -z "$2" ] && {
|
|
echo "Missing the simwifi mode."
|
|
exit -2
|
|
}
|
|
|
|
init_env
|
|
|
|
ln -s $CUR_DIR/sim_wifi.sh $LINK_DIR/sim_wifi.sh
|
|
|
|
echo "defwan:$1" > $DEFCONF_FILE
|
|
[ -n "$1" -a -n "$(ifconfig | grep $1)" ] && start_bridge $1
|
|
|
|
echo "mode:$2" >> $DEFCONF_FILE
|
|
[ "$2" = "hwsim" ] && modprobe mac80211_hwsim
|
|
|
|
# Turn off the wifi of networkmanager.
|
|
nmcli radio wifi off
|
|
|
|
# open the radio by rfkill
|
|
id_list=$(rfkill list | grep phy | awk -F':' '{print $1}')
|
|
for id in $id_list; do
|
|
rfkill unblock $id;
|
|
done
|
|
|
|
set_state SW_INIT "" $NUTTX_BR_IF $1
|
|
}
|
|
|
|
clean()
|
|
{
|
|
[ -z "$1" ] && {
|
|
echo "Missing the default wan interface."
|
|
exit -1
|
|
}
|
|
|
|
recovery_to_init
|
|
|
|
rm $LINK_DIR/sim_wifi.sh
|
|
|
|
cur_mode=$(get_var mode $DEFCONF_FILE)
|
|
[ "$cur_mode" = "hwsim" ] && modprobe -r mac80211_hwsim
|
|
|
|
echo "defwan:$1" > $DEFCONF_FILE
|
|
[ -n "$1" -a -n "$(ifconfig | grep $1)" ] && stop_bridge $1
|
|
|
|
rm -fr $RUN_DIR
|
|
rm -f $UDHCPC_SCRIPT
|
|
|
|
# Turn on the wifi of networkmanager.
|
|
nmcli radio wifi on
|
|
|
|
}
|
|
|
|
usage()
|
|
{
|
|
echo "$(basename $SOURCE) (rename <old> <new> |"
|
|
echo -e "\t init <wan> <mode> |clean <wan> |"
|
|
echo -e "\t start_wpa <wlan0> |stop_wpa |"
|
|
echo -e "\t start_hostapd <wlan0> |stop_hostapd |"
|
|
echo -e "\t start_udhcpc <wlan0> |stop_udhcpc |"
|
|
echo -e "\t start_dhcp <wlan0> |stop_dhcp |"
|
|
echo -e "\t start_hwsim |stop_hwsim |up_hwsim |"
|
|
echo -e "\t start_staap |stop_staap |"
|
|
echo -e "\t start_net <wlan0> |stop_net <wlan0> |"
|
|
echo -e "\t start_sta <wlan0> |stop_sta |"
|
|
echo -e "\t start_ap <wlan0> [eth0] |stop_ap <wlan0> [eth0] |"
|
|
echo -e "\t start_bridge <eth0> |stop_bridge <eth0> |"
|
|
echo -e "\t show | help)"
|
|
}
|
|
|
|
# locate the directory of the sim_wifi.sh.
|
|
|
|
get_script_path $0
|
|
|
|
case $1 in
|
|
init) init $2 $3;;
|
|
clean) clean $2;;
|
|
start_bridge) start_bridge $2;;
|
|
stop_bridge) stop_bridge $2;;
|
|
start_hwsim) start_hwsim $2 $3;;
|
|
stop_hwsim) stop_hwsim;;
|
|
up_hwsim) ifconfig hwsim0 up;;
|
|
start_wpa) start_wpa $2;;
|
|
stop_wpa) stop_wpa;;
|
|
start_hostapd) start_hostapd $2;;
|
|
stop_hostapd) stop_hostapd;;
|
|
rename) rename_ifdev $2 $3;;
|
|
start_udhcpc) start_udhcpc $2;;
|
|
stop_udhcpc) stop_udhcpc;;
|
|
start_dhcp) start_dhcp_server $2;;
|
|
stop_dhcp) stop_dhcp_server;;
|
|
start_net) start_net $2;;
|
|
stop_net) stop_net $2;;
|
|
start_sta) start_sta $2;;
|
|
stop_sta) stop_sta;;
|
|
start_ap) start_ap $2 $3;;
|
|
stop_ap) stop_ap $2 $3;;
|
|
start_staap) start_staap;;
|
|
stop_staap) stop_staap;;
|
|
show) show_status;;
|
|
help|*) usage;;
|
|
esac
|