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 while (not rospy.is_shutdown()) and self._running:
110 msg = None
111 address = None
112 status_text = ''.join(['listen on network: ', str(index), ' (', str(self._networks_count), ')'])
113 self.status_text_signal.emit(status_text)
114 with self.mutex:
115 while True:
116 try:
117 (msg, address) = self.sockets[index].recvfrom(1024)
118 hostname = None
119 force_update = False
120 if not address is None:
121 try:
122 hostname = self._hosts[address[0]]
123 except:
124 hostname = nm.nameres().hostname(str(address[0]))
125 if hostname is None or hostname == str(address[0]):
126 self.status_text_signal.emit(''.join(['resolve: ', str(address[0])]))
127 try:
128 (hostname, aliaslist, ipaddrlist) = socket.gethostbyaddr(str(address[0]))
129 nm.nameres().addInfo(None, hostname, hostname)
130 nm.nameres().addInfo(None, address[0], hostname)
131 except:
132 import traceback
133 print traceback.format_exc()
134 pass
135 self._hosts[address[0]] = hostname
136 if not msg is None:
137 try:
138 (version, msg_tuple) = Discoverer.msg2masterState(msg, address)
139 if not self._discovered.has_key(index):
140 self._discovered[index] = dict()
141 force_update = True
142 self._discovered[index][address] = (hostname, time.time())
143 except Exception, e:
144 import traceback
145 print traceback.format_exc()
146 pass
147 if force_update:
148 self._updateDisplay()
149 except socket.timeout:
150
151 break
152 except socket.error:
153 import traceback
154 rospy.logwarn("socket error: %s", traceback.format_exc())
155 break
156 except:
157 break
158 index += 1
159 if index >= len(self.sockets):
160 index = 0
161 self._updateDisplay()
162
164 self._running = False
165 with self.mutex:
166 for p in range(len(self.sockets)):
167 try:
168 self.sockets[p].close()
169 except:
170 pass
171 QtGui.QDialog.closeEvent(self, event)
172
174 self.display_clear_signal.emit()
175 text = '<div style="font-family:Fixedsys,Courier,monospace; padding:10px;">\n'
176 for index, addr_dict in self._discovered.items():
177 text = ''.join([text, 'Network <b>', str(index), '</b>: <a href="', str(index),'">join</a><dl>'])
178 for addr, (hostname, ts) in addr_dict.items():
179 text = ''.join([text, '<dt>', self._getTsStr(ts), ' <b><u>', str(hostname), '</u></b> ', str(addr), '</dt>\n'])
180 text = ''.join([text, '</dl><br>'])
181 text = ''.join([text, '</div>'])
182 self.display_append_signal.emit(text)
183
185 dt = datetime.fromtimestamp(timestamp)
186 diff = time.time()-timestamp
187 diff_dt = datetime.fromtimestamp(diff)
188 before = '0 sec'
189 if (diff < 60):
190 before = diff_dt.strftime('%S sec')
191 elif (diff < 3600):
192 before = diff_dt.strftime('%M:%S min')
193 elif (diff < 86400):
194 before = diff_dt.strftime('%H:%M:%S std')
195 else:
196 before = diff_dt.strftime('%d Day(s) %H:%M:%S')
197 return ''.join([dt.strftime('%H:%M:%S'), ' (', before, ')'])
198
200 self._updateDisplay()
201 try:
202 self.network_join_request.emit(int(url.toString()))
203 except:
204 import traceback
205 print traceback.format_exc()
206