/****************************************************************************/
/* Copyright 2014 MBARI.                                                    */
/* Monterey Bay Aquarium Research Institute Proprietary Information.        */
/* All rights reserved.                                                     */
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include <modbus.h>

#define SLAVE_ID        0x01
#define DEFAULT_BAUD    19200L
#define TOTAL_COILS     16
#define MODBUS_DEBUG    TRUE

int main(int argc, char* argv[])
{
    int ret;
    int coil;
    int state;
    modbus_t *ctx;
    long baud;

    if ( argc < 4)
    {
       printf("FCOIL compiled with libmodbus version %s on %s at %s\n\n",
              LIBMODBUS_VERSION_STRING, __DATE__, __TIME__);

        printf("Usage: fcoil port state coil [baud]\n");
        printf("Default baud is %ld\n\n", DEFAULT_BAUD);
        printf("Example:\n");
        printf("./fcoil com1  1 1\n");
        return -1;
    }

    /* set coil state */
    state = atoi(argv[2]);

    /* set coil address */
    coil = atoi(argv[3])-1; //address needs to be shifted for appropriate modbus addressing (libmodbus)



    /* set baud rate */
    baud = DEFAULT_BAUD;
    if ( argc == 5 )
    {
        baud = atol(argv[4]);
        switch ( baud )
        {
            case 9600:   break;
            case 19200:  break;
            case 38400:  break;
            case 57600:  break;
            case 115200: break;
            default: 
                printf("Invalid baud: %ld\n", baud);
                printf("Supported bauds: 9600, 19200, 38400, 57600, 115200\n");
                return -1;
        }
    }

    /* init the modbus interface */
    ctx = modbus_new_rtu(argv[1], baud, 'N', 8, 2);

    if (ctx == NULL)
    {
       fprintf(stderr, "Unable to allocate libmodbus context\n");
       return -1;
    }

    modbus_set_debug(ctx, MODBUS_DEBUG);
    modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK);
    modbus_set_slave(ctx, SLAVE_ID);

    if (modbus_connect(ctx) == -1)
    {
       fprintf(stderr, "ERROR Connection failed: %s\n",
               modbus_strerror(errno));
       modbus_free(ctx);
       return -1;
    }

    /* write the coil state */
    if (MODBUS_DEBUG)
    {
       printf("modbus_write_bit(SLAVE %d, COIL %d, STATE %d): ", 
              SLAVE_ID, coil, state);
    }

    ret = modbus_write_bit(ctx, coil, state);

    /* check for errors */
    if (ret != 1) 
    {
       printf("FAILED\n");
       ret = -1;
    }
    else
    {
       printf("OK\n");
       ret = 0;
    }
 
    /* Close the connection */
    modbus_close(ctx);
    modbus_free(ctx);

    return ret;
}
