falk0069 / hue-upnp

Philips Hue UPNP and HTTP emulator (works with the Android Hue app and Logitech Harmony Home Remotes)
30 stars 10 forks source link

Ability to specify interface to send uPnP commands on #9

Open ggiesen opened 8 years ago

ggiesen commented 8 years ago

I'm running hue-upnp on my Raspberry Pi running Raspbian. My Pi sits on two different networks courtesy of VLAN trunking. Unfortunately, this causes hue-upnp to send out uPnP packets out the wrong interface.

I worked around this manually by creating a static route for the uPnP broadcast IP (239.255.255.250) to point to the correct interface, but it would be useful to be able to specify in the configuration file the interface to send broadcasts out.

falk0069 commented 8 years ago

Doesn't setting the 'IP' config value do this for you? I thought the program used that value to bind to the correct interface. I'll have to look closer to what the program does if that is not the case -Andy On Jan 4, 2016 2:41 AM, "ggiesen" notifications@github.com wrote:

I'm running hue-upnp on my Raspberry Pi running Raspbian My Pi sits on two different networks courtesy of VLAN trunking Unfortunately, this causes hue-upnp to send out uPnP packets out the wrong interface

I worked around this manually by creating a static route for the uPnP broadcast IP (239255255250) to point to the correct interface, but it would be useful to be able to specify in the configuration file the interface to send broadcasts out

— Reply to this email directly or view it on GitHub https://github.com/falk0069/hue-upnp/issues/9.

ggiesen commented 8 years ago

Doesn't seem to.

falk0069 commented 8 years ago

I see that the bind only happens on the listening/server portion. I'm not sure how to bind on outbound calls. Maybe the bind call will work. It looks like if you set the 'port' parameter to 0, the 'OS default behavior' will be used. I'll have to do more research and experimenting. If you want you could try the bind call now and see if it works for you. I think the line would be

sock.bind((IP, 0))

Around line 151 in the code:

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
#Add this line:
sock.bind((IP, 0))
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20)
falk0069 commented 8 years ago

That seems to do the trick for me. I was able to force which interface the broadcasts use. With the latest code merge the added line was this:

sock.bind((CONFIG.standard['IP'],0))

Grab the latest code and see if it works for you.

falk0069 commented 8 years ago

ggiesen- You mentioned in the other issue that initial indications look like it's not working. Are you still having the issue? I was able to validate that with tcptrace that it is going out the correct interface. However, I got to thinking, why do you care about the periodic broadcasts? I think what you should care more about are the UDP responses. I looked at the code again and saw that the Responder class was binding the the OS default (around line 166). I just committed the code update so it also binds to the specified interface, so you might want to grab it and see if it makes a difference for you.

falk0069 commented 8 years ago

Ggiesen- I had to back out that last change. Binding to a specific port prevented any responses from working. I need to experiment more to see if there is a way to bind the udp responses.

falk0069 commented 8 years ago

ok...I think I found a solution. I created a brand new separate socket bound to the right interface that will do all the udp responses. I hope this does the trick for you.