code format
This commit is contained in:
@@ -1,46 +1,48 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP/TCP Broadcast/Multicast
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Ethernet, UDP/TCP Broadcast/Multicast
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "piincludes_p.h"
|
||||
#include "piethernet.h"
|
||||
|
||||
#include "piconfig.h"
|
||||
#include "pisysteminfo.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "piconstchars.h"
|
||||
#include "piincludes_p.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "pisysteminfo.h"
|
||||
// clang-format off
|
||||
#ifdef QNX
|
||||
# include <arpa/inet.h>
|
||||
# include <fcntl.h>
|
||||
# include <hw/nicinfo.h>
|
||||
# include <ifaddrs.h>
|
||||
# include <net/if.h>
|
||||
# include <net/if_dl.h>
|
||||
# include <hw/nicinfo.h>
|
||||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <ifaddrs.h>
|
||||
# include <fcntl.h>
|
||||
# ifdef BLACKBERRY
|
||||
# include <netinet/in.h>
|
||||
# include <netinet/in.h>
|
||||
# else
|
||||
# include <sys/dcmd_io-net.h>
|
||||
# include <sys/dcmd_io-net.h>
|
||||
# endif
|
||||
# define ip_mreqn ip_mreq
|
||||
# define ip_mreqn ip_mreq
|
||||
# define imr_address imr_interface
|
||||
#else
|
||||
# ifdef WINDOWS
|
||||
@@ -67,7 +69,9 @@
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
// clang-format on
|
||||
#include "piwaitevent_p.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
@@ -81,21 +85,21 @@
|
||||
* UDP and TCP. This class allow you send and receive packets to/from
|
||||
* another computer through network. Also it supports broadcast and
|
||||
* multicast extensions.
|
||||
*
|
||||
*
|
||||
* \section PIEthernet_sec1 IPv4
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* \section PIEthernet_sec2 UDP
|
||||
* User Datagram Protocol
|
||||
*
|
||||
*
|
||||
* \section PIEthernet_sec3 TCP
|
||||
* Transmission Control Protocol
|
||||
*
|
||||
*
|
||||
* */
|
||||
|
||||
#ifndef WINDOWS
|
||||
PIString getSockAddr(sockaddr * s) {
|
||||
return s == 0 ? PIString() : PIStringAscii(inet_ntoa(((sockaddr_in*)s)->sin_addr));
|
||||
return s == 0 ? PIString() : PIStringAscii(inet_ntoa(((sockaddr_in *)s)->sin_addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -145,7 +149,8 @@ void PIEthernet::Address::setPort(ushort _port) {
|
||||
|
||||
|
||||
void PIEthernet::Address::set(const PIString & ip_port) {
|
||||
PIString _ip; int p(0);
|
||||
PIString _ip;
|
||||
int p(0);
|
||||
splitIPPort(ip_port, &_ip, &p);
|
||||
port_ = p;
|
||||
initIP(_ip);
|
||||
@@ -159,13 +164,13 @@ void PIEthernet::Address::set(const PIString & _ip, ushort _port) {
|
||||
|
||||
|
||||
void PIEthernet::Address::set(uint _ip, ushort _port) {
|
||||
ip_ = _ip;
|
||||
ip_ = _ip;
|
||||
port_ = _port;
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::Address::clear() {
|
||||
ip_ = 0;
|
||||
ip_ = 0;
|
||||
port_ = 0;
|
||||
}
|
||||
|
||||
@@ -176,7 +181,8 @@ bool PIEthernet::Address::isNull() const {
|
||||
|
||||
|
||||
PIEthernet::Address PIEthernet::Address::resolve(const PIString & host_port) {
|
||||
PIString host; int port(0);
|
||||
PIString host;
|
||||
int port(0);
|
||||
splitIPPort(host_port, &host, &port);
|
||||
return resolve(host, port);
|
||||
}
|
||||
@@ -185,16 +191,14 @@ PIEthernet::Address PIEthernet::Address::resolve(const PIString & host_port) {
|
||||
PIEthernet::Address PIEthernet::Address::resolve(const PIString & host, ushort port) {
|
||||
Address ret(0, port);
|
||||
hostent * he = gethostbyname(host.dataAscii());
|
||||
if (!he)
|
||||
return ret;
|
||||
if (he->h_addr_list[0])
|
||||
ret.setIP(*((uint*)(he->h_addr_list[0])));
|
||||
if (!he) return ret;
|
||||
if (he->h_addr_list[0]) ret.setIP(*((uint *)(he->h_addr_list[0])));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::Address::splitIPPort(const PIString & ipp, PIString * _ip, int * _port) {
|
||||
//piCout << "parse" << ipp;
|
||||
// piCout << "parse" << ipp;
|
||||
int sp = ipp.findLast(":");
|
||||
if (_ip != 0) *_ip = (sp >= 0 ? ipp.left(sp) : ipp);
|
||||
if (_port != 0 && sp >= 0) *_port = ipp.right(ipp.length() - ipp.find(":") - 1).toInt();
|
||||
@@ -224,7 +228,8 @@ PIEthernet::PIEthernet(): PIIODevice("", ReadWrite) {
|
||||
}
|
||||
|
||||
|
||||
PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const PIFlags<PIEthernet::Parameters> params_): PIIODevice(ip_port, ReadWrite) {
|
||||
PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const PIFlags<PIEthernet::Parameters> params_)
|
||||
: PIIODevice(ip_port, ReadWrite) {
|
||||
construct();
|
||||
addr_r.set(ip_port);
|
||||
setType(type_);
|
||||
@@ -236,7 +241,7 @@ PIEthernet::PIEthernet(PIEthernet::Type type_, const PIString & ip_port, const P
|
||||
PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
construct();
|
||||
addr_s.set(ip_port);
|
||||
sock = sock_;
|
||||
sock = sock_;
|
||||
opened_ = connected_ = true;
|
||||
init();
|
||||
setParameters(PIEthernet::ReuseAddress | PIEthernet::MulticastLoop);
|
||||
@@ -244,21 +249,21 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
|
||||
setPath(ip_port);
|
||||
ethNonblocking(sock);
|
||||
PRIVATE->event.create();
|
||||
//piCoutObj << "new tcp client" << sock_;
|
||||
// piCoutObj << "new tcp client" << sock_;
|
||||
}
|
||||
|
||||
|
||||
PIEthernet::~PIEthernet() {
|
||||
//piCout << "~PIEthernet";
|
||||
// piCout << "~PIEthernet";
|
||||
stopAndWait();
|
||||
close();
|
||||
PRIVATE->event.destroy();
|
||||
//piCout << "~PIEthernet done";
|
||||
// piCout << "~PIEthernet done";
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::construct() {
|
||||
//piCout << " PIEthernet" << uint(this);
|
||||
// piCout << " PIEthernet" << uint(this);
|
||||
setOption(BlockingWrite);
|
||||
connected_ = connecting_ = listen_threaded = server_bounded = false;
|
||||
sock = sock_s = -1;
|
||||
@@ -273,17 +278,16 @@ void PIEthernet::construct() {
|
||||
#else
|
||||
setThreadedReadBufferSize(65536);
|
||||
#endif
|
||||
//setPriority(piHigh);
|
||||
// setPriority(piHigh);
|
||||
}
|
||||
|
||||
|
||||
bool PIEthernet::init() {
|
||||
if (isOpened()) return true;
|
||||
if (sock != -1) return true;
|
||||
//piCout << "init " << type();
|
||||
// piCout << "init " << type();
|
||||
PRIVATE->event.destroy();
|
||||
if (sock_s == sock)
|
||||
sock_s = -1;
|
||||
if (sock_s == sock) sock_s = -1;
|
||||
closeSocket(sock);
|
||||
closeSocket(sock_s);
|
||||
int st = 0, pr = 0;
|
||||
@@ -309,7 +313,7 @@ bool PIEthernet::init() {
|
||||
if (params[PIEthernet::Broadcast]) ethSetsockoptBool(sock, SOL_SOCKET, SO_BROADCAST);
|
||||
applyTimeouts();
|
||||
applyOptInt(IPPROTO_IP, IP_TTL, TTL());
|
||||
//piCoutObj << "inited" << path();
|
||||
// piCoutObj << "inited" << path();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -324,10 +328,10 @@ PIString PIEthernet::macFromBytes(const PIByteArray & mac) {
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PIEthernet::macToBytes(const PIString & mac) {
|
||||
PIByteArray PIEthernet::macToBytes(const PIString & mac) {
|
||||
PIByteArray r;
|
||||
PIStringList sl = mac.split(PIStringAscii(":"));
|
||||
piForeachC (PIString & i, sl)
|
||||
piForeachC(PIString & i, sl)
|
||||
r << uchar(i.toInt(16));
|
||||
return r;
|
||||
}
|
||||
@@ -363,25 +367,26 @@ PIEthernet::Address PIEthernet::getBroadcast(const PIEthernet::Address & ip, con
|
||||
|
||||
bool PIEthernet::openDevice() {
|
||||
if (connected_) return true;
|
||||
//piCoutObj << "open";
|
||||
// piCoutObj << "open";
|
||||
init();
|
||||
if (sock == -1 || path().isEmpty()) return false;
|
||||
addr_r.set(path());
|
||||
//if (type() == TCP_Client)
|
||||
// if (type() == TCP_Client)
|
||||
// connecting_ = true;
|
||||
if (type() != UDP || mode() == PIIODevice::WriteOnly)
|
||||
return true;
|
||||
if (type() != UDP || mode() == PIIODevice::WriteOnly) return true;
|
||||
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
if (params[PIEthernet::Broadcast]) PRIVATE->addr_.sin_addr.s_addr = INADDR_ANY;
|
||||
else PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
if (params[PIEthernet::Broadcast])
|
||||
PRIVATE->addr_.sin_addr.s_addr = INADDR_ANY;
|
||||
else
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
#ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
//piCout << "bind to" << (params[PIEthernet::Broadcast] ? "255.255.255.255" : ip_) << ":" << port_ << " ...";
|
||||
// piCout << "bind to" << (params[PIEthernet::Broadcast] ? "255.255.255.255" : ip_) << ":" << port_ << " ...";
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) {
|
||||
while ((bind(sock, (sockaddr *)&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) {
|
||||
init();
|
||||
tries++;
|
||||
}
|
||||
@@ -400,24 +405,22 @@ bool PIEthernet::openDevice() {
|
||||
|
||||
|
||||
bool PIEthernet::closeDevice() {
|
||||
//piCoutObj << "close";
|
||||
bool ned = connected_;
|
||||
// piCoutObj << "close";
|
||||
bool ned = connected_;
|
||||
connected_ = connecting_ = false;
|
||||
server_thread_.stop();
|
||||
PRIVATE->event.interrupt();
|
||||
if (server_thread_.isRunning()) {
|
||||
if (!server_thread_.waitForFinish(1000))
|
||||
server_thread_.terminate();
|
||||
if (!server_thread_.waitForFinish(1000)) server_thread_.terminate();
|
||||
}
|
||||
PRIVATE->event.destroy();
|
||||
if (sock_s == sock)
|
||||
sock_s = -1;
|
||||
if (sock_s == sock) sock_s = -1;
|
||||
closeSocket(sock);
|
||||
closeSocket(sock_s);
|
||||
while (!clients_.isEmpty())
|
||||
delete clients_.back();
|
||||
if (ned) {
|
||||
//piCoutObj << "Disconnect on close";
|
||||
// piCoutObj << "Disconnect on close";
|
||||
disconnected(false);
|
||||
}
|
||||
return true;
|
||||
@@ -425,8 +428,7 @@ bool PIEthernet::closeDevice() {
|
||||
|
||||
|
||||
void PIEthernet::closeSocket(int & sd) {
|
||||
if (sd != -1)
|
||||
ethClosesocket(sd, type() != PIEthernet::UDP);
|
||||
if (sd != -1) ethClosesocket(sd, type() != PIEthernet::UDP);
|
||||
sd = -1;
|
||||
}
|
||||
|
||||
@@ -445,13 +447,14 @@ void PIEthernet::applyTimeouts() {
|
||||
|
||||
void PIEthernet::applyTimeout(int fd, int opt, double ms) {
|
||||
if (fd == 0) return;
|
||||
//piCoutObj << "setReadIsBlocking" << yes;
|
||||
// piCoutObj << "setReadIsBlocking" << yes;
|
||||
#ifdef WINDOWS
|
||||
DWORD _tm = ms;
|
||||
#else
|
||||
double s = ms / 1000.;
|
||||
timeval _tm;
|
||||
_tm.tv_sec = piFloord(s); s -= _tm.tv_sec;
|
||||
_tm.tv_sec = piFloord(s);
|
||||
s -= _tm.tv_sec;
|
||||
_tm.tv_usec = s * 1000000.;
|
||||
#endif
|
||||
ethSetsockopt(fd, SOL_SOCKET, opt, &_tm, sizeof(_tm));
|
||||
@@ -461,8 +464,7 @@ void PIEthernet::applyTimeout(int fd, int opt, double ms) {
|
||||
void PIEthernet::applyOptInt(int level, int opt, int val) {
|
||||
if (sock < 0) return;
|
||||
ethSetsockoptInt(sock, level, opt, val);
|
||||
if (sock_s != sock && sock_s != -1)
|
||||
ethSetsockoptInt(sock_s, level, opt, val);
|
||||
if (sock_s != sock && sock_s != -1) ethSetsockoptInt(sock_s, level, opt, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -474,8 +476,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
return false;
|
||||
}
|
||||
if (isClosed()) {
|
||||
if (mcast_queue.contains(group))
|
||||
return false;
|
||||
if (mcast_queue.contains(group)) return false;
|
||||
mcast_queue.enqueue(group);
|
||||
if (!mcast_groups.contains(group)) mcast_groups << group;
|
||||
return true;
|
||||
@@ -488,7 +489,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
#endif
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
#ifdef LINUX
|
||||
//mreq.imr_address.s_addr = INADDR_ANY;
|
||||
// mreq.imr_address.s_addr = INADDR_ANY;
|
||||
/*PIEthernet::InterfaceList il = interfaces();
|
||||
const PIEthernet::Interface * ci = il.getByAddress(addr_r.ipString());
|
||||
if (ci != 0) mreq.imr_ifindex = ci->index;*/
|
||||
@@ -499,14 +500,14 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
||||
#else
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
else
|
||||
else
|
||||
#ifndef LWIP
|
||||
mreq.imr_address.s_addr = addr_r.ip();
|
||||
#else
|
||||
mreq.imr_interface.s_addr = addr_r.ip();
|
||||
#endif
|
||||
|
||||
//piCout << "join group" << group << "ip" << ip_ << "with index" << mreq.imr_ifindex << "socket" << sock;
|
||||
// piCout << "join group" << group << "ip" << ip_ << "with index" << mreq.imr_ifindex << "socket" << sock;
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(group.dataAscii());
|
||||
if (ethSetsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != 0) {
|
||||
piCoutObj << "Can`t join multicast group" << group << "," << ethErrorString();
|
||||
@@ -539,7 +540,7 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
||||
#else
|
||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
else
|
||||
else
|
||||
#ifndef LWIP
|
||||
mreq.imr_address.s_addr = addr_r.ip();
|
||||
#else
|
||||
@@ -565,14 +566,14 @@ bool PIEthernet::connect(bool threaded) {
|
||||
if (sock == -1) return false;
|
||||
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
|
||||
addr_r.set(path());
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
connecting_ = true;
|
||||
connected_ = connectTCP();
|
||||
connected_ = connectTCP();
|
||||
connecting_ = false;
|
||||
if (!connected_) {
|
||||
piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
@@ -592,26 +593,25 @@ bool PIEthernet::listen(bool threaded) {
|
||||
if (server_thread_.isRunning()) {
|
||||
if (!server_bounded) return true;
|
||||
server_thread_.stop();
|
||||
if (!server_thread_.waitForFinish(100))
|
||||
server_thread_.terminate();
|
||||
if (!server_thread_.waitForFinish(100)) server_thread_.terminate();
|
||||
}
|
||||
listen_threaded = true;
|
||||
server_bounded = false;
|
||||
server_bounded = false;
|
||||
server_thread_.start(server_func);
|
||||
return true;
|
||||
}
|
||||
listen_threaded = server_bounded = false;
|
||||
addr_r.set(path());
|
||||
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
opened_ = false;
|
||||
opened_ = false;
|
||||
int tries = 0;
|
||||
while ((bind(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) {
|
||||
while ((bind(sock, (sockaddr *)&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) {
|
||||
init();
|
||||
tries++;
|
||||
}
|
||||
@@ -620,7 +620,7 @@ bool PIEthernet::listen(bool threaded) {
|
||||
return false;
|
||||
}
|
||||
if (::listen(sock, 64) == -1) {
|
||||
piCoutObj << "Can`t listen on"<< addr_r << "," << ethErrorString();
|
||||
piCoutObj << "Can`t listen on" << addr_r << "," << ethErrorString();
|
||||
return false;
|
||||
}
|
||||
opened_ = server_bounded = true;
|
||||
@@ -652,9 +652,9 @@ bool PIEthernet::send(const PIEthernet::Address & addr, const void * data, int s
|
||||
return true;
|
||||
}
|
||||
Address pa = addr_s;
|
||||
addr_s = addr;
|
||||
int wr = write(data, size);
|
||||
addr_s = pa;
|
||||
addr_s = addr;
|
||||
int wr = write(data, size);
|
||||
addr_s = pa;
|
||||
return (wr == size);
|
||||
}
|
||||
|
||||
@@ -674,66 +674,65 @@ bool PIEthernet::send(const PIEthernet::Address & addr, const PIByteArray & data
|
||||
return true;
|
||||
}
|
||||
Address pa = addr_s;
|
||||
addr_s = addr;
|
||||
int wr = write(data);
|
||||
addr_s = pa;
|
||||
addr_s = addr;
|
||||
int wr = write(data);
|
||||
addr_s = pa;
|
||||
return (wr == data.size_s());
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::interrupt() {
|
||||
//piCout << "interrupt";
|
||||
// piCout << "interrupt";
|
||||
PRIVATE->event.interrupt();
|
||||
}
|
||||
|
||||
|
||||
ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
//piCout << "read" << sock;
|
||||
// piCout << "read" << sock;
|
||||
if (sock == -1) init();
|
||||
if (sock == -1 || read_to == 0) return -1;
|
||||
int rs = 0, lerr = 0;
|
||||
//piCoutObj << "read from " << path() << connecting_;
|
||||
// piCoutObj << "read from " << path() << connecting_;
|
||||
switch (type()) {
|
||||
case TCP_Client:
|
||||
if (connecting_) {
|
||||
addr_r.set(path());
|
||||
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
//piCoutObj << "connect to " << path() << "...";
|
||||
// piCoutObj << "connect to " << path() << "...";
|
||||
connected_ = connectTCP();
|
||||
//piCoutObj << "connect to " << path() << connected_;
|
||||
if (!connected_)
|
||||
piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
// piCoutObj << "connect to " << path() << connected_;
|
||||
if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
opened_.exchange(connected_);
|
||||
if (connected_) {
|
||||
connecting_ = false;
|
||||
connected();
|
||||
} else
|
||||
piMSleep(10);
|
||||
//piCout << "connected to" << path();
|
||||
// piCout << "connected to" << path();
|
||||
}
|
||||
if (!connected_) return -1;
|
||||
errorClear();
|
||||
#ifdef WINDOWS
|
||||
{
|
||||
long wr = waitForEvent(PRIVATE->event, FD_READ | FD_CLOSE);
|
||||
switch (wr) {
|
||||
case 0: return -1;
|
||||
case FD_READ:
|
||||
//piCout << "fd_read ...";
|
||||
rs = ethRecv(sock, read_to, max_size);
|
||||
break;
|
||||
case FD_CLOSE:
|
||||
//piCout << "fd_close ...";
|
||||
rs = -1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
long wr = waitForEvent(PRIVATE->event, FD_READ | FD_CLOSE);
|
||||
switch (wr) {
|
||||
case 0: return -1;
|
||||
case FD_READ:
|
||||
// piCout << "fd_read ...";
|
||||
rs = ethRecv(sock, read_to, max_size);
|
||||
break;
|
||||
case FD_CLOSE:
|
||||
// piCout << "fd_close ...";
|
||||
rs = -1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (PRIVATE->event.wait(sock)) {
|
||||
@@ -741,10 +740,10 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
rs = ethRecv(sock, read_to, max_size);
|
||||
}
|
||||
#endif
|
||||
//piCoutObj << "readed" << rs;
|
||||
// piCoutObj << "readed" << rs;
|
||||
if (rs <= 0) {
|
||||
lerr = ethErrorCore();
|
||||
//piCoutObj << "readed" << rs << "error" << lerr;
|
||||
// piCoutObj << "readed" << rs << "error" << lerr;
|
||||
|
||||
// async normal returns
|
||||
#ifdef WINDOWS
|
||||
@@ -752,7 +751,7 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
#else
|
||||
if (lerr == EWOULDBLOCK || lerr == EAGAIN || lerr == EINTR) {
|
||||
#endif
|
||||
//piCoutObj << "Ignore would_block" << lerr;
|
||||
// piCoutObj << "Ignore would_block" << lerr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -763,15 +762,15 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
#else
|
||||
if (lerr == ETIMEDOUT) {
|
||||
#endif
|
||||
//piCoutObj << "Ignore read timeout";
|
||||
// piCoutObj << "Ignore read timeout";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// disconnect here
|
||||
//piCoutObj << "Disconnnected, check for event, connected =" << connected_;
|
||||
// piCoutObj << "Disconnnected, check for event, connected =" << connected_;
|
||||
if (connected_.exchange(false)) {
|
||||
opened_ = false;
|
||||
//piCoutObj << "Disconnect on read," << ethErrorString();
|
||||
// piCoutObj << "Disconnect on read," << ethErrorString();
|
||||
closeSocket(sock);
|
||||
init();
|
||||
disconnected(rs < 0);
|
||||
@@ -779,38 +778,38 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
if (params[KeepConnection]) {
|
||||
connect();
|
||||
}
|
||||
//piCoutObj << "eth" << ip_ << "disconnected";
|
||||
// piCoutObj << "eth" << ip_ << "disconnected";
|
||||
}
|
||||
if (rs > 0) received(read_to, rs);
|
||||
return rs;
|
||||
case UDP: {
|
||||
memset(&PRIVATE->raddr_, 0, sizeof(PRIVATE->raddr_));
|
||||
//piCoutObj << "read from" << path() << "...";
|
||||
// piCoutObj << "read from" << path() << "...";
|
||||
#ifdef WINDOWS
|
||||
long wr = waitForEvent(PRIVATE->event, FD_READ | FD_CLOSE);
|
||||
switch (wr) {
|
||||
case FD_READ:
|
||||
//piCout << "fd_read ...";
|
||||
rs = ethRecvfrom(sock, read_to, max_size, 0, (sockaddr*)&PRIVATE->raddr_);
|
||||
// piCout << "fd_read ...";
|
||||
rs = ethRecvfrom(sock, read_to, max_size, 0, (sockaddr *)&PRIVATE->raddr_);
|
||||
break;
|
||||
case FD_CLOSE:
|
||||
//piCout << "fd_close ...";
|
||||
// piCout << "fd_close ...";
|
||||
rs = -1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
#else
|
||||
rs = ethRecvfrom(sock, read_to, max_size, 0, (sockaddr*)&PRIVATE->raddr_);
|
||||
rs = ethRecvfrom(sock, read_to, max_size, 0, (sockaddr *)&PRIVATE->raddr_);
|
||||
#endif
|
||||
//piCoutObj << "read from" << path() << rs << "bytes";
|
||||
// piCoutObj << "read from" << path() << rs << "bytes";
|
||||
if (rs > 0) {
|
||||
addr_lr.set(uint(PRIVATE->raddr_.sin_addr.s_addr), ntohs(PRIVATE->raddr_.sin_port));
|
||||
//piCoutObj << "read from" << ip_r << ":" << port_r << rs << "bytes";
|
||||
// piCoutObj << "read from" << ip_r << ":" << port_r << rs << "bytes";
|
||||
received(read_to, rs);
|
||||
}
|
||||
//else piCoutObj << "read returt" << rs << ", error" << ethErrorString();
|
||||
// else piCoutObj << "read returt" << rs << ", error" << ethErrorString();
|
||||
return rs;
|
||||
}
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return -1;
|
||||
@@ -820,39 +819,42 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) {
|
||||
ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
if (sock == -1) init();
|
||||
if (sock == -1 || !isWriteable()) {
|
||||
//piCoutObj << "Can`t send to uninitialized socket";
|
||||
// piCoutObj << "Can`t send to uninitialized socket";
|
||||
return -1;
|
||||
}
|
||||
//piCoutObj << "sending to " << ip_s << ":" << port_s << " " << max_size << " bytes";
|
||||
// piCoutObj << "sending to " << ip_s << ":" << port_s << " " << max_size << " bytes";
|
||||
int ret = 0;
|
||||
switch (type()) {
|
||||
case UDP:
|
||||
PRIVATE->saddr_.sin_port = htons(addr_s.port());
|
||||
PRIVATE->saddr_.sin_port = htons(addr_s.port());
|
||||
PRIVATE->saddr_.sin_addr.s_addr = addr_s.ip();
|
||||
PRIVATE->saddr_.sin_family = AF_INET;
|
||||
//piCoutObj << "write to" << ip_s << ":" << port_s << "socket" << sock_s << max_size << "bytes ...";
|
||||
return ethSendto(sock_s, data, max_size,
|
||||
PRIVATE->saddr_.sin_family = AF_INET;
|
||||
// piCoutObj << "write to" << ip_s << ":" << port_s << "socket" << sock_s << max_size << "bytes ...";
|
||||
return ethSendto(sock_s,
|
||||
data,
|
||||
max_size,
|
||||
#ifndef WINDOWS
|
||||
isOptionSet(BlockingWrite) ? 0 : MSG_DONTWAIT
|
||||
isOptionSet(BlockingWrite) ? 0 : MSG_DONTWAIT
|
||||
#else
|
||||
0
|
||||
0
|
||||
#endif
|
||||
, (sockaddr * )&PRIVATE->saddr_, sizeof(PRIVATE->saddr_));
|
||||
//piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
||||
,
|
||||
(sockaddr *)&PRIVATE->saddr_,
|
||||
sizeof(PRIVATE->saddr_));
|
||||
// piCout << "[PIEth] write to" << ip_s << ":" << port_s << "ok";
|
||||
case TCP_Client: {
|
||||
if (connecting_) {
|
||||
memset(&PRIVATE->addr_, 0, sizeof(PRIVATE->addr_));
|
||||
addr_r.set(path());
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_port = htons(addr_r.port());
|
||||
PRIVATE->addr_.sin_addr.s_addr = addr_r.ip();
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
PRIVATE->addr_.sin_family = AF_INET;
|
||||
#ifdef QNX
|
||||
PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_);
|
||||
#endif
|
||||
//piCoutObj << "connect to " << ip << ":" << port_;
|
||||
// piCoutObj << "connect to " << ip << ":" << port_;
|
||||
connected_ = connectTCP();
|
||||
if (!connected_)
|
||||
piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString();
|
||||
opened_.exchange(connected_);
|
||||
if (connected_) {
|
||||
connecting_ = false;
|
||||
@@ -860,10 +862,10 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
}
|
||||
}
|
||||
if (!connected_) return -1;
|
||||
auto disconnectFunc = [this](){
|
||||
auto disconnectFunc = [this]() {
|
||||
if (connected_.exchange(false)) {
|
||||
opened_ = false;
|
||||
//piCoutObj << "Disconnect on write," << ethErrorString();
|
||||
// piCoutObj << "Disconnect on write," << ethErrorString();
|
||||
closeSocket(sock);
|
||||
init();
|
||||
disconnected(true);
|
||||
@@ -876,7 +878,7 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
ssize_t remain_size = max_size;
|
||||
ssize_t remain_size = max_size;
|
||||
const char * remain_data = (const char *)data;
|
||||
while (remain_size > 0) {
|
||||
int sr = ::send(sock, remain_data, remain_size, 0);
|
||||
@@ -888,7 +890,7 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
if (err == EAGAIN || err == EWOULDBLOCK) {
|
||||
#endif
|
||||
piMinSleep();
|
||||
//piCoutObj << "wait for write";
|
||||
// piCoutObj << "wait for write";
|
||||
continue;
|
||||
} else {
|
||||
disconnectFunc();
|
||||
@@ -899,7 +901,8 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
|
||||
remain_size -= sr;
|
||||
}
|
||||
}
|
||||
return ret;}
|
||||
return ret;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
return -1;
|
||||
@@ -919,13 +922,13 @@ PIIODevice::DeviceInfoFlags PIEthernet::deviceInfoFlags() const {
|
||||
|
||||
void PIEthernet::clientDeleted(PIObject * o) {
|
||||
clients_mutex.lock();
|
||||
clients_.removeOne((PIEthernet*)o);
|
||||
clients_.removeOne((PIEthernet *)o);
|
||||
clients_mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::server_func(void * eth) {
|
||||
PIEthernet * ce = (PIEthernet * )eth;
|
||||
PIEthernet * ce = (PIEthernet *)eth;
|
||||
if (ce->listen_threaded) {
|
||||
if (!ce->server_bounded) {
|
||||
if (!ce->listen(false)) {
|
||||
@@ -949,9 +952,9 @@ void PIEthernet::server_func(void * eth) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//piCout << "server" << "accept ...";
|
||||
int s = accept(ce->sock, (sockaddr * )&client_addr, &slen);
|
||||
//piCout << "server" << "accept done" << ethErrorString();
|
||||
// piCout << "server" << "accept ...";
|
||||
int s = accept(ce->sock, (sockaddr *)&client_addr, &slen);
|
||||
// piCout << "server" << "accept done" << ethErrorString();
|
||||
if (s == -1) {
|
||||
int lerr = ethErrorCore();
|
||||
#ifdef WINDOWS
|
||||
@@ -976,7 +979,7 @@ void PIEthernet::server_func(void * eth) {
|
||||
ce->clients_ << e;
|
||||
ce->clients_mutex.unlock();
|
||||
ce->newConnection(e);
|
||||
//cout << "connected " << ip << endl;
|
||||
// cout << "connected " << ip << endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -992,19 +995,20 @@ void PIEthernet::setType(Type t, bool reopen) {
|
||||
|
||||
|
||||
bool PIEthernet::connectTCP() {
|
||||
::connect(sock, (sockaddr * )&(PRIVATE->addr_), sizeof(PRIVATE->addr_));
|
||||
//piCout << errorString();
|
||||
::connect(sock, (sockaddr *)&(PRIVATE->addr_), sizeof(PRIVATE->addr_));
|
||||
// piCout << errorString();
|
||||
#ifdef WINDOWS
|
||||
long wr = waitForEvent(PRIVATE->event, FD_CONNECT | FD_CLOSE);
|
||||
switch (wr) {
|
||||
case FD_CONNECT:
|
||||
//piCout << "fd_connect ...";
|
||||
// piCout << "fd_connect ...";
|
||||
return ethIsWriteable(sock);
|
||||
default: break;
|
||||
}
|
||||
#else
|
||||
if (PRIVATE->event.wait(sock, PIWaitEvent::CheckWrite)) {
|
||||
if (ethIsWriteable(sock)) return true;
|
||||
if (ethIsWriteable(sock))
|
||||
return true;
|
||||
else {
|
||||
closeSocket(sock);
|
||||
init();
|
||||
@@ -1019,16 +1023,15 @@ bool PIEthernet::connectTCP() {
|
||||
long PIEthernet::waitForEvent(PIWaitEvent & event, long mask) {
|
||||
if (!event.isCreate() || sock < 0) return 0;
|
||||
if (WSAEventSelect(sock, event.getEvent(), mask) == SOCKET_ERROR) {
|
||||
if (ethErrorCore() == WSAEINPROGRESS)
|
||||
return 0;
|
||||
if (ethErrorCore() == WSAEINPROGRESS) return 0;
|
||||
}
|
||||
if (event.wait()) {
|
||||
//DWORD wr = WSAWaitForMultipleEvents(1, &(PRIVATE->read_event), FALSE, WSA_INFINITE, TRUE);
|
||||
//if (wr == WSA_WAIT_EVENT_0) {
|
||||
// DWORD wr = WSAWaitForMultipleEvents(1, &(PRIVATE->read_event), FALSE, WSA_INFINITE, TRUE);
|
||||
// if (wr == WSA_WAIT_EVENT_0) {
|
||||
WSANETWORKEVENTS events;
|
||||
memset(&events, 0, sizeof(events));
|
||||
WSAEnumNetworkEvents(sock, event.getEvent(), &events);
|
||||
//piCoutObj << "wait result" << events.lNetworkEvents;
|
||||
// piCoutObj << "wait result" << events.lNetworkEvents;
|
||||
return events.lNetworkEvents;
|
||||
}
|
||||
return 0;
|
||||
@@ -1037,8 +1040,8 @@ long PIEthernet::waitForEvent(PIWaitEvent & event, long mask) {
|
||||
|
||||
|
||||
bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) {
|
||||
PIConfig::Entry * em = (PIConfig::Entry * )e_main;
|
||||
PIConfig::Entry * ep = (PIConfig::Entry * )e_parent;
|
||||
PIConfig::Entry * em = (PIConfig::Entry *)e_main;
|
||||
PIConfig::Entry * ep = (PIConfig::Entry *)e_parent;
|
||||
setReadIP(readDeviceSetting<PIString>("ip", readIP(), em, ep));
|
||||
setReadPort(readDeviceSetting<int>("port", readPort(), em, ep));
|
||||
setParameter(PIEthernet::Broadcast, readDeviceSetting<bool>("broadcast", isParameterSet(PIEthernet::Broadcast), em, ep));
|
||||
@@ -1061,7 +1064,7 @@ PIString PIEthernet::constructFullPathDevice() const {
|
||||
ret += ":" + readIP() + ":" + PIString::fromNumber(readPort());
|
||||
if (type() == PIEthernet::UDP) {
|
||||
ret += ":" + sendIP() + ":" + PIString::fromNumber(sendPort());
|
||||
piForeachC (PIString & m, multicastGroups())
|
||||
piForeachC(PIString & m, multicastGroups())
|
||||
ret += ":mcast:" + m;
|
||||
}
|
||||
return ret;
|
||||
@@ -1070,7 +1073,7 @@ PIString PIEthernet::constructFullPathDevice() const {
|
||||
|
||||
void PIEthernet::configureFromFullPathDevice(const PIString & full_path) {
|
||||
PIStringList pl = full_path.split(":");
|
||||
bool mcast = false;
|
||||
bool mcast = false;
|
||||
for (int i = 0; i < pl.size_s(); ++i) {
|
||||
PIString p(pl[i]);
|
||||
switch (i) {
|
||||
@@ -1079,14 +1082,26 @@ void PIEthernet::configureFromFullPathDevice(const PIString & full_path) {
|
||||
if (p == "udp") setType(UDP);
|
||||
if (p == "tcp") setType(TCP_Client);
|
||||
break;
|
||||
case 1: setReadIP(p); setSendIP(p); break;
|
||||
case 2: setReadPort(p.toInt()); setSendPort(p.toInt()); break;
|
||||
case 1:
|
||||
setReadIP(p);
|
||||
setSendIP(p);
|
||||
break;
|
||||
case 2:
|
||||
setReadPort(p.toInt());
|
||||
setSendPort(p.toInt());
|
||||
break;
|
||||
case 3: setSendIP(p); break;
|
||||
case 4: setSendPort(p.toInt()); break;
|
||||
}
|
||||
if (i <= 4) continue;
|
||||
if (i % 2 == 1) {if (p.toLowerCase() == "mcast") mcast = true;}
|
||||
else {if (mcast) {joinMulticastGroup(p); mcast = false;}}
|
||||
if (i % 2 == 1) {
|
||||
if (p.toLowerCase() == "mcast") mcast = true;
|
||||
} else {
|
||||
if (mcast) {
|
||||
joinMulticastGroup(p);
|
||||
mcast = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1095,7 +1110,8 @@ PIPropertyStorage PIEthernet::constructVariantDevice() const {
|
||||
PIPropertyStorage ret;
|
||||
PIVariantTypes::Enum e;
|
||||
|
||||
e << "UDP" << "TCP";
|
||||
e << "UDP"
|
||||
<< "TCP";
|
||||
if (type() == PIEthernet::UDP)
|
||||
e.selectValue(0);
|
||||
else
|
||||
@@ -1118,21 +1134,21 @@ void PIEthernet::configureFromVariantDevice(const PIPropertyStorage & d) {
|
||||
setSendIP(d.propertyValueByName("send IP").toString());
|
||||
setSendPort(d.propertyValueByName("send port").toInt());
|
||||
PIStringList mcgl = d.propertyValueByName("multicast").toStringList();
|
||||
piForeachC (PIString & g, mcgl) {
|
||||
piForeachC(PIString & g, mcgl) {
|
||||
joinMulticastGroup(g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
//piCout << "PIEthernet::interfaces()";
|
||||
// piCout << "PIEthernet::interfaces()";
|
||||
PIEthernet::InterfaceList il;
|
||||
Interface ci;
|
||||
ci.index = -1;
|
||||
ci.mtu = 1500;
|
||||
ci.mtu = 1500;
|
||||
#ifdef WINDOWS
|
||||
int ret = 0;
|
||||
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
int ret = 0;
|
||||
ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO));
|
||||
if (!pAdapterInfo) {
|
||||
piCout << "[PIEthernet] Error allocating memory needed to call GetAdaptersInfo";
|
||||
@@ -1149,9 +1165,9 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
ci.name = PIString(pAdapter->AdapterName);
|
||||
ci.name = PIString(pAdapter->AdapterName);
|
||||
ci.index = pAdapter->Index;
|
||||
ci.mac = macFromBytes(PIByteArray(pAdapter->Address, pAdapter->AddressLength));
|
||||
ci.mac = macFromBytes(PIByteArray(pAdapter->Address, pAdapter->AddressLength));
|
||||
ci.flags = PIEthernet::ifActive | PIEthernet::ifRunning;
|
||||
if (pAdapter->Type == MIB_IF_TYPE_PPP) ci.flags |= PIEthernet::ifPTP;
|
||||
if (pAdapter->Type == MIB_IF_TYPE_LOOPBACK) ci.flags |= PIEthernet::ifLoopback;
|
||||
@@ -1159,7 +1175,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
ci.ptp.clear();
|
||||
IP_ADDR_STRING * as = &(pAdapter->IpAddressList);
|
||||
while (as) {
|
||||
// piCout << "[pAdapter]" << ci.name << PIString(as->IpAddress.String);
|
||||
// piCout << "[pAdapter]" << ci.name << PIString(as->IpAddress.String);
|
||||
ci.address = PIStringAscii(as->IpAddress.String);
|
||||
ci.netmask = PIStringAscii(as->IpMask.String);
|
||||
if (ci.address == "0.0.0.0") {
|
||||
@@ -1174,21 +1190,17 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
} else {
|
||||
switch (ret) {
|
||||
case ERROR_NO_DATA: break;
|
||||
case ERROR_NOT_SUPPORTED:
|
||||
piCout << "[PIEthernet] GetAdaptersInfo not supported";
|
||||
break;
|
||||
default:
|
||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret;
|
||||
case ERROR_NOT_SUPPORTED: piCout << "[PIEthernet] GetAdaptersInfo not supported"; break;
|
||||
default: piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret;
|
||||
}
|
||||
}
|
||||
if (pAdapterInfo)
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
if (pAdapterInfo) HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
#else
|
||||
#ifdef MICRO_PIP
|
||||
#else
|
||||
# ifdef ANDROID
|
||||
# ifdef MICRO_PIP
|
||||
# else
|
||||
# ifdef ANDROID
|
||||
struct ifconf ifc;
|
||||
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
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) {
|
||||
@@ -1200,24 +1212,21 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
PIStringList inl;
|
||||
struct ifreq ir;
|
||||
for (int i = 0; i < icnt; ++i) {
|
||||
ci.flags = 0;
|
||||
ci.flags = 0;
|
||||
PIString in = PIStringAscii(ifc.ifc_req[i].ifr_name);
|
||||
if (in.isEmpty()) continue;
|
||||
ci.name = in;
|
||||
strcpy(ir.ifr_name, in.dataAscii());
|
||||
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);
|
||||
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);
|
||||
ioctl(s, SIOCGIFMTU, &ci.mtu);
|
||||
if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback;
|
||||
il << ci;
|
||||
}
|
||||
delete ifc.ifc_buf;
|
||||
# else
|
||||
struct ifaddrs * ret, * cif = 0;
|
||||
# else
|
||||
struct ifaddrs *ret, *cif = 0;
|
||||
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if (getifaddrs(&ret) == 0) {
|
||||
cif = ret;
|
||||
@@ -1230,12 +1239,12 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
cif = cif->ifa_next;
|
||||
continue;
|
||||
}
|
||||
ci.name = PIString(cif->ifa_name);
|
||||
ci.name = PIString(cif->ifa_name);
|
||||
ci.address = getSockAddr(cif->ifa_addr);
|
||||
ci.netmask = getSockAddr(cif->ifa_netmask);
|
||||
ci.mac.clear();
|
||||
# ifdef QNX
|
||||
# ifndef BLACKBERRY
|
||||
# ifdef QNX
|
||||
# ifndef BLACKBERRY
|
||||
int fd = ::open((PIString("/dev/io-net/") + ci.name).dataAscii(), O_RDONLY);
|
||||
if (fd != 0) {
|
||||
nic_config_t nic;
|
||||
@@ -1243,20 +1252,20 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
::close(fd);
|
||||
ci.mac = macFromBytes(PIByteArray(nic.permanent_address, 6));
|
||||
}
|
||||
# endif
|
||||
# else
|
||||
# ifdef MAC_OS
|
||||
# endif
|
||||
# else
|
||||
# ifdef MAC_OS
|
||||
PIString req = PISystemInfo::instance()->ifconfigPath + " " + ci.name + " | grep ether";
|
||||
FILE * fp = popen(req.dataAscii(), "r");
|
||||
FILE * fp = popen(req.dataAscii(), "r");
|
||||
if (fp != 0) {
|
||||
char in[256];
|
||||
if (fgets(in, 256, fp) != 0) {
|
||||
req = PIString(in).trim();
|
||||
req = PIString(in).trim();
|
||||
ci.mac = req.cutLeft(req.find(" ") + 1).trim().toUpperCase();
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
# else
|
||||
# else
|
||||
if (s != -1) {
|
||||
struct ifreq ir;
|
||||
strcpy(ir.ifr_name, cif->ifa_name);
|
||||
@@ -1265,8 +1274,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
ci.mtu = ir.ifr_mtu;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
ci.flags = 0;
|
||||
if (cif->ifa_flags & IFF_UP) ci.flags |= PIEthernet::ifActive;
|
||||
if (cif->ifa_flags & IFF_RUNNING) ci.flags |= PIEthernet::ifRunning;
|
||||
@@ -1276,10 +1285,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
if (cif->ifa_flags & IFF_POINTOPOINT) ci.flags |= PIEthernet::ifPTP;
|
||||
ci.broadcast.clear();
|
||||
ci.ptp.clear();
|
||||
if (ci.flags[PIEthernet::ifBroadcast])
|
||||
ci.broadcast = getSockAddr(cif->ifa_broadaddr);
|
||||
if (ci.flags[PIEthernet::ifPTP])
|
||||
ci.ptp = getSockAddr(cif->ifa_dstaddr);
|
||||
if (ci.flags[PIEthernet::ifBroadcast]) ci.broadcast = getSockAddr(cif->ifa_broadaddr);
|
||||
if (ci.flags[PIEthernet::ifPTP]) ci.ptp = getSockAddr(cif->ifa_dstaddr);
|
||||
ci.index = if_nametoindex(cif->ifa_name);
|
||||
il << ci;
|
||||
cif = cif->ifa_next;
|
||||
@@ -1288,7 +1295,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
} else
|
||||
piCout << "[PIEthernet] Can`t get interfaces:" << errorString();
|
||||
if (s != -1) ::close(s);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
return il;
|
||||
@@ -1306,10 +1313,9 @@ PIEthernet::Address PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||
int s = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||
ioctl(s, SIOCGIFADDR, &ifr);
|
||||
::close(s);
|
||||
struct sockaddr_in * sa = (struct sockaddr_in * )&ifr.ifr_addr;
|
||||
struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr;
|
||||
return Address(uint(sa->sin_addr.s_addr));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1317,13 +1323,13 @@ PIVector<PIEthernet::Address> PIEthernet::allAddresses() {
|
||||
PIEthernet::InterfaceList il = interfaces();
|
||||
PIVector<Address> ret;
|
||||
bool has_127 = false;
|
||||
piForeachC (PIEthernet::Interface & i, il) {
|
||||
piForeachC(PIEthernet::Interface & i, il) {
|
||||
if (i.address == "127.0.0.1") has_127 = true;
|
||||
Address a(i.address);
|
||||
if (a.ip() == 0) continue;
|
||||
ret << a;
|
||||
}
|
||||
// piCout << "[PIEthernet::allAddresses]" << al;
|
||||
// piCout << "[PIEthernet::allAddresses]" << al;
|
||||
if (!has_127) ret << Address("127.0.0.1");
|
||||
return ret;
|
||||
}
|
||||
@@ -1343,8 +1349,14 @@ int PIEthernet::ethErrorCore() {
|
||||
PIString PIEthernet::ethErrorString() {
|
||||
#ifdef WINDOWS
|
||||
char * msg = nullptr;
|
||||
int err = WSAGetLastError();
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
|
||||
int err = WSAGetLastError();
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&msg,
|
||||
0,
|
||||
NULL);
|
||||
PIString ret = PIStringAscii("code ") + PIString::fromNumber(err) + PIStringAscii(" - ");
|
||||
if (msg) {
|
||||
ret += PIString::fromSystem(msg).trim();
|
||||
@@ -1362,9 +1374,11 @@ int PIEthernet::ethRecv(int sock, void * buf, int size, int flags) {
|
||||
if (sock < 0) return -1;
|
||||
return recv(sock,
|
||||
#ifdef WINDOWS
|
||||
(char*)
|
||||
(char *)
|
||||
#endif
|
||||
buf, size, flags);
|
||||
buf,
|
||||
size,
|
||||
flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -1376,9 +1390,13 @@ int PIEthernet::ethRecvfrom(int sock, void * buf, int size, int flags, sockaddr
|
||||
socklen_t len = sizeof(sockaddr);
|
||||
return recvfrom(sock,
|
||||
# ifdef WINDOWS
|
||||
(char*)
|
||||
(char *)
|
||||
# endif
|
||||
buf, size, flags, addr, &len);
|
||||
buf,
|
||||
size,
|
||||
flags,
|
||||
addr,
|
||||
&len);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1387,33 +1405,41 @@ int PIEthernet::ethSendto(int sock, const void * buf, int size, int flags, socka
|
||||
if (sock < 0) return -1;
|
||||
return sendto(sock,
|
||||
#ifdef WINDOWS
|
||||
(const char*)
|
||||
(const char *)
|
||||
#endif
|
||||
buf, size, flags, addr, addr_len);
|
||||
buf,
|
||||
size,
|
||||
flags,
|
||||
addr,
|
||||
addr_len);
|
||||
}
|
||||
|
||||
|
||||
void PIEthernet::ethClosesocket(int sock, bool shutdown) {
|
||||
//piCout << "close socket" << sock << shutdown;
|
||||
// piCout << "close socket" << sock << shutdown;
|
||||
if (sock < 0) return;
|
||||
if (shutdown) ::shutdown(sock,
|
||||
if (shutdown)
|
||||
::shutdown(sock,
|
||||
#ifdef WINDOWS
|
||||
SD_BOTH);
|
||||
closesocket(sock);
|
||||
SD_BOTH);
|
||||
closesocket(sock);
|
||||
#else
|
||||
SHUT_RDWR);
|
||||
::close(sock);
|
||||
SHUT_RDWR);
|
||||
::close(sock);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * optval, int optlen) {
|
||||
if (sock < 0) return -1;
|
||||
return setsockopt(sock, level, optname,
|
||||
return setsockopt(sock,
|
||||
level,
|
||||
optname,
|
||||
#ifdef WINDOWS
|
||||
(char*)
|
||||
(char *)
|
||||
#endif
|
||||
optval, optlen);
|
||||
optval,
|
||||
optlen);
|
||||
}
|
||||
|
||||
|
||||
@@ -1424,7 +1450,7 @@ int PIEthernet::ethSetsockoptInt(int sock, int level, int optname, int value) {
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
so = value;
|
||||
so = value;
|
||||
return ethSetsockopt(sock, level, optname, &so, sizeof(so));
|
||||
}
|
||||
|
||||
@@ -1436,7 +1462,7 @@ int PIEthernet::ethSetsockoptBool(int sock, int level, int optname, bool value)
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
so = (value ? 1 : 0);
|
||||
so = (value ? 1 : 0);
|
||||
return ethSetsockopt(sock, level, optname, &so, sizeof(so));
|
||||
}
|
||||
|
||||
@@ -1473,9 +1499,9 @@ bool PIEthernet::ethIsWriteable(int sock) {
|
||||
::select(0, nullptr, &fd_test, nullptr, &timeout);
|
||||
return FD_ISSET(sock, &fd_test);
|
||||
#else
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
socklen_t len = sizeof(ret);
|
||||
getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&ret, &len);
|
||||
getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&ret, &len);
|
||||
return ret == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user