blob: 80eca70fcfb892f061b6319c7f83b9872331e15f [file] [log] [blame]
Brianc9f64552014-04-02 19:44:09 -07001#include "aos/common/network/socket.h"
brians343bc112013-02-10 01:53:46 +00002
brians343bc112013-02-10 01:53:46 +00003#include <errno.h>
Austin Schuhf2a50ba2016-12-24 16:16:26 -08004#include <string.h>
Brianc9f64552014-04-02 19:44:09 -07005#include <sys/socket.h>
Austin Schuhf2a50ba2016-12-24 16:16:26 -08006#include <chrono>
brians343bc112013-02-10 01:53:46 +00007
Brian Silvermanf02c3982014-04-21 22:04:41 -07008#include "aos/common/byteorder.h"
Austin Schuhf2a50ba2016-12-24 16:16:26 -08009#include "aos/common/logging/logging.h"
brians343bc112013-02-10 01:53:46 +000010
11namespace aos {
Brianc9f64552014-04-02 19:44:09 -070012namespace network {
brians343bc112013-02-10 01:53:46 +000013
Austin Schuhf2a50ba2016-12-24 16:16:26 -080014namespace chrono = ::std::chrono;
15
brians343bc112013-02-10 01:53:46 +000016int Socket::Connect(NetworkPort port, const char *address, int type) {
17 last_ret_ = 0;
Brian Silvermana9cbe302013-03-12 18:41:44 -070018 if ((socket_ = socket(AF_INET, type, 0)) < 0) {
Brian Silverman01be0002014-05-10 15:44:38 -070019 PLOG(ERROR, "failed to create socket");
brians343bc112013-02-10 01:53:46 +000020 return last_ret_ = 1;
Brian Silvermana9cbe302013-03-12 18:41:44 -070021 }
brians343bc112013-02-10 01:53:46 +000022
Brian Silvermana9cbe302013-03-12 18:41:44 -070023 memset(&addr_, 0, sizeof(addr_));
24 addr_.in.sin_family = AF_INET;
Brian Silvermanf02c3982014-04-21 22:04:41 -070025 addr_.in.sin_port = hton<uint16_t>(static_cast<uint16_t>(port));
brians343bc112013-02-10 01:53:46 +000026#ifndef __VXWORKS__
27 const int failure_return = 0;
28#else
29 const int failure_return = -1;
30#endif
Brianc9f64552014-04-02 19:44:09 -070031 if (inet_aton(address, &addr_.in.sin_addr) == failure_return) {
Brian Silverman01be0002014-05-10 15:44:38 -070032 PLOG(ERROR, "invalid IP address '%s'", address);
brians343bc112013-02-10 01:53:46 +000033 return last_ret_ = -1;
Brian Silvermana9cbe302013-03-12 18:41:44 -070034 }
brians343bc112013-02-10 01:53:46 +000035
36 return last_ret_ = 0;
37}
Brian Silverman3204dd82013-03-12 18:42:01 -070038
brians343bc112013-02-10 01:53:46 +000039Socket::Socket() : socket_(-1), last_ret_(2) {}
Brian Silverman3204dd82013-03-12 18:42:01 -070040
brians343bc112013-02-10 01:53:46 +000041Socket::~Socket() {
Brian Silvermana9cbe302013-03-12 18:41:44 -070042 close(socket_);
brians343bc112013-02-10 01:53:46 +000043}
44
45void Socket::Reset() {
46 if (socket_ != -1) {
47 close(socket_);
48 socket_ = -1;
49 }
50 last_ret_ = 0;
51}
52
Brian Silverman3204dd82013-03-12 18:42:01 -070053int Socket::Receive(void *buf, int length) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070054 const int ret = recv(socket_, static_cast<char *>(buf), length, 0);
brians343bc112013-02-10 01:53:46 +000055 last_ret_ = (ret == -1) ? -1 : 0;
56 return ret;
57}
Brian Silverman3204dd82013-03-12 18:42:01 -070058
Austin Schuhf2a50ba2016-12-24 16:16:26 -080059int Socket::Receive(void *buf, int length, chrono::microseconds timeout) {
60 timeval timeout_timeval;
61 timeout_timeval.tv_sec = chrono::duration_cast<chrono::seconds>(timeout).count();
62 timeout_timeval.tv_usec =
63 chrono::duration_cast<chrono::microseconds>(
64 timeout - chrono::seconds(timeout_timeval.tv_sec))
65 .count();
Brian Silverman3204dd82013-03-12 18:42:01 -070066 fd_set fds;
67 FD_ZERO(&fds);
68 FD_SET(socket_, &fds);
69 switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout_timeval)) {
70 case 1:
71 return Receive(buf, length);
72 case 0:
73 return last_ret_ = 0;
74 default:
75 if (errno == EINTR) {
76 return last_ret_ = 0;
77 }
Brian Silverman01be0002014-05-10 15:44:38 -070078 PLOG(FATAL, "select(FD_SETSIZE, %p, NULL, NULL, %p) failed",
79 &fds, &timeout_timeval);
Brian Silverman3204dd82013-03-12 18:42:01 -070080 }
brians343bc112013-02-10 01:53:46 +000081}
Brian Silverman3204dd82013-03-12 18:42:01 -070082
brians343bc112013-02-10 01:53:46 +000083int Socket::Send(const void *buf, int length) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070084 const int ret = write(socket_,
Brianc9f64552014-04-02 19:44:09 -070085 static_cast<const char *>(buf), length);
brians343bc112013-02-10 01:53:46 +000086 last_ret_ = (ret == -1) ? -1 : 0;
87 return ret;
88}
89
Brianc9f64552014-04-02 19:44:09 -070090} // namespace network
Brian Silvermana9cbe302013-03-12 18:41:44 -070091} // namespace aos