/** * 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); } } } }
void *mode4_init(void *aldl_in) { aldl = (aldl_conf_t *)aldl_in; /* sanity check pcm address to avoid using this with wrong ecm */ if(aldl->comm->pcm_address != 0xF4) { error(EFATAL, ERROR_PLUGIN, "MODE4 Special plugin is for EE only."); }; /* allocate main message buffer for log entries */ msgbuf = malloc(sizeof(char) * MSGBUFSIZE); /* initialize root window */ WINDOW *root; if((root = initscr()) == NULL) { error(1,ERROR_NULL,"could not init ncurses"); } curs_set(0); /* remove cursor */ cbreak(); /* dont req. line break for input */ nodelay(root,true); /* non-blocking input */ noecho(); /* configure colors (even though this doesn't use much color) */ start_color(); init_pair(RED_ON_BLACK,COLOR_RED,COLOR_BLACK); init_pair(BLACK_ON_RED,COLOR_BLACK,COLOR_RED); init_pair(GREEN_ON_BLACK,COLOR_GREEN,COLOR_BLACK); init_pair(CYAN_ON_BLACK,COLOR_CYAN,COLOR_BLACK); init_pair(WHITE_ON_BLACK,COLOR_WHITE,COLOR_BLACK); init_pair(WHITE_ON_RED,COLOR_WHITE,COLOR_RED); /* fetch indexes (saves repeated lookups) */ p_idx.rpm = get_index_by_name(aldl,"RPM"); p_idx.idletarget = get_index_by_name(aldl,"IDLESPD"); p_idx.iacsteps = get_index_by_name(aldl,"IAC"); p_idx.cooltemp = get_index_by_name(aldl,"COOLTMP"); p_idx.map = get_index_by_name(aldl,"MAP"); p_idx.adv = get_index_by_name(aldl,"ADV"); p_idx.kr = get_index_by_name(aldl,"KR"); /* get initial screen size */ getmaxyx(stdscr,w_height,w_width); /* wait for connection */ m4_cons_wait_for_connection(); /* prepare 'empty' mode4 command */ m4_comm_init(); while(1) { /* get newest record */ rec = newest_record_wait(aldl,rec); if(rec == NULL) { /* disconnected */ m4_cons_wait_for_connection(); continue; } /* process engine status */ get_engine_status(); erase(); /* clear screen --------- */ mvprintw(0,1,M4_USE_STRING); /* print usage */ /* print eng status */ mvprintw(2,1,"%s",print_engine_status()); m4_commrev = 0; /* reset revision bit. input handler may set it */ m4_consoleif_handle_input(); /* get keyboard input and branch */ #ifdef M4_PRINT_HEX /* print the m4 string in hex for debug */ m4_draw_cmd(1,1); #endif if(m4_commrev == 1) { /* send command if revised */ m4_comm_submit(); } refresh(); usleep(500); } sleep(4); delwin(root); endwin(); refresh(); pthread_exit(NULL); return NULL; }