blob: 4f6687ea40a15bfdae0188cdfd91e2123b90ead2 [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) {
16 LOG(ERROR, "failed to create socket because of %d: %s\n",
17 errno, strerror(errno));
brians343bc112013-02-10 01:53:46 +000018 return last_ret_ = 1;
Brian Silvermana9cbe302013-03-12 18:41:44 -070019 }
brians343bc112013-02-10 01:53:46 +000020
Brian Silvermana9cbe302013-03-12 18:41:44 -070021 memset(&addr_, 0, sizeof(addr_));
22 addr_.in.sin_family = AF_INET;
Brian Silvermanf02c3982014-04-21 22:04:41 -070023 addr_.in.sin_port = hton<uint16_t>(static_cast<uint16_t>(port));
brians343bc112013-02-10 01:53:46 +000024#ifndef __VXWORKS__
25 const int failure_return = 0;
26#else
27 const int failure_return = -1;
28#endif
Brianc9f64552014-04-02 19:44:09 -070029 if (inet_aton(address, &addr_.in.sin_addr) == failure_return) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070030 LOG(ERROR, "Invalid IP address '%s' because of %d: %s\n", address,
brians343bc112013-02-10 01:53:46 +000031 errno, strerror(errno));
32 return last_ret_ = -1;
Brian Silvermana9cbe302013-03-12 18:41:44 -070033 }
brians343bc112013-02-10 01:53:46 +000034
35 return last_ret_ = 0;
36}
Brian Silverman3204dd82013-03-12 18:42:01 -070037
brians343bc112013-02-10 01:53:46 +000038Socket::Socket() : socket_(-1), last_ret_(2) {}
Brian Silverman3204dd82013-03-12 18:42:01 -070039
brians343bc112013-02-10 01:53:46 +000040Socket::~Socket() {
Brian Silvermana9cbe302013-03-12 18:41:44 -070041 close(socket_);
brians343bc112013-02-10 01:53:46 +000042}
43
44void Socket::Reset() {
45 if (socket_ != -1) {
46 close(socket_);
47 socket_ = -1;
48 }
49 last_ret_ = 0;
50}
51
Brian Silverman3204dd82013-03-12 18:42:01 -070052int Socket::Receive(void *buf, int length) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070053 const int ret = recv(socket_, static_cast<char *>(buf), length, 0);
brians343bc112013-02-10 01:53:46 +000054 last_ret_ = (ret == -1) ? -1 : 0;
55 return ret;
56}
Brian Silverman3204dd82013-03-12 18:42:01 -070057
58int Socket::Receive(void *buf, int length, time::Time timeout) {
59 timeval timeout_timeval = timeout.ToTimeval();
60 fd_set fds;
61 FD_ZERO(&fds);
62 FD_SET(socket_, &fds);
63 switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout_timeval)) {
64 case 1:
65 return Receive(buf, length);
66 case 0:
67 return last_ret_ = 0;
68 default:
69 if (errno == EINTR) {
70 return last_ret_ = 0;
71 }
72 LOG(FATAL, "select(FD_SETSIZE, %p, NULL, NULL, %p) failed with %d: %s\n",
73 &fds, &timeout_timeval, errno, strerror(errno));
74 }
brians343bc112013-02-10 01:53:46 +000075}
Brian Silverman3204dd82013-03-12 18:42:01 -070076
brians343bc112013-02-10 01:53:46 +000077int Socket::Send(const void *buf, int length) {
Brian Silvermana9cbe302013-03-12 18:41:44 -070078 const int ret = write(socket_,
Brianc9f64552014-04-02 19:44:09 -070079 static_cast<const char *>(buf), length);
brians343bc112013-02-10 01:53:46 +000080 last_ret_ = (ret == -1) ? -1 : 0;
81 return ret;
82}
83
Brianc9f64552014-04-02 19:44:09 -070084} // namespace network
Brian Silvermana9cbe302013-03-12 18:41:44 -070085} // namespace aos