| /* |
| * 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 <unistd.h> |
| #include <ctime> |
| #include <libraries/timing/timing.h> |
| #include <interfaces.h> |
| #include <pthread.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> |
| |
| #include <roverapp.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; |
| |
| socket_client_task_tmr.setTaskID("Socket_Client_Task"); |
| socket_client_task_tmr.setDeadline(0.5); |
| socket_client_task_tmr.setPeriod(0.5); |
| |
| /* 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; |
| } |
| |
| |
| |