static gboolean init(LXTermWindow* lxtermwin, gint argc, gchar** argv) { /* Normally, LXTerminal uses one process to control all of its windows. * The first process to start will create a Unix domain socket in * g_get_user_runtime_dir(). It will then bind and listen on this socket. * The subsequent processes will connect to the controller that owns the * Unix domain socket. They will pass their command line over the socket * and exit. * * If for any reason both the connect and bind fail, we will fall back to * having that process be standalone; it will not be either the controller * or a user of the controller. * * This function returns TRUE if this process should keep running and FALSE * if it should exit. */ /* Formulate the path for the Unix domain socket. */ #if GLIB_CHECK_VERSION (2, 28, 0) gchar * socket_path = g_strdup_printf("%s/.lxterminal-socket-%s", g_get_user_runtime_dir(), gdk_display_get_name(gdk_display_get_default())); #else gchar * socket_path = g_strdup_printf("%s/.lxterminal-socket-%s", g_get_user_cache_dir(), gdk_display_get_name(gdk_display_get_default())); #endif /* Create socket. */ int fd = socket(PF_UNIX, SOCK_STREAM, 0); if (fd < 0) { g_warning("Socket create failed: %s\n", g_strerror(errno)); goto err_socket; } /* Initialize socket address for Unix domain socket. */ struct sockaddr_un sock_addr; memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sun_family = AF_UNIX; snprintf(sock_addr.sun_path, sizeof(sock_addr.sun_path), "%s", socket_path); /* Try to connect to an existing LXTerminal process. */ if (connect(fd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) == 0) { g_free(socket_path); send_msg_to_controller(fd, argc, argv); return FALSE; } unlink(socket_path); g_free(socket_path); start_controller(&sock_addr, lxtermwin, fd); return TRUE; err_socket: g_free(socket_path); return TRUE; }
/** * Child process: Receives input from devices and responds appropriately * Responsible for adding and updating devices * Messages & Signals Parent during threshold crossing & GET/PUT commands **/ void child(){ int number_of_groups = 0; int msgid = start_controller(); group_st devices[50] = {}; message_package_st received_message; message_data_st received_data; toggle_act_message.data = toggle_act_data; // Signal Handler struct sigaction child_action; child_action.sa_handler = sigint_child_handler; sigemptyset(&child_action.sa_mask); child_action.sa_flags = 0; sigaction(SIGINT, &child_action, 0); // Device Management -- Sensors & Actuators while(1){ if ( msgrcv(msgid, (void *) &received_message, sizeof(received_message.data), 1, 0) == -1 ) { printf("\nCaught external signal interrupt.\n"); if (errno == EINTR) { continue; } else { fprintf(stderr, "Message Received failed with Error: %d\n", errno); exit(EXIT_FAILURE); } } received_data = received_message.data; int device_index = get_index_by_pid(devices, number_of_groups, received_data.pid); int name_index = get_index_by_name(devices, number_of_groups, received_data.name, SENSOR); // Stop everything --> Shut down Sensors, Actuators, and Controller if (received_data.command == STOP) { stop_system(msgid, devices, number_of_groups); } // Add new device --> No group exists else if (received_data.command == START && name_index == -1 && number_of_groups < 50){ int new_index = number_of_groups; number_of_groups++; printf("\nNew Device\nGroup: %s Threshold: %d\n\n", received_data.name, received_data.current_value); strcpy(devices[new_index].sensor_name, received_data.name); // New device is a SENSOR if (received_data.dev_type == SENSOR) { devices[new_index].sensor_pid = received_data.pid; devices[new_index].threshold = received_data.current_value; } // New device is an ACTUATOR else if (received_data.dev_type == ACTUATOR) { devices[new_index].actuator_pid = received_data.pid; devices[new_index].is_on = received_data.current_value; strcpy(devices[new_index].actuator_name, received_data.actuator_name); } } // Add new device --> Pair device with previously added actuator/sensor else if(received_data.command == START && name_index >= 0){ // New device is a SENSOR if (received_data.dev_type == SENSOR) { devices[name_index].sensor_pid = received_data.pid; devices[name_index].threshold = received_data.current_value; printf("Sensor added to \"%s\"\n\n", devices[name_index].sensor_name); } // New device is an ACTUATOR else if (received_data.dev_type == ACTUATOR) { devices[name_index].actuator_pid = received_data.pid; devices[name_index].is_on = received_data.current_value; strcpy(devices[name_index].actuator_name,received_data.actuator_name); printf("Actuator added to \"%s\"\n\n", devices[name_index].sensor_name); } } // Update Device --> Device has already been added else if (received_data.command == UPDATE && device_index >= 0) { if (received_data.dev_type == SENSOR) { devices[device_index].sensor_value = received_data.current_value; // Check Threshold and Actuator status (Actuator must exist) if (devices[device_index].actuator_pid != 0) { if (received_data.current_value >= devices[device_index].threshold && devices[device_index].is_on == ON) { update_actuator(msgid, devices, device_index, OFF, received_data.current_value); } else if (received_data.current_value < devices[device_index].threshold && devices[device_index].is_on == OFF) { update_actuator(msgid, devices, device_index, ON, received_data.current_value); } } } } // Handle GET Command else if (received_data.command == GET && name_index != -1) { char get_cmnd_msg[BUFFER_SIZE]; if (strcmp(devices[name_index].actuator_name, "\0")) { sprintf(get_cmnd_msg, "\nSensor %s with Current Value %d, paired with Actuator %s\n", devices[name_index].sensor_name, devices[name_index].sensor_value, devices[name_index].actuator_name ); notify_parent(msgid, get_cmnd_msg); } } // Handle PUT Command else if (received_data.command == PUT) { char put_cmnd_msg[BUFFER_SIZE]; int actuator_index = get_index_by_name(devices, number_of_groups, received_data.actuator_name, ACTUATOR); if(actuator_index != -1){ if (devices[actuator_index].is_on) { sprintf(put_cmnd_msg, "\nUser turned OFF Actuator %s\n", devices[actuator_index].actuator_name); printf("\nUser turned OFF Actuator %s\n", devices[actuator_index].actuator_name); devices[actuator_index].is_on = OFF; toggle_actuator(msgid, devices, actuator_index, OFF); } else { sprintf(put_cmnd_msg, "\nUser turned ON Actuator %s\n", devices[actuator_index].actuator_name); printf("\nUser turned ON Actuator %s\n", devices[actuator_index].actuator_name); devices[actuator_index].is_on = ON; toggle_actuator(msgid, devices, actuator_index, ON); } notify_parent(msgid, put_cmnd_msg); } } } }
/** * Entry point. */ int main(int argc, char **argv) { // Parse program options char *config_file = NULL; bool server = false; bool collector = false; bool callibrator = false; bool status_only = false; int log_option = 0; char c; while ((c = getopt(argc, argv, "hc:sdflr")) != EOF) { switch (c) { case 'h': { show_help(argv[0]); return 1; } case 'c': config_file = strdup(optarg); break; case 's': status_only = true; break; case 'd': server = true; break; case 'l': collector = true; break; case 'r': callibrator = true; break; case 'f': log_option |= LOG_PERROR; break; default: { fprintf(stderr, "ERROR: Invalid option %c!\n", c); show_help(argv[0]); return 1; } } } if (config_file == NULL) config_file = strdup("/etc/koruza.cfg"); // Load the configuration file struct ucl_parser *parser = ucl_parser_new(UCL_PARSER_KEY_LOWERCASE); ucl_object_t *config = NULL; ucl_object_t *obj = NULL; int ret_value = 0; if (!parser) { fprintf(stderr, "ERROR: Failed to initialize configuration parser!\n"); return 2; } if (!ucl_parser_add_file(parser, config_file)) { fprintf(stderr, "ERROR: Failed to parse configuration file '%s'!\n", config_file); fprintf(stderr, "ERROR: %s\n", ucl_parser_get_error(parser)); ret_value = 2; goto cleanup_exit; } else { config = ucl_parser_get_object(parser); } if (server) { obj = ucl_object_find_key(config, "server"); if (!obj) { fprintf(stderr, "ERROR: Missing server configuration!\n"); ret_value = 2; goto cleanup_exit; } start_server(obj, log_option); } else if (collector) { start_collector(config, log_option); } else if (callibrator) { start_callibrator(config, log_option); } else { start_controller(config, status_only); } cleanup_exit: // Cleanup and exit if (config) ucl_object_free(config); if (parser) ucl_parser_free(parser); return ret_value; }