/*
PIP - Platform Independent Primitives
Ethernet, UDP
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "piethernet.h"
PIEthernet::PIEthernet(void * data, ReadRetFunc slot): PIIODevice("", ReadWrite) {
piMonitor.ethernets++;
setPriority(piHigh);
type_ = UDP;
ret_data_ = data;
ip_ = ip_s = "";
port_ = port_s = 0;
sock = -1;
ret_func_ = slot;
connected_ = false;
server_thread_.setData(this);
setThreadedReadBufferSize(65536);
#ifdef WINDOWS
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
init();
}
PIEthernet::PIEthernet(PIEthernet::Type type, void * data, ReadRetFunc slot): PIIODevice("", ReadWrite) {
piMonitor.ethernets++;
setPriority(piHigh);
type_ = type;
ret_data_ = data;
ip_ = ip_s = "";
port_ = port_s = 0;
sock = -1;
ret_func_ = slot;
connected_ = false;
server_thread_.setData(this);
setThreadedReadBufferSize(65536);
#ifdef WINDOWS
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
init();
}
PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) {
piMonitor.ethernets++;
setPriority(piHigh);
type_ = TCP_Client;
parseAddress(ip_port, &ip_s, &port_s);
sock = sock_;
server_thread_.setData(this);
init_ = opened_ = connected_ = true;
setThreadedReadBufferSize(65536);
#ifdef WINDOWS
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
}
PIEthernet::~PIEthernet() {
piMonitor.ethernets--;
if (server_thread_.isRunning()) server_thread_.terminate();
closeSocket(sock);
#ifdef WINDOWS
WSACleanup();
#endif
//if (buffer_ != 0) delete buffer_;
//buffer_ = 0;
}
bool PIEthernet::init() {
//cout << "init " << type_ << endl;
closeSocket(sock);
int st = 0, so = 1;
if (type_ == UDP) st = SOCK_DGRAM;
if (type_ == TCP_Client || type_ == TCP_Server) st = SOCK_STREAM;
sock = socket(PF_INET, st, 0);
if (sock == -1) {
piCout << "[PIEthernet] Cant`t create socket, " << errorString() << endl;
return false;
}
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so));
//fcntl(sock, F_SETFL, 0/*O_NONBLOCK*/);
return true;
}
void PIEthernet::parseAddress(const PIString & ipp, PIString * ip, int * port) {
if (ip != 0) *ip = ipp.left(ipp.find(":"));
if (port != 0) *port = ipp.right(ipp.length() - ipp.find(":") - 1).toInt();
}
bool PIEthernet::openDevice() {
if (connected_) return true;
if (sock == -1) init();
if (sock == -1) return false;
//cout << " bind to " << path_ << " ..." <sock, (sockaddr * )&client_addr, &slen);
if (s == -1) {
piCout << "[PIEthernet] Cant`t accept new connection, " << errorString() << endl;
return;
}
PIString ip(inet_ntoa(client_addr.sin_addr));
ip += ":" + PIString::fromNumber(htons(client_addr.sin_port));
ce->clients_ << new PIEthernet(s, ip);
cout << "connected " << ip << endl;
//char d[256];
//cout << " recv " << recv(s, d, 256, 0) << endl;
//cout << recv(ce->clients_.back()->sock, d, 256, 0) << endl;
}