树莓派扫描周围路由器选择连接

编程入门 行业动态 更新时间:2024-10-26 15:30:32

树莓派扫描周围<a href=https://www.elefans.com/category/jswz/34/1771256.html style=路由器选择连接"/>

树莓派扫描周围路由器选择连接

开源思路

我自己的代码package mainimport ("errors""fmt""log""net""sort""github/schollz/wifiscan"
)func GetInterfaceIpv4Addr(interfaceName string) (addr net.IP, err error) {var (ief      *net.Interfaceaddrs    []net.Addripv4Addr net.IP)if ief, err = net.InterfaceByName(interfaceName); err != nil { // get interfacereturn}if addrs, err = ief.Addrs(); err != nil { // get addressesreturn}for _, addr := range addrs { // get ipv4 addressif ipv4Addr = addr.(*net.IPNet).IP.To4(); ipv4Addr != nil {break}}if ipv4Addr == nil {return nil, errors.New(fmt.Sprintf("Interface %s don't have an ipv4 address\n", interfaceName))}return ipv4Addr, nil
}
func CheckDHCP(ip net.IP) bool {if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {return false}return true
}
func main() {wifis, err := wifiscan.Scan()if err != nil {log.Fatal(err)}fmt.Println("++++++++++++++++++++++++\r\n")for _, w := range wifis {fmt.Println(w.SSID, w.RSSI)}fmt.Println("++++++++++++++++++++++++\r\n")fmt.Println(wifis)fmt.Println("++++++++++++++++++++++++\r\n")sort.SliceStable(wifis, func(i, j int) bool {return wifis[i].RSSI > wifis[j].RSSI})//.Println(wifis)fmt.Println("++++++++++++++++++++++++\r\n")for _, w := range wifis {fmt.Println(w.SSID, w.RSSI)}fmt.Println("++++++++++++++++++++++++\r\n")iface := "wlan0"ip, err := GetInterfaceIpv4Addr(iface)if err != nil {log.Printf("[WiFi] err: %s\r\n", err)log.Printf("[WiFi] Restart WiFi\r\n")return}log.Printf("[WiFi] %s have IP: %s\r\n", iface, ip.String())if !CheckDHCP(ip) {log.Printf("[WiFi] DHCP requesting is failed\r\n")log.Printf("[WiFi] Restart WiFi\r\n")return}log.Printf("[WiFi]DHCP OK\r\n")
}

台湾自己写 现在可以 准备连接

package mainimport ("errors""fmt""log""net""os/exec""regexp""sort""strconv""strings""sync"
)var (newCellRegexp = regexp.MustCompile(`^Cell\s+(?P<cell_number>.+)\s+-\s+Address:\s(?P<mac>.+)$`)regxp         [7]*regexp.Regexp
)var network_setting_template string = "network={\n" +"        ssid=\"%s\"\n" +"        psk=\"%s\"\n" +"}"var network_setting_with_whitelist_template string = "network={\n" +"        ssid=\"%s\"\n" +"        psk=\"%s\"\n" +"        bssid=\"%s\"\n" +"}"type Cell struct {CellNumber     string  `json:"cell_number"`MAC            string  `json:"mac"`ESSID          string  `json:"essid"`Mode           string  `json:"mode"`Frequency      float32 `json:"frequency"`FrequencyUnits string  `json:"frequency_units"`Channel        int     `json:"channel"`EncryptionKey  bool    `json:"encryption_key"`Encryption     string  `json:"encryption"`SignalQuality  int     `json:"signal_quality"`SignalTotal    int     `json:"signal_total"`SignalLevel    int     `json:"signal_level"`
}func Init() {// precompile regexpregxp = [7]*regexp.Regexp{regexp.MustCompile(`^ESSID:\"(?P<essid>.*)\"$`),regexp.MustCompile(`^Mode:(?P<mode>.+)$`),regexp.MustCompile(`^Frequency:(?P<frequency>[\d.]+) (?P<frequency_units>.+) \(Channel (?P<channel>\d+)\)$`),regexp.MustCompile(`^Encryption key:(?P<encryption_key>.+)$`),regexp.MustCompile(`^IE:\ WPA\ Version\ (?P<wpa>.+)$`),regexp.MustCompile(`^IE:\ IEEE\ 802\.11i/WPA2\ Version\ (?P<wpa2>)$`),regexp.MustCompile(`^Quality=(?P<signal_quality>\d+)/(?P<signal_total>\d+)\s+Signal level=(?P<signal_level>.+) d.+$`),}
}func Scan(interfaceName string, ssid string) ([]Cell, error) {// execute iwlist for scanning wireless networkscmd := exec.Command("iwlist", interfaceName, "scan", "essid", ssid)out, err := cmd.CombinedOutput()if err != nil {return nil, err}// parse fetched result//fmt.Print(string(out))return parse(string(out))
}func Filter(ssid string, c []Cell) []Cell {cell := make([]Cell, 0)for _, v := range c {if ssid == v.ESSID {cell = append(cell, v)}}sort.SliceStable(cell, func(i, j int) bool {return cell[i].SignalLevel > cell[j].SignalLevel})//fmt.Print(cell)return cell
}func parse(input string) (cells []Cell, err error) {lines := strings.Split(input, "\n")var cell *Cellvar wg sync.WaitGroupvar m sync.Mutexfor _, line := range lines {line = strings.TrimSpace(line)// check new cell valueif cellValues := newCellRegexp.FindStringSubmatch(line); len(cellValues) > 0 {cells = append(cells, Cell{CellNumber: cellValues[1],MAC:        cellValues[2],})cell = &cells[len(cells)-1]continue}// compare lines to regexpswg.Add(len(regxp))for _, reg := range regxp {go compare(line, &wg, &m, cell, reg)}wg.Wait()}return
}func compare(line string, wg *sync.WaitGroup, m *sync.Mutex, cell *Cell, reg *regexp.Regexp) {defer wg.Done()if values := reg.FindStringSubmatch(line); len(values) > 0 {keys := reg.SubexpNames()m.Lock()for i := 1; i < len(keys); i++ {switch keys[i] {case "essid":cell.ESSID = values[i]case "mode":cell.Mode = values[i]case "frequency":if frequency, err := strconv.ParseFloat(values[i], 32); err == nil {cell.Frequency = float32(frequency)}case "frequency_units":cell.FrequencyUnits = values[i]case "channel":if channel, err := strconv.ParseInt(values[i], 10, 32); err == nil {cell.Channel = int(channel)}case "encryption_key":if cell.EncryptionKey = values[i] == "on"; cell.EncryptionKey {cell.Encryption = "wep"} else {cell.Encryption = "off"}case "wpa":cell.Encryption = "wpa"case "wpa2":cell.Encryption = "wpa2"case "signal_quality":if quality, err := strconv.ParseInt(values[i], 10, 32); err == nil {cell.SignalQuality = int(quality)}case "signal_total":if total, err := strconv.ParseInt(values[i], 10, 32); err == nil {cell.SignalTotal = int(total)}case "signal_level":if level, err := strconv.ParseInt(values[i], 10, 32); err == nil {cell.SignalLevel = int(level)}}}m.Unlock()}
}func GetInterfaceIpv4Addr(interfaceName string) (addr net.IP, err error) {var (ief      *net.Interfaceaddrs    []net.Addripv4Addr net.IP)if ief, err = net.InterfaceByName(interfaceName); err != nil { // get interfacereturn}if addrs, err = ief.Addrs(); err != nil { // get addressesreturn}for _, addr := range addrs { // get ipv4 addressif ipv4Addr = addr.(*net.IPNet).IP.To4(); ipv4Addr != nil {break}}if ipv4Addr == nil {return nil, errors.New(fmt.Sprintf("Interface %s don't have an ipv4 address\n", interfaceName))}return ipv4Addr, nil
}
func CheckDHCP(ip net.IP) bool {if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {return false}return true
}func Restart(iface string) {cmd := exec.Command("wpa_cli", "-i", iface, "reconfigure")stdout, err := cmd.Output()if err != nil {log.Printf("[WiFi] Restart failed, err : %v\r\n", err)} else {log.Printf("[WiFi] stdout:%s\r\n", stdout)}
}
func GetMAC(iface string) (string, error) {cmd := exec.Command("iwconfig", iface)stdout, err := cmd.Output()if err != nil {log.Printf("[WiFi] GetMAC failed, err : %v\r\n", err)return "", err}str := string(stdout)key := "Access Point: "no_connection_key := "Not-Associated"if strings.Contains(str, no_connection_key) {log.Printf("[WiFi] GetMAC failed, have no connection\r\n")return "", errors.New("Have no wifi connection")}mac_index_start := strings.Index(str, key) + len(key)mac_len := len("xx:xx:xx:xx:xx:xx")return str[mac_index_start : mac_index_start+mac_len], nil
}func main() {Init()//Scan("wlan0", "mCube-Xsens-Employee")Cell,_ := Scan("wlan0", "mCube-Xsens-Employee")for _, w := range Cell {fmt.Println(w.MAC,w.ESSID, w.SignalLevel)}fmt.Println("----------\r\n")Cell = Filter("mCube-Xsens-Employee",Cell)fmt.Println("----------\r\n")for _, w := range Cell {fmt.Println(w.MAC,w.ESSID, w.SignalLevel)}log.Printf("[WiFi]DHCP OK\r\n")
}

小结

代码逻辑说明
WIFINAME := "ZF"(手动修改) 它是PI周围环境中路由器WIFI的名字 也是PI本地保存的WIFI的名字
PI执行扫描 把周围路由器名字叫 WIFINAME 的全部整理出来 放在数组
对数组做排序和排除 所谓排除是把PI本身本地保存的BSSID也就是MAC的这个路由器排除掉
然后做数组中的路由器依次尝试连接 选择DHCP正常的保存记录在本地


修改点是 本地WIFI信息修改以后 尝试连接有如下一些手段
A
    sudo ifconfig wlan0 down
    sudo ifconfig wlan0 up
B
    killall wpa_supplicant 
    wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf 
C   
    wpa_cli -i wlan0 reconfigure
    
D
    sudo service networking restart
目前测试发现D是最好用的 所以Restart选择用D


测试
本地2个路由器都是ZF PI本身WIFI只有2行 测试效果是循环切换2个路由器
为了ABCD准备代码

func Restart(iface string) {cmd := exec.Command("wpa_cli", "-i", iface, "reconfigure")stdout, err := cmd.Output()if err != nil {log.Printf("[WiFiRestart] Restart failed, err : %v\r\n", err)} else {log.Printf("[WiFiRestart] stdout:%s\r\n", stdout)}time.Sleep(time.Minute)exec.Command("wpa_cli", "-i", iface, "reconfigure")
}func Restart(iface string) {cmd := exec.Command("killall", "wpa_supplicant")stdout, err := cmd.Output()if err != nil {log.Printf("[WiFiRestart] Restart failed, err : %v\r\n", err)} else {log.Printf("[WiFiRestart] stdout:%s\r\n", stdout)}cmd = exec.Command("wpa_supplicant", "-B","-i",iface,"-c","/etc/wpa_supplicant/wpa_supplicant.conf")stdout, err = cmd.Output()if err != nil {log.Printf("[WiFiRestart] Restart failed, err : %v\r\n", err)} else {log.Printf("[WiFiRestart] stdout:%s\r\n", stdout)}
}func Restart(iface string) {cmd := exec.Command("service", "networking",  "restart")stdout, err := cmd.Output()if err != nil {log.Printf("[WiFiRestart] Restart failed, err : %v\r\n", err)} else {log.Printf("[WiFiRestart] stdout:%s\r\n", stdout)}time.Sleep(time.Second*10)
}

不要手段修改文件的思路

好文 arm 使用wpa_cli连接wifi - 简书

wpa_cli -i wlan0 add_network


wpa_cli -i wlan0 set_network 1 ssid \"ZF\"

wpa_cli -i wlan0 set_network 1 psk \"HELLO-WORLD\"

wpa_cli -i wlan0 set_network 1 bssid A8:5E:45:FB:84:B4

wpa_cli -i wlan0 enable_network 1


WIN10
wpa_cli -i wlan0 set_network 0 bssid F2:C9:4E:7E:3F:1F

wpa_cli -i wlan0 select_network 1

最后我的代码

package mainimport ("errors""fmt""log""net""os""os/exec""regexp""sort""strconv""strings""sync""time"
)var (newCellRegexp = regexp.MustCompile(`^Cell\s+(?P<cell_number>.+)\s+-\s+Address:\s(?P<mac>.+)$`)regxp         [7]*regexp.Regexp
)var network_setting_template string = "network={\n" +"        ssid=\"%s\"\n" +"        psk=\"%s\"\n" +"}"var network_setting_with_whitelist_template string = "network={\n" +"        ssid=\"%s\"\n" +"        psk=\"%s\"\n" +"        bssid=\"%s\"\n" +"}"type Cell struct {CellNumber     string  `json:"cell_number"`MAC            string  `json:"mac"`ESSID          string  `json:"essid"`Mode           string  `json:"mode"`Frequency      float32 `json:"frequency"`FrequencyUnits string  `json:"frequency_units"`Channel        int     `json:"channel"`EncryptionKey  bool    `json:"encryption_key"`Encryption     string  `json:"encryption"`SignalQuality  int     `json:"signal_quality"`SignalTotal    int     `json:"signal_total"`SignalLevel    int     `json:"signal_level"`
}func Init() {// precompile regexpregxp = [7]*regexp.Regexp{regexp.MustCompile(`^ESSID:\"(?P<essid>.*)\"$`),regexp.MustCompile(`^Mode:(?P<mode>.+)$`),regexp.MustCompile(`^Frequency:(?P<frequency>[\d.]+) (?P<frequency_units>.+) \(Channel (?P<channel>\d+)\)$`),regexp.MustCompile(`^Encryption key:(?P<encryption_key>.+)$`),regexp.MustCompile(`^IE:\ WPA\ Version\ (?P<wpa>.+)$`),regexp.MustCompile(`^IE:\ IEEE\ 802\.11i/WPA2\ Version\ (?P<wpa2>)$`),regexp.MustCompile(`^Quality=(?P<signal_quality>\d+)/(?P<signal_total>\d+)\s+Signal level=(?P<signal_level>.+) d.+$`),}
}func Scan(interfaceName string, ssid string) ([]Cell, error) {// execute iwlist for scanning wireless networkscmd := exec.Command("iwlist", interfaceName, "scan", "essid", ssid)out, err := cmd.CombinedOutput()if err != nil {return nil, err}// parse fetched result//fmt.Print(string(out))return parse(string(out))
}func Filter(ssid string, c []Cell) []Cell {cell := make([]Cell, 0)wpa_config, err := os.ReadFile("/etc/wpa_supplicant/wpa_supplicant.conf")if err != nil {log.Printf("[Filter] Read wpa_supplicant failed\r\n")return cell}wpa_str := string(wpa_config)bssid :=""if strings.Contains(wpa_str, "bssid") {bssid_index_start := strings.Index(wpa_str, "bssid=") + len("bssid=")bssid_index_end   := len("xx:xx:xx:xx:xx:xx") + bssid_index_startbssid = wpa_str[bssid_index_start:bssid_index_end]} for _, v := range c {if ssid == v.ESSID && bssid != v.MAC {cell = append(cell, v)}}sort.SliceStable(cell, func(i, j int) bool {return cell[i].SignalLevel > cell[j].SignalLevel})//fmt.Print(cell)return cell
}func parse(input string) (cells []Cell, err error) {lines := strings.Split(input, "\n")var cell *Cellvar wg sync.WaitGroupvar m sync.Mutexfor _, line := range lines {line = strings.TrimSpace(line)// check new cell valueif cellValues := newCellRegexp.FindStringSubmatch(line); len(cellValues) > 0 {cells = append(cells, Cell{CellNumber: cellValues[1],MAC:        cellValues[2],})cell = &cells[len(cells)-1]continue}// compare lines to regexpswg.Add(len(regxp))for _, reg := range regxp {go compare(line, &wg, &m, cell, reg)}wg.Wait()}return
}func compare(line string, wg *sync.WaitGroup, m *sync.Mutex, cell *Cell, reg *regexp.Regexp) {defer wg.Done()if values := reg.FindStringSubmatch(line); len(values) > 0 {keys := reg.SubexpNames()m.Lock()for i := 1; i < len(keys); i++ {switch keys[i] {case "essid":cell.ESSID = values[i]case "mode":cell.Mode = values[i]case "frequency":if frequency, err := strconv.ParseFloat(values[i], 32); err == nil {cell.Frequency = float32(frequency)}case "frequency_units":cell.FrequencyUnits = values[i]case "channel":if channel, err := strconv.ParseInt(values[i], 10, 32); err == nil {cell.Channel = int(channel)}case "encryption_key":if cell.EncryptionKey = values[i] == "on"; cell.EncryptionKey {cell.Encryption = "wep"} else {cell.Encryption = "off"}case "wpa":cell.Encryption = "wpa"case "wpa2":cell.Encryption = "wpa2"case "signal_quality":if quality, err := strconv.ParseInt(values[i], 10, 32); err == nil {cell.SignalQuality = int(quality)}case "signal_total":if total, err := strconv.ParseInt(values[i], 10, 32); err == nil {cell.SignalTotal = int(total)}case "signal_level":if level, err := strconv.ParseInt(values[i], 10, 32); err == nil {cell.SignalLevel = int(level)}}}m.Unlock()}
}func GetInterfaceIpv4Addr(interfaceName string) (addr net.IP, err error) {var (ief      *net.Interfaceaddrs    []net.Addripv4Addr net.IP)if ief, err = net.InterfaceByName(interfaceName); err != nil { // get interfacereturn}if addrs, err = ief.Addrs(); err != nil { // get addressesreturn}for _, addr := range addrs { // get ipv4 addressif ipv4Addr = addr.(*net.IPNet).IP.To4(); ipv4Addr != nil {break}}if ipv4Addr == nil {return nil, errors.New(fmt.Sprintf("Interface %s don't have an ipv4 address\n", interfaceName))}return ipv4Addr, nil
}func CheckDHCP(ip net.IP) bool {if ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() {return false}return true
}func Restart(iface string) {cmd := exec.Command("service", "networking",  "restart")stdout, err := cmd.Output()if err != nil {log.Printf("[WiFiRestart] Restart failed, err : %v\r\n", err)} else {log.Printf("[WiFiRestart] stdout:%s\r\n", stdout)}time.Sleep(time.Second*10)
}func GetMAC(iface string) (string, error) {cmd := exec.Command("iwconfig", iface)stdout, err := cmd.Output()if err != nil {log.Printf("[WiFi] GetMAC failed, err : %v\r\n", err)return "", err}str := string(stdout)key := "Access Point: "no_connection_key := "Not-Associated"if strings.Contains(str, no_connection_key) {log.Printf("[WiFi] GetMAC failed, have no connection\r\n")return "", errors.New("Have no wifi connection")}mac_index_start := strings.Index(str, key) + len(key)mac_len := len("xx:xx:xx:xx:xx:xx")return str[mac_index_start : mac_index_start+mac_len], nil
}func hande_wpa_supplicant(bssid string) {wpa_config, err := os.ReadFile("/etc/wpa_supplicant/wpa_supplicant.conf")if err != nil {log.Printf("[hande_wpa_supplicant] Read wpa_supplicant failed\r\n")return}wpa_str := string(wpa_config)if strings.Contains(wpa_str, "bssid") { log.Printf("[hande_wpa_supplicant] have one\r\n")bssid_index_start := strings.Index(wpa_str, "bssid=") + len("bssid=")bssid_index_end   := len("xx:xx:xx:xx:xx:xx") + bssid_index_startold_bssid := wpa_str[bssid_index_start:bssid_index_end]wpa_str = strings.Replace(wpa_str, old_bssid, bssid, -1)} else {log.Printf("[hande_wpa_supplicant] have NO\r\n")new_bssid := "\r\n        bssid="new_bssid += bssidfile_index_end := strings.Index(wpa_str, "}")wpa_str = wpa_str[0 : file_index_end-1]wpa_str += new_bssidwpa_str += "\r\n}"}log.Printf("[hande_wpa_supplicant] Write to wpa_supplicant:\r\n%s\r\n", wpa_str)err = os.WriteFile("/etc/wpa_supplicant/wpa_supplicant.conf", []byte(wpa_str), 0644)if err != nil {log.Printf("[hande_wpa_supplicant] Failed to writeerr: %v\r\n", err)return}log.Printf("[hande_wpa_supplicant] ok\r\n")
}func main() {//WIFINAME := "mCube-Xsens-Employee"WIFINAME := "ZF"Init()Cell, _ := Scan("wlan0", WIFINAME)for _, w := range Cell {fmt.Println(w.MAC, w.ESSID, w.SignalLevel)}fmt.Println("----------\r\n")	fmt.Println("----------\r\n")Cell = Filter(WIFINAME, Cell)for _, w := range Cell {fmt.Println(w.MAC, w.ESSID, w.SignalLevel)} fmt.Println("----------\r\n")	fmt.Println("----------\r\n")//hande_wpa_supplicant("A8:5E:45:FB:84:B5")for _, w := range Cell {hande_wpa_supplicant(w.MAC)iface :="wlan0"Restart(iface)ip, err := GetInterfaceIpv4Addr(iface)if err != nil {log.Printf("[WiFiCheck] err: %s\r\n", err)log.Printf("[WiFiCheck] Restart WiFi\r\n")continue}log.Printf("[WiFiCheck] %s have IP: %s\r\n", iface, ip.String())if !CheckDHCP(ip) {log.Printf("[WiFiCheck] DHCP requesting is failed\r\n")log.Printf("[WiFiCheck] Restart WiFi\r\n")continue}log.Printf("[WiFiCheck]OK\r\n")break} log.Printf("886\r\n")
}

更多推荐

树莓派扫描周围路由器选择连接

本文发布于:2024-02-16 18:55:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1691108.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:路由器   树莓派

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!