Newer
Older
pc-autobackup / ssdp.py
@Jeff Rebeiro Jeff Rebeiro on 31 Jan 2013 1 KB add ssdp module
#!/usr/bin/python
 
# Python program that can send out M-SEARCH messages using SSDP (in server
# mode), or listen for SSDP messages (in client mode).
 
import sys
from twisted.internet import reactor, task
from twisted.internet.protocol import DatagramProtocol
 
SSDP_ADDR = '239.255.255.250'
SSDP_PORT = 1900
 
MS = 'M-SEARCH * HTTP/1.1\r\nHOST: %s:%d\r\nMAN: "ssdp:discover"\r\nMX: 2\r\nST: ssdp:all\r\n\r\n' % (SSDP_ADDR, SSDP_PORT)
 
class Base(DatagramProtocol):
    def datagramReceived(self, datagram, address):
        if address[0] == '10.0.1.120':
          first_line = datagram.rsplit('\r\n')[0]
          print "Received %s from %r" % (first_line, address, )
          print "Contents:"
          print datagram
 
    def stop(self):
        pass
 
class Server(Base):
    def __init__(self, iface):
        self.iface = iface
        task.LoopingCall(self.send_msearch).start(6) # every 6th seconds
 
    def send_msearch(self):
        port = reactor.listenUDP(0, self, interface=self.iface)
        print "Sending M-SEARCH..."
        port.write(MS, (SSDP_ADDR, SSDP_PORT))
        reactor.callLater(2.5, port.stopListening) # MX + a wait margin
 
class Client(Base):
    def __init__(self, iface):
        self.iface = iface
        self.ssdp = reactor.listenMulticast(SSDP_PORT, self, listenMultiple=True)
        self.ssdp.setLoopbackMode(1)
        self.ssdp.joinGroup(SSDP_ADDR, interface=iface)
 
    def stop(self):
        self.ssdp.leaveGroup(SSDP_ADDR, interface=self.iface)
        self.ssdp.stopListening()
 
def main(mode, iface):
    klass = Server if mode == 'server' else Client
    obj = klass(iface)
    reactor.addSystemEventTrigger('before', 'shutdown', obj.stop)
 
if __name__ == "__main__":
    if len(sys.argv) != 3:
        print "Usage: %s <server|client> <IP of interface>" % (sys.argv[0], )
        sys.exit(1)
    mode, iface = sys.argv[1:]
    reactor.callWhenRunning(main, mode, iface)
    reactor.run()