99from yamcs .client .model import Link
1010from yamcs .protobuf .cop1 import cop1_pb2
1111from yamcs .protobuf .links import links_pb2
12+ from yamcs .protobuf .sdls import sdls_pb2
1213
1314__all__ = [
1415 "Cop1Subscription" ,
@@ -231,9 +232,7 @@ def get_cop1_status(self) -> Cop1Status:
231232 message .ParseFromString (response .content )
232233 return Cop1Status (message )
233234
234- def create_cop1_subscription (
235- self , on_data : Callable [[Cop1Status ], None ], timeout : float = 60
236- ) -> Cop1Subscription :
235+ def create_cop1_subscription (self , on_data : Callable [[Cop1Status ], None ], timeout : float = 60 ) -> Cop1Subscription :
237236 """
238237 Create a new subscription for receiving status of the COP1 link.
239238
@@ -257,13 +256,52 @@ def create_cop1_subscription(
257256 # Represent subscription as a future
258257 subscription = Cop1Subscription (manager )
259258
260- wrapped_callback = functools .partial (
261- _wrap_callback_parse_cop1_status , subscription , on_data
262- )
259+ wrapped_callback = functools .partial (_wrap_callback_parse_cop1_status , subscription , on_data )
263260
264261 manager .open (wrapped_callback )
265262
266263 # Wait until a reply or exception is received
267264 subscription .reply (timeout = timeout )
268265
269266 return subscription
267+
268+ def sdls_get_ctr (self , spi : int ) -> int :
269+ """
270+ Get the sequence counter associated with a given `spi` (Security Parameter Index) on this link.
271+ """
272+ response = self .ctx .get_proto (f"/sdls/{ self ._instance } /{ self ._link } /{ spi } /seq" )
273+ message = sdls_pb2 .GetSeqCtrResponse ()
274+ message .ParseFromString (response .content )
275+ return int .from_bytes (message .seq , byteorder = "big" )
276+
277+ def sdls_set_ctr (self , spi : int , new_seq : int ):
278+ """
279+ Set the sequence counter associated with a given `spi` (Security Parameter Index) on this link to `new_seq`.
280+ """
281+ body = sdls_pb2 .SetSeqCtrRequestBody ()
282+ byte_length = (new_seq .bit_length () + 7 ) // 8
283+ body .seq = new_seq .to_bytes (byte_length , byteorder = "big" )
284+ self .ctx .put_proto (f"/sdls/{ self ._instance } /{ self ._link } /{ spi } /seq" , data = body .SerializeToString ())
285+
286+ def sdls_set_key (self , spi : int , key : bytes ):
287+ """
288+ Update the `key` associated with a given `spi` (Security Parameter Index) on this link.
289+ """
290+ self .ctx .put_proto (f"/sdls/{ self ._instance } /{ self ._link } /{ spi } /key" , data = key )
291+
292+ def sdls_set_spi (self , vc_id : int , spi : int ):
293+ """
294+ Update the `spi` used for SDLS on the VC `vc_id` on this link.
295+ """
296+ body = sdls_pb2 .SetSpiRequestBody ()
297+ body .spi = spi
298+ self .ctx .put_proto (f"/sdls/{ self ._instance } /{ self ._link } /{ vc_id } /spi" , data = body .SerializeToString ())
299+
300+ def sdls_set_spis (self , vc_id : int , spis : list [int ]):
301+ """
302+ Update the `spis` used for SDLS on the VC `vc_id` on this link.
303+ Only valid for incoming links (i.e., downlink).
304+ """
305+ body = sdls_pb2 .SetSpisRequestBody ()
306+ body .spis [:] = spis
307+ self .ctx .put_proto (f"/sdls/{ self ._instance } /{ self ._link } /{ vc_id } /spis" , data = body .SerializeToString ())
0 commit comments