diff --git a/WinNUT_V2/WinNUT-Client/WinNUT.vb b/WinNUT_V2/WinNUT-Client/WinNUT.vb index bdd1e55..deec7d5 100644 --- a/WinNUT_V2/WinNUT-Client/WinNUT.vb +++ b/WinNUT_V2/WinNUT-Client/WinNUT.vb @@ -446,6 +446,7 @@ Public Class WinNUT UpdateIcon_NotifyIcon() LogFile.LogTracing("Update Icon", LogLvl.LOG_DEBUG, Me) RaiseEvent UpdateBatteryState("Lost Connect") + UpdateMainMenuState() End Sub ''' diff --git a/WinNUT_V2/WinNUT-Client_Common/Common_Enums.vb b/WinNUT_V2/WinNUT-Client_Common/Common_Enums.vb index 2d6a8e6..abec61b 100644 --- a/WinNUT_V2/WinNUT-Client_Common/Common_Enums.vb +++ b/WinNUT_V2/WinNUT-Client_Common/Common_Enums.vb @@ -61,7 +61,8 @@ End Enum ' Define possible responses according to NUT protcol v1.2 Public Enum NUTResponse - NORESPONSE + EMPTY + UNRECOGNIZED OK VAR ACCESSDENIED diff --git a/WinNUT_V2/WinNUT-Client_Common/Nut_Socket.vb b/WinNUT_V2/WinNUT-Client_Common/Nut_Socket.vb index a8f616f..daf48f5 100644 --- a/WinNUT_V2/WinNUT-Client_Common/Nut_Socket.vb +++ b/WinNUT_V2/WinNUT-Client_Common/Nut_Socket.vb @@ -35,7 +35,7 @@ Public Class Nut_Socket ''' Private streamInUse As Boolean - Public Event Socket_Broken(ex As NutException) + Public Event Socket_Broken() Public Sub New(Nut_Config As Nut_Parameter, ByRef logger As Logger) LogFile = logger @@ -122,9 +122,10 @@ Public Class Nut_Socket ''' ''' Perform various functions necessary to disconnect the socket from the NUT server. ''' - ''' Skip sending the LOGOUT command to the NUT server. Unknown effects. - Public Sub Disconnect(Optional forceful = False) - If IsLoggedIn AndAlso Not forceful Then + ''' Do not send the LOGOUT command to the NUT server. Unknown effects. + Public Sub Disconnect(Optional skipLogout = False) + If IsLoggedIn AndAlso Not skipLogout Then + ' TODO: Move to new subroutine. Query_Data("LOGOUT") End If @@ -138,47 +139,11 @@ Public Class Nut_Socket ReaderStream.Dispose() End If - If NutStream IsNot Nothing Then - NutStream.Dispose() - End If - If client IsNot Nothing Then client.Close() End If End Sub - ''' - ''' Parse and enumerate a NUT protocol response. - ''' - ''' The raw response given from a query. - ''' - Private Function EnumResponse(Data As String) As NUTResponse - Dim Response As NUTResponse - ' Remove hyphens to prepare for parsing. - Dim SanitisedString = UCase(Data.Replace("-", String.Empty)) - ' Break the response down so we can get specifics. - Dim SplitString = SanitisedString.Split(" "c) - - Select Case SplitString(0) - Case "OK", "VAR", "DESC", "UPS" - Response = NUTResponse.OK - Case "BEGIN" - Response = NUTResponse.BEGINLIST - Case "END" - Response = NUTResponse.ENDLIST - Case "ERR" - Response = DirectCast([Enum].Parse(GetType(NUTResponse), SplitString(1)), NUTResponse) - Case "NETWORK", "1.0", "1.1", "1.2", "1.3" - 'In case of "VER" or "NETVER" Query - Response = NUTResponse.OK - Case Else - ' We don't recognize the response, throw an error. - Response = NUTResponse.NORESPONSE - 'Throw New Exception("Unknown response from NUT server: " & Response) - End Select - Return Response - End Function - ''' ''' Attempt to send a query to the NUT server, and do some basic parsing. ''' @@ -188,43 +153,59 @@ Public Class Nut_Socket ''' call is in progress. ''' Thrown when the NUT server returns an error or unexpected response. Function Query_Data(Query_Msg As String) As Transaction - Dim Response As NUTResponse - Dim DataResult As String - Dim finalTransaction As Transaction + If Not ConnectionStatus Then + Throw New InvalidOperationException("Attempted to send query " & Query_Msg & " while disconnected.") + End If If streamInUse Then - Throw New InvalidOperationException("Attempted to query " & Query_Msg & " while stream is in use.") + Throw New InvalidOperationException("Attempted to send query " & Query_Msg & " while stream is in use.") End If - If ConnectionStatus Then + Try streamInUse = True + WriterStream.WriteLine(Query_Msg) + WriterStream.Flush() + Catch + Throw + Finally + streamInUse = False + End Try - Try - WriterStream.WriteLine(Query_Msg & vbCr) - WriterStream.Flush() - Catch - Throw - Finally - streamInUse = False - End Try + Dim responseEnum = NUTResponse.EMPTY + Dim response = ReaderStream.ReadLine() - DataResult = Trim(ReaderStream.ReadLine()) - Response = EnumResponse(DataResult) - finalTransaction = New Transaction(Query_Msg, DataResult, Response) - - ' Handle error conditions - If DataResult = Nothing OrElse DataResult.StartsWith("ERR") Then - ' TODO: Does null dataresult really mean an error condition? - ' https://stackoverflow.com/a/6523010/530172 - 'Disconnect(True, True) - 'RaiseEvent Socket_Broken(New NutException(Query_Msg, Nothing)) - Throw New NutException(finalTransaction) - End If + If String.IsNullOrEmpty(response) Then + ' End of stream reached, likely server terminated connection. + Disconnect(True) + RaiseEvent Socket_Broken() Else - Throw New InvalidOperationException("Attempted to send query while disconnected.") + Dim parseResponse = response.Trim().ToUpper().Split(" "c) ' TODO: Is Trim unnecessary? + + Select Case parseResponse(0) + Case "OK", "VAR", "DESC", "UPS" + responseEnum = NUTResponse.OK + Case "BEGIN" + responseEnum = NUTResponse.BEGINLIST + Case "END" + responseEnum = NUTResponse.ENDLIST + Case "NETWORK", "1.0", "1.1", "1.2", "1.3" + 'In case of "VER" or "NETVER" Query + responseEnum = NUTResponse.OK + Case "ERR" + responseEnum = DirectCast([Enum].Parse(GetType(NUTResponse), + parseResponse(1).Replace("-", String.Empty)), NUTResponse) + Case Else + responseEnum = NUTResponse.UNRECOGNIZED + End Select End If - Return finalTransaction + Dim transaction = New Transaction(Query_Msg, response, responseEnum) + + If responseEnum = NUTResponse.OK OrElse responseEnum = NUTResponse.BEGINLIST OrElse responseEnum = NUTResponse.ENDLIST Then + Return transaction + End If + + Throw New NutException(transaction) End Function Public Function Query_List_Datas(Query_Msg As String) As List(Of UPS_List_Datas) @@ -351,12 +332,4 @@ Public Class Nut_Socket Throw New NutException(Nut_Query) End If End Function - - Private Sub Event_WatchDog(sender As Object, e As EventArgs) - Dim Nut_Query = Query_Data("") - If Nut_Query.ResponseType = NUTResponse.NORESPONSE Then - Disconnect(True) - RaiseEvent Socket_Broken(New NutException(Nut_Query)) - End If - End Sub End Class diff --git a/WinNUT_V2/WinNUT-Client_Common/UPS_Device.vb b/WinNUT_V2/WinNUT-Client_Common/UPS_Device.vb index 64dcf2e..a133eae 100644 --- a/WinNUT_V2/WinNUT-Client_Common/UPS_Device.vb +++ b/WinNUT_V2/WinNUT-Client_Common/UPS_Device.vb @@ -429,7 +429,6 @@ Public Class UPS_Device Catch Excep As Exception LogFile.LogTracing("Something went wrong in Retrieve_UPS_Datas:", LogLvl.LOG_ERROR, Me) LogFile.LogException(Excep, Me) - Socket_Broken() End Try End Sub @@ -481,12 +480,10 @@ Public Class UPS_Device Continue For End If End If - Case Else - LogFile.LogTracing("Error with " & varName & ", trying next", LogLvl.LOG_WARNING, Me) - ' Continue to next variable - Continue For + Throw End Select + Catch ex As Exception LogFile.LogTracing("Exception for variable " & varName & ": " & ex.Message & ", trying next", LogLvl.LOG_WARNING, Me) ' Continue to next variable