From 495330ce3cfb6b168d2fb9b56aa125bbc7ff6e7d Mon Sep 17 00:00:00 2001
From: deva <deva>
Date: Tue, 10 Jan 2006 10:03:41 +0000
Subject: *** empty log message ***

---
 src/aa_socket.cc      | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/aa_socket.h       |  42 +++++++++
 src/cprlisten.cc      |  50 ++++++++--
 src/cprlisten.h       |  10 ++
 src/cprquerydialog.cc |  29 ++++++
 src/cprquerydialog.h  |   7 ++
 src/thread.cc         |  12 ++-
 src/thread.h          |   1 +
 8 files changed, 393 insertions(+), 12 deletions(-)
 create mode 100644 src/aa_socket.cc
 create mode 100644 src/aa_socket.h

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;
 };
 
-- 
cgit v1.2.3