Code: Select all
'' ----------------------------------------------------------------------------
'' UDP Packet test for Network variables
'' Version 0.1
'' Author F.Dodd March 2006
'' FreeBasic v0.15 (www.freebasic.net/)
'' SDL Simple DirectMedia Layer v1.2 (www.libsdl.org/)
''
'' Thanks and acknowledgement to many members of the FreeBasic forums for
'' helpfull postings and code snippets to learn and crib from
''
'' ----------------------------------------------------------------------------
' Library includes ------------------------------------------------------------
' SDL Library for Networking support. Requires SDL.dll SDL_Net.dll
'$include: "SDL/SDL_net.bi"
' Structured type declarations ------------------------------------------------
' a network variables message
Type netvarmessage
uifunction As Uinteger ' what this message is to do
uiindex As Uinteger ' the index of the record being addressed
uivalue As Uinteger ' the value of the record being addressed
End Type
' Constant value declarations -------------------------------------------------
Const NET_VAR_WRITE = 0 ' function code for writing a variable value
Const NET_VAR_ACK = 1 ' function code for acknowledging a message
Const NET_VAR_PORT = 41003 ' the sockets port used for network variable comms
' Subroutine and Function declarations ----------------------------------------
' Swapping Little to Big endianess or visa-versa of a 32bit unsigned value
Declare Function SwapEndian( uiValue As Uinteger )
' writing a UDP packet containing a network variable write message
Declare Sub NetVarWrite( index As Uinteger, value As Uinteger )
' writing a UDP packet containing a network variable acknowledgement
Declare Sub NetVarAck()
' Handle a received network variable message
Declare Sub HandleNetVarMessage(silentsignal)
' Display a banner with some instructions
Declare Sub PrintHelp()
' Global variable declarations ------------------------------------------------
' these variables are shared across all subroutines and functions
Dim Shared As UDPsocket data_socket ' the socket for UDP transmissions
Dim Shared As UDPpacket packet ' buffer for UDP packet sends and receives
Dim Shared As netvarmessage data_buffer ' buffer for UDP packet data
Dim Shared As String address ' string containing the network address
' -----------------------------------------------------------------------------
''
'' main() function
''
Dim As IPaddress iaddress ' numerical host address and port
Dim As UInteger uiIndex = 0 ' a variable index
Dim As UInteger uiValue = 0 ' a variable value
' initialise the SDL network library
If SDLNet_Init() = 0 Then
' ask the user for host address
Line Input "Please enter the host address (<Enter> for 192.168.0.65): ";address
' if the user entered a blank address
If address = "" Then
' set the address to the default
address = "192.168.0.65"
End If
' resolve the host address for the specified address
SDLNet_ResolveHost( @iaddress, Strptr(address), NET_VAR_PORT)
' open the socket on the network variable port
data_socket = SDLNet_UDP_Open( NET_VAR_PORT )
' if the socket was successfully opened
If Not data_socket = 1 Then
' bind the socket to the resolved host using the first available channel
packet.channel = SDLNet_UDP_Bind( data_socket, -1, @iaddress )
' if the socket was successfully bound
If Not packet.channel = -1 Then
'display the help script
PrintHelp
' a network variables udp packet always contains 12 bytes of data
' point the packet at our data buffer and specify the size of the
' buffer
packet.Data = CAST( Zstring Ptr, @data_buffer )
packet.Len = 12
packet.maxlen = 12
' automatic acknowledgements are not silenced
silentsignal = 0
' the exit signal is not raised
exitsignal = 0
' inform the user that we are wait for a udp data packet
Print "Listening for a packet ..."
' repeat until the exit signal is raised
While exitsignal = 0
' handle incomming network messages ...........................
' check if there is a packet waiting
sizerecv = SDLNet_UDP_Recv( data_socket, @packet)
' if data was received
If sizerecv = 1 Then
' process the received data
HandleNetVarMessage(silentsignal)
' inform the user that we are wait for a udp data packet
Print "Press C to reset. Listening for a packet ..."
End if
' handle user input ...........................................
' check if a key was pressed
a$ = Inkey$
' arbitrate based on the pressed key
Select Case a$
Case "s","S"
' user has asked to toggle acknowledment mode
' if we are not silent
If silentsignal = 0 Then
' switch into silent mode
Print "Silencing Replies"
silentsignal = 1
Else
' we were in silent mode
' switch into automatic acknowledgement mode
Print "Allowing Replies"
silentsignal = 0
End If
Case "w","W"
' get the index and value
Line Input "Variable Number ";A$
Line Input "Variable Value ";B$
uiIndex = Val(A$)
uiValue = Val(B$)
' write the network variable
NetVarWrite( uiIndex, uiValue )
Case "r","R"
' increment the value
uiValue += 1
' resend the network variable
NetVarWrite( uiIndex, uiValue )
Case "a","A"
' manually transmit an acknowledgement (this should
' cause an unexpected ack error at the host)
NetVarAck
Case "c","C"
' reset the display
Cls
PrintHelp
Case Else
' handle non specific keys
' If an unrecognised key is pressed its a signal to end
If Not a$ = "" Then
' signal that the application is to exit
exitsignal = 1
End If
End Select
Wend
Else
Print "Unable to bind socket"
End If
SDLNet_UDP_Close(data_socket)
Else
Print "Unable to open a socket on port ";NET_VAR_PORT
End If
SDLNet_Quit()
Else
Print "SDL Library could not be initialised"
End If
' Subroutine and Function declarations ----------------------------------------
'' ............................................................................
'' Function to change the endianess of the data in the transmission
''
Function SwapEndian( uiValue As Uinteger )
Dim uiConverted As Uinteger
uiConverted = ( uiValue And &hFF ) Shl 24
uiConverted += ( uiValue And &hFF00 ) Shl 8
uiConverted += ( uiValue And &hFF0000 ) Shr 8
uiConverted += ( uiValue And &hFF000000 ) Shr 24
SwapEndian = uiConverted
End Function
'' ............................................................................
'' Subroutine to send a UDP packet that writes a network variable
''
Sub NetVarWrite( index As Uinteger, value As Uinteger )
' Format the network variable write data
data_buffer.uifunction = 0
data_buffer.uiindex = SwapEndian(index)
data_buffer.uivalue = SwapEndian(value)
' send out an acknowledgement
Print "Writing network variable ";index;" with ";value
sizesent=SDLNet_UDP_Send(data_socket, packet.channel, @packet)
' display a message to the user if an error occurs
If sizesent < 1 Then
Print "Unable to send data correctly"
End If
End Sub
'' ............................................................................
'' Subroutine to send a UDP packet that acknowledges a network variable write
''
Sub NetVarAck()
' Reply with an ACK
data_buffer.uifunction = &h01000000
' send out an acknowledgement
Print "Sending an acknowledgement"
sizesent=SDLNet_UDP_Send(data_socket, packet.channel, @packet)
' display a message to the user if an error occurs
If sizesent < 1 Then
Print "Unable to send data correctly"
End If
End Sub
'' ............................................................................
'' Handle a received network variable message
''
Sub HandleNetVarMessage(silentsignal)
' display the recieved packet
Print Time$;": Received( Func:";SwapEndian(data_buffer.uiFunction);
Print " Index:";SwapEndian(data_buffer.uiindex);
Print " Value:";SwapEndian(data_buffer.uivalue);" )"
' if automatic acknowledgements are not silenced and
If silentsignal = 0 Then
' if the function code indicates we received a write
If data_buffer.uifunction = 0 Then
NetVarAck
End If
End If
' insert a blank line to format the display
Print ""
End Sub
'' ............................................................................
'' Display a banner with some instructions
''
Sub PrintHelp()
' reset the display
Cls
' display instructions
Print "UDP Network Variable Test Software v0.1 talking to ";address
Print
Print "Press C to clear the display and reprint this message"
Print "Press S to toggle automatic acknowledgments on and off"
Print "Press A to manually transmit an acknowledgement"
Print "Press W to manually send a test write message"
Print "Press R to increment the value in and resend the test message"
Print "Press any other key to exit"
Print
End Sub