Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
squirreltown
Roku Guru

Re: FInd box on LAN

"belltown" wrote:
Here's a little Python 3 program that you can run on your Pi to respond to M-SEARCH requests from a Roku. As it's written right now, it impersonates a Roku device, but you can change the "ST" field to something else, and make sure the Roku code searches for the same value.

Thank you! I added a print to see what was happening and then added a function to insert the local ip address into the MSEARCH response and am now getting this Pi to show up in the ECPaddr list in your roku code. I'm pretty sure that's it - I can fill in all the rest. There are a bunch of python examples like this, but they are all written slightly differently - yours wins.

EnTerr - Here I am trying to be less ignorant and you're complaining. 🙂
Kinetics Screensavers
0 Kudos
belltown
Roku Guru

Re: FInd box on LAN

"squirreltown" wrote:
I ... added a function to insert the local ip address into the MSEARCH response

The code I posted already does that. Unless you mean you re-wrote that part as a function to make it clearer, which is always a good idea.
0 Kudos
squirreltown
Roku Guru

Re: FInd box on LAN

"belltown" wrote:
"squirreltown" wrote:
I ... added a function to insert the local ip address into the MSEARCH response

The code I posted already does that. Unless you mean you re-wrote that part as a function to make it clearer, which is always a good idea.

Hey, i'm totally not knowing this python thing, i guess {ipAddr} is supposed to grab it? I did this. Thanks again, I'll make the xml file and finish this mañana.           

import socket
import struct


sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 1900))
addMembershipData = struct.pack('4sl', socket.inet_aton('239.255.255.250'), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, addMembershipData)

def get_ip_address():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(('8.8.8.8', 80))
    return s.getsockname()[0]

MSEARCH_RESPONSE = ('HTTP/1.1 200 OK\r\n'
                    'Cache-Control: max-age=3600\r\n'
                    'ST: raspberr\r\r\n'
                    'Location: http://'+get_ip_address()+':8060/\r\n'
                    '\r\n')
while True:
    data, addr = sock.recvfrom(4096)
    if data.startswith(b'M-SEARCH'):
        print data
        response = str.encode(MSEARCH_RESPONSE.format(ipAddr=addr[0]))
        sock.sendto(response, addr)
Kinetics Screensavers
0 Kudos
belltown
Roku Guru

Re: FInd box on LAN

You're right, you do need to get your local address and pass that into the M-SEARCH string. In my example, I was passing in the address obtained from recvfrom(), which only works if the client and server are running on the same machine, as they were when I "tested" it.

What I would do though is leave the M-SEARCH statement as I originally had it, but change:
response = str.encode(MSEARCH_RESPONSE.format(ipAddr=addr[0]))

to:

response = str.encode(MSEARCH_RESPONSE.format(ipAddr=get_ip_address())

or, use your version of the MSEARCH_RESPONSE statement, and change the above line to:

response = str.encode(MSEARCH_RESPONSE)
0 Kudos
EnTerr
Roku Guru

Re: FInd box on LAN

"belltown" wrote:
You're right, you do need to get your local address and pass that into the M-SEARCH string. In my example, I was passing in the address obtained from recvfrom(), which only works if the client and server are running on the same machine, as they were when I "tested" it.

Should just do `sock.getsockname()` on the socket at hand instead of the contraption to connect google DNS. Not only faster/simpler but also more "righteous" - imagine a multihomed (>1 IP) host, where Roku is on a different interface than the internet.
0 Kudos
EnTerr
Roku Guru

Re: FInd box on LAN

"squirreltown" wrote:
EnTerr - Here I am trying to be less ignorant and you're complaining. 🙂

it pains me to see a sledgehammer used to crack nuts  😎
also i am firm believer that the more complicated (more elements, more interactions, more points of failure) a system is, the more fragile it is.
0 Kudos
belltown
Roku Guru

Re: FInd box on LAN

"EnTerr" wrote:
"belltown" wrote:
You're right, you do need to get your local address and pass that into the M-SEARCH string. In my example, I was passing in the address obtained from recvfrom(), which only works if the client and server are running on the same machine, as they were when I "tested" it.

Should just do `sock.getsockname()` on the socket at hand instead of the contraption to connect google DNS. Not only faster/simpler but also more "righteous" - imagine a multihomed (>1 IP) host, where Roku is on a different interface than the internet.

In Python, getsockname() is a socket function exported by the socket module, not a socket method, so you wouldn't call it on the socket object; i.e. you'd call socket.getsockname(), not sock.getsockname(). Also, it would return '0.0.0.0' if sock.bind(('', 1900)) was used -- at least it does on my system. Sometimes socket.gethostbyname(socket.gethostname()) works; however, depending on which OS you use, and how your hosts file is set up, you may get back a localhost address (127.0.1.1 in my case). I think squirreltown's method has a better chance of determining the local ip address, providing you can connect to Google DNS. If you can't then you probably have other problems to worry about.
0 Kudos
belltown
Roku Guru

Re: FInd box on LAN

"EnTerr" wrote:
the more complicated (more elements, more interactions, more points of failure) a system is, the more fragile it is.

That's a true statement for sure.
0 Kudos