This shows you the differences between two versions of the page.
| — | sdk:serial-point-to-multipoint [2015/05/06 12:49] (current) – created - external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Serial Point to Multipoint ====== | ||
| + | This script reads messages coming from the local serial port and forwards them via TCP to a all remote host (and vice versa). | ||
| + | The local port can be the physical RS-232 (SERIAL1) or a virtual one using a USB adapter (SERIAL2). | ||
| + | <code c serial-point-to-multipoint.are> | ||
| + | // DESC: This script reads messages coming from the serial port and forwards them via TCP to a all remote host (and vice versa). | ||
| + | // Copyright (C) 2014 NetModule AG | ||
| + | // 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 (Only changed if your device has more then one serial Interface (NB3710) */ | ||
| + | DEV = " | ||
| + | |||
| + | /* TCP Options */ | ||
| + | /* If the script try to connect to a tcp slave, how many retries should it make */ | ||
| + | RETRY = 3; | ||
| + | /* The pause in seconds between the retries*/ | ||
| + | RETRY_INTERVAL = 3; | ||
| + | /* How many seconds should the script wait to run a new set of retries after the client got lost, or the retries were not sucessfull */ | ||
| + | RECOVER_INTERVAL = 120; | ||
| + | |||
| + | |||
| + | //################################################################ | ||
| + | //################################################################ | ||
| + | //################################################################ | ||
| + | /* Only changed things below this line if you know what you are doing */ | ||
| + | //################################################################ | ||
| + | //################################################################ | ||
| + | //################################################################ | ||
| + | POLL_TIMEOUT = 10; /* seconds */ | ||
| + | REMOTE_PORT =2000; | ||
| + | |||
| + | |||
| + | |||
| + | template slave | ||
| + | { | ||
| + | hostname = ""; | ||
| + | fd = -1; | ||
| + | state = " | ||
| + | downSince = 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() { | ||
| + | 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.downSince=this.jiffy(); | ||
| + | this.state=" | ||
| + | close(this.fd); | ||
| + | return -1; | ||
| + | } | ||
| + | |||
| + | int disconnect() { | ||
| + | close(this.fd); | ||
| + | this.fd=-1; | ||
| + | this.state=" | ||
| + | this.downSince=this.jiffy(); | ||
| + | nb_syslog(" | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | |||
| + | } // of template slave | ||
| + | |||
| + | void usage() | ||
| + | { | ||
| + | nb_syslog(" | ||
| + | exit(1); | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | int start_serial() { | ||
| + | |||
| + | /* check serial port config */ | ||
| + | status = nb_config_get(" | ||
| + | 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() { | ||
| + | |||
| + | close(fd); | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | // ################################################### | ||
| + | // ################################################### | ||
| + | // ######## | ||
| + | // ################################################### | ||
| + | // ################################################### | ||
| + | // ################################################### | ||
| + | |||
| + | /* check arguments */ | ||
| + | if (strlen(argv[1]) == 0) { | ||
| + | nb_syslog(" | ||
| + | usage(); | ||
| + | } | ||
| + | |||
| + | /* create slave host list and set */ | ||
| + | |||
| + | |||
| + | nb_syslog(" | ||
| + | for (i=1; i < argc; i++) { | ||
| + | slaves[i-1] = new slave(argv[i]); | ||
| + | } | ||
| + | // connect to slave | ||
| + | //for ( i=0; i < length(slaves); | ||
| + | for ( i=0; i < length(slaves); | ||
| + | | ||
| + | rc = slaves[i].connect(); | ||
| + | if (rc < 0) { | ||
| + | nb_syslog(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | nb_syslog(" | ||
| + | serial_fd = start_serial(); | ||
| + | |||
| + | |||
| + | |||
| + | // Creating tcp fd array for select() | ||
| + | fds=mkarray(); | ||
| + | tcp_fds=mkarray(); | ||
| + | j=0; | ||
| + | for ( i=0; i < length(slaves); | ||
| + | if (slaves[i].state == " | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | fds=array_merge(serial_fd, | ||
| + | |||
| + | |||
| + | 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) { | ||
| + | /* lets put the socket on disable */ | ||
| + | slaves[i].disconnect(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | /* check serial buffer and send message */ | ||
| + | len = strlen(serialbuffer); | ||
| + | // we have data for the slaves lets sent it | ||
| + | msg = serialbuffer; | ||
| + | msglen = len; | ||
| + | serialbuffer = ""; | ||
| + | |||
| + | /* send TCP packet to every socket */ | ||
| + | if (len > 0) { | ||
| + | for ( i=0; i < length(slaves); | ||
| + | if (slaves[i].state == " | ||
| + | sent = send(slaves[i].fd, | ||
| + | if (sent == -1) { | ||
| + | nb_syslog(" | ||
| + | /* lets put the socket on disable */ | ||
| + | slaves[i].disconnect(); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | /* check if we have a error on the soocket */ | ||
| + | for ( i=0; i < length(slaves); | ||
| + | if (slaves[i].state == " | ||
| + | sockop=getsockopt(slaves[i].fd, | ||
| + | if (sockop != 0) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | // reconnect to lost slaves | ||
| + | for ( i=0; i < length(slaves); | ||
| + | if (slaves[i].state == " | ||
| + | if ( (slaves[i].downSince + RECOVER_INTERVAL) < slaves[i].jiffy() ) { | ||
| + | slaves[i].connect(); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // recreate online fds | ||
| + | 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); | ||
| + | </ | ||
| + | |||