Example #1
0
    def get(self):   # overload get() from parent
        """Get the next response from the network.

        Arguments: None
        Returns: a received datagram, may be empty only with time and retry
        number.
        """
        if self._count < 0:
            return

        while True:
            _o_datagram = super().get()
            if _o_datagram is None:
                self._count -= 1
                _o_dummy_datagram = SSDPdatagram()
                if self._count > 0:
                    super().request()
                    self._retry += 1
                    _o_dummy_datagram.request = self._retry
                    #return _rel_time + 's ' + str(self._retry) + '\r\n'
                else:
                    self._count = -1
                    _o_dummy_datagram.request = 0
                    #return _rel_time + 's ' + '0' + '\r\n'
                return _o_dummy_datagram.fdevice(
                    base_time=self._timestamp_first_request)
            else:
                _device = _o_datagram.ipaddr + ' ' +_o_datagram.uuid
                if _device not in self._devicelist:
                    self._devicelist.append(_device)
                    _o_datagram.request = self._retry
                    return _o_datagram.fdevice(
                        base_time=self._timestamp_first_request,
                        verbose=self._verbose)
Example #2
0
 def test3_fdevice(self):
     """Test formating device from listen datagram without addr and data."""
     o_datagram = SSDPdatagram()
     result = o_datagram.fdevice()
     self.assertEqual(result, '0000.0000s 0\r\n')
     result = o_datagram.fdevice(base_time=time() - 1.5)
     self.assertRegex(result, r'^0001\.\d\d\d\ds 0\r\n$')
Example #3
0
 def test8_fdevice(self):
     """Test format device verbose listen datagram without addr and data."""
     o_datagram = SSDPdatagram()
     result = o_datagram.fdevice(verbose=True)
     self.assertEqual(result, '0000.0000s 0\r\n')
     result = o_datagram.fdevice(base_time=time() - 1.5, verbose=True)
     self.assertRegex(result, r'^0001\.\d\d\d\ds 0\r\n$')
Example #4
0
 def test9_fdevice(self):
     """Test formating device verbose from listen datagram without data."""
     o_datagram = SSDPdatagram(addr=LADDR1)
     o_datagram.request = 2
     result = o_datagram.fdevice(verbose=True)
     self.assertEqual(result, '0000.0000s 2 192.168.10.86:57535\r\n')
     result = o_datagram.fdevice(base_time=time() - 1.5, verbose=True)
     self.assertRegex(result, (r'^0001\.\d\d\d\ds 2 '
                               r'192\.168\.10\.86:57535\r\n$'))
Example #5
0
 def test10_fdevice(self):
     """Test formating device verbose from listen datagram without addr."""
     o_datagram = SSDPdatagram(raw_data=LDATAGRAM1)
     o_datagram.request = 4
     result = o_datagram.fdevice(verbose=True)
     self.assertEqual(result, '0000.0000s 4\r\n' + LDATAGRAM1.decode())
     result = o_datagram.fdevice(base_time=time() - 1.5, verbose=True)
     self.assertRegex(result[:9], r'^0001\.\d\d\d\d$')
     self.assertEqual(result[9:], 's 4\r\n' + LDATAGRAM1.decode())
Example #6
0
 def _get_datagram(self):
     """Listen to the next SSDP datagram on the local network"""
     if self._timeout != 0:
         try:
             data, addr = self._sock.recvfrom(self.RECVBUF)
             if len(data) >= self.RECVBUF:
                 raise SystemExit("ERROR: receive buffer overflow")
             self._o_datagram = SSDPdatagram(addr, data)
         except KeyboardInterrupt:
             self._timeout = 0
Example #7
0
 def test7_fdevice(self):
     """Test formating a device verbose output from a listen datagram."""
     o_datagram = SSDPdatagram(addr=LADDR1, raw_data=LDATAGRAM1)
     o_datagram.request = 3
     result = o_datagram.fdevice(verbose=True)
     self.assertEqual(
         result,
         '0000.0000s 3 192.168.10.86:57535\r\n' + LDATAGRAM1.decode())
     result = o_datagram.fdevice(base_time=time() - 1.5, verbose=True)
     self.assertRegex(result[:9], r'^0001\.\d\d\d\d$')
     self.assertEqual(result[9:],
                      's 3 192.168.10.86:57535\r\n' + LDATAGRAM1.decode())
Example #8
0
 def test6_fdevice(self):
     """Test formating a device verbose output from a search datagram."""
     o_datagram = SSDPdatagram(addr=SADDR1, raw_data=SDATAGRAM1)
     result = o_datagram.fdevice(verbose=True)
     self.assertEqual(
         result,
         '0000.0000s 0 192.168.10.119:47383\r\n' + SDATAGRAM1.decode())
     result = o_datagram.fdevice(time() + 2, verbose=True)
     self.assertEqual(
         result,
         '0000.0000s 0 192.168.10.119:47383\r\n' + SDATAGRAM1.decode())
     result = o_datagram.fdevice(base_time=time() - 1.5, verbose=True)
     self.assertRegex(result[:9], r'^0001\.\d\d\d\d$')
     self.assertEqual(result[9:],
                      's 0 192.168.10.119:47383\r\n' + SDATAGRAM1.decode())
Example #9
0
 def test5_fdevice(self):
     """Test formating device output from a listen datagram without addr."""
     o_datagram = SSDPdatagram(raw_data=LDATAGRAM1)
     o_datagram.request = 4
     result = o_datagram.fdevice()
     self.assertEqual(
         result,
         ('0000.0000s 4 NOTIFY uuid:f4f7681c-3056-11e8-86bd-87a6e4e2c42d '
          'Linux/4.14.71-v7+, UPnP/1.0, Portable SDK for UPnP '
          'devices/1.6.19+git20160116\r\n'))
     result = o_datagram.fdevice(base_time=time() - 1.5)
     self.assertRegex(result, (
         r'^0001\.\d\d\d\ds 4 NOTIFY '
         r'uuid:f4f7681c-3056-11e8-86bd-87a6e4e2c42d Linux/4\.14\.71-v7\+, '
         r'UPnP/1\.0, Portable SDK for UPnP devices/1\.6\.19\+git20160116'
         r'\r\n$'))
Example #10
0
    def test5_ssdp_datagram(self):
        """Test structure of a SSDP datagram object from listen."""
        o_datagram = SSDPdatagram(addr=LADDR1, raw_data=LDATAGRAM1)
        self.assertAlmostEqual(o_datagram.timestamp, time(), 2)
        self.assertEqual(o_datagram.ipaddr, '192.168.10.86')
        self.assertEqual(o_datagram.port, '57535')
        self.assertEqual(o_datagram.request, 0)

        self.assertEqual(o_datagram.method, 'NOTIFY')
        self.assertEqual(o_datagram.host, '239.255.255.250:1900')
        self.assertEqual(o_datagram.cache_control, 'max-age=100')
        self.assertEqual(o_datagram.location,
                         'http://192.168.10.86:49494/description.xml')
        self.assertEqual(o_datagram.opt,
                         '"http://schemas.upnp.org/upnp/1/0/"; ns=01')
        self.assertEqual(o_datagram.x01_nls,
                         '293e3a3c-760d-11e8-8719-a7d281e29bfc')
        self.assertEqual(o_datagram.nt,
                         'urn:schemas-upnp-org:device:MediaRenderer:1')
        self.assertEqual(o_datagram.nts, 'ssdp:alive')
        self.assertEqual(o_datagram.server,
                         ('Linux/4.14.71-v7+, UPnP/1.0, Portable SDK for UPnP '
                          'devices/1.6.19+git20160116'))
        self.assertEqual(o_datagram.x_user_agent, 'redsonic')
        self.assertEqual(o_datagram.usn,
                         ('uuid:f4f7681c-3056-11e8-86bd-87a6e4e2c42d'
                          '::urn:schemas-upnp-org:device:MediaRenderer:1'))
        self.assertEqual(o_datagram.uuid,
                         'f4f7681c-3056-11e8-86bd-87a6e4e2c42d')
        self.assertEqual(o_datagram.data, LDATAGRAM1.decode())
Example #11
0
    def get(self):
        """Get next SSDP datagram from multicast net within a timeout.

        This method returns a SSDPdatagram object that represents a received
        SSDP record from an upnp root device on the local netwwork. A call
        returns only when a datagram has received or when the timeout has
        expired. The timeout is the given response time for the devices (plus a
        small network delay).
        """
        if self._response_time == 0:
            return
        else:
            try:
                # The timeout (in sec) for the socket is reduced after every
                # received data so the over all transfer has finished after the
                # given response time (plus a small network delay added).
                _tout = int(round(
                    self._response_time \
                    - (time() - self._timestamp_request))) \
                    + 1
                self._sock.settimeout(_tout)
                data, addr = self._sock.recvfrom(self.RECVBUF)
                if len(data) >= self.RECVBUF:
                    raise SystemExit("ERROR: receive buffer overflow")
                return SSDPdatagram(addr, data)
            except socket.timeout:
                self._response_time = 0
                return
Example #12
0
 def test2_fdevice(self):
     """Test formating a device output from a listen datagram."""
     o_datagram = SSDPdatagram(addr=LADDR1, raw_data=LDATAGRAM1)
     o_datagram.request = 3
     result = o_datagram.fdevice()
     self.assertEqual(
         result,
         ('0000.0000s 3 NOTIFY 192.168.10.86:57535 '
          'uuid:f4f7681c-3056-11e8-86bd-87a6e4e2c42d Linux/4.14.71-v7+, '
          'UPnP/1.0, Portable SDK for UPnP devices/1.6.19+git20160116\r\n'))
     result = o_datagram.fdevice(base_time=time() - 1.5)
     self.assertRegex(result, (
         r'^0001\.\d\d\d\ds 3 NOTIFY 192\.168\.10\.86:57535 '
         r'uuid:f4f7681c-3056-11e8-86bd-87a6e4e2c42d Linux/4\.14\.71-v7\+, '
         r'UPnP/1\.0, Portable SDK for UPnP devices/1\.6\.19\+git20160116'
         r'\r\n$'))
Example #13
0
    def test1_ssdp_datagram(self):
        """Test structure of a SSDP datagram object from search response."""
        o_datagram = SSDPdatagram(addr=SADDR1, raw_data=SDATAGRAM1)
        self.assertAlmostEqual(o_datagram.timestamp, time(), 2)
        self.assertEqual(len(o_datagram.__dict__), 17)

        self.assertEqual(o_datagram.method, '')
        self.assertEqual(o_datagram.bootid_upnp_org, '0')
        self.assertEqual(o_datagram.cache_control, 'max-age=1800')
        self.assertEqual(o_datagram.configid_upnp_org, '1')
        self.assertEqual(o_datagram.date, 'Sun, 23 Sep 2018 17:08:38 GMT')
        self.assertEqual(o_datagram.ext, '')
        self.assertEqual(o_datagram.ipaddr, '192.168.10.119')
        self.assertEqual(o_datagram.location,
                         ('http://192.168.10.119:8008/ssdp/device-desc.xml'))
        self.assertEqual(o_datagram.opt, '"http://schemas.upnp.org/upnp/1/0/";'
                         ' ns=01')
        self.assertEqual(o_datagram.port, '47383')
        self.assertEqual(o_datagram.request, 0)
        self.assertEqual(
            o_datagram.server, 'Linux/3.10.79, UPnP/1.0, '
            'Portable SDK for UPnP devices/1.6.18')
        self.assertEqual(o_datagram.st, 'upnp:rootdevice')
        self.assertEqual(
            o_datagram.usn,
            ('uuid:3b2867a3-b55f-8e77-5ad8-a6d0c6990277::upnp:rootdevice'))
        self.assertEqual(o_datagram.uuid,
                         '3b2867a3-b55f-8e77-5ad8-a6d0c6990277')
        self.assertEqual(o_datagram.x01_nls,
                         'd2631d76-1dd1-11b2-9c2f-ee4373b37081')
        self.assertEqual(o_datagram.x_user_agent, 'redsonic')
        self.assertEqual(o_datagram.data, SDATAGRAM1.decode())
Example #14
0
    def test2_ssdp_datagram(self):
        """Test SSDP datagram from search response without addr and data."""
        o_datagram = SSDPdatagram()
        self.assertAlmostEqual(o_datagram.timestamp, time(), 2)
        self.assertEqual(len(o_datagram.__dict__), 4)

        self.assertEqual(o_datagram.ipaddr, '')
        self.assertEqual(o_datagram.port, '')
        self.assertEqual(o_datagram.method, '')
        self.assertEqual(o_datagram.request, 0)
        self.assertIsNone(o_datagram.data)
Example #15
0
    def test4_ssdp_datagram(self):
        """Test SSDP datagram from search response without addr."""
        o_datagram = SSDPdatagram(raw_data=SDATAGRAM1)
        self.assertAlmostEqual(o_datagram.timestamp, time(), 2)
        self.assertEqual(len(o_datagram.__dict__), 17)

        self.assertEqual(o_datagram.ipaddr, '')
        self.assertEqual(o_datagram.port, '')
        self.assertEqual(o_datagram.method, '')
        self.assertEqual(o_datagram.request, 0)
        self.assertEqual(o_datagram.data, SDATAGRAM1.decode())
Example #16
0
    def test3_ssdp_datagram(self):
        """Test SSDP datagram from search response without data."""
        o_datagram = SSDPdatagram(addr=SADDR1)
        self.assertAlmostEqual(o_datagram.timestamp, time(), 2)
        self.assertEqual(len(o_datagram.__dict__), 4)

        self.assertEqual(o_datagram.ipaddr, '192.168.10.119')
        self.assertEqual(o_datagram.port, '47383')
        self.assertEqual(o_datagram.method, '')
        self.assertEqual(o_datagram.request, 0)
        self.assertIsNone(o_datagram.data)
Example #17
0
 def test1_fdevice(self):
     """Test formating a device output from a search datagram."""
     o_datagram = SSDPdatagram(addr=SADDR1, raw_data=SDATAGRAM1)
     result = o_datagram.fdevice()
     self.assertEqual(
         result,
         ('0000.0000s 0 192.168.10.119:47383 '
          'uuid:3b2867a3-b55f-8e77-5ad8-a6d0c6990277 Linux/3.10.79, '
          'UPnP/1.0, Portable SDK for UPnP devices/1.6.18\r\n'))
     result = o_datagram.fdevice(time() + 2)
     self.assertEqual(
         result,
         ('0000.0000s 0 192.168.10.119:47383 '
          'uuid:3b2867a3-b55f-8e77-5ad8-a6d0c6990277 Linux/3.10.79, '
          'UPnP/1.0, Portable SDK for UPnP devices/1.6.18\r\n'))
     result = o_datagram.fdevice(base_time=time() - 1.5)
     self.assertRegex(
         result,
         (r'^0001\.\d\d\d\ds 0 192\.168\.10\.119:47383 '
          r'uuid:3b2867a3-b55f-8e77-5ad8-a6d0c6990277 Linux/3\.10\.79, '
          r'UPnP/1\.0, Portable SDK for UPnP devices/1\.6\.18\r\n$'))
Example #18
0
class Listen(Mcast):
    """Passive listen for notifies from devices on the local network

    We are only listen to the upnp multicast group.
    """
    _verbose = False
    _open_timestamp = 0
    _timeout = 0
    _sock = None
    _o_datagram = None

    def __init__(self, verbose=False):
        """Setup verbose output if requested."""
        self._verbose = verbose

    def open(self):
        """Initialize and open a connection and join to the multicast group"""

        self._open_timestamp = time()
        self._timeout = -1
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                   socket.IPPROTO_UDP)
        self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # use MCAST_GRP instead of '' to listen only to MCAST_GRP,
        # not all groups on MCAST_PORT
        # self._sock.bind(('', self._MCAST_PORT))
        self._sock.bind((self._MCAST_GRP, self._MCAST_PORT))
        mreq = struct.pack("4sl", socket.inet_aton(self._MCAST_GRP),
                           socket.INADDR_ANY)
        self._sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
                              mreq)

    def _get_datagram(self):
        """Listen to the next SSDP datagram on the local network"""
        if self._timeout != 0:
            try:
                data, addr = self._sock.recvfrom(self.RECVBUF)
                if len(data) >= self.RECVBUF:
                    raise SystemExit("ERROR: receive buffer overflow")
                self._o_datagram = SSDPdatagram(addr, data)
            except KeyboardInterrupt:
                self._timeout = 0

    def get(self):
        """Listen for upnp datagrams on the local network."""
        self._get_datagram()
        if self._timeout == 0:
            return
        return self._o_datagram.fdevice(base_time=self._open_timestamp,
                                        verbose=self._verbose)