static bool receive_and_queue_message(dsmesock_connection_t* conn) { bool keep_connection = true; DSM_MSGTYPE_SET_LOGGING_VERBOSITY* logging; dsmemsg_generic_t* msg; msg = (dsmemsg_generic_t*)dsmesock_receive(conn); if (msg) { broadcast_internally_from_socket(msg, conn); if (DSMEMSG_CAST(DSM_MSGTYPE_CLOSE, msg)) { keep_connection = false; } else if ((logging = DSMEMSG_CAST(DSM_MSGTYPE_SET_LOGGING_VERBOSITY, msg))) { dsme_log_set_verbosity(logging->verbosity); } free(msg); } return keep_connection; }
int main(void) { dsmesock_connection_t* dsme_conn; fd_set rfds; DSM_MSGTYPE_STATE_QUERY req_msg = DSME_MSG_INIT(DSM_MSGTYPE_STATE_QUERY); dsmemsg_generic_t* msg; DSM_MSGTYPE_STATE_CHANGE_IND* msg2; int ret; dsme_conn = dsmesock_connect(); if (dsme_conn == 0) { fprintf(stderr, "dsmesock_connect\n"); return state; } /* Sending a query if the original message has already gone by */ dsmesock_send(dsme_conn, &req_msg); while (1) { struct timeval tv; tv.tv_sec = DSME_STATE_TIMEOUT; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET(dsme_conn->fd, &rfds); ret = select(dsme_conn->fd + 1, &rfds, NULL, NULL, &tv); if (ret == -1) { fprintf(stderr, "error in select()\n"); printf("MALF"); return EXIT_FAILURE; } if (ret == 0) { fprintf(stderr, "Timeout!\n"); printf("MALF"); return EXIT_FAILURE; } msg = (dsmemsg_generic_t*)dsmesock_receive(dsme_conn); if ((msg2 = DSMEMSG_CAST(DSM_MSGTYPE_STATE_CHANGE_IND, msg)) != 0) { fprintf(stderr, "received state:%i\n", msg2->state); switch (msg2->state) { case DSME_STATE_ACTDEAD: printf("ACTDEAD"); return EXIT_SUCCESS; case DSME_STATE_USER: printf("USER"); return EXIT_SUCCESS; case DSME_STATE_TEST: printf("TEST"); return EXIT_SUCCESS; case DSME_STATE_LOCAL: printf("LOCAL"); return EXIT_SUCCESS; case DSME_STATE_MALF: printf("MALF"); return EXIT_SUCCESS; case DSME_STATE_SHUTDOWN: printf("SHUTDOWN"); return EXIT_SUCCESS; case DSME_STATE_BOOT: printf("BOOT"); return EXIT_SUCCESS; default: fprintf(stderr, "unknown state: %d\n", msg2->state); break; } } else { fprintf(stderr, "The received message wasn't state change indication\n"); } free(msg); } return EXIT_FAILURE; }
/** * Callback for pending I/O from dsmesock * * XXX: is the error policy reasonable? * * @param source Unused * @param condition Unused * @param data Unused * @return TRUE on success, FALSE on failure */ static gboolean mce_dsme_iowatch_cb(GIOChannel *source, GIOCondition condition, gpointer data) { gboolean keep_going = TRUE; dsmemsg_generic_t *msg = 0; DSM_MSGTYPE_STATE_CHANGE_IND *msg2; (void)source; (void)data; if( condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL) ) { if( !mce_dsme_shutting_down() ) mce_log(LL_CRIT, "DSME socket hangup/error"); keep_going = FALSE; goto EXIT; } if( !(msg = dsmesock_receive(mce_dsme_connection)) ) goto EXIT; if( DSMEMSG_CAST(DSM_MSGTYPE_CLOSE, msg) ) { if( !mce_dsme_shutting_down() ) mce_log(LL_WARN, "DSME socket closed"); keep_going = FALSE; } else if( DSMEMSG_CAST(DSM_MSGTYPE_PROCESSWD_PING, msg) ) { mce_dsme_send_pong(); } else if( (msg2 = DSMEMSG_CAST(DSM_MSGTYPE_STATE_CHANGE_IND, msg)) ) { system_state_t prev = system_state; system_state = mce_dsme_normalise_system_state(msg2->state); mce_log(LL_DEVEL, "DSME device state change: %d", system_state); /* If we're changing to a different state, * add the transition flag, UNLESS the old state * was MCE_STATE_UNDEF */ if( system_state != prev && prev != MCE_STATE_UNDEF ) mce_add_submode_int32(MCE_TRANSITION_SUBMODE); switch (system_state) { case MCE_STATE_USER: execute_datapipe_output_triggers(&led_pattern_activate_pipe, MCE_LED_PATTERN_DEVICE_ON, USE_INDATA); break; case MCE_STATE_ACTDEAD: case MCE_STATE_BOOT: case MCE_STATE_UNDEF: break; case MCE_STATE_SHUTDOWN: case MCE_STATE_REBOOT: execute_datapipe_output_triggers(&led_pattern_deactivate_pipe, MCE_LED_PATTERN_DEVICE_ON, USE_INDATA); break; default: break; } mce_log(LL_DEVEL, "system_state: %s -> %s", system_state_repr(prev), system_state_repr(system_state)); execute_datapipe(&system_state_pipe, GINT_TO_POINTER(system_state), USE_INDATA, CACHE_INDATA); } else { mce_log(LL_DEBUG, "Unhandled message type %s (0x%x) received from DSME", mce_dsme_msg_type_repr(msg->type_), msg->type_); /* <- unholy access of a private member */ } EXIT: free(msg); if( !keep_going ) { if( !mce_dsme_shutting_down() ) { mce_log(LL_WARN, "DSME i/o notifier disabled;" " assuming dsme was stopped"); } /* mark notifier as removed */ mce_dsme_iowatch_id = 0; /* close and wait for possible dsme restart */ mce_dsme_disconnect(); } return keep_going; }
/** * Callback for pending I/O from dsmesock * * XXX: is the error policy reasonable? * * @param source Unused * @param condition Unused * @param data Unused * @return TRUE on success, FALSE on failure */ static gboolean io_data_ready_cb(GIOChannel *source, GIOCondition condition, gpointer data) { dsmemsg_generic_t *msg; DSM_MSGTYPE_STATE_CHANGE_IND *msg2; system_state_t oldstate = datapipe_get_gint(system_state_pipe); system_state_t newstate = MCE_STATE_UNDEF; (void)source; (void)condition; (void)data; if (dsme_disabled == TRUE) goto EXIT; if ((msg = (dsmemsg_generic_t *)dsmesock_receive(dsme_conn)) == NULL) goto EXIT; if (DSMEMSG_CAST(DSM_MSGTYPE_CLOSE, msg)) { /* DSME socket closed: try once to reopen; * if that fails, exit */ mce_log(LL_ERR, "DSME socket closed; trying to reopen"); if ((init_dsmesock()) == FALSE) { // FIXME: this is not how one should exit from mainloop mce_quit_mainloop(); exit(EXIT_FAILURE); } } else if (DSMEMSG_CAST(DSM_MSGTYPE_PROCESSWD_PING, msg)) { dsme_send_pong(); } else if ((msg2 = DSMEMSG_CAST(DSM_MSGTYPE_STATE_CHANGE_IND, msg))) { newstate = normalise_dsme_state(msg2->state); mce_log(LL_DEBUG, "DSME device state change: %d", newstate); /* If we're changing to a different state, * add the transition flag, UNLESS the old state * was MCE_STATE_UNDEF */ if ((oldstate != newstate) && (oldstate != MCE_STATE_UNDEF)) mce_add_submode_int32(MCE_TRANSITION_SUBMODE); switch (newstate) { case MCE_STATE_USER: execute_datapipe_output_triggers(&led_pattern_activate_pipe, MCE_LED_PATTERN_DEVICE_ON, USE_INDATA); break; case MCE_STATE_ACTDEAD: case MCE_STATE_BOOT: case MCE_STATE_UNDEF: break; case MCE_STATE_SHUTDOWN: case MCE_STATE_REBOOT: execute_datapipe_output_triggers(&led_pattern_deactivate_pipe, MCE_LED_PATTERN_DEVICE_ON, USE_INDATA); break; default: break; } execute_datapipe(&system_state_pipe, GINT_TO_POINTER(newstate), USE_INDATA, CACHE_INDATA); } else { mce_log(LL_DEBUG, "Unknown message type (%x) received from DSME!", msg->type_); /* <- unholy access of a private member */ } free(msg); EXIT: return TRUE; }