Code: Select all
;
; PIC Ethernet Discover
;
; |
#Version = "1.00"
EnableExplicit
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
#AF_INET = 2
#SOCK_DGRAM = 2
#SO_BROADCAST = 6
#SOL_SOCKET = 1
#INADDR_ANY = 0
#INADDR_BROADCAST = $FFFFFFFF
#IPPROTO_UDP = 17
#FIONBIO = $5421
#INVALID_SOCKET = -1
#SOCKET_ERROR = -1
Structure sockaddr_in Align #PB_Structure_AlignC
sin_family.u
sin_port.u
sin_addr.l
sin_zero.a[8]
EndStructure
CompilerCase #PB_OS_MacOS
#AF_INET = 2
#SOCK_DGRAM = 2
#SO_BROADCAST = $20
#SOL_SOCKET = $FFFF
#INADDR_ANY = 0
#INADDR_BROADCAST = $FFFFFFFF
#IPPROTO_UDP = 17
#INVALID_SOCKET = -1
#SOCKET_ERROR = -1
Structure sockaddr_in Align #PB_Structure_AlignC
sin_family.u
sin_port.u
sin_addr.l
sin_zero.a[8]
EndStructure
CompilerEndSelect
Define service.sockaddr_in
Define RxAddr.sockaddr_in
Define RxAddrLen.i
Define TxAddr.sockaddr_in
Define Socket.i
Define argp.l
Define *Buffer
Define Querry$, Receive$, Found$, Name$, MAC$, IP$
Define.i Starttime, Avail, First, Exit, Event, Found, i
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Define wsaData.WSADATA
; initialize the WindowsSocketAPI
If WSAStartup_($101, @wsaData) <> #NO_ERROR
End 2
EndIf
CompilerEndIf
; open an UDP socket
Socket = SOCKET_(#AF_INET, #SOCK_DGRAM, #IPPROTO_UDP)
If Socket = #INVALID_SOCKET
End 3
EndIf
; set it to none blocking
argp = 1
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
ioctl_(Socket, #FIONBIO, @argp)
CompilerCase #PB_OS_MacOS
#F_SETFL = 4
#O_NONBLOCK = 4
fcntl_(Socket, #F_SETFL, #O_NONBLOCK)
CompilerCase #PB_OS_Windows
ioctlsocket_(Socket, #FIONBIO, @argp)
CompilerEndSelect
; allow broadcasts on that socket
argp = $FFFFFFFF
setsockopt_(Socket, #SOL_SOCKET, #SO_BROADCAST, @argp, 4)
; bind the socket to port 30303 and listen to all incoming addresses
service\sin_family = #AF_INET
service\sin_addr = #INADDR_ANY
service\sin_port = htons_(30303)
If bind_(Socket, @service, SizeOf(sockaddr_in)) <> #SOCKET_ERROR
*Buffer = AllocateMemory(1536)
If *Buffer
; needed for recvfrom()
RxAddrLen = SizeOf(sockaddr_in)
Querry$ = "Discovery: Who is out there?"
RxAddr\sin_family = #AF_INET
RxAddr\sin_port = htons_(30303)
RxAddr\sin_addr = #INADDR_ANY
TxAddr\sin_family = #AF_INET
TxAddr\sin_port = htons_(30303)
TxAddr\sin_addr = #INADDR_BROADCAST
OpenWindow(0, 0, 0, 400, 200, "Ethernet Discover V" + #Version + " (c) 2012 Infratec AG", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ListIconGadget(0, 10, 10, 380, 180, "Name", 100, #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "MAC", 110)
AddGadgetColumn(0, 2, "Address", 100)
SetActiveGadget(0)
AddWindowTimer(0, 0, 100)
First = #True
Exit = #False
Repeat
Event = WaitWindowEvent(10)
Select Event
Case #PB_Event_Timer
If EventTimer() = 0
If First
RemoveWindowTimer(0, 0)
AddWindowTimer(0, 0, 5000)
First = #False
EndIf
sendto_(Socket, @Querry$, Len(Querry$), 0, @TxAddr, SizeOf(sockaddr_in))
EndIf
Case #PB_Event_Gadget
If EventType() = #PB_EventType_LeftDoubleClick
IP$ = GetGadgetItemText(0, GetGadgetState(0), 2)
RunProgram("http://" + IP$)
EndIf
Case #PB_Event_CloseWindow : Exit = #True
EndSelect
Avail = recvfrom_(Socket, *Buffer, MemorySize(*Buffer), #Null, @RxAddr, @RxAddrLen)
If Avail > 0
Receive$ = PeekS(*Buffer, Avail)
If Receive$ <> Querry$
Receive$ = ReplaceString(Receive$, #CRLF$, #LF$)
Name$ = StringField(Receive$, 1, #LF$)
MAC$ = StringField(Receive$, 2, #LF$)
;Info$ = StringField(Receive$, 3, #LF$)
IP$ = IPString(RxAddr\sin_addr)
Found = #False
For i = 0 To CountGadgetItems(0) - 1
If GetGadgetItemText(0, i, 1) = MAC$
Found = #True
Break
EndIf
Next i
If Found
SetGadgetItemText(0, i, Name$, 0)
SetGadgetItemText(0, i, IP$, 2)
Else
AddGadgetItem(0, -1, Name$ + #LF$ + MAC$ + #LF$ + IP$)
EndIf
EndIf
EndIf
Until Exit
FreeMemory(*Buffer)
EndIf
EndIf
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
close_(Socket)
CompilerElse
closesocket_(Socket)
WSACleanup_()
CompilerEndIf
It discovers MicroChip ethernet PIC CPUs when the TCP/IP stack is running.