blob: 1448304c80d7625f13ee25484161c83399d5fadd [file] [log] [blame]
Brianc9f64552014-04-02 19:44:09 -07001#include "aos/common/network/socket.h"
brians343bc112013-02-10 01:53:46 +00002
3#include <string.h>
4#include <errno.h>
Brianc9f64552014-04-02 19:44:09 -07005#include <sys/socket.h>
brians343bc112013-02-10 01:53:46 +00006
Brian Silvermana9cbe302013-03-12 18:41:44 -07007#include "aos/common/logging/logging.h"
brians343bc112013-02-10 01:53:46 +00008
9namespace aos {
Brianc9f64552014-04-02 19:44:09 -070010namespace network {
brians343bc112013-02-10 01:53:46 +000011
12int Socket::Connect(NetworkPort port, const char *address, int type) {
13 last_ret_ = 0;
Brian Silvermana9cbe302013-03-12 18:41:44 -070014 if ((socket_ = socket(AF_INET, type, 0)) < 0) {
15 LOG(ERROR, "failed to create socket because of %d: %s\n",
16 errno, strerror(errno));
brians343bc112013-02-10 01:53:46 +000017 return last_ret_ = 1;
Brian Silvermana9cbe302013-03-12 18:41:44 -070018 }
brians343bc112013-02-10 01:53:46 +000019
Brian Silvermana9cbe302013-03-12 18:41:44 -070020 memset(&addr_, 0, sizeof(addr_));
21 addr_.in.sin_family = AF_INET;
brians343bc112013-02-10 01:53:46 +000022 addr_.in.sin_port = htons(static_cast<uint16_t>(port));
23#ifndef __VXWORKS__
24 const int failure_return = 0;
25#else
26 const int failure_return = -1;
27#endif
Brianc9f64552014-04-02 19:44:09 -070028 if (inet_aton(address, &addr_.in.sin_addr) == failure_return) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070029 LOG(ERROR, "Invalid IP address '%s' because of %d: %s\n", address,
brians343bc112013-02-10 01:53:46 +000030 errno, strerror(errno));
31 return last_ret_ = -1;
Brian Silvermana9cbe302013-03-12 18:41:44 -070032 }
brians343bc112013-02-10 01:53:46 +000033
34 return last_ret_ = 0;
35}
Brian Silverman3204dd82013-03-12 18:42:01 -070036
brians343bc112013-02-10 01:53:46 +000037Socket::Socket() : socket_(-1), last_ret_(2) {}
Brian Silverman3204dd82013-03-12 18:42:01 -070038
brians343bc112013-02-10 01:53:46 +000039Socket::~Socket() {
Brian Silvermana9cbe302013-03-12 18:41:44 -070040 close(socket_);
brians343bc112013-02-10 01:53:46 +000041}
42
43void Socket::Reset() {
44 if (socket_ != -1) {
45 close(socket_);
46 socket_ = -1;
47 }
48 last_ret_ = 0;
49}
50
Brian Silverman3204dd82013-03-12 18:42:01 -070051int Socket::Receive(void *buf, int length) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070052 const int ret = recv(socket_, static_cast<char *>(buf), length, 0);
brians343bc112013-02-10 01:53:46 +000053 last_ret_ = (ret == -1) ? -1 : 0;
54 return ret;
55}
Brian Silverman3204dd82013-03-12 18:42:01 -070056
57int Socket::Receive(void *buf, int length, time::Time timeout) {
58 timeval timeout_timeval = timeout.ToTimeval();
59 fd_set fds;
60 FD_ZERO(&fds);
61 FD_SET(socket_, &fds);
62 switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout_timeval)) {
63 case 1:
64 return Receive(buf, length);
65 case 0:
66 return last_ret_ = 0;
67 default:
68 if (errno == EINTR) {
69 return last_ret_ = 0;
70 }
71 LOG(FATAL, "select(FD_SETSIZE, %p, NULL, NULL, %p) failed with %d: %s\n",
72 &fds, &timeout_timeval, errno, strerror(errno));
73 }
brians343bc112013-02-10 01:53:46 +000074}
Brian Silverman3204dd82013-03-12 18:42:01 -070075
brians343bc112013-02-10 01:53:46 +000076int Socket::Send(const void *buf, int length) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070077 const int ret = write(socket_,
Brianc9f64552014-04-02 19:44:09 -070078 static_cast<const char *>(buf), length);
brians343bc112013-02-10 01:53:46 +000079 last_ret_ = (ret == -1) ? -1 : 0;
80 return ret;
81}
82
Brianc9f64552014-04-02 19:44:09 -070083} // namespace network
Brian Silvermana9cbe302013-03-12 18:41:44 -070084} // namespace aos