gpscat.in 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!@PYSHEBANG@
  2. #
  3. # @GENERATED@
  4. "Display GPS output. Hexify it if necessary."
  5. # This file is Copyright 2010 by the GPSD project
  6. # SPDX-License-Identifier: BSD-2-clause
  7. # This code runs compatibly under Python 2 and 3.x for x >= 2.
  8. # Preserve this property!
  9. from __future__ import absolute_import, print_function, division
  10. import getopt
  11. import os
  12. import select
  13. import socket
  14. import string
  15. import sys
  16. import termios
  17. # pylint wants local modules last
  18. try:
  19. import gps
  20. import gps.packet as sniffer
  21. from gps.misc import BINARY_ENCODING
  22. except ImportError as e:
  23. sys.stderr.write(
  24. "gpscat: can't load Python gps libraries -- check PYTHONPATH.\n")
  25. sys.stderr.write("%s\n" % e)
  26. sys.exit(1)
  27. gps_version = '@VERSION@'
  28. if gps.__version__ != gps_version:
  29. sys.stderr.write("gpscat: ERROR: need gps module version %s, got %s\n" %
  30. (gps_version, gps.__version__))
  31. sys.exit(1)
  32. # The spec says 82, but some receivers (TN-200, GSW 2.3.2) output 86 characters
  33. # the Skyrtaq S2525F8 emits 100 chars
  34. NMEA_MAX = 102
  35. # Lowest debug level at which packet getter begins to emit messages, minus one
  36. BASELEVEL = sniffer.LOG_IO
  37. highhalf_latch = True
  38. PRINTABLE = set(bytearray(string.printable, encoding=BINARY_ENCODING))
  39. def hexdump(st):
  40. "Convert string to hex string"
  41. dmp = ""
  42. for ch in bytearray(st): # bytearray gets array of ints in Python 2 and 3
  43. if ch in PRINTABLE:
  44. dmp += chr(ch)
  45. else:
  46. dmp += "\\x%02x" % ch
  47. return dmp
  48. debuglevel = 0
  49. def reporter(errlevel, mesg):
  50. "Report errors, depending on log level"
  51. if errlevel <= debuglevel:
  52. sys.stdout.write(mesg)
  53. def printusage():
  54. "Print usage"
  55. sys.stderr.write("usage: gpscat [-D debuglevel] [-h] [-p] [-s speed] [-t] "
  56. "[-V] serial-port\n")
  57. if __name__ == '__main__':
  58. try:
  59. try:
  60. (options, arguments) = getopt.getopt(sys.argv[1:], "hps:tD:V")
  61. except getopt.GetoptError as msg:
  62. print("gpscat: " + str(msg))
  63. raise SystemExit(1)
  64. speed = None
  65. parity = None
  66. stopbits = None
  67. rawmode = True
  68. typeflag = False
  69. for (switch, val) in options:
  70. if switch == '-D':
  71. debuglevel = BASELEVEL + int(val)
  72. elif switch == '-h':
  73. printusage()
  74. raise SystemExit(0)
  75. elif switch == '-p':
  76. rawmode = False
  77. elif switch == '-s':
  78. if val[-2] in ('N', 'E', 'O'):
  79. parity = val[-2]
  80. stopbits = int(val[-1])
  81. val = val[:-2]
  82. speed = int(val)
  83. elif switch == '-t':
  84. typeflag = True
  85. rawmode = False
  86. elif switch == '-V':
  87. sys.stderr.write("gpscat: Version %s\n" % gps_version)
  88. sys.exit(0)
  89. if len(arguments) != 1:
  90. printusage()
  91. raise SystemExit(1)
  92. if "rfcomm" in arguments[0]: # Bluetooth special case
  93. s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM,
  94. socket.BTPROTO_RFCOMM)
  95. s.connect((arguments[0], 1))
  96. tty = s.fileno()
  97. else: # Ordinary device
  98. tty = os.open(arguments[0], os.O_RDWR)
  99. if speed is not None:
  100. (iflag, oflag, cflag, lflag, ispeed, ospeed, cc) = \
  101. termios.tcgetattr(tty)
  102. try:
  103. ispeed = ospeed = eval("termios.B%d" % speed)
  104. except AttributeError:
  105. sys.stderr.write("gpscat: unknown baud rate %d\n" % speed)
  106. raise SystemExit(1)
  107. if stopbits:
  108. cflag &= ~termios.CSIZE
  109. cflag |= (termios.CS8, termios.CS7)[stopbits - 1]
  110. if parity:
  111. if parity == 'N':
  112. iflag &= ~termios.PARENB
  113. iflag &= ~termios.INPCK
  114. elif parity == 'O':
  115. iflag |= termios.INPCK
  116. cflag |= termios.PARENB
  117. cflag |= termios.PARODD
  118. elif parity == 'E':
  119. iflag |= termios.INPCK
  120. cflag |= termios.PARENB
  121. cflag &= ~termios.PARODD
  122. termios.tcsetattr(tty, termios.TCSANOW,
  123. [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
  124. if not rawmode:
  125. getter = sniffer.new()
  126. sniffer.register_report(reporter)
  127. seqno = 0
  128. while True:
  129. rlist, wlist, xlist = select.select([tty], [], [])
  130. if rlist == [tty]:
  131. if rawmode:
  132. buf = os.read(tty, NMEA_MAX)
  133. if not buf:
  134. break
  135. sys.stdout.write(hexdump(buf))
  136. else:
  137. (length, ptype, packet, counter) = getter.get(tty)
  138. seqno += 1
  139. if length == 0:
  140. break
  141. if typeflag:
  142. sys.stdout.write('%d (%d@%d): %s\n' % (ptype, length,
  143. counter - length, hexdump(packet)))
  144. else:
  145. sys.stdout.write(hexdump(packet) + "\n")
  146. except KeyboardInterrupt:
  147. if rawmode:
  148. sys.stdout.write("\n")
  149. raise SystemExit(0)
  150. # Local variables:
  151. # mode: python
  152. # end:
  153. # vim: set expandtab shiftwidth=4