Ticket #2213: SSDPdiscover_V5_bugreport.au3

File SSDPdiscover_V5_bugreport.au3, 7.0 KB (added by skyteddy <rainer@…>, 11 years ago)
Line 
1#include <Date.au3>
2#include <Array.au3>
3
4Opt("MustDeclareVars", 1)
5
6; --- MainVar-Deklaration ---
7#region MainVar-Deklaration
8; Für SSDPdiscover
9Global $MyCollectedResponses ; Array with the collected Responses
10Global $MyTimeToSearch = 15 * 1000 ; time to search in ticks
11Global $MySendInterval = 3 * 1000; each x ticks the ssdp-discover will be sent
12Global $MyResultDatei = ".\ssdp-discover-result.txt"
13Global $MyTemp, $MyError, $MyReturn
14#endregion MainVar-Deklaration
15
16
17; --- Main ---
18#region Main
19; -- SSDP Discxover via UPnP --
20$MyReturn = SSDPdiscover_V1($MyCollectedResponses, $MyTimeToSearch, $MySendInterval)
21$MyError = @error
22If $MyError <> 0 Then
23        $MyTemp = "SSDPdiscover failed!" & @CRLF & @CRLF
24        Switch $MyError
25                Case 0
26                        ; nix
27                Case 1
28                        $MyTemp &= "UDPOpen-error"
29                Case 2
30                        $MyTemp &= "UDPSend-error"
31                Case 3
32                        $MyTemp &= "UDPRecv-error"
33                Case 4
34                        $MyTemp &= "UDPBind-error"
35        EndSwitch
36        MsgBox(0, "error:", $MyTemp)
37        Exit
38EndIf
39
40If IsArray($MyCollectedResponses) Then
41        _ArrayDisplay($MyCollectedResponses)
42Else
43        MsgBox(0, "error", "no responses")
44EndIf
45
46Exit
47#endregion Main
48
49
50
51; --- Funktionsdefinitionen ---
52#region Funktionsdefinitionen
53; Function that performs a UPnP ssdp-discover and writes the results into an array.
54; In addition, the IP addresses of the devices are written in a second array.
55; V1: Receive-Socket = Send-Socket. Works on XP (independed how many networkcards are installed) and Win 7 only, when all network cards, exclude 1, are disabled in the device manager
56; Error:
57;   0  =  no Error
58;   1  =  UDPOpen-error
59;   2  =  UDPSend-error
60;   3  =  UDPRecv-error
61;   4  =  UDPBind-error
62Func SSDPdiscover_V1(ByRef $ResponsesArray, $TicksToSearch = 10000, $SendIntervalInTicks = 1000)
63
64        ; --- UPnP-Kommando ---
65        Local Const $UPnPcmd = _
66                        'M-SEARCH * HTTP/1.1' & @CRLF & _
67                        'ST:upnp:rootdevice' & @CRLF & _
68                        'MX: 10' & @CRLF & _
69                        'MAN: "ssdp:discover"' & @CRLF & _
70                        'HOST: 239.255.255.250:1900' & @CRLF & _
71                        @CRLF
72        Local $UPNPsendSocket, $UPNPreceiveSocket
73        Local $SendCounter = 0, $ReceiveCounter = 0
74        Local $ReceiveData
75        Local $StartTimeoutTimer, $UsedTimeoutTicks ; Timeout-Timer
76        Local $StartSendTimer, $UsedSendTicks ; Send-Timer
77        Local $OldRemainSeconds = -99, $RemainSeconds
78        Local $return = 1, $error = 0
79
80        ; Arrays "löschen"
81        $ResponsesArray = ""
82
83        ; UPnP-Kommando ausgeben
84        ConsoleWrite(@CRLF)
85        ConsoleWrite("UPnP-Kommando:" & @CRLF)
86        ConsoleWrite($UPnPcmd & @CRLF)
87
88        ; UDP starten
89        UDPStartup()
90
91        ; - Sender -
92        ;    $array[1] contains the real socket, $array[2] contains the specified IP address and $array[3] contains the port
93        $UPNPsendSocket = UDPOpen("239.255.255.250", 1900)
94        ConsoleWrite("SendSocket: real socket: " & $UPNPsendSocket[1] & ", IP-address: " & $UPNPsendSocket[2] & ", port: " & $UPNPsendSocket[3] & @CRLF & @CRLF)
95        ; _ArrayDisplay($UPNPsendSocket)
96        If $UPNPsendSocket[0] == -1 Or $UPNPsendSocket[0] == 0 Then ; documentation is somewhat vague
97                ; Error 1
98                Return SetError(1, 0, 0)
99        EndIf
100
101        ; - Empfänger -
102        ; Socket muß der gleiche sein, sonst geht es nicht. Allerdings funktioniert es nicht auf Win 7-Rechnern mit mehreren Netzwerkkarten :-(
103        $UPNPreceiveSocket = $UPNPsendSocket
104
105        ; Timer setzen
106        $StartTimeoutTimer = TimerInit() ; Timeout-Timer
107        $StartSendTimer = -99 ; Notlösung, kann man schöner programmieren
108
109        While 1
110
111                ; SenderPause berechnen
112                If $StartSendTimer = -99 Then
113                        ; Timer wurde bisher noch nicht gesetzt, daher UsedTicks setzen
114                        $UsedSendTicks = $SendIntervalInTicks + 10
115                Else
116                        ; Berechnen
117                        $UsedSendTicks = TimerDiff($StartSendTimer)
118                EndIf
119
120                ; Senden
121                If $UsedSendTicks > $SendIntervalInTicks Then
122                        $SendCounter += 1
123                        ConsoleWrite("UPnP Send Count Nr " & $SendCounter & @CRLF & @CRLF)
124                        UDPSend($UPNPsendSocket, $UPnPcmd)
125                        If @error <> 0 Then
126                                $error = 2
127                                $return = 0
128                                ExitLoop
129                        EndIf
130                        ; reset timer
131                        $StartSendTimer = TimerInit()
132                EndIf
133
134                ; kurze Pause (nach dem Senden)
135                Sleep(100)
136
137                ; Empfangen
138                $ReceiveData = UDPRecv($UPNPreceiveSocket, 1024)
139                If @error <> 0 Then
140                        $error = 3
141                        $return = 0
142                        ExitLoop
143                EndIf
144                If $ReceiveData <> "" Then
145                        $ReceiveCounter += 1
146                        ConsoleWrite("-------------------- Received Response " & $ReceiveCounter & ":" & " --------------------" & @CRLF)
147                        ConsoleWrite($ReceiveData & @CRLF)
148                        ; Wenn neue Responds, dann hinzugügen
149                        If AddItemToArray($ResponsesArray, $ReceiveData, 1) > 0 Then
150                                ConsoleWrite("+> added" & @CRLF & @CRLF)
151                        Else
152                                ConsoleWrite("-> still available" & @CRLF & @CRLF)
153                        EndIf
154                EndIf
155
156                ; Verbrauchte Zeit ermitteln
157                $UsedTimeoutTicks = TimerDiff($StartTimeoutTimer)
158                ; Wenn die Zeit verstrichen ist, dann raus
159                If $UsedTimeoutTicks >= $TicksToSearch Then
160                        ExitLoop
161                Else
162                        ; Restsekunden berechnen und als TrayTip ausgeben
163                        $RemainSeconds = Ceiling(($TicksToSearch - $UsedTimeoutTicks) / 1000)
164                        If $RemainSeconds <> $OldRemainSeconds Then
165                                TrayTip("SSDP-Discover", "Search for devices via UPnP (" & $RemainSeconds & " seconds)... ", 5, 1)
166                                $OldRemainSeconds = $RemainSeconds
167                        EndIf
168                EndIf
169        WEnd
170
171        ; TrayTip schliessen
172        TrayTip("", "", 0)
173
174        ; Socket schliessen
175        UDPCloseSocket($UPNPsendSocket)
176        UDPCloseSocket($UPNPreceiveSocket)
177
178        ; UDP beenden
179        UDPShutdown()
180
181        ; Sortieren
182        If IsArray($ResponsesArray) Then _ArraySort($ResponsesArray, 0, 1)
183
184        ; Wenn error vorhanden, dann error zurückliefern
185        If $error > 0 Then
186                ; error zurückliefern
187                Return SetError($error, 0, $return)
188        Else
189                ; Normaler Return
190                Return $return
191        EndIf
192
193EndFunc   ;==>SSDPdiscover_V1
194
195
196
197
198; Funktion, die ein Item an das Array (mit Zelle) hinzufügt und dabei den Counter in Zelle 0 um eins erhöht
199; Ist das Array noch leer, wird es angelegt. Es wird der Counter zurückgeliefert
200; Wenn $OnlyIfNew = 1, dann wird vorher geschaut, ob es schon im Array vorhanden ist
201Func AddItemToArray(ByRef $ArrayWithCounterCell, $value, $OnlyIfNew = 0) ; Fügt zum Array ein Item hinzu und erhöht den Wert in Zelle 0. Ist das Array leer, wird eines erzeugt
202
203        ; Schauen, ob es ein Array ist. Wenn nicht, dann wird es angelegt und der Wert hinzugefügt
204        If IsArray($ArrayWithCounterCell) Then
205                ; es ist ein Array
206                ; ggf. schauen, ob es bereits enthalten ist
207                If $OnlyIfNew == 1 Then
208                        ; Raus, wenn es bereist enthalten ist, also größer als 0
209                        If _ArraySearch($ArrayWithCounterCell, $value, 1) > 0 Then
210                                Return 0
211                        EndIf
212                EndIf
213
214                ; Element hinzufügen
215                Local $ret = _ArrayAdd($ArrayWithCounterCell, $value)
216                ; wenn ungleich -1 dann den Counter erhöhen
217                If $ret <> -1 Then
218                        ; um 1 erhöhren in Zelle 0
219                        Local $Count = $ArrayWithCounterCell[0] + 1
220                        $ArrayWithCounterCell[0] = $Count
221                        ; Index, also Count zurückliefern
222                        Return $Count
223                Else
224                        Return -1
225                EndIf
226        Else
227                ; Es ist kein Array, daher erzeugen und Wert hinzufügen
228                Dim $ArrayWithCounterCell[2]
229                $ArrayWithCounterCell[0] = 1
230                $ArrayWithCounterCell[1] = $value
231                Return 1
232        EndIf
233
234EndFunc   ;==>AddItemToArray
235#endregion Funktionsdefinitionen