Ticket #2213: SSDPdiscover_V5_bugreport.au3

File SSDPdiscover_V5_bugreport.au3, 7.0 KB (added by skyteddy <rainer@…>, on Jun 5, 2012 at 3:53:19 PM)
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