
#include "LibmodbusWrapper.h"

namespace modbus
{
    CLibmodbusWrapper::CLibmodbusWrapper()
        :_ctx(NULL)
        , _ip("")
        ,_port(-1)
        ,_slave_id(-1)
    {
    }


    CLibmodbusWrapper::~CLibmodbusWrapper()
    {
        deinitialize();
    }

    void CLibmodbusWrapper::deinitialize()
    {
        if (_ctx)
        {
            modbus_close(_ctx);
            modbus_free(_ctx);
            _ctx = NULL;
            _ip = "";
            _port = -1;
            _slave_id = -1;
        }
    }
    int CLibmodbusWrapper::initialize(const char *ip, int port, int slave_id)
    {
        int rc = 0;

        this->deinitialize();

        _ctx = modbus_new_tcp(ip, port);
        if (_ctx == NULL)
        {
            //����ʧ��
            fprintf(stderr, "CLibmodbusWrapper: Unable to allocate libmodbus context\n");
            return -3;
        }

        // ���õ���ģʽ
        modbus_set_debug(_ctx, FALSE);

        // �������ӵ�slave�ţ��˴�Ϊ1
        rc = modbus_set_slave(_ctx, slave_id);
        if (rc == -1)
        {
            fprintf(stderr, "CLibmodbusWrapper: Invalid slave ID\n");
            modbus_free(_ctx);
            _ctx = NULL;
            return -2;
        }

        rc = modbus_connect(_ctx);
        if (rc == -1)
        {
            fprintf(stderr, "CLibmodbusWrapper: Connection failed: %s\n", modbus_strerror(errno));
            modbus_free(_ctx);
            _ctx = NULL;
            return -1;
        }

        _ip = ip;
        _port = port;
        _slave_id = slave_id;

        return 0;
    }

    int CLibmodbusWrapper::read_registers(int addr, int nb, uint16_t *dest)
    {
        if (modbus_read_registers(_ctx, addr, nb, dest) == -1)
        {
            fprintf(stderr, "CLibmodbusWrapper: Read registers failed: %s\n", modbus_strerror(errno));
            // printf("%s---%s, %d\n", modbus_strerror(errno), "Broken pipe", strcmp(modbus_strerror(errno), "Broken pipe")==0?1:0);
            return -1;
        }
        return 0;
    }

    int CLibmodbusWrapper::write_registers(int addr, int nb, uint16_t *dest)
    {
        if (modbus_write_registers(_ctx, addr, nb, dest) == -1)
        {
            fprintf(stderr, "CLibmodbusWrapper: Write registers failed: %s\n", modbus_strerror(errno));
            return -1;
        }
        return 0;
    }


    int CLibmodbusWrapper::read_register(int addr, uint16_t *dest)
    {
        if (modbus_read_registers(_ctx, addr, 1, dest) == -1)
        {
            fprintf(stderr, "CLibmodbusWrapper: Read registers failed: %s\n", modbus_strerror(errno));
            return -1;
        }
        return 0;
    }

    int CLibmodbusWrapper::write_register(int addr, uint16_t *dest)
    {
        if (modbus_write_registers(_ctx, addr, 1, dest) == -1)
        {
            fprintf(stderr, "CLibmodbusWrapper: Write registers failed: %s\n", modbus_strerror(errno));
            return -1;
        }
        return 0;
    }
}
