4646from serial import SerialException , SerialTimeoutException
4747
4848from geocompy .data import Angle , Byte
49- from geocompy .communication import Connection , DUMMYLOGGER
49+ from geocompy .communication import (
50+ Connection ,
51+ DUMMYLOGGER ,
52+ crc16_bytewise as crc16
53+ )
5054from .gctypes import (
5155 GeoComCode ,
5256 GeoComResponse ,
@@ -120,16 +124,18 @@ class GeoCom(GeoComType):
120124 _R1P : re .Pattern [str ] = re .compile (
121125 r"^%R1P,"
122126 r"(\d+)," # COM code
123- r"(\d+):" # Transaction ID
124- r"(\d+)" # RPC code
127+ r"(\d+)" # Transaction ID
128+ r"(?:,(\d+))?" # CRC checksum
129+ r":(\d+)" # RPC code
125130 r"(?:,(.*))?$" # parameters
126131 )
127132
128133 def __init__ (
129134 self ,
130135 connection : Connection ,
131136 logger : Logger | None = None ,
132- retry : int = 2
137+ retry : int = 2 ,
138+ crc : bool = False
133139 ):
134140 """
135141 After the subsystems are initialized, the connection is tested by
@@ -229,6 +235,8 @@ def __init__(
229235 .. versionremoved:: GeoCOM-TPS1200
230236 """
231237
238+ self ._crc : bool = crc
239+
232240 for i in range (retry ):
233241 try :
234242 self ._conn .send ("\n " )
@@ -355,6 +363,11 @@ def request(
355363 trid = self .transaction_counter % _MAX_TRANSACTION
356364 self .transaction_counter += 1
357365 cmd = f"%R1Q,{ rpc } ,{ trid } :{ ',' .join (strparams )} "
366+
367+ if self ._crc :
368+ crc = crc16 (cmd )
369+ cmd = f"%R1Q,{ rpc } ,{ trid } ,{ crc } :{ ',' .join (strparams )} "
370+
358371 try :
359372 answer = self ._conn .exchange (cmd )
360373 except SerialTimeoutException :
@@ -432,7 +445,7 @@ def parse_response(
432445
433446 """
434447 m = self ._R1P .match (response )
435- _ , rpc , trid_expected = cmd .split (":" )[0 ].split ("," )
448+ rpc , trid_expected = cmd .split (":" )[0 ].split ("," )[ 1 : 3 ]
436449 rpcname = rpcnames .get (int (rpc ), rpc )
437450 if not m :
438451 return GeoComResponse (
@@ -444,7 +457,20 @@ def parse_response(
444457 0
445458 )
446459
447- com_field , tr_field , rpc_field , values = m .groups ()
460+ com_field , tr_field , crc_field , rpc_field , values = m .groups ()
461+ if crc_field is not None :
462+ crc = int (crc_field )
463+ beg , end = m .regs [3 ]
464+ if crc != crc16 (response [:beg - 1 ] + response [end :]):
465+ return GeoComResponse (
466+ rpcname ,
467+ cmd ,
468+ response ,
469+ GeoComCode .COM_CLNT_RX_CHECKSUM_ERROR ,
470+ GeoComCode .OK ,
471+ 0
472+ )
473+
448474 trid = int (tr_field )
449475 if trid != int (trid_expected ):
450476 return GeoComResponse (
@@ -467,9 +493,6 @@ def parse_response(
467493 rpccode = GeoComCode .UNDEFINED
468494
469495 if values is None :
470- values = ""
471-
472- if values == "" :
473496 return GeoComResponse (
474497 rpcname ,
475498 cmd ,
0 commit comments