quarchpy 2.2.17.dev1__py3-none-any.whl → 2.2.17.dev3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quarchpy/__init__.py +57 -49
- quarchpy/_version.py +1 -1
- quarchpy/connection_specific/connection_QIS.py +3 -8
- quarchpy/connection_specific/connection_QPS.py +116 -8
- quarchpy/connection_specific/connection_Telnet.py +19 -5
- quarchpy/connection_specific/jdk_jres/fix_permissions.py +0 -3
- quarchpy/connection_specific/usb_libs/libusb1.py +21 -0
- quarchpy/debug/SystemTest.py +65 -7
- quarchpy/debug/module_debug.py +11 -3
- quarchpy/device/device.py +93 -45
- quarchpy/device/scanDevices.py +55 -24
- quarchpy/qis/qisFuncs.py +236 -127
- quarchpy/qps/qpsFuncs.py +267 -171
- quarchpy/run.py +1 -1
- {quarchpy-2.2.17.dev1.dist-info → quarchpy-2.2.17.dev3.dist-info}/METADATA +5 -1
- {quarchpy-2.2.17.dev1.dist-info → quarchpy-2.2.17.dev3.dist-info}/RECORD +19 -18
- {quarchpy-2.2.17.dev1.dist-info → quarchpy-2.2.17.dev3.dist-info}/WHEEL +1 -1
- quarchpy-2.2.17.dev3.dist-info/licenses/LICENSE.txt +21 -0
- {quarchpy-2.2.17.dev1.dist-info → quarchpy-2.2.17.dev3.dist-info}/top_level.txt +0 -0
quarchpy/device/device.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from typing import Optional, Tuple, Any, Union # Added for type hinting in docstrings
|
|
3
3
|
import logging
|
|
4
|
-
logger = logging.getLogger(__name__)
|
|
5
4
|
import os
|
|
6
5
|
import re
|
|
7
6
|
import sys
|
|
@@ -9,8 +8,9 @@ import time
|
|
|
9
8
|
|
|
10
9
|
from quarchpy.qps import isQpsRunning
|
|
11
10
|
from quarchpy.qis import isQisRunning
|
|
12
|
-
|
|
13
11
|
from quarchpy.connection import QISConnection, PYConnection, QPSConnection
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
14
|
# Check Python version and set timeout exception
|
|
15
15
|
if sys.version_info.major == 2:
|
|
16
16
|
try:
|
|
@@ -23,6 +23,14 @@ if sys.version_info.major == 2:
|
|
|
23
23
|
else:
|
|
24
24
|
timeout_exception = TimeoutError # Python 3: Use built-in TimeoutError
|
|
25
25
|
|
|
26
|
+
class _InstanceWrapper:
|
|
27
|
+
"""Helper class to wrap external instances to match expected connectionObj structure."""
|
|
28
|
+
def __init__(self, interface_obj, mode: str):
|
|
29
|
+
if mode == "QPS":
|
|
30
|
+
self.qps = interface_obj
|
|
31
|
+
elif mode == "QIS":
|
|
32
|
+
self.qis = interface_obj
|
|
33
|
+
|
|
26
34
|
# --- Main Device Class ---
|
|
27
35
|
class quarchDevice:
|
|
28
36
|
"""
|
|
@@ -43,19 +51,26 @@ class quarchDevice:
|
|
|
43
51
|
connectionTypeName (Optional[str]): Alias for ConCommsType. Set for PY type.
|
|
44
52
|
"""
|
|
45
53
|
|
|
46
|
-
def __init__(self,
|
|
54
|
+
def __init__(self,
|
|
55
|
+
ConString: str,
|
|
56
|
+
ConType: str = "PY",
|
|
57
|
+
timeout: str = "5",
|
|
58
|
+
qps_instance: Optional['QpsInterface'] = None,
|
|
59
|
+
qis_instance: Optional['QisInterface'] = None):
|
|
47
60
|
"""
|
|
48
61
|
Initializes the quarchDevice, establishes the connection.
|
|
49
62
|
|
|
50
63
|
Performs initial parameter validation, determines the connection type,
|
|
51
64
|
delegates to specific helper methods to create the underlying connection
|
|
52
65
|
object (PYConnection, QISConnection, or QPSConnection), and verifies
|
|
53
|
-
the connection.
|
|
66
|
+
the connection. Supports injection of existing QIS/QPS instances.
|
|
54
67
|
|
|
55
68
|
Args:
|
|
56
69
|
ConString (str): The connection string (e.g., "USB:ID", "TCP:IP", "QIS:ID").
|
|
57
70
|
ConType (str, optional): The connection mode ('PY', 'QIS', 'QPS'). Defaults to "PY".
|
|
58
71
|
timeout (str, optional): Communication timeout in seconds. Defaults to "5".
|
|
72
|
+
qps_instance (Optional[QpsInterface], optional): An existing QPS instance to use. Defaults to None.
|
|
73
|
+
qis_instance (Optional[QisInterface], optional): An existing QIS instance to use. Defaults to None.
|
|
59
74
|
|
|
60
75
|
Raises:
|
|
61
76
|
ValueError: If ConString format is invalid or timeout is not numeric.
|
|
@@ -74,6 +89,12 @@ class quarchDevice:
|
|
|
74
89
|
self.timeout = 5 # Default int timeout
|
|
75
90
|
self.is_module_resetting = False
|
|
76
91
|
|
|
92
|
+
# Determine ConType based on provided instances
|
|
93
|
+
if qps_instance:
|
|
94
|
+
self.ConType = "QPS"
|
|
95
|
+
if qis_instance:
|
|
96
|
+
self.ConType = "QIS"
|
|
97
|
+
|
|
77
98
|
# Call helper to store and validate parameters
|
|
78
99
|
self._store_and_validate_params(ConString, ConType, timeout)
|
|
79
100
|
|
|
@@ -84,9 +105,9 @@ class quarchDevice:
|
|
|
84
105
|
if con_type_upper == "PY":
|
|
85
106
|
self._initialize_py_connection()
|
|
86
107
|
elif con_type_upper.startswith("QIS"):
|
|
87
|
-
self._initialize_qis_connection()
|
|
108
|
+
self._initialize_qis_connection(existing_instance=qis_instance)
|
|
88
109
|
elif con_type_upper.startswith("QPS"):
|
|
89
|
-
self._initialize_qps_connection()
|
|
110
|
+
self._initialize_qps_connection(existing_instance=qps_instance)
|
|
90
111
|
else:
|
|
91
112
|
# Invalid ConType should have been caught by check_module_format
|
|
92
113
|
raise ValueError(f"Invalid connection type '{self.ConType}'.")
|
|
@@ -401,7 +422,7 @@ class quarchDevice:
|
|
|
401
422
|
logger.warning(f"scanIP method not found on {server_type} connection object.")
|
|
402
423
|
return None # Cannot scan
|
|
403
424
|
|
|
404
|
-
scan_response = scan_method(target_ip) # Scan using the target IP
|
|
425
|
+
scan_response = scan_method(server_conn_obj, target_ip) # Scan using the target IP
|
|
405
426
|
if "located" not in str(scan_response).lower():
|
|
406
427
|
logger.debug(f"{server_type} scan for {target_ip} did not locate the device.")
|
|
407
428
|
return None # Scan didn't find it
|
|
@@ -442,13 +463,16 @@ class quarchDevice:
|
|
|
442
463
|
return True
|
|
443
464
|
return False
|
|
444
465
|
|
|
445
|
-
def _initialize_qis_connection(self):
|
|
466
|
+
def _initialize_qis_connection(self, existing_instance: Optional['QisInterface'] = None):
|
|
446
467
|
"""
|
|
447
468
|
Initializes the connection using the QIS method.
|
|
448
469
|
|
|
449
470
|
Parses host/port, prepares connection string, creates QISConnection object,
|
|
450
471
|
verifies the device presence on the server using the common helper, and
|
|
451
|
-
sets the device as default on the QIS server.
|
|
472
|
+
sets the device as default on the QIS server. Also supports injection of an existing QIS instance.
|
|
473
|
+
|
|
474
|
+
Args:
|
|
475
|
+
qis_instance (Optional[QisInterface], optional): An existing QIS instance to use. Defaults to None.
|
|
452
476
|
|
|
453
477
|
Sets:
|
|
454
478
|
self.connectionObj, self.ConString.
|
|
@@ -459,27 +483,33 @@ class quarchDevice:
|
|
|
459
483
|
ImportError: If QISConnection class is missing.
|
|
460
484
|
"""
|
|
461
485
|
logger.debug("Attempting QIS connection...")
|
|
462
|
-
host, port = self._parse_server_details(default_port=9722)
|
|
463
486
|
self._prepare_server_con_string()
|
|
464
487
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
488
|
+
if existing_instance:
|
|
489
|
+
# Extract details directly from the provided instance
|
|
490
|
+
host = getattr(existing_instance, 'host', 'unknown')
|
|
491
|
+
port = getattr(existing_instance, 'port', 'unknown')
|
|
492
|
+
|
|
493
|
+
# Wrap it to match self.connectionObj.qis structure
|
|
494
|
+
self.connectionObj = _InstanceWrapper(existing_instance, "QIS")
|
|
495
|
+
logger.debug(f"Using provided QIS instance for '{self.ConString}' at {host}:{port}")
|
|
496
|
+
else:
|
|
497
|
+
# Legacy creation
|
|
498
|
+
host, port = self._parse_server_details(default_port=9722)
|
|
499
|
+
try:
|
|
500
|
+
self.connectionObj = QISConnection(self.ConString, host, port)
|
|
501
|
+
logger.debug(f"QISConnection object created for '{self.ConString}' via {host}:{port}")
|
|
502
|
+
except Exception as e_qisconn:
|
|
503
|
+
raise ConnectionError("Failed to establish QIS connection.") from e_qisconn
|
|
504
|
+
|
|
505
|
+
# Verify device presence (uses the connection object we just set up)
|
|
475
506
|
try:
|
|
476
|
-
# Pass the QIS-specific sub-object (self.connectionObj.qis) to the helper
|
|
477
507
|
self._verify_server_device(self.connectionObj.qis, "QIS")
|
|
478
508
|
except TimeoutError as e_timeout:
|
|
479
|
-
self.close_connection()
|
|
480
|
-
raise e_timeout
|
|
509
|
+
self.close_connection()
|
|
510
|
+
raise e_timeout
|
|
481
511
|
except Exception as e_qis_conn:
|
|
482
|
-
self.close_connection()
|
|
512
|
+
self.close_connection()
|
|
483
513
|
raise ConnectionError(f"Failed QIS device verification: {e_qis_conn}") from e_qis_conn
|
|
484
514
|
|
|
485
515
|
# Set QIS default device
|
|
@@ -493,13 +523,18 @@ class quarchDevice:
|
|
|
493
523
|
logger.warning(f"QIS command '$default {self.ConString}' failed.")
|
|
494
524
|
except Exception as e_def:
|
|
495
525
|
logger.warning(f"Error setting QIS default device: {e_def}")
|
|
526
|
+
pass
|
|
496
527
|
|
|
497
|
-
def _initialize_qps_connection(self,
|
|
528
|
+
def _initialize_qps_connection(self, existing_instance: Optional['QpsInterface'] = None):
|
|
498
529
|
"""
|
|
499
530
|
Initializes the connection using the QPS method.
|
|
500
531
|
|
|
501
532
|
Parses host/port, prepares connection string, creates QPSConnection object,
|
|
502
533
|
and verifies the device presence on the server using the common helper.
|
|
534
|
+
Also supports injection of an existing QPS instance.
|
|
535
|
+
|
|
536
|
+
Args:
|
|
537
|
+
existing_instance (Optional[QpsInterface], optional): An existing QPS instance to use. Defaults to None.
|
|
503
538
|
|
|
504
539
|
Sets:
|
|
505
540
|
self.connectionObj, self.ConString (potentially updated).
|
|
@@ -510,29 +545,34 @@ class quarchDevice:
|
|
|
510
545
|
ImportError: If QPSConnection class is missing.
|
|
511
546
|
"""
|
|
512
547
|
logger.debug("Attempting QPS connection...")
|
|
513
|
-
|
|
514
|
-
self._prepare_server_con_string() # type: ignore[misc] # Private call ok
|
|
548
|
+
self._prepare_server_con_string()
|
|
515
549
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
550
|
+
if existing_instance:
|
|
551
|
+
# Extract details directly from the provided instance
|
|
552
|
+
host = getattr(existing_instance, 'host', 'unknown')
|
|
553
|
+
port = getattr(existing_instance, 'port', 'unknown')
|
|
554
|
+
|
|
555
|
+
# Wrap it to match self.connectionObj.qps structure
|
|
556
|
+
self.connectionObj = _InstanceWrapper(existing_instance, "QPS")
|
|
557
|
+
logger.debug(f"Using provided QPS instance for '{self.ConString}' at {host}:{port}")
|
|
558
|
+
else:
|
|
559
|
+
# Legacy creation
|
|
560
|
+
host, port = self._parse_server_details(default_port=9822)
|
|
561
|
+
try:
|
|
562
|
+
self.connectionObj = QPSConnection(host, port)
|
|
563
|
+
logger.debug(f"QPSConnection object created via {host}:{port}")
|
|
564
|
+
except Exception as e_qpsconn:
|
|
565
|
+
raise ConnectionError("Failed to establish QPS connection.") from e_qpsconn
|
|
566
|
+
|
|
567
|
+
# Verify device presence
|
|
526
568
|
try:
|
|
527
|
-
|
|
528
|
-
self._verify_server_device(self.connectionObj.qps, "QPS") # type: ignore[misc] # Private call ok
|
|
569
|
+
self._verify_server_device(self.connectionObj.qps, "QPS")
|
|
529
570
|
except TimeoutError as e_timeout:
|
|
530
|
-
self.close_connection()
|
|
531
|
-
raise e_timeout
|
|
571
|
+
self.close_connection()
|
|
572
|
+
raise e_timeout
|
|
532
573
|
except Exception as e_qps_conn:
|
|
533
|
-
self.close_connection()
|
|
574
|
+
self.close_connection()
|
|
534
575
|
raise ConnectionError(f"Failed QPS device verification: {e_qps_conn}") from e_qps_conn
|
|
535
|
-
# QPS typically doesn't use/need a '$default' command
|
|
536
576
|
|
|
537
577
|
def _verify_connection_object(self):
|
|
538
578
|
"""
|
|
@@ -1254,7 +1294,11 @@ def checkModuleFormat(ConString: str) -> bool:
|
|
|
1254
1294
|
|
|
1255
1295
|
|
|
1256
1296
|
# --- getQuarchDevice / get_quarch_device ---
|
|
1257
|
-
def get_quarch_device(connectionTarget: str,
|
|
1297
|
+
def get_quarch_device(connectionTarget: str,
|
|
1298
|
+
ConType: str = "PY",
|
|
1299
|
+
timeout: str = "5",
|
|
1300
|
+
qps_instance: Optional['QpsInterface'] = None,
|
|
1301
|
+
qis_instance: Optional['QisInterface'] = None) -> 'Union[quarchDevice, subDevice]':
|
|
1258
1302
|
"""
|
|
1259
1303
|
Creates and returns a quarchDevice or subDevice instance.
|
|
1260
1304
|
|
|
@@ -1271,6 +1315,10 @@ def get_quarch_device(connectionTarget: str, ConType: str = "PY", timeout: str =
|
|
|
1271
1315
|
currently defaults to "PY" internally based on original logic.
|
|
1272
1316
|
timeout (str, optional): The connection timeout in seconds as a string.
|
|
1273
1317
|
Defaults to "5".
|
|
1318
|
+
qps_instance (Optional[QpsInterface], optional): An optional QpsInterface instance
|
|
1319
|
+
to use for QPS connections. Defaults to None.
|
|
1320
|
+
qis_instance (Optional[QisInterface], optional): An optional QisInterface instance
|
|
1321
|
+
to use for QIS connections. Defaults to None.
|
|
1274
1322
|
|
|
1275
1323
|
Returns:
|
|
1276
1324
|
quarchDevice | subDevice | Any: An instance representing the connected device.
|
|
@@ -1328,7 +1376,7 @@ def get_quarch_device(connectionTarget: str, ConType: str = "PY", timeout: str =
|
|
|
1328
1376
|
# Standard device connection
|
|
1329
1377
|
logger.debug(f"Standard device connection for: {connectionTarget}")
|
|
1330
1378
|
# Use passed ConType and timeout
|
|
1331
|
-
myDevice = quarchDevice(connectionTarget, ConType=ConType, timeout=timeout)
|
|
1379
|
+
myDevice = quarchDevice(connectionTarget, ConType=ConType, timeout=timeout, qps_instance=qps_instance, qis_instance=qis_instance)
|
|
1332
1380
|
logger.info(f"Successfully connected to standard device: {connectionTarget}")
|
|
1333
1381
|
|
|
1334
1382
|
return myDevice
|
quarchpy/device/scanDevices.py
CHANGED
|
@@ -249,25 +249,40 @@ def list_network(target_conn="all", debugPrint=False, lanTimeout=1, ipAddressLoo
|
|
|
249
249
|
network_modules = {}
|
|
250
250
|
msg_received = None
|
|
251
251
|
counter += 1
|
|
252
|
-
|
|
252
|
+
|
|
253
253
|
try:
|
|
254
|
+
# recvfrom returns a tuple: (bytes_data, (address, port))
|
|
254
255
|
msg_received = mySocket.recvfrom(1024)
|
|
255
256
|
except Exception as e:
|
|
256
257
|
logger.debug(str(e))
|
|
257
|
-
# check if any a device was targeted directly and allow parse
|
|
258
258
|
if specifiedDevice is not None:
|
|
259
259
|
msg_received = specifiedDevice
|
|
260
260
|
specifiedDevice = None
|
|
261
261
|
else:
|
|
262
262
|
break
|
|
263
|
-
cont = 0
|
|
264
263
|
|
|
265
|
-
#
|
|
266
|
-
#
|
|
267
|
-
|
|
268
|
-
|
|
264
|
+
# --- ROBUST DATA EXTRACTION ---
|
|
265
|
+
# If msg_received is a tuple (data, addr), split them out
|
|
266
|
+
if isinstance(msg_received, tuple) and len(msg_received) >= 2:
|
|
267
|
+
raw_payload = msg_received[0]
|
|
268
|
+
addr_info = msg_received[1] # This is (ip, port)
|
|
269
|
+
else:
|
|
270
|
+
# Fallback if data is raw bytes or something else
|
|
271
|
+
raw_payload = msg_received
|
|
272
|
+
addr_info = ("0.0.0.0", 0)
|
|
273
|
+
|
|
274
|
+
# Ensure we have bytes to split
|
|
275
|
+
if isinstance(raw_payload, bytes):
|
|
276
|
+
splits = raw_payload.split(b"\r\n")
|
|
277
|
+
else:
|
|
278
|
+
continue # Skip this iteration if we don't have valid data
|
|
279
|
+
|
|
280
|
+
# Remove empty trailing element if it exists
|
|
281
|
+
if splits and splits[-1] == b"":
|
|
282
|
+
del splits[-1]
|
|
283
|
+
# ------------------------------
|
|
269
284
|
|
|
270
|
-
# Decode
|
|
285
|
+
# Decode and extend discovered_devices
|
|
271
286
|
if discovered_devices is not None:
|
|
272
287
|
idn_info = IDNInfo()
|
|
273
288
|
fix_idn_info = FixtureIDNInfo()
|
|
@@ -277,18 +292,23 @@ def list_network(target_conn="all", debugPrint=False, lanTimeout=1, ipAddressLoo
|
|
|
277
292
|
discovered_device.populate_device_info()
|
|
278
293
|
discovered_devices.append(discovered_device)
|
|
279
294
|
|
|
295
|
+
cont = 0
|
|
280
296
|
for lines in splits:
|
|
281
297
|
if cont <= 1:
|
|
282
298
|
index = cont
|
|
283
299
|
data = repr(lines).replace("'", "").replace("b", "")
|
|
284
300
|
cont += 1
|
|
285
301
|
else:
|
|
286
|
-
|
|
302
|
+
# lines[0] returns an int, so we use slicing lines[0:1] to keep it bytes
|
|
303
|
+
index = repr(lines[0:1]).replace("'", "").replace("b", "")
|
|
287
304
|
data = repr(lines[1:]).replace("'", "").replace("b", "")
|
|
288
305
|
network_modules[index] = data
|
|
306
|
+
|
|
289
307
|
module_name = get_user_level_serial_number(network_modules)
|
|
290
|
-
logger.debug("Found UDP response: " + module_name)
|
|
291
|
-
|
|
308
|
+
logger.debug("Found UDP response: " + str(module_name))
|
|
309
|
+
|
|
310
|
+
# FIXED: Safely get the IP from our extracted addr_info
|
|
311
|
+
ip_module = addr_info[0].strip() if isinstance(addr_info, (tuple, list)) else "Unknown"
|
|
292
312
|
try:
|
|
293
313
|
# Add a QTL before modules without it.
|
|
294
314
|
if "QTL" not in module_name.decode("utf-8"):
|
|
@@ -298,32 +318,43 @@ def list_network(target_conn="all", debugPrint=False, lanTimeout=1, ipAddressLoo
|
|
|
298
318
|
if "QTL" not in module_name:
|
|
299
319
|
module_name = "QTL" + module_name
|
|
300
320
|
|
|
321
|
+
# Helper to check if this module already exists in our list with a proper IP
|
|
322
|
+
def is_duplicate_ghost(name, current_modules, protocol):
|
|
323
|
+
if ip_module != "0.0.0.0":
|
|
324
|
+
return False
|
|
325
|
+
# Check if any existing entry for this protocol has the same module name
|
|
326
|
+
return any(m_name == name for key, m_name in current_modules.items() if key.startswith(protocol))
|
|
327
|
+
|
|
328
|
+
# Ensure module_name is a string for dictionary values and logging
|
|
329
|
+
if isinstance(module_name, bytes):
|
|
330
|
+
module_name = module_name.decode("utf-8", errors="ignore")
|
|
331
|
+
|
|
301
332
|
# Checks if there's a value in the TELNET key.
|
|
302
|
-
if target_conn.lower()
|
|
333
|
+
if target_conn.lower() in ["all", "telnet"]:
|
|
303
334
|
if network_modules.get("\\x8a") or network_modules.get("138"):
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
335
|
+
if not is_duplicate_ghost(module_name, lan_modules, "TELNET:"):
|
|
336
|
+
lan_modules[f"TELNET:{ip_module}"] = module_name
|
|
337
|
+
logger.debug(f"Found Telnet module: {module_name} at {ip_module}")
|
|
307
338
|
|
|
308
339
|
# Checks if there's a value in the REST key.
|
|
309
|
-
if target_conn.lower()
|
|
340
|
+
if target_conn.lower() in ["all", "rest"]:
|
|
310
341
|
if network_modules.get("\\x84") or network_modules.get("132"):
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
342
|
+
if not is_duplicate_ghost(module_name, lan_modules, "REST:"):
|
|
343
|
+
lan_modules[f"REST:{ip_module}"] = module_name
|
|
344
|
+
logger.debug(f"Found REST module: {module_name} at {ip_module}")
|
|
314
345
|
|
|
315
346
|
# Checks if there's a value in the TCP key.
|
|
316
|
-
if target_conn.lower()
|
|
347
|
+
if target_conn.lower() in ["all", "tcp"]:
|
|
317
348
|
if network_modules.get("\\x85") or network_modules.get("133"):
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
349
|
+
if not is_duplicate_ghost(module_name, lan_modules, "TCP:"):
|
|
350
|
+
lan_modules[f"TCP:{ip_module}"] = module_name
|
|
351
|
+
logger.debug(f"Found TCP module: {module_name} at {ip_module}")
|
|
321
352
|
mySocket.close()
|
|
322
353
|
if ipAddressLookup is not None:
|
|
323
354
|
if moduleFound is None:
|
|
324
355
|
printText("IP Scan failed, no module found.")
|
|
325
356
|
else:
|
|
326
|
-
printText("IP Scan succeeded, module found: " + moduleFound)
|
|
357
|
+
printText("IP Scan succeeded, module found: " + str(moduleFound))
|
|
327
358
|
logger.debug("Finished UDP scan")
|
|
328
359
|
retVal.update(lan_modules)
|
|
329
360
|
return retVal
|