diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/aa_socket.cc | 254 | ||||
| -rw-r--r-- | src/aa_socket.h | 42 | ||||
| -rw-r--r-- | src/cprlisten.cc | 50 | ||||
| -rw-r--r-- | src/cprlisten.h | 10 | ||||
| -rw-r--r-- | src/cprquerydialog.cc | 29 | ||||
| -rw-r--r-- | src/cprquerydialog.h | 7 | ||||
| -rw-r--r-- | src/thread.cc | 12 | ||||
| -rw-r--r-- | src/thread.h | 1 | 
8 files changed, 393 insertions, 12 deletions
| diff --git a/src/aa_socket.cc b/src/aa_socket.cc new file mode 100644 index 0000000..28ecead --- /dev/null +++ b/src/aa_socket.cc @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +#include "aa_socket.h" + +//#include <string.h> + +#include <iostream> +using namespace std; + +#include <unistd.h> +//#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include <errno.h> + +#include <netinet/in.h> +#if defined(linux) +#include <endian.h> +#else +#include <sys/endian.h> +#endif /*defined(linux)*/ + +// for gethostbyname +#include <netdb.h> + +// These functions are wrappers, to preserve my nice method naming! +inline int _socket(int a,int b,int c){return socket(a,b,c);}  +inline int _connect(int a,const struct sockaddr *b,socklen_t c){return connect(a,b,c);} +inline int _listen(int a,int b){return listen(a,b);} +inline int _send(int a,char *b,unsigned int c, int d){return send(a,b,c,d);} + + +AASocket::AASocket() +{ +} + +AASocket::~AASocket() +{ +  int err = close(socket);  // close server +	if(err == -1) throw Network_error("close", strerror(errno)); +} + +void AASocket::connect(char *host, unsigned short port) +{ +  // create socket +  socket = _socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  +  // PF_INET: ipv4, PF_INET6: ipv6 +  // tcp: IPPROTO_TCP +  // upd: IPPROTO_UDP + +  if (socket == -1) throw Network_error("socket", strerror(errno)); + +  socketaddr.sin_family = AF_INET; // Use "internet protocol" IP +  socketaddr.sin_port = htons(port);  // connect to that port +  socketaddr.sin_addr.s_addr = INADDR_ANY; +  // INADDR_ANY puts your IP address automatically + + + +	struct hostent *hp = gethostbyname(host); +	//	memcpy(&socketaddr.sin_addr.s_addr, *(hp->h_addr_list),sizeof(struct in_addr)); +	memcpy(&(socketaddr.sin_addr),*(hp->h_addr_list),sizeof(struct in_addr)); + +	// FIXME: gethostbyname() +	//  socketaddr.sin_addr.s_addr = inet_addr(host);  +  //inet_aton (ip, &socketaddr.sin_addr); +   +  int err = _connect(socket, (struct sockaddr*)&socketaddr, sizeof(socketaddr)); +	if(err == -1) throw Network_error("connect", strerror(errno)); +} + +void AASocket::listen(unsigned short port) +{ +	int err; + +	bind_socket = _socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); +	if(bind_socket == -1) throw Network_error("tmp socket", strerror(errno)); +	 +	int optval = 1; +	err = setsockopt(bind_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); +	if(err == -1) throw Network_error("setsockopt", strerror(errno)); + +  socketaddr.sin_family = AF_INET; // Use "internet protocol" IP +  socketaddr.sin_port = htons(port);  // connect to that port +  socketaddr.sin_addr.s_addr = INADDR_ANY; +  // INADDR_ANY puts your IP address automatically +	 +	// bind socket to address specified by "sa" parameter +	err = bind(bind_socket, (struct sockaddr*)&socketaddr, sizeof(socketaddr)); +	if(err == -1) throw Network_error("bind", strerror(errno)); +	 +	err = _listen(bind_socket, 5); +	if(err == -1) throw Network_error("listen", strerror(errno)); + +  int csalen = sizeof(socketaddr); +  socket = accept(bind_socket,  +									(struct sockaddr*)&socketaddr,  +									(socklen_t*)&csalen); +	if(socket == -1) throw Network_error("accept", strerror(errno)); + +	err = close(bind_socket); // We don't need this anymore +  bind_socket = -1; +	if(err == -1) throw Network_error("tmp close", strerror(errno)); +} + + +void AASocket::force_close() +{ +  if(bind_socket != -1) close(bind_socket); // This should break the accept call +} + + +void AASocket::send(char* buf, unsigned int size) +{ +	//unsigned int newsize = size + sizeof(unsigned int); +	//	char *newbuf = new char[newsize]; + +	unsigned int nsize = htonl(size); +	int n = _send(socket, (char*)&nsize, sizeof(unsigned int), MSG_WAITALL); +	if(n == -1) throw Network_error("send", strerror(errno)); + +	n = _send(socket, buf, size, MSG_WAITALL); +	if(n == -1) throw Network_error("send", strerror(errno)); +} + + +int AASocket::receive(char* buf, unsigned int size) +{ +	unsigned int insize; +	 +	int n = recv(socket, &insize, sizeof(unsigned int), MSG_WAITALL); +	if(n == -1) throw Network_error("recv", strerror(errno)); + +	insize = ntohl(insize); +	if(insize > size) { +		char err_buf[256]; +		sprintf(err_buf, "Buffer is too small. Should be %d is %d." , insize, size); +		throw Network_error("receive", err_buf); +	} +	 +	n = recv(socket, buf, insize, MSG_WAITALL); +	if(n == -1) throw Network_error("recv", strerror(errno)); + +	return n; +} + + +void AASocket::send_string(string str) +{ +	this->send((char*)str.c_str(), str.length()); +} + + +string AASocket::receive_string() +{ +	char buf[1024]; +	memset(buf, 0, sizeof(buf)); + +	receive(buf, sizeof(buf)); + +  return string(buf); +} + + + +#ifdef TEST_SOCKET + +/** + * Test application for AASocket + * It should print the following to stdout: + * A: Hello, how are you? + * B: Fine thanks. + * A: What about you? + * B: I'm fine too. + */ + +#include <sys/types.h> +#include <unistd.h> + +#include <string> +#include <iostream> + +int main() +{ +	char buf[1024]; +	memset(buf, 0, sizeof(buf)); +  int f = fork(); +  switch(f) { +  case -1: // Fork error +    perror("Fork failed!"); +    return 1; + +  case 0:  // Forked child +		{ +			try { +				AASocket out; + +				sleep(1); // Make sure the other end is listening + +				// Test connect +				out.connect("127.0.0.1", 6666); + +				// Test raw communication send +				sprintf(buf, "Hello how are you?"); +				out.send(buf, sizeof(buf)); + +				// Test raw communication receive +				out.receive(buf, sizeof(buf)); +				std::cout << "B: " << buf << std::endl; + +				// Test string receive +				std::string q = out.receive_string(); +				std::cout << "B: " << q << std::endl; + +				// Test string send +				out.send_string(std::string("I'm fine too.")); +				return 0; +			} catch(Network_error e) { +				std::cerr << "Out: " << e.error << std::endl; +			} +		} +  default: // Parent +		{ +			try { +				AASocket in; +				 +				// Test listen +				in.listen(6666); + +				// Test raw communication receive +				in.receive(buf, sizeof(buf)); +				std::cout << "A: " << buf << std::endl; + +				// Test raw communication send +				sprintf(buf, "Fine thanks."); +				in.send(buf, sizeof(buf)); + +				// Test string send +				in.send_string(std::string("What about you?")); + +				// Test string receive	 +				std::string a = in.receive_string(); +				std::cout << "A: " << a << std::endl; +				return 0; +			} catch(Network_error e) { +				std::cerr << "In: " << e.error << std::endl; +			} +		} +	} +	return 0; +} +#endif/*TEST_SOCKET*/ diff --git a/src/aa_socket.h b/src/aa_socket.h new file mode 100644 index 0000000..0d02723 --- /dev/null +++ b/src/aa_socket.h @@ -0,0 +1,42 @@ +#ifndef __SOCKET_H__ +#define __SOCKET_H__ + +#include <string> + +#include <netinet/in.h> +//#include <sys/socket.h> + + +/** + * Exceptions + */ +struct Network_error { +	Network_error(char *event, char *err) { +		error = std::string(err) + " - in " + std::string(event); +	} +	std::string error; +}; + +class AASocket { +public: +  AASocket(); +  ~AASocket(); + +  void listen(unsigned short port); +  void connect(char *ip, unsigned short port); +   +  void send(char* buf, unsigned int buf_size); +  int receive(char* buf, unsigned int buf_size); + +  void send_string(std::string buf); +  std::string receive_string(); + +	void force_close(); + +private: +  struct sockaddr_in socketaddr; +  int socket; +	int bind_socket; // Tmp socket for listen. +}; + +#endif/*__SOCKET_H__*/ diff --git a/src/cprlisten.cc b/src/cprlisten.cc index 9a816d2..9ecac86 100644 --- a/src/cprlisten.cc +++ b/src/cprlisten.cc @@ -26,36 +26,68 @@   */  #include "cprlisten.h" -#include "socket.h" +#include "aa_socket.h"  #include <iostream>  #include <string>  using namespace std; +#define MAGIC_STOP_STRING "SHUTTHEFUCKUP" +  CPRListen::CPRListen(unsigned short port)  {  	this->port = port;  	cpr = "N/A"; +	cprchanged = false; +	running = true;  }  CPRListen::~CPRListen()  {  } +void CPRListen::stop() +{ +	running = false; +	try { +		AASocket socket; +		socket.connect("localhost", port); +		socket.send_string(MAGIC_STOP_STRING); +	} catch(Network_error &e) { +		cerr << "In stop(): " << e.error << endl; +	} +} +  void CPRListen::thread_main()  { -	while(1) { +	while(running) {  		try { -			Socket socket; +			string newcpr; +			AASocket socket;  			socket.listen(port); -			mutex.lock(); -			cpr = socket.receive_string(); -			mutex.unlock(); -			cerr << "Got CPR: " << cpr << endl; +			newcpr = socket.receive_string(); + + 			if(newcpr == MAGIC_STOP_STRING) { +				running = false; +			}	else { +				mutex.lock(); +				cprchanged = true; +				cpr = newcpr; +				mutex.unlock(); +				//	cerr << "Got CPR: " << cpr << endl; +			} +  		} catch(Network_error &e) { -			cerr << e.error << endl; +			cerr << "In thread_main(): " << e.error << endl; +			running = false;  		}  	} +	//	cout << "fisk!" << endl; +} + +bool CPRListen::cprChanged() +{ +	return cprchanged;  }  string CPRListen::getCpr() @@ -66,5 +98,7 @@ string CPRListen::getCpr()  	cpr_copy = cpr;  	mutex.unlock(); +	cprchanged = false; +  	return cpr_copy;  } diff --git a/src/cprlisten.h b/src/cprlisten.h index 57551f5..5808aec 100644 --- a/src/cprlisten.h +++ b/src/cprlisten.h @@ -33,15 +33,25 @@  #include "thread.h"  #include "mutex.h" +#include "aa_socket.h" +  class CPRListen: public Thread {  public:  	CPRListen(unsigned short port);  	~CPRListen(); +	bool cprChanged();  	std::string getCpr();  	void thread_main(); +	void stop(); // Stops the call to listen +  private: + +	volatile bool running; +	AASocket *socket; + +	bool cprchanged;  	unsigned short port;  	std::string cpr;  	Mutex mutex; diff --git a/src/cprquerydialog.cc b/src/cprquerydialog.cc index 4506e42..552aeb6 100644 --- a/src/cprquerydialog.cc +++ b/src/cprquerydialog.cc @@ -114,11 +114,40 @@ CPRQueryDialog::CPRQueryDialog(QLabel *lcpr,  	connect(bca,SIGNAL(clicked()), SLOT(b_c_clicked()));  	this->move(175,150); + +  listen = new CPRListen(config->readInt("cprlisten_port")); +  listen_timer = new QTimer(this); +  connect(listen_timer, SIGNAL(timeout()), SLOT(listen_timeout())); +  listen->run(); +  listen_timer->start(500); // Check every 500 ms +    show();  }  CPRQueryDialog::~CPRQueryDialog()  { +  // Cleanup +  //  delete timer; +  //  delete cprSocket + +  // Cleanup after cpr listen +  listen->stop(); +  //  listen->wait_stop(); +  delete listen; +  //  delete listen_timer; +} + +void CPRQueryDialog::listen_timeout() +{ +  string newcpr; +  if(listen->cprChanged()) { +    char newcpr_buf[32]; +    newcpr = listen->getCpr(); +    sprintf(newcpr_buf, "%s-%s", newcpr.substr(0,6).c_str(), newcpr.substr(6,4).c_str()); +    //    printf("cprbuf[%s]\n", newcpr_buf); +    lbl_cpr->setText(newcpr_buf); +    verifycpr(newcpr_buf); +  }  }  /** diff --git a/src/cprquerydialog.h b/src/cprquerydialog.h index 2acf1b4..d9c7341 100644 --- a/src/cprquerydialog.h +++ b/src/cprquerydialog.h @@ -86,6 +86,8 @@ using namespace std;  #include "messagebox.h" +#include "cprlisten.h" +  class CPRQueryDialog : public QDialog {    Q_OBJECT  public: @@ -106,8 +108,13 @@ public slots:    void cprSocket_connected();    void cprSocket_error(int errnum);    void cprSocket_timeout(); +  void listen_timeout(); +  private: +  CPRListen *listen; +  QTimer *listen_timer; +    QStatusBar *statusbar;    QLabel *lbl_cpr; diff --git a/src/thread.cc b/src/thread.cc index 2791c53..147cf00 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -36,17 +36,21 @@ static void* thread_run(void *data) {  }  Thread::Thread() -{} +{ +}  Thread::~Thread() -{} +{ +}  void Thread::run()  { -  pthread_create (&tid, NULL, thread_run, this); +  pthread_attr_init(&attr); +   +  pthread_create(&tid, &attr, thread_run, this);  }  void Thread::wait_stop()  { -  pthread_join (tid, NULL); +  pthread_join(tid, NULL);  } diff --git a/src/thread.h b/src/thread.h index 6b7a52a..3d58d74 100644 --- a/src/thread.h +++ b/src/thread.h @@ -42,6 +42,7 @@ public:    virtual void thread_main() = 0;  private: +  pthread_attr_t attr;    pthread_t tid;  }; | 
