Skip to content

Commit abc33e0

Browse files
committed
complete TCP UDP support
1 parent 2bebeb6 commit abc33e0

File tree

6 files changed

+99
-43
lines changed

6 files changed

+99
-43
lines changed

COMTool/Main.py

Lines changed: 79 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ def loadConfig():
2828
from i18n import _
2929
import version
3030
import utils_ui
31-
from conn import Serial, ConnectionStatus
31+
from conn import Serial, ConnectionStatus, TCP_UDP
3232
from plugins import plugins
3333
from widgets import TitleBar, CustomTitleBarWindowMixin, EventFilter
3434
except ImportError:
3535
from COMTool import helpAbout,autoUpdate, utils_ui
3636
from COMTool.Combobox import ComboBox
3737
from COMTool.i18n import _
3838
from COMTool import version
39-
from COMTool.conn import Serial, ConnectionStatus
39+
from COMTool.conn import Serial, ConnectionStatus, TCP_UDP
4040
from COMTool.plugins import plugins
4141
from .widgets import TitleBar, CustomTitleBarWindowMixin, EventFilter
4242

@@ -75,21 +75,35 @@ def __init__(self,app, eventFilter, config):
7575
self.DataPath = parameters.dataPath
7676
self.config = config
7777
self.initVar()
78-
self.initConn(self.config.basic["connId"], self.config.conns)
7978
self.initPlugins(self.config.basic["plugins"], self.config.basic["activePlugin"], self.config.plugins)
8079
self.initWindow()
80+
self.initConn(self.config.basic["connId"], self.config.conns)
8181
self.uiLoadConfigs(self.config)
8282
self.initEvent()
8383
self.uiInitDone()
8484

85-
def __del__(self):
86-
pass
85+
def initVar(self):
86+
self.strings = parameters.Strings(self.config.basic["locale"])
87+
self.dataToSend = []
88+
self.fileToSend = []
89+
self.connSelectComboboxes = []
90+
self.changingConn = False
91+
self.connectionWidget = None
8792

8893
def initConn(self, connId, configs):
8994
# get all conn info
90-
self.connections = [Serial()]
95+
self.connections = [Serial(), TCP_UDP()]
96+
# add conn select combobox
97+
self.changingConn = True
98+
for i, conn in enumerate(self.connections):
99+
for combobox in self.connSelectComboboxes:
100+
combobox.addItem(conn.name)
101+
if conn.id == connId:
102+
combobox.setCurrentIndex(i)
103+
self.changingConn = False
91104
# init connections
92-
for conn in self.connections:
105+
activeConn = self.connections[0]
106+
for i, conn in enumerate(self.connections):
93107
conn.onReceived = self.onReceived
94108
conn.configGlobal = self.config.basic
95109
conn.hintSignal.connect(self.showHint)
@@ -100,14 +114,11 @@ def initConn(self, connId, configs):
100114
else: # add new dict obj for conn to use
101115
configs[conn.id] = config
102116
conn.onInit(config)
103-
# init last used one
104-
self.connection = None
105-
for conn in self.connections:
117+
conn.onWidget()
106118
if conn.id == connId:
107-
self.connection = conn
108-
if not self.connection:
109-
self.connection = self.connections[0]
110-
119+
activeConn = conn
120+
# init last used one
121+
self.changeConn(activeConn)
111122

112123
def initPlugins(self, enabled, activeId, configs):
113124
if not enabled:
@@ -117,6 +128,7 @@ def initPlugins(self, enabled, activeId, configs):
117128
for plugin in self.plugins:
118129
plugin.hintSignal = self.hintSignal
119130
plugin.send = self.sendData
131+
plugin.isConnected = self.isConnected
120132
plugin.clearCountSignal = self.clearCountSignal
121133
plugin.reloadWindowSignal = self.reloadWindowSignal
122134
plugin.configGlobal = self.config.basic
@@ -145,29 +157,22 @@ def activePlugin(self, plugin):
145157
plugin.active = True
146158
parent = None
147159
if (not "main" in plugin.connParent) and plugin.connParent:
148-
plugin.isConnected = self.connection.isConnected
149160
for pluginParent in self.plugins:
150161
if pluginParent.id == plugin.connParent:
151162
pluginParent.active = True
152-
pluginParent.isConnected = self.connection.isConnected
153163
pluginParent.send = self.sendData
154164
if not plugin in pluginParent.connChilds:
155165
pluginParent.connChilds.append(plugin)
156166
parent = pluginParent
157167
break
158168
plugin.send = parent.sendData
159169
if not parent:
160-
plugin.isConnected = self.connection.isConnected
161170
plugin.send = self.sendData
162171
self.config.basic["activePlugin"] = plugin.id
163172

164-
def initVar(self):
165-
self.strings = parameters.Strings(self.config.basic["locale"])
166-
self.dataToSend = []
167-
self.fileToSend = []
168-
169173
def uiInitDone(self):
170-
self.connection.onUiInitDone()
174+
for conn in self.connections:
175+
conn.onUiInitDone()
171176
for plugin in self.plugins:
172177
plugin.onUiInitDone()
173178
# always hide functional, and show before init complete so we can get its width height
@@ -231,11 +236,21 @@ def addTabPanel(tabWidget, name, plugin, connectionWidget = None):
231236
settingLayout = QVBoxLayout()
232237
settingWidget.setLayout(settingLayout)
233238
# connection settings
239+
connSelectCommbox = ComboBox()
240+
self.connSelectComboboxes.append(connSelectCommbox)
241+
connSelectCommbox.currentIndexChanged.connect(self.onConnChanged)
234242
connSettingsGroupBox = QGroupBox(_("Connection"))
235243
layout = QVBoxLayout()
236244
connSettingsGroupBox.setLayout(layout)
245+
layout.addWidget(connSelectCommbox)
246+
layout.setContentsMargins(1, 6, 0, 0)
247+
connectionWidgetWrapper = QWidget()
248+
layout2 = QVBoxLayout()
249+
layout2.setContentsMargins(0, 0, 0, 0)
250+
connectionWidgetWrapper.setLayout(layout2)
251+
layout.addWidget(connectionWidgetWrapper)
237252
if connectionWidget:
238-
layout.addWidget(connectionWidget)
253+
layout2.addWidget(connectionWidget)
239254
settingLayout.addWidget(connSettingsGroupBox)
240255
# other settings
241256
widget = plugin.onWidgetSettings(settingLayout)
@@ -250,7 +265,7 @@ def addTabPanel(tabWidget, name, plugin, connectionWidget = None):
250265
contentWidget.setStretchFactor(0, 1)
251266
contentWidget.setStretchFactor(1, 2)
252267
contentWidget.setStretchFactor(2, 1)
253-
return contentWidget, connSettingsGroupBox
268+
return contentWidget, connectionWidgetWrapper
254269
self.tabWidget = QTabWidget()
255270
# self.contentLayout.setSpacing(0)
256271
# self.contentLayout.setContentsMargins(0,0,0,0)
@@ -278,17 +293,13 @@ def addTabPanel(tabWidget, name, plugin, connectionWidget = None):
278293
self.contentLayout.addWidget(self.tabWidget)
279294
# get widgets from plugins
280295
# widget main
281-
self.connectionWidget = self.connection.onWidget()
282296
self.tabWidgets = []
283297
self.connParentWidgets = []
284298
for i, plugin in enumerate(self.plugins):
285299
active = False
286300
if plugin.id == self.config.basic["activePlugin"]:
287301
active = True
288-
conn = self.connectionWidget
289-
else:
290-
conn = None
291-
w, connParent = addTabPanel(self.tabWidget, plugin.name, plugin, conn)
302+
w, connParent = addTabPanel(self.tabWidget, plugin.name, plugin, None)
292303
self.tabWidgets.append(w)
293304
self.connParentWidgets.append(connParent)
294305
if active:
@@ -395,16 +406,49 @@ def bindVar(self, uiObj, varObj, varName: str, vtype=None, vErrorMsg="", checkVa
395406

396407
def changeConnToTab(self, idx):
397408
print("-- switch to tab", idx)
409+
# remove from old container
398410
parent = self.connectionWidget.parentWidget()
399-
if parent.layout().indexOf(self.connectionWidget) >= 0:
400-
parent.layout().removeWidget(self.connectionWidget)
411+
parent.layout().removeWidget(self.connectionWidget)
412+
# add to new container
401413
newParent = self.connParentWidgets[idx]
402414
newParent.layout().addWidget(self.connectionWidget)
403415
self.updateStyle(parent)
404416
self.updateStyle(newParent)
405417
self.activePlugin(self.plugins[idx])
406418

407-
def sendData(self, data_bytes=None, file_path=None, callback=lambda ok,msg:None):
419+
def changeConn(self, connection:object):
420+
# remove conn widget from the container
421+
parent = None
422+
if self.connectionWidget:
423+
parent = self.connectionWidget.parentWidget()
424+
parent.layout().removeWidget(self.connectionWidget)
425+
self.connectionWidget.setParent(None)
426+
self.updateStyle(parent)
427+
# add new conn widget to container
428+
self.connection = connection
429+
self.connectionWidget = connection.widget
430+
if not parent:
431+
parent = self.connParentWidgets[self.tabWidget.currentIndex()]
432+
parent.layout().addWidget(self.connectionWidget)
433+
self.updateStyle(parent)
434+
435+
def onConnChanged(self, idx):
436+
'''
437+
combobox changed item
438+
'''
439+
if self.changingConn:
440+
return
441+
self.changingConn = True
442+
# update all tab's connSelectCombobox widget show
443+
for w in self.connSelectComboboxes:
444+
w.setCurrentIndex(idx)
445+
# change connection
446+
print("-- change conn to", self.connections[idx].id)
447+
self.changeConn(self.connections[idx])
448+
self.config.basic["connId"] = self.connections[idx].id
449+
self.changingConn = False
450+
451+
def sendData(self, data_bytes=None, file_path=None, callback=lambda ok, msg:None):
408452
if data_bytes:
409453
self.dataToSend.insert(0, (data_bytes, callback))
410454
if file_path:
@@ -422,6 +466,8 @@ def onReceived(self, data):
422466
if plugin.active:
423467
plugin.onReceived(data)
424468

469+
def isConnected(self):
470+
return self.connection.isConnected()
425471

426472
def sendDataProcess(self):
427473
self.receiveProgressStop = False

COMTool/conn/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from .base import ConnectionStatus
22
from .conn_serial import Serial
3-
3+
from .conn_tcp_udp import TCP_UDP
44

COMTool/conn/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ class COMM(QObject):
2525
hintSignal = pyqtSignal(str, str, str) # hintSignal.emit(type(error, warning, info), title, msg)
2626
configGlobal = {}
2727
id = ""
28+
name = ""
2829

2930
def __init__(self) -> None:
3031
super().__init__()
31-
if not self.id:
32+
if (not self.id) or not self.name:
3233
raise ValueError(f"var id of {self} should be set")
3334

3435
def onInit(self, config):

COMTool/conn/conn_serial.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class Serial(COMM):
3838
getConfig
3939
'''
4040
id = "serial"
41+
name = _("Serial")
4142
showSerialComboboxSignal = pyqtSignal(list)
4243
showSwitchSignal = pyqtSignal(ConnectionStatus)
4344
def onInit(self, config):
@@ -93,7 +94,7 @@ def onUiInitDone(self):
9394
self.detectSerialPort()
9495

9596
def onWidget(self):
96-
serialSetting = QWidget()
97+
self.widget = QWidget()
9798
serialSettingsLayout = QGridLayout()
9899
serialPortLabek = QLabel(_("Port"))
99100
serailBaudrateLabel = QLabel(_("Baudrate"))
@@ -152,7 +153,7 @@ def onWidget(self):
152153
serialSettingsLayout.addWidget(self.checkBoxRTS, 6, 0,1,1)
153154
serialSettingsLayout.addWidget(self.checkBoxDTR, 6, 1,1,1)
154155
serialSettingsLayout.addWidget(self.serialOpenCloseButton, 7, 0,1,2)
155-
serialSetting.setLayout(serialSettingsLayout)
156+
self.widget.setLayout(serialSettingsLayout)
156157
self.widgetConfMap["port"] = self.serialPortCombobox
157158
self.widgetConfMap["baudrate"] = self.serailBaudrateCombobox
158159
self.widgetConfMap["bytesize"] = self.serailBytesCombobox
@@ -162,8 +163,7 @@ def onWidget(self):
162163
self.widgetConfMap["rts"] = self.checkBoxRTS
163164
self.widgetConfMap["dtr"] = self.checkBoxDTR
164165
self.initEvet()
165-
self.widget = serialSetting
166-
return serialSetting
166+
return self.widget
167167

168168
def initEvet(self):
169169
self.serialPortCombobox.clicked.connect(self.detectSerialPort)

COMTool/conn/conn_tcp_udp.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class TCP_UDP(COMM):
3838
getConfig
3939
'''
4040
id = "tcp_udp"
41+
name = "TCP UDP"
4142
showSwitchSignal = pyqtSignal(ConnectionStatus)
4243
updateTargetSignal = pyqtSignal(str)
4344
updateClientsSignal = pyqtSignal(bool, tuple)
@@ -286,6 +287,7 @@ def setSerialConfig(self, conf_type, obj, value):
286287
self.changeMode("client", init=True)
287288
else:
288289
obj.setChecked(False)
290+
self.modeServerRadioBtn.setChecked(True)
289291
self.changeMode("server", init=True)
290292
elif conf_type == "target":
291293
for i, target in enumerate(self.config["target"][1]):
@@ -454,6 +456,10 @@ def receiveDataProcess(self, conn, remote_addr:tuple = None):
454456
t = 0
455457
conn.settimeout(0.1)
456458
protocolIsTcp = self.config["protocol"] == "tcp"
459+
modeIsServer = self.config["mode"] == "server"
460+
remoteStr = ""
461+
if remote_addr:
462+
remoteStr = f'{remote_addr[0]}:{remote_addr[1]}'
457463
while self.status != ConnectionStatus.CLOSED:
458464
if waitingReconnect:
459465
try:
@@ -478,6 +484,9 @@ def receiveDataProcess(self, conn, remote_addr:tuple = None):
478484
try:
479485
if protocolIsTcp:
480486
data = conn.recv(4096)
487+
# ignore not selected target's msg
488+
if modeIsServer and self.serverModeSelectedClient and (remoteStr != self.serverModeSelectedClient):
489+
data = None
481490
else:
482491
data, target = conn.recvfrom(4096)
483492
if data == b'': # closed by peer(peer send FIN, now we can close this connection)
@@ -500,9 +509,9 @@ def receiveDataProcess(self, conn, remote_addr:tuple = None):
500509
buffer = b''
501510
except Exception as e:
502511
print("-- recv error:", e, type(e))
503-
if not self.config["auto_reconnect"]:
512+
if modeIsServer or not self.config["auto_reconnect"]:
504513
over = False
505-
if self.config["protocol"] == "tcp" and self.config["mode"] == "server":
514+
if protocolIsTcp and modeIsServer:
506515
self.onConnectionStatus.emit(ConnectionStatus.CLOSED, _("Connection") + f' {remote_addr[0]}:{remote_addr[1]} ' + _("closed!"))
507516
over = True
508517
else:

COMTool/version.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
major = 2
3-
minor = 3
4-
dev = 2
3+
minor = 4
4+
dev = 0
55

66
__version__ = "{}.{}.{}".format(major, minor, dev)
77

0 commit comments

Comments
 (0)