For my SonosController I need to do subscriptions to UPNP events (https://en.wikipedia.org/wiki/Universal ... tification). I tried LOTS of things for a day or two and actually got quite far in the end. One piece is still missing, though.
This is what currently is working:
- Setting up a server that is listening to incoming requests
- Calling the host's endpoint to subscribe to to its events
- Receiving a first query from the host
Now, according to the docs about on how to do such a subscription, the listening server has to confirm the first incoming request with a "200 OK".
Now, how do I do this, sending a "200 OK"?
Here's the script containing the mentioned bits of code. If you have a Sonos speaker, change the IPs accordingly and it should run:
Code: Select all
@REQUIRE "hurl", {Link = True}
@APPTITLE "UPNP-Subscription-Test"
Function p_Subscribe()
Local serverId = CreateServer(Nil)
Local ip$ = "192.168.1.122" ; TODO: get IP dynamically, GetLocalInterfaces()
Local port$ = GetLocalPort(serverId, #NETWORKSERVER)
DebugPrint(ip$ .. ":" .. port$)
Local host$ = "192.168.1.241:1400" ; IP of a Sonos speaker
Local easy = hurl.Easy()
easy:setopt_customrequest("SUBSCRIBE /MediaRenderer/AVTransport/Event HTTP/1.1") ; this took me hours to figure out :-)
easy:setopt_httpheader({
"TIMEOUT: Second-600",
"CALLBACK: <http://" .. ip$ .. ":" .. port$ .. ">",
"NT: upnp:event",
"Host: " .. host$
});
easy:setopt_url("http://".. host$)
easy:setopt_writefunction(p_WriteFunction)
easy:perform()
EndFunction
Function p_WriteFunction(data)
DebugPrint("p_WriteFunction", data)
DebugPrint(data)
EndFunction
Function p_OnConnect(data)
DebugPrint("p_OnConnect")
p_PrintTable(data)
EndFunction
Function p_OnReceiveData(data)
DebugPrint("p_OnReceiveData")
p_PrintTable(data)
EndFunction
Function p_PrintTable(table)
For k, v In Pairs(table)
If GetType(v) = #TABLE
DebugPrint(k, ":")
p_PrintTable(v)
Else
DebugPrint(k, ":", v)
EndIf
Next
DebugPrint("-----------------------------------------")
EndFunction
InstallEventHandler({
OnConnect = p_OnConnect,
OnReceiveData = p_OnReceiveData
})
p_Subscribe()
Repeat
WaitEvent
Forever
Code: Select all
192.168.1.122:55429
p_OnConnect
action : OnConnect
clientid : UserData: 00000000032562F0
timestamp : 1.3396244049072
serverid : UserData: 00000000032569F0
-----------------------------------------
p_OnReceiveData
id : UserData: 00000000032562F0
timestamp : 1.3416767120361
action : OnReceiveData
-----------------------------------------
Cheers,
Michael