예제 #1
0
    def tobytes(self):

        bits = bitarray()

        # build header
        bits += int_to_bitarray((self.size / 24) - 1,
                                2)  # (0-1): packet length
        bits += int_to_bitarray(self.index, 2)  # (2-3): continuity index
        bits += bitarray('1' if self.first else
                         '0')  # (4): first packet of datagroup series
        bits += bitarray(
            '1' if self.last else '0')  # (5): last packet of datagroup series
        bits += int_to_bitarray(self.address, 10)  # (6-15): packet address
        bits += bitarray('0')  # (16): Command flag = 0 (data)
        bits += int_to_bitarray(len(self.data),
                                7)  # (17-23): useful data length

        # add the packet data
        tmp = bitarray()
        tmp.frombytes(self.data)
        bits += tmp  # (24-n): packet data

        # add packet padding if needed
        bits += bitarray('0' * (self.size - len(self.data) - 5) * 8)

        # add CRC
        bits += int_to_bitarray(calculate_crc(bits.tobytes()), 16)

        return bits.tobytes()
예제 #2
0
def _segment(data, strategy):

    segments = []

    # partition the segments up using the maximum segment size
    i = 0
    if not data: return segments
    while i < len(data):
        segment_size = strategy.get_next_segment_size(data, i, segments)

        # get segment data
        segment_data = data[i:i + segment_size if i +
                            segment_size < len(data) else len(data)]

        # segment header
        bits = bitarray()
        bits += int_to_bitarray(
            0, 3)  # (0-2): Repetition Count remaining (0 = only broadcast)
        bits += int_to_bitarray(len(segment_data), 13)  # (3-16): SegmentSize

        segments.append(bits.tobytes() + segment_data)

        i += segment_size

    return segments
예제 #3
0
 def encode_data(self):
     bits = bitarray()
     bits += int_to_bitarray(self.charset,
                             4)  # (0-3): Character set indicator
     bits += int_to_bitarray(0, 4)  # (4-7): RFA
     tmp = bitarray()
     tmp.fromstring(self.url)
     bits += tmp
     return bits
예제 #4
0
    def tobytes(self):

        bits = bitarray()

        # datagroup header
        bits += bitarray('0')  # (0): ExtensionFlag - 0=no extension
        bits += bitarray(
            '1' if self.crc_enabled else '0'
        )  # (1): CrcFlag - true if there is a CRC at the end of the datagroup
        bits += bitarray('1')  # (2): SegmentFlag - 1=segment header included
        bits += bitarray('1')  # (3): UserAccessFlag - true
        bits += int_to_bitarray(self._type, 4)  # (4-7): DataGroupType
        bits += int_to_bitarray(self.continuity % 16,
                                4)  # (8-11): ContinuityIndex
        bits += int_to_bitarray(
            self.repetition,
            4)  # (12-15): RepetitionIndex - remaining = 0 (only this once)

        # session header
        # segment field
        bits += bitarray(
            '1' if self.last else '0')  # (16): Last - true if the last segment
        bits += int_to_bitarray(self.segment_index,
                                15)  # (17-32): SegmentNumber

        # user access field
        bits += bitarray('000')  # (33-35): RFA
        bits += bitarray(
            '1')  # (36): TransportId - true to include Transport ID
        bits += int_to_bitarray(
            2, 4
        )  # (37-40): LengthIndicator - length of transport Id and End user address fields (will be 2 bytes as only transport ID defined)
        bits += int_to_bitarray(self._transport_id, 16)  # (41-56) transport ID

        # data field
        tmp = bitarray()
        tmp.frombytes(self._data)
        bits += tmp

        # CRC
        crc = 0
        if self.crc_enabled: crc = calculate_crc(bits.tobytes())
        bits += int_to_bitarray(crc, 16)

        return bits.tobytes()
예제 #5
0
def encode_directorymode(objects,
                         directory_parameters=None,
                         segmenting_strategy=None):
    """
    Encode a set of MOT objects into directory mode segments, along with a segmented
    directory object
    """

    datagroups = []
    if not segmenting_strategy: segmenting_strategy = ConstantSegmentSize()

    # build the directory entries
    entries = bitarray()
    for object in objects:
        # encode header extension parameters
        extension_bits = bitarray()
        for parameter in object.get_parameters():
            extension_bits += parameter.encode()

        # transport ID in first 2 bytes
        entries += int_to_bitarray(object.get_transport_id(), 16)

        # add the core parameters into the header
        entries += int_to_bitarray(len(object.get_body()),
                                   28)  # (0-27): BodySize in bytes
        entries += int_to_bitarray(
            extension_bits.length() / 8 + 7,
            13)  # (28-40): HeaderSize in bytes (core=7 + extension)
        entries += int_to_bitarray(object.get_type().type,
                                   6)  # (41-46): ContentType
        entries += int_to_bitarray(object.get_type().subtype,
                                   9)  # (47-55): ContentSubType
        entries += extension_bits  # (56-n): Header extension data

    # build directory parameters
    directory_params = bitarray()
    if directory_parameters is not None:
        for parameter in directory_parameters:
            directory_params += parameter.encode()

    # build directory header
    bits = bitarray()
    bits += bitarray('0')  # (0): CompressionFlag: This bit shall be set to 0
    bits += bitarray('0')  # (1): RFU
    bits += int_to_bitarray(
        len(entries.tobytes()),
        30)  # (2-31): DirectorySize: total size of the MOT directory in bytes
    bits += int_to_bitarray(
        len(objects), 16
    )  # (32-47): NumberOfObjects: Total number of objects described by the directory
    bits += int_to_bitarray(
        0, 24
    )  # (48-71): DataCarouselPeriod: Max time in tenths of seconds for the data carousel to complete a cycle. Value of zero for undefined
    bits += bitarray('000')  # (72-74): RFU
    bits += int_to_bitarray(
        0, 13
    )  # (75-87): SegmentSize: Size in bytes that will be used for the segmentation of objects within the MOT carousel. Value of zero indicates that objects can have different segmentation sizes. The last segment of an obect may be smaller than this size.
    bits += int_to_bitarray(
        len(directory_params.tobytes()), 16
    )  # (88-103): DirectoryExtensionLength: Length of following directory extension bytes

    # add directory parameters
    bits += directory_params

    # add directory entries
    bits += entries

    # segment and add directory datagroups with a new transport ID
    directory_transport_id = generate_transport_id()
    segments = _segment(bits.tobytes(), segmenting_strategy)
    for i, segment in enumerate(segments):
        header_group = Datagroup(directory_transport_id,
                                 DIRECTORY_UNCOMPRESSED,
                                 segment,
                                 i,
                                 i % 16,
                                 last=True if i == len(segments) -
                                 1 else False)
        tmp = bitarray()
        tmp.frombytes(header_group.tobytes())
        tmp.frombytes(header_group.tobytes())
        datagroups.append(header_group)

    # add body datagroups
    for object in objects:
        segments = _segment(object.get_body(), segmenting_strategy)
        for i, segment in enumerate(segments):
            body_group = Datagroup(object.get_transport_id(),
                                   BODY,
                                   segment,
                                   i,
                                   i % 16,
                                   last=True if i == len(segments) -
                                   1 else False)
            datagroups.append(body_group)
    return datagroups
예제 #6
0
def encode_headermode(objects, segmenting_strategy=None):
    """
    Encode a set of MOT Objects into header mode segments
    """

    datagroups = []
    if not segmenting_strategy: segmenting_strategy = ConstantSegmentSize()

    # backward compatibility
    if not isinstance(objects, list): objects = [objects]
    logger.debug('encoding %d MOT objects to header mode datagroups',
                 len(objects))

    for object in objects:
        if not object: raise ValueError('object returned is null')

        # split body data into segments
        body_data = object.get_body()
        body_segments = _segment(body_data, segmenting_strategy)

        # encode header extension parameters
        extension_bits = bitarray()
        for parameter in object.get_parameters():
            extension_bits += parameter.encode()

        # insert the core parameters into the header
        bits = bitarray()
        bits += int_to_bitarray(len(body_data) if body_data else 0,
                                28)  # (0-27): BodySize in bytes
        bits += int_to_bitarray(
            extension_bits.length() / 8 + 7,
            13)  # (28-40): HeaderSize in bytes (core=7 + extension)
        bits += int_to_bitarray(object.get_type().type,
                                6)  # (41-46): ContentType
        bits += int_to_bitarray(object.get_type().subtype,
                                9)  # (47-55): ContentSubType
        bits += extension_bits  # (56-n): Header extension data
        header_segments = _segment(bits.tobytes(), segmenting_strategy)

        # add header datagroups
        for i, segment in enumerate(header_segments):
            header_group = Datagroup(object.get_transport_id(),
                                     HEADER,
                                     segment,
                                     i,
                                     i % 16,
                                     last=True if i == len(header_segments) -
                                     1 else False)
            datagroups.append(header_group)

        # add body datagroups
        for i, segment in enumerate(body_segments):
            body_group = Datagroup(object.get_transport_id(),
                                   BODY,
                                   segment,
                                   i,
                                   i % 16,
                                   last=True if i == len(body_segments) -
                                   1 else False)
            datagroups.append(body_group)

        return datagroups