===================================
SocketCAN - Controller Area Network
===================================

Overview / What is SocketCAN
============================

The socketcan package is an implementation of CAN protocols
(Controller Area Network) for Linux.  CAN is a networking technology
which has widespread use in automation, embedded devices, and
automotive fields.  While there have been other CAN implementations
for Linux based on character devices, SocketCAN uses the Berkeley
socket API, the Linux network stack and implements the CAN device
drivers as network interfaces.  The CAN socket API has been designed
as similar as possible to the TCP/IP protocols to allow programmers,
familiar with network programming, to easily learn how to use CAN
sockets.


.. _socketcan-motivation:

Motivation / Why Using the Socket API
=====================================

There have been CAN implementations for Linux before SocketCAN so the
question arises, why we have started another project.  Most existing
implementations come as a device driver for some CAN hardware, they
are based on character devices and provide comparatively little
functionality.  Usually, there is only a hardware-specific device
driver which provides a character device interface to send and
receive raw CAN frames, directly to/from the controller hardware.
Queueing of frames and higher-level transport protocols like ISO-TP
have to be implemented in user space applications.  Also, most
character-device implementations support only one single process to
open the device at a time, similar to a serial interface.  Exchanging
the CAN controller requires employment of another device driver and
often the need for adaption of large parts of the application to the
new driver's API.

SocketCAN was designed to overcome all of these limitations.  A new
protocol family has been implemented which provides a socket interface
to user space applications and which builds upon the Linux network
layer, enabling use all of the provided queueing functionality.  A device
driver for CAN controller hardware registers itself with the Linux
network layer as a network device, so that CAN frames from the
controller can be passed up to the network layer and on to the CAN
protocol family module and also vice-versa.  Also, the protocol family
module provides an API for transport protocol modules to register, so
that any number of transport protocols can be loaded or unloaded
dynamically.  In fact, the can core module alone does not provide any
protocol and cannot be used without loading at least one additional
protocol module.  Multiple sockets can be opened at the same time,
on different or the same protocol module and they can listen/send
frames on different or the same CAN IDs.  Several sockets listening on
the same interface for frames with the same CAN ID are all passed the
same received matching CAN frames.  An application wishing to
communicate using a specific transport protocol, e.g. ISO-TP, just
selects that protocol when opening the socket, and then can read and
write application data byte streams, without having to deal with
CAN-IDs, frames, etc.

Similar functionality visible from user-space could be provided by a
character device, too, but this would lead to a technically inelegant
solution for a couple of reasons:

* **Intricate usage:**  Instead of passing a protocol argument to
  socket(2) and using bind(2) to select a CAN interface and CAN ID, an
  application would have to do all these operations using ioctl(2)s.

* **Code duplication:**  A character device cannot make use of the Linux
  network queueing code, so all that code would have to be duplicated
  for CAN networking.

* **Abstraction:**  In most existing character-device implementations, the
  hardware-specific device driver for a CAN controller directly
  provides the character device for the application to work with.
  This is at least very unusual in Unix systems for both, char and
  block devices.  For example you don't have a character device for a
  certain UART of a serial interface, a certain sound chip in your
  computer, a SCSI or IDE controller providing access to your hard
  disk or tape streamer device.  Instead, you have abstraction layers
  which provide a unified character or block device interface to the
  application on the one hand, and a interface for hardware-specific
  device drivers on the other hand.  These abstractions are provided
  by subsystems like the tty layer, the audio subsystem or the SCSI
  and IDE subsystems for the devices mentioned above.

  The easiest way to implement a CAN device driver is as a character
  device without such a (complete) abstraction layer, as is done by most
  existing drivers.  The right way, however, would be to add such a
  layer with all the functionality like registering for certain CAN
  IDs, supporting several open file descriptors and (de)multiplexing
  CAN frames between them, (sophisticated) queueing of CAN frames, and
  providing an API for device drivers to register with.  However, then
  it would be no more difficult, or may be even easier, to use the
  networking framework provided by the Linux kernel, and this is what
  SocketCAN does.

The use of the networking framework of the Linux kernel is just the
natural and most appropriate way to implement CAN for Linux.


.. _socketcan-concept:

SocketCAN Concept
=================

As described in :ref:`socketcan-motivation` the main goal of SocketCAN is to
provide a socket interface to user space applications which builds
upon the Linux network layer. In contrast to the commonly known
TCP/IP and ethernet networking, the CAN bus is a broadcast-only(!)
medium that has no MAC-layer addressing like ethernet. The CAN-identifier
(can_id) is used for arbitration on the CAN-bus. Therefore the CAN-IDs
have to be chosen uniquely on the bus. When designing a CAN-ECU
network the CAN-IDs are mapped to be sent by a specific ECU.
For this reason a CAN-ID can be treated best as a kind of source address.


.. _socketcan-receive-lists:

Receive Lists
-------------

The network transparent access of multiple applications leads to the
problem that different applications may be interested in the same
CAN-IDs from the same CAN network interface. The SocketCAN core
module - which implements the protocol family CAN - provides several
high efficient receive lists for this reason. If e.g. a user space
application opens a CAN RAW socket, the raw protocol module itself
requests the (range of) CAN-IDs from the SocketCAN core that are
requested by the user. The subscription and unsubscription of
CAN-IDs can be done for specific CAN interfaces or for all(!) known
CAN interfaces with the can_rx_(un)register() functions provided to
CAN protocol modules by the SocketCAN core (see :ref:`socketcan-core-module`).
To optimize the CPU usage at runtime the receive lists are split up
into several specific lists per device that match the requested
filter complexity for a given use-case.


.. _socketcan-local-loopback1:

Local Loopback of Sent Frames
-----------------------------

As known from other networking concepts the data exchanging
applications may run on the same or different nodes without any
change (except for the according addressing information):

.. code::

	 ___   ___   ___                   _______   ___
	| _ | | _ | | _ |                 | _   _ | | _ |
	||A|| ||B|| ||C||                 ||A| |B|| ||C||
	|___| |___| |___|                 |_______| |___|
	  |     |     |                       |       |
	-----------------(1)- CAN bus -(2)---------------

To ensure that application A receives the same information in the
example (2) as it would receive in example (1) there is need for
some kind of local loopback of the sent CAN frames on the appropriate
node.

The Linux network devices (by default) just can handle the
transmission and reception of media dependent frames. Due to the
arbitration on the CAN bus the transmission of a low prio CAN-ID
may be delayed by the reception of a high prio CAN frame. To
reflect the correct [#f1]_ traffic on the node the loopback of the sent
data has to be performed right after a successful transmission. If
the CAN network interface is not capable of performing the loopback for
some reason the SocketCAN core can do this task as a fallback solution.
See :ref:`socketcan-local-loopback2` for details (recommended).

The loopback functionality is enabled by default to reflect standard
networking behaviour for CAN applications. Due to some requests from
the RT-SocketCAN group the loopback optionally may be disabled for each
separate socket. See sockopts from the CAN RAW sockets in :ref:`socketcan-raw-sockets`.

.. [#f1] you really like to have this when you're running analyser
       tools like 'candump' or 'cansniffer' on the (same) node.


.. _socketcan-network-problem-notifications:

Network Problem Notifications
-----------------------------

The use of the CAN bus may lead to several problems on the physical
and media access control layer. Detecting and logging of these lower
layer problems is a vital requirement for CAN users to identify
hardware issues on the physical transceiver layer as well as
arbitration problems and error frames caused by the different
ECUs. The occurrence of detected errors are important for diagnosis
and have to be logged together with the exact timestamp. For this
reason the CAN interface driver can generate so called Error Message
Frames that can optionally be passed to the user application in the
same way as other CAN frames. Whenever an error on the physical layer
or the MAC layer is detected (e.g. by the CAN controller) the driver
creates an appropriate error message frame. Error messages frames can
be requested by the user application using the common CAN filter
mechanisms. Inside this filter definition the (interested) type of
errors may be selected. The reception of error messages is disabled
by default. The format of the CAN error message frame is briefly
described in the Linux header file "include/uapi/linux/can/error.h".


How to use SocketCAN
====================

Like TCP/IP, you first need to open a socket for communicating over a
CAN network. Since SocketCAN implements a new protocol family, you
need to pass PF_CAN as the first argument to the socket(2) system
call. Currently, there are two CAN protocols to choose from, the raw
socket protocol and the broadcast manager (BCM). So to open a socket,
you would write::

    s = socket(PF_CAN, SOCK_RAW, CAN_RAW);

and::

    s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);

respectively.  After the successful creation of the socket, you would
normally use the bind(2) system call to bind the socket to a CAN
interface (which is different from TCP/IP due to different addressing
- see :ref:`socketcan-concept`). After binding (CAN_RAW) or connecting (CAN_BCM)
the socket, you can read(2) and write(2) from/to the socket or use
send(2), sendto(2), sendmsg(2) and the recv* counterpart operations
on the socket as usual. There are also CAN specific socket options
described below.

The Classical CAN frame structure (aka CAN 2.0B), the CAN FD frame structure
and the sockaddr structure are defined in include/linux/can.h:

.. code-block:: C

    struct can_frame {
            canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
            union {
                    /* CAN frame payload length in byte (0 .. CAN_MAX_DLEN)
                     * was previously named can_dlc so we need to carry that
                     * name for legacy support
                     */
                    __u8 len;
                    __u8 can_dlc; /* deprecated */
            };
            __u8    __pad;   /* padding */
            __u8    __res0;  /* reserved / padding */
            __u8    len8_dlc; /* optional DLC for 8 byte payload length (9 .. 15) */
            __u8    data[8] __attribute__((aligned(8)));
    };

Remark: The len element contains the payload length in bytes and should be
used instead of can_dlc. The deprecated can_dlc was misleadingly named as
it always contained the plain payload length in bytes and not the so called
'data length code' (DLC).

To pass the raw DLC from/to a Classical CAN network device the len8_dlc
element can contain values 9 .. 15 when the len element is 8 (the real
payload length for all DLC values greater or equal to 8).

The alignment of the (linear) payload data[] to a 64bit boundary
allows the user to define their own structs and unions to easily access
the CAN payload. There is no given byteorder on the CAN bus by
default. A read(2) system call on a CAN_RAW socket transfers a
struct can_frame to the user space.

The sockaddr_can structure has an interface index like the
PF_PACKET socket, that also binds to a specific interface:

.. code-block:: C

    struct sockaddr_can {
            sa_family_t can_family;
            int         can_ifindex;
            union {
                    /* transport protocol class address info (e.g. ISOTP) */
                    struct { canid_t rx_id, tx_id; } tp;

                    /* J1939 address information */
                    struct {
                            /* 8 byte name when using dynamic addressing */
                            __u64 name;

                            /* pgn:
                             * 8 bit: PS in PDU2 case, else 0
                             * 8 bit: PF
                             * 1 bit: DP
                             * 1 bit: reserved
                             */
                            __u32 pgn;

                            /* 1 byte address */
                            __u8 addr;
                    } j1939;

                    /* reserved for future CAN protocols address information */
            } can_addr;
    };

To determine the interface index an appropriate ioctl() has to
be used (example for CAN_RAW sockets without error checking):

.. code-block:: C

    int s;
    struct sockaddr_can addr;
    struct ifreq ifr;

    s = socket(PF_CAN, SOCK_RAW, CAN_RAW);

    strcpy(ifr.ifr_name, "can0" );
    ioctl(s, SIOCGIFINDEX, &ifr);

    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    bind(s, (struct sockaddr *)&addr, sizeof(addr));

    (..)

To bind a socket to all(!) CAN interfaces the interface index must
be 0 (zero). In this case the socket receives CAN frames from every
enabled CAN interface. To determine the originating CAN interface
the system call recvfrom(2) may be used instead of read(2). To send
on a socket that is bound to 'any' interface sendto(2) is needed to
specify the outgoing interface.

Reading CAN frames from a bound CAN_RAW socket (see above) consists
of reading a struct can_frame:

.. code-block:: C

    struct can_frame frame;

    nbytes = read(s, &frame, sizeof(struct can_frame));

    if (nbytes < 0) {
            perror("can raw socket read");
            return 1;
    }

    /* paranoid check ... */
    if (nbytes < sizeof(struct can_frame)) {
            fprintf(stderr, "read: incomplete CAN frame\n");
            return 1;
    }

    /* do something with the received CAN frame */

Writing CAN frames can be done similarly, with the write(2) system call::

    nbytes = write(s, &frame, sizeof(struct can_frame));

When the CAN interface is bound to 'any' existing CAN interface
(addr.can_ifindex = 0) it is recommended to use recvfrom(2) if the
information about the originating CAN interface is needed:

.. code-block:: C

    struct sockaddr_can addr;
    struct ifreq ifr;
    socklen_t len = sizeof(addr);
    struct can_frame frame;

    nbytes = recvfrom(s, &frame, sizeof(struct can_frame),
                      0, (struct sockaddr*)&addr, &len);

    /* get interface name of the received CAN frame */
    ifr.ifr_ifindex = addr.can_ifindex;
    ioctl(s, SIOCGIFNAME, &ifr);
    printf("Received a CAN frame from interface %s", ifr.ifr_name);

To write CAN frames on sockets bound to 'any' CAN interface the
outgoing interface has to be defined certainly:

.. code-block:: C

    strcpy(ifr.ifr_name, "can0");
    ioctl(s, SIOCGIFINDEX, &ifr);
    addr.can_ifindex = ifr.ifr_ifindex;
    addr.can_family  = AF_CAN;

    nbytes = sendto(s, &frame, sizeof(struct can_frame),
                    0, (struct sockaddr*)&addr, sizeof(addr));

An accurate timestamp can be obtained with an ioctl(2) call after reading
a message from the socket:

.. code-block:: C

    struct timeval tv;
    ioctl(s, SIOCGSTAMP, &tv);

The timestamp has a resolution of one microsecond and is set automatically
at the reception of a CAN frame.

Remark about CAN FD (flexible data rate) support:

Generally the handling of CAN FD is very similar to the formerly described
examples. The new CAN FD capable CAN controllers support two different
bitrates for the arbitration phase and the payload phase of the CAN FD frame
and up to 64 bytes of payload. This extended payload length breaks all the
kernel interfaces (ABI) which heavily rely on the CAN frame with fixed eight
bytes of payload (struct can_frame) like the CAN_RAW socket. Therefore e.g.
the CAN_RAW socket supports a new socket option CAN_RAW_FD_FRAMES that
switches the socket into a mode that allows the handling of CAN FD frames
and Classical CAN frames simultaneously (see :ref:`socketcan-rawfd`).

The struct canfd_frame is defined in include/linux/can.h:

.. code-block:: C

    struct canfd_frame {
            canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
            __u8    len;     /* frame payload length in byte (0 .. 64) */
            __u8    flags;   /* additional flags for CAN FD */
            __u8    __res0;  /* reserved / padding */
            __u8    __res1;  /* reserved / padding */
            __u8    data[64] __attribute__((aligned(8)));
    };

The struct canfd_frame and the existing struct can_frame have the can_id,
the payload length and the payload data at the same offset inside their
structures. This allows to handle the different structures very similar.
When the content of a struct can_frame is copied into a struct canfd_frame
all structure elements can be used as-is - only the data[] becomes extended.

When introducing the struct canfd_frame it turned out that the data length
code (DLC) of the struct can_frame was used as a length information as the
length and the DLC has a 1:1 mapping in the range of 0 .. 8. To preserve
the easy handling of the length information the canfd_frame.len element
contains a plain length value from 0 .. 64. So both canfd_frame.len and
can_frame.len are equal and contain a length information and no DLC.
For details about the distinction of CAN and CAN FD capable devices and
the mapping to the bus-relevant data length code (DLC), see :ref:`socketcan-can-fd-driver`.

The length of the two CAN(FD) frame structures define the maximum transfer
unit (MTU) of the CAN(FD) network interface and skbuff data length. Two
definitions are specified for CAN specific MTUs in include/linux/can.h:

.. code-block:: C

  #define CAN_MTU   (sizeof(struct can_frame))   == 16  => Classical CAN frame
  #define CANFD_MTU (sizeof(struct canfd_frame)) == 72  => CAN FD frame


Returned Message Flags
----------------------

When using the system call recvmsg(2) on a RAW or a BCM socket, the
msg->msg_flags field may contain the following flags:

MSG_DONTROUTE:
	set when the received frame was created on the local host.

MSG_CONFIRM:
	set when the frame was sent via the socket it is received on.
	This flag can be interpreted as a 'transmission confirmation' when the
	CAN driver supports the echo of frames on driver level, see
	:ref:`socketcan-local-loopback1` and :ref:`socketcan-local-loopback2`.
	(Note: In order to receive such messages on a RAW socket,
	CAN_RAW_RECV_OWN_MSGS must be set.)


.. _socketcan-raw-sockets:

RAW Protocol Sockets with can_filters (SOCK_RAW)
------------------------------------------------

Using CAN_RAW sockets is extensively comparable to the commonly
known access to CAN character devices. To meet the new possibilities
provided by the multi user SocketCAN approach, some reasonable
defaults are set at RAW socket binding time:

- The filters are set to exactly one filter receiving everything
- The socket only receives valid data frames (=> no error message frames)
- The loopback of sent CAN frames is enabled (see :ref:`socketcan-local-loopback2`)
- The socket does not receive its own sent frames (in loopback mode)

These default settings may be changed before or after binding the socket.
To use the referenced definitions of the socket options for CAN_RAW
sockets, include <linux/can/raw.h>.


.. _socketcan-rawfilter:

RAW socket option CAN_RAW_FILTER
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The reception of CAN frames using CAN_RAW sockets can be controlled
by defining 0 .. n filters with the CAN_RAW_FILTER socket option.

The CAN filter structure is defined in include/linux/can.h:

.. code-block:: C

    struct can_filter {
            canid_t can_id;
            canid_t can_mask;
    };

A filter matches, when:

.. code-block:: C

    <received_can_id> & mask == can_id & mask

which is analogous to known CAN controllers hardware filter semantics.
The filter can be inverted in this semantic, when the CAN_INV_FILTER
bit is set in can_id element of the can_filter structure. In
contrast to CAN controller hardware filters the user may set 0 .. n
receive filters for each open socket separately:

.. code-block:: C

    struct can_filter rfilter[2];

    rfilter[0].can_id   = 0x123;
    rfilter[0].can_mask = CAN_SFF_MASK;
    rfilter[1].can_id   = 0x200;
    rfilter[1].can_mask = 0x700;

    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

To disable the reception of CAN frames on the selected CAN_RAW socket:

.. code-block:: C

    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);

To set the filters to zero filters is quite obsolete as to not read
data causes the raw socket to discard the received CAN frames. But
having this 'send only' use-case we may remove the receive list in the
Kernel to save a little (really a very little!) CPU usage.

CAN Filter Usage Optimisation
.............................

The CAN filters are processed in per-device filter lists at CAN frame
reception time. To reduce the number of checks that need to be performed
while walking through the filter lists the CAN core provides an optimized
filter handling when the filter subscription focuses on a single CAN ID.

For the possible 2048 SFF CAN identifiers the identifier is used as an index
to access the corresponding subscription list without any further checks.
For the 2^29 possible EFF CAN identifiers a 10 bit XOR folding is used as
hash function to retrieve the EFF table index.

To benefit from the optimized filters for single CAN identifiers the
CAN_SFF_MASK or CAN_EFF_MASK have to be set into can_filter.mask together
with set CAN_EFF_FLAG and CAN_RTR_FLAG bits. A set CAN_EFF_FLAG bit in the
can_filter.mask makes clear that it matters whether a SFF or EFF CAN ID is
subscribed. E.g. in the example from above:

.. code-block:: C

    rfilter[0].can_id   = 0x123;
    rfilter[0].can_mask = CAN_SFF_MASK;

both SFF frames with CAN ID 0x123 and EFF frames with 0xXXXXX123 can pass.

To filter for only 0x123 (SFF) and 0x12345678 (EFF) CAN identifiers the
filter has to be defined in this way to benefit from the optimized filters:

.. code-block:: C

    struct can_filter rfilter[2];

    rfilter[0].can_id   = 0x123;
    rfilter[0].can_mask = (CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_SFF_MASK);
    rfilter[1].can_id   = 0x12345678 | CAN_EFF_FLAG;
    rfilter[1].can_mask = (CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK);

    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));


RAW Socket Option CAN_RAW_ERR_FILTER
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

As described in :ref:`socketcan-network-problem-notifications` the CAN interface driver can generate so
called Error Message Frames that can optionally be passed to the user
application in the same way as other CAN frames. The possible
errors are divided into different error classes that may be filtered
using the appropriate error mask. To register for every possible
error condition CAN_ERR_MASK can be used as value for the error mask.
The values for the error mask are defined in linux/can/error.h:

.. code-block:: C

    can_err_mask_t err_mask = ( CAN_ERR_TX_TIMEOUT | CAN_ERR_BUSOFF );

    setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
               &err_mask, sizeof(err_mask));


RAW Socket Option CAN_RAW_LOOPBACK
~~~~~~~                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                