Source code for simulator.core.DtnSegments

import abc
from collections import defaultdict
import numpy as np
from .DtnCore import Message

[docs]class LtpSegment(Message, metaclass=abc.ABCMeta): """ Abstract LTP segments that is then specialized into a Data Segment (DS), Report Segment (RS) or Report Acknowledgement Segment (RA). Other segments such as session cancellation or cancellation ack are not defined here. """ _segment_types = ['DS', 'RS', 'RA', 'CS'] def __init__(self, type, session_id): # Call parent constructor super(LtpSegment, self).__init__() # Check the provided type if type not in LtpSegment._segment_types: raise ValueError('LTP segment type can only be {}'.format(LtpSegment._segment_types)) # Set the LTP session that this segment belongs to self.session_id = session_id # Set this segment type self.type = type # Set the size to None. Its subclasses must override this value self.size = None @property def mid(self): return (hex(id(self)), 0) @property def num_bits(self): return self.size def __str__(self): return '<LtpSegment>'
[docs]class LtpDataSegment(LtpSegment): """ An LTP Data Segment (see page 16, rfc 5326) """ def __init__(self, session_id, offset, length, checkpoint=None, report=None): """ Class constructor :param bid: Block id = block hash :param offset: Offset from start of block in Bytes :param length: Length of data in this segment in Bytes :param checkpoint: Checkpoint id if this segment is checkpoint. Otherwise None :param report: Report serial number if this segment is issued in response to a report segment """ # Call parent constructor super(LtpDataSegment, self).__init__("DS", session_id) # Store variables self.offset = offset self.length = length self.checkpoint = checkpoint self.report = report # Size in bytes of this segment. Assume 10 bytes of overhead self.size = np.ceil(self.length + 10) @property def is_checkpoint(self): return self.checkpoint is not None def __str__(self): return '<LtpDataSegment ({}, {}, {})>'.format(self.offset, self.length, self.checkpoint)
[docs]class LtpReportSegment(LtpSegment): """ An LTP Report Segment (see page 17, rfc 5326) """ # Static variable to keep track of report serial numbers # It is a dictionary indexed by checkpoint serial number report_counter = defaultdict(int) def __init__(self, session_id): # Call parent constructor super(LtpReportSegment, self).__init__("RS", session_id) # Store variables self.id = None self.checkpoint = None self.lower_bnd = float('inf') # Initial value self.upper_bnd = -float('inf') # Initial value self.claims = set() # A claim is a tuple of format (offset, length) # Size in bytes of this segment. Assume 25 bytes constant self.size = 25.0 @property def num_claims(self): return len(self.claims) def __str__(self): s = '<LtpReportSegment {} (lb={}, ub={})\n'.format(self.id, self.lower_bnd,self.upper_bnd) for i, claim in enumerate(self.claims): s += ' Claim {}: offset={}, length={}\n'.format(i+1, claim[0], claim[1]) return s[0:-1] + '>' def __repr__(self): return '<LtpReportSegment {} (lb={}, ub={})>'.format(self.id, self.lower_bnd, self.upper_bnd)
[docs]class LtpReportAcknowledgementSegment(LtpSegment): def __init__(self, session_id, report_id): # Call parent constructor super(LtpReportAcknowledgementSegment, self).__init__("RA", session_id) # Store variables self.report_id = report_id # Size of this report. Assume 10 bytes self.size = 10.0 def __str__(self): return '<LtpReportAck {}>'.format(self.report_id)
[docs]class LtpCancelSessionSegment(LtpSegment): """ This is not equivalent to the cancel sessions in the LTP specification. It is a convenient way to signal the ``run_ltp_session`` of either a DtnOutductLTP or DtnInductLTP that there has been an error during transmission of this block and this session should be cancelled and the bundles in the block sent to re-routers. """ def __init__(self, session_id): super(LtpCancelSessionSegment, self).__init__("CS", session_id)