package openwrt import ( "fmt" "regexp" "strconv" "strings" ) // UCIWirelessConf is the representation of UCI Wireless Configuration type UCIWirelessConf struct { uciClient *UCI Devices []map[string]string DefaultInterface map[string]string Interfaces []*UCIWirelessInterface } // NewUCIWirelessConf builds a new UCIWirelessConf instance func NewUCIWirelessConf(uci *UCI) *UCIWirelessConf { return &UCIWirelessConf{ uciClient: uci, Devices: []map[string]string{}, //, 10), DefaultInterface: map[string]string{}, Interfaces: []*UCIWirelessInterface{}, //, 10), } } // parse wireless.default_radio[0-9] section of UCI Configuration func (wc *UCIWirelessConf) parseDefaultInterface(lines []string) int { matches := map[string]string{ "Name": "default_radio0=", "Type": "default_radio0.type=", "Channel": "default_radio0.channel=", "Hwmode": "default_radio0.hwmode=", "Htmode": "default_radio0.htmode=", "Country": "default_radio0.country=", "Path": "default_radio0.path=", } for _, line := range lines { for key, value := range matches { if strings.Contains(line, value) { wc.DefaultInterface[key] = strings.Split(line, "=")[1] } } } return 0 } func (wc *UCIWirelessConf) parseInterfaces(lines []string) int { matches := map[string]*regexp.Regexp{ "Name": regexp.MustCompile(`@wifi-iface\[[0-9]\]=`), "Device": regexp.MustCompile(`@wifi-iface\[[0-9]\].device=`), "Mode": regexp.MustCompile(`@wifi-iface\[[0-9]\].mode=`), "Ssid": regexp.MustCompile(`@wifi-iface\[[0-9]\].ssid=`), "Encryption": regexp.MustCompile(`@wifi-iface\[[0-9]\].encryption=`), "Key": regexp.MustCompile(`@wifi-iface\[[0-9]\].key=`), } for _, li := range lines { var idx int sIdx := strings.Split(li, "[")[1] sIdx = strings.Split(sIdx, "]")[0] if s, err := strconv.ParseInt(sIdx, 10, 32); err == nil { idx = int(s) } if idx >= len(wc.Interfaces) { for i := 0; i <= idx; i++ { wc.Interfaces = append(wc.Interfaces, NewUCIWirelessInterface()) } } if wc.Interfaces[idx] == nil { wc.Interfaces[idx] = NewUCIWirelessInterface() wc.Interfaces[idx].Index = idx } for key, expr := range matches { if expr.MatchString(li) { value := strings.Split(li, "=")[1] if key == "Name" { wc.Interfaces[idx].Name = value } if key == "Device" { wc.Interfaces[idx].Device = value //FIXME //dev := fmt.Sprintf("wireless.%s", value) //path := wc.uciClient.Show(dev) //wc.Interfaces[idx].DevicePath = strings.Split(path.Stdout, "=")[1] } if key == "Mode" { wc.Interfaces[idx].Mode = value } if key == "Ssid" { wc.Interfaces[idx].Ssid = value } if key == "Encryption" { wc.Interfaces[idx].Encryption = value } if key == "Key" { wc.Interfaces[idx].Key = value } } } } return 0 } func (wc *UCIWirelessConf) parseDevicesConf(lines []string) int { matches := map[string]string{ "Name": "radio[0-9]=", "Type": "radio[0-9].type=", "Channel": "radio[0-9].channel=", "Hwmode": "radio[0-9].hwmode=", "Htmode": "radio[0-9].htmode=", "Country": "radio[0-9].country=", "Path": "radio[0-9].path=", } for _, line := range lines { var idx int re := regexp.MustCompile("[0-9]") rIdx := re.FindString(line) if s, err := strconv.ParseInt(rIdx, 10, 32); err == nil { idx = int(s) } if len(wc.Devices) == 0 { wc.Devices = append(wc.Devices, make(map[string]string)) } if idx >= len(wc.Devices) { for i := 0; i < idx; i++ { wc.Devices = append(wc.Devices, make(map[string]string)) } } if wc.Devices[idx] == nil { wc.Devices[idx] = make(map[string]string) } for key, expr := range matches { re := regexp.MustCompile(expr) if re.MatchString(line) { value := strings.Split(line, "=")[1] value = strings.Trim(value, "'") if key == "Name" { wc.Devices[idx]["Device"] = fmt.Sprintf("radio%d", idx) } wc.Devices[idx][key] = value } } } return 0 } func grep(lines string, pattern string) []string { var res []string for _, line := range strings.Split(strings.TrimSuffix(lines, "\n"), "\n") { re := regexp.MustCompile(pattern) if re.MatchString(line) { res = append(res, line) } } return res } // Load return the Wireless Configuration func (wc *UCIWirelessConf) Load() *UCIWirelessConf { conf := wc.uciClient.Show("wireless") wc.parseDevicesConf(grep(conf.Stdout, "wireless.radio")) wc.parseDefaultInterface(grep(conf.Stdout, "wireless.default_radio0")) wc.parseInterfaces(grep(conf.Stdout, "wireless.@wifi-iface")) return wc }