summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Maki <jmaki@multitech.com>2010-11-19 12:18:35 -0600
committerJames Maki <jmaki@multitech.com>2010-11-19 12:18:35 -0600
commit05a380df982e25ca320113f98f8c7eb659677775 (patch)
tree60b21ec419248abfe9b7073c6c1b841ccaab01a2
parentbea2da186e9788a5f5e46eefdff3e318400c4526 (diff)
downloadvenus-gps-05a380df982e25ca320113f98f8c7eb659677775.tar.gz
venus-gps-05a380df982e25ca320113f98f8c7eb659677775.tar.bz2
venus-gps-05a380df982e25ca320113f98f8c7eb659677775.zip
use TCP_CORK instead of MSG_MORE
-rw-r--r--src/utils.c31
-rw-r--r--src/utils.h2
-rw-r--r--src/venus_gps.c101
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) {