From 9314ec141b15996dc0e6a71785efbf491eec8493 Mon Sep 17 00:00:00 2001
From: zhangzengfei <zhangzengfei@smartai.com>
Date: 星期二, 12 九月 2023 15:07:54 +0800
Subject: [PATCH] 修改wifi配置

---
 system-service/sys/system.go             |  156 +++++++++++++-------------
 system-service/controllers/syssetconf.go |   29 ++++
 system-service/iwlist/iwlist.go          |  169 ++++++++++++++++++++++++++++
 system-service/main.go                   |    1 
 4 files changed, 275 insertions(+), 80 deletions(-)

diff --git a/system-service/controllers/syssetconf.go b/system-service/controllers/syssetconf.go
index c5b2efa..a884e95 100644
--- a/system-service/controllers/syssetconf.go
+++ b/system-service/controllers/syssetconf.go
@@ -1020,10 +1020,12 @@
 // @Router /data/api-v/sysset/getWifiList [POST]
 func (sset SysSetController) GetWifiList(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
 	fname := c.PostForm("ifname")
-	wifiList, err := sys.GetWifi(fname)
+	wifiList, err := sys.ScanWifiList(fname)
 	if nil == err {
 		return &bhomeclient.Reply{Success: true, Data: wifiList}
 	} else {
+		logger.Debug("iwlist err,", fname, err.Error())
+
 		return &bhomeclient.Reply{Success: false, Msg: err.Error()}
 	}
 }
@@ -1040,7 +1042,30 @@
 	passwd := c.PostForm("passwd")
 	ssid := c.PostForm("ssid")
 
-	err := sys.ConnectWifi(fname, passwd, ssid)
+	err := sys.ConnectWifi(fname, ssid, passwd)
+	if nil == err {
+		return &bhomeclient.Reply{Success: true, Data: "杩炴帴鎴愬姛!"}
+	} else {
+		msg := err.Error()
+		if strings.Contains(msg, "exit status") {
+			msg = "鍔犲叆澶辫触,璇锋鏌ラ厤缃�!"
+		}
+		return &bhomeclient.Reply{Success: false, Msg: msg}
+	}
+}
+
+// @Summary 杩炴帴wifi
+// @Description 杩炴帴wifi
+// @Produce json
+// @Tags 杩炴帴wifi
+// @Success 200 {string} json "{"code":200, msg:"",data:[],success:true}"
+// @Failure 500 {string} json "{"code":500, msg:"",data:"[]",success:false}"
+// @Router /data/api-v/sysset/connectWifi [POST]
+func (sset SysSetController) DisonnectWifi(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
+	fname := c.PostForm("ifname")
+
+	// 鍏抽棴wifi杩炴帴鏃秙sid 浼燿el
+	err := sys.ConnectWifi(fname, "del", "")
 	if nil == err {
 		return &bhomeclient.Reply{Success: true, Data: "杩炴帴鎴愬姛!"}
 	} else {
diff --git a/system-service/iwlist/iwlist.go b/system-service/iwlist/iwlist.go
new file mode 100644
index 0000000..a175a21
--- /dev/null
+++ b/system-service/iwlist/iwlist.go
@@ -0,0 +1,169 @@
+package iwlist
+
+import (
+	"os/exec"
+	"regexp"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+var (
+	newCellRegexp = regexp.MustCompile(`^Cell\s+(?P<cell_number>.+)\s+-\s+Address:\s(?P<mac>.+)$`)
+	regxp         [7]*regexp.Regexp
+)
+
+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"`
+	Connected      bool    `json:"connected"`
+}
+
+func init() {
+	// precompile regexp
+	regxp = [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) ([]Cell, error) {
+	// execute iwlist for scanning wireless networks
+	cmd := exec.Command("iwlist", interfaceName, "scan")
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		return nil, err
+	}
+
+	wifiList, err := parse(string(out))
+	if err != nil {
+		return wifiList, err
+	}
+
+	// 鑾峰彇褰撳墠杩炴帴鐨剋ifi
+	// 浣跨敤iwconfig 鑾峰彇褰撳墠鎺ュ彛鐨勮繛鎺ョ姸鎬�, 杩囨护鍑鸿繛鎺ョ殑wifi鍚嶇О
+	// 蹇界暐浜哅ode鐨勫垽鏂紝杩炴帴鍚庡簲璇ユ槸Managed
+	//wlan0     IEEE 802.11AC  ESSID:"Basic"  Nickname:"<WIFI@REALTEK>"
+	//          Mode:Managed  Frequency:5.22 GHz  Access Point: 82:45:58:18:17:E6
+	//          Bit Rate:200 Mb/s   Sensitivity:0/0
+	//          Retry:off   RTS thr:off   Fragment thr:off
+	//          Power Management:off
+	//          Link Quality=75/100  Signal level=-53 dBm  Noise level=0 dBm
+	//          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
+	//          Tx excessive retries:0  Invalid misc:0   Missed beacon:0
+
+	reg, _ := regexp.Compile(`ESSID:\"(\w+)\".*\n\s+Mode:(\w+).*Point:\s?(\S+)`)
+	cmd = exec.Command("iwconfig", interfaceName)
+	out, _ = cmd.CombinedOutput()
+
+	res := reg.FindStringSubmatch(string(out))
+	if len(res) == 4 {
+		for i, v := range wifiList {
+			if v.MAC == res[3] {
+				wifiList[i].Connected = true
+				wifiList[0], wifiList[i] = wifiList[i], wifiList[0]
+			}
+		}
+	}
+
+	return wifiList, nil
+}
+
+func parse(input string) (cells []Cell, err error) {
+	lines := strings.Split(input, "\n")
+
+	var cell *Cell
+	var wg sync.WaitGroup
+	var m sync.Mutex
+	for _, line := range lines {
+		line = strings.TrimSpace(line)
+
+		// check new cell value
+		if 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 regexps
+		wg.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()
+	}
+}
diff --git a/system-service/main.go b/system-service/main.go
index f95fe17..168e931 100644
--- a/system-service/main.go
+++ b/system-service/main.go
@@ -155,6 +155,7 @@
 	funcMap[urlPrefix+"/sysset/getWifiList"] = ssController.GetWifiList
 	funcMap[urlPrefix+"/sysset/getDefKeyboardLayout"] = ssController.GetDefKeyboardLayout
 	funcMap[urlPrefix+"/sysset/connectWifi"] = ssController.ConnectWifi
+	funcMap[urlPrefix+"/sysset/disconnectWifi"] = ssController.DisonnectWifi
 	funcMap[urlPrefix+"/sysset/getSysSetting"] = ssController.GetSysSetting
 	funcMap[urlPrefix+"/sysset/updateSysSetting"] = ssController.UpdateSysSetting
 	funcMap[urlPrefix+"/sysset/freedisk"] = ssController.DiskInfo
diff --git a/system-service/sys/system.go b/system-service/sys/system.go
index 41d6e46..c79d6f0 100644
--- a/system-service/sys/system.go
+++ b/system-service/sys/system.go
@@ -11,6 +11,7 @@
 	"strconv"
 	"vamicro/config"
 	"vamicro/extend/util"
+	"vamicro/system-service/iwlist"
 	"vamicro/system-service/models"
 	sysVo "vamicro/system-service/vo"
 
@@ -141,7 +142,7 @@
 	return info, err
 }
 
-//鑾峰彇缃戝崱淇℃伅
+// 鑾峰彇缃戝崱淇℃伅
 func GetNetWorkCards() ([]sysVo.NetWorkCard, error) {
 	interfaces, err := net.Interfaces()
 	if nil != err {
@@ -184,7 +185,7 @@
 	return data, nil
 }
 
-//淇敼IP鍙戝竷娑堟伅
+// 淇敼IP鍙戝竷娑堟伅
 func IpChangePublish(newIp string) bool {
 	//淇敼鍥芥爣ip
 	tmpResourceConf := models.ResourceConfig{}
@@ -213,7 +214,8 @@
 	return false
 }
 
-/**
+/*
+*
 鏇存柊閰嶇疆
 @param serverName 鏈嶅姟鍚嶇О
 @param newIp 鏈嶅姟Ip
@@ -491,7 +493,7 @@
 	return err == nil
 }
 
-//璁剧疆璇█
+// 璁剧疆璇█
 func SetLang(lang string, language string) error {
 	// set env
 	envCMD := exec.Command("/bin/sh", "-c", "LANG=%s", lang)
@@ -525,7 +527,7 @@
 	return err
 }
 
-//鑾峰彇褰撳墠璇█
+// 鑾峰彇褰撳墠璇█
 func GetLang() (string, error) {
 	content, err := execRootCommand("cat /etc/default/locale|grep LANG")
 	if nil == err {
@@ -541,7 +543,7 @@
 	return "", err
 }
 
-//鑾峰彇榛樿閿洏甯冨眬
+// 鑾峰彇榛樿閿洏甯冨眬
 func GetDefKeyboard() (string, error) {
 	content, err := execRootCommand("cat /etc/default/keyboard|grep XKBLAYOUT")
 	if nil == err {
@@ -557,7 +559,7 @@
 	return "", err
 }
 
-//鑾峰彇閿洏甯冨眬
+// 鑾峰彇閿洏甯冨眬
 func GetKeyboardLayouts() (map[string]string, []sysVo.KeyBoardLayout, error) {
 	output, err := execRootCommand("man -P cat xkeyboard-config")
 	if nil != err {
@@ -615,7 +617,7 @@
 	return keyBoardLayoutMap, keyBoardLayouts, nil
 }
 
-//璁剧疆閿洏甯冨眬
+// 璁剧疆閿洏甯冨眬
 func SetKeyboardLayout(layout string) error {
 	cmdStr := fmt.Sprintf("sed -i 's/XKBLAYOUT=.*/XKBLAYOUT=\"%s\"/' /etc/default/keyboard", layout)
 	_, err := execRootCommand(cmdStr)
@@ -623,7 +625,7 @@
 	return err
 }
 
-//鍏抽棴缃戠粶
+// 鍏抽棴缃戠粶
 func DownNetCard(networkAdapter string) error {
 	cmdStr := fmt.Sprintf("ip link set %s down", networkAdapter)
 	_, err := execRootCommand(cmdStr)
@@ -631,7 +633,7 @@
 	return err
 }
 
-//寮�鍚綉缁�
+// 寮�鍚綉缁�
 func UpNetCard(networkAdapter string) error {
 	_, _, err := GetLocalIP(networkAdapter)
 	if err != nil {
@@ -643,7 +645,7 @@
 	return err
 }
 
-//鑾峰彇鏃犵嚎缃戝崱
+// 鑾峰彇鏃犵嚎缃戝崱
 func GetIwDev() ([]string, error) {
 	content, err := execRootCommand("iw dev")
 	if nil == err {
@@ -664,76 +666,74 @@
 	return nil, errors.New("iw dev not found")
 }
 
-//鑾峰彇wifi缃戠粶
-func GetWifi(netcard string) ([]sysVo.WiFi, error) {
-	reg, err := regexp.Compile(`Quality=(\d+)/70[^\n]+\n\s+Encryption key:([^\n]+)\n\s+ESSID:\"([^\"]+)\"`)
-	if nil == err {
-		var wifiList = make([]sysVo.WiFi, 0)
-		info, err := execRootCommand(fmt.Sprintf("iwlist %s scan", netcard))
-		if nil == err {
-			res := reg.FindAllStringSubmatch(string(info), -1)
-			for _, item := range res {
-				if len(item) >= 4 {
-					wifi := sysVo.WiFi{item[3], item[1], item[2]}
-					wifiList = append(wifiList, wifi)
-				}
-			}
-			return wifiList, nil
-		}
-	}
-	return nil, err
+// 鑾峰彇wifi缃戠粶
+func ScanWifiList(netcard string) ([]iwlist.Cell, error) {
+	return iwlist.Scan(netcard)
 }
 
-//杩炴帴WIFI
-func ConnectWifi(fname, passwd, ssid string) error {
-	content, err := execRootCommand(fmt.Sprintf("wpa_cli -i %s add_network", fname))
-	if nil != err {
+// 杩炴帴WIFI
+func ConnectWifi(fname, ssid, passwd string) error {
+	networkConfigScript := "/opt/vasystem/script/wlanconfig"
+
+	// 妫�鏌ユ枃浠舵槸鍚﹀瓨鍦�
+	if _, err := os.Stat(networkConfigScript); err != nil {
 		return err
 	}
-	newid := strings.TrimSpace(string(content))
-	reg, err := regexp.Compile(`^(\d+)$`)
-	if nil == err {
-		b := reg.MatchString(newid)
-		if !b {
-			return errors.New("WIFI鍔犲叆澶辫触")
-		}
-		ret, err := execRootCommand(fmt.Sprintf("wpa_cli -i %s set_network %s ssid '\"%s\"'", fname, newid, ssid))
-		if nil != err {
-			return err
-		}
-		if strings.TrimSpace(string(ret)) != "OK" {
-			return errors.New(string(ret))
-		}
-		ret, err = execRootCommand(fmt.Sprintf("wpa_cli -i %s set_network %s psk '\"%s\"'", fname, newid, passwd))
-		if nil != err {
-			return err
-		}
-		if strings.TrimSpace(string(ret)) != "OK" {
-			return errors.New(string(ret))
-		}
-		ret, err = execRootCommand(fmt.Sprintf("wpa_cli -i %s disconnect", fname))
-		if nil != err {
-			return err
-		}
-		if strings.TrimSpace(string(ret)) != "OK" {
-			return errors.New(string(ret))
-		}
-		ret, err = execRootCommand(fmt.Sprintf("wpa_cli -i %s select_network %s", fname, newid))
-		if nil != err {
-			return err
-		}
-		if strings.TrimSpace(string(ret)) != "OK" {
-			return errors.New(string(ret))
-		}
-		_, err = execRootCommand(fmt.Sprintf("udhcpc -i %s -q -n", fname))
-		if nil != err {
-			return errors.New("瀵嗙爜濂藉儚涓嶅鍝�")
-		}
-		_, err = execRootCommand(fmt.Sprintf("wpa_cli -i %s save_config", fname))
-		return nil
-	} else {
-		return err
-	}
+
+	// # wlanconfig wlan0 Basic Basic2019
+	cmdStr := fmt.Sprintf("%s %s %s %s", networkConfigScript, fname, ssid, passwd)
+	_, err := execRootCommand(cmdStr)
+
+	return err
+
+	//content, err := execRootCommand(fmt.Sprintf("wpa_cli -i %s add_network", fname))
+	//if nil != err {
+	//	return err
+	//}
+	//newid := strings.TrimSpace(string(content))
+	//reg, err := regexp.Compile(`^(\d+)$`)
+	//if nil == err {
+	//	b := reg.MatchString(newid)
+	//	if !b {
+	//		return errors.New("WIFI鍔犲叆澶辫触")
+	//	}
+	//	ret, err := execRootCommand(fmt.Sprintf("wpa_cli -i %s set_network %s ssid '\"%s\"'", fname, newid, ssid))
+	//	if nil != err {
+	//		return err
+	//	}
+	//	if strings.TrimSpace(string(ret)) != "OK" {
+	//		return errors.New(string(ret))
+	//	}
+	//	ret, err = execRootCommand(fmt.Sprintf("wpa_cli -i %s set_network %s psk '\"%s\"'", fname, newid, passwd))
+	//	if nil != err {
+	//		return err
+	//	}
+	//	if strings.TrimSpace(string(ret)) != "OK" {
+	//		return errors.New(string(ret))
+	//	}
+	//	ret, err = execRootCommand(fmt.Sprintf("wpa_cli -i %s disconnect", fname))
+	//	if nil != err {
+	//		return err
+	//	}
+	//	if strings.TrimSpace(string(ret)) != "OK" {
+	//		return errors.New(string(ret))
+	//	}
+	//	ret, err = execRootCommand(fmt.Sprintf("wpa_cli -i %s select_network %s", fname, newid))
+	//	if nil != err {
+	//		return err
+	//	}
+	//	if strings.TrimSpace(string(ret)) != "OK" {
+	//		return errors.New(string(ret))
+	//	}
+	//	_, err = execRootCommand(fmt.Sprintf("udhcpc -i %s -q -n", fname))
+	//	if nil != err {
+	//		return errors.New("瀵嗙爜濂藉儚涓嶅鍝�")
+	//	}
+	//	_, err = execRootCommand(fmt.Sprintf("wpa_cli -i %s save_config", fname))
+	//	return nil
+	//} else {
+	//	return err
+	//}
 }
 
 func ExistService(name string) string {
@@ -744,7 +744,7 @@
 	return string(b)
 }
 
-//閰嶇疆mqtt
+// 閰嶇疆mqtt
 func SetMqttConf(conf *sysVo.MqttConf) error {
 	etcPath := "/etc/mosquitto/mosquitto.conf"
 	pwfile := "/etc/mosquitto/pwfile"

--
Gitblit v1.8.0