WiFi: reworked RPC, CLI, WebClient data structures

This commit is contained in:
MaMe82 2018-09-11 17:43:04 +02:00
parent c7df6b3d01
commit 4a29298b3c
14 changed files with 2074 additions and 1601 deletions

View File

@ -12,15 +12,13 @@ import (
//Empty settings used to store cobra flags
var (
tmpWifiStrReg string = ""
tmpWifiStrChannel uint8 = 0
tmpWifiHideSSID bool = false
tmpWifiDisabled bool = false
tmpWifiDisableNexmon bool = false
tmpWifiSSID string = ""
tmpWifiPSK string = ""
tmpWifiStrReg string = ""
tmpWifiStrChannel uint8 = 0
tmpWifiHideSSID bool = false
tmpWifiDisabled bool = false
tmpWifiDisableNexmon bool = false
tmpWifiSSID string = ""
tmpWifiPSK string = ""
)
/*
@ -40,29 +38,28 @@ var wifiCmd = &cobra.Command{
var wifiSetCmd = &cobra.Command{
Use: "set",
Short: "set WiFi settings",
Long: ``,
Long: ``,
}
var wifiSetAPCmd = &cobra.Command{
Use: "ap",
Short: "Configure WiFi interface as access point",
Long: ``,
Run: cobraWifiSetAP,
Long: ``,
Run: cobraWifiSetAP,
}
var wifiSetStaCmd = &cobra.Command{
Use: "sta",
Short: "Configure WiFi interface to join a network as station",
Long: ``,
Run: cobraWifiSetSta,
Long: ``,
Run: cobraWifiSetSta,
}
var wifiGetCmd = &cobra.Command{
Use: "get",
Short: "get WiFi settings",
Long: ``,
Run: cobraWifiGet,
Long: ``,
Run: cobraWifiGet,
}
func cobraWifiGet(cmd *cobra.Command, args []string) {
@ -78,16 +75,15 @@ func cobraWifiSetAP(cmd *cobra.Command, args []string) {
return
}
fmt.Printf("Deploying WiFi inteface settings:\n\t%v\n", settings)
err = ClientDeployWifiSettings(StrRemoteHost, StrRemotePort, settings)
state, err := ClientDeployWifiSettings(StrRemoteHost, StrRemotePort, settings)
if err != nil {
fmt.Println(status.Convert(err).Message())
os.Exit(-1) //exit with error
} else {
fmt.Printf("%+v\n", state)
}
return
}
@ -101,86 +97,92 @@ func cobraWifiSetSta(cmd *cobra.Command, args []string) {
return
}
fmt.Printf("Deploying WiFi inteface settings:\n\t%v\n", settings)
err = ClientDeployWifiSettings(StrRemoteHost, StrRemotePort, settings)
state,err := ClientDeployWifiSettings(StrRemoteHost, StrRemotePort, settings)
if err != nil {
fmt.Println(status.Convert(err).Message())
os.Exit(-1) //exit with error
} else {
fmt.Printf("%+v\n", state)
}
return
}
func createWifiAPSettings(channel uint8, reg string, strSSID string, strPSK string, hideSsid bool, nonexmon bool, disabled bool) (settings *pb.WiFiSettings, err error) {
func createWifiAPSettings(channel uint8, reg string, strSSID string, strPSK string, hideSsid bool, nonexmon bool, disabled bool) (settings *pb.WiFi2Settings, err error) {
if channel < 1 || channel > 14 {
return nil,errors.New(fmt.Sprintf("Only 2.4GHz channels between 1 and 14 are supported, but '%d' was given\n", channel))
return nil, errors.New(fmt.Sprintf("Only 2.4GHz channels between 1 and 14 are supported, but '%d' was given\n", channel))
}
if len(reg) != 2 {
return nil,errors.New(fmt.Sprintf("Regulatory domain has to consist of two uppercase letters (ISO/IEC 3166-1 alpha2), but '%s' was given\n", reg))
return nil, errors.New(fmt.Sprintf("Regulatory domain has to consist of two uppercase letters (ISO/IEC 3166-1 alpha2), but '%s' was given\n", reg))
}
reg = strings.ToUpper(reg)
if len(strSSID) < 1 || len(strSSID) > 32 {
return nil,errors.New(fmt.Sprintf("SSID has to consist of 1 to 32 ASCII letters (even if hidden), but '%s' was given\n", strSSID))
return nil, errors.New(fmt.Sprintf("SSID has to consist of 1 to 32 ASCII letters (even if hidden), but '%s' was given\n", strSSID))
}
if len(strPSK) > 0 && len(strPSK) < 8 {
return nil,errors.New(fmt.Sprintf("A non-empty PSK implies WPA2 and has to have a minimum of 8 characters, but given PSK has '%d' charactres\n", len(strPSK)))
return nil, errors.New(fmt.Sprintf("A non-empty PSK implies WPA2 and has to have a minimum of 8 characters, but given PSK has '%d' charactres\n", len(strPSK)))
}
settings = &pb.WiFiSettings{
Mode: pb.WiFiSettings_AP,
AuthMode: pb.WiFiSettings_OPEN,
Disabled: disabled,
Reg: reg,
ApChannel: uint32(channel),
ApHideSsid: hideSsid,
BssCfgAP: &pb.BSSCfg{
settings = &pb.WiFi2Settings{
WorkingMode: pb.WiFi2WorkingMode_AP,
AuthMode: pb.WiFi2AuthMode_OPEN,
Disabled: disabled,
Regulatory: reg,
Channel: uint32(channel),
HideSsid: hideSsid,
Ap_BSS: &pb.WiFi2BSSCfg{
SSID: strSSID,
PSK: strPSK,
PSK: strPSK,
},
DisableNexmon: nonexmon,
BssCfgClient: nil, //not needed
Client_BSSList: []*pb.WiFi2BSSCfg{},
Nexmon: !nonexmon,
Name: "default",
}
if len(strPSK) > 0 {
settings.AuthMode = pb.WiFiSettings_WPA2_PSK //if PSK is given use WPA2
settings.AuthMode = pb.WiFi2AuthMode_WPA2_PSK //if PSK is given use WPA2
}
return settings, err
}
func createWifiStaSettings(reg string, strSSID string, strPSK string, nonexmon bool, disabled bool) (settings *pb.WiFiSettings, err error) {
func createWifiStaSettings(reg string, strSSID string, strPSK string, nonexmon bool, disabled bool) (settings *pb.WiFi2Settings, err error) {
if len(reg) != 2 {
return nil,errors.New(fmt.Sprintf("Regulatory domain has to consist of two uppercase letters (ISO/IEC 3166-1 alpha2), but '%s' was given\n", reg))
return nil, errors.New(fmt.Sprintf("Regulatory domain has to consist of two uppercase letters (ISO/IEC 3166-1 alpha2), but '%s' was given\n", reg))
}
reg = strings.ToUpper(reg)
if len(strSSID) < 1 || len(strSSID) > 32 {
return nil,errors.New(fmt.Sprintf("SSID has to consist of 1 to 32 ASCII letters (even if hidden), but '%s' was given\n", strSSID))
return nil, errors.New(fmt.Sprintf("SSID has to consist of 1 to 32 ASCII letters (even if hidden), but '%s' was given\n", strSSID))
}
if len(strPSK) > 0 && len(strPSK) < 8 {
return nil,errors.New(fmt.Sprintf("A non-empty PSK implies WPA2 and has to have a minimum of 8 characters, but given PSK has '%d' charactres\n", len(strPSK)))
return nil, errors.New(fmt.Sprintf("A non-empty PSK implies WPA2 and has to have a minimum of 8 characters, but given PSK has '%d' charactres\n", len(strPSK)))
}
settings = &pb.WiFiSettings{
Mode: pb.WiFiSettings_STA,
AuthMode: pb.WiFiSettings_OPEN,
Disabled: disabled,
Reg: reg,
BssCfgClient: &pb.BSSCfg{
SSID: strSSID,
PSK: strPSK,
settings = &pb.WiFi2Settings{
WorkingMode: pb.WiFi2WorkingMode_STA,
AuthMode: pb.WiFi2AuthMode_OPEN,
Disabled: disabled,
Regulatory: reg,
Client_BSSList: []*pb.WiFi2BSSCfg{
&pb.WiFi2BSSCfg{
SSID: strSSID,
PSK: strPSK,
},
},
DisableNexmon: nonexmon,
BssCfgAP: nil, //not needed
Nexmon: !nonexmon,
Ap_BSS: &pb.WiFi2BSSCfg{}, //not needed
Name: "default",
HideSsid: false,
}
if len(strPSK) > 0 {
settings.AuthMode = pb.WiFiSettings_WPA2_PSK //if PSK is given use WPA2
settings.AuthMode = pb.WiFi2AuthMode_WPA2_PSK //if PSK is given use WPA2
}
return settings, err
@ -193,12 +195,12 @@ func init() {
wifiSetCmd.AddCommand(wifiSetAPCmd)
wifiSetCmd.AddCommand(wifiSetStaCmd)
wifiSetCmd.PersistentFlags().StringVarP(&tmpWifiStrReg, "reg","r", "US", "Sets the regulatory domain according to ISO/IEC 3166-1 alpha2")
wifiSetCmd.PersistentFlags().BoolVarP(&tmpWifiDisabled, "disable","d", false, "The flag disables the WiFi interface (omitting the flag enables the interface")
wifiSetCmd.PersistentFlags().BoolVarP(&tmpWifiDisableNexmon, "nonexmon","n", false, "Don't use the modified nexmon firmware")
wifiSetCmd.PersistentFlags().StringVarP(&tmpWifiSSID, "ssid","s", "", "The SSID to use for an Access Point or to join as station")
wifiSetCmd.PersistentFlags().StringVarP(&tmpWifiPSK, "psk","k", "", "The Pre-Shared-Key to use for the Access Point (if empty, an OPEN AP is created) or for the network")
wifiSetCmd.PersistentFlags().StringVarP(&tmpWifiStrReg, "reg", "r", "US", "Sets the regulatory domain according to ISO/IEC 3166-1 alpha2")
wifiSetCmd.PersistentFlags().BoolVarP(&tmpWifiDisabled, "disable", "d", false, "The flag disables the WiFi interface (omitting the flag enables the interface")
wifiSetCmd.PersistentFlags().BoolVarP(&tmpWifiDisableNexmon, "nonexmon", "n", false, "Don't use the modified nexmon firmware")
wifiSetCmd.PersistentFlags().StringVarP(&tmpWifiSSID, "ssid", "s", "", "The SSID to use for an Access Point or to join as station")
wifiSetCmd.PersistentFlags().StringVarP(&tmpWifiPSK, "psk", "k", "", "The Pre-Shared-Key to use for the Access Point (if empty, an OPEN AP is created) or for the network")
wifiSetAPCmd.Flags().Uint8VarP(&tmpWifiStrChannel, "channel","c", 1, "The WiFi channel to use for the Access Point")
wifiSetAPCmd.Flags().BoolVarP(&tmpWifiHideSSID, "hide","x", false, "Hide the SSID of the Access Point")
wifiSetAPCmd.Flags().Uint8VarP(&tmpWifiStrChannel, "channel", "c", 1, "The WiFi channel to use for the Access Point")
wifiSetAPCmd.Flags().BoolVarP(&tmpWifiHideSSID, "hide", "x", false, "Hide the SSID of the Access Point")
}

View File

@ -258,7 +258,7 @@ func ClientDeployEthernetInterfaceSettings(host string, port string, settings *p
}
func ClientDeployWifiSettings(host string, port string, settings *pb.WiFiSettings) (err error) {
func ClientDeployWifiSettings(host string, port string, settings *pb.WiFi2Settings) (state *pb.WiFi2State, err error) {
// Set up a connection to the server.
address := host + ":" + port
//log.Printf("Connecting %s ...", address)
@ -274,10 +274,8 @@ func ClientDeployWifiSettings(host string, port string, settings *pb.WiFiSetting
ctx, cancel := context.WithTimeout(context.Background(), time.Second * 30)
defer cancel()
_,err = rpcClient.DeployWifiSettings(ctx, settings)
return err
state,err = rpcClient.DeployWiFiSettings2(ctx, settings)
return
}
func ClientHIDRunScript(host string, port string, scriptPath string, timeoutSeconds uint32) (scriptRes *pb.HIDScriptResult, err error) {

1
ntest.go Normal file
View File

@ -0,0 +1 @@
package main

View File

@ -8,6 +8,9 @@
grpc.proto
It has these top-level messages:
WiFi2Settings
WiFi2State
WiFi2BSSCfg
StringMessage
EventRequest
EventValue
@ -33,8 +36,6 @@
DHCPServerSettings
DHCPServerRange
DHCPServerStaticHost
WiFiSettings
BSSCfg
Empty
*/
package P4wnP1_grpc
@ -51,6 +52,53 @@ import (
// is compatible with the jspb package it is being compiled against.
const _ = jspb.JspbPackageIsVersion2
// WiFi2 (distinguish state and settings)
type WiFi2WorkingMode int
const (
WiFi2WorkingMode_UNKNOWN WiFi2WorkingMode = 0
WiFi2WorkingMode_AP WiFi2WorkingMode = 1
WiFi2WorkingMode_STA WiFi2WorkingMode = 2
WiFi2WorkingMode_STA_FAILOVER_AP WiFi2WorkingMode = 3
)
var WiFi2WorkingMode_name = map[int]string{
0: "UNKNOWN",
1: "AP",
2: "STA",
3: "STA_FAILOVER_AP",
}
var WiFi2WorkingMode_value = map[string]int{
"UNKNOWN": 0,
"AP": 1,
"STA": 2,
"STA_FAILOVER_AP": 3,
}
func (x WiFi2WorkingMode) String() string {
return WiFi2WorkingMode_name[int(x)]
}
type WiFi2AuthMode int
const (
WiFi2AuthMode_WPA2_PSK WiFi2AuthMode = 0
WiFi2AuthMode_OPEN WiFi2AuthMode = 1
)
var WiFi2AuthMode_name = map[int]string{
0: "WPA2_PSK",
1: "OPEN",
}
var WiFi2AuthMode_value = map[string]int{
"WPA2_PSK": 0,
"OPEN": 1,
}
func (x WiFi2AuthMode) String() string {
return WiFi2AuthMode_name[int(x)]
}
type EthernetInterfaceSettings_Mode int
const (
@ -77,47 +125,476 @@ func (x EthernetInterfaceSettings_Mode) String() string {
return EthernetInterfaceSettings_Mode_name[int(x)]
}
type WiFiSettings_Mode int
const (
WiFiSettings_AP WiFiSettings_Mode = 0
WiFiSettings_STA WiFiSettings_Mode = 1
WiFiSettings_STA_FAILOVER_AP WiFiSettings_Mode = 2
)
var WiFiSettings_Mode_name = map[int]string{
0: "AP",
1: "STA",
2: "STA_FAILOVER_AP",
}
var WiFiSettings_Mode_value = map[string]int{
"AP": 0,
"STA": 1,
"STA_FAILOVER_AP": 2,
type WiFi2Settings struct {
// Generic
Name string
Disabled bool
Regulatory string
WorkingMode WiFi2WorkingMode
AuthMode WiFi2AuthMode
Channel uint32
Ap_BSS *WiFi2BSSCfg
Client_BSSList []*WiFi2BSSCfg
HideSsid bool
Nexmon bool
}
func (x WiFiSettings_Mode) String() string {
return WiFiSettings_Mode_name[int(x)]
// GetName gets the Name of the WiFi2Settings.
func (m *WiFi2Settings) GetName() (x string) {
if m == nil {
return x
}
return m.Name
}
type WiFiSettings_APAuthMode int
const (
WiFiSettings_WPA2_PSK WiFiSettings_APAuthMode = 0
WiFiSettings_OPEN WiFiSettings_APAuthMode = 1
)
var WiFiSettings_APAuthMode_name = map[int]string{
0: "WPA2_PSK",
1: "OPEN",
}
var WiFiSettings_APAuthMode_value = map[string]int{
"WPA2_PSK": 0,
"OPEN": 1,
// GetDisabled gets the Disabled of the WiFi2Settings.
func (m *WiFi2Settings) GetDisabled() (x bool) {
if m == nil {
return x
}
return m.Disabled
}
func (x WiFiSettings_APAuthMode) String() string {
return WiFiSettings_APAuthMode_name[int(x)]
// GetRegulatory gets the Regulatory of the WiFi2Settings.
func (m *WiFi2Settings) GetRegulatory() (x string) {
if m == nil {
return x
}
return m.Regulatory
}
// GetWorkingMode gets the WorkingMode of the WiFi2Settings.
func (m *WiFi2Settings) GetWorkingMode() (x WiFi2WorkingMode) {
if m == nil {
return x
}
return m.WorkingMode
}
// GetAuthMode gets the AuthMode of the WiFi2Settings.
func (m *WiFi2Settings) GetAuthMode() (x WiFi2AuthMode) {
if m == nil {
return x
}
return m.AuthMode
}
// GetChannel gets the Channel of the WiFi2Settings.
func (m *WiFi2Settings) GetChannel() (x uint32) {
if m == nil {
return x
}
return m.Channel
}
// GetAp_BSS gets the Ap_BSS of the WiFi2Settings.
func (m *WiFi2Settings) GetAp_BSS() (x *WiFi2BSSCfg) {
if m == nil {
return x
}
return m.Ap_BSS
}
// GetClient_BSSList gets the Client_BSSList of the WiFi2Settings.
func (m *WiFi2Settings) GetClient_BSSList() (x []*WiFi2BSSCfg) {
if m == nil {
return x
}
return m.Client_BSSList
}
// GetHideSsid gets the HideSsid of the WiFi2Settings.
func (m *WiFi2Settings) GetHideSsid() (x bool) {
if m == nil {
return x
}
return m.HideSsid
}
// GetNexmon gets the Nexmon of the WiFi2Settings.
func (m *WiFi2Settings) GetNexmon() (x bool) {
if m == nil {
return x
}
return m.Nexmon
}
// MarshalToWriter marshals WiFi2Settings to the provided writer.
func (m *WiFi2Settings) MarshalToWriter(writer jspb.Writer) {
if m == nil {
return
}
if len(m.Name) > 0 {
writer.WriteString(1, m.Name)
}
if m.Disabled {
writer.WriteBool(2, m.Disabled)
}
if len(m.Regulatory) > 0 {
writer.WriteString(3, m.Regulatory)
}
if int(m.WorkingMode) != 0 {
writer.WriteEnum(4, int(m.WorkingMode))
}
if int(m.AuthMode) != 0 {
writer.WriteEnum(5, int(m.AuthMode))
}
if m.Channel != 0 {
writer.WriteUint32(6, m.Channel)
}
if m.Ap_BSS != nil {
writer.WriteMessage(7, func() {
m.Ap_BSS.MarshalToWriter(writer)
})
}
for _, msg := range m.Client_BSSList {
writer.WriteMessage(8, func() {
msg.MarshalToWriter(writer)
})
}
if m.HideSsid {
writer.WriteBool(9, m.HideSsid)
}
if m.Nexmon {
writer.WriteBool(13, m.Nexmon)
}
return
}
// Marshal marshals WiFi2Settings to a slice of bytes.
func (m *WiFi2Settings) Marshal() []byte {
writer := jspb.NewWriter()
m.MarshalToWriter(writer)
return writer.GetResult()
}
// UnmarshalFromReader unmarshals a WiFi2Settings from the provided reader.
func (m *WiFi2Settings) UnmarshalFromReader(reader jspb.Reader) *WiFi2Settings {
for reader.Next() {
if m == nil {
m = &WiFi2Settings{}
}
switch reader.GetFieldNumber() {
case 1:
m.Name = reader.ReadString()
case 2:
m.Disabled = reader.ReadBool()
case 3:
m.Regulatory = reader.ReadString()
case 4:
m.WorkingMode = WiFi2WorkingMode(reader.ReadEnum())
case 5:
m.AuthMode = WiFi2AuthMode(reader.ReadEnum())
case 6:
m.Channel = reader.ReadUint32()
case 7:
reader.ReadMessage(func() {
m.Ap_BSS = m.Ap_BSS.UnmarshalFromReader(reader)
})
case 8:
reader.ReadMessage(func() {
m.Client_BSSList = append(m.Client_BSSList, new(WiFi2BSSCfg).UnmarshalFromReader(reader))
})
case 9:
m.HideSsid = reader.ReadBool()
case 13:
m.Nexmon = reader.ReadBool()
default:
reader.SkipField()
}
}
return m
}
// Unmarshal unmarshals a WiFi2Settings from a slice of bytes.
func (m *WiFi2Settings) Unmarshal(rawBytes []byte) (*WiFi2Settings, error) {
reader := jspb.NewReader(rawBytes)
m = m.UnmarshalFromReader(reader)
if err := reader.Err(); err != nil {
return nil, err
}
return m, nil
}
type WiFi2State struct {
Name string
Regulatory string
WorkingMode WiFi2WorkingMode
AuthMode WiFi2AuthMode
Channel uint32
Bss *WiFi2BSSCfg
HideSsid bool
Nexmon bool
Disabled bool
}
// GetName gets the Name of the WiFi2State.
func (m *WiFi2State) GetName() (x string) {
if m == nil {
return x
}
return m.Name
}
// GetRegulatory gets the Regulatory of the WiFi2State.
func (m *WiFi2State) GetRegulatory() (x string) {
if m == nil {
return x
}
return m.Regulatory
}
// GetWorkingMode gets the WorkingMode of the WiFi2State.
func (m *WiFi2State) GetWorkingMode() (x WiFi2WorkingMode) {
if m == nil {
return x
}
return m.WorkingMode
}
// GetAuthMode gets the AuthMode of the WiFi2State.
func (m *WiFi2State) GetAuthMode() (x WiFi2AuthMode) {
if m == nil {
return x
}
return m.AuthMode
}
// GetChannel gets the Channel of the WiFi2State.
func (m *WiFi2State) GetChannel() (x uint32) {
if m == nil {
return x
}
return m.Channel
}
// GetBss gets the Bss of the WiFi2State.
func (m *WiFi2State) GetBss() (x *WiFi2BSSCfg) {
if m == nil {
return x
}
return m.Bss
}
// GetHideSsid gets the HideSsid of the WiFi2State.
func (m *WiFi2State) GetHideSsid() (x bool) {
if m == nil {
return x
}
return m.HideSsid
}
// GetNexmon gets the Nexmon of the WiFi2State.
func (m *WiFi2State) GetNexmon() (x bool) {
if m == nil {
return x
}
return m.Nexmon
}
// GetDisabled gets the Disabled of the WiFi2State.
func (m *WiFi2State) GetDisabled() (x bool) {
if m == nil {
return x
}
return m.Disabled
}
// MarshalToWriter marshals WiFi2State to the provided writer.
func (m *WiFi2State) MarshalToWriter(writer jspb.Writer) {
if m == nil {
return
}
if len(m.Name) > 0 {
writer.WriteString(1, m.Name)
}
if len(m.Regulatory) > 0 {
writer.WriteString(2, m.Regulatory)
}
if int(m.WorkingMode) != 0 {
writer.WriteEnum(3, int(m.WorkingMode))
}
if int(m.AuthMode) != 0 {
writer.WriteEnum(4, int(m.AuthMode))
}
if m.Channel != 0 {
writer.WriteUint32(5, m.Channel)
}
if m.Bss != nil {
writer.WriteMessage(6, func() {
m.Bss.MarshalToWriter(writer)
})
}
if m.HideSsid {
writer.WriteBool(7, m.HideSsid)
}
if m.Nexmon {
writer.WriteBool(8, m.Nexmon)
}
if m.Disabled {
writer.WriteBool(9, m.Disabled)
}
return
}
// Marshal marshals WiFi2State to a slice of bytes.
func (m *WiFi2State) Marshal() []byte {
writer := jspb.NewWriter()
m.MarshalToWriter(writer)
return writer.GetResult()
}
// UnmarshalFromReader unmarshals a WiFi2State from the provided reader.
func (m *WiFi2State) UnmarshalFromReader(reader jspb.Reader) *WiFi2State {
for reader.Next() {
if m == nil {
m = &WiFi2State{}
}
switch reader.GetFieldNumber() {
case 1:
m.Name = reader.ReadString()
case 2:
m.Regulatory = reader.ReadString()
case 3:
m.WorkingMode = WiFi2WorkingMode(reader.ReadEnum())
case 4:
m.AuthMode = WiFi2AuthMode(reader.ReadEnum())
case 5:
m.Channel = reader.ReadUint32()
case 6:
reader.ReadMessage(func() {
m.Bss = m.Bss.UnmarshalFromReader(reader)
})
case 7:
m.HideSsid = reader.ReadBool()
case 8:
m.Nexmon = reader.ReadBool()
case 9:
m.Disabled = reader.ReadBool()
default:
reader.SkipField()
}
}
return m
}
// Unmarshal unmarshals a WiFi2State from a slice of bytes.
func (m *WiFi2State) Unmarshal(rawBytes []byte) (*WiFi2State, error) {
reader := jspb.NewReader(rawBytes)
m = m.UnmarshalFromReader(reader)
if err := reader.Err(); err != nil {
return nil, err
}
return m, nil
}
type WiFi2BSSCfg struct {
SSID string
PSK string
}
// GetSSID gets the SSID of the WiFi2BSSCfg.
func (m *WiFi2BSSCfg) GetSSID() (x string) {
if m == nil {
return x
}
return m.SSID
}
// GetPSK gets the PSK of the WiFi2BSSCfg.
func (m *WiFi2BSSCfg) GetPSK() (x string) {
if m == nil {
return x
}
return m.PSK
}
// MarshalToWriter marshals WiFi2BSSCfg to the provided writer.
func (m *WiFi2BSSCfg) MarshalToWriter(writer jspb.Writer) {
if m == nil {
return
}
if len(m.SSID) > 0 {
writer.WriteString(1, m.SSID)
}
if len(m.PSK) > 0 {
writer.WriteString(2, m.PSK)
}
return
}
// Marshal marshals WiFi2BSSCfg to a slice of bytes.
func (m *WiFi2BSSCfg) Marshal() []byte {
writer := jspb.NewWriter()
m.MarshalToWriter(writer)
return writer.GetResult()
}
// UnmarshalFromReader unmarshals a WiFi2BSSCfg from the provided reader.
func (m *WiFi2BSSCfg) UnmarshalFromReader(reader jspb.Reader) *WiFi2BSSCfg {
for reader.Next() {
if m == nil {
m = &WiFi2BSSCfg{}
}
switch reader.GetFieldNumber() {
case 1:
m.SSID = reader.ReadString()
case 2:
m.PSK = reader.ReadString()
default:
reader.SkipField()
}
}
return m
}
// Unmarshal unmarshals a WiFi2BSSCfg from a slice of bytes.
func (m *WiFi2BSSCfg) Unmarshal(rawBytes []byte) (*WiFi2BSSCfg, error) {
reader := jspb.NewReader(rawBytes)
m = m.UnmarshalFromReader(reader)
if err := reader.Err(); err != nil {
return nil, err
}
return m, nil
}
// Alive check
@ -2598,276 +3075,6 @@ func (m *DHCPServerStaticHost) Unmarshal(rawBytes []byte) (*DHCPServerStaticHost
return m, nil
}
// WiFi
type WiFiSettings struct {
Disabled bool
Reg string
Mode WiFiSettings_Mode
AuthMode WiFiSettings_APAuthMode
ApChannel uint32
BssCfgAP *BSSCfg
BssCfgClient *BSSCfg
ApHideSsid bool
DisableNexmon bool
}
// GetDisabled gets the Disabled of the WiFiSettings.
func (m *WiFiSettings) GetDisabled() (x bool) {
if m == nil {
return x
}
return m.Disabled
}
// GetReg gets the Reg of the WiFiSettings.
func (m *WiFiSettings) GetReg() (x string) {
if m == nil {
return x
}
return m.Reg
}
// GetMode gets the Mode of the WiFiSettings.
func (m *WiFiSettings) GetMode() (x WiFiSettings_Mode) {
if m == nil {
return x
}
return m.Mode
}
// GetAuthMode gets the AuthMode of the WiFiSettings.
func (m *WiFiSettings) GetAuthMode() (x WiFiSettings_APAuthMode) {
if m == nil {
return x
}
return m.AuthMode
}
// GetApChannel gets the ApChannel of the WiFiSettings.
func (m *WiFiSettings) GetApChannel() (x uint32) {
if m == nil {
return x
}
return m.ApChannel
}
// GetBssCfgAP gets the BssCfgAP of the WiFiSettings.
func (m *WiFiSettings) GetBssCfgAP() (x *BSSCfg) {
if m == nil {
return x
}
return m.BssCfgAP
}
// GetBssCfgClient gets the BssCfgClient of the WiFiSettings.
func (m *WiFiSettings) GetBssCfgClient() (x *BSSCfg) {
if m == nil {
return x
}
return m.BssCfgClient
}
// GetApHideSsid gets the ApHideSsid of the WiFiSettings.
func (m *WiFiSettings) GetApHideSsid() (x bool) {
if m == nil {
return x
}
return m.ApHideSsid
}
// GetDisableNexmon gets the DisableNexmon of the WiFiSettings.
func (m *WiFiSettings) GetDisableNexmon() (x bool) {
if m == nil {
return x
}
return m.DisableNexmon
}
// MarshalToWriter marshals WiFiSettings to the provided writer.
func (m *WiFiSettings) MarshalToWriter(writer jspb.Writer) {
if m == nil {
return
}
if m.Disabled {
writer.WriteBool(1, m.Disabled)
}
if len(m.Reg) > 0 {
writer.WriteString(2, m.Reg)
}
if int(m.Mode) != 0 {
writer.WriteEnum(3, int(m.Mode))
}
if int(m.AuthMode) != 0 {
writer.WriteEnum(4, int(m.AuthMode))
}
if m.ApChannel != 0 {
writer.WriteUint32(5, m.ApChannel)
}
if m.BssCfgAP != nil {
writer.WriteMessage(6, func() {
m.BssCfgAP.MarshalToWriter(writer)
})
}
if m.BssCfgClient != nil {
writer.WriteMessage(7, func() {
m.BssCfgClient.MarshalToWriter(writer)
})
}
if m.ApHideSsid {
writer.WriteBool(8, m.ApHideSsid)
}
if m.DisableNexmon {
writer.WriteBool(10, m.DisableNexmon)
}
return
}
// Marshal marshals WiFiSettings to a slice of bytes.
func (m *WiFiSettings) Marshal() []byte {
writer := jspb.NewWriter()
m.MarshalToWriter(writer)
return writer.GetResult()
}
// UnmarshalFromReader unmarshals a WiFiSettings from the provided reader.
func (m *WiFiSettings) UnmarshalFromReader(reader jspb.Reader) *WiFiSettings {
for reader.Next() {
if m == nil {
m = &WiFiSettings{}
}
switch reader.GetFieldNumber() {
case 1:
m.Disabled = reader.ReadBool()
case 2:
m.Reg = reader.ReadString()
case 3:
m.Mode = WiFiSettings_Mode(reader.ReadEnum())
case 4:
m.AuthMode = WiFiSettings_APAuthMode(reader.ReadEnum())
case 5:
m.ApChannel = reader.ReadUint32()
case 6:
reader.ReadMessage(func() {
m.BssCfgAP = m.BssCfgAP.UnmarshalFromReader(reader)
})
case 7:
reader.ReadMessage(func() {
m.BssCfgClient = m.BssCfgClient.UnmarshalFromReader(reader)
})
case 8:
m.ApHideSsid = reader.ReadBool()
case 10:
m.DisableNexmon = reader.ReadBool()
default:
reader.SkipField()
}
}
return m
}
// Unmarshal unmarshals a WiFiSettings from a slice of bytes.
func (m *WiFiSettings) Unmarshal(rawBytes []byte) (*WiFiSettings, error) {
reader := jspb.NewReader(rawBytes)
m = m.UnmarshalFromReader(reader)
if err := reader.Err(); err != nil {
return nil, err
}
return m, nil
}
type BSSCfg struct {
SSID string
PSK string
}
// GetSSID gets the SSID of the BSSCfg.
func (m *BSSCfg) GetSSID() (x string) {
if m == nil {
return x
}
return m.SSID
}
// GetPSK gets the PSK of the BSSCfg.
func (m *BSSCfg) GetPSK() (x string) {
if m == nil {
return x
}
return m.PSK
}
// MarshalToWriter marshals BSSCfg to the provided writer.
func (m *BSSCfg) MarshalToWriter(writer jspb.Writer) {
if m == nil {
return
}
if len(m.SSID) > 0 {
writer.WriteString(1, m.SSID)
}
if len(m.PSK) > 0 {
writer.WriteString(2, m.PSK)
}
return
}
// Marshal marshals BSSCfg to a slice of bytes.
func (m *BSSCfg) Marshal() []byte {
writer := jspb.NewWriter()
m.MarshalToWriter(writer)
return writer.GetResult()
}
// UnmarshalFromReader unmarshals a BSSCfg from the provided reader.
func (m *BSSCfg) UnmarshalFromReader(reader jspb.Reader) *BSSCfg {
for reader.Next() {
if m == nil {
m = &BSSCfg{}
}
switch reader.GetFieldNumber() {
case 1:
m.SSID = reader.ReadString()
case 2:
m.PSK = reader.ReadString()
default:
reader.SkipField()
}
}
return m
}
// Unmarshal unmarshals a BSSCfg from a slice of bytes.
func (m *BSSCfg) Unmarshal(rawBytes []byte) (*BSSCfg, error) {
reader := jspb.NewReader(rawBytes)
m = m.UnmarshalFromReader(reader)
if err := reader.Err(); err != nil {
return nil, err
}
return m, nil
}
type Empty struct {
}
@ -2939,9 +3146,6 @@ type P4WNP1Client interface {
DeployEthernetInterfaceSettings(ctx context.Context, in *EthernetInterfaceSettings, opts ...grpcweb.CallOption) (*Empty, error)
GetAllDeployedEthernetInterfaceSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*DeployedEthernetInterfaceSettings, error)
GetDeployedEthernetInterfaceSettings(ctx context.Context, in *StringMessage, opts ...grpcweb.CallOption) (*EthernetInterfaceSettings, error)
// WiFi
DeployWifiSettings(ctx context.Context, in *WiFiSettings, opts ...grpcweb.CallOption) (*Empty, error)
GetDeployedWifiSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*WiFiSettings, error)
// HIDScript / job management
HIDRunScript(ctx context.Context, in *HIDScriptRequest, opts ...grpcweb.CallOption) (*HIDScriptResult, error)
HIDRunScriptJob(ctx context.Context, in *HIDScriptRequest, opts ...grpcweb.CallOption) (*HIDScriptJob, error)
@ -2959,6 +3163,9 @@ type P4WNP1Client interface {
EventListen(ctx context.Context, in *EventRequest, opts ...grpcweb.CallOption) (P4WNP1_EventListenClient, error)
// Alive check
EchoRequest(ctx context.Context, in *StringMessage, opts ...grpcweb.CallOption) (*StringMessage, error)
DeployWiFiSettings2(ctx context.Context, in *WiFi2Settings, opts ...grpcweb.CallOption) (*WiFi2State, error)
GetWiFiState2(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*WiFi2State, error)
ListenWiFiStateChanges2(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*WiFi2State, error)
}
type p4WNP1Client struct {
@ -3062,24 +3269,6 @@ func (c *p4WNP1Client) GetDeployedEthernetInterfaceSettings(ctx context.Context,
return new(EthernetInterfaceSettings).Unmarshal(resp)
}
func (c *p4WNP1Client) DeployWifiSettings(ctx context.Context, in *WiFiSettings, opts ...grpcweb.CallOption) (*Empty, error) {
resp, err := c.client.RPCCall(ctx, "DeployWifiSettings", in.Marshal(), opts...)
if err != nil {
return nil, err
}
return new(Empty).Unmarshal(resp)
}
func (c *p4WNP1Client) GetDeployedWifiSettings(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*WiFiSettings, error) {
resp, err := c.client.RPCCall(ctx, "GetDeployedWifiSettings", in.Marshal(), opts...)
if err != nil {
return nil, err
}
return new(WiFiSettings).Unmarshal(resp)
}
func (c *p4WNP1Client) HIDRunScript(ctx context.Context, in *HIDScriptRequest, opts ...grpcweb.CallOption) (*HIDScriptResult, error) {
resp, err := c.client.RPCCall(ctx, "HIDRunScript", in.Marshal(), opts...)
if err != nil {
@ -3219,3 +3408,30 @@ func (c *p4WNP1Client) EchoRequest(ctx context.Context, in *StringMessage, opts
return new(StringMessage).Unmarshal(resp)
}
func (c *p4WNP1Client) DeployWiFiSettings2(ctx context.Context, in *WiFi2Settings, opts ...grpcweb.CallOption) (*WiFi2State, error) {
resp, err := c.client.RPCCall(ctx, "DeployWiFiSettings2", in.Marshal(), opts...)
if err != nil {
return nil, err
}
return new(WiFi2State).Unmarshal(resp)
}
func (c *p4WNP1Client) GetWiFiState2(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*WiFi2State, error) {
resp, err := c.client.RPCCall(ctx, "GetWiFiState2", in.Marshal(), opts...)
if err != nil {
return nil, err
}
return new(WiFi2State).Unmarshal(resp)
}
func (c *p4WNP1Client) ListenWiFiStateChanges2(ctx context.Context, in *Empty, opts ...grpcweb.CallOption) (*WiFi2State, error) {
resp, err := c.client.RPCCall(ctx, "ListenWiFiStateChanges2", in.Marshal(), opts...)
if err != nil {
return nil, err
}
return new(WiFi2State).Unmarshal(resp)
}

File diff suppressed because it is too large Load Diff

View File

@ -3,256 +3,281 @@ syntax = "proto3";
package P4wnP1_grpc;
service P4WNP1 {
//USB gadget
rpc GetDeployedGadgetSetting (Empty) returns (GadgetSettings) {}
rpc DeployGadgetSetting (Empty) returns (GadgetSettings) {}
rpc GetGadgetSettings (Empty) returns (GadgetSettings) {}
rpc SetGadgetSettings (GadgetSettings) returns (GadgetSettings) {}
rpc GetLEDSettings (Empty) returns (LEDSettings) {}
rpc SetLEDSettings (LEDSettings) returns (Empty) {}
rpc MountUMSFile (GadgetSettingsUMS) returns (Empty) {}
//USB gadget
rpc GetDeployedGadgetSetting (Empty) returns (GadgetSettings) { }
rpc DeployGadgetSetting (Empty) returns (GadgetSettings) { }
rpc GetGadgetSettings (Empty) returns (GadgetSettings) { }
rpc SetGadgetSettings (GadgetSettings) returns (GadgetSettings) { }
rpc GetLEDSettings (Empty) returns (LEDSettings) { }
rpc SetLEDSettings (LEDSettings) returns (Empty) { }
rpc MountUMSFile (GadgetSettingsUMS) returns (Empty) { }
//Ethernet
rpc DeployEthernetInterfaceSettings(EthernetInterfaceSettings) returns (Empty) {}
rpc GetAllDeployedEthernetInterfaceSettings(Empty) returns (DeployedEthernetInterfaceSettings) {}
rpc GetDeployedEthernetInterfaceSettings(StringMessage) returns (EthernetInterfaceSettings) {} //StringMessage has to contain the interface name
//Ethernet
rpc DeployEthernetInterfaceSettings (EthernetInterfaceSettings) returns (Empty) { }
rpc GetAllDeployedEthernetInterfaceSettings (Empty) returns (DeployedEthernetInterfaceSettings) { }
rpc GetDeployedEthernetInterfaceSettings (StringMessage) returns (EthernetInterfaceSettings) { } //StringMessage has to contain the interface name
// WiFi
rpc DeployWifiSettings(WiFiSettings) returns (Empty) {}
rpc GetDeployedWifiSettings(Empty) returns (WiFiSettings) {}
/*
// WiFi
rpc DeployWifiSettings (WiFiSettings) returns (WiFiConnectionState) {}
rpc GetDeployedWifiSettings (Empty) returns (WiFiSettings) {}
*/
//HIDScript / job management
rpc HIDRunScript (HIDScriptRequest) returns (HIDScriptResult) { }
rpc HIDRunScriptJob (HIDScriptRequest) returns (HIDScriptJob) { }
rpc HIDGetScriptJobResult (HIDScriptJob) returns (HIDScriptResult) { }
rpc HIDCancelScriptJob (HIDScriptJob) returns (Empty) { }
rpc HIDGetRunningScriptJobs (Empty) returns (HIDScriptJobList) { }
rpc HIDCancelAllScriptJobs (Empty) returns (Empty) { }
rpc HIDGetRunningJobState (HIDScriptJob) returns (HIDRunningJobStateResult) { }
//HIDScript / job management
rpc HIDRunScript(HIDScriptRequest) returns (HIDScriptResult) {}
rpc HIDRunScriptJob(HIDScriptRequest) returns (HIDScriptJob) {}
rpc HIDGetScriptJobResult(HIDScriptJob) returns (HIDScriptResult) {}
rpc HIDCancelScriptJob(HIDScriptJob) returns (Empty) {}
rpc HIDGetRunningScriptJobs(Empty) returns (HIDScriptJobList) {}
rpc HIDCancelAllScriptJobs(Empty) returns (Empty) {}
rpc HIDGetRunningJobState(HIDScriptJob) returns (HIDRunningJobStateResult) {}
//FileSystem
rpc FSWriteFile (WriteFileRequest) returns (Empty) { }
rpc FSReadFile (ReadFileRequest) returns (ReadFileResponse) { }
rpc FSGetFileInfo (FileInfoRequest) returns (FileInfoResponse) { }
rpc FSCreateTempDirOrFile (TempDirOrFileRequest) returns (TempDirOrFileResponse) { }
//FileSystem
rpc FSWriteFile(WriteFileRequest) returns (Empty) {}
rpc FSReadFile(ReadFileRequest) returns (ReadFileResponse) {}
rpc FSGetFileInfo(FileInfoRequest) returns (FileInfoResponse) {}
rpc FSCreateTempDirOrFile(TempDirOrFileRequest) returns (TempDirOrFileResponse) {}
//Events
rpc EventListen (EventRequest) returns (stream Event) { }
//Events
rpc EventListen(EventRequest) returns (stream Event) {}
//Alive check
rpc EchoRequest (StringMessage) returns (StringMessage) { }
//Alive check
rpc EchoRequest(StringMessage) returns (StringMessage) {}
rpc DeployWiFiSettings2 (WiFi2Settings) returns (WiFi2State) {}
rpc GetWiFiState2 (Empty) returns (WiFi2State) {}
rpc ListenWiFiStateChanges2 (Empty) returns (WiFi2State) {}
// ToDo: Template requests (store, load, listStored)
}
/* WiFi2 (distinguish state and settings) */
enum WiFi2WorkingMode {
UNKNOWN = 0;
AP = 1; //acts as access point
STA = 2; //acts as station for an existing access point
STA_FAILOVER_AP = 3; //acts as station, if connection to the given AP isn't possible spawns an own AP
}
enum WiFi2AuthMode {
WPA2_PSK = 0; //AP uses WPA2 pre-shared key
OPEN = 1; //Open System Authentication (no authentication)
}
message WiFi2Settings {
/* Generic */
string name = 1; //for template storage
bool disabled = 2; //disabled means neither hostapd, nor wpa_supplicant are running, the interface could still be enabled
string regulatory = 3; //Regulatory domain per ISO/IEC 3166-1 alpha2
WiFi2WorkingMode working_mode = 4;
WiFi2AuthMode auth_mode = 5;
uint32 channel = 6;
WiFi2BSSCfg ap_BSS = 7; //SSID of AP to spawn + PSK if needed
repeated WiFi2BSSCfg client_BSS_list = 8; //SSID of Infra to join + PSK if needed
bool hide_ssid = 9; //if true, SSID gets hidden for spawned AP
bool nexmon = 13;
}
message WiFi2State {
string name = 1; //name of template in use
string regulatory = 2; //Regulatory domain per ISO/IEC 3166-1 alpha2
WiFi2WorkingMode working_mode = 3;
WiFi2AuthMode auth_mode = 4;
uint32 channel = 5;
WiFi2BSSCfg bss = 6; //SSID currently connected (STA) or spawned (AP)
bool hide_ssid = 7;
bool nexmon = 8;
bool disabled = 9;
}
message WiFi2BSSCfg {
string SSID = 1;
string PSK = 2;
}
/* Alive check */
message StringMessage {
string msg = 1;
string msg = 1;
}
/* Events */
message EventRequest {
int64 listenType = 1;
int64 listenType = 1;
}
message EventValue {
oneof val {
string tstring = 1;
bool tbool = 2;
int64 tint64 = 3;
}
oneof val {
string tstring = 1;
bool tbool = 2;
int64 tint64 = 3;
}
}
message Event {
int64 type = 1;
repeated EventValue values = 2;
int64 type = 1;
repeated EventValue values = 2;
}
/* File System */
message TempDirOrFileRequest {
string dir = 1;
string prefix = 2;
bool onlyFolder = 3;
string dir = 1;
string prefix = 2;
bool onlyFolder = 3;
}
message TempDirOrFileResponse {
string resultPath = 1;
string resultPath = 1;
}
message ReadFileRequest {
string path = 1;
int64 start = 2;
bytes data = 3;
string path = 1;
int64 start = 2;
bytes data = 3;
}
message ReadFileResponse {
int64 readCount = 1;
int64 readCount = 1;
}
message WriteFileRequest {
string path = 1;
bool append = 2;
bool mustNotExist = 3;
bytes data = 4;
string path = 1;
bool append = 2;
bool mustNotExist = 3;
bytes data = 4;
}
message FileInfoRequest {
string path = 1;
string path = 1;
}
message FileInfoResponse {
string name = 1;
int64 size = 2;
uint32 mode = 3;
int64 modTime = 4; //unused
bool isDir = 5;
string name = 1;
int64 size = 2;
uint32 mode = 3;
int64 modTime = 4; //unused
bool isDir = 5;
}
/* HID */
message HIDScriptRequest {
string scriptPath = 1;
uint32 timeoutSeconds = 2; //a timeout > 0 interrupts the HIDScript when reached, meassurement in seconds
string scriptPath = 1;
uint32 timeoutSeconds = 2; //a timeout > 0 interrupts the HIDScript when reached, meassurement in seconds
}
message HIDScriptJob {
uint32 id = 1;
uint32 id = 1;
}
message HIDScriptJobList {
repeated uint32 ids = 1;
repeated uint32 ids = 1;
}
message HIDRunningJobStateResult {
int64 id = 1;
int64 vmId = 2;
string source = 3;
int64 id = 1;
int64 vmId = 2;
string source = 3;
}
message HIDScriptResult {
HIDScriptJob job = 1;
bool isFinished = 2;
string resultJson = 3;
//string logOutput = 4; //will be used to retrieve log output of unfinished scripts, better implemented in dedicated method with stream
HIDScriptJob job = 1;
bool isFinished = 2;
string resultJson = 3;
//string logOutput = 4; //will be used to retrieve log output of unfinished scripts, better implemented in dedicated method with stream
}
/* LED */
message LEDSettings {
uint32 blink_count = 1;
uint32 blink_count = 1;
}
/* End LED */
/* USB Gadget */
message GadgetSettings {
bool enabled = 1;
string vid = 2;
string pid = 3;
string manufacturer = 4;
string product = 5;
string serial = 6;
bool use_CDC_ECM = 7;
bool use_RNDIS = 8;
bool use_HID_KEYBOARD = 9;
bool use_HID_MOUSE = 10;
bool use_HID_RAW = 11;
bool use_UMS = 12;
bool use_SERIAL = 13;
GadgetSettingsEthernet rndis_settings = 14; //Only applicable if RNDIS on
GadgetSettingsEthernet cdc_ecm_settings = 15; //Only applicable if CDC ECM on
GadgetSettingsUMS ums_settings = 16;
//EthernetInterfaceSettings ethernet_settings = 17; //only applicable if RNDIS or CDC ECM on
bool enabled = 1;
string vid = 2;
string pid = 3;
string manufacturer = 4;
string product = 5;
string serial = 6;
bool use_CDC_ECM = 7;
bool use_RNDIS = 8;
bool use_HID_KEYBOARD = 9;
bool use_HID_MOUSE = 10;
bool use_HID_RAW = 11;
bool use_UMS = 12;
bool use_SERIAL = 13;
GadgetSettingsEthernet rndis_settings = 14; //Only applicable if RNDIS on
GadgetSettingsEthernet cdc_ecm_settings = 15; //Only applicable if CDC ECM on
GadgetSettingsUMS ums_settings = 16;
//EthernetInterfaceSettings ethernet_settings = 17; //only applicable if RNDIS or CDC ECM on
}
message GadgetSettingsEthernet {
string host_addr = 1;
string dev_addr = 2;
string host_addr = 1;
string dev_addr = 2;
}
message GadgetSettingsUMS {
bool cdrom = 1;
string file = 2;
bool cdrom = 1;
string file = 2;
}
/* End USB Gadget */
/* Ethernet Interface Settings */
message DeployedEthernetInterfaceSettings {
repeated EthernetInterfaceSettings list = 1;
repeated EthernetInterfaceSettings list = 1;
}
message EthernetInterfaceSettings {
string name = 1;
enum Mode {
MANUAL = 0;
DHCP_CLIENT = 1;
DHCP_SERVER = 2;
UNMANAGED = 3; // Indicates that the settings aren't known, as they aren't managed by the service
}
Mode mode = 2;
string ipAddress4 = 3;
string netmask4 = 4;
bool enabled = 5;
DHCPServerSettings dhcpServerSettings = 6;
bool settingsInUse = 7; //indicates if the given settings are applied to the interface
string name = 1;
enum Mode {
MANUAL = 0;
DHCP_CLIENT = 1;
DHCP_SERVER = 2;
UNMANAGED = 3; // Indicates that the settings aren't known, as they aren't managed by the service
}
Mode mode = 2;
string ipAddress4 = 3;
string netmask4 = 4;
bool enabled = 5;
DHCPServerSettings dhcpServerSettings = 6;
bool settingsInUse = 7; //indicates if the given settings are applied to the interface
}
/* DHCP */
message DHCPServerSettings {
uint32 listenPort = 1; //if a port other thaan 0 is provided, a DNS server is bound to this port in addition to DHCP
string listenInterface = 2;
string leaseFile = 3;
bool notAuthoritative = 4;
bool doNotBindInterface = 5; //if true, DHCP server binds to 0.0.0.0, no matter which interface is given (no restart needed on interface up/down)
string callbackScript = 6; //Script executes when lease is added/deleted `scriptname <add|del> <MAC> <IP> <HOSTNAME>`
uint32 listenPort = 1; //if a port other thaan 0 is provided, a DNS server is bound to this port in addition to DHCP
string listenInterface = 2;
string leaseFile = 3;
bool notAuthoritative = 4;
bool doNotBindInterface = 5; //if true, DHCP server binds to 0.0.0.0, no matter which interface is given (no restart needed on interface up/down)
string callbackScript = 6; //Script executes when lease is added/deleted `scriptname <add|del> <MAC> <IP> <HOSTNAME>`
repeated DHCPServerRange ranges = 7;
repeated DHCPServerRange ranges = 7;
//repeated DHCPServerOption options = 8;
map<uint32, string> options = 8; //Replaced by map (dealing with key duplicates is ONLY PARTIALY handled by proto3), See RFC 2132 for details of available options
repeated DHCPServerStaticHost staticHosts = 9;
repeated DHCPServerStaticHost staticHosts = 9;
}
//Could be used for IPv4 or IPv6 (refer dnsmasq docs), nor field for prefix length (default is 64)
message DHCPServerRange {
string rangeLower = 1; //Lowest IP of DHCP range
string rangeUpper = 2; //Highest IP of DHCP range
string leaseTime = 3;
string rangeLower = 1; //Lowest IP of DHCP range
string rangeUpper = 2; //Highest IP of DHCP range
string leaseTime = 3;
}
//Used for static leases
message DHCPServerStaticHost {
string mac = 1;
string ip = 2;
string mac = 1;
string ip = 2;
}
/* End DHCP */
/* WiFi */
message WiFiSettings {
enum Mode {
AP = 0; //acts as access point
STA = 1; //acts as station for an existing access point
STA_FAILOVER_AP = 2; //acts as station, if connection to the given AP isn't possible spawns an own AP
}
enum APAuthMode {
WPA2_PSK = 0; //AP uses WPA2 pre-shared key
OPEN = 1; //Open System Authentication (no authentication)
}
bool disabled = 1;
string reg = 2; //Regulatory domain per ISO/IEC 3166-1 alpha2
Mode mode = 3;
APAuthMode auth_mode = 4;
uint32 ap_channel = 5;
BSSCfg BssCfgAP = 6; //SSID of AP to spawn + PSK if needed
BSSCfg BssCfgClient = 7; //SSID of Infra to join + PSK if needed
bool ap_hide_ssid = 8; //if true, SSID gets hidden for spawned AP
bool disable_nexmon = 10; //if true, legacy driver / firmware is used instead of nexmon
message Empty {
}
message BSSCfg {
string SSID = 1;
string PSK = 2;
}
/* End WiFI */
message Empty {}

View File

@ -2,59 +2,400 @@ package service
import (
pb "github.com/mame82/P4wnP1_go/proto"
"log"
"github.com/mame82/P4wnP1_go/netlink"
"sync"
"os/exec"
"github.com/mame82/P4wnP1_go/service/util"
"net"
"errors"
"fmt"
"os/exec"
"strings"
"os"
"io/ioutil"
"syscall"
"log"
"time"
"sync"
"syscall"
"net"
"io/ioutil"
"os"
"regexp"
"strconv"
)
const (
wifi_if_name string = "wlan0"
)
//ToDo: big to do ... move all the shitty command tool line wrapping/parsing (iw, hostapd, wpa_supplicant etc.) to dedicated netlink/nl80211 implementation
//VERY LOW PRIORITY, as this basically means reimplementing the whole toolset for a way too small benefit
type WiFiAuthMode int
const (
WiFiAuthMode_OPEN WiFiAuthMode = iota
//WiFiAuthMode_WEP
WiFiAuthMode_WPA_PSK
WiFiAuthMode_WPA2_PSK
WiFiAuthMode_UNSUPPORTED
)
const (
WPA_SUPPLICANT_CONNECT_TIMEOUT = time.Second * 20
)
type WifiState struct {
mutexSettings *sync.Mutex
Settings *pb.WiFiSettings
CmdWpaSupplicant *exec.Cmd
mutexWpaSupplicant *sync.Mutex
CmdHostapd *exec.Cmd
mutexHostapd *sync.Mutex
IfaceName string
PathWpaSupplicantConf string
PathHostapdConf string
LoggerHostapd *util.TeeLogger
LoggerWpaSupplicant *util.TeeLogger
OutMonitorWpaSupplicant *wpaSupplicantOutMonitor
func wifiCheckExternalBinaries() error {
if !binaryAvailable("wpa_supplicant") {
return errors.New("wpa_supplicant seems to be missing, please install it")
}
// to create wpa_supplicant.conf
if !binaryAvailable("wpa_passphrase") {
return errors.New("wpa_passphrase seems to be missing, please install it")
}
if !binaryAvailable("hostapd") {
return errors.New("hostapd seems to be missing, please install it")
}
// for wifiScan
if !binaryAvailable("iw") {
return errors.New("The tool 'iw' seems to be missing, please install it")
}
return nil
}
type WiFiService struct {
State *pb.WiFi2State
Settings *pb.WiFi2Settings
mutexSettings *sync.Mutex // Lock settings on change
CmdWpaSupplicant *exec.Cmd //Manages wpa-supplicant process
mutexWpaSupplicant *sync.Mutex //mutex for wpa-supplicant proc
CmdHostapd *exec.Cmd //Manages hostapd process
mutexHostapd *sync.Mutex //hostapd proc lock
IfaceName string //Name of WiFi interface
PathWpaSupplicantConf string // path to config file for wpa-supplicant
PathHostapdConf string // path to config file for hostapd
LoggerHostapd *util.TeeLogger //logger for hostapd
LoggerWpaSupplicant *util.TeeLogger //logger for WPA supplicant
OutMonitorWpaSupplicant *wpaSupplicantOutMonitor //Monitors wpa_supplicant output and sets signals where needed
}
func (wSvc *WiFiService) StartHostapd() (err error) {
log.Printf("Starting hostapd for interface '%s'...\n", wSvc.IfaceName)
wSvc.mutexHostapd.Lock()
defer wSvc.mutexHostapd.Unlock()
//stop hostapd if already running
if wSvc.CmdHostapd != nil {
// avoid deadlock
wSvc.mutexHostapd.Unlock()
wSvc.StopHostapd()
wSvc.mutexHostapd.Lock()
}
wSvc.CmdHostapd = exec.Command("/usr/sbin/hostapd", wSvc.PathHostapdConf)
wSvc.CmdHostapd.Stdout = wSvc.LoggerHostapd.LogWriter
wSvc.CmdHostapd.Stderr = wSvc.LoggerHostapd.LogWriter
err = wSvc.CmdHostapd.Start()
if err != nil {
wSvc.CmdHostapd.Wait()
return errors.New(fmt.Sprintf("Error starting hostapd '%v'", err))
}
log.Printf("... hostapd for interface '%s' started\n", wSvc.IfaceName)
return nil
}
func (wSvc *WiFiService) StopHostapd() (err error) {
eSuccess := fmt.Sprintf("... hostapd for interface '%s' stopped", wSvc.IfaceName)
eCantStop := fmt.Sprintf("... couldn't terminate hostapd for interface '%s'", wSvc.IfaceName)
wSvc.mutexHostapd.Lock()
defer wSvc.mutexHostapd.Unlock()
if wSvc.CmdHostapd == nil {
log.Printf("... hostapd for interface '%s' isn't running, no need to stop it\n", wSvc.IfaceName)
return nil
}
wSvc.CmdHostapd.Process.Signal(syscall.SIGTERM)
wSvc.CmdHostapd.Wait()
if !wSvc.CmdHostapd.ProcessState.Exited() {
log.Printf("... hostapd didn't react on SIGTERM for interface '%s', trying SIGKILL\n", wSvc.IfaceName)
wSvc.CmdHostapd.Process.Kill()
time.Sleep(500 * time.Millisecond)
if wSvc.CmdHostapd.ProcessState.Exited() {
wSvc.CmdHostapd = nil
log.Println(eSuccess)
return nil
} else {
log.Println(eCantStop)
return errors.New(eCantStop)
}
}
wSvc.CmdHostapd = nil
log.Println(eSuccess)
return nil
}
func (wSvc *WiFiService) StopWpaSupplicant() (err error) {
eSuccess := fmt.Sprintf("... wpa_supplicant for interface '%s' stopped", wSvc.IfaceName)
eCantStop := fmt.Sprintf("... couldn't terminate wpa_supplicant for interface '%s'", wSvc.IfaceName)
log.Printf("... stop running wpa_supplicant processes for interface '%s'\n", wSvc.IfaceName)
wSvc.mutexWpaSupplicant.Lock()
defer wSvc.mutexWpaSupplicant.Unlock()
if wSvc.CmdWpaSupplicant == nil {
log.Printf("... wpa_supplicant for interface '%s' wasn't running, no need to stop it\n", wSvc.IfaceName)
return nil
}
log.Printf("... sending SIGTERM for wpa_supplicant on interface '%s' with PID\n", wSvc.IfaceName, wSvc.CmdWpaSupplicant.Process.Pid)
wSvc.CmdWpaSupplicant.Process.Signal(syscall.SIGTERM)
wSvc.CmdWpaSupplicant.Wait()
if !wSvc.CmdWpaSupplicant.ProcessState.Exited() {
log.Printf("... wpa_supplicant didn't react on SIGTERM for interface '%s', trying SIGKILL\n", wSvc.IfaceName)
wSvc.CmdWpaSupplicant.Process.Kill()
time.Sleep(500 * time.Millisecond)
if wSvc.CmdWpaSupplicant.ProcessState.Exited() {
wSvc.CmdWpaSupplicant = nil
log.Println(eSuccess)
return nil
} else {
log.Println(eCantStop)
return errors.New(eCantStop)
}
}
wSvc.CmdWpaSupplicant = nil
log.Println(eSuccess)
return nil
}
func (wSvc *WiFiService) StartWpaSupplicant(timeout time.Duration) (err error) {
log.Printf("Starting wpa_supplicant for interface '%s'...\n", wSvc.IfaceName)
wSvc.mutexWpaSupplicant.Lock()
defer wSvc.mutexWpaSupplicant.Unlock()
//stop wpa_supplicant if already running
if wSvc.CmdWpaSupplicant != nil {
// avoid dead lock
wSvc.mutexWpaSupplicant.Unlock()
wSvc.StopWpaSupplicant()
wSvc.mutexWpaSupplicant.Lock()
}
//we monitor output of wpa_supplicant till we are connected, fail due to wrong PSK or timeout is reached
//Note: PID file creation doesn't work when not started as daemon, so we do it manually, later on
wSvc.CmdWpaSupplicant = exec.Command("/sbin/wpa_supplicant", "-c", wSvc.PathWpaSupplicantConf, "-i", wSvc.IfaceName)
wSvc.CmdWpaSupplicant.Stdout = wSvc.LoggerWpaSupplicant.LogWriter
err = wSvc.CmdWpaSupplicant.Start()
if err != nil {
return err
}
//wait for result in output
connected, errcon := wSvc.OutMonitorWpaSupplicant.WaitConnectResultOnce(timeout)
if errcon != nil {
log.Printf("... wpa_supplicant reached timeout of '%v' without beeing able to connect to given network\n", timeout)
log.Println("... killing wpa_supplicant")
// avoid dead lock
wSvc.mutexWpaSupplicant.Unlock()
wSvc.StopWpaSupplicant()
wSvc.mutexWpaSupplicant.Lock()
return errors.New("TIMEOUT REACHED")
}
if connected {
//We could return success and keep wpa_supplicant running
log.Println("... connected to given WiFi network, wpa_supplicant running")
return nil
} else {
//we stop wpa_supplicant and return err
log.Println("... seems the wrong PSK was provided for the given WiFi network, stopping wpa_supplicant ...")
//wifiStopWpaSupplicant(nameIface)
log.Println("... killing wpa_supplicant")
// avoid dead lock
wSvc.mutexWpaSupplicant.Unlock()
wSvc.StopWpaSupplicant()
wSvc.mutexWpaSupplicant.Lock()
return errors.New("Wrong PSK")
}
return nil
}
func (wSvc *WiFiService) GetState() pb.WiFi2State {
return *wSvc.State
}
func MatchGivenBBSToScanResult(scanRes []BSS, targets []*pb.WiFi2BSSCfg) (matches []*pb.WiFi2BSSCfg) {
for _,bssCfgTarget := range targets {
for _,bssCfgScan := range scanRes {
if bssCfgScan.SSID == bssCfgTarget.SSID {
// SSID match, possible candidate
matches = append(matches, bssCfgTarget)
}
}
}
return
}
func (wSvc *WiFiService) runStaMode(newWifiSettings *pb.WiFi2Settings) (err error) {
if len(newWifiSettings.Client_BSSList) == 0 {
return errors.New("Error: WiFi mode set to station (STA) but no BSS configurations provided")
}
//scan for provided wifi
scanres, err := WifiScan(wSvc.IfaceName)
if err != nil {
return errors.New(fmt.Sprintf("Scanning for existing WiFi networks failed: %v", err))
}
matchingBssList := MatchGivenBBSToScanResult(scanres, newWifiSettings.Client_BSSList)
if len(matchingBssList) == 0 {
return errors.New(fmt.Sprintf("Non of the given SSIDs found during scan\n"))
}
// Create config for the remaining networks
confstr, err := wifiCreateWpaSupplicantConfStringList(matchingBssList)
if err != nil { return err }
// store config to file
log.Printf("Creating wpa_supplicant configuration file at '%s'\n", wSvc.PathWpaSupplicantConf)
err = ioutil.WriteFile(wSvc.PathWpaSupplicantConf, []byte(confstr), os.ModePerm)
if err != nil { return err }
//ToDo: proper error handling, in case connection not possible
err = wSvc.StartWpaSupplicant(WPA_SUPPLICANT_CONNECT_TIMEOUT)
if err != nil { return err }
wSvc.State.Bss.SSID = "unknown SSID"
wSvc.State.Channel = newWifiSettings.Channel
wSvc.State.Regulatory = newWifiSettings.Regulatory
wSvc.State.HideSsid = newWifiSettings.HideSsid
wSvc.State.WorkingMode = pb.WiFi2WorkingMode_STA
wSvc.State.Disabled = false
return nil
}
// ToDo: Output monitor for AP-ENABLED (same approach as for wpa_supplicant)
func (wSvc *WiFiService) runAPMode(newWifiSettings *pb.WiFi2Settings) (err error) {
//generate hostapd.conf (overwrite old one)
hostapdCreateConfigFile2(newWifiSettings, wSvc.PathHostapdConf)
//start hostapd
err = wSvc.StartHostapd()
if err != nil {
wSvc.State.WorkingMode = pb.WiFi2WorkingMode_UNKNOWN
return err
}
// update Connection wSvc
wSvc.State.Bss.SSID = newWifiSettings.Ap_BSS.SSID
wSvc.State.Channel = newWifiSettings.Channel
wSvc.State.Regulatory = newWifiSettings.Regulatory
wSvc.State.HideSsid = newWifiSettings.HideSsid
wSvc.State.WorkingMode = pb.WiFi2WorkingMode_AP
wSvc.State.Disabled = false
return nil
}
func (wSvc *WiFiService) DeploySettings(newWifiSettings *pb.WiFi2Settings) (wstate *pb.WiFi2State, err error) {
log.Println("Deploying new WiFi settings...")
log.Printf("Settings: %+v\n", newWifiSettings)
wSvc.mutexSettings.Lock()
defer wSvc.mutexSettings.Unlock()
// Reset wSvc to unknown, if something goes wrong, there's no wpa_supplicant or hostapd
wSvc.State.WorkingMode = pb.WiFi2WorkingMode_UNKNOWN
//ToDo: Dis/Enable nexmon if needed
//stop wpa_supplicant if needed
err = wSvc.StopWpaSupplicant()
if err != nil { return wSvc.State, err}
//kill hostapd in case it is still running
err = wSvc.StopHostapd()
if err != nil { return wSvc.State, err}
wSvc.State.Disabled = true
if !newWifiSettings.Disabled {
switch newWifiSettings.WorkingMode {
case pb.WiFi2WorkingMode_AP:
err = wSvc.runAPMode(newWifiSettings)
case pb.WiFi2WorkingMode_STA, pb.WiFi2WorkingMode_STA_FAILOVER_AP:
errSta := wSvc.runStaMode(newWifiSettings)
if errSta != nil {
//in failover mode, we try to enable AP first
if newWifiSettings.WorkingMode == pb.WiFi2WorkingMode_STA_FAILOVER_AP {
log.Println(errSta)
log.Printf("Trying to fail over to Access Point Mode...")
err = wSvc.runAPMode(newWifiSettings)
} else {
err = errSta
}
}
default:
// None allowed working mode, so we leave wSvc as UNKNOWN
err = errors.New("Unknown working mode")
}
}
if err == nil {
log.Printf("... WiFi settings deployed successfully\n")
} else {
log.Printf("... deploying WiFi settings failed: %s\n", err.Error())
}
// update settings (wSvc is updated by runAPMode/runStaMode)
wSvc.Settings = newWifiSettings
return wSvc.State, nil
}
func NewWifiService() (res *WiFiService) {
ifName := wifi_if_name
err := wifiCheckExternalBinaries()
if err != nil { panic(err) }
//Check interface existence
if exists,_ := CheckInterfaceExistence(ifName); !exists {
panic(errors.New(fmt.Sprintf("WiFi interface '%s' not present")))
}
res = &WiFiService{
mutexSettings: &sync.Mutex{},
CmdWpaSupplicant: nil,
mutexWpaSupplicant: &sync.Mutex{},
CmdHostapd: nil,
mutexHostapd: &sync.Mutex{},
IfaceName: ifName,
PathWpaSupplicantConf: fmt.Sprintf("/tmp/wpa_supplicant_%s.conf", ifName),
PathHostapdConf: fmt.Sprintf("/tmp/hostapd_%s.conf", ifName),
}
res.OutMonitorWpaSupplicant = NewWpaSupplicantOutMonitor()
res.LoggerHostapd = util.NewTeeLogger(true)
res.LoggerHostapd.SetPrefix("hostapd: ")
res.LoggerWpaSupplicant = util.NewTeeLogger(true)
res.LoggerWpaSupplicant.SetPrefix("wpa_supplicant: ")
res.LoggerWpaSupplicant.AddOutput(res.OutMonitorWpaSupplicant) // add watcher too tee'ed output writers
// Initial settings and state on service start
res.Settings = &pb.WiFi2Settings{
Disabled: false,
WorkingMode: pb.WiFi2WorkingMode_AP,
Client_BSSList: []*pb.WiFi2BSSCfg{},
Ap_BSS: &pb.WiFi2BSSCfg{},
}
res.State = &pb.WiFi2State{
Disabled: true,
WorkingMode: pb.WiFi2WorkingMode_UNKNOWN,
Bss: &pb.WiFi2BSSCfg{},
}
return res
}
type wpaSupplicantOutMonitor struct {
resultReceived *util.Signal
result bool
@ -108,422 +449,26 @@ func NewWpaSupplicantOutMonitor() *wpaSupplicantOutMonitor {
}
}
func NewWifiState(startupSettings *pb.WiFiSettings, ifName string) (res *WifiState) {
if !binaryAvailable("wpa_supplicant") {
panic("wpa_supplicant seems to be missing, please install it")
}
// to create wpa_supplicant.conf
if !binaryAvailable("wpa_passphrase") {
panic("wpa_passphrase seems to be missing, please install it")
}
if !binaryAvailable("hostapd") {
panic("hostapd seems to be missing, please install it")
}
// for wifiScan
if !binaryAvailable("iw") {
panic("The tool 'iw' seems to be missing, please install it")
}
res = &WifiState{
mutexSettings: &sync.Mutex{},
IfaceName: ifName,
Settings: startupSettings,
CmdWpaSupplicant: nil,
mutexWpaSupplicant: &sync.Mutex{},
CmdHostapd: nil,
mutexHostapd: &sync.Mutex{},
PathWpaSupplicantConf: fmt.Sprintf("/tmp/wpa_supplicant_%s.conf", ifName),
PathHostapdConf: fmt.Sprintf("/tmp/hostapd_%s.conf", ifName),
}
type WiFiAuthMode int
res.OutMonitorWpaSupplicant = NewWpaSupplicantOutMonitor()
res.LoggerHostapd = util.NewTeeLogger(true)
res.LoggerHostapd.SetPrefix("hostapd: ")
res.LoggerWpaSupplicant = util.NewTeeLogger(true)
res.LoggerWpaSupplicant.SetPrefix("wpa_supplicant: ")
res.LoggerWpaSupplicant.AddOutput(res.OutMonitorWpaSupplicant) // add watcher too tee'ed output writers
return
}
func (wifiState *WifiState) StartHostapd() (err error) {
log.Printf("Starting hostapd for interface '%s'...\n", wifiState.IfaceName)
wifiState.mutexHostapd.Lock()
defer wifiState.mutexHostapd.Unlock()
//check if interface is valid
if_exists, _ := CheckInterfaceExistence(wifiState.IfaceName)
if !if_exists {
return errors.New(fmt.Sprintf("The given interface '%s' doesn't exist", wifiState.IfaceName))
}
//stop hostapd if already running
if wifiState.CmdHostapd != nil {
// avoid deadlock
wifiState.mutexHostapd.Unlock()
wifiState.StopHostapd()
wifiState.mutexHostapd.Lock()
}
//We use the run command and allow hostapd to daemonize
//wifiState.CmdHostapd = exec.Command("/usr/sbin/hostapd", "-f", logFileHostapd(wifiState.IfaceName), wifiState.PathHostapdConf)
wifiState.CmdHostapd = exec.Command("/usr/sbin/hostapd", wifiState.PathHostapdConf)
wifiState.CmdHostapd.Stdout = wifiState.LoggerHostapd.LogWriter
wifiState.CmdHostapd.Stderr = wifiState.LoggerHostapd.LogWriter
err = wifiState.CmdHostapd.Start()
if err != nil {
//bytes, _ := wifiState.CmdHostapd.CombinedOutput()
//println(string(bytes))
wifiState.CmdHostapd.Wait()
return errors.New(fmt.Sprintf("Error starting hostapd '%v'", err))
}
log.Printf("... hostapd for interface '%s' started\n", wifiState.IfaceName)
return nil
}
func (wifiState *WifiState) StopHostapd() (err error) {
eSuccess := fmt.Sprintf("... hostapd for interface '%s' stopped", wifiState.IfaceName)
eCantStop := fmt.Sprintf("... couldn't terminate hostapd for interface '%s'", wifiState.IfaceName)
wifiState.mutexHostapd.Lock()
defer wifiState.mutexHostapd.Unlock()
if wifiState.CmdHostapd == nil {
log.Printf("... hostapd for interface '%s' isn't running, no need to stop it\n", wifiState.IfaceName)
return nil
}
wifiState.CmdHostapd.Process.Signal(syscall.SIGTERM)
wifiState.CmdHostapd.Wait()
if !wifiState.CmdHostapd.ProcessState.Exited() {
log.Printf("... hostapd didn't react on SIGTERM for interface '%s', trying SIGKILL\n", wifiState.IfaceName)
wifiState.CmdHostapd.Process.Kill()
time.Sleep(500 * time.Millisecond)
if wifiState.CmdHostapd.ProcessState.Exited() {
wifiState.CmdHostapd = nil
log.Println(eSuccess)
return nil
} else {
log.Println(eCantStop)
return errors.New(eCantStop)
}
}
wifiState.CmdHostapd = nil
log.Println(eSuccess)
return nil
}
func (wifiState *WifiState) StopWpaSupplicant() (err error) {
eSuccess := fmt.Sprintf("... wpa_supplicant for interface '%s' stopped", wifiState.IfaceName)
eCantStop := fmt.Sprintf("... couldn't terminate wpa_supplicant for interface '%s'", wifiState.IfaceName)
log.Printf("... stop running wpa_supplicant processes for interface '%s'\n", wifiState.IfaceName)
wifiState.mutexWpaSupplicant.Lock()
defer wifiState.mutexWpaSupplicant.Unlock()
if wifiState.CmdWpaSupplicant == nil {
log.Printf("... wpa_supplicant for interface '%s' wasn't running, no need to stop it\n", wifiState.IfaceName)
return nil
}
log.Printf("... sending SIGTERM for wpa_supplicant on interface '%s' with PID\n", wifiState.IfaceName, wifiState.CmdWpaSupplicant.Process.Pid)
wifiState.CmdWpaSupplicant.Process.Signal(syscall.SIGTERM)
wifiState.CmdWpaSupplicant.Wait()
if !wifiState.CmdWpaSupplicant.ProcessState.Exited() {
log.Printf("... wpa_supplicant didn't react on SIGTERM for interface '%s', trying SIGKILL\n", wifiState.IfaceName)
wifiState.CmdWpaSupplicant.Process.Kill()
time.Sleep(500 * time.Millisecond)
if wifiState.CmdWpaSupplicant.ProcessState.Exited() {
wifiState.CmdWpaSupplicant = nil
log.Println(eSuccess)
return nil
} else {
log.Println(eCantStop)
return errors.New(eCantStop)
}
}
wifiState.CmdWpaSupplicant = nil
log.Println(eSuccess)
return nil
}
func (wifiState *WifiState) StartWpaSupplicant(timeout time.Duration) (err error) {
log.Printf("Starting wpa_supplicant for interface '%s'...\n", wifiState.IfaceName)
wifiState.mutexWpaSupplicant.Lock()
defer wifiState.mutexWpaSupplicant.Unlock()
//check if interface is valid
if_exists, _ := CheckInterfaceExistence(wifiState.IfaceName)
if !if_exists {
return errors.New(fmt.Sprintf("The given interface '%s' doesn't exist", wifiState.IfaceName))
}
//stop wpa_supplicant if already running
if wifiState.CmdWpaSupplicant != nil {
// avoid dead lock
wifiState.mutexWpaSupplicant.Unlock()
wifiState.StopWpaSupplicant()
wifiState.mutexWpaSupplicant.Lock()
}
//we monitor output of wpa_supplicant till we are connected, fail due to wrong PSK or timeout is reached
//Note: PID file creation doesn't work when not started as daemon, so we do it manually, later on
wifiState.CmdWpaSupplicant = exec.Command("/sbin/wpa_supplicant", "-c", wifiState.PathWpaSupplicantConf, "-i", wifiState.IfaceName)
wifiState.CmdWpaSupplicant.Stdout = wifiState.LoggerWpaSupplicant.LogWriter
err = wifiState.CmdWpaSupplicant.Start()
if err != nil {
return err
}
//wait for result in output
connected, errcon := wifiState.OutMonitorWpaSupplicant.WaitConnectResultOnce(timeout)
if errcon != nil {
log.Printf("... wpa_supplicant reached timeout of '%v' without beeing able to connect to given network\n", timeout)
log.Println("... killing wpa_supplicant")
// avoid dead lock
wifiState.mutexWpaSupplicant.Unlock()
wifiState.StopWpaSupplicant()
wifiState.mutexWpaSupplicant.Lock()
return errors.New("TIMEOUT REACHED")
}
if connected {
//We could return success and keep wpa_supplicant running
log.Println("... connected to given WiFi network, wpa_supplicant running")
return nil
} else {
//we stop wpa_supplicant and return err
log.Println("... seems the wrong PSK was provided for the given WiFi network, stopping wpa_supplicant ...")
//wifiStopWpaSupplicant(nameIface)
log.Println("... killing wpa_supplicant")
// avoid dead lock
wifiState.mutexWpaSupplicant.Unlock()
wifiState.StopWpaSupplicant()
wifiState.mutexWpaSupplicant.Lock()
return errors.New("Wrong PSK")
}
return nil
}
const (
WiFiAuthMode_OPEN WiFiAuthMode = iota
//WiFiAuthMode_WEP
WiFiAuthMode_WPA_PSK
WiFiAuthMode_WPA2_PSK
WiFiAuthMode_UNSUPPORTED
)
type BSS struct {
SSID string
BSSID net.HardwareAddr
Frequency int
BeaconInterval time.Duration //carefull, on IE level beacon interval isn't meassured in milliseconds
BeaconInterval time.Duration //carefull, on IE level beacon interval isn't measured in milliseconds
AuthMode WiFiAuthMode
Signal float32 //Signal strength in dBm
}
func (state WifiState) GetDeployWifiSettings() (ws *pb.WiFiSettings, err error) {
return state.Settings, nil
}
func (state *WifiState) DeployWifiSettings(newWifiSettings *pb.WiFiSettings) (err error) {
log.Printf("Trying to deploy WiFi settings:\n%v\n", newWifiSettings)
ifName := wifi_if_name
state.mutexSettings.Lock()
defer state.mutexSettings.Unlock()
//Get Interface
iface, err := net.InterfaceByName(ifName)
if err != nil {
return errors.New(fmt.Sprintf("No WiFi interface present: %v\n", err))
}
firmwareChange := false
if newWifiSettings.DisableNexmon {
//load legacy driver + firmware
if wifiIsNexmonLoaded() {
err = wifiLoadLegacy()
if err != nil {
return
}
firmwareChange = true
}
} else {
//load nexmon driver + firmware
if !wifiIsNexmonLoaded() {
err = wifiLoadNexmon()
if err != nil {
return
}
firmwareChange = true
}
}
if firmwareChange {
ReInitNetworkInterface(ifName)
}
linkStateChange := false
currentlyEnabled, errstate := netlink.NetworkLinkGetStateUp(iface)
if errstate != nil {
linkStateChange = true
} // current link state couldn't be retireved, regard as changed
if currentlyEnabled == newWifiSettings.Disabled {
linkStateChange = true
} //Is disabled and should be enabled, or the other way around
if linkStateChange || firmwareChange { // Enable/Disable if only if needed
// ToDo: the new interface state isn't reflected to respective ethernet settings
if newWifiSettings.Disabled {
log.Printf("Setting WiFi interface %s to DOWN\n", iface.Name)
err = netlink.NetworkLinkDown(iface)
} else {
log.Printf("Setting WiFi interface %s to UP\n", iface.Name)
err = netlink.NetworkLinkUp(iface)
}
}
//set proper regulatory dom
err = wifiSetReg(newWifiSettings.Reg)
if err != nil {
log.Printf("Error setting WiFi regulatory domain '%s': %v\n", newWifiSettings.Reg, err) //we don't abort on error here
}
//stop wpa_supplicant if needed
state.StopWpaSupplicant()
//kill hostapd in case it is still running
err = state.StopHostapd()
if err != nil {
return err // ToDo: returning at this point is a bit harsh
}
switch newWifiSettings.Mode {
case pb.WiFiSettings_AP:
err = state.runAPMode(newWifiSettings)
if err != nil {
return err
}
case pb.WiFiSettings_STA, pb.WiFiSettings_STA_FAILOVER_AP:
if newWifiSettings.BssCfgClient == nil {
return state.apFailoverOrError(
newWifiSettings,
errors.New("Error: WiFi mode set to station (STA) but no BSS configuration for target WiFi provided"),
)
}
if len(newWifiSettings.BssCfgClient.SSID) == 0 {
return state.apFailoverOrError(
newWifiSettings,
errors.New("Error: WiFi mode set to station (STA) but no SSID provided to identify BSS to join"),
)
}
//scan for provided wifi
scanres, err := WifiScan(ifName)
if err != nil {
return state.apFailoverOrError(
newWifiSettings,
errors.New(fmt.Sprintf("Scanning for existing WiFi networks failed: %v", err)),
)
}
var matchingBss *BSS = nil
for _, bss := range scanres {
if bss.SSID == newWifiSettings.BssCfgClient.SSID {
matchingBss = &bss
break
}
}
if matchingBss == nil {
return state.apFailoverOrError(
newWifiSettings,
errors.New(fmt.Sprintf("SSID not found during scan: '%s'", newWifiSettings.BssCfgClient.SSID)),
)
}
if len(newWifiSettings.BssCfgClient.PSK) == 0 && matchingBss.AuthMode != WiFiAuthMode_OPEN {
//seems we try to connect an OPEN AUTHENTICATION network, but the existing BSS isn't OPEN AUTH
return state.apFailoverOrError(
newWifiSettings,
errors.New(fmt.Sprintf("WiFi SSID '%s' found during scan, but authentication mode isn't OPEN and no PSK was provided", newWifiSettings.BssCfgClient.SSID)),
)
} else {
err = WifiCreateWpaSupplicantConfigFile(newWifiSettings.BssCfgClient.SSID, newWifiSettings.BssCfgClient.PSK, state.PathWpaSupplicantConf)
if err != nil {
return state.apFailoverOrError(
newWifiSettings,
err,
)
}
//ToDo: proper error handling, in case connection not possible
err = state.StartWpaSupplicant(WPA_SUPPLICANT_CONNECT_TIMEOUT)
if err != nil {
return state.apFailoverOrError(
newWifiSettings,
err,
)
}
}
}
log.Printf("... WiFi settings deployed successfully, checking for stored interface configuration...\n")
// store new state
state.Settings = newWifiSettings
return nil
}
func (state *WifiState) runAPMode(newWifiSettings *pb.WiFiSettings) (err error) {
//generate hostapd.conf (overwrite old one)
hostapdCreateConfigFile(newWifiSettings, state.PathHostapdConf)
//start hostapd
return state.StartHostapd()
}
func (state *WifiState) apFailoverOrError(newWifiSettings *pb.WiFiSettings, givenErr error) (err error) {
if newWifiSettings.Mode == pb.WiFiSettings_STA_FAILOVER_AP {
log.Println(givenErr)
log.Printf("Trying to fail over to Access Point Mode...")
return state.runAPMode(newWifiSettings)
} else {
return givenErr
}
}
//check if nexmon driver + firmware is active is loaded
func wifiIsNexmonLoaded() bool {
return true
}
func wifiLoadNexmon() error {
log.Println("Loading nexmon WiFi firmware")
return nil
}
func wifiLoadLegacy() error {
log.Println("Loading leagcy WiFi firmware")
return nil
}
func wifiSetReg(reg string) (err error) {
if len(reg) == 0 {
reg = "US" //default
log.Printf("No ISO/IEC 3166-1 alpha2 regulatory domain provided, defaulting to '%s'\n", reg)
}
reg = strings.ToUpper(reg)
proc := exec.Command("/sbin/iw", "reg", "set", reg)
err = proc.Run()
if err != nil {
return err
}
log.Printf("Notified kernel to use ISO/IEC 3166-1 alpha2 regulatory domain '%s'\n", reg)
return nil
}
func WifiScan(ifName string) (result []BSS, err error) {
proc := exec.Command("/sbin/iw", ifName, "scan")
res, err := proc.CombinedOutput()
@ -536,34 +481,30 @@ func WifiScan(ifName string) (result []BSS, err error) {
return
}
func WifiCreateWpaSupplicantConfigFile(ssid string, psk string, filename string) (err error) {
log.Printf("Creating wpa_suuplicant configuration file at '%s'\n", filename)
fileContent, err := wifiCreateWpaSupplicantConfString(ssid, psk)
if err != nil {
return
}
err = ioutil.WriteFile(filename, []byte(fileContent), os.ModePerm)
return
}
func wifiCreateWpaSupplicantConfStringList(bsslist []*pb.WiFi2BSSCfg) (config string, err error) {
// if a PSK is provided, we assume it is needed, otherwise we assume OPEN AUTHENTICATION
for _,bss := range bsslist {
ssid := bss.SSID
psk := bss.PSK
if len(psk) > 0 {
fmt.Println("Connecting WiFi with PSK")
proc := exec.Command("/usr/bin/wpa_passphrase", ssid, psk)
cres, err := proc.CombinedOutput()
func wifiCreateWpaSupplicantConfString(ssid string, psk string) (config string, err error) {
// if a PSK is provided, we assume it is needed, otherwise we assum OPEN AUTHENTICATION
if len(psk) > 0 {
fmt.Println("Connecting WiFi with PSK")
proc := exec.Command("/usr/bin/wpa_passphrase", ssid, psk)
cres, err := proc.CombinedOutput()
if err != nil {
return "", errors.New(fmt.Sprintf("Error craeting wpa_supplicant.conf for SSID '%s' with PSK '%s': %s", ssid, psk, string(cres)))
}
config = string(cres)
} else {
fmt.Println("Connecting WiFi with OPEN AUTH")
config = fmt.Sprintf(
`network={
if err != nil {
return "", errors.New(fmt.Sprintf("Error craeting wpa_supplicant.conf for SSID '%s' with PSK '%s': %s", ssid, psk, string(cres)))
}
config += string(cres)
} else {
fmt.Println("Connecting WiFi with OPEN AUTH")
config += fmt.Sprintf(
`network={
ssid="%s"
key_mgmt=NONE
}`, ssid)
}
`, ssid)
}
}
@ -572,12 +513,13 @@ func wifiCreateWpaSupplicantConfString(ssid string, psk string) (config string,
return
}
func wifiCreateHostapdConfString(ws *pb.WiFiSettings) (config string, err error) {
if ws.Mode != pb.WiFiSettings_STA_FAILOVER_AP && ws.Mode != pb.WiFiSettings_AP {
return "", errors.New("WiFiSettings don't use an AP")
func wifiCreateHostapdConfString2(ws *pb.WiFi2Settings) (config string, err error) {
if ws.WorkingMode != pb.WiFi2WorkingMode_AP && ws.WorkingMode != pb.WiFi2WorkingMode_STA_FAILOVER_AP {
return "", errors.New("Couldn't create hostapd configuration, the settings don't include an AP")
}
if ws.BssCfgAP == nil {
if ws.Ap_BSS == nil {
return "", errors.New("WiFiSettings don't contain a BSS configuration for an AP")
}
@ -590,22 +532,22 @@ func wifiCreateHostapdConfString(ws *pb.WiFiSettings) (config string, err error)
config += fmt.Sprintf("ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]\n") // 40MHz channels with 20ns guard interval
config += fmt.Sprintf("macaddr_acl=0\n") //Accept all MAC addresses
config += fmt.Sprintf("ssid=%s\n", ws.BssCfgAP.SSID)
config += fmt.Sprintf("channel=%d\n", ws.ApChannel)
config += fmt.Sprintf("ssid=%s\n", ws.Ap_BSS.SSID)
config += fmt.Sprintf("channel=%d\n", ws.Channel)
if ws.AuthMode == pb.WiFiSettings_WPA2_PSK {
if ws.AuthMode == pb.WiFi2AuthMode_WPA2_PSK {
config += fmt.Sprintf("auth_algs=1\n") //Use WPA authentication
config += fmt.Sprintf("wpa=2\n") //Use WPA2
//ToDo: check if PSK could be provided encrypted
config += fmt.Sprintf("wpa_key_mgmt=WPA-PSK\n") //Use a pre-shared key
config += fmt.Sprintf("wpa_passphrase=%s\n", ws.BssCfgAP.PSK) //Set PSK
config += fmt.Sprintf("wpa_passphrase=%s\n", ws.Ap_BSS.PSK) //Set PSK
config += fmt.Sprintf("rsn_pairwise=CCMP\n") //Use Use AES, instead of TKIP
} else {
config += fmt.Sprintf("auth_algs=3\n") //Both, open and shared auth
}
if ws.ApHideSsid {
if ws.HideSsid {
config += fmt.Sprintf("ignore_broadcast_ssid=2\n") //Require clients to know the SSID
} else {
config += fmt.Sprintf("ignore_broadcast_ssid=0\n") //Send beacons + probes
@ -614,9 +556,9 @@ func wifiCreateHostapdConfString(ws *pb.WiFiSettings) (config string, err error)
return
}
func hostapdCreateConfigFile(s *pb.WiFiSettings, filename string) (err error) {
func hostapdCreateConfigFile2(s *pb.WiFi2Settings, filename string) (err error) {
log.Printf("Creating hostapd configuration file at '%s'\n", filename)
fileContent, err := wifiCreateHostapdConfString(s)
fileContent, err := wifiCreateHostapdConfString2(s)
if err != nil {
return
}

View File

@ -118,6 +118,7 @@ func GetDefaultGadgetSettings() (res pb.GadgetSettings) {
return res
}
/*
func GetDefaultWiFiSettings() (res *pb.WiFiSettings) {
res = &pb.WiFiSettings{
Mode: pb.WiFiSettings_AP,
@ -135,3 +136,4 @@ func GetDefaultWiFiSettings() (res *pb.WiFiSettings) {
}
return
}
*/

View File

@ -1,3 +1,5 @@
// +build linux
package service
import (
@ -28,20 +30,34 @@ var (
type server struct {}
func (s *server) DeployWiFiSettings2(ctx context.Context, wset *pb.WiFi2Settings) (wstate *pb.WiFi2State, err error) {
return ServiceState.WifiSvc.DeploySettings(wset)
}
func (s *server) GetWiFiState2(ctx context.Context, empty *pb.Empty) (wstate *pb.WiFi2State, err error) {
st := ServiceState.WifiSvc.GetState()
return &st, nil
}
func (s *server) ListenWiFiStateChanges2(ctx context.Context, empty *pb.Empty) (wstate *pb.WiFi2State, err error) {
panic("implement me")
}
/*
func (s *server) GetDeployedWifiSettings(ctx context.Context, req *pb.Empty) (resp *pb.WiFiSettings, err error) {
return ServiceState.Wifi.GetDeployWifiSettings()
}
func (s *server) DeployWifiSettings(ctx context.Context, ws *pb.WiFiSettings) (empty *pb.Empty, err error) {
func (s *server) DeployWifiSettings(ctx context.Context, ws *pb.WiFiSettings) (wifiConState *pb.WiFiConnectionState, err error) {
log.Printf("Trying to deploy WiFi settings %v", ws)
empty = &pb.Empty{}
err = ServiceState.Wifi.DeployWifiSettings(ws)
if err != nil {
log.Printf("Error deploying WiFi settings settings %v", err)
}
return
return ServiceState.Wifi.ConState, err
}
*/
func (s *server) GetDeployedEthernetInterfaceSettings(ctx context.Context, req *pb.StringMessage) (resp *pb.EthernetInterfaceSettings, err error) {
if settings,exist := ServiceState.StoredNetworkSetting[req.Msg]; exist && settings.SettingsInUse {

View File

@ -12,7 +12,8 @@ type GlobalServiceState struct {
Led *LedState
HidDevPath map[string]string //stores device path for HID devices
StoredNetworkSetting map[string]*pb.EthernetInterfaceSettings
Wifi *WifiState
// Wifi *WifiState
WifiSvc *WiFiService
}
func InitGlobalServiceState() (err error) {
@ -40,7 +41,9 @@ func InitGlobalServiceState() (err error) {
IpAddress4: "172.24.0.1",
Netmask4: "255.255.255.0",
}
state.Wifi = NewWifiState(GetDefaultWiFiSettings(), wifi_if_name)
// state.Wifi = NewWifiState(GetDefaultWiFiSettings(), wifi_if_name)
state.WifiSvc = NewWifiService()
state.HidDevPath = make(map[string]string) //should be initialized BEFORE UsbGadgetManager uses it
state.EvMgr = NewEventManager(20)
@ -53,7 +56,6 @@ func InitGlobalServiceState() (err error) {
return nil
}
func (state *GlobalServiceState) StartService() {
state.EvMgr.Start()
}

View File

@ -41,10 +41,10 @@ func InitComponentsWiFi() {
Value int `js:"value"`
}{Object:O()}
mode.Value = val
switch pb.WiFiSettings_APAuthMode(val) {
case pb.WiFiSettings_WPA2_PSK:
switch pb.WiFi2AuthMode(val) {
case pb.WiFi2AuthMode_WPA2_PSK:
mode.Label = "WPA2"
case pb.WiFiSettings_OPEN:
case pb.WiFi2AuthMode_OPEN:
mode.Label = "Open"
default:
mode.Label = "Unknown"
@ -55,27 +55,30 @@ func InitComponentsWiFi() {
}),
hvue.Computed("wifiModes", func(vm *hvue.VM) interface{} {
modes := js.Global.Get("Array").New()
for val,_ := range pb.WiFiSettings_Mode_name {
for val,_ := range pb.WiFi2WorkingMode_name {
mode := struct {
*js.Object
Label string `js:"label"`
Value int `js:"value"`
}{Object:O()}
mode.Value = val
switch pb.WiFiSettings_Mode(val) {
case pb.WiFiSettings_AP:
switch pb.WiFi2WorkingMode(val) {
case pb.WiFi2WorkingMode_AP:
mode.Label = "Access Point (AP)"
case pb.WiFiSettings_STA:
case pb.WiFi2WorkingMode_STA:
mode.Label = "Station (Client)"
case pb.WiFiSettings_STA_FAILOVER_AP:
case pb.WiFi2WorkingMode_STA_FAILOVER_AP:
mode.Label = "Client with Failover to AP"
default:
mode.Label = "Unknown"
continue
}
modes.Call("push", mode)
}
return modes
}),
hvue.Computed("mode_ap", func(vm *hvue.VM) interface{} {return pb.WiFi2WorkingMode_AP}),
hvue.Computed("mode_sta", func(vm *hvue.VM) interface{} {return pb.WiFi2WorkingMode_STA_FAILOVER_AP}),
hvue.Computed("mode_failover", func(vm *hvue.VM) interface{} {return pb.WiFi2WorkingMode_STA_FAILOVER_AP}),
hvue.Method("reset",
func(vm *hvue.VM) {
vm.Get("$store").Call("dispatch", VUEX_ACTION_UPDATE_WIFI_SETTINGS_FROM_DEPLOYED)
@ -145,7 +148,7 @@ const templateWiFi = `
</q-card>
</div>
<div class="col-lg-4" v-if="settings.mode != 0">
<div class="col-lg-4" v-if="settings.mode == mode_sta || settings.mode == mode_failover">
<q-card class="full-height">
<q-card-title>
WiFi client settings
@ -172,7 +175,7 @@ const templateWiFi = `
</q-item-main>
</q-item>
<template v-if="settings.mode == 2">
<template v-if="settings.mode == mode_failover">
<q-item>
<q-item-main>
<q-alert type="warning">
@ -185,7 +188,7 @@ const templateWiFi = `
</q-card>
</div>
<div class="col-lg-4" v-if="settings.mode != 1">
<div class="col-lg-4" v-if="settings.mode == mode_ap || settings.mode == mode_failover">
<q-card class="full-height">
<q-card-title>
WiFi Access Point settings
@ -247,6 +250,17 @@ const templateWiFi = `
</q-list>
</q-card>
</div>
<div class="col-lg-12">
<q-card class="full-height">
<q-card-title>
<q-icon name="alarm" /><q-icon name="alarm" />
</q-card-title>
WiFiState {{ $store.state.wifiConnectionState }}
</q-card>
</div>
</div>
</q-page>

View File

@ -18,22 +18,22 @@ var eNoHidEvent = errors.New("No HID event")
type jsGadgetSettings struct {
*js.Object
Enabled bool `js:"Enabled"`
Vid string `js:"Vid"`
Pid string `js:"Pid"`
Manufacturer string `js:"Manufacturer"`
Product string `js:"Product"`
Serial string `js:"Serial"`
Use_CDC_ECM bool `js:"Use_CDC_ECM"`
Use_RNDIS bool `js:"Use_RNDIS"`
Use_HID_KEYBOARD bool `js:"Use_HID_KEYBOARD"`
Use_HID_MOUSE bool `js:"Use_HID_MOUSE"`
Use_HID_RAW bool `js:"Use_HID_RAW"`
Use_UMS bool `js:"Use_UMS"`
Use_SERIAL bool `js:"Use_SERIAL"`
Enabled bool `js:"Enabled"`
Vid string `js:"Vid"`
Pid string `js:"Pid"`
Manufacturer string `js:"Manufacturer"`
Product string `js:"Product"`
Serial string `js:"Serial"`
Use_CDC_ECM bool `js:"Use_CDC_ECM"`
Use_RNDIS bool `js:"Use_RNDIS"`
Use_HID_KEYBOARD bool `js:"Use_HID_KEYBOARD"`
Use_HID_MOUSE bool `js:"Use_HID_MOUSE"`
Use_HID_RAW bool `js:"Use_HID_RAW"`
Use_UMS bool `js:"Use_UMS"`
Use_SERIAL bool `js:"Use_SERIAL"`
RndisSettings *VGadgetSettingsEthernet `js:"RndisSettings"`
CdcEcmSettings *VGadgetSettingsEthernet `js:"CdcEcmSettings"`
UmsSettings *VGadgetSettingsUMS `js:"UmsSettings"`
UmsSettings *VGadgetSettingsUMS `js:"UmsSettings"`
}
type VGadgetSettingsEthernet struct {
@ -42,10 +42,9 @@ type VGadgetSettingsEthernet struct {
DevAddr string `js:"DevAddr"`
}
type VGadgetSettingsUMS struct {
*js.Object
Cdrom bool `js:"Cdrom"`
Cdrom bool `js:"Cdrom"`
File string `js:"File"`
}
@ -121,7 +120,6 @@ func (jsGS *jsGadgetSettings) fromGS(gs *pb.GadgetSettings) {
}
}
func NewUSBGadgetSettings() *jsGadgetSettings {
gs := &jsGadgetSettings{
Object: O(),
@ -135,18 +133,17 @@ func NewUSBGadgetSettings() *jsGadgetSettings {
type jsEvent struct {
*js.Object
Type int64 `js:"type"`
Values []interface{}
Type int64 `js:"type"`
Values []interface{}
JSValues *js.Object `js:"values"`
}
func NewJsEventFromNative(event *pb.Event) (res *jsEvent) {
res = &jsEvent{Object:O()}
res = &jsEvent{Object: O()}
res.JSValues = js.Global.Get("Array").New()
res.Type = event.Type
res.Values = make([]interface{}, len(event.Values))
for idx,val := range event.Values {
for idx, val := range event.Values {
switch valT := val.Val.(type) {
case *pb.EventValue_Tint64:
res.Values[idx] = valT.Tint64
@ -170,89 +167,115 @@ func NewJsEventFromNative(event *pb.Event) (res *jsEvent) {
type jsLogEvent struct {
*js.Object
EvLogSource string `js:"source"`
EvLogLevel int `js:"level"`
EvLogLevel int `js:"level"`
EvLogMessage string `js:"message"`
EvLogTime string `js:"time"`
EvLogTime string `js:"time"`
}
//HID event
type jsHidEvent struct {
*js.Object
EvType int64 `js:"evtype"`
VMId int64 `js:"vmId"`
JobId int64 `js:"jobId"`
HasError bool `js:"hasError"`
Result string `js:"result"`
Error string `js:"error"`
Message string `js:"message"`
EvType int64 `js:"evtype"`
VMId int64 `js:"vmId"`
JobId int64 `js:"jobId"`
HasError bool `js:"hasError"`
Result string `js:"result"`
Error string `js:"error"`
Message string `js:"message"`
EvLogTime string `js:"time"`
}
func (jsEv *jsEvent) toLogEvent() (res *jsLogEvent, err error) {
if jsEv.Type != common_web.EVT_LOG || len(jsEv.Values) != 4 { return nil,eNoLogEvent}
res = &jsLogEvent{Object:O()}
if jsEv.Type != common_web.EVT_LOG || len(jsEv.Values) != 4 {
return nil, eNoLogEvent
}
res = &jsLogEvent{Object: O()}
var ok bool
res.EvLogSource,ok = jsEv.Values[0].(string)
if !ok { return nil,eNoLogEvent }
res.EvLogSource, ok = jsEv.Values[0].(string)
if !ok {
return nil, eNoLogEvent
}
ll,ok := jsEv.Values[1].(int64)
if !ok { return nil,eNoLogEvent}
ll, ok := jsEv.Values[1].(int64)
if !ok {
return nil, eNoLogEvent
}
res.EvLogLevel = int(ll)
res.EvLogMessage,ok = jsEv.Values[2].(string)
if !ok { return nil,eNoLogEvent}
res.EvLogMessage, ok = jsEv.Values[2].(string)
if !ok {
return nil, eNoLogEvent
}
res.EvLogTime,ok = jsEv.Values[3].(string)
if !ok { return nil,eNoLogEvent}
res.EvLogTime, ok = jsEv.Values[3].(string)
if !ok {
return nil, eNoLogEvent
}
return res,nil
return res, nil
}
func (jsEv *jsEvent) toHidEvent() (res *jsHidEvent, err error) {
if jsEv.Type != common_web.EVT_HID || len(jsEv.Values) != 8 { return nil,eNoHidEvent}
res = &jsHidEvent{Object:O()}
if jsEv.Type != common_web.EVT_HID || len(jsEv.Values) != 8 {
return nil, eNoHidEvent
}
res = &jsHidEvent{Object: O()}
var ok bool
res.EvType,ok = jsEv.Values[0].(int64)
if !ok { return nil,eNoHidEvent }
res.EvType, ok = jsEv.Values[0].(int64)
if !ok {
return nil, eNoHidEvent
}
res.VMId,ok = jsEv.Values[1].(int64)
if !ok { return nil,eNoHidEvent}
res.VMId, ok = jsEv.Values[1].(int64)
if !ok {
return nil, eNoHidEvent
}
res.JobId,ok = jsEv.Values[2].(int64)
if !ok { return nil,eNoHidEvent}
res.JobId, ok = jsEv.Values[2].(int64)
if !ok {
return nil, eNoHidEvent
}
res.HasError,ok = jsEv.Values[3].(bool)
if !ok { return nil,eNoHidEvent}
res.HasError, ok = jsEv.Values[3].(bool)
if !ok {
return nil, eNoHidEvent
}
res.Result,ok = jsEv.Values[4].(string)
if !ok { return nil,eNoHidEvent}
res.Result, ok = jsEv.Values[4].(string)
if !ok {
return nil, eNoHidEvent
}
res.Error,ok = jsEv.Values[5].(string)
if !ok { return nil,eNoHidEvent}
res.Error, ok = jsEv.Values[5].(string)
if !ok {
return nil, eNoHidEvent
}
res.Message,ok = jsEv.Values[6].(string)
if !ok { return nil,eNoHidEvent}
res.Message, ok = jsEv.Values[6].(string)
if !ok {
return nil, eNoHidEvent
}
res.EvLogTime,ok = jsEv.Values[7].(string)
if !ok { return nil,eNoHidEvent}
res.EvLogTime, ok = jsEv.Values[7].(string)
if !ok {
return nil, eNoHidEvent
}
return res,nil
return res, nil
}
/* HIDJobList */
type jsHidJobState struct {
*js.Object
Id int64 `js:"id"`
VmId int64 `js:"vmId"`
HasFailed bool `js:"hasFailed"`
HasSucceeded bool `js:"hasSucceeded"`
LastMessage string `js:"lastMessage"`
TextResult string `js:"textResult"`
// TextError string `js:"textError"`
Id int64 `js:"id"`
VmId int64 `js:"vmId"`
HasFailed bool `js:"hasFailed"`
HasSucceeded bool `js:"hasSucceeded"`
LastMessage string `js:"lastMessage"`
TextResult string `js:"textResult"`
// TextError string `js:"textError"`
LastUpdateTime string `js:"lastUpdateTime"` //JSON timestamp from server
ScriptSource string `js:"textSource"`
}
@ -263,7 +286,7 @@ type jsHidJobStateList struct {
}
func NewHIDJobStateList() *jsHidJobStateList {
jl := &jsHidJobStateList{Object:O()}
jl := &jsHidJobStateList{Object: O()}
jl.Jobs = O()
/*
@ -309,10 +332,10 @@ func (jl *jsHidJobStateList) UpdateEntry(id, vmId int64, hasFailed, hasSucceeded
//Check if job exists, update existing one if already present
var j *jsHidJobState
if res := jl.Jobs.Get(key);res == js.Undefined {
j = &jsHidJobState{Object:O()}
if res := jl.Jobs.Get(key); res == js.Undefined {
j = &jsHidJobState{Object: O()}
} else {
j = &jsHidJobState{Object:res}
j = &jsHidJobState{Object: res}
}
//Create job object
@ -324,7 +347,9 @@ func (jl *jsHidJobStateList) UpdateEntry(id, vmId int64, hasFailed, hasSucceeded
j.LastMessage = message
j.TextResult = textResult
j.LastUpdateTime = lastUpdateTime
if len(scriptSource) > 0 {j.ScriptSource = scriptSource}
if len(scriptSource) > 0 {
j.ScriptSource = scriptSource
}
//jl.Jobs.Set(strconv.Itoa(int(j.Id)), j) //jobs["j.ID"]=j <--Property addition/update can't be detected by Vue.js, see https://vuejs.org/v2/guide/list.html#Object-Change-Detection-Caveats
hvue.Set(jl.Jobs, key, j)
}
@ -335,34 +360,85 @@ func (jl *jsHidJobStateList) DeleteEntry(id int64) {
}
/* WiFi settings */
/*
type WiFiSettings struct {
Disabled bool
Reg string
Mode WiFiSettings_Mode
AuthMode WiFiSettings_APAuthMode
ApChannel uint32
BssCfgAP *BSSCfg
BssCfgClient *BSSCfg
ApHideSsid bool
DisableNexmon bool
type jsWiFiConnectionState struct {
*js.Object
Mode int `js:"mode"`
Reg string `js:"reg"`
Channel uint32 `js:"channel"`
SSID string `js:"SSID"`
Hidden bool `js:"hidden"`
Nexmon bool `js:"nexmon"`
Disabled bool `js:"disabled"`
}
func (target *jsWiFiConnectionState) fromGo(src *pb.WiFi2State) {
target.Mode = int(src.WorkingMode)
target.Reg = src.Regulatory
target.Channel = src.Channel
target.SSID = src.Bss.SSID
target.Hidden = src.HideSsid
target.Nexmon = src.Nexmon
target.Disabled = src.Disabled
return
}
func (src *jsWiFiConnectionState) toGo() (target *pb.WiFi2State) {
target = &pb.WiFi2State{
Regulatory: src.Reg,
Channel: src.Channel,
Bss: &pb.WiFi2BSSCfg{
SSID: src.SSID,
PSK: "",
},
HideSsid: src.Hidden,
Nexmon: src.Nexmon,
WorkingMode: pb.WiFi2WorkingMode(src.Mode),
Disabled: src.Disabled,
Name: "",
}
return
}
func (src jsWiFiConnectionState) ModeString() (strMode string) {
switch src.Mode {
case 1:
return "Access Point"
case 2:
return "Station"
default:
return "UNKNOWN"
}
}
func NewWiFiConnectionState() *jsWiFiConnectionState {
res := &jsWiFiConnectionState{Object: O()}
res.SSID = "Unknown SSID"
res.Channel = 0
res.Mode = 0
res.Hidden = false
res.Reg = "Unknown reg"
res.Nexmon = false
return res
}
*/
type jsWiFiSettings struct {
*js.Object
Disabled bool `js:"disabled"`
Reg string `js:"reg"`
Mode int `js:"mode"` //AP, STA, Failover
AuthMode int `js:"authMode"` //WPA2_PSK, OPEN
Channel int `js:"channel"`
Disabled bool `js:"disabled"`
Reg string `js:"reg"`
Mode int `js:"mode"` //AP, STA, Failover
AuthMode int `js:"authMode"` //WPA2_PSK, OPEN
Channel int `js:"channel"`
// next two fields are interpreted as BssCfgAp or BssCfgClient, depending on Mode
AP_SSID string `js:"apSsid"`
AP_PSK string `js:"apPsk"`
STA_SSID string `js:"staSsid"`
STA_PSK string `js:"staPsk"`
HideSsid bool `js:"hideSsid"`
DisableNexmon bool `js:"disableNexmon"`
AP_SSID string `js:"apSsid"`
AP_PSK string `js:"apPsk"`
STA_SSID string `js:"staSsid"`
STA_PSK string `js:"staPsk"`
HideSsid bool `js:"hideSsid"`
DisableNexmon bool `js:"disableNexmon"`
}
func (target *jsWiFiSettings) fromGo(src *pb.WiFiSettings) {
@ -397,22 +473,47 @@ func (src *jsWiFiSettings) toGo() (target *pb.WiFiSettings) {
// assure undefined strings end up as empty strings
target = &pb.WiFiSettings{
Disabled: src.Disabled,
Reg: src.Reg,
Mode: pb.WiFiSettings_Mode(src.Mode),
AuthMode: pb.WiFiSettings_APAuthMode(src.AuthMode),
Disabled: src.Disabled,
Reg: src.Reg,
Mode: pb.WiFiSettings_Mode(src.Mode),
AuthMode: pb.WiFiSettings_APAuthMode(src.AuthMode),
DisableNexmon: src.DisableNexmon,
ApChannel: uint32(src.Channel),
ApHideSsid: src.HideSsid,
ApChannel: uint32(src.Channel),
ApHideSsid: src.HideSsid,
BssCfgClient: &pb.BSSCfg{
SSID: src.STA_SSID,
PSK: src.STA_PSK,
PSK: src.STA_PSK,
},
BssCfgAP: &pb.BSSCfg{
SSID: src.AP_SSID,
PSK: src.AP_PSK,
PSK: src.AP_PSK,
},
}
return target
}
func (src *jsWiFiSettings) toGo2() (target *pb.WiFi2Settings) {
// assure undefined strings end up as empty strings
target = &pb.WiFi2Settings{
Name: "mainconfig",
Disabled: src.Disabled,
Regulatory: src.Reg,
WorkingMode: pb.WiFi2WorkingMode(src.Mode),
AuthMode: pb.WiFi2AuthMode(src.AuthMode),
Nexmon: !src.DisableNexmon,
Channel: uint32(src.Channel),
HideSsid: src.HideSsid,
Ap_BSS: &pb.WiFi2BSSCfg{
SSID: src.AP_SSID,
PSK: src.AP_PSK,
},
Client_BSSList: []*pb.WiFi2BSSCfg{
&pb.WiFi2BSSCfg{
SSID: src.STA_SSID,
PSK: src.STA_PSK,
},
},
}
return target
}
@ -427,7 +528,7 @@ func (isl *jsEthernetSettingsList) fromGo(src *pb.DeployedEthernetInterfaceSetti
//Options array (converted from map)
isl.Interfaces = js.Global.Get("Array").New()
for _, ifSets := range src.List {
jsIfSets := &jsEthernetInterfaceSettings{Object:O()}
jsIfSets := &jsEthernetInterfaceSettings{Object: O()}
jsIfSets.fromGo(ifSets)
isl.Interfaces.Call("push", jsIfSets)
}
@ -436,13 +537,13 @@ func (isl *jsEthernetSettingsList) fromGo(src *pb.DeployedEthernetInterfaceSetti
type jsEthernetInterfaceSettings struct {
*js.Object
Name string `js:"name"`
Mode int `js:"mode"`
IpAddress4 string `js:"ipAddress4"`
Netmask4 string `js:"netmask4"`
Enabled bool `js:"enabled"`
Name string `js:"name"`
Mode int `js:"mode"`
IpAddress4 string `js:"ipAddress4"`
Netmask4 string `js:"netmask4"`
Enabled bool `js:"enabled"`
DhcpServerSettings *jsDHCPServerSettings `js:"dhcpServerSettings"`
SettingsInUse bool `js:"settingsInUse"`
SettingsInUse bool `js:"settingsInUse"`
}
func (target *jsEthernetInterfaceSettings) fromGo(src *pb.EthernetInterfaceSettings) {
@ -454,18 +555,18 @@ func (target *jsEthernetInterfaceSettings) fromGo(src *pb.EthernetInterfaceSetti
target.SettingsInUse = src.SettingsInUse
if src.DhcpServerSettings != nil {
target.DhcpServerSettings = &jsDHCPServerSettings{Object:O()}
target.DhcpServerSettings = &jsDHCPServerSettings{Object: O()}
target.DhcpServerSettings.fromGo(src.DhcpServerSettings)
}
}
func (src *jsEthernetInterfaceSettings) toGo() (target *pb.EthernetInterfaceSettings) {
target = &pb.EthernetInterfaceSettings{
Name: src.Name,
Mode: pb.EthernetInterfaceSettings_Mode(src.Mode),
IpAddress4: src.IpAddress4,
Netmask4: src.Netmask4,
Enabled: src.Enabled,
Name: src.Name,
Mode: pb.EthernetInterfaceSettings_Mode(src.Mode),
IpAddress4: src.IpAddress4,
Netmask4: src.Netmask4,
Enabled: src.Enabled,
SettingsInUse: src.SettingsInUse,
}
@ -480,7 +581,7 @@ func (src *jsEthernetInterfaceSettings) toGo() (target *pb.EthernetInterfaceSett
func (iface *jsEthernetInterfaceSettings) CreateDhcpSettingsForInterface() {
//create dhcp server settings
settings := &jsDHCPServerSettings{Object:O()}
settings := &jsDHCPServerSettings{Object: O()}
settings.ListenInterface = iface.Name
settings.ListenPort = 0 // 0 means DNS is disabled
settings.LeaseFile = common_web.NameLeaseFileDHCPSrv(iface.Name)
@ -489,38 +590,37 @@ func (iface *jsEthernetInterfaceSettings) CreateDhcpSettingsForInterface() {
settings.CallbackScript = ""
//ToDo: add missing fields
//Ranges array
settings.Ranges = js.Global.Get("Array").New()
settings.Options = js.Global.Get("Array").New()
settings.StaticHosts = js.Global.Get("Array").New()
//add empty option for router and DNS to prevent netmask from promoting itself via DHCP
optNoRouter := &jsDHCPServerOption{Object:O()}
optNoRouter := &jsDHCPServerOption{Object: O()}
optNoRouter.Option = 3
optNoRouter.Value = ""
settings.AddOption(optNoRouter)
optNoDNS := &jsDHCPServerOption{Object:O()}
optNoDNS := &jsDHCPServerOption{Object: O()}
optNoDNS.Option = 6
optNoDNS.Value = ""
settings.AddOption(optNoDNS)
//iface.DhcpServerSettings = settings
// Update the field with Vue in order to have proper setters in place
hvue.Set(iface,"dhcpServerSettings", settings)
hvue.Set(iface, "dhcpServerSettings", settings)
}
type jsDHCPServerSettings struct {
*js.Object
ListenPort int `js:"listenPort"`
ListenInterface string `js:"listenInterface"`
LeaseFile string `js:"leaseFile"`
NotAuthoritative bool `js:"nonAuthoritative"`
DoNotBindInterface bool `js:"doNotBindInterface"`
CallbackScript string `js:"callbackScript"`
Ranges *js.Object `js:"ranges"`//[]*DHCPServerRange
Options *js.Object `js:"options"` //map[uint32]string
StaticHosts *js.Object `js:"staticHosts"`//[]*DHCPServerStaticHost
ListenPort int `js:"listenPort"`
ListenInterface string `js:"listenInterface"`
LeaseFile string `js:"leaseFile"`
NotAuthoritative bool `js:"nonAuthoritative"`
DoNotBindInterface bool `js:"doNotBindInterface"`
CallbackScript string `js:"callbackScript"`
Ranges *js.Object `js:"ranges"` //[]*DHCPServerRange
Options *js.Object `js:"options"` //map[uint32]string
StaticHosts *js.Object `js:"staticHosts"` //[]*DHCPServerStaticHost
}
func (src *jsDHCPServerSettings) toGo() (target *pb.DHCPServerSettings) {
@ -535,13 +635,12 @@ func (src *jsDHCPServerSettings) toGo() (target *pb.DHCPServerSettings) {
println("jsRanges", src.Ranges)
//Check if ranges are present
if src.Ranges != js.Undefined {
if numRanges := src.Ranges.Length(); numRanges > 0 {
target.Ranges = make([]*pb.DHCPServerRange, numRanges)
//iterate over JS array
for i:= 0; i < numRanges; i++ {
for i := 0; i < numRanges; i++ {
jsRange := &jsDHCPServerRange{Object: src.Ranges.Index(i)}
target.Ranges[i] = &pb.DHCPServerRange{}
target.Ranges[i].RangeUpper = jsRange.RangeUpper
@ -556,7 +655,7 @@ func (src *jsDHCPServerSettings) toGo() (target *pb.DHCPServerSettings) {
if numOptions := src.Options.Length(); numOptions > 0 {
target.Options = make(map[uint32]string)
//iterate over JS array
for i:= 0; i < numOptions; i++ {
for i := 0; i < numOptions; i++ {
jsOption := &jsDHCPServerOption{Object: src.Options.Index(i)}
target.Options[uint32(jsOption.Option)] = jsOption.Value
}
@ -568,7 +667,7 @@ func (src *jsDHCPServerSettings) toGo() (target *pb.DHCPServerSettings) {
if numStaticHosts := src.StaticHosts.Length(); numStaticHosts > 0 {
target.StaticHosts = make([]*pb.DHCPServerStaticHost, numStaticHosts)
//iterate over JS array
for i:= 0; i < numStaticHosts; i++ {
for i := 0; i < numStaticHosts; i++ {
jsStaticHost := &jsDHCPServerStaticHost{Object: src.StaticHosts.Index(i)}
target.StaticHosts[i] = &pb.DHCPServerStaticHost{}
target.StaticHosts[i].Mac = jsStaticHost.Mac
@ -579,7 +678,6 @@ func (src *jsDHCPServerSettings) toGo() (target *pb.DHCPServerSettings) {
return target
}
func (settings *jsDHCPServerSettings) AddRange(dhcpRange *jsDHCPServerRange) {
if settings.Ranges == js.Undefined {
settings.Ranges = js.Global.Get("Array").New()
@ -588,7 +686,9 @@ func (settings *jsDHCPServerSettings) AddRange(dhcpRange *jsDHCPServerRange) {
}
func (settings *jsDHCPServerSettings) RemoveRange(dhcpRange *jsDHCPServerRange) {
if settings.Ranges == js.Undefined { return }
if settings.Ranges == js.Undefined {
return
}
//Check if in array
if idx := settings.Ranges.Call("indexOf", dhcpRange).Int(); idx > -1 {
@ -596,7 +696,6 @@ func (settings *jsDHCPServerSettings) RemoveRange(dhcpRange *jsDHCPServerRange)
}
}
func (settings *jsDHCPServerSettings) AddOption(dhcpOption *jsDHCPServerOption) {
if settings.Options == js.Undefined {
settings.Options = js.Global.Get("Array").New()
@ -604,9 +703,10 @@ func (settings *jsDHCPServerSettings) AddOption(dhcpOption *jsDHCPServerOption)
settings.Options.Call("push", dhcpOption)
}
func (settings *jsDHCPServerSettings) RemoveOption(dhcpOption *jsDHCPServerOption) {
if settings.Options == js.Undefined { return }
if settings.Options == js.Undefined {
return
}
//Check if in array
if idx := settings.Options.Call("indexOf", dhcpOption).Int(); idx > -1 {
@ -621,9 +721,10 @@ func (settings *jsDHCPServerSettings) AddStaticHost(dhcpStaticHost *jsDHCPServer
settings.StaticHosts.Call("push", dhcpStaticHost)
}
func (settings *jsDHCPServerSettings) RemoveStaticHost(dhcpStaticHost *jsDHCPServerStaticHost) {
if settings.StaticHosts == js.Undefined { return }
if settings.StaticHosts == js.Undefined {
return
}
//Check if in array
if idx := settings.StaticHosts.Call("indexOf", dhcpStaticHost).Int(); idx > -1 {
@ -631,7 +732,6 @@ func (settings *jsDHCPServerSettings) RemoveStaticHost(dhcpStaticHost *jsDHCPSer
}
}
func (target *jsDHCPServerSettings) fromGo(src *pb.DHCPServerSettings) {
target.ListenPort = int(src.ListenPort)
target.ListenInterface = src.ListenInterface
@ -641,25 +741,25 @@ func (target *jsDHCPServerSettings) fromGo(src *pb.DHCPServerSettings) {
target.CallbackScript = src.CallbackScript
//Ranges array
target.Ranges = js.Global.Get("Array").New( )
for _,dhcpRange := range src.Ranges {
jsRange := &jsDHCPServerRange{Object:O()}
target.Ranges = js.Global.Get("Array").New()
for _, dhcpRange := range src.Ranges {
jsRange := &jsDHCPServerRange{Object: O()}
jsRange.fromGo(dhcpRange)
target.Ranges.Call("push", jsRange)
}
//Options array (converted from map)
target.Options = js.Global.Get("Array").New( )
target.Options = js.Global.Get("Array").New()
for optId, optVal := range src.Options {
jsOption := &jsDHCPServerOption{Object:O()}
jsOption := &jsDHCPServerOption{Object: O()}
jsOption.fromGo(optId, optVal)
target.Options.Call("push", jsOption)
}
//StaticHosts array
target.StaticHosts = js.Global.Get("Array").New( )
for _,staticHost := range src.StaticHosts {
jsStaticHost := &jsDHCPServerStaticHost{Object:O()}
target.StaticHosts = js.Global.Get("Array").New()
for _, staticHost := range src.StaticHosts {
jsStaticHost := &jsDHCPServerStaticHost{Object: O()}
jsStaticHost.fromGo(staticHost)
target.Ranges.Call("push", jsStaticHost)
}
@ -678,11 +778,10 @@ func (target *jsDHCPServerRange) fromGo(src *pb.DHCPServerRange) {
target.LeaseTime = src.LeaseTime
}
type jsDHCPServerOption struct {
*js.Object
Option int `js:"option"`
Value string `js:"value"`
Option int `js:"option"`
Value string `js:"value"`
}
func (target *jsDHCPServerOption) fromGo(srcID uint32, srcVal string) {
@ -693,7 +792,7 @@ func (target *jsDHCPServerOption) fromGo(srcID uint32, srcVal string) {
type jsDHCPServerStaticHost struct {
*js.Object
Mac string `js:"mac"`
Ip string `js:"ip"`
Ip string `js:"ip"`
}
func (target *jsDHCPServerStaticHost) fromGo(src *pb.DHCPServerStaticHost) {
@ -704,9 +803,9 @@ func (target *jsDHCPServerStaticHost) fromGo(src *pb.DHCPServerStaticHost) {
/* EVENT LOGGER */
type jsEventReceiver struct {
*js.Object
LogArray *js.Object `js:"logArray"`
HidEventArray *js.Object `js:"eventHidArray"`
MaxEntries int `js:"maxEntries"`
LogArray *js.Object `js:"logArray"`
HidEventArray *js.Object `js:"eventHidArray"`
MaxEntries int `js:"maxEntries"`
JobList *jsHidJobStateList `js:"jobList"` //Needs to be exposed to JS in order to use JobList.UpdateEntry() from this JS object
}
@ -723,15 +822,15 @@ func NewEventReceiver(maxEntries int, jobList *jsHidJobStateList) *jsEventReceiv
return eventReceiver
}
func (data *jsEventReceiver) handleHidEvent(hEv *jsHidEvent ) {
func (data *jsEventReceiver) handleHidEvent(hEv *jsHidEvent) {
println("Received HID EVENT", hEv)
switch hEv.EvType {
case common_web.HidEventType_JOB_STARTED:
// Note: the JOB_STARTED event carries the script source in the message field, (no need to re-request the job
// state in order to retrieve the source code of the job, when adding it to the job state list)
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, false, "Script started", "", hEv.EvLogTime,hEv.Message)
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, false, "Script started", "", hEv.EvLogTime, hEv.Message)
case common_web.HidEventType_JOB_FAILED:
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, false, hEv.Message, hEv.Error, hEv.EvLogTime,"")
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, false, hEv.Message, hEv.Error, hEv.EvLogTime, "")
notification := &QuasarNotification{Object: O()}
notification.Message = "HIDScript job " + strconv.Itoa(int(hEv.JobId)) + " failed"
@ -741,7 +840,7 @@ func (data *jsEventReceiver) handleHidEvent(hEv *jsHidEvent ) {
notification.Timeout = 5000
QuasarNotify(notification)
case common_web.HidEventType_JOB_SUCCEEDED:
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, true, hEv.Message, hEv.Result, hEv.EvLogTime,"")
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, true, hEv.Message, hEv.Result, hEv.EvLogTime, "")
notification := &QuasarNotification{Object: O()}
notification.Message = "HIDScript job " + strconv.Itoa(int(hEv.JobId)) + " succeeded"
@ -752,29 +851,28 @@ func (data *jsEventReceiver) handleHidEvent(hEv *jsHidEvent ) {
QuasarNotify(notification)
case common_web.HidEventType_JOB_CANCELLED:
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, true, false, hEv.Message, hEv.Message, hEv.EvLogTime,"")
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, true, false, hEv.Message, hEv.Message, hEv.EvLogTime, "")
default:
println("unhandled hid event " + common_web.EventType_name[hEv.EvType], hEv)
println("unhandled hid event "+common_web.EventType_name[hEv.EvType], hEv)
}
}
/* This method gets internalized and therefor the mutex won't be accessible*/
func (data *jsEventReceiver) HandleEvent(ev *pb.Event ) {
func (data *jsEventReceiver) HandleEvent(ev *pb.Event) {
go func() {
jsEv := NewJsEventFromNative(ev)
switch jsEv.Type {
//if LOG event add to logArray
case common_web.EVT_LOG:
if logEv,err := jsEv.toLogEvent(); err == nil {
if logEv, err := jsEv.toLogEvent(); err == nil {
data.LogArray.Call("push", logEv)
} else {
println("couldn't convert to LogEvent: ", jsEv)
}
//if HID event add to eventHidArray
case common_web.EVT_HID:
if hidEv,err := jsEv.toHidEvent(); err == nil {
if hidEv, err := jsEv.toHidEvent(); err == nil {
data.HidEventArray.Call("push", hidEv)
//handle event

View File

@ -63,6 +63,7 @@ type GlobalState struct {
FailedConnectionAttempts int `js:"failedConnectionAttempts"`
InterfaceSettings *jsEthernetSettingsList `js:"InterfaceSettings"`
WiFiSettings *jsWiFiSettings `js:"wifiSettings"`
WiFiState *jsWiFiConnectionState `js:"wifiConnectionState"`
}
func createGlobalStateStruct() GlobalState {
@ -89,7 +90,7 @@ func createGlobalStateStruct() GlobalState {
panic("Couldn't retrieve WiFi settings")
}
state.WiFiSettings = wifiSettings
state.WiFiState = NewWiFiConnectionState()
return state
}
@ -128,16 +129,32 @@ func actionUpdateWifiSettingsFromDeployed(store *mvuex.Store, context *mvuex.Act
return
}
/*
func actionDeployWifiSettings(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState, settings *jsWiFiSettings) {
go func() {
println("Vuex dispatch deploy WiFi settings")
// convert to Go type
goSettings := settings.toGo()
err := RpcClient.DeployeWifiSettings(time.Second*3, goSettings)
wstate, err := RpcClient.DeployWifiSettings(time.Second*20, goSettings)
if err != nil {
Alert(err)
QuasarNotifyError("Error deploying WiFi Settings", err.Error(), QUASAR_NOTIFICATION_POSITION_BOTTOM)
}
state.WiFiState.fromGo(wstate)
}()
}
*/
func actionDeployWifiSettings(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState, settings *jsWiFiSettings) {
go func() {
println("Vuex dispatch deploy WiFi settings")
// convert to Go type
goSettings := settings.toGo2()
wstate, err := RpcClient.DeployWifiSettings2(time.Second*20, goSettings)
if err != nil {
QuasarNotifyError("Error deploying WiFi Settings", err.Error(), QUASAR_NOTIFICATION_POSITION_BOTTOM)
}
state.WiFiState.fromGo(wstate)
}()
}
@ -251,7 +268,7 @@ func initMVuex() *mvuex.Store {
}),
mvuex.Getter("hidjobsRunning", func(state *GlobalState) interface{} {
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available
filtered := jobs.Call("filter", func(job *jsHidJobState) bool {
return !(job.HasSucceeded || job.HasFailed)
@ -260,7 +277,7 @@ func initMVuex() *mvuex.Store {
}),
mvuex.Getter("hidjobsFailed", func(state *GlobalState) interface{} {
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available
filtered := jobs.Call("filter", func(job *jsHidJobState) bool {
return job.HasFailed
@ -269,7 +286,7 @@ func initMVuex() *mvuex.Store {
}),
mvuex.Getter("hidjobsSucceeded", func(state *GlobalState) interface{} {
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available
filtered := jobs.Call("filter", func(job *jsHidJobState) bool {
return job.HasSucceeded

View File

@ -39,15 +39,24 @@ func (rpc *Rpc) DeployedEthernetInterfaceSettings(timeout time.Duration, setting
return
}
func (rpc *Rpc) DeployeWifiSettings(timeout time.Duration, settings *pb.WiFiSettings) (err error) {
func (rpc *Rpc) DeployWifiSettings(timeout time.Duration, settings *pb.WiFiSettings) (state *pb.WiFiConnectionState, err error) {
// ToDo: The RPC call has to return an error in case deployment fails
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
_, err = rpc.Client.DeployWifiSettings(ctx, settings)
state, err = rpc.Client.DeployWifiSettings(ctx, settings)
return
}
func (rpc *Rpc) DeployWifiSettings2(timeout time.Duration, settings *pb.WiFi2Settings) (state *pb.WiFi2State, err error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
state, err = rpc.Client.DeployWiFiSettings2(ctx, settings)
return
}
func (rpc *Rpc) GetDeployedWiFiSettings(timeout time.Duration) (settingsList *jsWiFiSettings, err error) {
/*
//ToDo: Only placeholder, replace with real "get deployed" RPC