blob: 0366e7c749d3f9d8143bfc4b3d18a0a2a5b16935 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include "aos/common/network/Socket.h"
2
3#include <string.h>
4#include <errno.h>
5
Brian Silvermana9cbe302013-03-12 18:41:44 -07006#include "aos/common/logging/logging.h"
brians343bc112013-02-10 01:53:46 +00007#include "aos/common/network/SocketLibraries.h"
8
9namespace aos {
10
11int Socket::Connect(NetworkPort port, const char *address, int type) {
12 last_ret_ = 0;
Brian Silvermana9cbe302013-03-12 18:41:44 -070013 if ((socket_ = socket(AF_INET, type, 0)) < 0) {
14 LOG(ERROR, "failed to create socket because of %d: %s\n",
15 errno, strerror(errno));
brians343bc112013-02-10 01:53:46 +000016 return last_ret_ = 1;
Brian Silvermana9cbe302013-03-12 18:41:44 -070017 }
brians343bc112013-02-10 01:53:46 +000018
Brian Silvermana9cbe302013-03-12 18:41:44 -070019 memset(&addr_, 0, sizeof(addr_));
20 addr_.in.sin_family = AF_INET;
brians343bc112013-02-10 01:53:46 +000021 addr_.in.sin_port = htons(static_cast<uint16_t>(port));
22#ifndef __VXWORKS__
23 const int failure_return = 0;
24#else
25 const int failure_return = -1;
26#endif
Brian Silvermana9cbe302013-03-12 18:41:44 -070027 if (inet_aton(lame_unconst(address), &addr_.in.sin_addr) == failure_return) {
28 LOG(ERROR, "Invalid IP address '%s' because of %d: %s\n", address,
brians343bc112013-02-10 01:53:46 +000029 errno, strerror(errno));
30 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 }
70 LOG(FATAL, "select(FD_SETSIZE, %p, NULL, NULL, %p) failed with %d: %s\n",
71 &fds, &timeout_timeval, errno, strerror(errno));
72 }
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_,
brians343bc112013-02-10 01:53:46 +000077 lame_unconst(static_cast<const char *>(buf)), length);
brians343bc112013-02-10 01:53:46 +000078 last_ret_ = (ret == -1) ? -1 : 0;
79 return ret;
80}
81
Brian Silvermana9cbe302013-03-12 18:41:44 -070082} // namespace aos