This repository has been archived on 2024-08-02. You can view files and clone it, but cannot push or open issues or pull requests.
orion/openwrt/uci_wireless_conf.go

180 lines
4.6 KiB
Go

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
}