1
0
mirror of https://github.com/fHDHR/fHDHR_NextPVR.git synced 2025-12-06 11:16:58 -05:00

Implement SSDP Alive Refresh

This commit is contained in:
deathbybandaid 2020-12-04 10:08:05 -05:00
parent 33dd833cde
commit 7ffd33ae51
5 changed files with 66 additions and 23 deletions

View File

@ -0,0 +1,14 @@
{
"ssdp":{
"enabled":{
"value": true,
"config_file": true,
"config_web": false
},
"refresh_frequency":{
"value": 1800,
"config_file": true,
"config_web": false
}
}
}

View File

@ -21,7 +21,7 @@
<button class="pull-left" onclick="OpenLink('/origin')">{{ fhdhr.config.dict["main"]["servicename"] }}</a></button> <button class="pull-left" onclick="OpenLink('/origin')">{{ fhdhr.config.dict["main"]["servicename"] }}</a></button>
<button class="pull-left" onclick="OpenLink('/channels')">Channels</a></button> <button class="pull-left" onclick="OpenLink('/channels')">Channels</a></button>
<button class="pull-left" onclick="OpenLink('/guide')">Guide</a></button> <button class="pull-left" onclick="OpenLink('/guide')">Guide</a></button>
<button class="pull-left" onclick="OpenLink('/cluster')">Cluster</a></button> <button class="pull-left" onclick="OpenLink('/cluster')">Cluster/SSDP</a></button>
<button class="pull-left" onclick="OpenLink('/tuners')">Tuners</a></button> <button class="pull-left" onclick="OpenLink('/tuners')">Tuners</a></button>
<button class="pull-left" onclick="OpenLink('/xmltv')">xmltv</a></button> <button class="pull-left" onclick="OpenLink('/xmltv')">xmltv</a></button>
<button class="pull-left" onclick="OpenLink('/version')">Version</a></button> <button class="pull-left" onclick="OpenLink('/version')">Version</a></button>

View File

@ -2,13 +2,14 @@
{% block content %} {% block content %}
<h4 style="text-align: center;">Cluster</h4> <h4 style="text-align: center;">Cluster/SSDP</h4>
{% if not fhdhr.config.dict["fhdhr"]["discovery_address"] %} {% if not fhdhr.config.dict["fhdhr"]["discovery_address"] %}
<p style="text-align: center;">Discovery Address must be set for SSDP/Cluster</p> <p style="text-align: center;">Discovery Address must be set for Cluster/SSDP</p>
{% else %} {% else %}
<div style="text-align: center;"> <div style="text-align: center;">
<button onclick="OpenLink('/api/cluster?method=scan&redirect=%2Fcluster')">Force Scan</a></button> <button onclick="OpenLink('/api/cluster?method=scan&redirect=%2Fcluster')">Force Scan</a></button>
<button onclick="OpenLink('/api/cluster?method=alive&redirect=%2Fcluster')">Send Alive</a></button>
<button onclick="OpenLink('/api/cluster?method=disconnect&redirect=%2Fcluster')">Disconnect</a></button> <button onclick="OpenLink('/api/cluster?method=disconnect&redirect=%2Fcluster')">Disconnect</a></button>
</div> </div>
<br> <br>

View File

@ -1,6 +1,7 @@
# Adapted from https://github.com/MoshiBin/ssdpy and https://github.com/ZeWaren/python-upnp-ssdp-example # Adapted from https://github.com/MoshiBin/ssdpy and https://github.com/ZeWaren/python-upnp-ssdp-example
import socket import socket
import struct import struct
import time
from .ssdp_detect import fHDHR_Detect from .ssdp_detect import fHDHR_Detect
from .rmg_ssdp import RMG_SSDP from .rmg_ssdp import RMG_SSDP
@ -14,7 +15,8 @@ class SSDPServer():
self.detect_method = fHDHR_Detect(fhdhr) self.detect_method = fHDHR_Detect(fhdhr)
if fhdhr.config.dict["fhdhr"]["discovery_address"]: if (fhdhr.config.dict["fhdhr"]["discovery_address"] and
fhdhr.config.dict["ssdp"]["enabled"]):
self.sock = None self.sock = None
self.proto = "ipv4" self.proto = "ipv4"
@ -84,13 +86,51 @@ class SSDPServer():
self.rmg_ssdp = RMG_SSDP(fhdhr, self._broadcast_ip) self.rmg_ssdp = RMG_SSDP(fhdhr, self._broadcast_ip)
self.hdhr_ssdp = HDHR_SSDP(fhdhr, self._broadcast_ip) self.hdhr_ssdp = HDHR_SSDP(fhdhr, self._broadcast_ip)
self.refresh = int(fhdhr.config.dict["ssdp"]["refresh_frequency"])
self.refresh_last = None
self.do_alive()
self.m_search() self.m_search()
def do_alive(self, forcealive=False):
send_alive = False
if not self.refresh_last:
send_alive = True
elif forcealive:
send_alive = True
elif time.time() >= (self.refresh_last + self.refresh):
send_alive = True
if send_alive:
self.fhdhr.logger.info("Sending Alive message to network.")
self.do_notify(('239.255.255.250', 1900))
self.refresh_last = time.time()
def do_notify(self, address):
notify_list = []
hdhr_notify = self.hdhr_ssdp.get()
notify_list.append(hdhr_notify)
if self.fhdhr.config.dict["rmg"]["enabled"]:
rmg_notify = self.rmg_ssdp.get()
notify_list.append(rmg_notify)
for notify in notify_list:
self.fhdhr.logger.debug("Created {}".format(notify))
try:
self.sock.sendto(notify, address)
except OSError as e:
# Most commonly: We received a multicast from an IP not in our subnet
self.fhdhr.logger.debug("Unable to send NOTIFY: %s" % e)
pass
def on_recv(self, data, address): def on_recv(self, data, address):
self.fhdhr.logger.debug("Received packet from {}: {}".format(address, data)) self.fhdhr.logger.debug("Received packet from {}: {}".format(address, data))
(host, port) = address
try: try:
header, payload = data.decode().split('\r\n\r\n')[:2] header, payload = data.decode().split('\r\n\r\n')[:2]
except ValueError: except ValueError:
@ -110,24 +150,8 @@ class SSDPServer():
self.fhdhr.logger.debug("Received qualifying M-SEARCH from {}".format(address)) self.fhdhr.logger.debug("Received qualifying M-SEARCH from {}".format(address))
self.fhdhr.logger.debug("M-SEARCH data: {}".format(headers)) self.fhdhr.logger.debug("M-SEARCH data: {}".format(headers))
notify_list = [] self.do_notify(address)
hdhr_notify = self.hdhr_ssdp.get()
notify_list.append(hdhr_notify)
if self.fhdhr.config.dict["rmg"]["enabled"]:
rmg_notify = self.rmg_ssdp.get()
notify_list.append(rmg_notify)
for notify in notify_list:
self.fhdhr.logger.debug("Created NOTIFY: {}".format(notify))
try:
self.sock.sendto(notify, address)
except OSError as e:
# Most commonly: We received a multicast from an IP not in our subnet
self.fhdhr.logger.debug("Unable to send NOTIFY to {}: {}".format(address, e))
pass
elif cmd[0] == 'NOTIFY' and cmd[1] == '*': elif cmd[0] == 'NOTIFY' and cmd[1] == '*':
# SSDP presence # SSDP presence
self.fhdhr.logger.debug("NOTIFY data: {}".format(headers)) self.fhdhr.logger.debug("NOTIFY data: {}".format(headers))
@ -169,5 +193,6 @@ class SSDPServer():
while True: while True:
data, address = self.sock.recvfrom(1024) data, address = self.sock.recvfrom(1024)
self.on_recv(data, address) self.on_recv(data, address)
self.do_alive()
except KeyboardInterrupt: except KeyboardInterrupt:
self.sock.close() self.sock.close()

View File

@ -44,6 +44,9 @@ class Cluster():
elif method == 'disconnect': elif method == 'disconnect':
self.fhdhr.device.cluster.disconnect() self.fhdhr.device.cluster.disconnect()
elif method == 'alive':
self.fhdhr.device.ssdp.do_alive(forcealive=True)
else: else:
return "Invalid Method" return "Invalid Method"