This shows you the differences between two versions of the page.
Last revision | |||
— | sdk:scripts:serial-tcp-broadcast [2015/05/05 15:04] – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== SDK Script serial-tcp-broadcast.are ====== | ||
+ | <code c serial-tcp-broadcast.are> | ||
+ | /* DESC: This script reads messages coming from the serial port and forwards them via TCP to remote hosts (and vice versa). | ||
+ | * Copyright (C) 2014 NetModule AG, Switzerland | ||
+ | * | ||
+ | * Usage: usage: serial-tcp-broadcast.are < | ||
+ | * Version: 2.0 | ||
+ | * | ||
+ | */ | ||
+ | |||
+ | /* | ||
+ | * Options to configure by user | ||
+ | */ | ||
+ | |||
+ | /* Serial Baud Rate 9600, 19200, 38400, 57600, 115200 */ | ||
+ | SER_SPEED = 115200; | ||
+ | /* number of data bits (5, 6, 7, 8) */ | ||
+ | SER_DATABIT = 8; | ||
+ | /* number of stop bits (1, 2) */ | ||
+ | SER_STOPBIT = 1; | ||
+ | /* parity (0=no parity, 1=odd parity, 2=even parity) */ | ||
+ | SER_PARITY = 0; | ||
+ | /* flow control (0=none, 1=xon/xoff, 2=hardware) */ | ||
+ | SER_FLOW = 0; | ||
+ | /* name of the Serial Interface */ | ||
+ | DEV = " | ||
+ | DEVIDX = ((int) substr(DEV, 6, 1)) - 1; | ||
+ | |||
+ | /* TCP Options */ | ||
+ | /* number of retries when connecting to a slave */ | ||
+ | RETRY = 3; | ||
+ | /* the interval in seconds for each retry */ | ||
+ | RETRY_INTERVAL = 3; | ||
+ | /* recovery interval after slave got disconnected or retries were unsuccessful */ | ||
+ | RECOVER_INTERVAL = 120; | ||
+ | |||
+ | |||
+ | /* | ||
+ | * Only changed things below if you know what you are doing | ||
+ | */ | ||
+ | |||
+ | POLL_TIMEOUT = 10; /* seconds */ | ||
+ | REMOTE_PORT =2000; | ||
+ | |||
+ | /* slave template */ | ||
+ | template slave | ||
+ | { | ||
+ | hostname = ""; | ||
+ | fd = -1; | ||
+ | state = " | ||
+ | since = 0; | ||
+ | |||
+ | void slave(string remotehost) | ||
+ | { | ||
+ | nb_syslog(" | ||
+ | if (strlen(remotehost) > 0) { | ||
+ | this.hostname = remotehost; | ||
+ | } else { | ||
+ | nb_syslog(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | int jiffy() | ||
+ | { | ||
+ | sys = sysinfo(); | ||
+ | u = struct_get(sys, | ||
+ | |||
+ | if (is_void(u) || u < 1) { | ||
+ | return 0; | ||
+ | } else { | ||
+ | return u; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | int connect() { | ||
+ | if (this.fd > -1) { | ||
+ | close(this.fd); | ||
+ | this.fd = -1; | ||
+ | } | ||
+ | nb_syslog(" | ||
+ | |||
+ | /* open TCP socket */ | ||
+ | sock = socket(AF_INET, | ||
+ | setsockopt(sock, | ||
+ | setsockopt(sock, | ||
+ | setsockopt(sock, | ||
+ | setsockopt(sock, | ||
+ | |||
+ | if (sock < 0) { | ||
+ | nb_syslog(" | ||
+ | } | ||
+ | for (i = 0; i < RETRY; i++) { | ||
+ | if (connect(sock, | ||
+ | nb_syslog(" | ||
+ | nb_syslog(" | ||
+ | sleep(RETRY_INTERVAL); | ||
+ | } else { | ||
+ | nb_syslog(" | ||
+ | this.fd = sock; | ||
+ | this.state = " | ||
+ | return 0; | ||
+ | } | ||
+ | } | ||
+ | nb_syslog(" | ||
+ | this.since = this.jiffy(); | ||
+ | this.state = " | ||
+ | close(this.fd); | ||
+ | this.fd = -1; | ||
+ | |||
+ | return -1; | ||
+ | } | ||
+ | |||
+ | int disconnect() { | ||
+ | if (this.fd > -1) { | ||
+ | close(this.fd); | ||
+ | this.fd = -1; | ||
+ | } | ||
+ | this.state = " | ||
+ | this.since = this.jiffy(); | ||
+ | nb_syslog(" | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | } /* endof template slave */ | ||
+ | |||
+ | int start_serial() | ||
+ | { | ||
+ | /* check serial port config */ | ||
+ | status = nb_config_get(sprintf(" | ||
+ | if (status != " | ||
+ | nb_syslog(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | /* set attributes */ | ||
+ | rc = nb_serial_setattr(DEV, | ||
+ | if (rc != 0) { | ||
+ | nb_syslog(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | /* open serial port */ | ||
+ | fd = nb_serial_open(DEV); | ||
+ | if (fd < 0) { | ||
+ | nb_syslog(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | return fd; | ||
+ | } | ||
+ | |||
+ | int stop_serial() | ||
+ | { | ||
+ | if (fd > -1) { | ||
+ | close(fd); | ||
+ | fd = -1; | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | void usage() | ||
+ | { | ||
+ | nb_syslog(" | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | |||
+ | /* ------------------------ main ------------------------------- */ | ||
+ | |||
+ | |||
+ | if (strlen(argv[1]) == 0) { | ||
+ | nb_syslog(" | ||
+ | usage(); | ||
+ | } | ||
+ | |||
+ | /* create slaves */ | ||
+ | nb_syslog(" | ||
+ | for (i = 1; i < argc; i++) { | ||
+ | slaves[i-1] = new slave(argv[i]); | ||
+ | } | ||
+ | |||
+ | /* connect slave */ | ||
+ | for (i = 0; i < length(slaves); | ||
+ | nb_syslog(" | ||
+ | rc = slaves[i].connect(); | ||
+ | if (rc < 0) { | ||
+ | nb_syslog(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | nb_syslog(" | ||
+ | serial_fd = start_serial(); | ||
+ | |||
+ | /* create file descriptor array */ | ||
+ | fds = mkarray(); | ||
+ | tcp_fds = mkarray(); | ||
+ | j = 0; | ||
+ | for (i = 0; i < length(slaves); | ||
+ | if (slaves[i].state == " | ||
+ | tcp_fds[j] = slaves[i].fd; | ||
+ | j++; | ||
+ | } | ||
+ | } | ||
+ | fds = array_merge(serial_fd, | ||
+ | |||
+ | |||
+ | /* loop infinitely */ | ||
+ | while (1) { | ||
+ | buffer = ""; | ||
+ | rc = select(fds, POLL_TIMEOUT); | ||
+ | if (rc == -1) { | ||
+ | nb_syslog(" | ||
+ | } else if (rc == serial_fd) { | ||
+ | /* received something from serial device */ | ||
+ | data = read(serial_fd, | ||
+ | if (data) { | ||
+ | serialbuffer = strcat(serialbuffer, | ||
+ | nb_syslog(" | ||
+ | } | ||
+ | } else if (rc != 0 && array_search(tcp_fds, | ||
+ | /* received something from TCP */ | ||
+ | data = recv(rc); | ||
+ | len=strlen(data); | ||
+ | if (len > 0) { | ||
+ | /* write to serial device */ | ||
+ | write(serial_fd, | ||
+ | } else if(len == 0) { | ||
+ | // | ||
+ | for (i = 0; i < length(slaves); | ||
+ | if (rc == slaves[i].fd) { | ||
+ | /* disconnect */ | ||
+ | slaves[i].disconnect(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | /* check serial buffer and send message */ | ||
+ | len = strlen(serialbuffer); | ||
+ | msg = serialbuffer; | ||
+ | msglen = len; | ||
+ | serialbuffer = ""; | ||
+ | |||
+ | /* send TCP packet to every slave */ | ||
+ | if (len > 0) { | ||
+ | for (i = 0; i < length(slaves); | ||
+ | if (slaves[i].state == " | ||
+ | sent = send(slaves[i].fd, | ||
+ | if (sent == -1) { | ||
+ | nb_syslog(" | ||
+ | /* disconnect slave */ | ||
+ | slaves[i].disconnect(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | /* check if we have an error on the socket */ | ||
+ | for (i = 0; i < length(slaves); | ||
+ | if (slaves[i].state == " | ||
+ | opt = getsockopt(slaves[i].fd, | ||
+ | if (opt != 0) { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* reconnect to disconnected slaves */ | ||
+ | for ( i=0; i < length(slaves); | ||
+ | if (slaves[i].state == " | ||
+ | if ( (slaves[i].since + RECOVER_INTERVAL) < slaves[i].jiffy() ) { | ||
+ | slaves[i].connect(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* re-create file descriptor array */ | ||
+ | fds = mkarray(); | ||
+ | tcp_fds = mkarray(); | ||
+ | j = 0; | ||
+ | for (i = 0; i < length(slaves); | ||
+ | if (slaves[i].state == " | ||
+ | | ||
+ | j++; | ||
+ | } | ||
+ | } | ||
+ | fds = array_merge(serial_fd, | ||
+ | } | ||
+ | |||
+ | exit(0); | ||
+ | |||
+ | |||
+ | </ | ||