mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Add reverse find to smartdevice using broadcasts
Cache the list of IP addresses
This commit is contained in:
parent
ffde6a4a04
commit
4ce9dd36fa
@ -88,6 +88,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
SEND_NOOP_EVERY_NTH_PROBE = 5
|
||||
DISCONNECT_AFTER_N_SECONDS = 30*60 # 30 minutes
|
||||
|
||||
BROADCAST_PORTS = [54982, 48123, 39001, 44044, 59678]
|
||||
|
||||
opcodes = {
|
||||
'NOOP' : 12,
|
||||
@ -525,19 +526,27 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
self.device_socket = None
|
||||
self.is_connected = False
|
||||
|
||||
def _attach_to_port(self, port):
|
||||
def _attach_to_port(self, sock, port):
|
||||
try:
|
||||
self._debug('try port', port)
|
||||
self.listen_socket.bind(('', port))
|
||||
sock.bind(('', port))
|
||||
except socket.error:
|
||||
self._debug('socket error on port', port)
|
||||
port = 0
|
||||
except:
|
||||
self._debug('Unknown exception while allocating listen socket')
|
||||
self._debug('Unknown exception while attaching port to socket')
|
||||
traceback.print_exc()
|
||||
raise
|
||||
return port
|
||||
|
||||
def _close_listen_socket(self):
|
||||
self.listen_socket.close()
|
||||
self.listen_socket = None
|
||||
self.is_connected = False
|
||||
if getattr(self, 'broadcast_socket', None) is not None:
|
||||
self.broadcast_socket.close()
|
||||
self.broadcast_socket = None
|
||||
|
||||
# The public interface methods.
|
||||
|
||||
@synchronous('sync_lock')
|
||||
@ -569,6 +578,18 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
except:
|
||||
self._close_device_socket()
|
||||
return (self.is_connected, self)
|
||||
if getattr(self, 'broadcast_socket', None) is not None:
|
||||
ans = select.select((self.broadcast_socket,), (), (), 0)
|
||||
if len(ans[0]) > 0:
|
||||
try:
|
||||
packet = self.broadcast_socket.recvfrom(100)
|
||||
remote = packet[1]
|
||||
message = str(socket.gethostname().partition('.')[0] + '|') + str(self.port)
|
||||
self._debug('received broadcast', packet, message)
|
||||
self.broadcast_socket.sendto(message, remote)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
if getattr(self, 'listen_socket', None) is not None:
|
||||
ans = select.select((self.listen_socket,), (), (), 0)
|
||||
if len(ans[0]) > 0:
|
||||
@ -976,31 +997,26 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
message = _('Invalid port in options: %s')% \
|
||||
self.settings().extra_customization[self.OPT_PORT_NUMBER]
|
||||
self._debug(message)
|
||||
self.listen_socket.close()
|
||||
self.listen_socket = None
|
||||
self.is_connected = False
|
||||
self._close_listen_socket()
|
||||
return message
|
||||
|
||||
port = self._attach_to_port(opt_port)
|
||||
port = self._attach_to_port(self.listen_socket, opt_port)
|
||||
if port == 0:
|
||||
message = _('Failed to connect to port %d. Try a different value.')%opt_port
|
||||
self._debug(message)
|
||||
self.listen_socket.close()
|
||||
self.listen_socket = None
|
||||
self.is_connected = False
|
||||
self._close_listen_socket()
|
||||
return message
|
||||
else:
|
||||
while i < 100: # try up to 100 random port numbers
|
||||
i += 1
|
||||
port = self._attach_to_port(random.randint(8192, 32000))
|
||||
port = self._attach_to_port(self.listen_socket,
|
||||
random.randint(8192, 32000))
|
||||
if port != 0:
|
||||
break
|
||||
if port == 0:
|
||||
message = _('Failed to allocate a random port')
|
||||
self._debug(message)
|
||||
self.listen_socket.close()
|
||||
self.listen_socket = None
|
||||
self.is_connected = False
|
||||
self._close_listen_socket()
|
||||
return message
|
||||
|
||||
try:
|
||||
@ -1008,9 +1024,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
except:
|
||||
message = 'listen on port %d failed' % port
|
||||
self._debug(message)
|
||||
self.listen_socket.close()
|
||||
self.listen_socket = None
|
||||
self.is_connected = False
|
||||
self._close_listen_socket()
|
||||
return message
|
||||
|
||||
try:
|
||||
@ -1018,21 +1032,40 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
except:
|
||||
message = 'registration with bonjour failed'
|
||||
self._debug(message)
|
||||
self.listen_socket.close()
|
||||
self.listen_socket = None
|
||||
self.is_connected = False
|
||||
self._close_listen_socket()
|
||||
return message
|
||||
|
||||
self._debug('listening on port', port)
|
||||
self.port = port
|
||||
|
||||
# Now try to open a UDP socket to receive broadcasts on
|
||||
|
||||
try:
|
||||
self.broadcast_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
except:
|
||||
message = 'creation of broadcast socket failed. This is not fatal.'
|
||||
self._debug(message)
|
||||
return message
|
||||
|
||||
for p in self.BROADCAST_PORTS:
|
||||
port = self._attach_to_port(self.broadcast_socket, p)
|
||||
if port != 0:
|
||||
self._debug('broadcast socket listening on port', port)
|
||||
break
|
||||
|
||||
if port == 0:
|
||||
self.broadcast_socket.close()
|
||||
self.broadcast_socket = None
|
||||
message = 'attaching port to broadcast socket failed. This is not fatal.'
|
||||
self._debug(message)
|
||||
return message
|
||||
|
||||
|
||||
@synchronous('sync_lock')
|
||||
def shutdown(self):
|
||||
if getattr(self, 'listen_socket', None) is not None:
|
||||
do_zeroconf(unpublish_zeroconf, self.port)
|
||||
self.listen_socket.close()
|
||||
self.listen_socket = None
|
||||
self.is_connected = False
|
||||
self._close_listen_socket()
|
||||
|
||||
# Methods for dynamic control
|
||||
|
||||
|
@ -255,7 +255,7 @@ class ConnectShareAction(InterfaceAction):
|
||||
use_fixed_port = dm.get_option('smartdevice', 'use_fixed_port')
|
||||
port_number = dm.get_option('smartdevice', 'port_number')
|
||||
if show_port and use_fixed_port:
|
||||
text = self.share_conn_menu.DEVICE_MSGS[1] + ' [%s port %s]'%(
|
||||
text = self.share_conn_menu.DEVICE_MSGS[1] + ' [%s, port %s]'%(
|
||||
formatted_addresses, port_number)
|
||||
else:
|
||||
text = self.share_conn_menu.DEVICE_MSGS[1] + ' [' + formatted_addresses + ']'
|
||||
|
@ -27,7 +27,7 @@ def _cmp_ipaddr(l, r):
|
||||
|
||||
return cmp(lparts, rparts)
|
||||
|
||||
def get_all_ip_addresses():
|
||||
def _get_all_ip_addresses():
|
||||
ip_info = [netifaces.ifaddresses(x).get(netifaces.AF_INET, None)
|
||||
for x in netifaces.interfaces()]
|
||||
|
||||
@ -42,9 +42,14 @@ def get_all_ip_addresses():
|
||||
all_ipaddrs.append(addrs['addr'])
|
||||
|
||||
all_ipaddrs.sort(cmp=_cmp_ipaddr)
|
||||
print(all_ipaddrs)
|
||||
return all_ipaddrs
|
||||
|
||||
_all_ip_addresses = []
|
||||
def get_all_ip_addresses():
|
||||
global _all_ip_addresses
|
||||
if not _all_ip_addresses:
|
||||
_all_ip_addresses = _get_all_ip_addresses()
|
||||
return _all_ip_addresses
|
||||
|
||||
class SmartdeviceDialog(QDialog, Ui_Dialog):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user