This shows you the differences between two versions of the page.
sdk:scripts:serial-udp-server [2015/05/05 15:04] |
sdk:scripts:serial-udp-server [2015/05/05 15:04] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== SDK Script serial-udp-server.are ====== | ||
+ | <code c serial-udp-server.are> | ||
+ | /* DESC: This script reads messages coming from the serial port and forwards them via UDP to a remote host (and vice versa). | ||
+ | * Copyright (C) 2013 NetModule AG, Switzerland | ||
+ | */ | ||
+ | |||
+ | DEV = "SERIAL1"; | ||
+ | |||
+ | REMOTE_HOST = argv[1]; | ||
+ | REMOTE_PORT = (int) argv[2]; | ||
+ | LOCAL_PORT = (int) argv[3]; | ||
+ | MAX_PACKET_SIZE = (int) argv[4]; /* bytes */ | ||
+ | POLL_TIMEOUT = (int) argv[5]; /* seconds */ | ||
+ | LATENCY = (int) argv[6]; /* seconds */ | ||
+ | |||
+ | void usage() | ||
+ | { | ||
+ | printf("usage: serial-udp-server.are <remote-host> <remote-port> <local-port> <max-packet-size> <poll-timeout> <latency>\n"); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | int jiffy() | ||
+ | { | ||
+ | sys = sysinfo(); | ||
+ | u = struct_get(sys, "uptime"); | ||
+ | |||
+ | if (is_void(u) || u < 1) { | ||
+ | return 0; | ||
+ | } else { | ||
+ | return u; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* check arguments */ | ||
+ | if (strlen(argv[1]) == 0) { | ||
+ | nb_syslog("ERROR: no remote host specified"); | ||
+ | usage(); | ||
+ | } | ||
+ | if (strlen(argv[2]) == 0) { | ||
+ | nb_syslog("ERROR: no remote port specified"); | ||
+ | usage(); | ||
+ | } | ||
+ | if (strlen(argv[3]) == 0) { | ||
+ | nb_syslog("ERROR: no local port specified"); | ||
+ | usage(); | ||
+ | } | ||
+ | if (strlen(argv[4]) == 0) { | ||
+ | MAX_PACKET_SIZE = 1380; | ||
+ | } | ||
+ | if (strlen(argv[5]) == 0 || POLL_TIMEOUT < 1) { | ||
+ | POLL_TIMEOUT = 1; | ||
+ | } | ||
+ | if (strlen(argv[6]) == 0 || LATENCY < 1) { | ||
+ | LATENCY = 2; | ||
+ | } | ||
+ | |||
+ | /* check serial port config */ | ||
+ | status = nb_config_get("serial.0.status"); | ||
+ | if (status != "2") { | ||
+ | nb_syslog("serial port is not enabled for us"); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | /* set attributes */ | ||
+ | rc = nb_serial_setattr(DEV, 115200, 8, 1, 0, 0); | ||
+ | if (rc != 0) { | ||
+ | nb_syslog("ERROR: unable to set serial attributes (rc %d)", rc); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | /* open serial port */ | ||
+ | fd = nb_serial_open(DEV); | ||
+ | if (fd < 0) { | ||
+ | nb_syslog("Unable to open serial device (%s)", DEV); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | /* open UDP socket */ | ||
+ | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||
+ | if (sock < 0) { | ||
+ | nb_syslog("ERROR: unable to open socket"); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | /* bind socket to 1st LAN interface */ | ||
+ | addr = nb_ifc_address("LAN1"); | ||
+ | rc = bind(sock, REMOTE_PORT, addr); | ||
+ | if (rc == -1) { | ||
+ | nb_syslog("ERROR: unable to bind to port %d\n", REMOTE_PORT); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | nb_syslog("Listening for messages (local %d, remote %s:%d)", LOCAL_PORT, REMOTE_HOST, REMOTE_PORT); | ||
+ | |||
+ | fds = mkarray(sock, fd); | ||
+ | last = jiffy(); | ||
+ | buffer = ""; | ||
+ | |||
+ | while (1) { | ||
+ | rc = select(fds, POLL_TIMEOUT); | ||
+ | if (rc == -1) { | ||
+ | nb_syslog("ERROR: select failed"); | ||
+ | close(fd); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | if (rc == fd) { | ||
+ | /* received something from serial device */ | ||
+ | data = read(fd, 4096); | ||
+ | if (data) { | ||
+ | buffer = strcat(buffer, data); | ||
+ | } | ||
+ | } else if (rc == sock) { | ||
+ | /* received something from UDP */ | ||
+ | data = recvfrom(sock); | ||
+ | if (data) { | ||
+ | len = strlen(data); | ||
+ | if (len > 0) { | ||
+ | /* write to serial device */ | ||
+ | if (len > MAX_PACKET_SIZE) len = MAX_PACKET_SIZE; | ||
+ | write(fd, data, len); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* check serial buffer and send message */ | ||
+ | len = strlen(buffer); | ||
+ | if (len == 0) continue; | ||
+ | |||
+ | now = jiffy(); | ||
+ | elapsed = now - last; | ||
+ | |||
+ | if (len < MAX_PACKET_SIZE && elapsed < LATENCY) continue; | ||
+ | |||
+ | if (len <= MAX_PACKET_SIZE) { | ||
+ | msg = buffer; | ||
+ | msglen = len; | ||
+ | buffer = ""; | ||
+ | } else { | ||
+ | msg = substr(buffer, 0, MAX_PACKET_SIZE); | ||
+ | msglen = MAX_PACKET_SIZE; | ||
+ | buffer = substr(buffer, MAX_PACKET_SIZE); | ||
+ | } | ||
+ | |||
+ | /* send UDP packet */ | ||
+ | sendbufto(sock, msg, msglen, REMOTE_HOST, REMOTE_PORT); | ||
+ | last = now; | ||
+ | } | ||
+ | |||
+ | close(sock); | ||
+ | close(fd); | ||
+ | |||
+ | exit(0); | ||
+ | |||
+ | </code> | ||