summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exports/exports.go11
-rw-r--r--internal/fsm/fsm.go33
-rw-r--r--state.go21
-rw-r--r--wrappers/python/src/__init__.py1
-rw-r--r--wrappers/python/src/main.py6
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()
diff --git a/state.go b/state.go
index ef3ea65..da78d19 100644
--- a/state.go
+++ b/state.go
@@ -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)