1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 from python_qt_binding import QtCore, QtGui
35
36 import time
37 from datetime import datetime
38
39 import roslib
40 import roslib.message
41 import rospy
42 import threading
43 import socket
44
45 from master_discovery_fkie.udp import McastSocket
46 from master_discovery_fkie.master_discovery import Discoverer
47 import node_manager_fkie as nm
48
50
51 TIMEOUT = 0.1
52
53 display_clear_signal = QtCore.Signal()
54 display_append_signal = QtCore.Signal(str)
55 status_text_signal = QtCore.Signal(str)
56 network_join_request = QtCore.Signal(int)
57
58
59 - def __init__(self, default_mcast_group, default_port, networks_count, parent=None):
60 '''
61 Creates an input dialog.
62 @param default_port: the default discovery port
63 @type default_port: C{int}
64 @param networks_count: the count of discovering ports
65 @type networks_count: C{int}
66 '''
67 QtGui.QDialog.__init__(self, parent=parent)
68 threading.Thread.__init__(self)
69 self.setObjectName('NetworkDiscoveryDialog')
70 self.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
71 self.setWindowFlags(QtCore.Qt.Window)
72 self.setWindowTitle('Network Discovery')
73 self.resize(728,512)
74 self.verticalLayout = QtGui.QVBoxLayout(self)
75 self.verticalLayout.setObjectName("verticalLayout")
76 self.verticalLayout.setContentsMargins(1, 1, 1, 1)
77
78 self.display = QtGui.QTextBrowser(self)
79 self.display.setReadOnly(True)
80 self.verticalLayout.addWidget(self.display);
81 self.display_clear_signal.connect(self.display.clear)
82 self.display_append_signal.connect(self.display.append)
83 self.display.anchorClicked.connect(self.on_anchorClicked)
84
85 self.status_label = QtGui.QLabel('0 messages', self)
86 self.verticalLayout.addWidget(self.status_label)
87 self.status_text_signal.connect(self.status_label.setText)
88
89 self._networks_count = networks_count
90 self.sockets = []
91 for p in range(networks_count):
92 msock = McastSocket(default_port+p, default_mcast_group)
93 self.sockets.append(msock)
94 msock.settimeout(self.TIMEOUT)
95 self._running = True
96
97 self._discovered = dict()
98
99 self._hosts = dict()
100
101 self.mutex = threading.RLock()
102
103 self.setDaemon(True)
104 self.start()
105
106
108 index = 0
109 self.parent().masterlist_service.refresh(self.parent().getMasteruri(), False)
110 while (not rospy.is_shutdown()) and self._running:
111 msg = None
112 address = None
113 status_text = ''.join(['listen on network: ', str(index), ' (', str(self._networks_count), ')'])
114 self.status_text_signal.emit(status_text)
115 with self.mutex:
116 while True:
117 try:
118 (msg, address) = self.sockets[index].recvfrom(1024)
119 hostname = None
120 force_update = False
121 if not address is None:
122 try:
123 hostname = self._hosts[address[0]]
124 except:
125 hostname = nm.nameres().hostname(str(address[0]))
126 if hostname is None or hostname == str(address[0]):
127 self.status_text_signal.emit(''.join(['resolve: ', str(address[0])]))
128 try:
129 (hostname, aliaslist, ipaddrlist) = socket.gethostbyaddr(str(address[0]))
130 nm.nameres().addInfo(None, hostname, hostname)
131 nm.nameres().addInfo(None, address[0], hostname)
132 except:
133 import traceback
134 print traceback.format_exc(1)
135 pass
136 self._hosts[address[0]] = hostname
137 if not msg is None:
138 try:
139 (version, msg_tuple) = Discoverer.msg2masterState(msg, address)
140 if not self._discovered.has_key(index):
141 self._discovered[index] = dict()
142 force_update = True
143 self._discovered[index][address] = (hostname, time.time())
144 except Exception, e:
145 import traceback
146 print traceback.format_exc(1)
147 pass
148 if force_update:
149 self._updateDisplay()
150 except socket.timeout:
151
152 break
153 except socket.error:
154 import traceback
155 rospy.logwarn("socket error: %s", traceback.format_exc(1))
156 break
157 except:
158 break
159 index += 1
160 if index >= len(self.sockets):
161 index = 0
162 self._updateDisplay()
163 self.parent().masterlist_service.refresh(self.parent().getMasteruri(), False)
164
166 self._running = False
167 with self.mutex:
168 for p in range(len(self.sockets)):
169 try:
170 self.sockets[p].close()
171 except:
172 pass
173 QtGui.QDialog.closeEvent(self, event)
174
176 self.display_clear_signal.emit()
177 text = '<div style="font-family:Fixedsys,Courier,monospace; padding:10px;">\n'
178 for index, addr_dict in self._discovered.items():
179 text = ''.join([text, 'Network <b>', str(index), '</b>: <a href="', str(index),'">join</a><dl>'])
180 for addr, (hostname, ts) in addr_dict.items():
181 text = ''.join([text, '<dt>', self._getTsStr(ts), ' <b><u>', str(hostname), '</u></b> ', str(addr), '</dt>\n'])
182 text = ''.join([text, '</dl><br>'])
183 text = ''.join([text, '</div>'])
184 self.display_append_signal.emit(text)
185
187 dt = datetime.fromtimestamp(timestamp)
188 diff = time.time()-timestamp
189 diff_dt = datetime.fromtimestamp(diff)
190 before = '0 sec'
191 if (diff < 60):
192 before = diff_dt.strftime('%S sec')
193 elif (diff < 3600):
194 before = diff_dt.strftime('%M:%S min')
195 elif (diff < 86400):
196 before = diff_dt.strftime('%H:%M:%S std')
197 else:
198 before = diff_dt.strftime('%d Day(s) %H:%M:%S')
199 return ''.join([dt.strftime('%H:%M:%S'), ' (', before, ')'])
200
202 self._updateDisplay()
203 try:
204 self.network_join_request.emit(int(url.toString()))
205 except:
206 import traceback
207 print traceback.format_exc(1)
208