diff options
| -rw-r--r-- | exports/exports.go | 11 | ||||
| -rw-r--r-- | internal/fsm/fsm.go | 33 | ||||
| -rw-r--r-- | state.go | 21 | ||||
| -rw-r--r-- | wrappers/python/src/__init__.py | 1 | ||||
| -rw-r--r-- | wrappers/python/src/main.py | 6 |
5 files changed, 56 insertions, 16 deletions
diff --git a/exports/exports.go b/exports/exports.go index 331270f..a00fa15 100644 --- a/exports/exports.go +++ b/exports/exports.go @@ -260,6 +260,17 @@ func SetDisconnected(name *C.char) *C.char { return C.CString(ErrorToString(setDisconnectedErr)) } +//export SetConnecting +func SetConnecting(name *C.char) *C.char { + nameStr := C.GoString(name) + state, stateErr := GetVPNState(nameStr) + if stateErr != nil { + return C.CString(ErrorToString(stateErr)) + } + setConnectingErr := state.SetConnecting() + return C.CString(ErrorToString(setConnectingErr)) +} + //export SetConnected func SetConnected(name *C.char) *C.char { nameStr := C.GoString(name) diff --git a/internal/fsm/fsm.go b/internal/fsm/fsm.go index 85e83fb..f719da7 100644 --- a/internal/fsm/fsm.go +++ b/internal/fsm/fsm.go @@ -57,11 +57,14 @@ const ( // Requested config means the user has requested a config for connecting REQUEST_CONFIG + // Ask profile means the go code is asking for a profile selection from the UI + ASK_PROFILE + // Has config means the user has gotten a config HAS_CONFIG - // Ask profile means the go code is asking for a profile selection from the UI - ASK_PROFILE + // Connecting means the OS is establishing a connection to the server + CONNECTING // Connected means the user has been connected to the server CONNECTED @@ -91,6 +94,8 @@ func (s FSMStateID) String() string { return "Ask_Profile" case AUTHORIZED: return "Authorized" + case CONNECTING: + return "Connecting" case CONNECTED: return "Connected" default: @@ -109,13 +114,14 @@ type ( type FSMState struct { Transitions []FSMTransition - MainState bool + + // Which state to go back to on a back transition + BackState FSMStateID } type FSM struct { States FSMStates Current FSMStateID - PreviousMain FSMStateID // Info to be passed from the parent state Name string @@ -127,9 +133,9 @@ type FSM struct { func (fsm *FSM) Init(name string, callback func(string, string, string), logger *log.FileLogger, directory string, debug bool) { fsm.States = FSMStates{ - DEREGISTERED: FSMState{Transitions: []FSMTransition{{NO_SERVER, "Client registers"}}, MainState: true}, - NO_SERVER: FSMState{Transitions: []FSMTransition{{CHOSEN_SERVER, "User chooses a server"}, {SEARCH_SERVER, "The user is trying to choose a Server in the UI"}}, MainState: true}, - SEARCH_SERVER: FSMState{Transitions: []FSMTransition{{LOADING_SERVER, "User clicks a server in the UI"}, {NO_SERVER, "Cancel or Error"}}, MainState: true}, + DEREGISTERED: FSMState{Transitions: []FSMTransition{{NO_SERVER, "Client registers"}}}, + NO_SERVER: FSMState{Transitions: []FSMTransition{{CHOSEN_SERVER, "User chooses a server"}, {SEARCH_SERVER, "The user is trying to choose a Server in the UI"}, {CONNECTED, "The user is already connected"}}}, + SEARCH_SERVER: FSMState{Transitions: []FSMTransition{{LOADING_SERVER, "User clicks a server in the UI"}, {NO_SERVER, "Cancel or Error"}}, BackState: NO_SERVER}, ASK_LOCATION: FSMState{Transitions: []FSMTransition{{CHOSEN_SERVER, "Location chosen"}, {NO_SERVER, "Cancel or Error"}, {SEARCH_SERVER, "Cancel or Error"}}}, LOADING_SERVER: FSMState{Transitions: []FSMTransition{{CHOSEN_SERVER, "Server info loaded"}, {ASK_LOCATION, "User chooses a Secure Internet server but no location is configured"}}}, CHOSEN_SERVER: FSMState{Transitions: []FSMTransition{{AUTHORIZED, "Found tokens in config"}, {OAUTH_STARTED, "No tokens found in config"}}}, @@ -137,8 +143,9 @@ func (fsm *FSM) Init(name string, callback func(string, string, string), logger AUTHORIZED: FSMState{Transitions: []FSMTransition{{OAUTH_STARTED, "Re-authorize with OAuth"}, {REQUEST_CONFIG, "Client requests a config"}}}, REQUEST_CONFIG: FSMState{Transitions: []FSMTransition{{ASK_PROFILE, "Multiple profiles found and no profile chosen"}, {HAS_CONFIG, "Only one profile or profile already chosen"}, {NO_SERVER, "Cancel or Error"}, {OAUTH_STARTED, "Re-authorize"}}}, ASK_PROFILE: FSMState{Transitions: []FSMTransition{{HAS_CONFIG, "User chooses profile"}, {NO_SERVER, "Cancel or Error"}, {SEARCH_SERVER, "Cancel or Error"}}}, - HAS_CONFIG: FSMState{Transitions: []FSMTransition{{CONNECTED, "OS reports connected"}, {REQUEST_CONFIG, "User chooses a new profile"}, {NO_SERVER, "User wants to choose a new server"}}, MainState: true}, - CONNECTED: FSMState{Transitions: []FSMTransition{{HAS_CONFIG, "OS reports disconnected"}}, MainState: true}, + HAS_CONFIG: FSMState{Transitions: []FSMTransition{{CONNECTING, "OS reports it is trying to connect"}, {REQUEST_CONFIG, "User chooses a new profile"}, {NO_SERVER, "User wants to choose a new server"}}, BackState: NO_SERVER}, + CONNECTING: FSMState{Transitions: []FSMTransition{{HAS_CONFIG, "Cancel or Error"}, {CONNECTED, "Done connecting"}}}, + CONNECTED: FSMState{Transitions: []FSMTransition{{HAS_CONFIG, "OS reports disconnected"}}}, } fsm.Current = DEREGISTERED fsm.Name = name @@ -185,7 +192,7 @@ func (fsm *FSM) writeGraph() { } func (fsm *FSM) GoBack() { - fsm.GoTransition(fsm.PreviousMain) + fsm.GoTransition(fsm.States[fsm.Current].BackState) } func (fsm *FSM) GoTransitionWithData(newState FSMStateID, data string, background bool) bool { @@ -193,12 +200,6 @@ func (fsm *FSM) GoTransitionWithData(newState FSMStateID, data string, backgroun if ok { oldState := fsm.Current - - // Is the Old (now current) state a main state? - // If so set the previous main state such that we could go easily back to it - if fsm.States[oldState].MainState { - fsm.PreviousMain = oldState - } fsm.Current = newState if fsm.Debug { fsm.writeGraph() @@ -338,6 +338,10 @@ func (state *VPNState) SetSearchServer() error { } func (state *VPNState) SetConnected() error { + if state.FSM.InState(fsm.CONNECTED) { + // already connected, show no error + return nil + } if !state.FSM.HasTransition(fsm.CONNECTED) { return &types.WrappedErrorMessage{Message: "failed to set connected", Err: fsm.WrongStateTransitionError{Got: state.FSM.Current, Want: fsm.CONNECTED}.CustomError()} } @@ -346,7 +350,24 @@ func (state *VPNState) SetConnected() error { return nil } +func (state *VPNState) SetConnecting() error { + if state.FSM.InState(fsm.CONNECTING) { + // already loading connection, show no error + return nil + } + if !state.FSM.HasTransition(fsm.CONNECTING) { + return &types.WrappedErrorMessage{Message: "failed to set connecting", Err: fsm.WrongStateTransitionError{Got: state.FSM.Current, Want: fsm.CONNECTING}.CustomError()} + } + + state.FSM.GoTransition(fsm.CONNECTING) + return nil +} + func (state *VPNState) SetDisconnected() error { + if state.FSM.InState(fsm.HAS_CONFIG) { + // already disconnected, show no error + return nil + } if !state.FSM.HasTransition(fsm.HAS_CONFIG) { return &types.WrappedErrorMessage{Message: "failed to set disconnected", Err: fsm.WrongStateTransitionError{Got: state.FSM.Current, Want: fsm.HAS_CONFIG}.CustomError()} } diff --git a/wrappers/python/src/__init__.py b/wrappers/python/src/__init__.py index a438ed3..802ceec 100644 --- a/wrappers/python/src/__init__.py +++ b/wrappers/python/src/__init__.py @@ -82,6 +82,7 @@ lib.SetSecureLocation.argtypes, lib.SetSecureLocation.restype = [ c_char_p, ], c_void_p lib.SetConnected.argtypes, lib.SetConnected.restype = [c_char_p], c_void_p +lib.SetConnecting.argtypes, lib.SetConnecting.restype = [c_char_p], c_void_p lib.SetDisconnected.argtypes, lib.SetDisconnected.restype = [c_char_p], c_void_p lib.GetIdentifier.argtypes, lib.GetIdentifier.restype = [c_char_p], DataError lib.SetIdentifier.argtypes, lib.SetIdentifier.restype = [c_char_p, c_char_p], c_void_p diff --git a/wrappers/python/src/main.py b/wrappers/python/src/main.py index 84be0ab..008973d 100644 --- a/wrappers/python/src/main.py +++ b/wrappers/python/src/main.py @@ -144,6 +144,12 @@ class EduVPN(object): if connect_err: raise Exception(connect_err) + def set_connecting(self) -> None: + connecting_err = self.go_function(lib.SetConnecting) + + if connecting_err: + raise Exception(connecting_err) + def set_disconnected(self) -> None: disconnect_err = self.go_function(lib.SetDisconnected) |
