Example #1
0
    async def send_until(self, frames: typing.Iterable[_media.DataFrame],
                         monotonic_deadline: float) -> int:
        del monotonic_deadline  # Unused
        if self._closed:
            raise pyuavcan.transport.ResourceClosedError

        if self._raise_on_send_once:
            self._raise_on_send_once, ex = None, self._raise_on_send_once
            assert isinstance(ex, Exception)
            raise ex

        frames = list(frames)
        assert len(
            frames
        ) > 0, 'Interface constraint violation: empty transmission set'
        assert min(
            map(lambda x: len(x.data),
                frames)) >= 1, 'CAN frames with empty payload are not valid'
        # The media interface spec says that it is guaranteed that the CAN ID is the same across the set; enforce this.
        assert len(set(
            map(lambda x: x.identifier,
                frames))) == 1, 'Interface constraint violation: nonuniform ID'

        timestamp = pyuavcan.transport.Timestamp.now()

        # Broadcast across the virtual bus we're emulating here.
        for p in self._peers:
            if p is not self:
                # Unconditionally clear the loopback flag because for the other side these are
                # regular received frames, not loopback frames.
                p._receive(
                    _media.TimestampedDataFrame(identifier=f.identifier,
                                                data=f.data,
                                                format=f.format,
                                                loopback=False,
                                                timestamp=timestamp)
                    for f in frames)

        # Simple loopback emulation with acceptance filtering.
        self._receive(
            _media.TimestampedDataFrame(identifier=f.identifier,
                                        data=f.data,
                                        format=f.format,
                                        loopback=True,
                                        timestamp=timestamp) for f in frames
            if f.loopback)

        return len(frames)
 def inject_received(self, frames: typing.Iterable[_media.DataFrame]) -> None:
     timestamp = pyuavcan.transport.Timestamp.now()
     self._receive(_media.TimestampedDataFrame(identifier=f.identifier,
                                               data=f.data,
                                               format=f.format,
                                               loopback=f.loopback,
                                               timestamp=timestamp)
                   for f in frames)
Example #3
0
 def _parse_native_frame(source: bytes,
                         loopback: bool,
                         timestamp: pyuavcan.transport.Timestamp) \
         -> typing.Optional[_media.TimestampedDataFrame]:
     header_size = _FRAME_HEADER_STRUCT.size
     ident_raw, data_length, _flags = _FRAME_HEADER_STRUCT.unpack(
         source[:header_size])
     if (ident_raw & _CAN_RTR_FLAG) or (
             ident_raw
             & _CAN_ERR_FLAG):  # Unsupported format, ignore silently
         _logger.debug('Frame dropped: id_raw=%08x', ident_raw)
         return None
     frame_format = _media.FrameFormat.EXTENDED if ident_raw & _CAN_EFF_FLAG else _media.FrameFormat.BASE
     data = source[header_size:header_size + data_length]
     assert len(data) == data_length
     ident = ident_raw & _CAN_EFF_MASK
     return _media.TimestampedDataFrame(identifier=ident,
                                        data=bytearray(data),
                                        format=frame_format,
                                        loopback=loopback,
                                        timestamp=timestamp)