首页 > 其他 > 详细

【原创】修改WIFI保持连接脚本

时间:2014-04-07 12:03:19      阅读:492      评论:0      收藏:0      [点我收藏+]

【原创】修改WIFI保持连接脚本

  项目中用到wifi,由于无线网络的不稳定性,可能会造成wifi的掉线,这就需要在程序中判断网络的是否联通,并且能在断线后继续搜寻无线网络并重新连接。

并且因为wifi连接有许多现成的工具,所以在这里就利用shell脚本来实现此功能。

  本篇博客主要是记录我修改此脚本到当前项目的记录,包含shell脚本的一些用法和wifi连接工具的用法:

一、初始化函数init_var

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
}

  

二、主循环程序如下

1
2
3
4
5
6
7
8
9
10
11
12
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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[i]} #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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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文件函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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信号的漫游。

 

  

  

【原创】修改WIFI保持连接脚本,布布扣,bubuko.com

【原创】修改WIFI保持连接脚本

原文:http://www.cnblogs.com/M-Bing/p/3647268.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!