#include <stdio.h>
#include <ntcan.h>
/*
* This example demonstrates how the NTCAN-API can be used to open a handle,
* set a baudrate and wait for reception of a Classical CAN frames or CAN FD
* frames with an identifier that has been previously enabled for this
* handle.
* Finally all proper cleanup operations are performed
*/
int main()
{
    int net=0; /* Logical net number (here: 42) */
    uint32_t mode=NTCAN_MODE_FD; /* Mode bits for canOpen */
    int32_t txqueuesize=8; /* Maximum number of messages to transmit */
    int32_t rxqueuesize=8; /* Maximum number of messages to receive */
    int32_t txtimeout=100; /* Timeout for transmit in ms */
    int32_t rxtimeout=10000; /* Timeout for receiving data in ms */
    NTCAN_HANDLE rxhandle; /* CAN handle returned by canOpen() */
    NTCAN_RESULT retvalue; /* Return values of NTCAN API calls */
    NTCAN_BAUDRATE_X baud; /* Bit rate configuration */
    CMSG_X cmsg[8]; /* Buffer for can messages */
    int i; /* Loop counter */
    int32_t len; /* Size in # of messages for canReadX() */
    int32_t idCount = 0x800;
/* ############################################################### */
    retvalue = canOpen( net,
                        mode,
                        txqueuesize,
                        rxqueuesize,
                        txtimeout,
                        rxtimeout,
                        &rxhandle);
    if (retvalue != NTCAN_SUCCESS)
    {
        printf("canOpen() failed with error %d!\n", retvalue);
        return(-1);
    }
    printf("function canOpen() returned OK !\n");
/* ############################### ################################ */
    baud.mode = NTCAN_BAUDRATE_MODE_INDEX;
    baud.flags = NTCAN_BAUDRATE_FLAG_FD;
    baud.arb.u.idx = NTCAN_BAUD_1000; /* Nominal bit rate: 1000KBit/s */
    baud.data.u.idx = NTCAN_BAUD_5000; /* Data phase bit rate: 5 MBit/s */
    retvalue = canSetBaudrateX(rxhandle, &baud);
    if (retvalue != 0)
    { 
        printf("canSetBaudrateX() failed with error %d!\n", retvalue);
        canClose(rxhandle);
        return(-1);
    }
    printf("function canSetBaudrateX() returned OK !\n");
/* ############################################################### */
    retvalue = canIdRegionAdd(rxhandle, 0, &idCount); /* Enable CAN-IDs 0-0x7ff */
    if (retvalue != NTCAN_SUCCESS)
    {
        printf("canIdRegionAdd() failed with error %d!\n", retvalue);
        canClose(rxhandle);
        return(-1);
    }
    printf("function canIdRegionAdd() returned OK !\n");
/* ############################################################### */
    for(;;) {
        /*
        * Set max numbers of messages that can be returned with
        * one canReadX() call according to buffer size.
        */
        len = 8;
        retvalue = canReadX(rxhandle, &cmsg[0], &len, NULL);
        if (retvalue == NTCAN_RX_TIMEOUT)
        {
            printf("canReadX() returned timeout\n");
            continue;
        }
        else if(retvalue != NTCAN_SUCCESS)
        { 
            printf("canReadX() failed with error %d!\n", retvalue);
        }
        else
        { 
            printf("Function canReadX() returned OK !\n");
            printf("ID of received message :%x!\n", cmsg[0].id);
            printf("DLC of received message :%x!\n", NTCAN_DLC(cmsg[0].len));
            if(NTCAN_IS_FD(cmsg[0].len)) {
                // printf("BRS of received message :%x!\n", !NTCAN_IS_FD_WITHOUT_BRS(cmsg[0].len));
                if(NTCAN_IS_FD_WITHOUT_BRS(cmsg[0].len))
                    printf("CAN FD without BRS!\nThe bit rate of data phase is NOT changed.\n");
                else
                    printf("CAN FD with BRS!\nThe bit rate of data phase is changed.\n");
            } else 
            {
                printf("RTR of received message :%x!\n", NTCAN_IS_RTR(cmsg[0].len));
            }
            for (i=0;i<NTCAN_LEN_TO_DATASIZE(cmsg[0].len);i++)
                printf("Byte %d of received message :%x!\n", i, cmsg[0].data[i]);
        }
        break;
    };
/* ############################################################### */
    retvalue = canIdDelete( rxhandle, 0);
    if (retvalue != NTCAN_SUCCESS)
        printf("canIdDelete() failed with error %d!\n", retvalue);
    printf("function canIdDelete() returned OK !\n");
/* ############################################################### */
    retvalue = canClose (rxhandle);
    if (retvalue != NTCAN_SUCCESS)
        printf("canClose() failed with error %d!\n", retvalue);
    else
        printf("canClose() returned OK !\n");
/* ############################################################### */
    return(0);
}