diff options
-rw-r--r-- | src/utils.c | 31 | ||||
-rw-r--r-- | src/utils.h | 2 | ||||
-rw-r--r-- | src/venus_gps.c | 101 |
3 files changed, 90 insertions, 44 deletions
diff --git a/src/utils.c b/src/utils.c index 7a15427..9272ef5 100644 --- a/src/utils.c +++ b/src/utils.c @@ -29,6 +29,13 @@ #include <netdb.h> #include <fcntl.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> + +#define UDP_CORK 1 + #include "log.h" #include "utils.h" @@ -144,6 +151,30 @@ int set_nonblocking(int fd) return err; } +int udp_cork(int fd, int corked) +{ + int tmp; + + tmp = setsockopt(fd, IPPROTO_UDP, UDP_CORK, &corked, sizeof(corked)); + if (tmp < 0) { + log_error("setsockopt UDP_CORK failed"); + } + + return -1; +} + +int tcp_cork(int fd, int corked) +{ + int tmp; + + tmp = setsockopt(fd, IPPROTO_TCP, TCP_CORK, &corked, sizeof(corked)); + if (tmp < 0) { + log_error("setsockopt TCP_CORK failed"); + } + + return -1; +} + int host_to_inet(const char *host, struct in_addr *in) { struct hostent h; diff --git a/src/utils.h b/src/utils.h index e9ab44d..53b457f 100644 --- a/src/utils.h +++ b/src/utils.h @@ -21,6 +21,8 @@ ssize_t safe_readn(int fd, void *buf, size_t len); ssize_t safe_write(int fd, const void *buf, size_t count); ssize_t full_write(int fd, const void *buf, size_t len); int set_nonblocking(int fd); +int udp_cork(int fd, int corked); +int tcp_cork(int fd, int corked); int inet_conn_str(const char *host, int port, int type); int inet_conn_ia(struct in_addr *host, int port, int type); diff --git a/src/venus_gps.c b/src/venus_gps.c index 9a26e4f..e5b4836 100644 --- a/src/venus_gps.c +++ b/src/venus_gps.c @@ -1,4 +1,6 @@ /* + * default: + * goto error; * Venus GPS Controller Example * * Copyright (C) 2010 by Multi-Tech Systems @@ -53,7 +55,7 @@ #define ID_PREFIX_MAX 10 #define ID_MAX 20 -#define SLEEP_AFTER_FAILURE 1 +#define SLEEP_AFTER_FAILURE 5 static char id[ID_MAX + 1]; static char id_prefix[ID_PREFIX_MAX + 1]; @@ -249,11 +251,12 @@ struct gps_timeval { }; enum { - WRITE_MSG_SOCKET, + WRITE_MSG_TCP, + WRITE_MSG_UDP, WRITE_MSG_FILE, }; -int write_sentence(int fd, const char *buf, size_t len, int where) +int write_sentence(int fd, const char *buf, size_t len) { int tmp; @@ -261,25 +264,24 @@ int write_sentence(int fd, const char *buf, size_t len, int where) return 0; } - if (where == WRITE_MSG_SOCKET) { - if (*id_prefix) { - tmp = send(fd, id_prefix, strlen(id_prefix), MSG_MORE); - } - if (*id) { - tmp = send(fd, id, strlen(id), MSG_MORE); - } - tmp = send(fd, buf, len, MSG_MORE); - } else { - if (*id_prefix) { - tmp = full_write(fd, id_prefix, strlen(id_prefix)); + if (*id_prefix) { + tmp = full_write(fd, id_prefix, strlen(id_prefix)); + if (tmp < 0) { + log_error("write id-prefix failed: %m"); + return tmp; } - if (*id) { - tmp = full_write(fd, id, strlen(id)); + } + if (*id) { + tmp = full_write(fd, id, strlen(id)); + if (tmp < 0) { + log_error("write id failed: %m"); + return tmp; } - tmp = full_write(fd, buf, len); } + tmp = full_write(fd, buf, len); if (tmp < 0) { - log_error("write failed: %m"); + log_error("write sentence failed: %m"); + return tmp; } return tmp; @@ -288,14 +290,20 @@ int write_sentence(int fd, const char *buf, size_t len, int where) int write_msg(int fd, struct gps_msg *msg, struct gps_timeval *gpstv, int where) { struct timeval tmptv; - int tmp; + int tmp = 0; int count = 0; + if (where == WRITE_MSG_TCP) { + tcp_cork(fd, 1); + } else if (where == WRITE_MSG_UDP) { + udp_cork(fd, 1); + } + if (gpgga && timercmp(&gpstv->gpgga, &msg->timestamp, <=)) { - tmp = write_sentence(fd, msg->gpgga, strlen(msg->gpgga), where); + tmp = write_sentence(fd, msg->gpgga, strlen(msg->gpgga)); if (tmp < 0) { log_error("write_sentence failed"); - return -1; + goto error; } tmptv.tv_sec = gpgga - 1; @@ -304,10 +312,10 @@ int write_msg(int fd, struct gps_msg *msg, struct gps_timeval *gpstv, int where) count++; } if (gpgsa && timercmp(&gpstv->gpgsa, &msg->timestamp, <=)) { - tmp = write_sentence(fd, msg->gpgsa, strlen(msg->gpgsa), where); + tmp = write_sentence(fd, msg->gpgsa, strlen(msg->gpgsa)); if (tmp < 0) { log_error("write_sentence failed"); - return -1; + goto error; } tmptv.tv_sec = gpgsa - 1; @@ -316,20 +324,20 @@ int write_msg(int fd, struct gps_msg *msg, struct gps_timeval *gpstv, int where) count++; } if (gpgsv && timercmp(&gpstv->gpgsv, &msg->timestamp, <=)) { - tmp = write_sentence(fd, msg->gpgsv[0], strlen(msg->gpgsv[0]), where); + tmp = write_sentence(fd, msg->gpgsv[0], strlen(msg->gpgsv[0])); if (tmp < 0) { log_error("write_sentence failed"); - return -1; + goto error; } - tmp = write_sentence(fd, msg->gpgsv[1], strlen(msg->gpgsv[1]), where); + tmp = write_sentence(fd, msg->gpgsv[1], strlen(msg->gpgsv[1])); if (tmp < 0) { log_error("write_sentence failed"); - return -1; + goto error; } - tmp = write_sentence(fd, msg->gpgsv[2], strlen(msg->gpgsv[2]), where); + tmp = write_sentence(fd, msg->gpgsv[2], strlen(msg->gpgsv[2])); if (tmp < 0) { log_error("write_sentence failed"); - return -1; + goto error; } tmptv.tv_sec = gpgsv - 1; @@ -338,10 +346,10 @@ int write_msg(int fd, struct gps_msg *msg, struct gps_timeval *gpstv, int where) count++; } if (gpgll && timercmp(&gpstv->gpgll, &msg->timestamp, <=)) { - tmp = write_sentence(fd, msg->gpgll, strlen(msg->gpgll), where); + tmp = write_sentence(fd, msg->gpgll, strlen(msg->gpgll)); if (tmp < 0) { log_error("write_sentence failed"); - return -1; + goto error; } tmptv.tv_sec = gpgll - 1; @@ -350,10 +358,10 @@ int write_msg(int fd, struct gps_msg *msg, struct gps_timeval *gpstv, int where) count++; } if (gprmc && timercmp(&gpstv->gprmc, &msg->timestamp, <=)) { - tmp = write_sentence(fd, msg->gprmc, strlen(msg->gprmc), where); + tmp = write_sentence(fd, msg->gprmc, strlen(msg->gprmc)); if (tmp < 0) { log_error("write_sentence failed"); - return -1; + goto error; } tmptv.tv_sec = gprmc - 1; @@ -362,10 +370,10 @@ int write_msg(int fd, struct gps_msg *msg, struct gps_timeval *gpstv, int where) count++; } if (gpvtg && timercmp(&gpstv->gpvtg, &msg->timestamp, <=)) { - tmp = write_sentence(fd, msg->gpvtg, strlen(msg->gpvtg), where); + tmp = write_sentence(fd, msg->gpvtg, strlen(msg->gpvtg)); if (tmp < 0) { log_error("write_sentence failed"); - return -1; + goto error; } tmptv.tv_sec = gpvtg - 1; @@ -374,15 +382,15 @@ int write_msg(int fd, struct gps_msg *msg, struct gps_timeval *gpstv, int where) count++; } - if (count && where == WRITE_MSG_SOCKET) { - tmp = send(fd, NULL, 0, 0); - if (tmp < 0) { - log_error("send failed: %m"); - return -1; - } +error: + + if (where == WRITE_MSG_TCP) { + tcp_cork(fd, 0); + } else if (where == WRITE_MSG_UDP) { + udp_cork(fd, 0); } - return count; + return tmp < 0 ? tmp : count; } static int gps_client_consume(int fd, int consumer, int where) @@ -476,15 +484,20 @@ static void *gps_socket_client(void *arg) int sd; int consumer; char *type_name = NULL; + int write_type; struct socket_client_args *sc = (struct socket_client_args *) arg; switch (sc->type) { case SOCK_STREAM: type_name = "TCP"; + write_type = WRITE_MSG_TCP; break; case SOCK_DGRAM: type_name = "UDP"; + write_type = WRITE_MSG_UDP; break; + default: + goto error; } pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); @@ -506,7 +519,7 @@ static void *gps_socket_client(void *arg) sleep(SLEEP_AFTER_FAILURE); } else { log_info("connection opened"); - gps_client_consume(sd, consumer, WRITE_MSG_SOCKET); + gps_client_consume(sd, consumer, write_type); close(sd); log_info("connection closed"); } @@ -539,7 +552,7 @@ static void *gps_tcp_server_conn(void *arg) goto error; } - gps_client_consume(sd, consumer, WRITE_MSG_SOCKET); + gps_client_consume(sd, consumer, WRITE_MSG_TCP); error: if (consumer >= 0) { |