设为首页 收藏本站
查看: 1331|回复: 0

[经验分享] 【原创】修改WIFI保持连接脚本

[复制链接]

尚未签到

发表于 2015-10-1 08:42:10 | 显示全部楼层 |阅读模式
  【原创】修改WIFI保持连接脚本
  项目中用到wifi,由于无线网络的不稳定性,可能会造成wifi的掉线,这就需要在程序中判断网络的是否联通,并且能在断线后继续搜寻无线网络并重新连接。
  并且因为wifi连接有许多现成的工具,所以在这里就利用shell脚本来实现此功能。
  本篇博客主要是记录我修改此脚本到当前项目的记录,包含shell脚本的一些用法和wifi连接工具的用法:
  一、初始化函数init_var



init_var() {
#until [ -d $SYSFS ] ; do sleep 1; done
#find the first useable wifi card
local wifi_dev               #定义局部变量wifi_dev
wifi_dev=$(iwconfig 2>&1  | grep -v "no wireless" ) #查看当前设备有的无线设备,grep -v 指的是去除no wireless这一行
while true; do                #无限循环
if [ -z "$wifi_dev" ]; then #判断wifi_dev字符串是否为空 是空则执行下面的命令
sleep 3
wifi_dev=$(iwconfig 2>&1  | grep -v "no wireless" )
else                   #不为空  获取当前wifi设备名
IFACE=$(iwconfig 2>&1 | grep -v -n "no wireless" | awk '{print $1}' | awk -F: '{print $2}' | grep 0)
break
fi
done
# support only pc run dhclient
which dhclient     #判断 dhclient工具是否存在
if [ $? -ne 0 ]; then
RUN_PC=0
else
RUN_PC=1
fi
if [ "$RUN_PC" = "0" ] ; then
DHCP_CLIENT=udhcpc
DHCP_CLIENT_OPT=" -i "
PING_KEYWORD=round-trip
DHCP_WAIT_TIMES=5
else
DHCP_CLIENT=dhclient
PING_KEYWORD=rtt
DHCP_WAIT_TIMES=5
rm -f /var/lib/dhclient/dhclient.leases
fi
tmpfsloc=$(mount | grep tmpfs | awk '{print $3}' | head -n 1)
loc=${tmpfsloc:-/dev}
WPA_CONFIGFILE=$loc/wpa_supplicant.conf

echo dhcp client app is $DHCP_CLIENT    #打印相关信息
echo ping key words is $PING_KEYWORD
echo ESSID is $CONF_ESSID
echo interface is $IFACE
echo run mode is $RUN_MODE
}

  
  二、主循环程序如下



while [ -d $SYSFS ] ; do
network_connect
if [ $? -ne 0 ]; then
echo --INFO--:network is disconnected? try to reconnect
ifconfig $IFACE 0.0.0.0
setup_wifi
fi
sleep $CHECK_PERIOD
done

  network_connect是一个函数,其主要功能是判断网络是否联通,然后是一个判断语句,如过network_connect不成功(返回的不是0),
  则执行setup_wifi函数,此函数的主要功能重新设置并连接wifi。如果网络联通则睡眠CHECK_PERIOD秒后再重新判断连接是否正常。
  三、判断网络是否连接函数network_connect



network_connect() {
#get ip first
ifconfig $IFACE | grep -q "inet addr"  #判断当前是否有IP地址
if [ $? -ne 0 ]; then
echo can\'t find IP
return 1
fi

#get default gateway
route | grep -q default | awk '{print $2}'  #获取当前连接路由的网关地址
if [ $? -ne 0 ]; then
echo can\'t get default gatway
return 1
else
SERVER_IP=$(route | grep default | awk '{print $2}')
fi
if [ -z $SERVER_IP ]; then
echo did not get server ip by route, server_ip=$SERVER_IP
return 1
fi
if ! ping -c $PING_RETRY_COUNT -q $SERVER_IP | grep -q $PING_KEYWORD; then  #利用ping命令查看网络是否联通
echo ping $SERVER_IP failed
return 1
fi
}

  
  四、加入路由函数setup_wifi



setup_wifi() {
ifconfig $IFACE down
ifconfig $IFACE up        #将无线网卡重启
echo start wireless scanning
local count=0
until [ $count -ge 3 ]  ;
do
get_auth_mode          #获取AP加密方式等信息,如果未找到指定AP,将会返回1
if [ $? -ne 0 ]; then
echo "AP $CONF_ESSID not found, sleeping...";
sleep 5;
let 'count=count+1';              
else
break                         #找到后返回
fi
done
#scan ok
if [ $count -lt 3 ] ; then
if [ "$RUN_MODE" = "debug" ] ; then
set_wifi_mode
return 0
fi
fi
local index
if [ $count -lt 3 ] ; then
echo APs list: ${mac_ary
  • }  #打印获取后的同名AP列表
    echo signal list: ${siglevel_ary
  • }
    echo sort index: ${sort_ary
  • }
    for(( i = 1; i <= $AP_COUNT; i++)) #下面的功能是找到最大信号的那个AP  并加入到其中,如果加入不成功,依次加次强的那个
    do
    index=${sort_ary} #the first is most signal
    bssid=${mac_ary[index]}
    echo try AP: ${ssid_name_ary[index]}  $bssid
    set_wifi_mode                      #该函数是设置wifi模式,并调用WPA_CONFIGFILE工具,连接AP
    if [ $? -ne 0 ]; then
    echo association with $bssid failed
    else
    echo association with $bssid OK
    break
    fi
    done
    fi
    }

      五、搜寻指定AP,并获得AP加密方式函数get_auth_mode



    get_auth_mode() {
    local grep_expr found
    local ad_hoc_grep
    iwlist_log=$(iwlist $IFACE scanning)  #扫描所有AP信息
    grep_expr="ESSID:\"$CONF_ESSID\""
    ad_hoc_grep="Mode:$ADHOC_MODE"

    local start_line
    start_line=$(printf "%s \n" "$iwlist_log" | grep -n $grep_expr | awk -F: '{print $1}')#找到符合指定AP名的行
    AP_COUNT=$(echo $start_line | wc -w)   #判断有几行
    echo total ap number is $AP_COUNT    #有几行就说明有几个同名AP
    # if AP_COUNT > 0
    if [ $AP_COUNT -gt 0 ]; then   #如果大于0就说明找到指定AP
    found=true
    else
    return 1
    fi
    start_line=$(printf "%s \n" "$iwlist_log" | grep  $grep_expr -B 2 | grep Cell | awk '{print $2}') #获得全部指定AP名的Cell
    local i cell
    for((i = 1; i <= $AP_COUNT; i++ )) #将每个同名AP分离出来  并存到数组内
    do
    cell=$(echo $start_line | awk '{print $('$i')}')
    get_ssid_str $cell  $i                   #根据Cell编号,获取每个同名AP的加密信息
    done
    #suppose all APs used the same encryption settings, for supporting roaming
    ssid_str=${ssid_str_ary[1]}   #数组内第一个AP就是同名AP中信号最强的
    Encryption=$(printf "%s \n" "$ssid_str" | grep Encryption | awk -F: '{print $2}')#下面是获取其加密类型
    Auth_Suite=$(printf "%s \n" "$ssid_str" | grep "Authentication Suites" | awk '{print $5}')
    Group_cipher=$(printf "%s \n" "$ssid_str" | grep "Group Cipher" | head -n 1 | awk '{print $4}')
    echo --INFO--:Group_cipher=$Group_cipher
    #Pair_ciper=$(printf "%s \n" "$ssid_str" | grep "Pairwise Ciphers" | awk '{print $5}')
    if [ "$Auth_Suite" = "802.1X" ]; then #转化为wpa_supplicant对应的加密类型
    #Auth_Suite is PSK or 802.1X
    echo didn\'t support WPA Enterprise, Authentication Suites is $Auth_Suite
    return 1
    fi
    if [ "$Group_cipher" = "CCMP" -o "$Group_cipher" = "TKIP" ]; then
    EncrypType=$Group_cipher
    fi
    AuthMode=WEP
    if [ "$Encryption" = "off"  ]; then
    AuthMode=
    return 0
    fi
    if  echo $ssid_str | grep -q "802.11i/WPA2"  ; then
    AuthMode=WPA2
    return 0
    fi
    if  echo $ssid_str | grep -q "WPA Version" ; then
    AuthMode=WPA
    return 0
    fi
    return 0
    }

      六、加入AP函数set_wifi_mode



    set_wifi_mode() {
    echo auth mode is $AuthMode
    if [ "$RUN_MODE" = "debug" ] ; then
    killall $DHCP_CLIENT
    killall wpa_supplicant
    sleep 5
    ifconfig $IFACE up
    sleep 2
    #iwconfig $IFACE key off
    iwconfig $IFACE mode $ADHOC_MODE
    sleep 2
    iwconfig $IFACE essid "$DEBUG_CONF_ESSID"
    ifconfig $IFACE $DEBUG_FIX_IP
    return
    fi
    if [ "$AuthMode" = "WEP" ] ; then #判断加密类型  生成wpa_supplicant所需的.conf文件
    local pref
    if [ "$WEP_KEY_TYPE" = "char" ] ; then
    pref="s:"
    fi
    iwconfig $IFACE key open $pref$PASSWORD  [$WEP_KEYINDEX]
    iwconfig $IFACE essid "$CONF_ESSID"
    echo try "open" Authentication mode
    sleep 5
    name=$(iwconfig $IFACE | head -1 | awk -F\" '{print $2}')
    if [ "$name" != "$CONF_ESSID" ];then
    echo "open" Authentication mode failed, try shard mode
    iwconfig $IFACE key restricted $pref$PASSWORD  [$WEP_KEYINDEX]
    iwconfig $IFACE essid "$CONF_ESSID"
    fi
    elif [ "$AuthMode" = "WPA2" -o "$AuthMode" = "WPA" ] ; then
    killall wpa_supplicant
    write_wpa_config                       #此函数生产.conf文件
    sleep 2
    ifconfig $IFACE up
    sleep 2
    wpa_supplicant -i $IFACE -B -c $WPA_CONFIGFILE  #利用wpa_supplicant工具加AP
    #wait wpa config, associ
    sleep 10
    else
    iwconfig $IFACE key off
    iwconfig $IFACE essid "$CONF_ESSID"
    fi
    if [ "$AuthMode" != "WPA2" -a "$AuthMode" != "WPA" ]; then
    if [ "$SET_MODE" = "yes" ] ; then
    if [ "$RUN_MODE" = "debug" ] ; then
    killall $DHCP_CLIENT
    killall wpa_supplicant
    sleep 2
    ifconfig $IFACE up
    sleep 2
    fi
    iwconfig $IFACE mode $ADHOC_MODE
    else
    iwconfig $IFACE mode $DEFAULT_MODE
    fi
    fi
    #check if successed  #判断是否加入成功
    ssidname=$(iwconfig $IFACE | grep $IFACE | awk -F: '{print $2}' | awk '{print $1}')
    cur_bssid=$(iwconfig $IFACE | grep "Access Point:" | awk  '{print $6}')
    cur_mode=$(iwconfig $IFACE | grep Mode | awk -F: '{print $2}' | awk '{print $1}')
    echo $ssidname $cur_bssid $cur_mode
    if [ "$ssidname" != "\"$CONF_ESSID\"" -o "$bssid" != "$cur_bssid" \
    -o "$cur_mode" != "$DEFAULT_MODE" ]; then
    #fail
    return 1
    fi
    if [ -z $FIX_IP ] ; then
    dhcp_pc
    dhcp_ok=$(ifconfig $IFACE  | grep "inet addr" | awk '{print $1}')
    if [ -z $dhcp_ok ]; then
    return 1
    fi
    else
    ifconfig $IFACE $FIX_IP
    fi
    if [ "$RUN_MODE" != "debug" ] ; then
    route add default gateway $SERVER_IP $IFACE
    fi
    return 0
    }

      七、生产wpa_supplicant所需.conf文件函数



    write_wpa_config() {
    #init wpa_supplicant.conf file
    if [ -f $WPA_CONFIGFILE ]; then
    rm -f $WPA_CONFIGFILE
    fi
    cat >$WPA_CONFIGFILE<<-EOF
    ctrl_interface=/var/run/wpa_supplicant
    network={
    ssid="$CONF_ESSID"
    bssid=$bssid
    scan_ssid=1
    key_mgmt=WPA-PSK
    proto=$AuthMode
    pairwise=$EncrypType
    group=$EncrypType
    psk="$PASSWORD"
    }
    EOF
    }

      至此,此脚本全部结束,这个脚本的最好处在于支持wifi信号的漫游。
      
      
      

  • 运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
    2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
    3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
    4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
    5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
    6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
    7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
    8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

    所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-121137-1-1.html 上篇帖子: Delphi在Android下通过WiFI进行调试 下篇帖子: android 2.3 wifi (二)
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码加入运维网微信交流群X

    扫码加入运维网微信交流群

    扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

    扫描微信二维码查看详情

    客服E-mail:kefu@iyunv.com 客服QQ:1061981298


    QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


    提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


    本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



    合作伙伴: 青云cloud

    快速回复 返回顶部 返回列表