# Send and Receive

## Bus On / Bus Off

When the CAN controller is on bus, it is receiving messages and is sending acknowledge bits in response to all correctly received messages. A controller that is off bus is not taking part in the bus communication at all.

When you have a `canlib.canlib.Channel` object, use `busOn` to go on bus and `busOff` to go off bus.

If you have multiple `Channel` objects to the same controller, the controller will go off bus when the last of the `Channel` objects go off bus (i.e. all `Channel` objects must be off bus for the controller to be off bus). You can use `readStatus` and watch the flag `BUS_OFF` to see if the controller has gone off bus.

You can set a channel to silent mode by using the `SILENT` mode if you want it to be on-bus without interfering with the traffic in any way, see CAN Driver Modes.

This example opens a channel, takes it on-bus, then takes it off-bus and closes it:

    >>> from canlib import canlib
    ... with canlib.openChannel(channel=1) as ch:
    ...     ch.busOn()
    ...     ...
    ...     ch.busOff()

## Reading Messages

Incoming messages are placed in a queue in the driver. In most cases the hardware does message buffering as well. You can read the first message in the queue by calling `read`, which will raise the exception `canlib.canlib.CanNoMsg` if there was no message available.

The `flags` attribute of the `Frame` returned by `read` contains a combination of the `MessageFlag` flags, including `FDF`, `BRS`, and `ESI` if the CAN FD protocol is enabled, and error flags such as `OVERRUN` which provides you with more information about the message; for example, a frame with a 29-bit identifier will have the `EXT` bit set, and a remote frame will have the `RTR` bit set. Note that the flag argument is a combination of the `MessageFlag`, so more than one flag might be set.

See CAN Frames for more information.

Sometimes it is desirable to have a peek into the more remote parts of the queue. Is there, for example, any message waiting that has a certain identifier?

> - If you want to read just a message with a specified identifier, and throw all others away, you can call `readSpecificSkip`. This routine will return the first message with the specified identifier, discarding any other message in front of the desired one.
> - If you want to wait until a message arrives (or a timeout occurs) and then read it, call `read` with a timeout.
> - If you want to wait until there is at least one message in the queue with a certain identifier, but you don’t want to read it, call `readSyncSpecific`.

The following code fragment reads the next available CAN message, (using default bitrate 500 kbit/s):

    >>> from canlib import canlib
    ... with canlib.openChannel(channel=0) as ch:
    ...     ch.busOn()
    ...     frame = ch.read(timeout=1000)
    ...     ch.busOff()
    >>> frame
    Frame(id=709, data=bytearray(b'\xb5R'), dlc=2, flags=<MessageFlag.STD: 2>, timestamp=3)

## Acceptance Filters

You can set filters to reduce the number of received messages. CANlib supports setting of the hardware filters on the CAN interface board. This is done with the `canlib.canlib.Channel.canAccept` function.

You set an acceptance code and an acceptance mask which together determine which CAN identifiers are accepted or rejected.

If you want to remove an acceptance filter, call `canlib.canlib.Channel.canAccept` with the mask set to `NULL_MASK`.

To set the mask to 0xF0 and the code to 0x60:

    >>> from canlib import canlib
    >>> ch = canlib.openChannel(channel=0)
    >>> ch.canAccept(0x0f0, canlib.AcceptFilterFlag.SET_MASK_STD)
    >>> ch.canAccept(0x060, canlib.AcceptFilterFlag.SET_CODE_STD)
    >>> ...
    >>> ch.close()

This code snippet will cause all messages having a standard (11-bit) identifier with bit 7 - bit 4 in the identifier equal to 0110 (binary) will pass through. Other messages with standard identifiers will be rejected.

How acceptance filters can be used in a smaller project:

    >>> from canlib import canlib
    >>> ch = canlib.openChannel(channel=0)
    >>> # The acceptance filter only have to be called once for each ch object
    >>> ch.canAccept(0x0f0, canlib.AcceptFilterFlag.SET_MASK_STD)
    >>> ch.canAccept(0x060, canlib.AcceptFilterFlag.SET_CODE_STD)
    >>> ...
    >>> # We can now run the rest of the program and the acceptance filter
    >>> # will reject unwanted CAN messages.
    >>> while(True):
    >>>     frame = ch.read()
    >>>     ...
    >>> ...

### Code and Mask Format

Explanation of the code and mask format used by the `canlib.canlib.Channel.canAccept` function:

> A binary 1 in a mask means “the corresponding bit in the code is relevant” A binary 0 in a mask means “the corresponding bit in the code is not relevant” A relevant binary 1 in a code means “the corresponding bit in the identifier must be 1” A relevant binary 0 in a code means “the corresponding bit in the identifier must be 0”

In other words, the message is accepted if ((code XOR id) AND mask) == 0.

## Sending Messages

You transmit messages by calling `canlib.canlib.Channel.write`. Outgoing CAN messages are buffered in a transmit queue and sent on a First-In First-Out basis. You can use `canlib.canlib.Channel.writeSync` to wait until the messages in the queue have been sent.

Sending a CAN message:

    >>> from canlib import canlib, Frame
    ... with canlib.openChannel(channel=0) as ch:
    ...     ch.busOn()
    ...     frame = Frame(id_=234, data=[1,2])
    ...     ch.write(frame)
    ...     ch.busOff()

## Using Extended CAN (CAN 2.0B)

“Standard” CAN has 11-bit identifiers in the range 0 - 2047. “Extended” CAN, also called CAN 2.0B, has 29-bit identifiers. You specify which kind of identifiers you want to use in your call to canWrite(): if you set the `EXT` flag in the flag argument, the message will be transmitted with a 29-bit identifier. Conversely, received 29-bit-identifier messages have the `EXT` flag set.

The following code fragment sends a CAN message on an already open channel. The CAN message will have identifier 1234 (extended) and DLC = 8. The contents of the data bytes will be whatever the data array happens to contain:

    >>> frame = Frame(id_=1234, data=[1,2,3,4,5,6,7,8], flags=canlib.MessageFlag.EXT)
    >>> frame
    Frame(id=1234, data=bytearray(b'\x01\x02\x03\x04\x05\x06\x07\x08'), dlc=8, flags=<MessageFlag.EXT: 4>, timestamp=None)
    >>> ch.write(frame)

## Object Buffers

Object buffers are currently not supported in the Python wrapper.