
' Jose includes used

#INCLUDE ONCE "cCTSQL/cCTSQLiteServer.bi"
#INCLUDE ONCE "Afx/CWindow.inc"
USING Afx

dim shared HWND_MAIN_CLOSEBUTTON as HWnd
Dim shared iErrorCode            as Long
Dim shared sErrorDescription     as String
Dim shared lpLogCriticalSection  as CRITICAL_SECTION

declare Sub BroadcastConnection(ByVal Instance as PTP_CALLBACK_INSTANCE, ByVal Context as PVOID, ByVal Work as PTP_WORK)
DECLARE Sub AcceptConnection(ByVal Instance as PTP_CALLBACK_INSTANCE, ByVal Context as PVOID, ByVal Work as PTP_WORK)
Declare Sub CallBackLogMessage(ByVal Instance as PTP_CALLBACK_INSTANCE, ByVal Context as PVOID, ByVal Work as PTP_WORK)
declare Function ListenerProc(ByVal HWnd as HWnd,ByVal uMsg as UINT,ByVal wParam as WPARAM,ByVal lParam as LPARAM) as LRESULT

CONST IDC_MAIN_CLOSEBUTTON = 28000


DECLARE FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
                          BYVAL hPrevInstance AS HINSTANCE, _
                          BYVAL szCmdLine AS ZSTRING PTR, _
                          BYVAL nCmdShow AS LONG) AS LONG

   END WinMain(GetModuleHandleW(NULL), NULL, COMMAND(), SW_NORMAL)

' // Forward declaration
DECLARE FUNCTION WndProc (BYVAL hWnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
                  BYVAL hPrevInstance AS HINSTANCE, _
                  BYVAL szCmdLine AS ZSTRING PTR, _
                  BYVAL nCmdShow AS LONG) AS LONG

Dim uLogRecord    as SQLITE_LOG

   ' // Create the main window
   DIM pWindow AS CWindow
   pWindow.Create(NULL, "", @WndProc)
   pWindow.SetClientSize(300, 210)
   pWindow.Center

   ' // Add and show a button control 
   
   HWND_MAIN_CLOSEBUTTON = pWindow.AddControl("Button", pWindow.hWindow, IDC_MAIN_CLOSEBUTTON, "&Shutdown", 105, 90, 75, 28, BS_PUSHBUTTON,-1)
   ShowWindow( HWND_MAIN_CLOSEBUTTON, SW_SHOW)   
   InitializeCriticalSection(ByVal VarPtr(lpLogCriticalSection))
   If oServer.StartupStatus = False Then

      Print "Server startup failed. Error=" + oServer.StartupErrorDescription
      
   else
      
      oServer.ServerSharedKey (0,1,2,3,4,5)
      
      oServer.ServerStartup (@ListenerProc, _
                             8791, _
                             8792, _
                             iErrorCode, _
                             sErrorDescription)
                             
      GetLocalTime(ByVal VarPtr(uLogRecord.LocalTime))
      uLogRecord.ErrorCode = 0
      uLogRecord.Event = SQLITE_EVENT_SERVER_STARTUP
      uLogRecord.Severity = SQLITE_SEVERITY_INFO                                   
      uLogRecord.Message = "Startup successful. Waiting for connections..."
      oServer.PostCallBack(uLogRecord)
   
   End If
   
   ' // Dispatch Windows messages
   
   FUNCTION = pWindow.DoEvents(nCmdShow)

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main window callback procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hWnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   SELECT CASE uMsg

      CASE WM_COMMAND
         
         If (LoWord(wParam) = IDC_MAIN_CLOSEBUTTON) Andalso (HiWord(wParam) = BN_CLICKED) Then

            oServer.ServerShutdown()
            DeleteCriticalSection(ByVal VarPtr(lpLogCriticalSection)) 
            
         PostQuitMessage(0)
         EXIT FUNCTION
            
         end if

      CASE WM_NOTIFY

      CASE WM_SIZE

    	CASE WM_DESTROY
         ' // End the application by sending an WM_QUIT message
         PostQuitMessage(0)
         EXIT FUNCTION

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProc(hWnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================
Sub BroadcastConnection(ByVal Instance as PTP_CALLBACK_INSTANCE, ByVal Context as PVOID, ByVal Work as PTP_WORK)

Dim sIPAddress        as String
Dim iErrorCode        as Long
Dim sErrorDescription as String
dim oCrypto           as cCTSQLiteCrypto
Dim uLogRecord        as SQLITE_LOG

    oServer.BroadcastReceived (sIPAddress,iErrorCode,sErrorDescription,oCrypto)
    
End Sub

Sub AcceptConnection(ByVal Instance as PTP_CALLBACK_INSTANCE, ByVal Context as PVOID, ByVal Work as PTP_WORK)

Dim sIPAddress        as String
Dim iErrorCode        as Long
Dim sErrorDescription as String
Dim hSocket           as SOCKET
Dim sSend             as String
Dim sReceive          as String
dim oCrypto           as cCTSQLiteCrypto
dim uServerKey        AS SQLITE_SERVER_ENCRYPTION
dim uClientKey        AS SQLITE_SERVER_ENCRYPTION
Dim uLogRecord        as SQLITE_LOG

    uLogRecord.Event = SQLITE_EVENT_CLIENT_CONNECT

    If oServer.AcceptTCPConnection(hSocket,sIPAddress,uServerKey,uClientKey,iErrorCode,sErrorDescription,oCrypto) = False then

       GetLocalTime(ByVal VarPtr(uLogRecord.LocalTime))
       uLogRecord.Severity = SQLITE_SEVERITY_FAILURE
       uLogRecord.IPAddress = sIPAddress
       uLogRecord.ErrorCode = iErrorCode
       uLogRecord.Message = sErrorDescription
       oServer.PostCallBack(uLogRecord)       
    
    else
       
       GetLocalTime(ByVal VarPtr(uLogRecord.LocalTime))
       uLogRecord.Severity = SQLITE_SEVERITY_INFO
       uLogRecord.IPAddress = sIPAddress
       uLogRecord.ErrorCode = 0
       uLogRecord.Message = ""
       oServer.PostCallBack(uLogRecord)       

       oServer.ClientReceive(hSocket,sReceive,iErrorCode,sErrorDescription,uClientKey,oCrypto)

       GetLocalTime(ByVal VarPtr(uLogRecord.LocalTime))
       uLogRecord.Event = SQLITE_EVENT_CLIENT_REQUEST       
       uLogRecord.Severity = SQLITE_SEVERITY_INFO
       uLogRecord.IPAddress = sIPAddress
       uLogRecord.ErrorCode = 0
       uLogRecord.Message = sReceive
       oServer.PostCallBack(uLogRecord)       
   
       sSend = "Echo=" + sReceive
   
       oServer.ClientSend(hSocket,sSend,iErrorCode,sErrorDescription,uServerKey,oCrypto)
       
       GetLocalTime(ByVal VarPtr(uLogRecord.LocalTime))
       uLogRecord.Event = SQLITE_EVENT_CLIENT_RESPONSE       
       uLogRecord.Severity = SQLITE_SEVERITY_INFO
       uLogRecord.IPAddress = sIPAddress
       uLogRecord.ErrorCode = 0
       uLogRecord.Message = sSend
       oServer.PostCallBack(uLogRecord)
   
       oServer.CloseClientConnection(hSocket)
       
    end if   

End Sub

Function ListenerProc(ByVal HWnd as HWnd, _
                      ByVal uMsg as UINT, _
                      ByVal wParam as WPARAM, _
                      ByVal lParam as LPARAM) as LRESULT

' Connection request messages are posted here

    Select Case uMsg

      Case SQLITE_SERVER_TCP_CONNECT

         Select Case LoWord(lParam)

            Case FD_ACCEPT
           
               oServer.CreateConnectionThread(@AcceptConnection)
                
            End Select
            
        Case SQLITE_SERVER_UDP_BROADCAST
  
            Select Case LoWord(lParam)

            Case FD_READ
            
               oServer.CreateConnectionThread(@BroadcastConnection)

            End Select
            
        Case SQLITE_SERVER_EVENT
           
' wParam contains the callback message id

           oServer.CreateMessageThread(@CallBackLogMessage,CAST(PVOID,wParam))

        Case WM_CREATE

        Case WM_CLOSE

        Case WM_DESTROY

            PostQuitMessage 0

    End Select

    Function = DefWindowProc(HWnd,uMsg,wParam,lParam)       ' Windows handles the rest
    
End Function
Sub CallBackLogMessage(ByVal Instance as PTP_CALLBACK_INSTANCE, ByVal Context as PVOID, ByVal Work as PTP_WORK)

dim uCallBack as SQLITE_LOG
Dim sMessage  as string

    oServer.GetCallBackMessage(Cast(Long,Context),uCallBack)

    sMessage = Str(uCallBack.LocalTime.wYear) _
             + "-" _
             + Format(uCallBack.LocalTime.wMonth,"00") _
             + "-" _
             + Format(uCallBack.LocalTime.wDay,"00") _
             + " " _
             + Format(uCallBack.LocalTime.wHour,"00") _
             + ":" _
             + Format(uCallBack.LocalTime.wMinute,"00") _
             + ":" _
             + Format(uCallBack.LocalTime.wSecond,"00") _ 
             + "." _
             + Format(uCallBack.LocalTime.wMilliseconds,"000") _
             + " "
             
    Select CASE uCallBack.Event
       
       Case SQLITE_EVENT_SERVER_STARTUP
 
          sMessage = sMessage + "Server Startup - " + uCallBack.Message
          
       Case SQLITE_EVENT_CLIENT_CONNECT
          
          If uCallBack.Severity = SQLITE_SEVERITY_FAILURE THEN
             
             sMessage = sMessage + "Client connection rejected - " _
                      + "IP=" + uCallBack.IPAddress + "," _
                      + str(uCallBack.ErrorCode) + " - " _
                      + uCallBack.Message
                      
          Else
             
             sMessage = sMessage + "Client connection from " _
                      + uCallBack.IPAddress _
                      + " accepted."
             
          END IF
          
       Case SQLITE_EVENT_BROADCAST_RECEIVED
          
          If uCallBack.Severity = SQLITE_SEVERITY_INFO THEN
          
             sMessage = sMessage + "Broadcast received from " + uCallBack.IPAddress
             
          Else
             
             If uCallBack.Severity = SQLITE_SEVERITY_WARNING THEN
                
                sMessage = sMessage + "Broadcast received from " + uCallBack.IPAddress + " rejected."
                
             Else
                
                sMessage = sMessage + "Broadcast received network error - " _
                         + str(uCallBack.ErrorCode) + " - " + uCallBack.Message  
                
             End If
             
          End If         

       Case SQLITE_EVENT_CLIENT_REQUEST
          
          sMessage = sMessage + "Request received from " + uCallBack.IPAddress + " - " _
                   + uCallBack.Message
                   
       Case SQLITE_EVENT_CLIENT_RESPONSE
          
          sMessage = sMessage + "Response to " + uCallBack.IPAddress + " - " _
                   + uCallBack.Message 

       Case SQLITE_EVENT_CLIENT_AUTHENTICATION
          
          sMessage = sMessage + "Client at " + uCallBack.IPAddress
          
          If uCallBack.Severity = SQLITE_SEVERITY_INFO THEN
             
             sMessage = sMessage + " authenticated."
             
          Else
             
             If uCallBack.Severity = SQLITE_SEVERITY_WARNING THEN
             
                sMessage = sMessage + " authentication failure."
                
             ELSE
                
                sMessage = sMessage + " authentication network error - " _
                         + str(uCallBack.ErrorCode) + " - " + uCallBack.Message  
                
             End If
             
          End If                            
             
       CASE ELSE
          
    END SELECT         

    EnterCriticalSection(@lpLogCriticalSection)

    print sMessage
   
    LeaveCriticalSection(@lpLogCriticalSection)   

end sub