ROVER - Modularization - added new tasks: socket communication, image processing, booth modes

Signed-off-by: Mustafa Ozcelikors <mozcelikors@gmail.com>
diff --git a/rover/src/tasks/booth_modes_task.cpp b/rover/src/tasks/booth_modes_task.cpp
new file mode 100644
index 0000000..1a09cd7
--- /dev/null
+++ b/rover/src/tasks/booth_modes_task.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    Booth modes implemented for demonstration of the APP4MC-APPSTACLE Rover
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created 23.10.2017
+ *
+ */
+
+#include <tasks/booth_modes_task.h>
+
+#include <wiringPi.h>
+#include <ctime>
+#include <unistd.h>
+#include <libraries/timing/timing.h>
+#include <api/basic_psys_rover.h>
+#include <interfaces.h>
+#include <pthread.h>
+#include <roverapp.h>
+#include <softPwm.h>
+
+#include <libraries/pthread_monitoring/collect_thread_name.h>
+
+void *Booth_Modes_Task(void * arg)
+{
+	timing booth_task_tmr;
+	booth_task_tmr.setTaskID("BM");
+	booth_task_tmr.setDeadline(0.1);
+	booth_task_tmr.setPeriod(0.1);
+
+	CollectThreadName("Booth_Modes_Task");
+
+	while (1)
+	{
+		booth_task_tmr.recordStartTime();
+		booth_task_tmr.calculatePreviousSlackTime();
+
+		//Task content starts here -----------------------------------------------
+
+		if (driving_mode == BOOTH1)
+		{
+
+		}
+
+		if (driving_mode == BOOTH2)
+		{
+
+		}
+
+		//Task content ends here -------------------------------------------------
+
+		booth_task_tmr.recordEndTime();
+		booth_task_tmr.calculateExecutionTime();
+		booth_task_tmr.calculateDeadlineMissPercentage();
+		booth_task_tmr.incrementTotalCycles();
+		pthread_mutex_lock(&booth_task_ti_l);
+			booth_task_ti.deadline = booth_task_tmr.getDeadline();
+			booth_task_ti.deadline_miss_percentage = booth_task_tmr.getDeadlineMissPercentage();
+			booth_task_ti.execution_time = booth_task_tmr.getExecutionTime();
+			booth_task_ti.period = booth_task_tmr.getPeriod();
+			booth_task_ti.prev_slack_time = booth_task_tmr.getPrevSlackTime();
+			booth_task_ti.task_id = booth_task_tmr.getTaskID();
+			booth_task_ti.start_time = booth_task_tmr.getStartTime();
+			booth_task_ti.end_time = booth_task_tmr.getEndTime();
+		pthread_mutex_unlock(&booth_task_ti_l);
+		booth_task_tmr.sleepToMatchPeriod();
+	}
+
+	/* the function must return something - NULL will do */
+	return NULL;
+}
+
+
+
diff --git a/rover/src/tasks/image_processing_task.cpp b/rover/src/tasks/image_processing_task.cpp
new file mode 100644
index 0000000..08070d2
--- /dev/null
+++ b/rover/src/tasks/image_processing_task.cpp
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *    Image processing task that is used for basic traffic cone detection
+ *    Using OpenCV 2.4.9
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, libraries compiled for cross compilation 16.10.2017
+ *    M.Ozcelikors <mozcelikors@gmail.com>, demonstrator image processing task added, 19.10.2017
+ *
+ *
+ * Usage Instructions:
+ *    1) To cross compile OpenCV, make sure you install OpenCV in your Raspberry Pi
+ *    2) Then find opencv shared objects using the following command
+ *    		find / -name libopencv*.so
+ *    		find / -name libopencv*.so*
+ *    3) Copy all of the found .so files to your C:\SysGCC\Raspberry\arm-linux-gnueabihf\sysroot\lib\arm-linux-gnueabihf (on Windows)
+ *    4) Be sure to use following Linker flags: (adjust the path to your system):
+ *    		-Wl,-verbose,-rpath-link,"C:\SysGCC\Raspberry\arm-linux-gnueabihf\sysroot\lib\arm-linux-gnueabihf"
+ *    5) Be sure to add the libraries you are using to the linker using -l:
+ *			such as ... -lopencv_core -lopencv_ml -lopencv_imgproc
+ *	  6) Be sure to include the library search paths using -L:
+ *	        -L"C:\SysGCC\Raspberry\arm-linux-gnueabihf\sysroot\lib\arm-linux-gnueabihf"
+ *	  7) Be sure to include OpenCV and raspicam libraries below to `include directories` in gcc using -I flag.
+ *
+ *	  IMPORTANT!: For this task to run, camera stream or any other processes that use the raspberry pi camera should be deactivated!
+ *
+ */
+
+#include <tasks/image_processing_task.h>
+
+#include <ctime>
+#include <wiringPi.h>
+#include <unistd.h>
+#include <libraries/timing/timing.h>
+#include <api/basic_psys_rover.h>
+#include <interfaces.h>
+#include <pthread.h>
+
+#include <libraries/pthread_monitoring/collect_thread_name.h>
+#include <roverapp.h>
+
+#include <iostream>
+#include <fstream>
+
+/* OpenCV 2.4.9 libraries, Includes (-I) are in /workspace, include paths are specified for "g++"!! */
+#include <opencv2/highgui/highgui.hpp>
+#include <opencv2/core/core.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <opencv2/opencv.hpp>
+
+/* raspicam-0.1.3 libraries, Includes (-I) are in /workspace, include paths are specified for "g++"!! */
+#include <raspicam.h>
+#include <raspicam_cv.h>
+
+using namespace cv;
+using namespace std;
+
+void *Image_Processing_Task(void *arg)
+{
+	timing imgproc_task_tmr;
+
+	CollectThreadName("Image_Processing_Task");
+
+	imgproc_task_tmr.setTaskID("ImgPr");
+	imgproc_task_tmr.setDeadline(1);
+	imgproc_task_tmr.setPeriod(1);
+
+	/*
+	char key;
+	char* output_window_name = "Camera Output";
+	char* grayscale_window_name = "Grayscale Image";
+	char* thresholded_window_name = "Thresholded Image";
+	char* contours_window_name = "Contours Image";
+
+	int first_time_cmp = 1;
+
+	int canny_lowthreshold = 20;
+	int canny_highthreshold = 50;
+	int width_bound = 16;//5
+	int height_bound = 16;//5
+	int solidity_bound = 9;
+	int max_val = 200;
+	int float_max_val = 30;
+	int color_max_val = 256;
+
+	//Orange
+	int u_h=0;//0;//0;//0;  //0
+	int u_s=177;//148;//102;//134;//120; //197
+	int u_v=178;//149;//220;//212;//120; //189
+	int d_h=203;//5;//256;//256; //9
+	int d_s=256;//256; //256
+	int d_v=256;//256; //256
+
+	int up_aspectRatio = 26;
+	int down_aspectRatio = 15;
+	int aspect_max_val = 50;
+	RNG rng(12345);
+
+	int detections_w[10];
+	int detections_h[10];
+	int detections_x[10];
+	int detections_y[10];
+	double  detections_wh[10];
+	int detection_count = 0;
+
+	int send_flag = 0;
+
+	namedWindow(output_window_name, CV_WINDOW_AUTOSIZE);
+	namedWindow(grayscale_window_name, 100);
+	namedWindow(thresholded_window_name, 100);
+	namedWindow(contours_window_name, 100);
+
+	moveWindow(grayscale_window_name, 20,20);
+	moveWindow(thresholded_window_name, 20, 250);
+	moveWindow(contours_window_name, 20, 600);
+
+
+	vector<int> compression_params;
+	compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
+	compression_params.push_back(100);
+
+	raspicam::RaspiCam_Cv Camera;
+	//Camera.set (CV_CAP_PROP_FORMAT, CV_8UC3);//CV_BGR2HSV); // Original format in Raspicam -> CV_8UC1);
+	if (!Camera.open()){
+		printf("Camera failed to open!\n");
+		abort();
+	}
+
+	Mat frame;
+	Mat frameRGB;
+	Mat imgGrayScale;
+	Mat imgHsv;
+	Mat imgRedThresh;
+	Mat imgWhiteThresh;
+	Mat imgResultingThresh;
+	Mat edges;
+	vector< vector<Point> > contours;
+	vector< Vec4i > hierarchy;
+	vector<Point> approx;
+	vector<Point> tempCont;
+	vector<vector<Point> > tempVecCont;
+	double contPeri;
+	Rect bBox;
+	double aspectRatio;
+
+	double area;
+	double hullArea;
+	double solidity;
+
+	int opening_length;
+	int opening_midpoint;
+
+	double maximum ;
+	double second_maximum ;
+	double third_maximum;
+	int maximum_idx ;
+	int second_maximum_idx ;
+	int third_maximum_idx;
+	double second_last_maximum;
+	double last_maximum;
+
+	int counter = 0;
+	int counter_max = 1;
+	//createTrackbar("canny low Threshold: ", output_window_name, &canny_lowthreshold, max_val, canny);
+	//createTrackbar("canny high Threshold: ", output_window_name, &canny_highthreshold, max_val, canny);
+	//createTrackbar("height: ", output_window_name, &height_bound, float_max_val, canny);
+	//createTrackbar("width: ", output_window_name, &width_bound, float_max_val, canny);
+	//createTrackbar("solidity: ", output_window_name, &solidity_bound, float_max_val, canny);
+	//createTrackbar("Up AspectRatio: ", output_window_name, &up_aspectRatio, aspect_max_val, canny);
+	//createTrackbar("Down AspectRatio: ", output_window_name, &down_aspectRatio, aspect_max_val, canny);
+	//createTrackbar("Up H: ", output_window_name, &u_h, color_max_val, canny);
+	//createTrackbar("Up S: ", output_window_name, &u_s, color_max_val, canny);
+	//createTrackbar("Up v: ", output_window_name, &u_v, color_max_val, canny);
+	//createTrackbar("Down H: ", output_window_name, &d_h, color_max_val, canny);
+	//createTrackbar("Down S: ", output_window_name, &d_s, color_max_val, canny);
+	//createTrackbar("Down v: ", output_window_name, &d_v, color_max_val, canny);
+*/
+
+	while (1)
+	{
+		imgproc_task_tmr.recordStartTime();
+		imgproc_task_tmr.calculatePreviousSlackTime();
+
+		//Task content starts here -----------------------------------------------
+/*
+		//Capture image with Raspicam_CV
+		Camera.grab();
+		Camera.retrieve(frame);  //cap >> frame
+
+		//cv::imwrite("raspicam_img.jpg", frame);
+
+		//printf("Starting...\n");
+		//key = waitKey(10);
+		//cout <<(int) char(key) << endl;
+		//if(char(key) == 27){
+		//    break;
+		//}
+		// if(char(key) == 10){
+
+		frameRGB.create(frame.size(), frame.type());
+		cvtColor(frame, frameRGB, CV_BGR2RGB);
+
+		imgHsv.create(frameRGB.size(), frameRGB.type());
+		cvtColor(frameRGB, imgHsv, CV_RGB2HSV);//HSV
+
+		//cv::imwrite("raspicam_img.jpg", imgHsv);
+
+		inRange(imgHsv, Scalar(u_h, u_s, u_v), Scalar(d_h, d_s, d_v), imgRedThresh);
+
+		//converting the original image into grayscale
+		imgGrayScale.create(frame.size(), frame.type());
+		cvtColor(frame, imgGrayScale, CV_BGR2GRAY);
+		bitwise_and(imgRedThresh, imgGrayScale, imgGrayScale);
+
+		// Floodfill from point (0, 0)
+		Mat im_floodfill = imgGrayScale.clone();
+		floodFill(im_floodfill, cv::Point(0,0), Scalar(255));
+
+		// Invert floodfilled image
+		Mat im_floodfill_inv;
+		bitwise_not(im_floodfill, im_floodfill_inv);
+
+		// Combine the two images to get the foreground.
+		imgGrayScale = (imgGrayScale | im_floodfill_inv);
+
+		GaussianBlur(imgGrayScale, imgGrayScale, Size(7,7), 1.5, 1.5);
+
+		//imshow(grayscale_window_name, imgGrayScale);
+
+		edges.create(imgGrayScale.size(), imgGrayScale.type());
+		Canny(imgGrayScale, edges, canny_lowthreshold, canny_highthreshold, 3);
+
+		findContours(edges, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));
+		Mat drawing = Mat::zeros(edges.size(), CV_8UC3);
+
+		//For all contours
+		for(int i=0 ; i<contours.size() ; i++){
+			contPeri = arcLength(contours.at(i), true);
+			approxPolyDP(contours.at(i), approx,  0.01 * contPeri, true);
+
+			//if(approx.size()>=7 && approx.size()<=9){
+			bBox = boundingRect(approx);
+			aspectRatio = bBox.width/bBox.height;
+
+			area = contourArea(contours.at(i));
+			convexHull(contours.at(i), tempCont);
+			hullArea = contourArea(tempCont);
+			solidity = area / hullArea;
+
+			// cout << "contour : " << approx.size() << endl;
+			// cout << bBox.width << "::" << bBox.height << "::" << solidity  << "::" << aspectRatio <<endl;
+
+			tempVecCont.clear();
+			tempVecCont.push_back(approx);
+
+			if(bBox.width > width_bound && bBox.height > height_bound && solidity > solidity_bound/10 )
+			{
+				//Find detections
+				//printf("%d\t%d\n",bBox.width, bBox.height);
+				detections_x[detection_count] = bBox.x;
+				detections_y[detection_count] = bBox.y;
+				detections_w[detection_count] = bBox.width;
+				detections_h[detection_count] = bBox.height;
+				detections_wh[detection_count] = bBox.width*bBox.height;
+				detection_count = detection_count + 1;
+
+				//Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));
+				//drawContours(drawing, tempVecCont, 0, color, 2, 8, hierarchy, 0, Point());
+				//rectangle( drawing, Point( bBox.x, bBox.y), Point( bBox.x+bBox.width, bBox.y+bBox.height), Scalar( 0, 55, 255 ), +4, 4 );
+			}
+			//}
+
+		}
+		//First we shall select the biggest two boxes, having biggest w x h.
+		maximum = detections_wh[0];
+		second_maximum = detections_wh[0];
+		third_maximum = detections_wh[0];
+		maximum_idx = 0;
+		second_maximum_idx = 0;
+		third_maximum_idx = 0;
+		int c;
+		for (c = 0; c < detection_count; c++)
+		{
+			if (detections_wh[c] > maximum)
+			{
+				third_maximum = second_maximum;
+				third_maximum_idx = second_maximum_idx;
+				second_maximum = maximum;
+				second_maximum_idx = maximum_idx;
+				maximum  = detections_wh[c];
+				maximum_idx = c;
+			}
+		}
+
+		if(maximum > 10000 || second_maximum > 10000 || third_maximum > 10000) //was 3000
+		{
+			send_flag = 1;
+			//Clear detection width*height array after command is sent
+			for (c = 0; c<detection_count; c++)
+			{
+				detections_wh[c] = 0;
+			}
+		}
+		else
+		{
+			ofstream myfile;
+			myfile.open("../../logs/image_processing/detection.inc");
+			myfile << "undetected";
+			myfile.close();
+		}
+		second_last_maximum = second_maximum;
+		last_maximum = maximum;
+
+
+		if(send_flag == 1){
+
+			printf("CONTOUR DETECTED\n");
+			counter = 0;
+			send_flag = 0;
+		}
+
+
+
+		counter++;
+		*/
+
+		//Task content ends here -------------------------------------------------
+
+		imgproc_task_tmr.recordEndTime();
+		imgproc_task_tmr.calculateExecutionTime();
+		imgproc_task_tmr.calculateDeadlineMissPercentage();
+		imgproc_task_tmr.incrementTotalCycles();
+		pthread_mutex_lock(&imgproc_task_ti_l);
+			imgproc_task_ti.deadline = imgproc_task_tmr.getDeadline();
+			imgproc_task_ti.deadline_miss_percentage = imgproc_task_tmr.getDeadlineMissPercentage();
+			imgproc_task_ti.execution_time = imgproc_task_tmr.getExecutionTime();
+			imgproc_task_ti.period = imgproc_task_tmr.getPeriod();
+			imgproc_task_ti.prev_slack_time = imgproc_task_tmr.getPrevSlackTime();
+			imgproc_task_ti.task_id = imgproc_task_tmr.getTaskID();
+			imgproc_task_ti.start_time = imgproc_task_tmr.getStartTime();
+			imgproc_task_ti.end_time = imgproc_task_tmr.getEndTime();
+		pthread_mutex_unlock(&imgproc_task_ti_l);
+		imgproc_task_tmr.sleepToMatchPeriod();
+	}
+
+	// Destroy the screens
+	/*destroyWindow(output_window_name);
+	destroyWindow(thresholded_window_name);
+	destroyWindow(grayscale_window_name);
+	destroyWindow(contours_window_name);*/
+
+	//Close raspicam
+	//cap.release(); --> In webcam
+	/*Camera.release();*/
+
+	/* the function must return something - NULL will do */
+	return NULL;
+}
diff --git a/rover/src/tasks/socket_client_task.cpp b/rover/src/tasks/socket_client_task.cpp
new file mode 100644
index 0000000..7775c3a
--- /dev/null
+++ b/rover/src/tasks/socket_client_task.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *     Socket client for rover-app to rover-web communication
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created 26.10.2017
+ *
+ */
+
+#include <tasks/socket_client_task.h>
+
+#include <wiringPi.h>
+#include <unistd.h>
+#include <ctime>
+#include <libraries/timing/timing.h>
+#include <api/basic_psys_rover.h>
+#include <interfaces.h>
+#include <pthread.h>
+
+#include <libraries/pthread_monitoring/collect_thread_name.h>
+#include <roverapp.h>
+
+#include <unistd.h>
+#include <string.h>
+
+/* Signal header */
+#include <signal.h>
+
+/* Socket defs header */
+#include <socket_settings.h>
+
+/* json-cpp library */
+#include <json/json.h>
+
+#include <math.h>
+
+/* Global definitions */
+int roverapp_send_sockfd;
+
+/* If returns nonzero -> socket has a non zero error status */
+int checkClientSocketStatus (int socket_fd)
+{
+	int error = 0;
+	socklen_t len = sizeof (error);
+	int retval = getsockopt (socket_fd, SOL_SOCKET, SO_ERROR, &error, &len);
+	return error;
+}
+
+Json::Value constructJSONData (int data_type)
+{
+	Json::Value data;
+	switch (data_type)
+	{
+		case SENSOR_DATA:
+			data["rover_dtype"] = "sensor";
+			data["data"]["infrared0"] = ceil(infrared_shared[0]);
+			data["data"]["infrared1"] = ceil(infrared_shared[1]);
+			data["data"]["infrared2"] = ceil(infrared_shared[2]);
+			data["data"]["infrared3"] = ceil (infrared_shared[3]);
+			data["data"]["front"] = ceil (distance_sr04_front_shared);
+			data["data"]["rear"] = ceil (distance_sr04_back_shared);
+			data["data"]["temperature"] = ceil (temperature_shared);
+			data["data"]["humidity"] = ceil (humidity_shared);
+			data["data"]["bearing"] = ceil (bearing_shared);
+			break;
+		case UTIL_DATA:
+			data["rover_dtype"] = "util";
+			data["data"]["core0"] = cpu_util_shared[0];
+			data["data"]["core1"] = cpu_util_shared[1];
+			data["data"]["core2"] = cpu_util_shared[2];
+			data["data"]["core3"] = cpu_util_shared[3];
+			break;
+		default:
+			data["rover_dtype"] = "none";
+			break;
+	}
+	return data;
+}
+
+void Socket_Client_Task_Terminator (int dummy)
+{
+	close(roverapp_send_sockfd);
+	running_flag = 0;
+}
+
+void *Socket_Client_Task (void * arg)
+{
+	timing socket_client_task_tmr;
+
+	CollectThreadName("Socket_Client_Task");
+
+	socket_client_task_tmr.setTaskID("Socket_Client_Task");
+	socket_client_task_tmr.setDeadline(0.8);
+	socket_client_task_tmr.setPeriod(0.8);
+
+	/* Add termination signal handler to properly close socket */
+	signal(SIGINT, Socket_Client_Task_Terminator);
+	signal(SIGTERM, Socket_Client_Task_Terminator);
+	signal(SIGKILL, Socket_Client_Task_Terminator);
+
+	/* Socket related initializations */
+	int n;
+	struct sockaddr_in serv_addr;
+	struct hostent *server;
+	char client_buffer[JSON_DATA_BUFSIZE];
+	char * eof_str = "\r\n";
+	int connected_flag = 0;
+
+	/* Send these data each iteration*/
+	int job_count = 2;
+	int job_list[job_count] = {SENSOR_DATA, UTIL_DATA};
+	int job_idx = 0;
+
+	/* Create JSON object to hold sensor data */
+	Json::FastWriter  string_writer;
+
+	while (running_flag)
+	{
+		socket_client_task_tmr.recordStartTime();
+		socket_client_task_tmr.calculatePreviousSlackTime();
+
+		//Task content starts here -----------------------------------------------
+		/* For Connecting / Reconnecting */
+		if (checkClientSocketStatus(roverapp_send_sockfd)!=0)
+		{
+			connected_flag = 0;
+		}
+
+		if (connected_flag == 0)
+		{
+			/* Try to connect or reconnect */
+			/* Create socket, and connect to the socket */
+			close(roverapp_send_sockfd);
+			roverapp_send_sockfd = socket(AF_INET, SOCK_STREAM, 0);
+			if (roverapp_send_sockfd < 0)
+				perror("ERROR opening socket");
+			server = gethostbyname(CONNECTION_HOSTNAME);
+			if (server == NULL) {
+				fprintf(stderr,"ERROR, no such host\n");
+				exit(0);
+			}
+			bzero((char *) &serv_addr, sizeof(serv_addr));
+			serv_addr.sin_family = AF_INET;
+			bcopy((char *)server->h_addr,
+				 (char *)&serv_addr.sin_addr.s_addr,
+				 server->h_length);
+			serv_addr.sin_port = htons(ROVERAPP_SEND_PORT);
+
+			/* Try to connect */
+			if (connect(roverapp_send_sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) == 0)
+			{
+				connected_flag = 1;
+				job_idx = 0;
+			}
+		}
+		else
+		{
+			/* Connected, start writing */
+			/* Construct the JSON data and Write to string */
+			std::string temp = string_writer.write(constructJSONData(job_list[job_idx++]));
+			if (job_idx == job_count)
+				job_idx = 0;
+
+			/* Clear buffer and Write to buffer from string */
+			bzero(client_buffer, JSON_DATA_BUFSIZE);
+			if (strncpy(client_buffer, temp.c_str(), sizeof(client_buffer)) == NULL)
+			{
+				perror("strcpy temp");
+			}
+			client_buffer[sizeof(client_buffer)-1] = 0;
+
+			/* Attach end of file character to string*/
+			if (strcat(client_buffer, eof_str) == NULL)
+			{
+				perror("strcat EOF");
+			}
+
+			/* Write to socket */
+			if (write(roverapp_send_sockfd, client_buffer, strlen(client_buffer)) == -1)
+			{
+				perror("write");
+				/* Very important approach to have re-usable socket client */
+				/* Checking connection status by using exit status of 'write' */
+				printf ("Disconnected from server : socket_client.cpp");
+				connected_flag = 0;
+			}
+		}
+
+		//Task content ends here -------------------------------------------------
+		socket_client_task_tmr.recordEndTime();
+		socket_client_task_tmr.calculateExecutionTime();
+		socket_client_task_tmr.calculateDeadlineMissPercentage();
+		socket_client_task_tmr.incrementTotalCycles();
+		pthread_mutex_lock(&socket_client_task_ti_l);
+			socket_client_task_ti.deadline = socket_client_task_tmr.getDeadline();
+			socket_client_task_ti.deadline_miss_percentage = socket_client_task_tmr.getDeadlineMissPercentage();
+			socket_client_task_ti.execution_time = socket_client_task_tmr.getExecutionTime();
+			socket_client_task_ti.period = socket_client_task_tmr.getPeriod();
+			socket_client_task_ti.prev_slack_time = socket_client_task_tmr.getPrevSlackTime();
+			socket_client_task_ti.task_id = socket_client_task_tmr.getTaskID();
+			socket_client_task_ti.start_time = socket_client_task_tmr.getStartTime();
+			socket_client_task_ti.end_time = socket_client_task_tmr.getEndTime();
+		pthread_mutex_unlock(&socket_client_task_ti_l);
+		socket_client_task_tmr.sleepToMatchPeriod();
+	}
+
+	/* the function must return something - NULL will do */
+	return NULL;
+}
+
+
+
diff --git a/rover/src/tasks/socket_server_task.cpp b/rover/src/tasks/socket_server_task.cpp
new file mode 100644
index 0000000..33ddd77
--- /dev/null
+++ b/rover/src/tasks/socket_server_task.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2017 FH Dortmund and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Description:
+ *     Socket server for rover-web to rover-app communication
+ *
+ * Contributors:
+ *    M.Ozcelikors <mozcelikors@gmail.com>, created 26.10.2017
+ *
+ */
+
+#include <tasks/socket_server_task.h>
+
+#include <string.h>
+#include <ctime>
+#include <wiringPi.h>
+#include <unistd.h>
+#include <libraries/timing/timing.h>
+#include <api/basic_psys_rover.h>
+#include <interfaces.h>
+#include <pthread.h>
+#include <softPwm.h>
+
+#include <libraries/pthread_monitoring/collect_thread_name.h>
+#include <roverapp.h>
+
+/* Signal header */
+#include <signal.h>
+
+/* Socket defs header */
+#include <socket_settings.h>
+
+/* json-cpp library */
+#include <json/json.h>
+
+/* Global definitions */
+int roverapp_listen_sockfd;
+int newroverapp_listen_sockfd;
+
+/* If returns nonzero -> socket has a non zero error status */
+int checkServerSocketStatus (int socket_fd)
+{
+	//TODO: Fix this function!
+	int error = 0;
+	socklen_t len = sizeof (error);
+	int retval = getsockopt (socket_fd, SOL_SOCKET, SO_ERROR, &error, &len);
+	return error;
+}
+
+void parseJSONData (char *server_buffer)
+{
+	Json::Value root;
+	Json::Reader reader;
+	bool parsingSuccessful = reader.parse( server_buffer, root );
+	if ( !parsingSuccessful )
+	{
+		std::cout  << "Failed to parse" << reader.getFormattedErrorMessages();
+	}
+
+	if (root["rover_dtype"].asString() == "control")
+	{
+		// Update shared variable
+		pthread_mutex_lock(&keycommand_lock);
+			//Take only the first char - since interface uses 1 char only
+			keycommand_shared = root["data"]["command"].asString()[0];
+			//printf("RECV=%c\n",keycommand_shared);
+		pthread_mutex_unlock(&keycommand_lock);
+	}
+	else if (root["rover_dtype"].asString() == "speed")
+	{
+		// Update shared variable
+		pthread_mutex_lock(&speed_lock);
+			speed_shared = root["data"]["speed"].asInt();
+			//printf("RECV=%d\n",speed_shared);
+		pthread_mutex_unlock(&speed_lock);
+	}
+	else
+	{
+		std::cout << "Unable to parse in socket_server_task.cpp" << std::endl;
+	}
+
+}
+
+void Socket_Server_Task_Terminator (int dummy)
+{
+	close(roverapp_listen_sockfd);
+	close(newroverapp_listen_sockfd);
+	running_flag = 0;
+}
+
+void *Socket_Server_Task(void * arg)
+{
+	timing socket_server_task_tmr;
+
+	CollectThreadName("Socket_Server_Task");
+
+	socket_server_task_tmr.setTaskID("Socket_Server_Task");
+	socket_server_task_tmr.setDeadline(0.05);
+	socket_server_task_tmr.setPeriod(0.05);
+
+	/* Add termination signal handler to properly close socket */
+	signal(SIGINT, Socket_Server_Task_Terminator);
+	signal(SIGTERM, Socket_Server_Task_Terminator);
+	signal(SIGKILL, Socket_Server_Task_Terminator);
+
+	socklen_t clilen;
+	char server_buffer[JSON_DATA_BUFSIZE];
+	struct sockaddr_in serv_addr, cli_addr;
+	int  n;
+	int true_ = 1;
+	int client_connected_flag = 0;
+
+	/* First call to socket() function */
+	roverapp_listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+	if (roverapp_listen_sockfd < 0) {
+		perror("ERROR opening socket");
+		exit(1);
+	}
+
+	/* Handle re-binding problems */
+	setsockopt(roverapp_listen_sockfd, SOL_SOCKET,SO_REUSEADDR,&true_,sizeof(int));
+
+	/* Initialize socket structure */
+	bzero((char *) &serv_addr, sizeof(serv_addr));
+
+	serv_addr.sin_family = AF_INET;
+	serv_addr.sin_addr.s_addr = inet_addr(BINDING_HOSTNAME);
+	serv_addr.sin_port = htons(ROVERAPP_LISTEN_PORT);
+	memset(serv_addr.sin_zero, '\0', sizeof serv_addr.sin_zero);
+
+	/* Now bind the host address using bind() call.*/
+	if (bind(roverapp_listen_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
+		perror("ERROR on binding");
+		exit(1);
+	}
+
+	/* Now start listening for the clients, here process will
+	  * go in sleep mode and will wait for the incoming connection
+	*/
+	listen(roverapp_listen_sockfd,5); // Max 5 connections queued
+	clilen = sizeof(cli_addr);
+
+	while(running_flag)
+	{
+		socket_server_task_tmr.recordStartTime();
+		socket_server_task_tmr.calculatePreviousSlackTime();
+
+		//Task content starts here -----------------------------------------------
+		/* Handle client acception or re-acception */
+		/* Checking if client socket is available */
+		if (checkServerSocketStatus(newroverapp_listen_sockfd)!=0)
+		{
+			client_connected_flag = 0;
+		}
+
+		if (client_connected_flag == 0)
+		{
+			/* If no client is connected currently */
+			/* Accept actual connection from the client */
+			newroverapp_listen_sockfd = accept(roverapp_listen_sockfd, (struct sockaddr *)&cli_addr, &clilen);
+
+			if (newroverapp_listen_sockfd < 0) {
+				perror("ERROR on accept -> newroverapp_listen_sockfd");
+				exit(1);
+			}
+			else
+			{
+				printf ("Client connected to newroverapp_listen_sockfd \n");
+				client_connected_flag = 1;
+			}
+		}
+		else
+		{
+			/* If a client is connected */
+			/* If connection is established then start communicating */
+			size_t buf_idx = 0;
+
+			/* Read one char at a time until the EOF_STR "\r\n" is reached */
+			while (buf_idx < JSON_DATA_BUFSIZE)
+			{
+				if ( 1 == read(newroverapp_listen_sockfd, &server_buffer[buf_idx], 1))
+				{
+					if (buf_idx > 0 &&  LINE_FEED == server_buffer[buf_idx] && CARRIAGE_RETURN == server_buffer[buf_idx - 1])
+					{
+						break;
+					}
+					buf_idx++;
+				}
+				else
+				{
+					/* Very important approach to have re-usable socket server */
+					/* Client connection status is determined by exit status of read */
+					printf ("Client disconnected!");
+					client_connected_flag = 0;
+					break;
+				}
+
+			}
+			// Received buffer
+			//printf ("buffer: %s\n",server_buffer);
+
+			/* Remove \r\n from at the end of the string */
+			server_buffer[buf_idx] = '\0';
+			server_buffer[buf_idx-1] = '\0';
+
+			/* Parse the JSON data, and update global variables */
+			parseJSONData(server_buffer);
+		}
+
+		//Task content ends here -------------------------------------------------
+
+		socket_server_task_tmr.recordEndTime();
+		socket_server_task_tmr.calculateExecutionTime();
+		socket_server_task_tmr.calculateDeadlineMissPercentage();
+		socket_server_task_tmr.incrementTotalCycles();
+		pthread_mutex_lock(&socket_server_task_ti_l);
+			socket_server_task_ti.deadline = socket_server_task_tmr.getDeadline();
+			socket_server_task_ti.deadline_miss_percentage = socket_server_task_tmr.getDeadlineMissPercentage();
+			socket_server_task_ti.execution_time = socket_server_task_tmr.getExecutionTime();
+			socket_server_task_ti.period = socket_server_task_tmr.getPeriod();
+			socket_server_task_ti.prev_slack_time = socket_server_task_tmr.getPrevSlackTime();
+			socket_server_task_ti.task_id = socket_server_task_tmr.getTaskID();
+			socket_server_task_ti.start_time = socket_server_task_tmr.getStartTime();
+			socket_server_task_ti.end_time = socket_server_task_tmr.getEndTime();
+		pthread_mutex_unlock(&socket_server_task_ti_l);
+		socket_server_task_tmr.sleepToMatchPeriod();
+
+	}
+}