blob: b674ff18a9d4307ccae250d67a1f74890a826b9f [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"
Brian Silvermanf02c3982014-04-21 22:04:41 -07008#include "aos/common/byteorder.h"
brians343bc112013-02-10 01:53:46 +00009
10namespace aos {
Brianc9f64552014-04-02 19:44:09 -070011namespace network {
brians343bc112013-02-10 01:53:46 +000012
13int Socket::Connect(NetworkPort port, const char *address, int type) {
14 last_ret_ = 0;
Brian Silvermana9cbe302013-03-12 18:41:44 -070015 if ((socket_ = socket(AF_INET, type, 0)) < 0) {
Brian Silverman01be0002014-05-10 15:44:38 -070016 PLOG(ERROR, "failed to create socket");
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;
Brian Silvermanf02c3982014-04-21 22:04:41 -070022 addr_.in.sin_port = hton<uint16_t>(static_cast<uint16_t>(port));
brians343bc112013-02-10 01:53:46 +000023#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 Silverman01be0002014-05-10 15:44:38 -070029 PLOG(ERROR, "invalid IP address '%s'", address);
brians343bc112013-02-10 01:53:46 +000030 return last_ret_ = -1;
Brian Silvermana9cbe302013-03-12 18:41:44 -070031 }
brians343bc112013-02-10 01:53:46 +000032
33 return last_ret_ = 0;
34}
Brian Silverman3204dd82013-03-12 18:42:01 -070035
brians343bc112013-02-10 01:53:46 +000036Socket::Socket() : socket_(-1), last_ret_(2) {}
Brian Silverman3204dd82013-03-12 18:42:01 -070037
brians343bc112013-02-10 01:53:46 +000038Socket::~Socket() {
Brian Silvermana9cbe302013-03-12 18:41:44 -070039 close(socket_);
brians343bc112013-02-10 01:53:46 +000040}
41
42void Socket::Reset() {
43 if (socket_ != -1) {
44 close(socket_);
45 socket_ = -1;
46 }
47 last_ret_ = 0;
48}
49
Brian Silverman3204dd82013-03-12 18:42:01 -070050int Socket::Receive(void *buf, int length) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070051 const int ret = recv(socket_, static_cast<char *>(buf), length, 0);
brians343bc112013-02-10 01:53:46 +000052 last_ret_ = (ret == -1) ? -1 : 0;
53 return ret;
54}
Brian Silverman3204dd82013-03-12 18:42:01 -070055
56int Socket::Receive(void *buf, int length, time::Time timeout) {
57 timeval timeout_timeval = timeout.ToTimeval();
58 fd_set fds;
59 FD_ZERO(&fds);
60 FD_SET(socket_, &fds);
61 switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout_timeval)) {
62 case 1:
63 return Receive(buf, length);
64 case 0:
65 return last_ret_ = 0;
66 default:
67 if (errno == EINTR) {
68 return last_ret_ = 0;
69 }
Brian Silverman01be0002014-05-10 15:44:38 -070070 PLOG(FATAL, "select(FD_SETSIZE, %p, NULL, NULL, %p) failed",
71 &fds, &timeout_timeval);
Brian Silverman3204dd82013-03-12 18:42:01 -070072 }
brians343bc112013-02-10 01:53:46 +000073}
Brian Silverman3204dd82013-03-12 18:42:01 -070074
brians343bc112013-02-10 01:53:46 +000075int Socket::Send(const void *buf, int length) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070076 const int ret = write(socket_,
Brianc9f64552014-04-02 19:44:09 -070077 static_cast<const char *>(buf), length);
brians343bc112013-02-10 01:53:46 +000078 last_ret_ = (ret == -1) ? -1 : 0;
79 return ret;
80}
81
Brianc9f64552014-04-02 19:44:09 -070082} // namespace network
Brian Silvermana9cbe302013-03-12 18:41:44 -070083} // namespace aos