giuliomoro@336: /*
giuliomoro@336:  * udpClient.cpp
giuliomoro@336:  *
giuliomoro@336:  *  Created on: 19 May 2015
giuliomoro@336:  *      Author: giulio moro
giuliomoro@336:  */
giuliomoro@336: #include <UdpClient.h>
giuliomoro@336: 
giuliomoro@336: 	UdpClient::UdpClient(){
giuliomoro@336: 		outSocket=socket(AF_INET, SOCK_DGRAM, 0);
giuliomoro@336: 		setSocketBroadcast(1);
giuliomoro@336: 		isSetPort=false;
giuliomoro@336: 		isSetServer=false;
giuliomoro@336: 		enabled=false;
giuliomoro@336: 	}
giuliomoro@336: 	UdpClient::UdpClient(int aPort, const char* aServerName){
giuliomoro@336: 		outSocket=socket(AF_INET, SOCK_DGRAM, 0);
giuliomoro@336: 		if(outSocket<0){
giuliomoro@336: 			enabled=false;
giuliomoro@336: 			return;
giuliomoro@336: 		}
giuliomoro@336: 		setSocketBroadcast(1);
giuliomoro@336: 		setPort(aPort);
giuliomoro@336: 		setServer(aServerName);
giuliomoro@336: 		isSetPort=true;
giuliomoro@336: 		isSetServer=true;
giuliomoro@336: 		enabled=true;
giuliomoro@336: 		memset(&stTimeOut, 0, sizeof(struct timeval));
giuliomoro@336: 	}
giuliomoro@336: 	UdpClient::~UdpClient(){
giuliomoro@336: 	   close(outSocket);
giuliomoro@336: 	}
giuliomoro@336: 	void UdpClient::setPort(int aPort){
giuliomoro@336: 		port=aPort;
giuliomoro@336: 		destinationServer.sin_port = htons(port);
giuliomoro@336: 		destinationServer.sin_family = AF_INET;
giuliomoro@336: 		isSetPort=true;
giuliomoro@336: 		if(isSetServer){
giuliomoro@336: 			enabled=true;
giuliomoro@336: 		}
giuliomoro@336: 	};
giuliomoro@336: 	void UdpClient::setServer(const char* aServerName){
giuliomoro@336: 		inet_pton(AF_INET,aServerName,&destinationServer.sin_addr);
giuliomoro@336: 		isSetServer=true;
giuliomoro@336: 		if(isSetPort){
giuliomoro@336: 			enabled=true;
giuliomoro@336: 		}
giuliomoro@336: 	};
giuliomoro@336: 	int UdpClient::send(void * message, int size){
giuliomoro@336: 		if(!enabled)
giuliomoro@336: 			return -1;
giuliomoro@336: 		unsigned int length;
giuliomoro@336: 		length=sizeof(struct sockaddr_in);
giuliomoro@336: 		int n=sendto(outSocket,message,size,0,(const struct sockaddr *)&destinationServer,length);
giuliomoro@336: 		if (n < 0){
giuliomoro@336: 			return n;
giuliomoro@336: 		}
giuliomoro@336: 		return 1;
giuliomoro@336: 	};
giuliomoro@336: 	int UdpClient::write(const char* remoteHostname, int remotePortNumber, void* sourceBuffer, int numBytesToWrite){
giuliomoro@336: 		setServer(remoteHostname);
giuliomoro@336: 		setPort(remotePortNumber);
giuliomoro@336: 		return send(sourceBuffer, numBytesToWrite);
giuliomoro@336: 	}
giuliomoro@336:   int UdpClient::waitUntilReady(bool readyForReading, int timeoutMsecs){
giuliomoro@336: //	If the socket is ready on return, this returns 1. If it times-out before the socket becomes ready, it returns 0. If an error occurs, it returns -1.
giuliomoro@336:     if(enabled==false)
giuliomoro@336: 		return -1;
giuliomoro@336:     if(timeoutMsecs<0)
giuliomoro@336: 		return select(outSocket+1, NULL, &stWriteFDS, NULL, NULL); //calling this with a NULL timeout will block indefinitely
giuliomoro@336:     FD_ZERO(&stWriteFDS);
giuliomoro@336:     FD_SET(outSocket, &stWriteFDS);
giuliomoro@336: 	float timeOutSecs=timeoutMsecs*0.001;
giuliomoro@336: 	stTimeOut.tv_sec=(int)timeOutSecs;
giuliomoro@336: 	timeOutSecs-=(int)timeOutSecs;
giuliomoro@336: 	stTimeOut.tv_usec=(int)(timeOutSecs*1000000);
giuliomoro@336:     int descriptorReady= select(outSocket+1, NULL, &stWriteFDS, NULL, &stTimeOut);
giuliomoro@336:     return descriptorReady>0? 1 : descriptorReady;
giuliomoro@336:   }
giuliomoro@336: 	int	UdpClient::setSocketBroadcast(int broadcastEnable){
giuliomoro@336: 		int ret = setsockopt(outSocket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
giuliomoro@336: 		if(ret < 0){
giuliomoro@336: 			printf("Impossible to set the socket to Broadcast\n");
giuliomoro@336: 		}
giuliomoro@336: 		return ret;
giuliomoro@336: 	}