init

Dependencies:   mbed C12832 EthernetInterface MQTT mbed-rtos picojson

Committer:
co838_mgl6
Date:
Thu May 05 14:02:24 2016 +0000
Revision:
3:f809d8f8e572
Parent:
1:1e45dd2c91fb
final

Who changed what in which revision?

UserRevisionLine numberNew contents of line
co838_mgl6 1:1e45dd2c91fb 1 #if !defined(LINUX_IPSTACK_H)
co838_mgl6 1:1e45dd2c91fb 2 #define LINUX_IPSTACK_H
co838_mgl6 1:1e45dd2c91fb 3
co838_mgl6 1:1e45dd2c91fb 4 class IPStack
co838_mgl6 1:1e45dd2c91fb 5 {
co838_mgl6 1:1e45dd2c91fb 6 public:
co838_mgl6 1:1e45dd2c91fb 7 IPStack()
co838_mgl6 1:1e45dd2c91fb 8 {
co838_mgl6 1:1e45dd2c91fb 9
co838_mgl6 1:1e45dd2c91fb 10 }
co838_mgl6 1:1e45dd2c91fb 11
co838_mgl6 1:1e45dd2c91fb 12 int Socket_error(const char* aString)
co838_mgl6 1:1e45dd2c91fb 13 {
co838_mgl6 1:1e45dd2c91fb 14
co838_mgl6 1:1e45dd2c91fb 15 if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && errno != EWOULDBLOCK)
co838_mgl6 1:1e45dd2c91fb 16 {
co838_mgl6 1:1e45dd2c91fb 17 if (strcmp(aString, "shutdown") != 0 || (errno != ENOTCONN && errno != ECONNRESET))
co838_mgl6 1:1e45dd2c91fb 18 printf("Socket error %s in %s for socket %d\n", strerror(errno), aString, mysock);
co838_mgl6 1:1e45dd2c91fb 19 }
co838_mgl6 1:1e45dd2c91fb 20 return errno;
co838_mgl6 1:1e45dd2c91fb 21 }
co838_mgl6 1:1e45dd2c91fb 22
co838_mgl6 1:1e45dd2c91fb 23 int connect(const char* hostname, int port)
co838_mgl6 1:1e45dd2c91fb 24 {
co838_mgl6 1:1e45dd2c91fb 25 int type = SOCK_STREAM;
co838_mgl6 1:1e45dd2c91fb 26 struct sockaddr_in address;
co838_mgl6 1:1e45dd2c91fb 27 int rc = -1;
co838_mgl6 1:1e45dd2c91fb 28 sa_family_t family = AF_INET;
co838_mgl6 1:1e45dd2c91fb 29 struct addrinfo *result = NULL;
co838_mgl6 1:1e45dd2c91fb 30 struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL};
co838_mgl6 1:1e45dd2c91fb 31
co838_mgl6 1:1e45dd2c91fb 32 if ((rc = getaddrinfo(hostname, NULL, &hints, &result)) == 0)
co838_mgl6 1:1e45dd2c91fb 33 {
co838_mgl6 1:1e45dd2c91fb 34 struct addrinfo* res = result;
co838_mgl6 1:1e45dd2c91fb 35
co838_mgl6 1:1e45dd2c91fb 36 /* prefer ip4 addresses */
co838_mgl6 1:1e45dd2c91fb 37 while (res)
co838_mgl6 1:1e45dd2c91fb 38 {
co838_mgl6 1:1e45dd2c91fb 39 if (res->ai_family == AF_INET)
co838_mgl6 1:1e45dd2c91fb 40 {
co838_mgl6 1:1e45dd2c91fb 41 result = res;
co838_mgl6 1:1e45dd2c91fb 42 break;
co838_mgl6 1:1e45dd2c91fb 43 }
co838_mgl6 1:1e45dd2c91fb 44 res = res->ai_next;
co838_mgl6 1:1e45dd2c91fb 45 }
co838_mgl6 1:1e45dd2c91fb 46
co838_mgl6 1:1e45dd2c91fb 47 if (result->ai_family == AF_INET)
co838_mgl6 1:1e45dd2c91fb 48 {
co838_mgl6 1:1e45dd2c91fb 49 address.sin_port = htons(port);
co838_mgl6 1:1e45dd2c91fb 50 address.sin_family = family = AF_INET;
co838_mgl6 1:1e45dd2c91fb 51 address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr;
co838_mgl6 1:1e45dd2c91fb 52 }
co838_mgl6 1:1e45dd2c91fb 53 else
co838_mgl6 1:1e45dd2c91fb 54 rc = -1;
co838_mgl6 1:1e45dd2c91fb 55
co838_mgl6 1:1e45dd2c91fb 56 freeaddrinfo(result);
co838_mgl6 1:1e45dd2c91fb 57 }
co838_mgl6 1:1e45dd2c91fb 58
co838_mgl6 1:1e45dd2c91fb 59 if (rc == 0)
co838_mgl6 1:1e45dd2c91fb 60 {
co838_mgl6 1:1e45dd2c91fb 61 mysock = socket(family, type, 0);
co838_mgl6 1:1e45dd2c91fb 62 if (mysock != -1)
co838_mgl6 1:1e45dd2c91fb 63 {
co838_mgl6 1:1e45dd2c91fb 64 int opt = 1;
co838_mgl6 1:1e45dd2c91fb 65
co838_mgl6 1:1e45dd2c91fb 66 //if (setsockopt(mysock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt)) != 0)
co838_mgl6 1:1e45dd2c91fb 67 // printf("Could not set SO_NOSIGPIPE for socket %d", mysock);
co838_mgl6 1:1e45dd2c91fb 68
co838_mgl6 1:1e45dd2c91fb 69 rc = ::connect(mysock, (struct sockaddr*)&address, sizeof(address));
co838_mgl6 1:1e45dd2c91fb 70 }
co838_mgl6 1:1e45dd2c91fb 71 }
co838_mgl6 1:1e45dd2c91fb 72
co838_mgl6 1:1e45dd2c91fb 73 return rc;
co838_mgl6 1:1e45dd2c91fb 74 }
co838_mgl6 1:1e45dd2c91fb 75
co838_mgl6 1:1e45dd2c91fb 76 int read(char* buffer, int len, int timeout_ms)
co838_mgl6 1:1e45dd2c91fb 77 {
co838_mgl6 1:1e45dd2c91fb 78 struct timeval interval = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
co838_mgl6 1:1e45dd2c91fb 79 if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 0))
co838_mgl6 1:1e45dd2c91fb 80 {
co838_mgl6 1:1e45dd2c91fb 81 interval.tv_sec = 0;
co838_mgl6 1:1e45dd2c91fb 82 interval.tv_usec = 100;
co838_mgl6 1:1e45dd2c91fb 83 }
co838_mgl6 1:1e45dd2c91fb 84
co838_mgl6 1:1e45dd2c91fb 85 setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO, (char *)&interval, sizeof(struct timeval));
co838_mgl6 1:1e45dd2c91fb 86
co838_mgl6 1:1e45dd2c91fb 87 //printf("reading %d bytes\n", len);
co838_mgl6 1:1e45dd2c91fb 88 int rc = ::recv(mysock, buffer, (size_t)len, 0);
co838_mgl6 1:1e45dd2c91fb 89 if (rc == -1)
co838_mgl6 1:1e45dd2c91fb 90 Socket_error("read");
co838_mgl6 1:1e45dd2c91fb 91 //printf("read %d bytes\n", rc);
co838_mgl6 1:1e45dd2c91fb 92 return rc;
co838_mgl6 1:1e45dd2c91fb 93 }
co838_mgl6 1:1e45dd2c91fb 94
co838_mgl6 1:1e45dd2c91fb 95 int write(char* buffer, int len, int timeout)
co838_mgl6 1:1e45dd2c91fb 96 {
co838_mgl6 1:1e45dd2c91fb 97 struct timeval tv;
co838_mgl6 1:1e45dd2c91fb 98
co838_mgl6 1:1e45dd2c91fb 99 tv.tv_sec = 0; /* 30 Secs Timeout */
co838_mgl6 1:1e45dd2c91fb 100 tv.tv_usec = timeout * 1000; // Not init'ing this can cause strange errors
co838_mgl6 1:1e45dd2c91fb 101
co838_mgl6 1:1e45dd2c91fb 102 setsockopt(mysock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
co838_mgl6 1:1e45dd2c91fb 103 int rc = ::write(mysock, buffer, len);
co838_mgl6 1:1e45dd2c91fb 104 //printf("write rc %d\n", rc);
co838_mgl6 1:1e45dd2c91fb 105 return rc;
co838_mgl6 1:1e45dd2c91fb 106 }
co838_mgl6 1:1e45dd2c91fb 107
co838_mgl6 1:1e45dd2c91fb 108 int disconnect()
co838_mgl6 1:1e45dd2c91fb 109 {
co838_mgl6 1:1e45dd2c91fb 110 return ::close(mysock);
co838_mgl6 1:1e45dd2c91fb 111 }
co838_mgl6 1:1e45dd2c91fb 112
co838_mgl6 1:1e45dd2c91fb 113 private:
co838_mgl6 1:1e45dd2c91fb 114
co838_mgl6 1:1e45dd2c91fb 115 int mysock;
co838_mgl6 1:1e45dd2c91fb 116
co838_mgl6 1:1e45dd2c91fb 117 };
co838_mgl6 1:1e45dd2c91fb 118
co838_mgl6 1:1e45dd2c91fb 119 #endif