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:
peri4
2014-04-15 13:19:07 +04:00
parent f50891b376
commit 77abb0bbea
46 changed files with 4538 additions and 2515 deletions

View File

@@ -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;
}