4
votes

I'm a total beginner to HTTP requests, but I'd like to write a Python app that uses Sony's API for controlling its Wi-Fi cameras. For now, I'm just trying to talk to the camera at all, but my get request keeps failing. I have all the docs (the UPnP documentation, SSDP doc, user's manual, etc.) but I think I'm missing something really fundamental. According to Sony's doc, I need to:

  1. Connect to the camera as an access point (i.e., log in like any other Wi-Fi router)
  2. Send a request to a certain URL and port

Does anyone have any idea what might be going wrong here? Any good resources on getting started with UPnP / SSDP? I got the formatting for the DISCOVERY_MSG string from here.

#!/usr/bin/python

def main():
    import requests

    DISCOVERY_MSG = ('M-SEARCH * HTTP/1.1\r\n' +
                 'HOST: 239.255.255.250:1900\r\n' +
                 'MAN: "ssdp:discover"\r\n' +
                 'MX: 3\r\n' +
                 'ST: urn:schemas-sony-com:service:ScalarWebAPI:1\r\n' +
                 'USER-AGENT: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1\r\n\r\n')

    try:
        r = requests.get(DISCOVERY_MSG)
    except:
        print('Didn\'t work')


if __name__ == '__main__':
  main()
2

2 Answers

14
votes
import sys
import socket

SSDP_ADDR = "239.255.255.250";
SSDP_PORT = 1900;
SSDP_MX = 1;
SSDP_ST = "urn:schemas-sony-com:service:ScalarWebAPI:1";

ssdpRequest = "M-SEARCH * HTTP/1.1\r\n" + \
                "HOST: %s:%d\r\n" % (SSDP_ADDR, SSDP_PORT) + \
                "MAN: \"ssdp:discover\"\r\n" + \
                "MX: %d\r\n" % (SSDP_MX, ) + \
                "ST: %s\r\n" % (SSDP_ST, ) + "\r\n";

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(ssdpRequest, (SSDP_ADDR, SSDP_PORT))
print sock.recv(1000)

https://github.com/crquan/work-on-sony-apis/blob/master/search-nex.py

3
votes

I think this has little to do with UPnP: Sony just happens to use SSDP for discovery, and the defacto SSDP specification happens to be in the UPnP architecture document.

As for the problem: requests.get() does an ordinary HTTP GET (or would if you provided the correct arguments), when you should send UDP multicast message(s) and handle the responses instead.

If you really intend to do this yourself, be prepared to learn a bit of networking and understand the SSDP protocol (see UPNP UDA part 1 for that). But my suggestion is to use an SSDP library or copy working open source code -- that way you can concentrate on actually providing new things (like an implementation of the sony protocol).