Coverage for /usr/lib/python3/dist-packages/serial/serialposix.py: 36%

451 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-03-28 13:34 +0000

1#!/usr/bin/env python 

2# 

3# backend for serial IO for POSIX compatible systems, like Linux, OSX 

4# 

5# This file is part of pySerial. https://github.com/pyserial/pyserial 

6# (C) 2001-2016 Chris Liechti <cliechti@gmx.net> 

7# 

8# SPDX-License-Identifier: BSD-3-Clause 

9# 

10# parts based on code from Grant B. Edwards <grante@visi.com>: 

11# ftp://ftp.visi.com/users/grante/python/PosixSerial.py 

12# 

13# references: http://www.easysw.com/~mike/serial/serial.html 

14 

15# Collection of port names (was previously used by number_to_device which was 

16# removed. 

17# - Linux /dev/ttyS%d (confirmed) 

18# - cygwin/win32 /dev/com%d (confirmed) 

19# - openbsd (OpenBSD) /dev/cua%02d 

20# - bsd*, freebsd* /dev/cuad%d 

21# - darwin (OS X) /dev/cuad%d 

22# - netbsd /dev/dty%02d (NetBSD 1.6 testing by Erk) 

23# - irix (IRIX) /dev/ttyf%d (partially tested) names depending on flow control 

24# - hp (HP-UX) /dev/tty%dp0 (not tested) 

25# - sunos (Solaris/SunOS) /dev/tty%c (letters, 'a'..'z') (confirmed) 

26# - aix (AIX) /dev/tty%d 

27 

28 

29# pylint: disable=abstract-method 

30import errno 

31import fcntl 

32import os 

33import select 

34import struct 

35import sys 

36import termios 

37 

38import serial 

39from serial.serialutil import SerialBase, SerialException, to_bytes, \ 

40 portNotOpenError, writeTimeoutError, Timeout 

41 

42 

43class PlatformSpecificBase(object): 

44 BAUDRATE_CONSTANTS = {} 

45 

46 def _set_special_baudrate(self, baudrate): 

47 raise NotImplementedError('non-standard baudrates are not supported on this platform') 

48 

49 def _set_rs485_mode(self, rs485_settings): 

50 raise NotImplementedError('RS485 not supported on this platform') 

51 

52 

53# some systems support an extra flag to enable the two in POSIX unsupported 

54# paritiy settings for MARK and SPACE 

55CMSPAR = 0 # default, for unsupported platforms, override below 

56 

57# try to detect the OS so that a device can be selected... 

58# this code block should supply a device() and set_special_baudrate() function 

59# for the platform 

60plat = sys.platform.lower() 

61 

62if plat[:5] == 'linux': # Linux (confirmed) # noqa 62 ↛ 161line 62 didn't jump to line 161, because the condition on line 62 was never false

63 import array 

64 

65 # extra termios flags 

66 CMSPAR = 0o10000000000 # Use "stick" (mark/space) parity 

67 

68 # baudrate ioctls 

69 TCGETS2 = 0x802C542A 

70 TCSETS2 = 0x402C542B 

71 BOTHER = 0o010000 

72 

73 # RS485 ioctls 

74 TIOCGRS485 = 0x542E 

75 TIOCSRS485 = 0x542F 

76 SER_RS485_ENABLED = 0b00000001 

77 SER_RS485_RTS_ON_SEND = 0b00000010 

78 SER_RS485_RTS_AFTER_SEND = 0b00000100 

79 SER_RS485_RX_DURING_TX = 0b00010000 

80 

81 class PlatformSpecific(PlatformSpecificBase): 

82 BAUDRATE_CONSTANTS = { 

83 0: 0o000000, # hang up 

84 50: 0o000001, 

85 75: 0o000002, 

86 110: 0o000003, 

87 134: 0o000004, 

88 150: 0o000005, 

89 200: 0o000006, 

90 300: 0o000007, 

91 600: 0o000010, 

92 1200: 0o000011, 

93 1800: 0o000012, 

94 2400: 0o000013, 

95 4800: 0o000014, 

96 9600: 0o000015, 

97 19200: 0o000016, 

98 38400: 0o000017, 

99 57600: 0o010001, 

100 115200: 0o010002, 

101 230400: 0o010003, 

102 460800: 0o010004, 

103 500000: 0o010005, 

104 576000: 0o010006, 

105 921600: 0o010007, 

106 1000000: 0o010010, 

107 1152000: 0o010011, 

108 1500000: 0o010012, 

109 2000000: 0o010013, 

110 2500000: 0o010014, 

111 3000000: 0o010015, 

112 3500000: 0o010016, 

113 4000000: 0o010017 

114 } 

115 

116 def _set_special_baudrate(self, baudrate): 

117 # right size is 44 on x86_64, allow for some growth 

118 buf = array.array('i', [0] * 64) 

119 try: 

120 # get serial_struct 

121 fcntl.ioctl(self.fd, TCGETS2, buf) 

122 # set custom speed 

123 buf[2] &= ~termios.CBAUD 

124 buf[2] |= BOTHER 

125 buf[9] = buf[10] = baudrate 

126 

127 # set serial_struct 

128 fcntl.ioctl(self.fd, TCSETS2, buf) 

129 except IOError as e: 

130 raise ValueError('Failed to set custom baud rate ({}): {}'.format(baudrate, e)) 

131 

132 def _set_rs485_mode(self, rs485_settings): 

133 buf = array.array('i', [0] * 8) # flags, delaytx, delayrx, padding 

134 try: 

135 fcntl.ioctl(self.fd, TIOCGRS485, buf) 

136 buf[0] |= SER_RS485_ENABLED 

137 if rs485_settings is not None: 

138 if rs485_settings.loopback: 

139 buf[0] |= SER_RS485_RX_DURING_TX 

140 else: 

141 buf[0] &= ~SER_RS485_RX_DURING_TX 

142 if rs485_settings.rts_level_for_tx: 

143 buf[0] |= SER_RS485_RTS_ON_SEND 

144 else: 

145 buf[0] &= ~SER_RS485_RTS_ON_SEND 

146 if rs485_settings.rts_level_for_rx: 

147 buf[0] |= SER_RS485_RTS_AFTER_SEND 

148 else: 

149 buf[0] &= ~SER_RS485_RTS_AFTER_SEND 

150 if rs485_settings.delay_before_tx is not None: 

151 buf[1] = int(rs485_settings.delay_before_tx * 1000) 

152 if rs485_settings.delay_before_rx is not None: 

153 buf[2] = int(rs485_settings.delay_before_rx * 1000) 

154 else: 

155 buf[0] = 0 # clear SER_RS485_ENABLED 

156 fcntl.ioctl(self.fd, TIOCSRS485, buf) 

157 except IOError as e: 

158 raise ValueError('Failed to set RS485 mode: {}'.format(e)) 

159 

160 

161elif plat == 'cygwin': # cygwin/win32 (confirmed) 

162 

163 class PlatformSpecific(PlatformSpecificBase): 

164 BAUDRATE_CONSTANTS = { 

165 128000: 0x01003, 

166 256000: 0x01005, 

167 500000: 0x01007, 

168 576000: 0x01008, 

169 921600: 0x01009, 

170 1000000: 0x0100a, 

171 1152000: 0x0100b, 

172 1500000: 0x0100c, 

173 2000000: 0x0100d, 

174 2500000: 0x0100e, 

175 3000000: 0x0100f 

176 } 

177 

178 

179elif plat[:6] == 'darwin': # OS X 

180 import array 

181 IOSSIOSPEED = 0x80045402 # _IOW('T', 2, speed_t) 

182 

183 class PlatformSpecific(PlatformSpecificBase): 

184 osx_version = os.uname()[2].split('.') 

185 # Tiger or above can support arbitrary serial speeds 

186 if int(osx_version[0]) >= 8: 

187 def _set_special_baudrate(self, baudrate): 

188 # use IOKit-specific call to set up high speeds 

189 buf = array.array('i', [baudrate]) 

190 fcntl.ioctl(self.fd, IOSSIOSPEED, buf, 1) 

191 

192elif plat[:3] == 'bsd' or \ 

193 plat[:7] == 'freebsd' or \ 

194 plat[:6] == 'netbsd' or \ 

195 plat[:7] == 'openbsd': 

196 

197 class ReturnBaudrate(object): 

198 def __getitem__(self, key): 

199 return key 

200 

201 class PlatformSpecific(PlatformSpecificBase): 

202 # Only tested on FreeBSD: 

203 # The baud rate may be passed in as 

204 # a literal value. 

205 BAUDRATE_CONSTANTS = ReturnBaudrate() 

206 

207else: 

208 class PlatformSpecific(PlatformSpecificBase): 

209 pass 

210 

211 

212# load some constants for later use. 

213# try to use values from termios, use defaults from linux otherwise 

214TIOCMGET = getattr(termios, 'TIOCMGET', 0x5415) 

215TIOCMBIS = getattr(termios, 'TIOCMBIS', 0x5416) 

216TIOCMBIC = getattr(termios, 'TIOCMBIC', 0x5417) 

217TIOCMSET = getattr(termios, 'TIOCMSET', 0x5418) 

218 

219# TIOCM_LE = getattr(termios, 'TIOCM_LE', 0x001) 

220TIOCM_DTR = getattr(termios, 'TIOCM_DTR', 0x002) 

221TIOCM_RTS = getattr(termios, 'TIOCM_RTS', 0x004) 

222# TIOCM_ST = getattr(termios, 'TIOCM_ST', 0x008) 

223# TIOCM_SR = getattr(termios, 'TIOCM_SR', 0x010) 

224 

225TIOCM_CTS = getattr(termios, 'TIOCM_CTS', 0x020) 

226TIOCM_CAR = getattr(termios, 'TIOCM_CAR', 0x040) 

227TIOCM_RNG = getattr(termios, 'TIOCM_RNG', 0x080) 

228TIOCM_DSR = getattr(termios, 'TIOCM_DSR', 0x100) 

229TIOCM_CD = getattr(termios, 'TIOCM_CD', TIOCM_CAR) 

230TIOCM_RI = getattr(termios, 'TIOCM_RI', TIOCM_RNG) 

231# TIOCM_OUT1 = getattr(termios, 'TIOCM_OUT1', 0x2000) 

232# TIOCM_OUT2 = getattr(termios, 'TIOCM_OUT2', 0x4000) 

233if hasattr(termios, 'TIOCINQ'): 233 ↛ 236line 233 didn't jump to line 236, because the condition on line 233 was never false

234 TIOCINQ = termios.TIOCINQ 

235else: 

236 TIOCINQ = getattr(termios, 'FIONREAD', 0x541B) 

237TIOCOUTQ = getattr(termios, 'TIOCOUTQ', 0x5411) 

238 

239TIOCM_zero_str = struct.pack('I', 0) 

240TIOCM_RTS_str = struct.pack('I', TIOCM_RTS) 

241TIOCM_DTR_str = struct.pack('I', TIOCM_DTR) 

242 

243TIOCSBRK = getattr(termios, 'TIOCSBRK', 0x5427) 

244TIOCCBRK = getattr(termios, 'TIOCCBRK', 0x5428) 

245 

246 

247class Serial(SerialBase, PlatformSpecific): 

248 """\ 

249 Serial port class POSIX implementation. Serial port configuration is 

250 done with termios and fcntl. Runs on Linux and many other Un*x like 

251 systems. 

252 """ 

253 

254 def open(self): 

255 """\ 

256 Open port with current settings. This may throw a SerialException 

257 if the port cannot be opened.""" 

258 if self._port is None: 258 ↛ 259line 258 didn't jump to line 259, because the condition on line 258 was never true

259 raise SerialException("Port must be configured before it can be used.") 

260 if self.is_open: 260 ↛ 261line 260 didn't jump to line 261, because the condition on line 260 was never true

261 raise SerialException("Port is already open.") 

262 self.fd = None 

263 # open 

264 try: 

265 self.fd = os.open(self.portstr, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) 

266 except OSError as msg: 

267 self.fd = None 

268 raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg)) 

269 #~ fcntl.fcntl(self.fd, fcntl.F_SETFL, 0) # set blocking 

270 

271 try: 

272 self._reconfigure_port(force_update=True) 

273 except: 

274 try: 

275 os.close(self.fd) 

276 except: 

277 # ignore any exception when closing the port 

278 # also to keep original exception that happened when setting up 

279 pass 

280 self.fd = None 

281 raise 

282 else: 

283 self.is_open = True 

284 try: 

285 if not self._dsrdtr: 285 ↛ 287line 285 didn't jump to line 287, because the condition on line 285 was never false

286 self._update_dtr_state() 

287 if not self._rtscts: 287 ↛ 295line 287 didn't jump to line 295, because the condition on line 287 was never false

288 self._update_rts_state() 

289 except IOError as e: 

290 if e.errno in (errno.EINVAL, errno.ENOTTY): 

291 # ignore Invalid argument and Inappropriate ioctl 

292 pass 

293 else: 

294 raise 

295 self.reset_input_buffer() 

296 self.pipe_abort_read_r, self.pipe_abort_read_w = os.pipe() 

297 self.pipe_abort_write_r, self.pipe_abort_write_w = os.pipe() 

298 fcntl.fcntl(self.pipe_abort_read_r, fcntl.F_SETFL, os.O_NONBLOCK) 

299 fcntl.fcntl(self.pipe_abort_write_r, fcntl.F_SETFL, os.O_NONBLOCK) 

300 

301 def _reconfigure_port(self, force_update=False): 

302 """Set communication parameters on opened port.""" 

303 if self.fd is None: 303 ↛ 304line 303 didn't jump to line 304, because the condition on line 303 was never true

304 raise SerialException("Can only operate on a valid file descriptor") 

305 

306 # if exclusive lock is requested, create it before we modify anything else 

307 if self._exclusive is not None: 307 ↛ 308line 307 didn't jump to line 308, because the condition on line 307 was never true

308 if self._exclusive: 

309 try: 

310 fcntl.flock(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB) 

311 except IOError as msg: 

312 raise SerialException(msg.errno, "Could not exclusively lock port {}: {}".format(self._port, msg)) 

313 else: 

314 fcntl.flock(self.fd, fcntl.LOCK_UN) 

315 

316 custom_baud = None 

317 

318 vmin = vtime = 0 # timeout is done via select 

319 if self._inter_byte_timeout is not None: 319 ↛ 320line 319 didn't jump to line 320, because the condition on line 319 was never true

320 vmin = 1 

321 vtime = int(self._inter_byte_timeout * 10) 

322 try: 

323 orig_attr = termios.tcgetattr(self.fd) 

324 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr 

325 except termios.error as msg: # if a port is nonexistent but has a /dev file, it'll fail here 

326 raise SerialException("Could not configure port: {}".format(msg)) 

327 # set up raw mode / no echo / binary 

328 cflag |= (termios.CLOCAL | termios.CREAD) 

329 lflag &= ~(termios.ICANON | termios.ECHO | termios.ECHOE | 

330 termios.ECHOK | termios.ECHONL | 

331 termios.ISIG | termios.IEXTEN) # |termios.ECHOPRT 

332 for flag in ('ECHOCTL', 'ECHOKE'): # netbsd workaround for Erk 

333 if hasattr(termios, flag): 333 ↛ 332line 333 didn't jump to line 332, because the condition on line 333 was never false

334 lflag &= ~getattr(termios, flag) 

335 

336 oflag &= ~(termios.OPOST | termios.ONLCR | termios.OCRNL) 

337 iflag &= ~(termios.INLCR | termios.IGNCR | termios.ICRNL | termios.IGNBRK) 

338 if hasattr(termios, 'IUCLC'): 338 ↛ 340line 338 didn't jump to line 340, because the condition on line 338 was never false

339 iflag &= ~termios.IUCLC 

340 if hasattr(termios, 'PARMRK'): 340 ↛ 344line 340 didn't jump to line 344, because the condition on line 340 was never false

341 iflag &= ~termios.PARMRK 

342 

343 # setup baud rate 

344 try: 

345 ispeed = ospeed = getattr(termios, 'B{}'.format(self._baudrate)) 

346 except AttributeError: 

347 try: 

348 ispeed = ospeed = self.BAUDRATE_CONSTANTS[self._baudrate] 

349 except KeyError: 

350 #~ raise ValueError('Invalid baud rate: %r' % self._baudrate) 

351 # may need custom baud rate, it isn't in our list. 

352 ispeed = ospeed = getattr(termios, 'B38400') 

353 try: 

354 custom_baud = int(self._baudrate) # store for later 

355 except ValueError: 

356 raise ValueError('Invalid baud rate: {!r}'.format(self._baudrate)) 

357 else: 

358 if custom_baud < 0: 

359 raise ValueError('Invalid baud rate: {!r}'.format(self._baudrate)) 

360 

361 # setup char len 

362 cflag &= ~termios.CSIZE 

363 if self._bytesize == 8: 363 ↛ 365line 363 didn't jump to line 365, because the condition on line 363 was never false

364 cflag |= termios.CS8 

365 elif self._bytesize == 7: 

366 cflag |= termios.CS7 

367 elif self._bytesize == 6: 

368 cflag |= termios.CS6 

369 elif self._bytesize == 5: 

370 cflag |= termios.CS5 

371 else: 

372 raise ValueError('Invalid char len: {!r}'.format(self._bytesize)) 

373 # setup stop bits 

374 if self._stopbits == serial.STOPBITS_ONE: 374 ↛ 376line 374 didn't jump to line 376, because the condition on line 374 was never false

375 cflag &= ~(termios.CSTOPB) 

376 elif self._stopbits == serial.STOPBITS_ONE_POINT_FIVE: 

377 cflag |= (termios.CSTOPB) # XXX same as TWO.. there is no POSIX support for 1.5 

378 elif self._stopbits == serial.STOPBITS_TWO: 

379 cflag |= (termios.CSTOPB) 

380 else: 

381 raise ValueError('Invalid stop bit specification: {!r}'.format(self._stopbits)) 

382 # setup parity 

383 iflag &= ~(termios.INPCK | termios.ISTRIP) 

384 if self._parity == serial.PARITY_NONE: 384 ↛ 386line 384 didn't jump to line 386, because the condition on line 384 was never false

385 cflag &= ~(termios.PARENB | termios.PARODD | CMSPAR) 

386 elif self._parity == serial.PARITY_EVEN: 

387 cflag &= ~(termios.PARODD | CMSPAR) 

388 cflag |= (termios.PARENB) 

389 elif self._parity == serial.PARITY_ODD: 

390 cflag &= ~CMSPAR 

391 cflag |= (termios.PARENB | termios.PARODD) 

392 elif self._parity == serial.PARITY_MARK and CMSPAR: 

393 cflag |= (termios.PARENB | CMSPAR | termios.PARODD) 

394 elif self._parity == serial.PARITY_SPACE and CMSPAR: 

395 cflag |= (termios.PARENB | CMSPAR) 

396 cflag &= ~(termios.PARODD) 

397 else: 

398 raise ValueError('Invalid parity: {!r}'.format(self._parity)) 

399 # setup flow control 

400 # xonxoff 

401 if hasattr(termios, 'IXANY'): 401 ↛ 407line 401 didn't jump to line 407, because the condition on line 401 was never false

402 if self._xonxoff: 402 ↛ 403line 402 didn't jump to line 403, because the condition on line 402 was never true

403 iflag |= (termios.IXON | termios.IXOFF) # |termios.IXANY) 

404 else: 

405 iflag &= ~(termios.IXON | termios.IXOFF | termios.IXANY) 

406 else: 

407 if self._xonxoff: 

408 iflag |= (termios.IXON | termios.IXOFF) 

409 else: 

410 iflag &= ~(termios.IXON | termios.IXOFF) 

411 # rtscts 

412 if hasattr(termios, 'CRTSCTS'): 412 ↛ 417line 412 didn't jump to line 417, because the condition on line 412 was never false

413 if self._rtscts: 413 ↛ 414line 413 didn't jump to line 414, because the condition on line 413 was never true

414 cflag |= (termios.CRTSCTS) 

415 else: 

416 cflag &= ~(termios.CRTSCTS) 

417 elif hasattr(termios, 'CNEW_RTSCTS'): # try it with alternate constant name 

418 if self._rtscts: 

419 cflag |= (termios.CNEW_RTSCTS) 

420 else: 

421 cflag &= ~(termios.CNEW_RTSCTS) 

422 # XXX should there be a warning if setting up rtscts (and xonxoff etc) fails?? 

423 

424 # buffer 

425 # vmin "minimal number of characters to be read. 0 for non blocking" 

426 if vmin < 0 or vmin > 255: 426 ↛ 427line 426 didn't jump to line 427, because the condition on line 426 was never true

427 raise ValueError('Invalid vmin: {!r}'.format(vmin)) 

428 cc[termios.VMIN] = vmin 

429 # vtime 

430 if vtime < 0 or vtime > 255: 430 ↛ 431line 430 didn't jump to line 431, because the condition on line 430 was never true

431 raise ValueError('Invalid vtime: {!r}'.format(vtime)) 

432 cc[termios.VTIME] = vtime 

433 # activate settings 

434 if force_update or [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] != orig_attr: 434 ↛ 441line 434 didn't jump to line 441, because the condition on line 434 was never false

435 termios.tcsetattr( 

436 self.fd, 

437 termios.TCSANOW, 

438 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]) 

439 

440 # apply custom baud rate, if any 

441 if custom_baud is not None: 441 ↛ 442line 441 didn't jump to line 442, because the condition on line 441 was never true

442 self._set_special_baudrate(custom_baud) 

443 

444 if self._rs485_mode is not None: 444 ↛ 445line 444 didn't jump to line 445, because the condition on line 444 was never true

445 self._set_rs485_mode(self._rs485_mode) 

446 

447 def close(self): 

448 """Close port""" 

449 if self.is_open: 449 ↛ exitline 449 didn't return from function 'close', because the condition on line 449 was never false

450 if self.fd is not None: 450 ↛ 459line 450 didn't jump to line 459, because the condition on line 450 was never false

451 os.close(self.fd) 

452 self.fd = None 

453 os.close(self.pipe_abort_read_w) 

454 os.close(self.pipe_abort_read_r) 

455 os.close(self.pipe_abort_write_w) 

456 os.close(self.pipe_abort_write_r) 

457 self.pipe_abort_read_r, self.pipe_abort_read_w = None, None 

458 self.pipe_abort_write_r, self.pipe_abort_write_w = None, None 

459 self.is_open = False 

460 

461 # - - - - - - - - - - - - - - - - - - - - - - - - 

462 

463 @property 

464 def in_waiting(self): 

465 """Return the number of bytes currently in the input buffer.""" 

466 #~ s = fcntl.ioctl(self.fd, termios.FIONREAD, TIOCM_zero_str) 

467 s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str) 

468 return struct.unpack('I', s)[0] 

469 

470 # select based implementation, proved to work on many systems 

471 def read(self, size=1): 

472 """\ 

473 Read size bytes from the serial port. If a timeout is set it may 

474 return less characters as requested. With no timeout it will block 

475 until the requested number of bytes is read. 

476 """ 

477 if not self.is_open: 477 ↛ 478line 477 didn't jump to line 478, because the condition on line 477 was never true

478 raise portNotOpenError 

479 read = bytearray() 

480 timeout = Timeout(self._timeout) 

481 while len(read) < size: 481 ↛ 518line 481 didn't jump to line 518, because the condition on line 481 was never false

482 try: 

483 ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left()) 

484 if self.pipe_abort_read_r in ready: 484 ↛ 485line 484 didn't jump to line 485, because the condition on line 484 was never true

485 os.read(self.pipe_abort_read_r, 1000) 

486 break 

487 # If select was used with a timeout, and the timeout occurs, it 

488 # returns with empty lists -> thus abort read operation. 

489 # For timeout == 0 (non-blocking operation) also abort when 

490 # there is nothing to read. 

491 if not ready: 491 ↛ 492line 491 didn't jump to line 492, because the condition on line 491 was never true

492 break # timeout 

493 buf = os.read(self.fd, size - len(read)) 

494 # read should always return some data as select reported it was 

495 # ready to read when we get to this point. 

496 if not buf: 496 ↛ 500line 496 didn't jump to line 500, because the condition on line 496 was never true

497 # Disconnected devices, at least on Linux, show the 

498 # behavior that they are always ready to read immediately 

499 # but reading returns nothing. 

500 raise SerialException( 

501 'device reports readiness to read but returned no data ' 

502 '(device disconnected or multiple access on port?)') 

503 read.extend(buf) 

504 except OSError as e: 

505 # this is for Python 3.x where select.error is a subclass of 

506 # OSError ignore BlockingIOErrors and EINTR. other errors are shown 

507 # https://www.python.org/dev/peps/pep-0475. 

508 if e.errno not in (errno.EAGAIN, errno.EALREADY, errno.EWOULDBLOCK, errno.EINPROGRESS, errno.EINTR): 

509 raise SerialException('read failed: {}'.format(e)) 

510 except select.error as e: 

511 # this is for Python 2.x 

512 # ignore BlockingIOErrors and EINTR. all errors are shown 

513 # see also http://www.python.org/dev/peps/pep-3151/#select 

514 if e[0] not in (errno.EAGAIN, errno.EALREADY, errno.EWOULDBLOCK, errno.EINPROGRESS, errno.EINTR): 

515 raise SerialException('read failed: {}'.format(e)) 

516 if timeout.expired(): 516 ↛ 481line 516 didn't jump to line 481, because the condition on line 516 was never false

517 break 

518 return bytes(read) 

519 

520 def cancel_read(self): 

521 if self.is_open: 

522 os.write(self.pipe_abort_read_w, b"x") 

523 

524 def cancel_write(self): 

525 if self.is_open: 

526 os.write(self.pipe_abort_write_w, b"x") 

527 

528 def write(self, data): 

529 """Output the given byte string over the serial port.""" 

530 if not self.is_open: 530 ↛ 531line 530 didn't jump to line 531, because the condition on line 530 was never true

531 raise portNotOpenError 

532 d = to_bytes(data) 

533 tx_len = length = len(d) 

534 timeout = Timeout(self._write_timeout) 

535 while tx_len > 0: 

536 try: 

537 n = os.write(self.fd, d) 

538 if timeout.is_non_blocking: 538 ↛ 541line 538 didn't jump to line 541, because the condition on line 538 was never true

539 # Zero timeout indicates non-blocking - simply return the 

540 # number of bytes of data actually written 

541 return n 

542 elif not timeout.is_infinite: 542 ↛ 545line 542 didn't jump to line 545, because the condition on line 542 was never true

543 # when timeout is set, use select to wait for being ready 

544 # with the time left as timeout 

545 if timeout.expired(): 

546 raise writeTimeoutError 

547 abort, ready, _ = select.select([self.pipe_abort_write_r], [self.fd], [], timeout.time_left()) 

548 if abort: 

549 os.read(self.pipe_abort_write_r, 1000) 

550 break 

551 if not ready: 

552 raise writeTimeoutError 

553 else: 

554 assert timeout.time_left() is None 

555 # wait for write operation 

556 abort, ready, _ = select.select([self.pipe_abort_write_r], [self.fd], [], None) 

557 if abort: 557 ↛ 558line 557 didn't jump to line 558, because the condition on line 557 was never true

558 os.read(self.pipe_abort_write_r, 1) 

559 break 

560 if not ready: 560 ↛ 561line 560 didn't jump to line 561, because the condition on line 560 was never true

561 raise SerialException('write failed (select)') 

562 d = d[n:] 

563 tx_len -= n 

564 except SerialException: 

565 raise 

566 except OSError as e: 

567 # this is for Python 3.x where select.error is a subclass of 

568 # OSError ignore BlockingIOErrors and EINTR. other errors are shown 

569 # https://www.python.org/dev/peps/pep-0475. 

570 if e.errno not in (errno.EAGAIN, errno.EALREADY, errno.EWOULDBLOCK, errno.EINPROGRESS, errno.EINTR): 

571 raise SerialException('write failed: {}'.format(e)) 

572 except select.error as e: 

573 # this is for Python 2.x 

574 # ignore BlockingIOErrors and EINTR. all errors are shown 

575 # see also http://www.python.org/dev/peps/pep-3151/#select 

576 if e[0] not in (errno.EAGAIN, errno.EALREADY, errno.EWOULDBLOCK, errno.EINPROGRESS, errno.EINTR): 

577 raise SerialException('write failed: {}'.format(e)) 

578 if not timeout.is_non_blocking and timeout.expired(): 578 ↛ 579line 578 didn't jump to line 579, because the condition on line 578 was never true

579 raise writeTimeoutError 

580 return length - len(d) 

581 

582 def flush(self): 

583 """\ 

584 Flush of file like objects. In this case, wait until all data 

585 is written. 

586 """ 

587 if not self.is_open: 

588 raise portNotOpenError 

589 termios.tcdrain(self.fd) 

590 

591 def reset_input_buffer(self): 

592 """Clear input buffer, discarding all that is in the buffer.""" 

593 if not self.is_open: 593 ↛ 594line 593 didn't jump to line 594, because the condition on line 593 was never true

594 raise portNotOpenError 

595 termios.tcflush(self.fd, termios.TCIFLUSH) 

596 

597 def reset_output_buffer(self): 

598 """\ 

599 Clear output buffer, aborting the current output and discarding all 

600 that is in the buffer. 

601 """ 

602 if not self.is_open: 602 ↛ 603line 602 didn't jump to line 603, because the condition on line 602 was never true

603 raise portNotOpenError 

604 termios.tcflush(self.fd, termios.TCOFLUSH) 

605 

606 def send_break(self, duration=0.25): 

607 """\ 

608 Send break condition. Timed, returns to idle state after given 

609 duration. 

610 """ 

611 if not self.is_open: 

612 raise portNotOpenError 

613 termios.tcsendbreak(self.fd, int(duration / 0.25)) 

614 

615 def _update_break_state(self): 

616 """\ 

617 Set break: Controls TXD. When active, no transmitting is possible. 

618 """ 

619 if self._break_state: 

620 fcntl.ioctl(self.fd, TIOCSBRK) 

621 else: 

622 fcntl.ioctl(self.fd, TIOCCBRK) 

623 

624 def _update_rts_state(self): 

625 """Set terminal status line: Request To Send""" 

626 if self._rts_state: 626 ↛ 629line 626 didn't jump to line 629, because the condition on line 626 was never false

627 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_RTS_str) 

628 else: 

629 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_RTS_str) 

630 

631 def _update_dtr_state(self): 

632 """Set terminal status line: Data Terminal Ready""" 

633 if self._dtr_state: 633 ↛ 636line 633 didn't jump to line 636, because the condition on line 633 was never false

634 fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str) 

635 else: 

636 fcntl.ioctl(self.fd, TIOCMBIC, TIOCM_DTR_str) 

637 

638 @property 

639 def cts(self): 

640 """Read terminal status line: Clear To Send""" 

641 if not self.is_open: 

642 raise portNotOpenError 

643 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) 

644 return struct.unpack('I', s)[0] & TIOCM_CTS != 0 

645 

646 @property 

647 def dsr(self): 

648 """Read terminal status line: Data Set Ready""" 

649 if not self.is_open: 

650 raise portNotOpenError 

651 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) 

652 return struct.unpack('I', s)[0] & TIOCM_DSR != 0 

653 

654 @property 

655 def ri(self): 

656 """Read terminal status line: Ring Indicator""" 

657 if not self.is_open: 

658 raise portNotOpenError 

659 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) 

660 return struct.unpack('I', s)[0] & TIOCM_RI != 0 

661 

662 @property 

663 def cd(self): 

664 """Read terminal status line: Carrier Detect""" 

665 if not self.is_open: 

666 raise portNotOpenError 

667 s = fcntl.ioctl(self.fd, TIOCMGET, TIOCM_zero_str) 

668 return struct.unpack('I', s)[0] & TIOCM_CD != 0 

669 

670 # - - platform specific - - - - 

671 

672 @property 

673 def out_waiting(self): 

674 """Return the number of bytes currently in the output buffer.""" 

675 #~ s = fcntl.ioctl(self.fd, termios.FIONREAD, TIOCM_zero_str) 

676 s = fcntl.ioctl(self.fd, TIOCOUTQ, TIOCM_zero_str) 

677 return struct.unpack('I', s)[0] 

678 

679 def fileno(self): 

680 """\ 

681 For easier use of the serial port instance with select. 

682 WARNING: this function is not portable to different platforms! 

683 """ 

684 if not self.is_open: 

685 raise portNotOpenError 

686 return self.fd 

687 

688 def set_input_flow_control(self, enable=True): 

689 """\ 

690 Manually control flow - when software flow control is enabled. 

691 This will send XON (true) or XOFF (false) to the other device. 

692 WARNING: this function is not portable to different platforms! 

693 """ 

694 if not self.is_open: 

695 raise portNotOpenError 

696 if enable: 

697 termios.tcflow(self.fd, termios.TCION) 

698 else: 

699 termios.tcflow(self.fd, termios.TCIOFF) 

700 

701 def set_output_flow_control(self, enable=True): 

702 """\ 

703 Manually control flow of outgoing data - when hardware or software flow 

704 control is enabled. 

705 WARNING: this function is not portable to different platforms! 

706 """ 

707 if not self.is_open: 

708 raise portNotOpenError 

709 if enable: 

710 termios.tcflow(self.fd, termios.TCOON) 

711 else: 

712 termios.tcflow(self.fd, termios.TCOOFF) 

713 

714 def nonblocking(self): 

715 """DEPRECATED - has no use""" 

716 import warnings 

717 warnings.warn("nonblocking() has no effect, already nonblocking", DeprecationWarning) 

718 

719 

720class PosixPollSerial(Serial): 

721 """\ 

722 Poll based read implementation. Not all systems support poll properly. 

723 However this one has better handling of errors, such as a device 

724 disconnecting while it's in use (e.g. USB-serial unplugged). 

725 """ 

726 

727 def read(self, size=1): 

728 """\ 

729 Read size bytes from the serial port. If a timeout is set it may 

730 return less characters as requested. With no timeout it will block 

731 until the requested number of bytes is read. 

732 """ 

733 if not self.is_open: 

734 raise portNotOpenError 

735 read = bytearray() 

736 poll = select.poll() 

737 poll.register(self.fd, select.POLLIN | select.POLLERR | select.POLLHUP | select.POLLNVAL) 

738 if size > 0: 

739 while len(read) < size: 

740 # print "\tread(): size",size, "have", len(read) #debug 

741 # wait until device becomes ready to read (or something fails) 

742 for fd, event in poll.poll(self._timeout * 1000): 

743 if event & (select.POLLERR | select.POLLHUP | select.POLLNVAL): 

744 raise SerialException('device reports error (poll)') 

745 # we don't care if it is select.POLLIN or timeout, that's 

746 # handled below 

747 buf = os.read(self.fd, size - len(read)) 

748 read.extend(buf) 

749 if ((self._timeout is not None and self._timeout >= 0) or 

750 (self._inter_byte_timeout is not None and self._inter_byte_timeout > 0)) and not buf: 

751 break # early abort on timeout 

752 return bytes(read) 

753 

754 

755class VTIMESerial(Serial): 

756 """\ 

757 Implement timeout using vtime of tty device instead of using select. 

758 This means that no inter character timeout can be specified and that 

759 the error handling is degraded. 

760 

761 Overall timeout is disabled when inter-character timeout is used. 

762 """ 

763 

764 def _reconfigure_port(self, force_update=True): 

765 """Set communication parameters on opened port.""" 

766 super(VTIMESerial, self)._reconfigure_port() 

767 fcntl.fcntl(self.fd, fcntl.F_SETFL, 0) # clear O_NONBLOCK 

768 

769 if self._inter_byte_timeout is not None: 

770 vmin = 1 

771 vtime = int(self._inter_byte_timeout * 10) 

772 elif self._timeout is None: 

773 vmin = 1 

774 vtime = 0 

775 else: 

776 vmin = 0 

777 vtime = int(self._timeout * 10) 

778 try: 

779 orig_attr = termios.tcgetattr(self.fd) 

780 iflag, oflag, cflag, lflag, ispeed, ospeed, cc = orig_attr 

781 except termios.error as msg: # if a port is nonexistent but has a /dev file, it'll fail here 

782 raise serial.SerialException("Could not configure port: {}".format(msg)) 

783 

784 if vtime < 0 or vtime > 255: 

785 raise ValueError('Invalid vtime: {!r}'.format(vtime)) 

786 cc[termios.VTIME] = vtime 

787 cc[termios.VMIN] = vmin 

788 

789 termios.tcsetattr( 

790 self.fd, 

791 termios.TCSANOW, 

792 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]) 

793 

794 def read(self, size=1): 

795 """\ 

796 Read size bytes from the serial port. If a timeout is set it may 

797 return less characters as requested. With no timeout it will block 

798 until the requested number of bytes is read. 

799 """ 

800 if not self.is_open: 

801 raise portNotOpenError 

802 read = bytearray() 

803 while len(read) < size: 

804 buf = os.read(self.fd, size - len(read)) 

805 if not buf: 

806 break 

807 read.extend(buf) 

808 return bytes(read) 

809 

810 # hack to make hasattr return false 

811 cancel_read = property()