Exemple #1
0
int main(int argc, char *argv[])
{
    modbus_t *m;
    uint8_t *q;
    int header_length;
    int socket;
    int rc;

    m = modbus_new_tcp("127.0.0.1", 1502);
    q = malloc(MODBUS_TCP_MAX_ADU_LENGTH);

    header_length = modbus_get_header_length(m);

    modbus_set_debug(m, TRUE);
    modbus_set_error_recovery(m, TRUE);

    socket = modbus_tcp_listen(m, 1);
    modbus_tcp_accept(m, &socket);

    while (1) {
	rc = modbus_receive(m, -1, q);
	if (rc < 0) {
	    error("modbus_receive() returned %d", rc);
	}

	dump_buffer(stdout, q, rc);
    }
}
ModbusClientV1::ModbusClientV1(char* device)
{
	ctx = modbus_new_rtu(device, 115200, 'E', 8, 1); // Port_name, Speed, Parity, Data_bits, Stop_bits
	if (ctx == NULL)
	{
		fprintf(stderr, "Unable to create the libmodbus context\n");
		return;
	}

	if (verbose > 4)
	{
		modbus_set_debug(ctx, 1);
	}

	int rc = modbus_set_slave(ctx, 1);

	// Connecting to existing modbus socket
	rc = modbus_connect(ctx);
	if (rc == -1)
	{
		fprintf(stderr, "Connection failed [%s]\n", modbus_strerror(errno));
		modbus_free(ctx);
		return;
	}

	// Change bytes and response timeouts for connections
	change_byte_timeout(0, 10000); /* 10 ms */
	change_response_timeout(0, 100000); /* 100 ms */

	isInitialized = true;
}
Exemple #3
0
//open serial port
bool EnergyCamOpen(unsigned int dwPort ){
  m_dwPort=dwPort;
  char comDeviceName[100];
      
  sprintf(comDeviceName, "/dev/ttyUSB%d", dwPort);
  m_ctx = (modbus_t* )modbus_new_rtu(comDeviceName, m_dwBaud, 'E', 8, 1); // parity 'E'ven used by EnergyCam's freemodbus implementation
    
  if(NULL == m_ctx)
    return false;

  modbus_set_debug( m_ctx, false);
  modbus_set_slave( m_ctx, 1);

  if (modbus_connect(m_ctx) == -1) {
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));

    modbus_free(m_ctx);
    m_ctx = NULL;
    return false; 
  } 
  else{
    printf,( "Connection OK: \n");
  }

  return true;
}
Exemple #4
0
/* Version 2.9.2 */
static int mb_init_connection (mb_host_t *host) /* {{{ */
{
  int status;

  if (host == NULL)
    return (EINVAL);

  if (host->connection != NULL)
    return (0);

  if (host->conntype == MBCONN_TCP)
  {
    if ((host->port < 1) || (host->port > 65535))
      host->port = MODBUS_TCP_DEFAULT_PORT;

    DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.",
        host->node, host->port);

    host->connection = modbus_new_tcp (host->node, host->port);
    if (host->connection == NULL)
    {
      ERROR ("Modbus plugin: Creating new Modbus/TCP object failed.");
      return (-1);
    }
  }
  else
  {
    DEBUG ("Modbus plugin: Trying to connect to \"%s\", baudrate %i.",
        host->node, host->baudrate);

    host->connection = modbus_new_rtu (host->node, host->baudrate, 'N', 8, 1);
    if (host->connection == NULL)
    {
      ERROR ("Modbus plugin: Creating new Modbus/RTU object failed.");
      return (-1);
    }
  }

#if COLLECT_DEBUG
  modbus_set_debug (host->connection, 1);
#endif

  /* We'll do the error handling ourselves. */
  modbus_set_error_recovery (host->connection, 0);

  status = modbus_connect (host->connection);
  if (status != 0)
  {
    ERROR ("Modbus plugin: modbus_connect (%s, %i) failed with status %i.",
        host->node, host->port ? host->port : host->baudrate, status);
    modbus_free (host->connection);
    host->connection = NULL;
    return (status);
  }

  return (0);
} /* }}} int mb_init_connection */
int main(void)
{
	int s = -1;
	modbus_t *ctx;
	modbus_mapping_t *mb_mapping;
	int rc = -1;
	pthread_t tId;

	pthread_attr_t attr;
	/* Initialize and set thread detached attribute */
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	ctx = modbus_new_tcp("127.0.0.1", 1502);
	modbus_set_debug(ctx, TRUE);

	mb_mapping = modbus_mapping_new(500, 500, 500, 500);
	if (mb_mapping == NULL) {
		fprintf(stderr, "Failed to allocate the mapping: %s\n",
			modbus_strerror(errno));
		modbus_free(ctx);
		return -1;
	}

	s = modbus_tcp_listen(ctx, 1);

	int id = 0;
	for (;;) {
		id++;
		printf("Waiting for another connection...\n\n");
		modbus_tcp_accept(ctx, &s);

		modbus_t *new_ctx = modbus_clone_tcp(ctx);

		SA *sa = (SA*)malloc(sizeof(SA));
		sa->ctxt = new_ctx;
		sa->mm = mb_mapping;
		sa->id = id;

		rc = pthread_create(&tId, &attr, serveClient, (void *)sa); 
		if (rc) {
			printf("ERROR; return code from pthread_create() is %d\n", rc);
			break;
		}
	}

	printf("Quit the loop: %s\n", modbus_strerror(errno));

	if (s != -1) {
		close(s);
	}	
	modbus_mapping_free(mb_mapping);
	modbus_close(ctx);
	modbus_free(ctx);

	return 0;
}
int main(int argc, char *arg[]) {
    modbus_t *ctx, *dup_ctx;
    int server_fd;
    pthread_t tcp_thread;

    file_read_random_data(RANDOM_DATA_POOL);

    if ((ctx = modbus_new_tcp("SERVER", MODBUS_TCP_DEFAULT_PORT)) == NULL) {
	printf("Failied to initialise modbus\n");
	return -1;
    }

    mb_mapping = modbus_mapping_new(0, 0, file_get_highest_channel(), 0);

listen:
    if ((server_fd = modbus_tcp_listen(ctx, LISTEN_BACKLOG)) < 0) {
	printf("Failed to initiate modbus_tcp server, %i\n", server_fd);
	printf("Root permissions are needed to open ports below 1024\n");
	printf("Currently configured to open port %i\n",
			MODBUS_TCP_DEFAULT_PORT);
	modbus_free(ctx);
	return -1;
    }

    while (1) {
	modbus_set_debug(ctx, TRUE);
	if (modbus_tcp_accept(ctx, &server_fd) < 0) {
	    /* libmodbus closes the supplied socket if accept fails - this may
	     * be making new connections impossible */
	    printf("Accept failed \n");
	    goto listen;
	}
	modbus_set_debug(ctx, FALSE);
	dup_ctx = malloc(sizeof(struct ctx_data));
	memcpy(dup_ctx, ctx, sizeof(struct ctx_data));
	pthread_create(&tcp_thread, 0, connection, dup_ctx);
    }

    modbus_mapping_free(mb_mapping);
    close(server_fd);
    modbus_free(ctx);

    return 0;
}
static int ctx_set_debug(lua_State *L)
{
	ctx_t *ctx = ctx_check(L, 1);
	bool opt;
	if (lua_isnil(L, -1)) {
		opt = true;
	} else {
		opt = lua_toboolean(L, -1);
	}
	modbus_set_debug(ctx->modbus, opt);
	return 0;
}
Exemple #8
0
static int openSerial(const char *device, int baudrate, char parity, int data_bits, int stop_bits)
{
	int ret = 0;
	if (!mb) {
		mb = modbus_new_rtu(device, baudrate, parity, data_bits, stop_bits);
		struct timeval tv = { 0, 100000 };
		modbus_set_response_timeout(mb, &tv);
		modbus_set_debug(mb, 1);
		ret = modbus_connect(mb);
		if (ret < 0)
			closeSerial();
	}
	return ret;
}
Exemple #9
0
/* Version 2.0.3 */
static int mb_init_connection (mb_host_t *host) /* {{{ */
{
  int status;

  if (host == NULL)
    return (EINVAL);

#if COLLECT_DEBUG
  modbus_set_debug (&host->connection, 1);
#endif

  /* We'll do the error handling ourselves. */
  modbus_set_error_handling (&host->connection, NOP_ON_ERROR);

  if (host->conntype == MBCONN_TCP)
  {
    if ((host->port < 1) || (host->port > 65535))
      host->port = MODBUS_TCP_DEFAULT_PORT;

    DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.",
        host->node, host->port);

    modbus_init_tcp (&host->connection,
        /* host = */ host->node,
        /* port = */ host->port);
  }
  else	/* MBCONN_RTU */
  {
    DEBUG ("Modbus plugin: Trying to connect to \"%s\".", host->node);

    modbus_init_rtu (&host->connection,
       /* device = */ host->node,
     /* baudrate = */ host->baudrate,
                      'N', 8, 1, 0);
  }

  status = modbus_connect (&host->connection);
  if (status != 0)
  {
    ERROR ("Modbus plugin: modbus_connect (%s, %i) failed with status %i.",
        host->node, host->port ? host->port : host->baudrate, status);
    return (status);
  }

  host->is_connected = 1;
  return (0);
} /* }}} int mb_init_connection */
Exemple #10
0
/* Version 2.9.2 */
static int mb_init_connection (mb_host_t *host) /* {{{ */
{
  int status;

  if (host == NULL)
    return (EINVAL);

  if (host->connection != NULL)
    return (0);

  /* Only reconnect once per interval. */
  if (host->have_reconnected)
    return (-1);

  if ((host->port < 1) || (host->port > 65535))
    host->port = MODBUS_TCP_DEFAULT_PORT;

  DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.",
      host->node, host->port);

  host->connection = modbus_new_tcp (host->node, host->port);
  if (host->connection == NULL)
  {
    host->have_reconnected = 1;
    ERROR ("Modbus plugin: Creating new Modbus/TCP object failed.");
    return (-1);
  }

  modbus_set_debug (host->connection, 1);

  /* We'll do the error handling ourselves. */
  modbus_set_error_recovery (host->connection, 0);

  status = modbus_connect (host->connection);
  if (status != 0)
  {
    ERROR ("Modbus plugin: modbus_connect (%s, %i) failed with status %i.",
        host->node, host->port, status);
    modbus_free (host->connection);
    host->connection = NULL;
    return (status);
  }

  host->have_reconnected = 1;
  return (0);
} /* }}} int mb_init_connection */
Exemple #11
0
static int mb_init_connection (mb_host_t *host) /* {{{ */
{
  int status;

  if (host == NULL)
    return (EINVAL);

  if (host->is_connected)
    return (0);

  /* Only reconnect once per interval. */
  if (host->have_reconnected)
    return (-1);

  modbus_set_debug (&host->connection, 1);

#if 0
  /* We'll do the error handling ourselves. */
  modbus_set_error_handling (&host->connection, NOP_ON_ERROR);
#endif

  if ((host->port < 1) || (host->port > 65535))
    host->port = MODBUS_TCP_DEFAULT_PORT;

  DEBUG ("Modbus plugin: Trying to connect to \"%s\", port %i.",
      host->node, host->port);

  modbus_init_tcp (&host->connection,
      /* host = */ host->node);
#if 0
      /* port = */ host->port);
#endif

  status = modbus_connect (&host->connection);
  if (status != 0)
  {
    ERROR ("Modbus plugin: modbus_connect (%s, %i) failed with status %i.",
        host->node, host->port, status);
    return (status);
  }

  host->is_connected = 1;
  host->have_reconnected = 1;
  return (0);
} /* }}} int mb_init_connection */
modbus_t *
m_connect(char *host, char *port)
{
    modbus_t *ctx;

    if ((ctx = modbus_new_tcp_pi(host, port)) == NULL)
        err(1, "ERROR: %s: modbus_new_tcp_pi()", __FUNCTION__);

    if (f_debug > 2)
        modbus_set_debug(ctx, TRUE);

    if (modbus_connect(ctx) < 0) {
        modbus_free(ctx);
        errx(1, "ERROR: %s: modbus_connect()", __FUNCTION__);
    }

    return ctx;
}
Exemple #13
0
int main(int argc, char *argv[])
{
    uint16_t *tab_rp_registers = NULL;
    modbus_t *ctx = NULL;
    uint32_t sec_to = 1;
    uint32_t usec_to = 0;
    int i;
    int rc;
    int nb_points = 1;
    ctx = modbus_new_rtu(SERIAL_PORT, BAUD_RATE, PARITY, BYTE_SIZE, STOP_BITS);
    if (ctx == NULL) {
        fprintf(stderr, "Unable to allocate libmodbus context\n");
        return -1;
    }
    modbus_set_debug(ctx, TRUE);
    modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL);
    modbus_set_slave(ctx, SERVER_ID);
    modbus_get_response_timeout(ctx, &sec_to, &usec_to);
    modbus_enable_rpi(ctx,TRUE);
    modbus_configure_rpi_bcm_pin(ctx,RPI_PIN);
    modbus_rpi_pin_export_direction(ctx);


    //modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec);
    if (modbus_connect(ctx) == -1)
    {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
    // modbus_get_response_timeout(ctx, &new_response_to_sec, &new_response_to_usec);
    /* Allocate and initialize the memory to store the registers */
    tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t));
    memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
    rc = modbus_read_registers(ctx, 97,1, tab_rp_registers);
    printf("Date received is : %d\n",tab_rp_registers[0]);
    free(tab_rp_registers);

    /* Close the connection */
    modbus_rpi_pin_unexport_direction(ctx);
    modbus_close(ctx);
    modbus_free(ctx);
}
Exemple #14
0
uint8_t *raw_data_command(int *re_size,int size,uint8_t *raw_req)
{
	modbus_t *sdl;
	int req_length,re_try = 0;
	//int rc;
	uint8_t *rsp;
	//raw_req = malloc(MODBUS_RTU_MAX_ADU_LENGTH);
	rsp = malloc(MODBUS_RTU_MAX_ADU_LENGTH);
sdl_wifi:
	sdl = modbus_new_tcp("169.254.114.25",502);
	//sdl = modbus_new_tcp("192.168.1.25",502);
	struct timeval old_response_timeout;
	struct timeval response_timeout;

	/* Save original timeout */
	modbus_get_response_timeout(sdl, &old_response_timeout);

	/* Define a new and too short timeout! */
	response_timeout.tv_sec = 2;
	response_timeout.tv_usec = 0;
	modbus_set_response_timeout(sdl, &response_timeout);

    modbus_set_debug(sdl, TRUE);
	modbus_set_error_recovery(sdl,
                              MODBUS_ERROR_RECOVERY_LINK |
                              MODBUS_ERROR_RECOVERY_PROTOCOL);
	
	modbus_set_slave(sdl,1);

	if (modbus_connect(sdl) == -1) 
	{    
		if(re_try < 2){re_try++; sleep(2);goto sdl_wifi;}
		return NULL;
	}
	req_length = modbus_send_raw_request(sdl, raw_req, size*sizeof(uint8_t));
	//rc = modbus_receive_confirmation(sdl, rsp);
	*re_size = modbus_receive_confirmation(sdl, rsp);
	//printf("%s\n",rsp);
	//printf("%d\n",*re_size);
	modbus_close(sdl);
	modbus_free(sdl);
	return rsp;
}
Exemple #15
0
int main(int argc, char** argv)
{
	modbus_param_t mb_param;
	int half_duplex  =  0;
	int c;
	char ** svp;
	int i;
	int set_args_index = -1;
	char set_args[MAX_SETS][MAX_STR];
	char *device  =  NULL;
	
	memset(set_args, 0, sizeof(set_args));

	while( (c =  getopt(argc, argv, "hnvd:s:")) !=  -1) {
		switch(c){
		case 's':
			/* NOTE IMPORTANT! This block MUST COME FIRST in the switch, before any opts,
			   otherwise GCC or getopts or something gets the indexes all wrong */
                        //  Thanks to http://stackoverflow.com/questions/3939157/c-getopt-multiple-value
			// Special case the first arg
			set_args_index = 0;
			strcpy(set_args[0], optarg);
			// Loop the rest
			i=1;
			while(optind < argc && *argv[optind] !=  '-'){
				strcpy(set_args[i], argv[optind]);
				if(debug > 0){
					printf("getopts multiopt: %s %s\n", argv[optind], set_args[i] );
				}
				// Ugly but explicit
				set_args_index++;
				i++;
				optind++;
			}
			break;
		case 'h': 
			half_duplex  =  1;
			break;
		case 'v': 
			debug  =  1;
			break;
		case 'n': 
			dry  =  1;
			break;
		case 'd':
			device = optarg;

		default:
			break;
		}
	}


	if(!device){
		printf("need to give serial port on command line\n");
		usage();
		return(1);
	}

	


	/* Setup the serial port parameters */
	modbus_init_rtu(&mb_param, device, 9600, "none", 8, 2, half_duplex);	


	if(debug > 0){
		modbus_set_debug(&mb_param, TRUE);
	}

	
	/* Open the MODBUS connection */
	if (modbus_connect(&mb_param)  ==  -1) {
		printf("ERROR Connection failed\n");
		return(1);
	}

	if(debug > 0){
		printf("We have %d set args to process...\n", set_args_index + 1);
	}

	
	i = set_args_index;
	while(i >= 0){
		printf("\nSetting values... %s\n", set_args[i]);
		set_options(&mb_param, set_args[i]);
		i--;
	}

	if(dry < 1 && set_args_index >= 0){
		commit_options(&mb_param);
	}

	if(dry < 1){
		read_values(&mb_param);
	}
	
	/* Close the MODBUS connection */
	modbus_close(&mb_param);
	
	return(0);
}
int main(int argc, char **argv)
{
    int retval = 0;
    modbus_t *mb_ctx;
    haldata_t *haldata;
    slavedata_t slavedata;
    int slave;
    int hal_comp_id;
    struct timespec loop_timespec, remaining;
    int baud, bits, stopbits, verbose;
    char *device, *endarg;
    char parity;
    int opt;
    int argindex, argvalue;
    done = 0;

    // assume that nothing is specified on the command line
    baud = 38400;
    bits = 8;
    stopbits = 1;
    verbose = 0;
    device = "/dev/ttyS0";
    parity = 'O';

    /* slave / register info */
    slave = 1;
    slavedata.read_reg_start = START_REGISTER_R;
    slavedata.read_reg_count = NUM_REGISTERS_R;
    slavedata.write_reg_start = START_REGISTER_W;
    slavedata.write_reg_count = NUM_REGISTERS_R;

    // process command line options
    while ((opt=getopt_long(argc, argv, option_string, long_options, NULL)) != -1) {
        switch(opt) {
            case 'b':   // serial data bits, probably should be 8 (and defaults to 8)
                argindex=match_string(optarg, bitstrings);
                if (argindex<0) {
                    printf("gs2_vfd: ERROR: invalid number of bits: %s\n", optarg);
                    retval = -1;
                    goto out_noclose;
                }
                bits = atoi(bitstrings[argindex]);
                break;
            case 'd':   // device name, default /dev/ttyS0
                // could check the device name here, but we'll leave it to the library open
                if (strlen(optarg) > FILENAME_MAX) {
                    printf("gs2_vfd: ERROR: device node name is too long: %s\n", optarg);
                    retval = -1;
                    goto out_noclose;
                }
                device = strdup(optarg);
                break;
            case 'g':
            case 'v':
                verbose = 1;
                break;
            case 'n':   // module base name
                if (strlen(optarg) > HAL_NAME_LEN-20) {
                    printf("gs2_vfd: ERROR: HAL module name too long: %s\n", optarg);
                    retval = -1;
                    goto out_noclose;
                }
                modname = strdup(optarg);
                break;
            case 'p':   // parity, should be a string like "even", "odd", or "none"
                argindex=match_string(optarg, paritystrings);
                if (argindex<0) {
                    printf("gs2_vfd: ERROR: invalid parity: %s\n", optarg);
                    retval = -1;
                    goto out_noclose;
                }
                parity = paritychars[argindex];
                break;
            case 'r':   // Baud rate, 38400 default
                argindex=match_string(optarg, ratestrings);
                if (argindex<0) {
                    printf("gs2_vfd: ERROR: invalid baud rate: %s\n", optarg);
                    retval = -1;
                    goto out_noclose;
                }
                baud = atoi(ratestrings[argindex]);
                break;
            case 's':   // stop bits, defaults to 1
                argindex=match_string(optarg, stopstrings);
                if (argindex<0) {
                    printf("gs2_vfd: ERROR: invalid number of stop bits: %s\n", optarg);
                    retval = -1;
                    goto out_noclose;
                }
                stopbits = atoi(stopstrings[argindex]);
                break;
            case 't':   // target number (MODBUS ID), default 1
                argvalue = strtol(optarg, &endarg, 10);
                if ((*endarg != '\0') || (argvalue < 1) || (argvalue > 254)) {
                    printf("gs2_vfd: ERROR: invalid slave number: %s\n", optarg);
                    retval = -1;
                    goto out_noclose;
                }
                slave = argvalue;
                break;
            case 'h':
            default:
                usage(argc, argv);
                exit(0);
                break;
        }
    }

    printf("%s: device='%s', baud=%d, parity='%c', bits=%d, stopbits=%d, address=%d, verbose=%d\n",
           modname, device, baud, parity, bits, stopbits, slave, verbose);
    /* point TERM and INT signals at our quit function */
    /* if a signal is received between here and the main loop, it should prevent
            some initialization from happening */
    signal(SIGINT, quit);
    signal(SIGTERM, quit);

    /* Assume 38.4k O-8-1 serial settings, device 1 */
    mb_ctx = modbus_new_rtu(device, baud, parity, bits, stopbits);
    if (mb_ctx == NULL) {
        printf("%s: ERROR: couldn't open modbus serial device: %s\n", modname, modbus_strerror(errno));
        goto out_noclose;
    }

    /* the open has got to work, or we're out of business */
    if (((retval = modbus_connect(mb_ctx))!=0) || done) {
        printf("%s: ERROR: couldn't open serial device: %s\n", modname, modbus_strerror(errno));
        goto out_noclose;
    }

    modbus_set_debug(mb_ctx, verbose);

    modbus_set_slave(mb_ctx, slave);

    /* create HAL component */
    hal_comp_id = hal_init(modname);
    if ((hal_comp_id < 0) || done) {
        printf("%s: ERROR: hal_init failed\n", modname);
        retval = hal_comp_id;
        goto out_close;
    }

    /* grab some shmem to store the HAL data in */
    haldata = (haldata_t *)hal_malloc(sizeof(haldata_t));
    if ((haldata == 0) || done) {
        printf("%s: ERROR: unable to allocate shared memory\n", modname);
        retval = -1;
        goto out_close;
    }

    retval = hal_pin_s32_newf(HAL_OUT, &(haldata->stat1), hal_comp_id, "%s.status-1", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_s32_newf(HAL_OUT, &(haldata->stat2), hal_comp_id, "%s.status-2", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->freq_cmd), hal_comp_id, "%s.frequency-command", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->freq_out), hal_comp_id, "%s.frequency-out", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->curr_out), hal_comp_id, "%s.output-current", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->DCBusV), hal_comp_id, "%s.DC-bus-volts", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->outV), hal_comp_id, "%s.output-voltage", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->RPM), hal_comp_id, "%s.motor-RPM", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->scale_freq), hal_comp_id, "%s.scale-frequency", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->power_factor), hal_comp_id, "%s.power-factor", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_float_newf(HAL_OUT, &(haldata->load_pct), hal_comp_id, "%s.load-percentage", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_s32_newf(HAL_OUT, &(haldata->FW_Rev), hal_comp_id, "%s.firmware-revision", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_param_s32_newf(HAL_RW, &(haldata->errorcount), hal_comp_id, "%s.error-count", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_param_float_newf(HAL_RW, &(haldata->looptime), hal_comp_id, "%s.loop-time", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_param_s32_newf(HAL_RW, &(haldata->retval), hal_comp_id, "%s.retval", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_bit_newf(HAL_OUT, &(haldata->at_speed), hal_comp_id, "%s.at-speed", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_bit_newf(HAL_OUT, &(haldata->is_stopped), hal_comp_id, "%s.is-stopped", modname); // JET
    if (retval!=0) goto out_closeHAL; 
    retval = hal_pin_float_newf(HAL_IN, &(haldata->speed_command), hal_comp_id, "%s.speed-command", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_bit_newf(HAL_IN, &(haldata->spindle_on), hal_comp_id, "%s.spindle-on", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_bit_newf(HAL_IN, &(haldata->spindle_fwd), hal_comp_id, "%s.spindle-fwd", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_bit_newf(HAL_IN, &(haldata->spindle_rev), hal_comp_id, "%s.spindle-rev", modname); //JET
    if (retval!=0) goto out_closeHAL;
    retval = hal_pin_bit_newf(HAL_IN, &(haldata->err_reset), hal_comp_id, "%s.err-reset", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_param_float_newf(HAL_RW, &(haldata->speed_tolerance), hal_comp_id, "%s.tolerance", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_param_float_newf(HAL_RW, &(haldata->motor_hz), hal_comp_id, "%s.nameplate-HZ", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_param_float_newf(HAL_RW, &(haldata->motor_RPM), hal_comp_id, "%s.nameplate-RPM", modname);
    if (retval!=0) goto out_closeHAL;
    retval = hal_param_s32_newf(HAL_RW, &(haldata->ack_delay), hal_comp_id, "%s.ack-delay", modname);
    if (retval!=0) goto out_closeHAL;

    /* make default data match what we expect to use */
    *(haldata->stat1) = 0;
    *(haldata->stat2) = 0;
    *(haldata->freq_cmd) = 0;
    *(haldata->freq_out) = 0;
    *(haldata->curr_out) = 0;
    *(haldata->DCBusV) = 0;
    *(haldata->outV) = 0;
    *(haldata->RPM) = 0;
    *(haldata->scale_freq) = 0;
    *(haldata->power_factor) = 0;
    *(haldata->load_pct) = 0;
    *(haldata->FW_Rev) = 0;
    haldata->errorcount = 0;
    haldata->looptime = 0.1;
    haldata->motor_RPM = 1730;
    haldata->motor_hz = 60;
    haldata->speed_tolerance = 0.01;
    haldata->ack_delay = 2;
    *(haldata->err_reset) = 0;
    *(haldata->spindle_on) = 0;
    *(haldata->spindle_fwd) = 1;
    *(haldata->spindle_rev) = 0;
    haldata->old_run = -1;		// make sure the initial value gets output
    haldata->old_dir = -1;
    haldata->old_err_reset = -1;
    hal_ready(hal_comp_id);
    
    /* here's the meat of the program.  loop until done (which may be never) */
    while (done==0) {
        read_data(mb_ctx, &slavedata, haldata);
        write_data(mb_ctx, &slavedata, haldata);
        /* don't want to scan too fast, and shouldn't delay more than a few seconds */
        if (haldata->looptime < 0.001) haldata->looptime = 0.001;
        if (haldata->looptime > 2.0) haldata->looptime = 2.0;
        loop_timespec.tv_sec = (time_t)(haldata->looptime);
        loop_timespec.tv_nsec = (long)((haldata->looptime - loop_timespec.tv_sec) * 1000000000l);
        nanosleep(&loop_timespec, &remaining);
    }
    
    retval = 0;	/* if we get here, then everything is fine, so just clean up and exit */
out_closeHAL:
    hal_exit(hal_comp_id);
out_close:
    modbus_close(mb_ctx);
    modbus_free(mb_ctx);
out_noclose:
    return retval;
}
Exemple #17
0
retCode get_tx_connection(const int this_mb_tx_num, int *ret_connected)
{
    char *fnct_name = "get_tx_connection";
    int ret;
    mb_tx_t   *this_mb_tx;
    mb_link_t *this_mb_link;
    int        this_mb_link_num;
    struct timeval timeout;

    if (this_mb_tx_num < 0 || this_mb_tx_num > gbl.tot_mb_tx) {
        ERR(gbl.init_dbg, "parameter out of range this_mb_tx_num[%d]", this_mb_tx_num);
        return retERR;
    }
    this_mb_tx = &gbl.mb_tx[this_mb_tx_num];

    if (ret_connected == NULL) {
        ERR(this_mb_tx->cfg_debug, "NULL pointer");
        return retERR;
    }

    this_mb_link_num = this_mb_tx->mb_link_num;
    if (this_mb_link_num < 0 || this_mb_link_num >= gbl.tot_mb_links) {
        ERR(this_mb_tx->cfg_debug, "parameter out of range this_mb_link_num[%d]", this_mb_link_num);
        return retERR;
    }
    this_mb_link = &gbl.mb_links[this_mb_link_num];

    *ret_connected = 0; //defaults to not connected

    if (modbus_get_socket(this_mb_link->modbus) < 0) {
        ret = modbus_connect(this_mb_link->modbus);
        if (ret != 0 || modbus_get_socket(this_mb_link->modbus) < 0) {
            modbus_set_socket(this_mb_link->modbus, -1); //some times ret was < 0 and fd > 0
            ERR(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] cannot connect to link, ret[%d] fd[%d]",
                this_mb_tx_num, this_mb_tx->mb_link_num, ret, modbus_get_socket(this_mb_link->modbus));
            return retOK; //not connected
        }
        DBG(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] new connection -> fd[%d]",
            this_mb_tx_num, this_mb_tx->mb_link_num, modbus_get_socket(this_mb_link->modbus));
    }
    else {
        DBG(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] already connected to fd[%d]",
            this_mb_tx_num, this_mb_tx->mb_link_num, modbus_get_socket(this_mb_link->modbus));
    }

    //set slave id according to each mb_tx
    ret = modbus_set_slave(this_mb_link->modbus, this_mb_tx->mb_tx_slave_id);
    if (ret != 0) {
        ERR(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] cannot set slave [%d]",
            this_mb_tx_num, this_mb_tx->mb_link_num, this_mb_tx->mb_tx_slave_id);
        return retOK; //not connected
    }

    //set the low level mb_link debug according to each mb_tx
    modbus_set_debug(this_mb_link->modbus, this_mb_tx->protocol_debug);

    //set response and byte timeout according to each mb_tx
    timeout.tv_sec  = this_mb_tx->mb_response_timeout_ms / 1000;
    timeout.tv_usec = (this_mb_tx->mb_response_timeout_ms % 1000) * 1000;
#if (LIBMODBUS_VERSION_CHECK(3, 1, 2))
    modbus_set_response_timeout(this_mb_link->modbus, timeout.tv_sec, timeout.tv_usec);
#else
    modbus_set_response_timeout(this_mb_link->modbus, &timeout);
#endif
    //DBG(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] response timeout [%d] ([%d] [%d])",
    //    this_mb_tx_num, this_mb_tx->mb_link_num, this_mb_tx->mb_response_timeout_ms,
    //    (int) timeout.tv_sec, (int) timeout.tv_usec);

    timeout.tv_sec  = this_mb_tx->mb_byte_timeout_ms / 1000;
    timeout.tv_usec = (this_mb_tx->mb_byte_timeout_ms % 1000) * 1000;
#if (LIBMODBUS_VERSION_CHECK(3, 1, 2))
    modbus_set_byte_timeout(this_mb_link->modbus, timeout.tv_sec, timeout.tv_usec);
#else
    modbus_set_byte_timeout(this_mb_link->modbus, &timeout);
#endif
    //DBG(this_mb_tx->cfg_debug, "mb_tx_num[%d] mb_links[%d] byte timeout [%d] ([%d] [%d])",
    //    this_mb_tx_num, this_mb_tx->mb_link_num, this_mb_tx->mb_byte_timeout_ms,
    //    (int) timeout.tv_sec, (int) timeout.tv_usec);

    *ret_connected = 1; //is connected (fd >= 0)
    return retOK;
}
Exemple #18
0
int main(int argc, char *argv[])
{
    int socket;
    modbus_t *ctx;
    modbus_mapping_t *mb_mapping;
    int rc;
    int use_backend;
    int justacounter;
    
    justacounter = 0;

while (TRUE) {
	
	
     /* TCP */
    if (argc > 1) {
        if (strcmp(argv[1], "tcp") == 0) {
            use_backend = TCP;
        } else if (strcmp(argv[1], "rtu") == 0) {
            use_backend = RTU;
        } else {
            printf("Usage:\n  %s [tcp|rtu] - Modbus client to measure data bandwith\n\n", argv[0]);
            exit(1);
        }
    } else {
        /* By default */
        use_backend = TCP;
	printf("bandwidth-server-one:\n Running in tcp mode - Modbus client to measure data bandwith\n\n");
    }

    if (use_backend == TCP) {
        printf("Waiting for TCP connection\n");
        ctx = modbus_new_tcp("127.0.0.1", 502);
        socket = modbus_tcp_listen(ctx, 1);
        modbus_tcp_accept(ctx, &socket);
        modbus_set_debug(ctx, TRUE);
	printf("TCP connection started!\n");
    } else {
	printf("Waiting for Serial connection\n");
        ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1);
        modbus_set_slave(ctx, 1);
        modbus_connect(ctx);
	printf("Serial connection started!\n");
    }

    mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS, 22,
                                    MODBUS_MAX_READ_REGISTERS, 22);
    if (mb_mapping == NULL) {
        fprintf(stderr, "Failed to allocate the mapping: %s\n",
                modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

    for(;;) {
        uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];

        rc = modbus_receive(ctx, query);
        if (rc >= 0) {
		mb_mapping->tab_input_registers[0] = justacounter++;	
	    printf("Replying to request.\n");
            modbus_reply(ctx, query, rc, mb_mapping);
        } else {
            /* Connection closed by the client or server */
           break;
        }
    }

    printf("Quit the loop: %s\n", modbus_strerror(errno));

    modbus_mapping_free(mb_mapping);
    close(socket);
    modbus_free(ctx);
}
    return 0;
}
int main(int argc, char*argv[])
{
    int s = -1;
    modbus_t *ctx;
    modbus_mapping_t *mb_mapping;
    int rc;
    int i;
    int use_backend;
    uint8_t *query;
    int header_length;

    if (argc > 1) {
        if (strcmp(argv[1], "tcp") == 0) {
            use_backend = TCP;
        } else if (strcmp(argv[1], "tcppi") == 0) {
            use_backend = TCP_PI;
        } else if (strcmp(argv[1], "rtu") == 0) {
            use_backend = RTU;
        } else {
            printf("Usage:\n  %s [tcp|tcppi|rtu] - Modbus server for unit testing\n\n", argv[0]);
            return -1;
        }
    } else {
        /* By default */
        use_backend = TCP;
    }

    if (use_backend == TCP) {
        ctx = modbus_new_tcp("127.0.0.1", 1502);
        query = malloc(MODBUS_TCP_MAX_ADU_LENGTH);
    } else if (use_backend == TCP_PI) {
        ctx = modbus_new_tcp_pi("::0", "1502");
        query = malloc(MODBUS_TCP_MAX_ADU_LENGTH);
    } else {
        ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1);
        modbus_set_slave(ctx, SERVER_ID);
        query = malloc(MODBUS_RTU_MAX_ADU_LENGTH);
    }
    header_length = modbus_get_header_length(ctx);

    modbus_set_debug(ctx, TRUE);

    mb_mapping = modbus_mapping_new(
        UT_BITS_ADDRESS + UT_BITS_NB,
        UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB,
        UT_REGISTERS_ADDRESS + UT_REGISTERS_NB,
        UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB);
    if (mb_mapping == NULL) {
        fprintf(stderr, "Failed to allocate the mapping: %s\n",
                modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

    /* Unit tests of modbus_mapping_new (tests would not be sufficient if two
       nb_* were identical) */
    if (mb_mapping->nb_bits != UT_BITS_ADDRESS + UT_BITS_NB) {
        printf("Invalid nb bits (%d != %d)\n", UT_BITS_ADDRESS + UT_BITS_NB, mb_mapping->nb_bits);
        modbus_free(ctx);
        return -1;
    }

    if (mb_mapping->nb_input_bits != UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB) {
        printf("Invalid nb input bits: %d\n", UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB);
        modbus_free(ctx);
        return -1;
    }

    if (mb_mapping->nb_registers != UT_REGISTERS_ADDRESS + UT_REGISTERS_NB) {
        printf("Invalid nb registers: %d\n", UT_REGISTERS_ADDRESS + UT_REGISTERS_NB);
        modbus_free(ctx);
        return -1;
    }

    if (mb_mapping->nb_input_registers != UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB) {
        printf("Invalid nb input registers: %d\n", UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB);
        modbus_free(ctx);
        return -1;
    }

    /* Examples from PI_MODBUS_300.pdf.
       Only the read-only input values are assigned. */

    /** INPUT STATUS **/
    modbus_set_bits_from_bytes(mb_mapping->tab_input_bits,
                               UT_INPUT_BITS_ADDRESS, UT_INPUT_BITS_NB,
                               UT_INPUT_BITS_TAB);

    /** INPUT REGISTERS **/
    for (i=0; i < UT_INPUT_REGISTERS_NB; i++) {
        mb_mapping->tab_input_registers[UT_INPUT_REGISTERS_ADDRESS+i] =
            UT_INPUT_REGISTERS_TAB[i];;
    }

    if (use_backend == TCP) {
        s = modbus_tcp_listen(ctx, 1);
        modbus_tcp_accept(ctx, &s);
    } else if (use_backend == TCP_PI) {
        s = modbus_tcp_pi_listen(ctx, 1);
        modbus_tcp_pi_accept(ctx, &s);
    } else {
        rc = modbus_connect(ctx);
        if (rc == -1) {
            fprintf(stderr, "Unable to connect %s\n", modbus_strerror(errno));
            modbus_free(ctx);
            return -1;
        }
    }

    for (;;) {
        do {
            rc = modbus_receive(ctx, query);
            /* Filtered queries return 0 */
        } while (rc == 0);

        /* The connection is not closed on errors which require on reply such as
           bad CRC in RTU. */
        if (rc == -1 && errno != EMBBADCRC) {
            /* Quit */
            break;
        }

        /* Special server behavior to test client */
        if (query[header_length] == 0x03) {
            /* Read holding registers */

            if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 3)
                == UT_REGISTERS_NB_SPECIAL) {
                printf("Set an incorrect number of values\n");
                MODBUS_SET_INT16_TO_INT8(query, header_length + 3,
                                         UT_REGISTERS_NB_SPECIAL - 1);
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1)
                       == UT_REGISTERS_ADDRESS_SPECIAL) {
                printf("Reply to this special register address by an exception\n");
                modbus_reply_exception(ctx, query,
                                       MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY);
                continue;
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1)
                       == UT_REGISTERS_ADDRESS_INVALID_TID_OR_SLAVE) {
                const int RAW_REQ_LENGTH = 5;
                uint8_t raw_req[] = {
                    (use_backend == RTU) ? INVALID_SERVER_ID : 0xFF,
                    0x03,
                    0x02, 0x00, 0x00
                };

                printf("Reply with an invalid TID or slave\n");
                modbus_send_raw_request(ctx, raw_req, RAW_REQ_LENGTH * sizeof(uint8_t));
                continue;
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1)
                       == UT_REGISTERS_ADDRESS_SLEEP_500_MS) {
                printf("Sleep 0.5 s before replying\n");
                usleep(500000);
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1)
                       == UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS) {
                /* Test low level only available in TCP mode */
                /* Catch the reply and send reply byte a byte */
                uint8_t req[] = "\x00\x1C\x00\x00\x00\x05\xFF\x03\x02\x00\x00";
                int req_length = 11;
                int w_s = modbus_get_socket(ctx);

                /* Copy TID */
                req[1] = query[1];
                for (i=0; i < req_length; i++) {
                    printf("(%.2X)", req[i]);
                    usleep(5000);
                    send(w_s, (const char*)(req + i), 1, MSG_NOSIGNAL);
                }
                continue;
            }
        }

        rc = modbus_reply(ctx, query, rc, mb_mapping);
        if (rc == -1) {
            break;
        }
    }

    printf("Quit the loop: %s\n", modbus_strerror(errno));

    if (use_backend == TCP) {
        if (s != -1) {
            close(s);
        }
    }
    modbus_mapping_free(mb_mapping);
    free(query);
    /* For RTU */
    modbus_close(ctx);
    modbus_free(ctx);

    return 0;
}
Exemple #20
0
int main(int argc, char *argv[])
{
    modbus_t            *ctx;
    struct timeval      timeout;
    int                 ret, i, rc, ii,iii;
    int nb_pointers;
   // unit16_t *tab_rp_registers;
    uint16_t        regs[MODBUS_MAX_READ_REGISTERS] = {0}; 
    uint16_t        regs2[MODBUS_MAX_READ_REGISTERS] = {0};
    char            regs3[MODBUS_MAX_READ_REGISTERS] = {0};
    FILE *fp = NULL;
 

    if(argc < 3){
        printf("INsufficient argument");
        return -1;
    }


    ctx = modbus_new_rtu(MODBUS_SERIAL_DEV,
            MODBUS_SERIAL_BAUDRATE,
            MODBUS_SERIAL_PARITY,
            MODBUS_SERIAL_DATABITS,
            MODBUS_SERIAL_STOPBITS);
 
    if (ctx == NULL) {
        fprintf(stderr, "Unable to create the libmodbus context\n");
        exit(-1);
    }
 
    
    i = modbus_rtu_get_serial_mode(ctx);
    if( i == MODBUS_RTU_RS232)
    {
	printf("Serial mode = RS232\n");
	ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS232);
	if(ret < 0)
	    fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno));
    }
    else if(i == MODBUS_RTU_RS485)
    {
	printf("Serial mode = RS485\n");
	ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
	if(ret < 0)
	    fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno));
    }
    else
    {
	printf("Serial mode = RS485\n");
	ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
	if(ret < 0)
	    fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno));
    }

    /* set slave device ID */
    modbus_set_slave(ctx, MODBUS_DEVICE_ID);
 
    /* Debug mode */
    modbus_set_debug(ctx, MODBUS_DEBUG);

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


    /* Allocate and initialize the memory to store the registers */
  /*  nb_points = (UT_REGISTERS_NB > UT_INPUT_REGISTERS_NB) ?
        UT_REGISTERS_NB : UT_INPUT_REGISTERS_NB;
    tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t));
    memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
    */

     /* write data in test.txt */
    fp = fopen("test2.txt", "w");
    if(fp == NULL)
    {
        printf("fail to open file!\n");
        return -1;
    }


    for( iii=1; iii <= strtol(argv[2],NULL, 10);iii++)
        {
                regs[iii] = strtol(argv[iii+2], NULL, 10);
        }

        rc = modbus_write_registers(ctx, strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 10), &regs[1]);
         if (rc < 0) {
                fprintf(stderr, "%s\n", modbus_strerror(errno));
         }


    /* read holding registers (0x03 function code) */

   rc = modbus_read_registers(ctx, strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 10), regs2);
    if (rc < 0) {
        fprintf(stderr, "%s\n", modbus_strerror(errno));
    }
    else {
            printf("HOLDING REGISTERS:\n");
            for (ii=0; ii < rc; ii++) {
                sprintf(regs3, "%d", regs2[ii]);
                fputs(regs3, fp);
                fputs("\n", fp);
                printf("[%d]=%d\n", ii, regs2[ii]);
            }
    }


    fclose(fp);

    /* Close the connection */
    modbus_close(ctx);

    modbus_free(ctx);
 
    return 0;
}
int main(int argc, char *argv[]) {
    extern int errno;
	modbus_t       *ctx;
	int registers;
    uint8_t rtu;
    int addr;
    int nb;
	int             rc;
    int ch;
    int verbose=0;
    int debug=0;
    int port=502;
    char name[255];

    addr=0;
    nb=1;

    strcpy(name,"127.0.0.1");
    
//	ctx = modbus_new_tcp("192.168.0.143", 1502);
//	ctx = modbus_new_tcp("127.0.0.1", 1502);
//	ctx = modbus_new_tcp("10.0.0.101", 502);
//	ctx = modbus_new_tcp("192.168.100.72", 1502);

    while((ch = getopt(argc,argv,"dvh?p:i:r:n:c:")) != -1) {
        switch(ch) {
            case 'c':
                sscanf(optarg,"%x",&registers);
                break;
            case 'd':
                debug=1;
                break;
            case 'v':
                verbose=1;
                break;
            case 'h':
            case '?':
                printf("Usage\n");
                exit(1);
                break;
            case 'p':
                port=atoi(optarg);
                break;
            case 'i':
                strcpy(name,optarg);
                break;
            case 'r':
                addr=atoi(optarg);
                break;
            case 'n':
                nb=atoi(optarg);
                break;
        }
    }

    if (verbose) {
        printf("Name    :%s\n",name);
        printf("Port    :%d\n",port);
        printf("Register:%d\n",addr);
        printf("Count   :%d\n", nb);
        printf("Data    :%04x\n", registers);
        printf("==================\n");
    }

	ctx = modbus_new_tcp(name, port);

	if (ctx == NULL) {
		fprintf(stderr, "modbus_new_tcp failed.\n");
		exit(-1);
	}

    if(debug) {
	    modbus_set_debug(ctx, TRUE);
    } else {
	    modbus_set_debug(ctx, FALSE);
    }
	modbus_set_error_recovery(ctx,
				  MODBUS_ERROR_RECOVERY_LINK |
				  MODBUS_ERROR_RECOVERY_PROTOCOL);

	if (modbus_connect(ctx) == -1) {
		fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
		modbus_free(ctx);
		return -1;
	}
    
	rc = modbus_write_registers(ctx, addr, nb,(uint16_t *) &registers);

	if (rc != nb) {
		printf("Failed:%d\n",rc);
        printf("==>%s\n", modbus_strerror(errno));
	}
    
//    printf("\nData = 0x%04x\n", registers & 0xffff);

    sleep(1);
    modbus_close(ctx);
    modbus_free(ctx);

    return 0;
}
Exemple #22
0
int main(int argc, char *argv[])
{
    modbus_t *ctx;
    uint16_t *tab_reg;
    int rc;
    int use_backend;
    const uint16_t values[] = {5678, 9012};

    if (argc > 1) {
        if (strcmp(argv[1], "tcp") == 0) {
            use_backend = TCP;
        } else if (strcmp(argv[1], "rtu") == 0) {
            use_backend = RTU;
        } else {
            printf("Usage:\n  %s [tcp|rtu] - Modbus client for unit testing\n\n", argv[0]);
            exit(1);
        }
    } else {
        /* By default */
        use_backend = TCP;
    }

    if (use_backend == TCP) {
        ctx = modbus_new_tcp("127.0.0.1", 1502);
    } else {
        ctx = modbus_new_rtu("/dev/ttyUSB1", 115200, 'N', 8, 1);
    }
    if (ctx == NULL) {
        fprintf(stderr, "Unable to allocate libmodbus context\n");
        return -1;
    }
    modbus_set_debug(ctx, TRUE);
    modbus_set_error_recovery(ctx,
                              MODBUS_ERROR_RECOVERY_LINK |
                              MODBUS_ERROR_RECOVERY_PROTOCOL);

    if (use_backend == RTU) {
        modbus_set_slave(ctx, SERVER_ID);
    }

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

    /* Allocate and initialize the memory to store the registers */
    tab_reg = (uint16_t *) malloc(10 * sizeof(uint16_t));

    /* Single register */
    printf("1/2 modbus_write_register");
    rc = modbus_write_register(ctx, 0, 1234);
    if (rc != 1) {
        goto close;
    }

    printf("2/2 modbus_read_registers");
    rc = modbus_read_registers(ctx, 0, 1, tab_reg);
    if (rc != 1) {
        goto close;
    }

    if (tab_reg[0] != 1234) {
        goto close;
    }

    /* Many registers */
    printf("1/2 modbus_write_registers");
    rc = modbus_write_registers(ctx, 1, 2, values);
    if (rc != 2) {
        goto close;
    }

    printf("2/2 modbus_read_registers");
    rc = modbus_read_registers(ctx, 1, 2, tab_reg);
    if (rc != 2) {
        goto close;
    }

close:
    /* Free the memory */
    free(tab_reg);

    /* Close the connection */
    modbus_close(ctx);
    modbus_free(ctx);

    return 0;
}
Exemple #23
0
int main(int argc, char *argv[])
{
    modbus_t            *ctx;
    struct timeval      timeout;
    int                 ret, i, rc, ii;
    int nb_pointers;
    //unit16_t *tab_rp_registers;
    uint16_t        regs[MODBUS_MAX_READ_REGISTERS] = {0};
    char            regs2[MODBUS_MAX_READ_REGISTERS]={0};
    FILE *fp = NULL;

    int err, rows, cols;
 

   if(argc != 5){
        printf("INsufficient argument");
        return -1;
    }
    err = opendb();
    if(err)
    {
	/*Database is not open*/
	return err;
    }


    ctx = modbus_new_rtu(MODBUS_SERIAL_DEV,
            MODBUS_SERIAL_BAUDRATE,
            MODBUS_SERIAL_PARITY,
            MODBUS_SERIAL_DATABITS,
            MODBUS_SERIAL_STOPBITS);
 
    if (ctx == NULL) {
        fprintf(stderr, "Unable to create the libmodbus context\n");
        exit(-1);
    }
 
    
    i = modbus_rtu_get_serial_mode(ctx);
    if( i == MODBUS_RTU_RS232)
    {
	printf("Serial mode = RS232\n");
	ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS232);
	if(ret < 0)
	    fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno));
    }
    else if(i == MODBUS_RTU_RS485)
    {
	printf("Serial mode = RS485\n");
	ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
	if(ret < 0)
	    fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno));
    }
      else
    {
	printf("Serial mode = RS485\n");
	ret = modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
	if(ret < 0)
	    fprintf(stderr, "modbus_rtu_set_serial_mode() error: %s\n", strerror(errno));
    }
    /* set slave device ID */
    modbus_set_slave(ctx, strtol(argv[2], NULL, 10));
 
    /* Debug mode */
    modbus_set_debug(ctx, MODBUS_DEBUG);

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


    /* Allocate and initialize the memory to store the registers */
    /*  nb_points = (UT_REGISTERS_NB > UT_INPUT_REGISTERS_NB) ?
        UT_REGISTERS_NB : UT_INPUT_REGISTERS_NB;
    tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t));
    memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
    */

     /* write data in test.txt */
    fp = fopen("test.txt", "w");
    if(fp == NULL)
    {
        printf("fail to open file!\n");
        return -1;
    }


 	

    rc = modbus_read_registers(ctx, strtol(argv[3], NULL, 16), strtol("1", NULL, 10), regs);
    if (rc < 0) {
	printf("1234\n");
        fprintf(stderr, "%s\n", modbus_strerror(errno));
    }
    else {
            printf("HOLDING REGISTERS:\n");
            for (ii=0; ii < rc; ii++) {
                sprintf(regs2, "%d", regs[ii]);
                fputs(regs2, fp);
                fputs("\n", fp);
                printf("[%d]=%d\n", ii, regs[ii]);
		sql_write2(argv[1], argv[2], argv[3], regs2, argv[4]);
		
            }
		if( mysql_query(dp, query))
		{
			fprintf(stderr, "%s\n", mysql_error(dp));
		}

		qp = mysql_store_result(dp);
		mysql_free_result(qp);
	
		mysql_close(dp);


    }

    fclose(fp);

    /* Close the connection */
    modbus_close(ctx);

    modbus_free(ctx);
 
    return 0;
}
Exemple #24
0
int main(int argc, char*argv[])
{
    int socket;
    modbus_t *ctx;
    modbus_mapping_t *mb_mapping;
    int rc;
    int i;
    int use_backend;
    uint8_t *query;
    int header_length;

    if (argc > 1) {
        if (strcmp(argv[1], "tcp") == 0) {
            use_backend = TCP;
        } else if (strcmp(argv[1], "rtu") == 0) {
            use_backend = RTU;
        } else {
            printf("Usage:\n  %s [tcp|rtu] - Modbus server for unit testing\n\n", argv[0]);
            return -1;
        }
    } else {
        /* By default */
        use_backend = TCP;
    }

    if (use_backend == TCP) {
        ctx = modbus_new_tcp("127.0.0.1", 1502);
        query = malloc(MODBUS_TCP_MAX_ADU_LENGTH);
    } else {
        ctx = modbus_new_rtu("/dev/ttyUSB0", 115200, 'N', 8, 1);
        modbus_set_slave(ctx, SERVER_ID);
        query = malloc(MODBUS_RTU_MAX_ADU_LENGTH);
    }
    header_length = modbus_get_header_length(ctx);

    modbus_set_debug(ctx, TRUE);
    modbus_set_error_recovery(ctx, TRUE);

    mb_mapping = modbus_mapping_new(
        UT_BITS_ADDRESS + UT_BITS_NB_POINTS,
        UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB_POINTS,
        UT_REGISTERS_ADDRESS + UT_REGISTERS_NB_POINTS,
        UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB_POINTS);
    if (mb_mapping == NULL) {
        fprintf(stderr, "Failed to allocate the mapping: %s\n",
                modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

    /* Examples from PI_MODBUS_300.pdf.
       Only the read-only input values are assigned. */

    /** INPUT STATUS **/
    modbus_set_bits_from_bytes(mb_mapping->tab_input_bits,
                               UT_INPUT_BITS_ADDRESS, UT_INPUT_BITS_NB_POINTS,
                               UT_INPUT_BITS_TAB);

    /** INPUT REGISTERS **/
    for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) {
        mb_mapping->tab_input_registers[UT_INPUT_REGISTERS_ADDRESS+i] =
            UT_INPUT_REGISTERS_TAB[i];;
    }

    if (use_backend == TCP) {
        socket = modbus_tcp_listen(ctx, 1);
        modbus_tcp_accept(ctx, &socket);
    } else {
        rc = modbus_connect(ctx);
        if (rc == -1) {
            fprintf(stderr, "Unable to connect %s\n", modbus_strerror(errno));
            modbus_free(ctx);
            return -1;
        }
    }

    for (;;) {
        rc = modbus_receive(ctx, -1, query);
        if (rc == -1) {
            /* Connection closed by the client or error */
            break;
        }

        /* Read holding registers */
        if (query[header_length] == 0x03) {
            if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 3)
                == UT_REGISTERS_NB_POINTS_SPECIAL) {
                printf("Set an incorrect number of values\n");
                MODBUS_SET_INT16_TO_INT8(query, header_length + 3,
                                         UT_REGISTERS_NB_POINTS);
            } else if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 1)
                == UT_REGISTERS_ADDRESS_SPECIAL) {
                modbus_reply_exception(ctx, query,
                                       MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY);
                continue;
            }
        }

        rc = modbus_reply(ctx, query, rc, mb_mapping);
        if (rc == -1) {
            break;
        }
    }

    printf("Quit the loop: %s\n", modbus_strerror(errno));

    if (use_backend == TCP) {
        close(socket);
    }
    modbus_mapping_free(mb_mapping);
    free(query);
    modbus_free(ctx);

    return 0;
}
/* At each loop, the program works in the range ADDRESS_START to
 * ADDRESS_END then ADDRESS_START + 1 to ADDRESS_END and so on.
 */
int main(void)
{
    modbus_t *ctx;
    int rc;
    int nb_fail;
    int nb_loop;
    int addr;
    int nb;
    uint8_t *tab_rq_bits;
    uint8_t *tab_rp_bits;
    uint16_t *tab_rq_registers;
    uint16_t *tab_rw_rq_registers;
    uint16_t *tab_rp_registers;

    /* RTU */
/*
    ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'N', 8, 1);
    modbus_set_slave(ctx, SERVER_ID);
*/

    /* TCP */
    ctx = modbus_new_tcp("127.0.0.1", 1502);
    modbus_set_debug(ctx, TRUE);

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

    /* Allocate and initialize the different memory spaces */
    nb = ADDRESS_END - ADDRESS_START;

    tab_rq_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
    memset(tab_rq_bits, 0, nb * sizeof(uint8_t));

    tab_rp_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
    memset(tab_rp_bits, 0, nb * sizeof(uint8_t));

    tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_rq_registers, 0, nb * sizeof(uint16_t));

    tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_rp_registers, 0, nb * sizeof(uint16_t));

    tab_rw_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_rw_rq_registers, 0, nb * sizeof(uint16_t));

    nb_loop = nb_fail = 0;
    while (nb_loop++ < LOOP) {
        for (addr = ADDRESS_START; addr <= ADDRESS_END; addr++) {
            int i;

            /* Random numbers (short) */
            for (i=0; i<nb; i++) {
                tab_rq_registers[i] = (uint16_t) (65535.0*rand() / (RAND_MAX + 1.0));
                tab_rw_rq_registers[i] = ~tab_rq_registers[i];
                tab_rq_bits[i] = tab_rq_registers[i] % 2;
            }
            nb = ADDRESS_END - addr;

            /* WRITE BIT */
            rc = modbus_write_bit(ctx, addr, tab_rq_bits[0]);
            if (rc != 1) {
                printf("ERROR modbus_write_bit (%d)\n", rc);
                printf("Address = %d, value = %d\n", addr, tab_rq_bits[0]);
                nb_fail++;
            } else {
                rc = modbus_read_bits(ctx, addr, 1, tab_rp_bits);
                if (rc != 1 || tab_rq_bits[0] != tab_rp_bits[0]) {
                    printf("ERROR modbus_read_bits single (%d)\n", rc);
                    printf("address = %d\n", addr);
                    nb_fail++;
                }
            }

            /* MULTIPLE BITS */
            rc = modbus_write_bits(ctx, addr, nb, tab_rq_bits);
            if (rc != nb) {
                printf("ERROR modbus_write_bits (%d)\n", rc);
                printf("Address = %d, nb = %d\n", addr, nb);
                nb_fail++;
            } else {
                rc = modbus_read_bits(ctx, addr, nb, tab_rp_bits);
                if (rc != nb) {
                    printf("ERROR modbus_read_bits\n");
                    printf("Address = %d, nb = %d\n", addr, nb);
                    nb_fail++;
                } else {
                    for (i=0; i<nb; i++) {
                        if (tab_rp_bits[i] != tab_rq_bits[i]) {
                            printf("ERROR modbus_read_bits\n");
                            printf("Address = %d, value %d (0x%X) != %d (0x%X)\n",
                                   addr, tab_rq_bits[i], tab_rq_bits[i],
                                   tab_rp_bits[i], tab_rp_bits[i]);
                            nb_fail++;
                        }
                    }
                }
            }

            /* SINGLE REGISTER */
            rc = modbus_write_register(ctx, addr, tab_rq_registers[0]);
            if (rc != 1) {
                printf("ERROR modbus_write_register (%d)\n", rc);
                printf("Address = %d, value = %d (0x%X)\n",
                       addr, tab_rq_registers[0], tab_rq_registers[0]);
                nb_fail++;
            } else {
                rc = modbus_read_registers(ctx, addr, 1, tab_rp_registers);
                if (rc != 1) {
                    printf("ERROR modbus_read_registers single (%d)\n", rc);
                    printf("Address = %d\n", addr);
                    nb_fail++;
                } else {
                    if (tab_rq_registers[0] != tab_rp_registers[0]) {
                        printf("ERROR modbus_read_registers single\n");
                        printf("Address = %d, value = %d (0x%X) != %d (0x%X)\n",
                               addr, tab_rq_registers[0], tab_rq_registers[0],
                               tab_rp_registers[0], tab_rp_registers[0]);
                        nb_fail++;
                    }
                }
            }

            /* MULTIPLE REGISTERS */
            rc = modbus_write_registers(ctx, addr, nb, tab_rq_registers);
            if (rc != nb) {
                printf("ERROR modbus_write_registers (%d)\n", rc);
                printf("Address = %d, nb = %d\n", addr, nb);
                nb_fail++;
            } else {
                rc = modbus_read_registers(ctx, addr, nb, tab_rp_registers);
                if (rc != nb) {
                    printf("ERROR modbus_read_registers (%d)\n", rc);
                    printf("Address = %d, nb = %d\n", addr, nb);
                    nb_fail++;
                } else {
                    for (i=0; i<nb; i++) {
                        if (tab_rq_registers[i] != tab_rp_registers[i]) {
                            printf("ERROR modbus_read_registers\n");
                            printf("Address = %d, value %d (0x%X) != %d (0x%X)\n",
                                   addr, tab_rq_registers[i], tab_rq_registers[i],
                                   tab_rp_registers[i], tab_rp_registers[i]);
                            nb_fail++;
                        }
                    }
                }
            }
            /* R/W MULTIPLE REGISTERS */
            rc = modbus_write_and_read_registers(ctx,
                                                 addr, nb, tab_rw_rq_registers,
                                                 addr, nb, tab_rp_registers);
            if (rc != nb) {
                printf("ERROR modbus_read_and_write_registers (%d)\n", rc);
                printf("Address = %d, nb = %d\n", addr, nb);
                nb_fail++;
            } else {
                for (i=0; i<nb; i++) {
                    if (tab_rp_registers[i] != tab_rw_rq_registers[i]) {
                        printf("ERROR modbus_read_and_write_registers READ\n");
                        printf("Address = %d, value %d (0x%X) != %d (0x%X)\n",
                               addr, tab_rp_registers[i], tab_rw_rq_registers[i],
                               tab_rp_registers[i], tab_rw_rq_registers[i]);
                        nb_fail++;
                    }
                }

                rc = modbus_read_registers(ctx, addr, nb, tab_rp_registers);
                if (rc != nb) {
                    printf("ERROR modbus_read_registers (%d)\n", rc);
                    printf("Address = %d, nb = %d\n", addr, nb);
                    nb_fail++;
                } else {
                    for (i=0; i<nb; i++) {
                        if (tab_rw_rq_registers[i] != tab_rp_registers[i]) {
                            printf("ERROR modbus_read_and_write_registers WRITE\n");
                            printf("Address = %d, value %d (0x%X) != %d (0x%X)\n",
                                   addr, tab_rw_rq_registers[i], tab_rw_rq_registers[i],
                                   tab_rp_registers[i], tab_rp_registers[i]);
                            nb_fail++;
                        }
                    }
                }
            }
        }

        printf("Test: ");
        if (nb_fail)
            printf("%d FAILS\n", nb_fail);
        else
            printf("SUCCESS\n");
    }

    /* Free the memory */
    free(tab_rq_bits);
    free(tab_rp_bits);
    free(tab_rq_registers);
    free(tab_rp_registers);

    /* Close the connection */
    modbus_close(ctx);
    modbus_free(ctx);

    return 0;
}
int main(int argc, char *argv[]) {
    modbus_t       *ctx_tcp;
    modbus_t    *ctx_serial;

    uint8_t        *query;
    uint8_t         *raw_query;
    uint8_t        *raw_reply;
    int             header_length;
    int             socket;
    int rc;

    modbus_mapping_t *mb_mapping;
    modbus_mapping_t *local_mb_mapping;

    const int RAW_REQ_LENGTH = 10;
    int RTU;
    int exitFlag = 0; // Set to non-zero to exit.
    //    int opt=1;
    int cnt=1;

    //    int tty_len=0;

    int baud_rate=9600;
    char parity='N';
    int length=8;
    int stop_bits=2;
    char *tty=(char *)NULL;
    char *ip=(char *)NULL;
    int port=1502;
    int verbose=1;
    int io_address=0;
    int tmp_address=0;

    uint16_t *localInputRegisters;
    int localInputRegistersSize;

    uint16_t *localHoldingRegisters;
    int localHoldingRegistersSize;

    int holdingShmKey=0;
    int holdingShmId=0;

    int holdingSemKey=0;
    int holdingSemId=0;


    int inputShmKey=0;
    int inputShmId=0;

    int inputSemKey=0;
    int inputSemId=0;

    int i;
    unsigned char *tmp;
    int ch;    // for getopt
    char *iniFile=(char *)NULL;
    char *ptr;

    int useSharedInput=0;
    int useSharedHolding=0;
    int modbusDebug = 0;
    int localRTU = 0;
    int serialRTUenabled = 0;

    char *iniFileName[] = {
        "/etc/newServer.ini",
        "/usr/local/etc/newServer.ini",
        "./newServer.ini"
    };

    while ((ch = getopt(argc,argv,"b:c:h?i:p:P:t:v")) != -1) {
        switch (ch) {
            case 'c':
                if ( iniFile != (char *)NULL) {
                    free(iniFile);
                }
                iniFile = strsave( optarg );

                if(verbose)
                    printf("Set ini file to %s\n",iniFile);
                break;
            case 'n':   // baud rate
                baud_rate=atoi(optarg);
                break;
            case 'h':
            case '?':
                usage();
                exit(0);
                break;
            case 'i':
                if ( ip != (char *)NULL) {
                    free(ip);
                }
                ip=strsave( optarg );
                break;
            case 'p':
                port=atoi( optarg );
                break;
            case 'P':
                parity=optarg[0];

                if ('E' != parity && 'O' != parity && 'N' != parity) {
                    fprintf(stderr,"Invalid parity %c, exiting.\n",parity);
                    exit(-1);
                }
                break;
            case 't':   // serial port
                if ( tty != (char *)NULL) {
                    free( tty );
                }
                tty=strsave( optarg );
                break;
            case 'v':
                verbose=1;
                break;
            default:
                break;
        }
    }

    if (iniFile == (char *)NULL) {
        for(i=0;(i<3 && (iniFile == (char *)NULL))  ;i++) {

            if ( verbose) {
                printf("%d:%s\n",i, iniFileName[i]);
            }

            if( 0 == access( iniFileName[i],R_OK)) {
                if(verbose ) {
                    printf("\tFile exists\n");
                }
                iniFile = strsave( iniFileName[i]);
            }
        }
    }    

    if (iniFile == (char *)NULL ) {
        printf("No existing ini file.\n");
        // Create an default file

        iniFile=strsave("./newServer.ini");
        printf("\tCreating new ini file %s\n", iniFile);

        createIni( iniFile );
        //        exit(0);
    }

    ini = iniparser_load( iniFile );
    ptr= iniparser_getstring(ini,"network:IP","127.0.0.1");

    if((char *)NULL == ip) {
        ip=strsave(ptr);
    }

    if (0 == port) {
        port = iniparser_getint(ini,"network:port",1502);
    }

    if (-1 == verbose) {
        verbose = iniparser_getboolean(ini,"system:verbose",0);
    }

    localHoldingRegistersSize = iniparser_getint(ini,"system:holding_reg_size", LOCAL_HOLDING_REGISTERS);

    localInputRegistersSize = iniparser_getint(ini,"system:input_reg_size", LOCAL_INPUT_REGISTERS);

    useSharedInput = iniparser_getboolean(ini,"system:share_input",0);
    useSharedHolding = iniparser_getboolean(ini,"system:share_holding",0);

    modbusDebug = iniparser_getboolean(ini,"modbus:debug",0);

    localRTU = iniparser_getint(ini,"modbus:LOCAL_RTU",255);

    serialRTUenabled = iniparser_getboolean(ini,"modbus:RTU",0);

    if( serialRTUenabled ) {
        if( (char *) NULL == tty) {
            tty = iniparser_getstring(ini,"modbus:tty","/dev/ttyUSB0");
        }
    } else {
        tty = (char *)NULL;
    }


    if(verbose) {
        printf("\n\t\tSettings\n");
        printf(  "\t\t========\n\n");
        printf("\tBuild Date\t:%s\n",__DATE__);
        printf("\tAddress\t\t:%s\n",ip);
        printf("\tNetwork port\t:%d\n",port);
        printf("\tSerial port\t:%s\n",tty);
        printf("\tBaud rate\t:%d\n",baud_rate);
        printf("\tParity\t\t:%c\n",parity);
    } else {
        printf("\nStarted.\n");
    }

    if (serialRTUenabled ) {
        if(access(tty,F_OK) == 0) {
            printf("Serial port %s exists.....\n",tty);
            // 
            // Now test that it is readable, writable.
            //
        } else {
            printf("Serial port %s does NOT exist\n",tty);
            printf("Disabling serial RTU.\n");
            free( tty );
            tty = (char *)NULL;
            serialRTUenabled=0;
        }
    }

    query = malloc(MODBUS_TCP_MAX_ADU_LENGTH);
    raw_query = malloc(RAW_REQ_LENGTH);
    raw_reply = malloc(MODBUS_TCP_MAX_ADU_LENGTH);

    mb_mapping = modbus_mapping_new(
            MODBUS_MAX_BITS,   // Coils
            MODBUS_MAX_BITS,   // Discrete inputs
            MODBUS_MAX_REGISTERS,   // Holding registers
            MODBUS_MAX_REGISTERS);  // Input registers

    local_mb_mapping = modbus_mapping_new(
            NULL,   // Coils
            NULL,   // Discrete inputs
            LOCAL_HOLDING_REGISTERS,   // Holding registers
            LOCAL_INPUT_REGISTERS);  // Input registers

    // 
    // Setup the memory for the holding registers.
    //
    if ( useSharedHolding ) {
        if (verbose)
            printf("Share the Holding regsisters R/W\n");

        localHoldingRegisters = local_mb_mapping->tab_registers;

        holdingShmKey = iniparser_getint(ini, "system:holding_reg_key",110);
        holdingSemKey = iniparser_getint(ini, "system:holding_reg_sema",111);

        holdingShmId = shmget(holdingShmKey, localHoldingRegistersSize, IPC_CREAT | 0600 );  // change to 0400

        if (holdingShmId < 0) {
            perror("Holding Reg shmget");
            exit(3);
        }
        local_mb_mapping->tab_registers = (uint16_t *)shmat(holdingShmId,NULL,0);
        if (local_mb_mapping->tab_registers < 0) {
            perror("Holding Reg shmat");
            exit(4);
        }

        /* 
         * Create the seamphore 
         */
        holdingSemId = semget( holdingSemKey, 1, IPC_CREAT | 0600 );
        if (-1 == holdingSemId) {
            perror("Input reg semaphore");
            exit(2);
        }
        /*
         *         Shared memory created, semaphore created (default is locked)
         *         release the seamphore !
         */
        rc = semctl(holdingSemId, 0, SETVAL, 1);

    }
    // 
    // Setup the memory for the shared input registers.
    // 
    if ( useSharedInput ) {
        if (verbose)
            printf("Share the Input regsisters R/W\n");

        localInputRegisters = local_mb_mapping->tab_input_registers; // Save the current pointer

        inputShmKey = iniparser_getint(ini, "system:input_reg_key",110);
        inputSemKey = iniparser_getint(ini, "system:input_reg_sema",111);

        inputShmId = shmget(inputShmKey, localInputRegistersSize, IPC_CREAT | 0600 );  // change to 0400

        if (inputShmId < 0) {
            perror("Input Reg shmget");
            exit(3);
        }
        local_mb_mapping->tab_input_registers = (uint16_t *)shmat(inputShmId,NULL,0);

        if ( local_mb_mapping->tab_input_registers < 0) {
            perror("Input Reg shmat");
            exit(1);
        }

        /* 
         * create the seamphore 
         */
        inputSemId = semget( inputSemKey, 1, IPC_CREAT | 0600 );
        if (-1 == inputSemId) {
            perror("Input reg semaphore");
            exit(2);
        }
        /*
         *         Shared memory created, semaphore created (default is locked)
         *         release the seamphore !
         */
        rc = semctl(inputSemId, 0, SETVAL, 1);

    }

    memset( localInputRegisters,0x00, LOCAL_INPUT_REGISTERS);
    memset( localHoldingRegisters,0x00, LOCAL_HOLDING_REGISTERS);

    local_mb_mapping->tab_input_registers[0]=0xaa55;

    ctx_tcp = modbus_new_tcp(ip, port);

    if ( tty != (char *)NULL ) {
        ctx_serial = modbus_new_rtu(tty, baud_rate, parity, length, stop_bits);
    }

    while ( !exitFlag ) {
        header_length = modbus_get_header_length(ctx_tcp);

        if(verbose) {
            modbus_set_debug(ctx_tcp, TRUE);
            //            modbus_set_debug(ctx_serial, TRUE);
        }

        do {
            socket = modbus_tcp_listen(ctx_tcp, 5);
            if (socket < 0) {
                printf("%04d: Socket in use.\n",cnt++);
                sleep(1);
            }
        } while(socket < 0);
        //        printf("modbus_tcp_listen   =%d\n",socket);
        if (socket == -1) {
            printf("\t: %s\n", modbus_strerror(errno));
        }

        rc=modbus_tcp_accept(ctx_tcp, &socket);

        //        printf("modbus_tcp_accept rc=%d\n",rc);
        if (rc == -1) {
            fprintf(stderr,"FATAL ERROR: %s\n", modbus_strerror(errno));
            exit(-1);
        }

        while ( 1 ) {
            do {
                if(verbose) {
                    printf("Recieve.\n");
                }
                rc = modbus_receive(ctx_tcp, query);
                //                printf("rc=%d\n",rc);
                /* Filtered queries return 0 */
            } while (rc == 0);

            if (-1 == rc) {
                if( verbose ) {
                    printf("Client disconnected.\n");
                }
                break;
            }
            RTU=query[header_length - 1];
            io_address= ( query[header_length+1] << 8) + (query[header_length+2] & 0xff);

            printf("IO Address=%04x\n",io_address);

            if (verbose) {
                if( localRTU == RTU ) {
                    printf("It's for me !\n");
                } else {
                    printf("RTU Id: %02d\n",RTU);
                }

                printf("IO Address=0x%04x\n",io_address);
                printf("Seq Number=0x%04x\n", query[1]);
            }   

            if( localRTU == RTU ) {
                //
                // Local mapping
                //
                int len;
                uint16_t data;
                int cnt=0;

                // Need to add address range checks, and return an error 
                // for an invalid function.

                switch (query[header_length]) {
                    case 0x03:  // read holding registers
                    case 0x04:  // read input registers
                        rc = modbus_reply(ctx_tcp, query, rc, local_mb_mapping);
                        break;
                    case 0x06: //write single register
                        swab(&query[8],&len,2);
                        swab(&query[10],&data,2);
                        printf("Data=%02d\n",data);

                        local_mb_mapping->tab_registers[io_address]=data;
                        rc = modbus_reply(ctx_tcp, query, rc, local_mb_mapping);
                        break;
                    case 0x10: // Write multiple registers
                        //                        len=query[7];
                        swab(&query[10],&len,2);
                        printf("Length=%02d\n",len);

                        for (i=13; i< (13 + len ); i +=2) {
                            data= (query[i] << 8) + (query[i+1] & 0xff);
                            printf("%04x\n",data);

                            local_mb_mapping->tab_registers[ io_address + cnt++ ] = data;
                        }
                        rc = modbus_reply(ctx_tcp, query, rc, local_mb_mapping);
                        break;

                    default:
                        break;
                }
            } else {
                if(serialRTUenabled)  {

                    modbus_set_slave( ctx_serial,RTU);
                    if( -1 == modbus_connect( ctx_serial)) {
                        fprintf(stderr, "Connection failed: %s\n",modbus_strerror(errno));
                    }
                    switch( query[header_length] ) {
                        case 0x06:
                            printf("Write Single Register %d\n",RTU);
                            memcpy(raw_query,&query[header_length-1], 6);
                            rc=modbus_send_raw_request( ctx_serial,raw_query,6);
                            modbus_receive_confirmation(ctx_serial, raw_reply);
                            rc = modbus_reply(ctx_tcp, query, rc, mb_mapping);

                            break;
                        case 0x03:
                        case 0x04:
                            printf("Read Registers %d\n",RTU);
                            break;
                        case 0x10:
                            {
                                int len=0;
                                //	      modbus_set_debug(ctx_serial, TRUE);

                                printf("Write multiple registers %d\n",RTU);
                                len=query[header_length - 2];
                                printf("Length %d\n",len);
                                memcpy(raw_query,&query[header_length-1], len);

                                rc=modbus_send_raw_request( ctx_serial,raw_query,len);
                                if( -1 == rc) {
                                    printf("modbus_send_raw_request: %s\n",modbus_strerror(errno));
                                } else {
                                    modbus_receive_confirmation(ctx_serial, raw_reply);
                                    rc = modbus_reply(ctx_tcp, query, rc, mb_mapping);
                                    printf("rc =  %d\n",rc);
                                    //		modbus_set_debug(ctx_serial, FALSE);
                                }
                            } 
                            break;
                    }

                    if( (0x03 == query[header_length]) || (0x04 == query[header_length])) {
                        int len;

                        if(verbose) {
                            switch (query[header_length]) {
                                case 0x03:
                                    printf("Read Holding Registers.\n");
                                    break;
                                case 0x04:
                                    printf("Read Input Registers.\n");
                                    break;
                                default:
                                    break;
                            }
                        }

                        memcpy(raw_query,&query[header_length-1], 6);

                        modbus_set_slave( ctx_serial, query[header_length-1]);

                        if( -1 == modbus_connect( ctx_serial)) {
                            fprintf(stderr, "Connection failed: %s\n",modbus_strerror(errno));
                        }

                        rc=modbus_send_raw_request( ctx_serial,raw_query,6);

                        if( -1 == rc ) {
                            printf("modbus_send_raw_request: %s\n",modbus_strerror(errno));
                        }

                        modbus_receive_confirmation(ctx_serial, raw_reply);
                        /*
                         * This next loop swaps bytes in words.
                         * If this is built and running on a little endian 
                         * machine (most machines are these days)
                         * Then this needs to be done.  
                         * If on a big endian machine (M68000 family) just 
                         * comment this out.
                         *                     
                         * It might be worth having a command line switch,
                         * detect endianness.
                         *                     
                         */

                        switch (query[header_length]) {
                            case 0x03:
                                printf("Read Holding Registers.\n");
                                tmp=(unsigned char *)mb_mapping->tab_registers;
                                break;
                            case 0x04:
                                printf("Read Input Registers.\n");
                                tmp=(unsigned char *)mb_mapping->tab_input_registers;
                                break;
                            default:
                                break;
                        }

                        tmp_address = (io_address*2);

                        for(i=0;i<raw_reply[2];i=i+2 ) {
                            tmp[tmp_address+i]=raw_reply[i+4];
                            tmp[tmp_address+i+1]=raw_reply[i+3];
                        }

                        for(i=0;i<10;i++) {
                            if (verbose) {
                                printf("!%02x!",raw_reply[i]);
                            }
                        }
                        printf("\n");

                        for(i=0;i<10;i++) {
                            if (verbose) {
                                printf("+%02x+",tmp[i]);
                            }
                        }
                        printf("\n");

                        //
                        // compute packet length by getting the data length 
                        // and then add 2.
                        // Then overwrite the outbound data.
                        //
                        len=raw_reply[2] + 3;
                        rc = modbus_reply(ctx_tcp, query, rc, mb_mapping);

                        //    memcpy(  mb_mapping->tab_input_registers, &raw_reply[3], raw_reply[2]);

                        //    MODBUS_SET_INT16_TO_INT8(query, header_length + 3, UT_REGISTERS_NB_SPECIAL - 1);

                    }
                }
            }

            //    printf("Reply with an invalid TID or slave\n");
            //    rc=modbus_reply_exception(ctx_tcp, query, 1);
            //    rc=modbus_send_raw_request(ctx_tcp, raw_reply, 10 * sizeof(uint8_t));


            //      rc = modbus_reply(ctx_tcp, query, rc, mb_mapping);
        }

        if( verbose ) {
            printf("Tidying up\n");
        }
        close(socket);

        usleep( 1000 ); // wait 1 ms

    }
    printf("simpleServer exiting.\n");
    modbus_close(ctx_tcp);
    modbus_free(ctx_tcp);
    free(query);
    modbus_mapping_free(mb_mapping);
    return(0);
}
Exemple #27
0
int main(int argc, char *argv[])
{
    modbus_t        *ctx;
    struct timeval  timeout;
    int             ret, ii;
    /*uint8_t       bits[MODBUS_MAX_READ_BITS] = {0};*/
    uint16_t        regs[MODBUS_MAX_READ_REGISTERS] = {0};
    char            regs2[MODBUS_MAX_READ_REGISTERS]={0};
    FILE *fp = NULL;
    
   if(argc != 3){
	printf("INsufficient argument");
	return 1;
    }    
 
    ctx = modbus_new_tcp(MODBUS_CLIENT_IP, MODBUS_CLIENT_PORT);
 
    /* set device ID */
    modbus_set_slave(ctx, MODBUS_DEVICE_ID);
 
    /* Debug mode */
    modbus_set_debug(ctx, MODBUS_DEBUG);
 
    /* set timeout */
    timeout.tv_sec = MODBUS_TIMEOUT_SEC;
    timeout.tv_usec = MODBUS_TIMEOUT_USEC;
    modbus_get_byte_timeout(ctx, &timeout);
 
    timeout.tv_sec = MODBUS_TIMEOUT_SEC;
    timeout.tv_usec = MODBUS_TIMEOUT_USEC;
    modbus_set_response_timeout(ctx, &timeout);
    
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Connexion failed: %s\n",
                modbus_strerror(errno));
        modbus_free(ctx);
        exit(-1);
    }

     /* write data in test.txt */
    fp = fopen("test.txt", "w");
    if(fp == NULL)
    {
        printf("fail to open file!\n");
        return -1;
    }
 

 
 
    /* read holding registers (0x03 function code) */

    ret = modbus_read_registers(ctx, strtol(argv[1], NULL, 16), strtol(argv[2], NULL, 10), regs);
    if (ret < 0) {
        fprintf(stderr, "%s\n", modbus_strerror(errno));
    }
    else {
            printf("HOLDING REGISTERS:\n");
            for (ii=0; ii < ret; ii++) {
		sprintf(regs2, "%d", regs[ii]);
		fputs(regs2, fp);
		fputs("\n", fp);
           	printf("[%d]=%d\n", ii, regs[ii]);
            }
    }
	
    

    fclose(fp);

    /* Close the connection */
    modbus_close(ctx);
    modbus_free(ctx);
 
    exit(0);
}
int setdebugmode(){
    modbus_set_debug(ctx, TRUE);
}
int main(int argc, char **argv)
{
    int c;
    int ok;

    int debug = 0;
    BackendParams *backend = 0;
    int slaveAddr = 1;
    int startAddr = 100;
    int startReferenceAt0 = 0;
    int readWriteNo = 1;
    int fType = FuncNone;
    int timeout_ms = 1000;
    int hasDevice = 0;

    int isWriteFunction = 0;
    enum WriteDataType {
        DataInt,
        Data8Array,
        Data16Array
    } wDataType = DataInt;
    union Data {
        int dataInt;
        uint8_t *data8;
        uint16_t *data16;
    } data;

    while (1) {
        int option_index = 0;
        static struct option long_options[] = {
            {DebugOpt,  no_argument, 0,  0},
            {0, 0,  0,  0}
        };

        c = getopt_long(argc, argv, "a:b:d:c:m:r:s:t:p:o:0",
                        long_options, &option_index);
        if (c == -1) {
            break;
        }

        switch (c) {
        case 0:
            if (0 == strcmp(long_options[option_index].name, DebugOpt)) {
                debug = 1;
            }
            break;

        case 'a': {
            slaveAddr = getInt(optarg, &ok);
            if (0 == ok) {
                printf("Slave address (%s) is not integer!\n\n", optarg);
                printUsage(argv[0]);
                exit(EXIT_FAILURE);
            }
        }
            break;

        case 'c': {
            readWriteNo = getInt(optarg, &ok);
            if (0 == ok) {
                printf("# elements to read/write (%s) is not integer!\n\n", optarg);
                printUsage(argv[0]);
                exit(EXIT_FAILURE);
            }
        }
            break;

        case 'm':
            if (0 == strcmp(optarg, TcpOptVal)) {
                backend = createTcpBackend((TcpBackend*)malloc(sizeof(TcpBackend)));
            }
            else if (0 == strcmp(optarg, RtuOptVal))
                backend = createRtuBackend((RtuBackend*)malloc(sizeof(RtuBackend)));
            else {
                printf("Unrecognized connection type %s\n\n", optarg);
                printUsage(argv[0]);
                exit(EXIT_FAILURE);
            }
            break;

        case 'r': {
            startAddr = getInt(optarg, &ok);
            if (0 == ok) {
                printf("Start address (%s) is not integer!\n\n", optarg);
                printUsage(argv[0]);
                exit(EXIT_FAILURE);
            }
        }
            break;

        case 't': {
            fType = getInt(optarg, &ok);
            if (0 == ok) {
                printf("Function type (%s) is not integer!\n\n", optarg);
                printUsage(argv[0]);
                exit(EXIT_FAILURE);
            }
        }
            break;

        case 'o': {
            timeout_ms = getInt(optarg, &ok);
            if (0 == ok) {
                printf("Timeout (%s) is not integer!\n\n", optarg);
                printUsage(argv[0]);
                exit(EXIT_FAILURE);
            }
            printf("Timeout set to %d\r\n", timeout_ms);
        }
            break;

        case '0':
            startReferenceAt0 = 1;
            break;
            //tcp/rtu params
        case 'p':
        case 'b':
        case 'd':
        case 's':
            if (0 == backend) {
                printf("Connection type (-m switch) has to be set before its params are provided!\n");
                printUsage(argv[0]);
                exit(EXIT_FAILURE);
            }
            else {
                if (0 == backend->setParam(backend, c, optarg)) {
                    printUsage(argv[0]);
                    exit(EXIT_FAILURE);
                }
            }
            break;
        case '?':
            break;

        default:
            printf("?? getopt returned character code 0%o ??\n", c);
        }
    }

    if (0 == backend) {
        printf("No connection type was specified!\n");
        printUsage(argv[0]);
        exit(EXIT_FAILURE);
    }

    if (1 == startReferenceAt0) {
        startAddr--;
    }

    //choose write data type
    switch (fType) {
    case(ReadCoils):
        wDataType = Data8Array;
        break;
    case(ReadDiscreteInput):
        wDataType = DataInt;
        break;
    case(ReadHoldingRegisters):
    case(ReadInputRegisters):
        wDataType = Data16Array;
        break;
    case(WriteSingleCoil):
    case(WriteSingleRegister):
        wDataType = DataInt;
        isWriteFunction = 1;
        break;
    case(WriteMultipleCoils):
        wDataType = Data8Array;
        isWriteFunction = 1;
        break;
    case(WriteMultipleRegisters):
        wDataType = Data16Array;
        isWriteFunction = 1;
        break;
    default:
        printf("No correct function type chosen");
        printUsage(argv[0]);
        exit(EXIT_FAILURE);
    }

    if (isWriteFunction) {
        int dataNo = argc - optind - 1;
        /*if (-1 != readWriteNo && dataNo != readWriteNo) {
            printf("Write count specified, not equal to data values count!");
            printUsage(argv[0]);
            exit(EXIT_FAILURE);
        }
        else*/ readWriteNo = dataNo;
    }

    //allocate buffer for data
    switch (wDataType) {
    case (DataInt):
        //no need to alloc anything
        break;
    case (Data8Array):
        data.data8 = malloc(readWriteNo * sizeof(uint8_t));
        break;
    case (Data16Array):
        data.data16 = malloc(readWriteNo * sizeof(uint16_t));
        break;
    default:
        printf("Data alloc error!\n");
        exit(EXIT_FAILURE);
    }

    int wDataIdx = 0;
    if (1 == debug && 1 == isWriteFunction)
        printf("Data to write: ");
    if (optind < argc) {
        while (optind < argc) {
            if (0 == hasDevice) {
                if (0 != backend) {
                    if (Rtu == backend->type) {
                        RtuBackend *rtuP = (RtuBackend*)backend;
                        strcpy(rtuP->devName, argv[optind]);
                        hasDevice = 1;
                    }
                    else if (Tcp == backend->type) {
                        TcpBackend *tcpP = (TcpBackend*)backend;
                        strcpy(tcpP->ip, argv[optind]);
                        hasDevice = 1;
                    }
                }
            }
            else {//setting write data buffer
                switch (wDataType) {
                case (DataInt):
                    data.dataInt = getInt(argv[optind], 0);
                    if (debug)
                        printf("0x%x", data.dataInt);
                    break;
                case (Data8Array): {
                    data.data8[wDataIdx] = getInt(argv[optind], 0);
                    if (debug)
                        printf("0x%02x ", data.data8[wDataIdx]);
                }
                    break;
                case (Data16Array): {
                    data.data16[wDataIdx] = getInt(argv[optind], 0);
                    if (debug)
                        printf("0x%04x ", data.data16[wDataIdx]);
                }
                    break;
                }
                wDataIdx++;
            }
            optind++;
        }
    }
    if (1 == debug && 1 == isWriteFunction)
        printf("\n");

    //create modbus context, and preapare it
    modbus_t *ctx = backend->createCtxt(backend);
    modbus_set_debug(ctx, debug);
    modbus_set_slave(ctx, slaveAddr);

    //issue the request
    int ret = -1;
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Connection failed: %s\n",
                modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    } else {
        switch (fType) {
        case(ReadCoils):
            ret = modbus_read_bits(ctx, startAddr, readWriteNo, data.data8);
            break;
        case(ReadDiscreteInput):
            printf("ReadDiscreteInput: not implemented yet!\n");
            wDataType = DataInt;
            break;
        case(ReadHoldingRegisters):
            ret = modbus_read_registers(ctx, startAddr, readWriteNo, data.data16);
            break;
        case(ReadInputRegisters):
            ret = modbus_read_input_registers(ctx, startAddr, readWriteNo, data.data16);
            break;
        case(WriteSingleCoil):
            ret = modbus_write_bit(ctx, startAddr, data.dataInt);
            break;
        case(WriteSingleRegister):
            ret = modbus_write_register(ctx, startAddr, data.dataInt);
            break;
        case(WriteMultipleCoils):
            ret = modbus_write_bits(ctx, startAddr, readWriteNo, data.data8);
            break;
        case(WriteMultipleRegisters):
            ret = modbus_write_registers(ctx, startAddr, readWriteNo, data.data16);
            break;
        default:
            printf("No correct function type chosen");
            printUsage(argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    if (ret == readWriteNo) {//success
        if (isWriteFunction)
            printf("SUCCESS: written %d elements!\n", readWriteNo);
        else {
            printf("SUCCESS: read %d of elements:\n\tData: ", readWriteNo);
            int i = 0;
            if (DataInt == wDataType) {
                printf("0x%04x\n", data.dataInt);
            }
            else {
                const char Format8[] = "0x%02x ";
                const char Format16[] = "0x%04x ";
                const char *format = ((Data8Array == wDataType) ? Format8 : Format16);
                for (; i < readWriteNo; ++i) {
                    printf(format, (Data8Array == wDataType) ? data.data8[i] : data.data16[i]);
                }
                printf("\n");
            }
        }
    }
    else {
        printf("ERROR occured!\n");
        modbus_strerror(errno);
    }

    //cleanup
    modbus_close(ctx);
    modbus_free(ctx);
    backend->del(backend);

    switch (wDataType) {
    case (DataInt):
        //nothing to be done
        break;
    case (Data8Array):
        free(data.data8);
        break;
    case (Data16Array):
        free(data.data16);
        break;
    }

    exit(EXIT_SUCCESS);
}
Exemple #30
0
int main( int argc, char **argv )
{
	int a, rc;
	int ec = 0;
	options_t options;
	modbus_t *ctx;

	uint8_t *tab_bit;
	uint16_t *tab_reg;

	if(argc > 1)
	{
		options_init(&options);
		for (a = 1; a < argc; a++)
		{
			options_execute(&options, argv[a], strlen(argv[a])+1);
			rc = options_finish(&options);
			DEBUG("argument: '%s' end state: %d\n",argv[a], rc);

			if (rc == -1)
			{
				options_err_disp(&options,argv[a]);
				ec = 1;
				goto exit;
			}
		}

		if(rc == 0)
		{
			fprintf(stderr, "Missing action argument\n");
			ec = 1;
			goto exit;
		}

		if(options.action == _UNDEF)
			goto exit;

		// Options are valid 
		options_dump(&options);
	
		ctx = modbus_init_con(&options);
		modbus_set_debug(ctx, options.debug);
		modbus_set_response_timeout(ctx, &options.timeout);

		if (modbus_connect(ctx) == -1) {
			fprintf(stderr, "Connection failed: %s\n",
				modbus_strerror(errno));
			ec = 1;
			goto destroy;
		}

		switch(options.action)
		{
			case _RC:
			case _RD:
				tab_bit = (uint8_t *) malloc(options.count * sizeof(uint8_t));
				DBG_ASSERT(tab_bit != NULL, "Unable to allocate tab_bit!");
				memset(tab_bit, 0, options.count * sizeof(uint8_t));
				
				switch(options.action)
				{
					case _RC:
						rc = modbus_read_bits(ctx, options.address, 
								options.count, tab_bit);
					break;

					case _RD:
						rc = modbus_read_input_bits(ctx, options.address, 
								options.count, tab_bit);

					break;
				}
				if (rc == -1) {
					fprintf(stderr, "%s\n", modbus_strerror(errno));
					ec = 1;
				} else {
					display_8bit(&options, tab_bit);
				}
				free(tab_bit);
			break;

			case _RH:
			case _RI:
				tab_reg = (uint16_t *) malloc(options.count * sizeof(uint16_t));
				DBG_ASSERT(tab_reg != NULL, "Unable to allocate tab_reg!");
				
				switch(options.action)
				{
					case _RH:
						rc = modbus_read_registers(ctx, options.address, 
								options.count, tab_reg);
					break;

					case _RI:
						rc = modbus_read_input_registers(ctx, options.address, 
								options.count, tab_reg);

					break;
				}
				if (rc == -1) {
					fprintf(stderr, "%s\n", modbus_strerror(errno));
					ec = 1;
				} else {
					display_16bit(&options, tab_reg);
				}
				free(tab_reg);
			break;

			case _WC:
				if(options.count == 1)
					rc =  modbus_write_bit(ctx, options.address, 
							options.coil_values[0]);
				else {
					rc = modbus_write_bits(ctx, options.address,
							options.count, options.coil_values);
				}

				if (rc == -1) {
					fprintf(stderr, "%s\n", modbus_strerror(errno));
					ec = 1;
				} else {
					printf("Success\n");
				}
			break;

			case _WH:
				if(options.count == 1)
					rc =  modbus_write_register(ctx, options.address, 
							options.reg_values[0]);
				else {
					rc = modbus_write_registers(ctx, options.address,
							options.count, options.reg_values);
				}

				if (rc == -1) {
					fprintf(stderr, "%s\n", modbus_strerror(errno));
					ec = 1;
				} else {
					printf("Success\n");
				}

			break;

			default:
				DBG_ASSERT(0,"Unhandled action enum constant!");
		}



	} else {
		options_help();
		ec = 1;
		goto exit;
	}

close:
	modbus_close(ctx);
destroy:
	modbus_free(ctx);
exit:
	return ec;
}