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
|
SEND_NOOP_EVERY_NTH_PROBE = 5
|
||||||
DISCONNECT_AFTER_N_SECONDS = 30*60 # 30 minutes
|
DISCONNECT_AFTER_N_SECONDS = 30*60 # 30 minutes
|
||||||
|
|
||||||
|
BROADCAST_PORTS = [54982, 48123, 39001, 44044, 59678]
|
||||||
|
|
||||||
opcodes = {
|
opcodes = {
|
||||||
'NOOP' : 12,
|
'NOOP' : 12,
|
||||||
@ -525,19 +526,27 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
self.device_socket = None
|
self.device_socket = None
|
||||||
self.is_connected = False
|
self.is_connected = False
|
||||||
|
|
||||||
def _attach_to_port(self, port):
|
def _attach_to_port(self, sock, port):
|
||||||
try:
|
try:
|
||||||
self._debug('try port', port)
|
self._debug('try port', port)
|
||||||
self.listen_socket.bind(('', port))
|
sock.bind(('', port))
|
||||||
except socket.error:
|
except socket.error:
|
||||||
self._debug('socket error on port', port)
|
self._debug('socket error on port', port)
|
||||||
port = 0
|
port = 0
|
||||||
except:
|
except:
|
||||||
self._debug('Unknown exception while allocating listen socket')
|
self._debug('Unknown exception while attaching port to socket')
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
raise
|
raise
|
||||||
return port
|
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.
|
# The public interface methods.
|
||||||
|
|
||||||
@synchronous('sync_lock')
|
@synchronous('sync_lock')
|
||||||
@ -569,6 +578,18 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
except:
|
except:
|
||||||
self._close_device_socket()
|
self._close_device_socket()
|
||||||
return (self.is_connected, self)
|
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:
|
if getattr(self, 'listen_socket', None) is not None:
|
||||||
ans = select.select((self.listen_socket,), (), (), 0)
|
ans = select.select((self.listen_socket,), (), (), 0)
|
||||||
if len(ans[0]) > 0:
|
if len(ans[0]) > 0:
|
||||||
@ -976,31 +997,26 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
message = _('Invalid port in options: %s')% \
|
message = _('Invalid port in options: %s')% \
|
||||||
self.settings().extra_customization[self.OPT_PORT_NUMBER]
|
self.settings().extra_customization[self.OPT_PORT_NUMBER]
|
||||||
self._debug(message)
|
self._debug(message)
|
||||||
self.listen_socket.close()
|
self._close_listen_socket()
|
||||||
self.listen_socket = None
|
|
||||||
self.is_connected = False
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
port = self._attach_to_port(opt_port)
|
port = self._attach_to_port(self.listen_socket, opt_port)
|
||||||
if port == 0:
|
if port == 0:
|
||||||
message = _('Failed to connect to port %d. Try a different value.')%opt_port
|
message = _('Failed to connect to port %d. Try a different value.')%opt_port
|
||||||
self._debug(message)
|
self._debug(message)
|
||||||
self.listen_socket.close()
|
self._close_listen_socket()
|
||||||
self.listen_socket = None
|
|
||||||
self.is_connected = False
|
|
||||||
return message
|
return message
|
||||||
else:
|
else:
|
||||||
while i < 100: # try up to 100 random port numbers
|
while i < 100: # try up to 100 random port numbers
|
||||||
i += 1
|
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:
|
if port != 0:
|
||||||
break
|
break
|
||||||
if port == 0:
|
if port == 0:
|
||||||
message = _('Failed to allocate a random port')
|
message = _('Failed to allocate a random port')
|
||||||
self._debug(message)
|
self._debug(message)
|
||||||
self.listen_socket.close()
|
self._close_listen_socket()
|
||||||
self.listen_socket = None
|
|
||||||
self.is_connected = False
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1008,9 +1024,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
except:
|
except:
|
||||||
message = 'listen on port %d failed' % port
|
message = 'listen on port %d failed' % port
|
||||||
self._debug(message)
|
self._debug(message)
|
||||||
self.listen_socket.close()
|
self._close_listen_socket()
|
||||||
self.listen_socket = None
|
|
||||||
self.is_connected = False
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1018,21 +1032,40 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
except:
|
except:
|
||||||
message = 'registration with bonjour failed'
|
message = 'registration with bonjour failed'
|
||||||
self._debug(message)
|
self._debug(message)
|
||||||
self.listen_socket.close()
|
self._close_listen_socket()
|
||||||
self.listen_socket = None
|
|
||||||
self.is_connected = False
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
self._debug('listening on port', port)
|
self._debug('listening on port', port)
|
||||||
self.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')
|
@synchronous('sync_lock')
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
if getattr(self, 'listen_socket', None) is not None:
|
if getattr(self, 'listen_socket', None) is not None:
|
||||||
do_zeroconf(unpublish_zeroconf, self.port)
|
do_zeroconf(unpublish_zeroconf, self.port)
|
||||||
self.listen_socket.close()
|
self._close_listen_socket()
|
||||||
self.listen_socket = None
|
|
||||||
self.is_connected = False
|
|
||||||
|
|
||||||
# Methods for dynamic control
|
# Methods for dynamic control
|
||||||
|
|
||||||
|
@ -255,7 +255,7 @@ class ConnectShareAction(InterfaceAction):
|
|||||||
use_fixed_port = dm.get_option('smartdevice', 'use_fixed_port')
|
use_fixed_port = dm.get_option('smartdevice', 'use_fixed_port')
|
||||||
port_number = dm.get_option('smartdevice', 'port_number')
|
port_number = dm.get_option('smartdevice', 'port_number')
|
||||||
if show_port and use_fixed_port:
|
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)
|
formatted_addresses, port_number)
|
||||||
else:
|
else:
|
||||||
text = self.share_conn_menu.DEVICE_MSGS[1] + ' [' + formatted_addresses + ']'
|
text = self.share_conn_menu.DEVICE_MSGS[1] + ' [' + formatted_addresses + ']'
|
||||||
|
@ -27,7 +27,7 @@ def _cmp_ipaddr(l, r):
|
|||||||
|
|
||||||
return cmp(lparts, rparts)
|
return cmp(lparts, rparts)
|
||||||
|
|
||||||
def get_all_ip_addresses():
|
def _get_all_ip_addresses():
|
||||||
ip_info = [netifaces.ifaddresses(x).get(netifaces.AF_INET, None)
|
ip_info = [netifaces.ifaddresses(x).get(netifaces.AF_INET, None)
|
||||||
for x in netifaces.interfaces()]
|
for x in netifaces.interfaces()]
|
||||||
|
|
||||||
@ -42,9 +42,14 @@ def get_all_ip_addresses():
|
|||||||
all_ipaddrs.append(addrs['addr'])
|
all_ipaddrs.append(addrs['addr'])
|
||||||
|
|
||||||
all_ipaddrs.sort(cmp=_cmp_ipaddr)
|
all_ipaddrs.sort(cmp=_cmp_ipaddr)
|
||||||
print(all_ipaddrs)
|
|
||||||
return 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):
|
class SmartdeviceDialog(QDialog, Ui_Dialog):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user