21 # You should have received a copy of the GNU General Public License |
21 # You should have received a copy of the GNU General Public License |
22 # along with this program; if not, write to the Free Software |
22 # along with this program; if not, write to the Free Software |
23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
24 |
24 |
25 |
25 |
26 |
|
27 |
|
28 import traceback |
26 import traceback |
29 from time import sleep |
27 from time import sleep |
30 import copy |
28 import copy |
31 import socket |
29 import socket |
32 import os.path |
30 import os.path |
33 |
31 |
34 import Pyro |
32 import Pyro5 |
35 import Pyro.core |
33 import Pyro5.client |
36 import Pyro.util |
34 import Pyro5.errors |
37 from Pyro.errors import PyroError |
|
38 |
35 |
39 import PSKManagement as PSK |
36 # TODO: PSK |
40 from connectors.PYRO.PSK_Adapter import setupPSKAdapter |
37 |
41 from runtime import PlcStatus |
38 from runtime import PlcStatus |
42 import importlib |
39 import importlib |
43 |
40 |
44 |
41 |
45 def switch_pyro_adapter(use_ssl): |
42 Pyro5.config.SERPENT_BYTES_REPR = True |
46 """ |
|
47 Reloads Pyro module with new settings. |
|
48 This is workaround for Pyro, because it doesn't work with SSL wrapper. |
|
49 """ |
|
50 # Pyro.config.PYRO_BROKEN_MSGWAITALL = use_ssl |
|
51 importlib.reload(Pyro.protocol) |
|
52 if use_ssl: |
|
53 setupPSKAdapter() |
|
54 |
|
55 |
43 |
56 def PYRO_connector_factory(uri, confnodesroot): |
44 def PYRO_connector_factory(uri, confnodesroot): |
57 """ |
45 """ |
58 This returns the connector to Pyro style PLCobject |
46 This returns the connector to Pyro style PLCobject |
59 """ |
47 """ |
60 confnodesroot.logger.write(_("PYRO connecting to URI : %s\n") % uri) |
48 confnodesroot.logger.write(_("PYRO connecting to URI : %s\n") % uri) |
61 |
49 |
62 scheme, location = uri.split("://") |
50 scheme, location = uri.split("://") |
63 use_ssl = scheme == "PYROS" |
51 |
64 switch_pyro_adapter(use_ssl) |
52 # TODO: use ssl |
65 if use_ssl: |
53 |
66 schemename = "PYROLOCPSK" |
54 schemename = "PYRO" |
67 url, ID = location.split('#') # TODO fix exception when # not found |
|
68 # load PSK from project |
|
69 secpath = os.path.join(str(confnodesroot.ProjectPath), 'psk', ID+'.secret') |
|
70 if not os.path.exists(secpath): |
|
71 confnodesroot.logger.write_error( |
|
72 'Error: Pre-Shared-Key Secret in %s is missing!\n' % secpath) |
|
73 return None |
|
74 secret = open(secpath).read().partition(':')[2].rstrip('\n\r') |
|
75 Pyro.config.PYROPSK = (secret, ID) |
|
76 # strip ID from URL, so that pyro can understand it. |
|
77 location = url |
|
78 else: |
|
79 schemename = "PYROLOC" |
|
80 |
55 |
81 # Try to get the proxy object |
56 # Try to get the proxy object |
82 try: |
57 try: |
83 RemotePLCObjectProxy = Pyro.core.getAttrProxyForURI(schemename + "://" + location + "/PLCObject") |
58 RemotePLCObjectProxy = Pyro5.client.Proxy(f"{schemename}:PLCObject@{location}") |
84 except Exception as e: |
59 except Exception as e: |
85 confnodesroot.logger.write_error( |
60 confnodesroot.logger.write_error( |
86 _("Connection to {loc} failed with exception {ex}\n").format( |
61 _("Connection to {loc} failed with exception {ex}\n").format( |
87 loc=location, ex=str(e))) |
62 loc=location, ex=str(e))) |
88 return None |
63 return None |
89 |
64 |
90 RemotePLCObjectProxy.adapter.setTimeout(60) |
65 RemotePLCObjectProxy._pyroTimeout = 60 |
91 |
66 |
92 def PyroCatcher(func, default=None): |
67 def PyroCatcher(func, default=None): |
93 """ |
68 """ |
94 A function that catch a Pyro exceptions, write error to logger |
69 A function that catch a Pyro exceptions, write error to logger |
95 and return default value when it happen |
70 and return default value when it happen |
96 """ |
71 """ |
97 def catcher_func(*args, **kwargs): |
72 def catcher_func(*args, **kwargs): |
98 try: |
73 try: |
99 return func(*args, **kwargs) |
74 return func(*args, **kwargs) |
100 except Pyro.errors.ConnectionClosedError as e: |
75 except Pyro5.errors.ConnectionClosedError as e: |
101 confnodesroot._SetConnector(None) |
76 confnodesroot._SetConnector(None) |
102 confnodesroot.logger.write_error(_("Connection lost!\n")) |
77 confnodesroot.logger.write_error(_("Connection lost!\n")) |
103 except Pyro.errors.ProtocolError as e: |
78 except Pyro5.errors.ProtocolError as e: |
104 confnodesroot.logger.write_error(_("Pyro exception: %s\n") % e) |
79 confnodesroot.logger.write_error(_("Pyro exception: %s\n") % e) |
105 except Exception as e: |
80 except Exception as e: |
106 # confnodesroot.logger.write_error(traceback.format_exc()) |
81 # confnodesroot.logger.write_error(traceback.format_exc()) |
107 errmess = ''.join(Pyro.util.getPyroTraceback(e)) |
82 errmess = ''.join(Pyro5.errors.get_pyro_traceback(e)) |
108 confnodesroot.logger.write_error(errmess + "\n") |
83 confnodesroot.logger.write_error(errmess + "\n") |
109 print(errmess) |
84 print(errmess) |
110 confnodesroot._SetConnector(None) |
85 confnodesroot._SetConnector(None) |
111 return default |
86 return default |
112 return catcher_func |
87 return catcher_func |