15.04.2014 - Version 0.3.8_beta, last version of 0.3.8 branch. Too much added and fixed...
This commit is contained in:
137
piethernet.cpp
137
piethernet.cpp
@@ -53,7 +53,7 @@ PIEthernet::PIEthernet(): PIIODevice("", ReadWrite) {
|
||||
ip_ = ip_s = "";
|
||||
port_ = port_s = 0;
|
||||
sock = sock_s = -1;
|
||||
connected_ = false;
|
||||
connected_ = connecting_ = false;
|
||||
params = PIEthernet::ReuseAddress;
|
||||
server_thread_.setData(this);
|
||||
setThreadedReadBufferSize(65536);
|
||||
@@ -69,7 +69,7 @@ PIEthernet::PIEthernet(PIEthernet::Type type, const PIString & ip_port, const PI
|
||||
ip_s = "";
|
||||
port_s = 0;
|
||||
sock = sock_s = -1;
|
||||
connected_ = false;
|
||||
connected_ = connecting_ = false;
|
||||
params = params_;
|
||||
server_thread_.setData(this);
|
||||
setThreadedReadBufferSize(65536);
|
||||
@@ -88,6 +88,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
server_thread_.setData(this);
|
||||
params = PIEthernet::ReuseAddress;
|
||||
init_ = opened_ = connected_ = true;
|
||||
connecting_ = false;
|
||||
setThreadedReadBufferSize(65536);
|
||||
}
|
||||
|
||||
@@ -133,6 +134,11 @@ bool PIEthernet::init() {
|
||||
return false;
|
||||
}
|
||||
#ifndef WINDOWS
|
||||
timeval to;
|
||||
to.tv_sec = 10;
|
||||
to.tv_usec = 0;
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to));
|
||||
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &to, sizeof(to));
|
||||
if (params[PIEthernet::ReuseAddress]) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so));
|
||||
if (params[PIEthernet::Broadcast]) setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &so, sizeof(so));
|
||||
#else
|
||||
@@ -300,7 +306,9 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
||||
|
||||
|
||||
bool PIEthernet::connect() {
|
||||
if (sock == -1) return false;
|
||||
connecting_ = true;
|
||||
return true;
|
||||
/*if (sock == -1) return false;
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
addr_.sin_port = htons(port_);
|
||||
@@ -315,7 +323,7 @@ bool PIEthernet::connect() {
|
||||
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||
opened_ = connected_;
|
||||
if (connected_) connected();
|
||||
return connected_;
|
||||
return connected_;*/
|
||||
}
|
||||
|
||||
|
||||
@@ -330,6 +338,7 @@ bool PIEthernet::listen() {
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
opened_ = false;
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr * )&addr_, sizeof(addr_)) == -1) && (tries < 10)) {
|
||||
init();
|
||||
@@ -343,6 +352,7 @@ bool PIEthernet::listen() {
|
||||
piCoutObj << "Can`t listen on "<< ip_ << ":" << port_ << ", " << ethErrorString();
|
||||
return false;
|
||||
}
|
||||
opened_ = true;
|
||||
//piCoutObj << "listen on " << ip_ << ":" << port_;
|
||||
server_thread_.start(server_func);
|
||||
return true;
|
||||
@@ -353,7 +363,7 @@ int PIEthernet::read(void * read_to, int max_size) {
|
||||
//cout << "read " << sock << endl;
|
||||
if (sock == -1) init();
|
||||
if (sock == -1 || read_to == 0) return -1;
|
||||
int rs = 0, s = 0;
|
||||
int rs = 0, s = 0, lerr = 0;
|
||||
sockaddr_in client_addr;
|
||||
socklen_t slen = sizeof(client_addr);
|
||||
//piCoutObj << "read from " << ip_ << ":" << port_ << endl;
|
||||
@@ -370,7 +380,51 @@ int PIEthernet::read(void * read_to, int max_size) {
|
||||
closeSocket(s);
|
||||
return rs;
|
||||
case TCP_Client:
|
||||
if (connecting_) {
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
//piCoutObj << "connect to " << ip << ":" << port_;
|
||||
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
||||
if (!connected_)
|
||||
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||
opened_ = connected_;
|
||||
if (connected_) {
|
||||
connecting_ = false;
|
||||
connected();
|
||||
}
|
||||
}
|
||||
if (!connected_) return -1;
|
||||
#ifdef WINDOWS
|
||||
rs = recv(sock, (char * )read_to, max_size, 0);
|
||||
#else
|
||||
rs = recv(sock, read_to, max_size, MSG_DONTWAIT);
|
||||
#endif
|
||||
if (rs <= 0) {
|
||||
#ifdef WINDOWS
|
||||
lerr = WSAGetLastError();
|
||||
if (lerr == WSAEWOULDBLOCK) {
|
||||
piMSleep(1);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
lerr = errno;
|
||||
if (lerr == EAGAIN || lerr == EWOULDBLOCK) {
|
||||
piMSleep(1);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (connected_) disconnected(rs < 0);
|
||||
connected_ = false;
|
||||
//piCoutObj << "eth" << path_ << "disconnected";
|
||||
}
|
||||
if (rs > 0) received(read_to, rs);
|
||||
return rs;
|
||||
case UDP:
|
||||
#ifdef WINDOWS
|
||||
rs = recv(sock, (char * )read_to, max_size, 0);
|
||||
@@ -378,11 +432,6 @@ int PIEthernet::read(void * read_to, int max_size) {
|
||||
rs = recv(sock, read_to, max_size, 0);
|
||||
#endif
|
||||
//piCout << "eth" << path_ << "read return" << rs << errno;
|
||||
if (rs <= 0 && type_ == TCP_Client) {
|
||||
connected_ = false;
|
||||
if (connected_) disconnected(rs < 0);
|
||||
//piCoutObj << "eth" << path_ << "disconnected";
|
||||
}
|
||||
if (rs > 0) received(read_to, rs);
|
||||
return rs;
|
||||
//return ::read(sock, read_to, max_size);
|
||||
@@ -435,6 +484,26 @@ int PIEthernet::write(const void * data, int max_size) {
|
||||
#endif
|
||||
//piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
||||
case TCP_Client:
|
||||
if (connecting_) {
|
||||
memset(&addr_, 0, sizeof(addr_));
|
||||
parseAddress(path_, &ip_, &port_);
|
||||
addr_.sin_port = htons(port_);
|
||||
addr_.sin_addr.s_addr = inet_addr(ip_.data());
|
||||
addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
addr_.sin_len = sizeof(addr_);
|
||||
#endif
|
||||
//piCoutObj << "connect to " << ip << ":" << port_;
|
||||
connected_ = (::connect(sock, (sockaddr * )&addr_, sizeof(addr_)) == 0);
|
||||
if (!connected_)
|
||||
piCoutObj << "Can`t connect to " << ip_ << ":" << port_ << ", " << ethErrorString();
|
||||
opened_ = connected_;
|
||||
if (connected_) {
|
||||
connecting_ = false;
|
||||
connected();
|
||||
}
|
||||
}
|
||||
if (!connected_) return -1;
|
||||
return ::send(sock, (const char *)data, max_size, 0);
|
||||
default: break;
|
||||
//return ::read(sock, read_to, max_size);
|
||||
@@ -475,9 +544,9 @@ bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) {
|
||||
|
||||
|
||||
PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
#ifdef WINDOWS
|
||||
PIEthernet::InterfaceList il;
|
||||
Interface ci;
|
||||
#ifdef WINDOWS
|
||||
PIP_ADAPTER_INFO pAdapterInfo, pAdapter = 0;
|
||||
int ret = 0;
|
||||
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
@@ -524,7 +593,6 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error: " << ret;
|
||||
if (pAdapterInfo)
|
||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||
return il;
|
||||
#else
|
||||
/*# ifdef QNX
|
||||
PIStringList il, sl;
|
||||
@@ -560,8 +628,34 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
return sl;
|
||||
# endif*/
|
||||
PIEthernet::InterfaceList il;
|
||||
Interface ci;
|
||||
# ifdef ANDROID
|
||||
struct ifconf ifc;
|
||||
int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
ifc.ifc_len = 256;
|
||||
ifc.ifc_buf = new char[ifc.ifc_len];
|
||||
if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
|
||||
piCout << "[PIEthernet] Can`t get interfaces:" << errorString();
|
||||
delete ifc.ifc_buf;
|
||||
return il;
|
||||
}
|
||||
int icnt = ifc.ifc_len / sizeof(ifreq);
|
||||
PIStringList inl;
|
||||
struct ifreq ir;
|
||||
for (int i = 0; i < icnt; ++i) {
|
||||
PIString in(ifc.ifc_req[i].ifr_name);
|
||||
if (in.isEmpty()) continue;
|
||||
ci.name = in;
|
||||
strcpy(ir.ifr_name, in.data());
|
||||
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0)
|
||||
ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
||||
if (ioctl(s, SIOCGIFADDR, &ir) >= 0)
|
||||
ci.address = getSockAddr(&ir.ifr_addr);
|
||||
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0)
|
||||
ci.netmask = getSockAddr(&ir.ifr_addr);
|
||||
il << ci;
|
||||
}
|
||||
delete ifc.ifc_buf;
|
||||
# else
|
||||
struct ifaddrs * ret;
|
||||
int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (getifaddrs(&ret) == 0) {
|
||||
@@ -574,7 +668,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
ci.address = getSockAddr(ret->ifa_addr);
|
||||
ci.netmask = getSockAddr(ret->ifa_netmask);
|
||||
ci.mac.clear();
|
||||
#ifdef QNX
|
||||
# ifdef QNX
|
||||
int fd = ::open((PIString("/dev/io-net/") + ci.name).data(), O_RDONLY);
|
||||
if (fd != 0) {
|
||||
nic_config_t nic;
|
||||
@@ -582,8 +676,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
::close(fd);
|
||||
ci.mac = macFromBytes(PIByteArray(nic.permanent_address, 6));
|
||||
}
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
# else
|
||||
# ifdef MAC_OS
|
||||
PIString req = PIString(ifconfigPath) + " " + ci.name + " | grep ether";
|
||||
FILE * fp = popen(req.data(), "r");
|
||||
if (fp != 0) {
|
||||
@@ -594,15 +688,15 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
# else
|
||||
# else
|
||||
if (s != -1) {
|
||||
struct ifreq ir;
|
||||
strcpy(ir.ifr_name, ret->ifa_name);
|
||||
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0)
|
||||
ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
# endif
|
||||
# endif
|
||||
ci.flags = 0;
|
||||
if (ret->ifa_flags & IFF_UP) ci.flags |= PIEthernet::ifActive;
|
||||
if (ret->ifa_flags & IFF_RUNNING) ci.flags |= PIEthernet::ifRunning;
|
||||
@@ -624,8 +718,9 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
} else
|
||||
piCout << "[PIEthernet] Can`t get interfaces:" << errorString();
|
||||
if (s != -1) ::close(s);
|
||||
return il;
|
||||
# endif
|
||||
#endif
|
||||
return il;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user