Jump to content

UPnP Relay Broadcasts


Recommended Posts

Why? I have a AV Media Server that follows the UPnP 1.0 Spec. that needs to be accessed from an Xbox 360 UPnP Rendering Device which is connected to the LAN via MS's ICS which routes data to and from the device. This creates a (seperate subnet/broadcast domain) therfore when the Xbox sends a SSDP discovery broadcast to discover the Media Server, if the server receives/responds, the return broadcast won't be received. From what I understand TCP/IP was intentionally designed to prevent broadcasts from being routed to other LANs. This creates a problem when you have a second broadcast domain on your primary LAN. Essentially, I have a WAN if you disregard the distances.

Still making a lot of assumptions here, If I receive the broadcast from the Media Server on the Comp. that is connected directly to the network aka the same broadcast domain, which provides the Xbox with Internet connectivity then relaying that broadcast from its neutral location would successfully allow the Xbox to discover the Media Server, as the Location header field(has the address of the server) in the relayed broadcast will reveal the information needed for the Xbox to become a control point of the Media Server.

I would love some clarifications on the subject.  I need to be able to receive multicast SSDP discovery messages via UDP. I've tried and failed so far... I can send a UPnP service discovery broadcast and receive respones but when I try to listen for these broadcasts, I fail.

I've attempted to bind to the multicast address - 239.255.255.255 on port 1900 and @IPAddress1 on an available high number port without luck. I really don't know much, just what I've read.

Thanks Everyone. ;)

Edit - I can bind to the address mentioned above, I just don't receive any data. My best quess is that I'm not listening properly!!!

I'm using this script to send a UPnP SSDP Broadcast.

#include <Array.au3>
#include <Inet.au3>
#include <String.au3>
#include <Icons.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

;#include <_XMLDomWrapper.au3>

; -- SSDP Discovery via UPnP --

Global $sErrMsg = "SSDP Discovery Failed!" & @CRLF & @CRLF, $iErrorSuccess = 0

Global $aRecycleBin_InitialSize = 25, $aRecycleBin[$aRecycleBin_InitialSize]

; -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
; SSDP Broadcast:
;   Recieve and Send Sockets are the same and use the same variable --- $aSocket.
;  Tested on XP. Works on Win 7 only when all but one NIC have been disabled via the device manager.
;
; SSDP Discovery Error Codes:
;   1  =  UDP Open Error
;   2  =  UDP Send Error
;   3  =  UDP Recv Error
;   4  =  UDP Bind Error
; -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Global $aResponse ; Empty variables for data collection
Global $iResult = SSDP_Broadcast($aResponse)

Switch @error
    Case 1
        $sErrMsg &= "UDP Open Error"
    Case 2
        $sErrMsg &= "UDP Send Error"
    Case 3
        $sErrMsg &= "UDP Recv Error"
    Case 4
        $sErrMsg &= "UDP Bind Error"
    Case Else
        $sErrMsg = False
EndSwitch

If $sErrMsg Then
    MsgBox(16 + 262144, "SSDP Discovery:", $sErrMsg)
    Exit
EndIf

If $iResult Then
    Global $aDevice[$aResponse[0] + 1][15]
    $aDevice[0][0] = $aResponse[0]
    ; Global Enum Identifiers 0 - 14 = 15 elements
    Global Enum $iLOCATION, $iEXT, $iUSN, $iSERVER, $iCACHECONTROL, $iST, $iDATE, $iCONTENTLENGTH, $iIP, $iXML, $iRESPONSE, _
            $iFRIENDLYNAME, $iDEVICETYPE, $iICONURL, $iMODELNAME
    For $i = 1 To $aDevice[0][0] Step 1
        $aDevice[$i][$iRESPONSE] = $aResponse[$i]
    Next
    _ParseResponse()
EndIf

Global $aTemp[$aDevice[0][0] + 1][15], $iCount = 0, $iD, $bMatch = False

For $i = 1 To $aDevice[0][0] Step 1
    If $aDevice[$i][$iLOCATION] <> "" Then
        $bMatch = False
        For $iD = 1 To $aDevice[0][0] Step 1
            If $aDevice[$i][$iSERVER] = $aTemp[$iD][$iSERVER] And _
                    $aDevice[$i][$iLOCATION] = $aTemp[$iD][$iLOCATION] Then
                $bMatch = True
                If $aDevice[$i][$iLOCATION] = $aTemp[$iD][$iLOCATION] And $aDevice[$i][$iUSN] <> "" Then
                    If $aTemp[$iD][$iUSN] = "" Then
                        $aTemp[$iD][$iUSN] = $aDevice[$i][$iUSN]
                    EndIf
                EndIf
            EndIf
        Next
        If $bMatch Then
            ContinueLoop
        Else
            $iCount += 1
            $aTemp[$iCount][$iLOCATION] = $aDevice[$i][$iLOCATION]
            $aTemp[$iCount][$iEXT] = $aDevice[$i][$iEXT]
            $aTemp[$iCount][$iSERVER] = $aDevice[$i][$iSERVER]
            $aTemp[$iCount][$iCACHECONTROL] = $aDevice[$i][$iCACHECONTROL]
            $aTemp[$iCount][$iST] = $aDevice[$i][$iST]
            $aTemp[$iCount][$iUSN] = $aDevice[$i][$iUSN]
            $aTemp[$iCount][$iDATE] = $aDevice[$i][$iDATE]
            $aTemp[$iCount][$iCONTENTLENGTH] = $aDevice[$i][$iCONTENTLENGTH]
            $aTemp[$iCount][$iIP] = _ExtractIP($aDevice[$i][$iLOCATION])
            $aTemp[$iCount][$iRESPONSE] = $aDevice[$i][$iRESPONSE]
        EndIf
    EndIf
Next
If $iCount Then
    $aTemp[0][0] = $iCount
    $aDevice = $aTemp
    $aTemp = ""
    ReDim $aDevice[$iCount + 1][15]
EndIf

For $i = 1 To $aDevice[0][0] Step 1
    $aDevice[$i][$iXML] = _INetGetSource($aDevice[$i][$iLOCATION])
    $hXML = FileOpen($aDevice[$i][$iIP] & " - Location" & $i & ".xml", 2)
    FileWrite($hXML, $aDevice[$i][$iXML])
    FileClose($hXML)
    $aDevice[$i][$iXML] = $aDevice[$i][$iIP] & " - Location" & $i & ".xml"
    _RecycleBin($aDevice[$i][$iXML])
Next

Dim $aType, $sXML, $sIcon, $hPic, $sImage, $sFriendlyName, $sMsg, $sIconURL
Dim $hBroadcastButton, $hCancelButton

For $iDEV = 1 To $aDevice[0][0] Step 1
    $sXML = FileRead($aDevice[$iDEV][$iXML])
    $aType = _StringBetween($sXML, "<deviceType>", "</deviceType>")
    If IsArray($aType) Then
        $aDevice[$iDEV][$iDEVICETYPE] = $aType[0]
        ConsoleWrite(">Found " & $aDevice[$iDEV][$iDEVICETYPE] & " at " & $aDevice[$iDEV][$iLOCATION] & @CRLF)
        GUICreate("UPnP Device", 300, 100, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
        $aDevice[$iDEV][$iMODELNAME] = _GetModelName($sXML)
        $iSolidus = StringInStr($aDevice[$iDEV][$iLOCATION], "/", 2, 3)
        $sIcon = StringMid($aDevice[$iDEV][$iLOCATION], 1, $iSolidus - 1)
        If Not @error Then
            $sIconURL = _GetIcon32($sXML)
            $sIcon &= $sIconURL
            $sImage = @ScriptDir & "\Device.png"
            If $sIconURL <> "" Then
                InetGet($sIcon, $sImage, 1)
            Else
                If $aDevice[$iDEV][$iMODELNAME] = "Xbox 360" Then
                    $sImage = @ScriptDir & "\Xbox360black.png"
                Else
                    $sImage = @ScriptDir & "\Question.png"
                EndIf
            EndIf
            $aDevice[$iDEV][$iICONURL] = $sImage
            $hPic = GUICtrlCreatePic("", 10, 20, 32, 32)
            _SetImage($hPic, $sImage)
            $sFriendlyName = _StringBetween($sXML, "<friendlyName>", "</friendlyName>")
            If IsArray($sFriendlyName) Then
                $sFriendlyName = _ArrayToString($sFriendlyName, "")
                $aDevice[$iDEV][$iFRIENDLYNAME] = $sFriendlyName
                ConsoleWrite($aDevice[$iDEV][$iFRIENDLYNAME] & @CRLF)
                GUICtrlCreateLabel($aDevice[$iDEV][$iFRIENDLYNAME], 52, 28, 248, 15)
            EndIf
            $hBroadcastButton = GUICtrlCreateButton("&Relay this broadcast", 55, 72, 145, 22)
            $hCancelButton = GUICtrlCreateButton("&Cancel", 210, 72, 80, 22)
        EndIf
        GUISetState()
        While 1
            $sMsg = GUIGetMsg()
            Switch $sMsg
                Case $GUI_EVENT_CLOSE
                    ExitLoop
                Case $hBroadcastButton
                    GUIDelete()
                    _RelayBroadcast($iDEV)
                Case $hCancelButton
                    ExitLoop
            EndSwitch
        WEnd
        GUIDelete()
    EndIf
Next


Func _Exit()
    _RecycleBin("", True)
    Exit(0)
EndFunc


Func _RelayBroadcast($iDEV)


;Global Enum $iLOCATION, $iEXT, $iUSN, $iSERVER, $iCACHECONTROL, $iST, $iDATE, $iCONTENTLENGTH, $iIP, $iXML, $iRESPONSE, _
;       $iFRIENDLYNAME, $iDEVICETYPE, $iICONURL, $iMODELNAME

    UDPStartup()
    Local $aSocket = UDPOpen("239.255.255.250", 1900)

    Local Enum $iSocket = 0, $iAddress = 1, $iPort = 2

    If Not $aSocket[$iSocket] Then
        Return SetError(1, 0, 0) ; Failed to open socket.
    EndIf

    HotKeySet("{ESC}", "_Exit")

    While 1
        TrayTip("UPnP Relay - " & $aDevice[$iDEV][$iFRIENDLYNAME], "+>Broadcasting..." & @CRLF & @CRLF & $aDevice[$iDEV][$iRESPONSE] & @CRLF & @CRLF, 2)
        UDPSend($aSocket, StringReplace($aDevice[$iDEV][$iRESPONSE], "TVersity Media Server", "UPnP Relay"))
        Sleep(1000)
    WEnd

    UDPCloseSocket($aSocket)
    UDPShutdown()

    _Exit()

EndFunc

Func _GetModelName($sXML)
    Local $aModel = _StringBetween($sXML, "<modelName>", "</modelName>")
    If IsArray($aModel) Then
        Return $aModel[0]
    EndIf
EndFunc   ;==>_GetModelName

Func _GetIcon32($sXML)
    Local $aIconList = _StringBetween($sXML, "<iconList>", "</iconList>")
    If IsArray($aIconList) Then
        Local $aIcon = _StringBetween($aIconList[0], "<icon>", "</icon>"), $aURL, $aSize
        If IsArray($aIcon) Then
            For $i = 0 To UBound($aIcon, 1) - 1 Step 1
                $aSize = _StringBetween($aIcon[$i], "<width>", "</width>")
                If IsArray($aSize) Then
                    If $aSize[0] = "32" Then
                        $aURL = _StringBetween($aIcon[$i], "<url>", "</url>")
                        If IsArray($aURL) Then
                            Return $aURL[0]
                        EndIf
                    EndIf
                EndIf
            Next
        EndIf
    EndIf
EndFunc   ;==>_GetIcon32

Func _ParseResponse()
    For $iDEV = 1 To $aDevice[0][0] Step 1
        Local $aLine = StringSplit($aDevice[$iDEV][$iRESPONSE], @CRLF, 1), $iColon, $aData[2]
        For $i = 1 To $aLine[0] Step 1
            $iColon = StringInStr($aLine[$i], ":", 2, 1)
            If $iColon Then
                $aData[0] = StringStripWS(StringMid($aLine[$i], 1, $iColon - 1), 3)
                $aData[1] = StringStripWS(StringMid($aLine[$i], $iColon + 1, StringLen($aLine[$i]) - $iColon), 3)
                Switch $aData[0]
                    Case "LOCATION"
                        $aDevice[$iDEV][$iLOCATION] = $aData[1]
                    Case "EXT"
                        $aDevice[$iDEV][$iEXT] = $aData[1]
                    Case "USN"
                        $aDevice[$iDEV][$iUSN] = $aData[1]
                    Case "SERVER"
                        $aDevice[$iDEV][$iSERVER] = $aData[1]
                    Case "CACHE-CONTROL"
                        $aDevice[$iDEV][$iCACHECONTROL] = $aData[1]
                    Case "ST"
                        $aDevice[$iDEV][$iST] = $aData[1]
                    Case "DATE"
                        $aDevice[$iDEV][$iDATE] = $aData[1]
                    Case "CONTENT-LENGTH"
                        $aDevice[$iDEV][$iCONTENTLENGTH] = $aData[1]
                EndSwitch
            EndIf
        Next
    Next
EndFunc   ;==>_ParseResponse

Func SSDP_Broadcast(ByRef $aResponse)
    Local $iSearchTime = 15000, $iSendInterval = 3000 ; Values are in miliseconds
    Local $iLastTimeCheck, $iTimeLeft
    Local $iSendCounter = 0, $iResponseCounter = 0
    Local $sResponse, $sIP
    Local $iRValue = 1, $iFuncError = 0

    Local Const $sBroadcast = _
            'M-SEARCH * HTTP/1.1' & @CRLF & _
            'ST:upnp:rootdevice' & @CRLF & _
            'MX: 10' & @CRLF & _
            'MAN: "ssdp:discover"' & @CRLF & _
            'HOST: 239.255.255.250:1900' & @CRLF & _
            @CRLF

    UDPStartup()
    Local $aSocket = UDPOpen("239.255.255.250", 1900)
    Local Enum $iSocket = 0, $iAddress = 1, $iPort = 2

    ; _ArrayDisplay($aSocket)

    If Not $aSocket[$iSocket] Then
        Return SetError(1, 0, 0) ; Failed to open socket.
    EndIf

    ; Start the Search Timer
    Local $hSearchTime = TimerInit(), $hSendTime = ""
    ; Variables to store the time difference from when the timer initialized.
    Local $iSearchTimer, $iSendTimer
    ; $iSendTimer hasn't been initialized so increase the value so that $iSendTimer is greater than $iSendInterval which prevents an inital delay.
    Local $iSendTimer = ($iSendInterval + 1)

    While 1
        ; Send the first message immediately, afterwards, Send at the specified interval, which is stored in $iSendInterval
        If $iSendCounter Then
            $iSendTimer = TimerDiff($hSendTime)
        EndIf

        ; SSDP Broadcast
        If $iSendTimer > $iSendInterval Then
            $iSendCounter += 1

            UDPSend($aSocket, $sBroadcast)
            If @error <> $iErrorSuccess Then
                $iFuncError = 2 ; Local Function - Error Code
                $iRValue = $iErrorSuccess
                ExitLoop
            EndIf

            ConsoleWrite(">SSDP Broadcast #" & $iSendCounter & @CRLF & @CRLF)
            ; Reinitialize the Send Timer
            $hSendTime = TimerInit()
        EndIf

        ; Short Pause (after the Send)
        Sleep(100)
        ; Recieve Response
        $sResponse = UDPRecv($aSocket, 1024)
        If @error <> 0 Then
            $iFuncError = 3 ; Local Function - Error Code
            $iRValue = 0
            ExitLoop
        EndIf

        If $sResponse <> "" Then ; If the response isn't null then execute this block
            $iResponseCounter += 1
            ConsoleWrite("-------------------- Received Response #" & $iResponseCounter & " --------------------" & @CRLF)
            ConsoleWrite($sResponse & @CRLF)
            ; If the Response isn't null and isn't already in array then add it.
            _AddToArray($aResponse, $sResponse, True)
        EndIf

        ; Update the Search Timer
        $iSearchTimer = TimerDiff($hSearchTime)
        ; If the deadline is met or past due then exit the While-Wend loop.
        If $iSearchTimer >= $iSearchTime Then
            ExitLoop
        Else
            ; Calculate and display the remaing time
            $iTimeLeft = Ceiling(($iSearchTime - $iSearchTimer) / 1000)
            If $iTimeLeft <> $iLastTimeCheck Then
                TrayTip("SSDP-Discovery", "Searching for devices via UPnP (" & $iTimeLeft & " seconds) remaining... ", 5, 1)
                $iLastTimeCheck = $iTimeLeft
            EndIf
        EndIf
    WEnd

    TrayTip("", "", 0) ; close the TrayTip
    UDPCloseSocket($aSocket)
    UDPShutdown()

    ; Sort the arrays
    If IsArray($aResponse) Then _ArraySort($aResponse, 0, 1)

    If $iFuncError Then
        ; If there was an error then set the @error macro and return $iRValue
        Return SetError($iFuncError, 0, $iRValue)
    Else
        Return $iRValue
    EndIf
EndFunc   ;==>SSDP_Broadcast

Func _ExtractIP($sResponse)
    Local $vIP = StringRegExp($sResponse, "\d+\.\d+\.\d+\.\d+", 1)
    ; The regular expression above should return an array.
    If Not IsArray($vIP) Then
        Return
    EndIf
    ; The first index should contain the IP address.
    $vIP = $vIP[0]
    ; Ensure that the address is IPv4.
    If _IsIPv4($vIP) Then
        Return $vIP
    EndIf
EndFunc   ;==>_ExtractIP


Func _IsIPv4($sIP)
    If StringRegExp($sIP, "\A(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])\z") Then
        Return True
    EndIf
EndFunc   ;==>_IsIPv4

Func _AddToArray(ByRef $avArray, $vData, $bOnlyAddUnique = False)
    If IsArray($avArray) Then
        If $bOnlyAddUnique Then
            ; _ArraySeach(Array, Value, Starting Index) - Function Definition
            If _ArraySearch($avArray, $vData, 1, 0, 1, 0, 0, 1) <> -1 Then
                ; If the value already exists than return
                Return False
            EndIf
        EndIf
        Local $iRValue = _ArrayAdd($avArray, $vData)
        If $iRValue <> -1 Then
            ; Increase and return the index counter.
            $avArray[0] += 1
            Return $avArray[0]
        Else
            Return $iRValue
        EndIf
    Else
        ; Create the array
        Dim $avArray[2]
        $avArray[0] = 1
        $avArray[1] = $vData
        Return True
    EndIf
EndFunc   ;==>_AddToArray

Func _RecycleBin($sFileName = "", $bCommit = False)
    Static Local $iFile = 0
    Local $iUbound = UBound($aRecycleBin, 1)
    If $iFile >= $iUbound Then
        ReDim $aRecycleBin[$iUbound + $aRecycleBin_InitialSize]
    EndIf
    If $bCommit Then
        For $iFile = 0 To UBound($aRecycleBin, 1) - 1
            FileDelete($aRecycleBin[$iFile])
            $aRecycleBin[$iFile] = ""
        Next
        ReDim $aRecycleBin[$aRecycleBin_InitialSize]
        Return 1
    EndIf
    $aRecycleBin[$iFile] = $sFileName
    $iFile += 1
    Return 1
EndFunc   ;==>_RecycleBin



























































#cs

    ; Function that performs a UPnP ssdp-discover and writes the results into an array.
    ; In addition, the IP addresses of the devices are written in a second array.
    ; V2: Receive-Socket and Send-Socket are differ. I try many different ways, but nothing works :-(
    ; SSDP Discovery:
    ;   0  =  kein Error
    ;   1  =  UDPOpen-error
    ;   2  =  UDPSend-error
    ;   3  =  UDPRecv-error
    ;   4  =  UDPBind-error
    Func SSDPdiscover_V2(ByRef $aResponse, ByRef $aIP, $iSearchTime = 10000, $iSendInterval = 1000)
    ; --- UPnP-Kommando ---
    Local Const $sBroadcast = _
    'M-SEARCH * HTTP/1.1' & @CRLF & _
    'ST:upnp:rootdevice' & @CRLF & _
    'MX: 10' & @CRLF & _
    'MAN: "ssdp:discover"' & @CRLF & _
    'HOST: 239.255.255.250:1900' & @CRLF & _
    @CRLF
    Local $aSocket, $aSocket
    Local $iSendCounter = 0, $iResponseCounter = 0
    Local $sResponse, $sIP
    Local $hSearchTime, $iSearchTimer ; Timeout-Timer
    Local $hSendTime, $iSendTimer ; Send-Timer
    Local $iLastTimeCheck = -99, $iTimeLeft
    Local $iRValue = 1, $iFuncError= 0
    ; Arrays "löschen"
    $aResponse = ""
    $aIP = ""
    ; UPnP-Kommando ausgeben
    ConsoleWrite(@CRLF)
    ConsoleWrite("UPnP-Kommando:" & @CRLF)
    ConsoleWrite($sBroadcast & @CRLF)
    ; UDP starten
    UDPStartup()
    ; - Sender -
    ;   $array[1] contains the real socket, $array[2] contains the specified IP address and $array[3] contains the port
    $aSocket = UDPOpen("239.255.255.250", 1900)
    ConsoleWrite("SendSocket: real socket: " & $aSocket[1] & ", IP-address: " & $aSocket[2] & ", port: " & $aSocket[3] & @CRLF & @CRLF)
    ; _ArrayDisplay($aSocket)
    If $aSocket[0] == -1 Or $aSocket[0] == 0 Then ; documentation is somewhat vague
    ; Error 1
    Return SetError(1, 0, 0)
    EndIf
    ; - Empfänger -
    If @IPAddress1 <> "0.0.0.0" Then ConsoleWrite(@IPAddress1 & @CRLF)
    If @IPAddress2 <> "0.0.0.0" Then ConsoleWrite(@IPAddress2 & @CRLF)
    If @IPAddress3 <> "0.0.0.0" Then ConsoleWrite(@IPAddress3 & @CRLF)
    If @IPAddress4 <> "0.0.0.0" Then ConsoleWrite(@IPAddress4 & @CRLF)
    ; $aSocket = UDPBind("127.0.0.1", 1900)
    ; $aSocket = UDPBind(@IPAddress1, 1900)
    ; $aSocket = UDPBind("127.0.0.1", $aSocket[1])
    ; $aSocket = UDPBind(@IPAddress1, $aSocket[1])
    ; $aSocket = UDPBind("239.255.255.250", 1900)
    $aSocket = UDPBind(@IPAddress1, 1900)
    ConsoleWrite("ReceiveSocket: real socket: " & $aSocket[1] & ", IP-address: " & $aSocket[2] & ", port: " & $aSocket[3] & @CRLF & @CRLF)
    ; _ArrayDisplay($aSocket)
    If $aSocket[0] == -1 Or $aSocket[0] == -0 Then ; documentation is somewhat vague
    ; Error 4
    Return SetError(4, 0, 0)
    EndIf
    ; Timer setzen
    $hSearchTime = TimerInit() ; Timeout-Timer
    $hSendTime = -99 ; temporary solution, could be better :)
    While 1
    ; SenderPause calculate
    If $hSendTime = -99 Then
    ; Timer has not been set, so put ticks Used
    $iSendTimer = $iSendInterval + 10
    Else
    ; calculate
    $iSendTimer = TimerDiff($hSendTime)
    EndIf
    ; Send
    If $iSendTimer > $iSendInterval Then
    $iSendCounter += 1
    ConsoleWrite("UPnP Send Count No. " & $iSendCounter & @CRLF & @CRLF)
    UDPSend($aSocket, $sBroadcast)
    If @error <> 0 Then
    $iFuncError= 2
    $iRValue = 0
    ExitLoop
    EndIf
    ; reset timer
    $hSendTime = TimerInit()
    EndIf
    ; Short Pause (after the Send)
    Sleep(100)
    ; Recieve
    $sResponse = UDPRecv($aSocket, 1024)
    If @error <> 0 Then
    $iFuncError= 3
    $iRValue = 0
    ExitLoop
    EndIf
    If $sResponse <> "" Then
    $iResponseCounter += 1
    ConsoleWrite("-------------------- Received Response " & $iResponseCounter & ":" & " --------------------" & @CRLF)
    ConsoleWrite($sResponse & @CRLF)
    ; when new Responds, then add
    If _AddToArray($aResponse, $sResponse, 1) > 0 Then
    ConsoleWrite("-> added" & @CRLF & @CRLF)
    Else
    ConsoleWrite("-> already available" & @CRLF & @CRLF)
    EndIf
    ; IP extract und collect
    $sIP = _ExtractIP($sResponse)
    If $sIP <> "" Then _AddToArray($aIP, $sIP, 1)
    EndIf
    ; spent time determine
    $iSearchTimer = TimerDiff($hSearchTime)
    ; when buy the elapsed time, then out
    If $iSearchTimer >= $iSearchTime Then
    ExitLoop
    Else
    ; Remaining seconds calculate and output as TrayTip
    $iTimeLeft = Ceiling(($iSearchTime - $iSearchTimer) / 1000)
    If $iTimeLeft <> $iLastTimeCheck Then
    TrayTip("SSDP-Discover", "Search for devices via UPnP (" & $iTimeLeft & " seconds)... ", 5, 1)
    $iLastTimeCheck = $iTimeLeft
    EndIf
    EndIf
    WEnd
    ; TrayTip close
    TrayTip("", "", 0)
    ; Socket close
    UDPCloseSocket($aSocket)
    UDPCloseSocket($aSocket)
    ; UDP end
    UDPShutdown()
    ; sort out
    If IsArray($aIP) Then _ArraySort($aIP, 0, 1)
    If IsArray($aResponse) Then _ArraySort($aResponse, 0, 1)
    ; When error exists, then return error
    If $iFuncError> 0 Then
    ; return error
    Return SetError($iError, 0, $iRValue)
    Else
    ; normal return
    Return $iRValue
    EndIf
    EndFunc   ;==>SSDPdiscover_V2
    ; Function extracted from the IP address ReceivedPacket

    #endregion function definitions

#ce

I'm using this script to listen for a broadcast.

Global $g_sIPAdress = "239.255.255.255"
Global $g_iPort = 1900
Global $g_iMaxChar = 1024
Global $g_iRecvInterval = 100

Global $g_aSocket

Global Enum $iStartupError, $iBindError, $iIPAddrError, $iPortError, $iSocketError, $iShutdownError

_Main()

Func _Main()
    _ServerInitialize()
    Local $sResponse = ""
    While 1
        $sResponse = _ServerReceive()
        If Not @error And $sResponse <> "" Then
            ConsoleWrite($sResponse & @CRLF & @CRLF)
        EndIf
        Sleep($g_iRecvInterval)
    WEnd
EndFunc

Func _ServerInitialize()
    UDPStartup()
    If @error Then
        Return SetError($iStartupError)
    Else
        OnAutoItExitRegister("_ServerShutdown")
    EndIf
    $g_aSocket = UDPBind($g_sIPAdress, $g_iPort)
    Switch @error
        Case 1
            Return SetError($iBindError, $iIPAddrError)
        Case 2
            Return SetError($iBindError, $iPortError)
    EndSwitch
EndFunc

Func _ServerReceive()
    Local $sResponse = UDPRecv($g_aSocket, $g_iMaxChar)
    If @error Then
        Return SetError($iSocketError, -1, $sResponse)
    Else
        Return $sResponse
    EndIf
EndFunc

Func _ServerShutdown()
    UDPCloseSocket($g_aSocket)
    If @error Then
        Return SetError($iSocketError)
    EndIf
    UDPShutdown()
    If @error Then
        Return SetError($iShutdownError)
    EndIf
EndFunc
Edited by Decipher
Spoiler

censored.jpg

 

Link to comment
Share on other sites

  • 1 year later...

Not to excite you sorry but i am having a similar question  but i cant see how to get the response back and get the IP of what i am looking for...

i tried using some of your code but its not doing anything and finishes quickly.... my post is here:

 

thanks it looks you have a great understanding of what is going on

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...