Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/SSDP?V=2
QUERY_STRINGV=2
CONTENT_TYPE
DOCUMENT_URI/revision/SSDP
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.130.133
REMOTE_PORT10612
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.15.156.140
HTTP_CF_RAY879db06bcf582d3d-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP3.15.156.140
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit SSDP http://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol%|%From\ Wikipedia%|%:\n\n''The\ Simple\ Service\ Discovery\ Protocol\ (SSDP)\ is\ a\ network\ protocol\ based\ on\ the\ Internet\ Protocol\ Suite\ for\ advertisement\ and\ discovery\ of\ network\ services\ and\ presence\ information.\ It\ accomplishes\ this\ without\ assistance\ of\ server-based\ configuration\ mechanisms,\ such\ as\ the\ Dynamic\ Host\ Configuration\ Protocol\ (DHCP)\ or\ the\ Domain\ Name\ System\ (DNS),\ and\ without\ special\ static\ configuration\ of\ a\ network\ host.\ SSDP\ is\ the\ basis\ of\ the\ discovery\ protocol\ of\ Universal\ Plug\ and\ Play\ and\ is\ intended\ for\ use\ in\ residential\ or\ small\ office\ environments.\ It\ was\ formally\ described\ in\ an\ IETF\ Internet\ draft\ by\ Microsoft\ and\ Hewlett-Packard\ in\ 1999.\ Although\ the\ IETF\ proposal\ has\ since\ expired,\ SSDP\ was\ incorporated\ into\ the\ UPnP\ protocol\ stack,\ and\ a\ description\ of\ the\ final\ implementation\ is\ included\ in\ UPnP\ standards\ documents.''\n\n----\n\n\[FB\]\ Here\ is\ a\ small\ SSDP\ package\ that\ I\ wrote\ for\ a\ UPnP\ media\ server\ of\ mine\ (\"Mediatheque\",\ just\ change\ the\ `ssdp::Server`\ variable\ to\ whatever\ you\ choose).\ \nThe\ code\ is\ quite\ simple:\ it\ creates\ a\ UDP\ multicast\ socket\ on\ the\ well\ known\ SSDP\ address\ and\ port\ 239.255.255.250:1900,\ posts\ periodic\ alive\ messages\ and\ listens\ to\ incoming\ discovery\ requests\ on\ its\ advertised\ services:\n\n======\n#\n#\ ssdp.tcl\ --\n#\n#\ \ \ \ \ \ \ \ SSDP\ handling.\ Note\ that\ only\ features\ needed\ by\ this\ application\ are\ \n#\ \ \ \ \ \ \ \ supported,\ this\ is\ not\ a\ generic\ SSDP\ package\ although\ it\ can\ serve\ as\n#\ \ \ \ \ \ \ \ a\ basis\ for\ implementing\ one.\n#\n#\ \ \ \ \ \ \ \ SSDP\ uses\ HTTPU\ messages\ on\ the\ multicast\ UDP\ address\ 239.255.255.250:1900\n#\ \ \ \ \ \ \ \ UPNP\ uses\ SSDP\ for\ service\ announcement\ and\ discovery.\n#\n#\ \ \ \ \ \ \ \ This\ package\ uses\ a\ single\ UDP\ socket\ provided\ by\ the\ Tcl\ udp\ extension.\ \n#\ \ \ \ \ \ \ \ Minimal\ version\ is\ 1.0.9\ for\ address\ reuse\ support\ (SO_REUSEADDR)\ because\n#\ \ \ \ \ \ \ \ several\ applications\ (clients\ or\ servers)\ may\ open\ this\ address\ on\ the\ same\ \n#\ \ \ \ \ \ \ \ machine.\n#\n#\ \ \ \ \ \ \ \ TODO:\ at\ present\ the\ udp\ package\ doesn't\ support\ binding\ to\ specific\ \n#\ \ \ \ \ \ \ \ interfaces,\ so\ we\ have\ to\ specify\ the\ advertised\ device\ addresses\ manually.\n#\n\npackage\ require\ udp\ 1.0.9\n\nnamespace\ eval\ ssdp\ \{\n\ \ \ \ variable\ Server\ \"Mediatheque\"\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\ Refresh\ interval.\n\ \ \ \ \ \ \ \ variable\ Refresh\ 1800\n\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ log\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Simple\ logging.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ log\ \{sock\ message\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"\\\[\[clock\ format\ \[clock\ seconds\]\ -format\ %Y%m%d\\\ %H:%M:%S\]\\\]\ (\$sock)\ \$message\"\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ start\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Starts\ SSDP\ listening\ and\ announcement.\ This\ creates\ the\ socket\ and\ \n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ a\ fileevent\ for\ incoming\ message\ handling.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Parameters:\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ addresses:\ \ \ \ \ \ \ \ List\ of\ HTTP\ device\ addresses\ to\ advertise.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ port:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ HTTP\ port\ of\ device.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ path:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Path\ of\ the\ device\ description\ file.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ udn:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ UDN\ of\ the\ provided\ device.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ services:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ List\ of\ provided\ service\ types.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ start\ \{addresses\ port\ path\ udn\ services\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Remember\ parameters.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Addresses\ \$addresses\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Port\ \$port\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Path\ \$path\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Udn\ \$udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Services\ \$services\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Open\ SSDP\ socket.\ This\ will\ stay\ open\ until\ a\ call\ to\ stop.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Sock\ \[udp_open\ 1900\ reuse\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$Sock\ -translation\ crlf\ -buffering\ none\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$Sock\ -mcastadd\ 239.255.255.250\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fileevent\ \$Sock\ readable\ \[namespace\ code\ incoming\]\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Send\ announcement\ periodically.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ announce\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ stop\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Stops\ SSDP\ listening\ and\ announcement.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ stop\ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Services\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Cancel\ the\ announcement\ event.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ after\ cancel\ \[namespace\ code\ announce\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Send\ byebye\ messages.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ byebye\ upnp:rootdevice\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ byebye\ \{\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ serviceType\ \$Services\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ byebye\ \$serviceType\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ announce\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Send\ alive\ messages\ periodically.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ announce\ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Services\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Refresh\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Send\ alive\ messages.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ alive\ upnp:rootdevice\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ alive\ \{\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ serviceType\ \$Services\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ alive\ \$serviceType\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Reschedule\ event.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ after\ \[expr\ \{\$Refresh*1000\}\]\ \[namespace\ code\ announce\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ incoming\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Handle\ incoming\ HTTPU\ messages.\ Respond\ to\ discovery\ requests\ for\ one\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ of\ the\ provided\ services.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ incoming\ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Sock\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Services\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Read\ UDP\ datagram.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ message\ \[read\ \$Sock\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ peer\ \[fconfigure\ \$Sock\ -peer\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ log\ \$Sock\ \"SSDP\ message\ from\ \[join\ \$peer\ :\]\ <<ENDMARKER\\n\$message\\nENDMARKER\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Decode\ as\ HTTPU.\ Headers\ are\ converted\ to\ lower\ case.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ message\ \[split\ \$message\ \\n\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lassign\ \[lindex\ \$message\ 0\]\ method\ url\ version\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ headers\ \[list\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ line\ \[lreplace\ \$message\ 0\ 0\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$line\ eq\ \"\"\}\ break\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ regexp\ \{^(\[^:\]+):(.*)\$\}\ \$line\ all\ header\ value\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ headers\ \[string\ tolower\ \$header\]\ \[string\ trim\ \$value\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ switch\ -exact\ \$method\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ M-SEARCH\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ trim\ \[dict\ get\ \$headers\ man\]\ \\\"\]\ \ eq\ \"ssdp:discover\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Service\ discovery.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ serviceType\ \[dict\ get\ \$headers\ st\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ match\ uuid:*\ \$serviceType\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Samsung\ DLNA\ fix\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ serviceType\ urn:schemas-upnp-org:device:MediaServer:1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[lsearch\ \$Services\ \$serviceType\]\ >=\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ log\ \$Sock\ \"Scheduling\ response\ to\ \[join\ \$peer\ :\]\ for\ service\ \$serviceType\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Randomize\ response\ delay\ between\ 0\ and\ MX\ seconds.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[catch\ \{set\ mx\ \[dict\ get\ \$headers\ mx\]\}\]\}\ \{set\ mx\ 0\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ after\ \[expr\ \{int(rand()*1000*\$mx)\}\]\ \[namespace\ code\ \[list\ respond\ \$peer\ \$serviceType\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ respond\ -\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Respond\ to\ incoming\ discovery\ requests.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Parameters:\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ peer:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Request\ sender.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ serviceType:\ \ \ \ \ \ \ \ \ Service\ type\ from\ the\ discovery\ request.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ respond\ \{peer\ serviceType\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Sock\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Server\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Refresh\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Port\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Path\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Get\ device\ address\ to\ advertise.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ s\ \[socket\ -async\ \[lindex\ \$peer\ 0\]\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ address\ \[lindex\ \[fconfigure\ \$s\ -sockname\]\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ close\ \$s\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ log\ \$Sock\ \"Responding\ to\ \[join\ \$peer\ :\]\ for\ service\ \$serviceType\ on\ interface\ \$address\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$Sock\ -remote\ \$peer\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ -nonewline\ \$Sock\ \\\n\"HTTP/1.1\ 200\ OK\nCACHE-CONTROL:\ max-age=\$Refresh\nSERVER:\ \$Server\nEXT:\nLOCATION:\ http://\$address:\$Port\$Path\nST:\ \$serviceType\nUSN:\ \$\{Udn\}::\$serviceType\nContent-Length:\ 0\n\n\"\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ notify\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Send\ SSDP\ notification\ for\ a\ given\ service\ type.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Parameters:\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ nts:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Message\ type\ (e.g.\ ssdp:alive\ or\ ssdp:byebye)\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ serviceType:\ \ \ \ \ \ \ \ Service\ type.\ If\ empty,\ notifies\ device.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ notify\ \{nts\ serviceType\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Sock\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Refresh\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Addresses\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Port\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Path\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$serviceType\ eq\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Notify\ device.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ nt\ \$Udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ usn\ \$Udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Notify\ service.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ nt\ \$serviceType\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ usn\ \$\{Udn\}::\$serviceType\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Send\ over\ multicast\ channel.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$Sock\ -remote\ \{239.255.255.250\ 1900\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ address\ \$Addresses\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Advertise\ all\ device\ addresses.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ -nonewline\ \$Sock\ \\\n\"NOTIFY\ *\ HTTP/1.1\nHOST:\ 239.255.255.250:1900\nCACHE-CONTROL:\ max-age=\$Refresh\nLOCATION:\ http://\$address:\$Port\$Path\nNTS:\ \$nts\nNT:\ \$nt\nUSN:\ \$usn\n\n\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\ Shortcuts\ for\ common\ message\ types.\n\ \ \ \ \ \ \ \ proc\ alive\ \ \{serviceType\}\ \{notify\ ssdp:alive\ \ \$serviceType\}\n\ \ \ \ \ \ \ \ proc\ byebye\ \{serviceType\}\ \{notify\ ssdp:byebye\ \$serviceType\}\n\}\n\n======\n\nExample:\n\n======\npackage\ require\ uuid\nset\ udn\ \"uuid:\[::uuid::uuid\ generate\]\"\nset\ addresses\ \[list\ 192.168.0.1\]\nset\ port\ 12345\nset\ path\ /description.xml\nset\ services\ \{\n\ \ \ \ \ \ \ \ urn:schemas-upnp-org:device:MediaServer:1\n\ \ \ \ \ \ \ \ urn:schemas-upnp-org:service:ContentDirectory:1\n\ \ \ \ \ \ \ \ urn:schemas-upnp-org:service:ConnectionManager:1\n\}\n\nssdp::start\ \$addresses\ \$port\ \$path\ \$udn\ \$services\n======\n\nThis\ advertises\ services\ for\ a\ typical\ UPnP\ media\ server,\ using\ description\ file\ `http://192.168.0.1:12345/description.xml`.\ You'll\ also\ need\ a\ HTTP\ server\ somewhere\ to\ serve\ this\ file,\ especially\ the\ description\ file\ given\ by\ the\ SSDP\ LOCATION\ header\ (here\ `http://192.168.0.1:12345/description.xml`\ but\ you\ can\ use\ anything\ as\ long\ as\ it\ follows\ the\ UPnP\ standard).\ For\ my\ project\ I\ use\ a\ mini\ HTTP\ server\ adapted\ from\ \[Embedded\ TCL\ Web\ Server\],\ but\ any\ server\ software\ will\ do\ the\ job\ (\[TclHttpd\],\ \[Apache\],\ http://en.wikipedia.org/wiki/Lighttpd%|%lighttpd%|%,\ whatever),\ so\ if\ you\ have\ your\ own\ HTTP\ server\ already\ up\ &\ running\ somewhere,\ just\ use\ its\ address\ here.\n\n======\n\[EF\]\ Thanks\ for\ publishing\ this,\ this\ can\ be\ a\ fantastic\ start...\n<<categories>>\ Networking regexp2} CALL {my render SSDP http://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol%|%From\ Wikipedia%|%:\n\n''The\ Simple\ Service\ Discovery\ Protocol\ (SSDP)\ is\ a\ network\ protocol\ based\ on\ the\ Internet\ Protocol\ Suite\ for\ advertisement\ and\ discovery\ of\ network\ services\ and\ presence\ information.\ It\ accomplishes\ this\ without\ assistance\ of\ server-based\ configuration\ mechanisms,\ such\ as\ the\ Dynamic\ Host\ Configuration\ Protocol\ (DHCP)\ or\ the\ Domain\ Name\ System\ (DNS),\ and\ without\ special\ static\ configuration\ of\ a\ network\ host.\ SSDP\ is\ the\ basis\ of\ the\ discovery\ protocol\ of\ Universal\ Plug\ and\ Play\ and\ is\ intended\ for\ use\ in\ residential\ or\ small\ office\ environments.\ It\ was\ formally\ described\ in\ an\ IETF\ Internet\ draft\ by\ Microsoft\ and\ Hewlett-Packard\ in\ 1999.\ Although\ the\ IETF\ proposal\ has\ since\ expired,\ SSDP\ was\ incorporated\ into\ the\ UPnP\ protocol\ stack,\ and\ a\ description\ of\ the\ final\ implementation\ is\ included\ in\ UPnP\ standards\ documents.''\n\n----\n\n\[FB\]\ Here\ is\ a\ small\ SSDP\ package\ that\ I\ wrote\ for\ a\ UPnP\ media\ server\ of\ mine\ (\"Mediatheque\",\ just\ change\ the\ `ssdp::Server`\ variable\ to\ whatever\ you\ choose).\ \nThe\ code\ is\ quite\ simple:\ it\ creates\ a\ UDP\ multicast\ socket\ on\ the\ well\ known\ SSDP\ address\ and\ port\ 239.255.255.250:1900,\ posts\ periodic\ alive\ messages\ and\ listens\ to\ incoming\ discovery\ requests\ on\ its\ advertised\ services:\n\n======\n#\n#\ ssdp.tcl\ --\n#\n#\ \ \ \ \ \ \ \ SSDP\ handling.\ Note\ that\ only\ features\ needed\ by\ this\ application\ are\ \n#\ \ \ \ \ \ \ \ supported,\ this\ is\ not\ a\ generic\ SSDP\ package\ although\ it\ can\ serve\ as\n#\ \ \ \ \ \ \ \ a\ basis\ for\ implementing\ one.\n#\n#\ \ \ \ \ \ \ \ SSDP\ uses\ HTTPU\ messages\ on\ the\ multicast\ UDP\ address\ 239.255.255.250:1900\n#\ \ \ \ \ \ \ \ UPNP\ uses\ SSDP\ for\ service\ announcement\ and\ discovery.\n#\n#\ \ \ \ \ \ \ \ This\ package\ uses\ a\ single\ UDP\ socket\ provided\ by\ the\ Tcl\ udp\ extension.\ \n#\ \ \ \ \ \ \ \ Minimal\ version\ is\ 1.0.9\ for\ address\ reuse\ support\ (SO_REUSEADDR)\ because\n#\ \ \ \ \ \ \ \ several\ applications\ (clients\ or\ servers)\ may\ open\ this\ address\ on\ the\ same\ \n#\ \ \ \ \ \ \ \ machine.\n#\n#\ \ \ \ \ \ \ \ TODO:\ at\ present\ the\ udp\ package\ doesn't\ support\ binding\ to\ specific\ \n#\ \ \ \ \ \ \ \ interfaces,\ so\ we\ have\ to\ specify\ the\ advertised\ device\ addresses\ manually.\n#\n\npackage\ require\ udp\ 1.0.9\n\nnamespace\ eval\ ssdp\ \{\n\ \ \ \ variable\ Server\ \"Mediatheque\"\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\ Refresh\ interval.\n\ \ \ \ \ \ \ \ variable\ Refresh\ 1800\n\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ log\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Simple\ logging.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ log\ \{sock\ message\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \"\\\[\[clock\ format\ \[clock\ seconds\]\ -format\ %Y%m%d\\\ %H:%M:%S\]\\\]\ (\$sock)\ \$message\"\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ start\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Starts\ SSDP\ listening\ and\ announcement.\ This\ creates\ the\ socket\ and\ \n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ a\ fileevent\ for\ incoming\ message\ handling.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Parameters:\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ addresses:\ \ \ \ \ \ \ \ List\ of\ HTTP\ device\ addresses\ to\ advertise.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ port:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ HTTP\ port\ of\ device.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ path:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Path\ of\ the\ device\ description\ file.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ udn:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ UDN\ of\ the\ provided\ device.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ services:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ List\ of\ provided\ service\ types.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ start\ \{addresses\ port\ path\ udn\ services\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Remember\ parameters.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Addresses\ \$addresses\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Port\ \$port\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Path\ \$path\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Udn\ \$udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Services\ \$services\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Open\ SSDP\ socket.\ This\ will\ stay\ open\ until\ a\ call\ to\ stop.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Sock\ \[udp_open\ 1900\ reuse\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$Sock\ -translation\ crlf\ -buffering\ none\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$Sock\ -mcastadd\ 239.255.255.250\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fileevent\ \$Sock\ readable\ \[namespace\ code\ incoming\]\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Send\ announcement\ periodically.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ announce\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ stop\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Stops\ SSDP\ listening\ and\ announcement.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ stop\ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Services\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Cancel\ the\ announcement\ event.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ after\ cancel\ \[namespace\ code\ announce\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Send\ byebye\ messages.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ byebye\ upnp:rootdevice\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ byebye\ \{\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ serviceType\ \$Services\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ byebye\ \$serviceType\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ announce\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Send\ alive\ messages\ periodically.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ announce\ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Services\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Refresh\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Send\ alive\ messages.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ alive\ upnp:rootdevice\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ alive\ \{\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ serviceType\ \$Services\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ alive\ \$serviceType\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Reschedule\ event.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ after\ \[expr\ \{\$Refresh*1000\}\]\ \[namespace\ code\ announce\]\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ incoming\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Handle\ incoming\ HTTPU\ messages.\ Respond\ to\ discovery\ requests\ for\ one\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ of\ the\ provided\ services.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ incoming\ \{\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Sock\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Services\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Read\ UDP\ datagram.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ message\ \[read\ \$Sock\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ peer\ \[fconfigure\ \$Sock\ -peer\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ log\ \$Sock\ \"SSDP\ message\ from\ \[join\ \$peer\ :\]\ <<ENDMARKER\\n\$message\\nENDMARKER\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Decode\ as\ HTTPU.\ Headers\ are\ converted\ to\ lower\ case.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ message\ \[split\ \$message\ \\n\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lassign\ \[lindex\ \$message\ 0\]\ method\ url\ version\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ headers\ \[list\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ line\ \[lreplace\ \$message\ 0\ 0\]\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$line\ eq\ \"\"\}\ break\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ regexp\ \{^(\[^:\]+):(.*)\$\}\ \$line\ all\ header\ value\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ lappend\ headers\ \[string\ tolower\ \$header\]\ \[string\ trim\ \$value\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ switch\ -exact\ \$method\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ M-SEARCH\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ trim\ \[dict\ get\ \$headers\ man\]\ \\\"\]\ \ eq\ \"ssdp:discover\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Service\ discovery.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ serviceType\ \[dict\ get\ \$headers\ st\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ match\ uuid:*\ \$serviceType\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Samsung\ DLNA\ fix\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ serviceType\ urn:schemas-upnp-org:device:MediaServer:1\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[lsearch\ \$Services\ \$serviceType\]\ >=\ 0\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ log\ \$Sock\ \"Scheduling\ response\ to\ \[join\ \$peer\ :\]\ for\ service\ \$serviceType\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Randomize\ response\ delay\ between\ 0\ and\ MX\ seconds.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[catch\ \{set\ mx\ \[dict\ get\ \$headers\ mx\]\}\]\}\ \{set\ mx\ 0\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ after\ \[expr\ \{int(rand()*1000*\$mx)\}\]\ \[namespace\ code\ \[list\ respond\ \$peer\ \$serviceType\]\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ respond\ -\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Respond\ to\ incoming\ discovery\ requests.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Parameters:\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ peer:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Request\ sender.\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ serviceType:\ \ \ \ \ \ \ \ \ Service\ type\ from\ the\ discovery\ request.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ respond\ \{peer\ serviceType\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Sock\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Server\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Refresh\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Port\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Path\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Get\ device\ address\ to\ advertise.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ s\ \[socket\ -async\ \[lindex\ \$peer\ 0\]\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ address\ \[lindex\ \[fconfigure\ \$s\ -sockname\]\ 0\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ close\ \$s\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ log\ \$Sock\ \"Responding\ to\ \[join\ \$peer\ :\]\ for\ service\ \$serviceType\ on\ interface\ \$address\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$Sock\ -remote\ \$peer\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ -nonewline\ \$Sock\ \\\n\"HTTP/1.1\ 200\ OK\nCACHE-CONTROL:\ max-age=\$Refresh\nSERVER:\ \$Server\nEXT:\nLOCATION:\ http://\$address:\$Port\$Path\nST:\ \$serviceType\nUSN:\ \$\{Udn\}::\$serviceType\nContent-Length:\ 0\n\n\"\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ notify\ --\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Send\ SSDP\ notification\ for\ a\ given\ service\ type.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ Parameters:\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ nts:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Message\ type\ (e.g.\ ssdp:alive\ or\ ssdp:byebye)\n\ \ \ \ \ \ \ \ #\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\ serviceType:\ \ \ \ \ \ \ \ Service\ type.\ If\ empty,\ notifies\ device.\n\ \ \ \ \ \ \ \ #\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ proc\ notify\ \{nts\ serviceType\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Sock\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Refresh\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Addresses\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Port\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Path\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ variable\ Udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$serviceType\ eq\ \"\"\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Notify\ device.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ nt\ \$Udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ usn\ \$Udn\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Notify\ service.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ nt\ \$serviceType\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ usn\ \$\{Udn\}::\$serviceType\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Send\ over\ multicast\ channel.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$Sock\ -remote\ \{239.255.255.250\ 1900\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ foreach\ address\ \$Addresses\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ Advertise\ all\ device\ addresses.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ -nonewline\ \$Sock\ \\\n\"NOTIFY\ *\ HTTP/1.1\nHOST:\ 239.255.255.250:1900\nCACHE-CONTROL:\ max-age=\$Refresh\nLOCATION:\ http://\$address:\$Port\$Path\nNTS:\ \$nts\nNT:\ \$nt\nUSN:\ \$usn\n\n\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \ #\ Shortcuts\ for\ common\ message\ types.\n\ \ \ \ \ \ \ \ proc\ alive\ \ \{serviceType\}\ \{notify\ ssdp:alive\ \ \$serviceType\}\n\ \ \ \ \ \ \ \ proc\ byebye\ \{serviceType\}\ \{notify\ ssdp:byebye\ \$serviceType\}\n\}\n\n======\n\nExample:\n\n======\npackage\ require\ uuid\nset\ udn\ \"uuid:\[::uuid::uuid\ generate\]\"\nset\ addresses\ \[list\ 192.168.0.1\]\nset\ port\ 12345\nset\ path\ /description.xml\nset\ services\ \{\n\ \ \ \ \ \ \ \ urn:schemas-upnp-org:device:MediaServer:1\n\ \ \ \ \ \ \ \ urn:schemas-upnp-org:service:ContentDirectory:1\n\ \ \ \ \ \ \ \ urn:schemas-upnp-org:service:ConnectionManager:1\n\}\n\nssdp::start\ \$addresses\ \$port\ \$path\ \$udn\ \$services\n======\n\nThis\ advertises\ services\ for\ a\ typical\ UPnP\ media\ server,\ using\ description\ file\ `http://192.168.0.1:12345/description.xml`.\ You'll\ also\ need\ a\ HTTP\ server\ somewhere\ to\ serve\ this\ file,\ especially\ the\ description\ file\ given\ by\ the\ SSDP\ LOCATION\ header\ (here\ `http://192.168.0.1:12345/description.xml`\ but\ you\ can\ use\ anything\ as\ long\ as\ it\ follows\ the\ UPnP\ standard).\ For\ my\ project\ I\ use\ a\ mini\ HTTP\ server\ adapted\ from\ \[Embedded\ TCL\ Web\ Server\],\ but\ any\ server\ software\ will\ do\ the\ job\ (\[TclHttpd\],\ \[Apache\],\ http://en.wikipedia.org/wiki/Lighttpd%|%lighttpd%|%,\ whatever),\ so\ if\ you\ have\ your\ own\ HTTP\ server\ already\ up\ &\ running\ somewhere,\ just\ use\ its\ address\ here.\n\n======\n\[EF\]\ Thanks\ for\ publishing\ this,\ this\ can\ be\ a\ fantastic\ start...\n<<categories>>\ Networking} CALL {my revision SSDP} CALL {::oo::Obj807113 process revision/SSDP} CALL {::oo::Obj807111 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4