9
9
from binascii import hexlify
10
10
from logging import getLogger
11
11
from select import POLLIN , poll as spoll
12
- from socket import (create_connection , socket , IPPROTO_TCP , TCP_NODELAY ,
13
- SHUT_RDWR , timeout as LegacyTimeoutError )
12
+ from socket import (AF_UNIX , IPPROTO_TCP , TCP_NODELAY , SHUT_RDWR , SOCK_STREAM ,
13
+ create_connection , socket , timeout as LegacyTimeoutError )
14
14
from struct import calcsize as scalc , pack as spack
15
15
from time import sleep , time as now
16
16
from typing import NamedTuple , Optional , Union
@@ -34,6 +34,10 @@ class SpiDevice:
34
34
"""Default allowed timeout to complete an exchange with the remote target.
35
35
"""
36
36
37
+ CONN_TIMEOUT = 1.0
38
+ """Maximum time to connect to the remote peer.
39
+ """
40
+
37
41
POLL_TIMEOUT = 0.05
38
42
"""Maximum time to wait on a blocking operation.
39
43
"""
@@ -88,22 +92,46 @@ def __init__(self):
88
92
self ._rev_rx = False
89
93
self ._rev_tx = False
90
94
91
- def connect (self , host : str , port : int ) -> None :
92
- """Open a TCP connection to the remote host.
95
+ def connect (self , host : str , port : Optional [ int ] = None ) -> None :
96
+ """Open a connection to the remote host.
93
97
94
- @param host the host name
95
- @paran port the TCP port
98
+ @param host the host name or the connection string
99
+ @param port the TCP port
96
100
"""
97
101
if self ._socket :
98
102
raise RuntimeError ('Cannot open multiple comm port at once' )
99
- try :
100
- self ._socket = create_connection ((host , port ), timeout = self .TIMEOUT )
101
- except OSError :
102
- self ._log .fatal ('Cannot connect to %s:%d' , host , port )
103
- raise
104
- # use poll
105
- self ._socket .settimeout (None )
106
- self ._socket .setsockopt (IPPROTO_TCP , TCP_NODELAY , 1 )
103
+ if port is not None :
104
+ try :
105
+ self ._socket = create_connection ((host , port ),
106
+ timeout = self .CONN_TIMEOUT )
107
+ self ._socket .setsockopt (IPPROTO_TCP , TCP_NODELAY , 1 )
108
+ except OSError :
109
+ self ._log .fatal ('Cannot connect to %s:%d' , host , port )
110
+ raise
111
+ else :
112
+ sock_args = host .split (':' )
113
+ try :
114
+ if sock_args [0 ] == 'tcp' :
115
+ try :
116
+ host , port = sock_args [1 :]
117
+ except ValueError as exc :
118
+ raise ValueError ('TCP port not specified' ) from exc
119
+ self ._socket = create_connection ((host , int (port )),
120
+ timeout = self .TIMEOUT )
121
+ self ._socket .setsockopt (IPPROTO_TCP , TCP_NODELAY , 1 )
122
+ elif sock_args [0 ] == 'unix' :
123
+ self ._socket = socket (AF_UNIX , SOCK_STREAM )
124
+ self ._socket .settimeout (self .CONN_TIMEOUT )
125
+ self ._socket .connect (sock_args [1 ])
126
+ else :
127
+ raise ValueError (f'Unsupported connection string: { host } ' )
128
+ except OSError :
129
+ if port :
130
+ self ._log .fatal ('Cannot connect to %s:%d' , host , port )
131
+ else :
132
+ self ._log .fatal ('Cannot connect to %s' , host )
133
+ raise
134
+ self ._socket .settimeout (None ) # use poll
107
135
108
136
def disconnect (self ) -> None :
109
137
"""Close the communication socket."""
0 commit comments