Comments (26)
Finally have some time to look at this.
from huenim.
@enthus1ast mac is back. Going to give this a go.
from huenim.
Assumption is I have some problems in the use of the nim apis. If it helps I can post some C code that does the same thing.
from huenim.
Yeah, please post the C code and also the output that this code gives.
from huenim.
Will dig up the code and post that output.
from huenim.
I have a bad example I put together in C here:
https://pastebin.com/CvmqvV2j
The bad example doesn't use the query to do a sendto first before listening for a response. I noticed that regardless of my query, I will get a response from my network which I can easily filter out the key tell-tale signs this is a Hue Hub.
Here are some responses from this code below. The giveaway that this is a HUE hub is the presence of a LOCATION value that ends with discovery.xml, for example:
LOCATION: http://10.0.0.222:80/description.xml
One of the approaches people take to find their hub(s) is to enumerate all ip addresses in the range of the local network, and try to hit port 80/description.xml. However that's sort of a waste. If the UPnP approach works, it should yield a narrow set of devices that will respond, and from those you filter based on the LOCATION. It's ugly either way, but the multicast approach should be more efficient.
Opening datagram socket....OK.
Setting SO_REUSEADDR...OK.
Binding datagram socket...OK.
Adding multicast group...OK.
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://10.0.0.222:80/description.xml
SERVER: FreeRTOS/7.4.2 UPnP/1.0 IpBridge/1.16.0
NTS: ssdp:alive
hue-bridgeid: 001788FFFE1A73B5
NT: upnp:rootdevice
USN: uuid:2f402f80-da50-11e1-9b23-0017881a73b5::upnp:rootdevice
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://10.0.0.222:80/description.xml
SERVER: FreeRTOS/7.4.2 UPnP/1.0 IpBridge/1.16.0
NTS: ssdp:alive
hue-bridgeid: 001788FFFE1A73B5
NT: upnp:rootdevice
USN: uuid:2f402f80-da50-11e1-9b23-0017881a73b5::upnp:rootdevice
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://10.0.0.222:80/description.xml
SERVER: FreeRTOS/7.4.2 UPnP/1.0 IpBridge/1.16.0
NTS: ssdp:alive
hue-bridgeid: 001788FFFE1A73B5
NT: uuid:2f402f80-da50-11e1-9b23-0017881a73b5
USN: uuid:2f402f80-da50-11e1-9b23-0017881a73b5
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://10.0.0.222:80/description.xml
SERVER: FreeRTOS/7.4.2 UPnP/1.0 IpBridge/1.16.0
NTS: ssdp:alive
hue-bridgeid: 001788FFFE1A73B5
NT: uuid:2f402f80-da50-11e1-9b23-0017881a73b5
USN: uuid:2f402f80-da50-11e1-9b23-0017881a73b5
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://10.0.0.222:80/description.xml
SERVER: FreeRTOS/7.4.2 UPnP/1.0 IpBridge/1.16.0
NTS: ssdp:alive
hue-bridgeid: 001788FFFE1A73B5
NT: urn:schemas-upnp-org:device:basic:1
USN: uuid:2f402f80-da50-11e1-9b23-0017881a73b5
b5
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=100
LOCATION: http://10.0.0.222:80/description.xml
SERVER: FreeRTOS/7.4.2 UPnP/1.0 IpBridge/1.16.0
NTS: ssdp:alive
hue-bridgeid: 001788FFFE1A73B5
NT: urn:schemas-upnp-org:device:basic:1
USN: uuid:2f402f80-da50-11e1-9b23-0017881a73b5
b5
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=120
LOCATION: http://10.0.0.1:47509/rootDesc.xml
SERVER: AsusWRT/380.66 UPnP/1.1 MiniUPnPd/2.0
NT: upnp:rootdevice
USN: uuid:c88b4917-3f2e-4982-93cb-8ae49467d857::upnp:rootdevice
NTS: ssdp:alive
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: 1505133119
BOOTID.UPNP.ORG: 1505133119
CONFIGID.UPNP.ORG: 1337
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=120
LOCATION: http://10.0.0.1:47509/rootDesc.xml
SERVER: AsusWRT/380.66 UPnP/1.1 MiniUPnPd/2.0
NT: urn:schemas-upnp-org:device:InternetGatewayDevice:1
USN: uuid:c88b4917-3f2e-4982-93cb-8ae49467d857::urn:schemas-upnp-org:device:InternetGatewayDevice:1
NTS: ssdp:alive
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: 1505133119
BOOTID.UPNP.ORG: 1505133119
CONFIGID.UPNP.ORG: 1337
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=120
LOCATION: http://10.0.0.1:47509/rootDesc.xml
SERVER: AsusWRT/380.66 UPnP/1.1 MiniUPnPd/2.0
NT: uuid:c88b4917-3f2e-4982-93cb-8ae49467d857
USN: uuid:c88b4917-3f2e-4982-93cb-8ae49467d857
NTS: ssdp:alive
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: 1505133119
BOOTID.UPNP.ORG: 1505133119
CONFIGID.UPNP.ORG: 1337
33119
BOOTID.UPNP.ORG: 1505133119
CONFIGID.UPNP.ORG: 1337
"
Reading datagram message...OK.
The message from multicast server is: "NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=120
LOCATION: http://10.0.0.1:47509/rootDesc.xml
SERVER: AsusWRT/380.66 UPnP/1.1 MiniUPnPd/2.0
NT: urn:schemas-upnp-org:device:WANConnectionDevice:1
USN: uuid:c88b4917-3f2e-4982-93cb-8ae49467d859::urn:schemas-upnp-org:device:WANConnectionDevice:1
NTS: ssdp:alive
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: 1505133119
BOOTID.UPNP.ORG: 1505133119
CONFIGID.UPNP.ORG: 1337
"
from huenim.
In the Java version of this, it worked like a charm. The nim version I would never get a response.
from huenim.
Hrm, all I can is guess, but this part is missing from your Nim code (isn't it?):
if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)
from huenim.
Thanks. I'll revisit this and try that, spent some time on different variations of the discover initially, and eventually switched to the nupnp implementation. UPnP has a bad rap because of security concerns, but this is still useful for a number of IoT type devices that are out there.
from huenim.
@truedat101 if this is still relevant you could have a look at https://github.com/enthus1ast/nimMulticast
from huenim.
@enthus1ast actually yeah, awesome. I spent a fair amount of time chasing down what I was doing wrong , so will have a look at your lib.
from huenim.
Will have a look at this module nimMulticast.
from huenim.
just skimmed through your code:
bindAddr(socket, Port(1900), "239.255.255.250")
afaik for multicast there is no need to bind to the multicast address.
The multicast enabled socket will receive every datagram send to the multicast group.
from huenim.
Good point. Need to get back into this.
from huenim.
Hmm, tried socket.bindAddr(Port(1900)) , but still just get back empty response. I have to remember how I was snooping the network for UPnP discovery. I've been through the code several times and didn't find a solution.
Need to try the suggestion #3 (comment) from Dominik.
from huenim.
this principally is what multicast joinGroup does.
So to receive multicast datagrams you have to:
- create a socket
- bindAddr (bind to your interface address not the multicast group!)
- socket.joinGroup("239.255.255.250")
when joinGroup returns true, the socket should be able to receive multicast.
you can test this by sending to the multicast group (the sender socket does not need to be in the multicast group) so sending a datagram with ncat should be enough:
[david@eb ~]$ ncat -4 --udp 239.255.255.250 1900
this should be visible in your testprogram
from huenim.
Something like this should work:
bindAddr(socket, Port(1900))
let group = "239.255.255.250"
assert true == socket.joinGroup(group)
let res = socket.sendTo(group, Port(1900),cstring(upnpquery),upnpquery.len.cint)
# [...]
let bytesReceived = recvFrom(socket, data, recvlen, recvaddr, recvport)
from huenim.
Great, thank you for the tips. I'll jump onto this tonight. As mentioned, I have this all working reliably in my java code and also C code version, but really wanted to make this a no-brainer thing to work with UPnP w/ NIM, and eliminate the need to do discovery using the Hue's funky nupnp solution that requires a proper internet connection.
from huenim.
So I've added 0.1.2 version of multicast to the project. Strange error when I compile.
multicast-0.1.2/multicast.nim(54, 6) Error: undeclared identifier: 'IPv4'
This should be present in IPAddressFamily. Anyway, is this something obvious I've missed, or should I file a ticket on multicast.
from huenim.
@truedat101 strange that this works for me, since this is a pure enum mhh.
Nonetheless i pushed a new version, please try if it now compiles for you.
from huenim.
@enthus1ast Thanks I'll give this a look. I guess the only thing I can think of that might be different is I'm on Mac OS X for this particular project and using num 0.17.0.
from huenim.
i bet this issue is because of 0.17 but i see another issue comeing: it might be that IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP int values differs from posix (they differ from old windows to new windows and linux.
I might have to add these values for mac. Unfortunately i have no access to a mac. So please report if its working :)
from huenim.
Ahh,ok, that does make sense. I can continue testing on the mac. At least that can get resolved through testing. I can move to a later release as well.
from huenim.
Great upgraded to multicast module 0.1.3. Build is fine.
On the run, I get:
Traceback (most recent call last)
runTests.nim(12) runTests
huenim.nim(155) findHueHubsViaUPnP
system.nim(3613) failedAssertImpl
system.nim(3605) raiseAssert
system.nim(2724) sysFatal
Unhandled exception: true == joinGroup(socket, group, 255)
assert true == socket.joinGroup(group)
from huenim.
@truedat101 i've pushed a new branch of multicast: https://github.com/enthus1ast/nimMulticast/tree/freebsdAndMacos
i still have no access to macos but i've installed a freebsd and tested the branch on it.
I've also fixed the example (edit: i know the example was working with an older nim version, so it might be, if you still use 0.17 that i've just broke the example for you) so to test if multicast works on macos you could just run the tests/example.nim
on two different machines.
Please report if macos works now, then i'll merge it into master :)
from huenim.
Apologies for the delay. I am sad to report my mac died. Awaiting its return from the shop and then I'll jump back onto testing that.
from huenim.
Related Issues (4)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from huenim.