2018-07-29 04:08:24 +02:00
|
|
|
import logging
|
|
|
|
from twisted.internet import defer
|
|
|
|
from txupnp.util import get_lan_info
|
|
|
|
from txupnp.ssdp import SSDPFactory
|
|
|
|
from txupnp.scpd import SCPDCommandRunner
|
|
|
|
from txupnp.gateway import Gateway
|
2018-07-29 05:06:17 +02:00
|
|
|
from txupnp.fault import UPnPError
|
2018-07-29 04:08:24 +02:00
|
|
|
from txupnp.constants import GATEWAY_SCHEMA
|
|
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class SOAPServiceManager(object):
|
|
|
|
def __init__(self, reactor):
|
|
|
|
self._reactor = reactor
|
|
|
|
self.iface_name, self.router_ip, self.lan_address = get_lan_info()
|
2018-07-29 23:32:14 +02:00
|
|
|
self.sspd_factory = SSDPFactory(self._reactor, self.lan_address, self.router_ip)
|
2018-07-29 04:08:24 +02:00
|
|
|
self._command_runners = {}
|
|
|
|
self._selected_runner = GATEWAY_SCHEMA
|
|
|
|
|
|
|
|
@defer.inlineCallbacks
|
2018-07-29 23:32:14 +02:00
|
|
|
def discover_services(self, address=None, timeout=30, max_devices=1):
|
2018-07-29 04:08:24 +02:00
|
|
|
server_infos = yield self.sspd_factory.m_search(
|
2018-07-29 23:32:14 +02:00
|
|
|
address or self.router_ip, timeout=timeout, max_devices=max_devices
|
2018-07-29 04:08:24 +02:00
|
|
|
)
|
|
|
|
locations = []
|
|
|
|
for server_info in server_infos:
|
2018-07-29 04:33:45 +02:00
|
|
|
if 'st' in server_info and server_info['st'] not in self._command_runners:
|
2018-07-29 04:08:24 +02:00
|
|
|
locations.append(server_info['location'])
|
|
|
|
gateway = Gateway(**server_info)
|
|
|
|
yield gateway.discover_services()
|
|
|
|
command_runner = SCPDCommandRunner(gateway)
|
|
|
|
yield command_runner.discover_commands()
|
|
|
|
self._command_runners[gateway.urn.decode()] = command_runner
|
2018-07-29 04:33:45 +02:00
|
|
|
elif 'st' not in server_info:
|
|
|
|
log.error("don't know how to handle gateway: %s", server_info)
|
|
|
|
continue
|
2018-07-29 04:08:24 +02:00
|
|
|
defer.returnValue(len(self._command_runners))
|
|
|
|
|
|
|
|
def set_runner(self, urn):
|
|
|
|
if urn not in self._command_runners:
|
|
|
|
raise IndexError(urn)
|
|
|
|
self._command_runners = urn
|
|
|
|
|
|
|
|
def get_runner(self):
|
2018-07-29 05:06:17 +02:00
|
|
|
if self._command_runners and not self._selected_runner in self._command_runners:
|
|
|
|
self._selected_runner = list(self._command_runners.keys())[0]
|
|
|
|
if not self._command_runners:
|
2018-07-29 05:19:22 +02:00
|
|
|
raise UPnPError("no devices found")
|
2018-07-29 04:08:24 +02:00
|
|
|
return self._command_runners[self._selected_runner]
|
|
|
|
|
|
|
|
def get_available_runners(self):
|
|
|
|
return self._command_runners.keys()
|