예제 #1
0
파일: mce.c 프로젝트: spiiroin/mce
/**
 * Main
 *
 * @param argc Number of command line arguments
 * @param argv Array with command line arguments
 * @return 0 on success, non-zero on failure
 */
int main(int argc, char **argv)
{
	int status = EXIT_FAILURE;

	/* Set the program-name */
	progname = PRG_NAME;

	/* Parse the command-line options */
	if( !mce_command_line_parse(options, argc, argv) )
		goto EXIT;

	/* We don't take any non-flag arguments */
	if ((argc - optind) > 0) {
		fprintf(stderr, "%s: Too many arguments\n"
			"Try: `%s --help' for more information.\n",
			progname, progname);
		exit(EXIT_FAILURE);
	}

	mce_log_open(PRG_NAME, LOG_DAEMON, mce_args.logtype);
	mce_log_set_verbosity(mce_args.verbosity);

#ifdef ENABLE_WAKELOCKS
	/* Since mce enables automatic suspend, we must try to
	 * disable it when mce process exits */
	atexit(mce_cleanup_wakelocks);

	/* Allow acquiring of multiplexed wakelock */
	mce_wakelock_init();
#endif

	/* Identify mce version & flavor on start up */
	mce_log(LL_WARN, "MCE %s (%s) starting up",
		G_STRINGIFY(PRG_VERSION),
		(LL_DEVEL == LL_EXTRA) ? "devel" : "release");

	/* Daemonize if requested */
	if( mce_args.daemonflag )
		daemonize();

	/* Register a mainloop */
	mainloop = g_main_loop_new(NULL, FALSE);

	/* Signal handlers can be installed once we have a mainloop */
	if( !mce_init_signal_pipe() ) {
		mce_log(LL_CRIT, "Failed to initialise signal pipe");
		exit(EXIT_FAILURE);
	}
	mce_signal_handlers_install();

	/* Initialise subsystems */

	/* Get configuration options */
	if( !mce_conf_init() ) {
		mce_log(LL_CRIT,
			"Failed to initialise configuration options");
		exit(EXIT_FAILURE);
	}

	/* Open fbdev as early as possible */
	mce_fbdev_init();

	/* Start worker thread */
	if( !mce_worker_init() )
		goto EXIT;

	/* Initialise D-Bus */
	if( !mce_dbus_init(mce_args.systembus) ) {
		mce_log(LL_CRIT,
			"Failed to initialise D-Bus");
		exit(EXIT_FAILURE);
	}

	/* Initialise GConf
	 * pre-requisite: g_type_init()
	 */
	if (mce_setting_init() == FALSE) {
		mce_log(LL_CRIT,
			"Cannot connect to default GConf engine");
		exit(EXIT_FAILURE);
	}

	/* Setup all datapipes */
	mce_datapipe_init();

	/* Allow registering of suspend proof timers */
	mce_hbtimer_init();

	/* Allow registering of suspend blocking timers */
	mce_wltimer_init();

	/* Initialise mode management
	 * pre-requisite: mce_setting_init()
	 * pre-requisite: mce_dbus_init()
	 */
	if (mce_mode_init() == FALSE) {
		goto EXIT;
	}

	/* Initialise DSME
	 * pre-requisite: mce_setting_init()
	 * pre-requisite: mce_dbus_init()
	 * pre-requisite: mce_mce_init()
	 */
	if( !mce_dsme_init() )
		goto EXIT;

	/* Initialise powerkey driver */
	if (mce_powerkey_init() == FALSE) {
		goto EXIT;
	}

	/* Initialise /dev/input driver
	 * pre-requisite: g_type_init()
	 */
	if (mce_input_init() == FALSE) {
		goto EXIT;
	}

	/* Initialise switch driver */
	if (mce_switches_init() == FALSE) {
		goto EXIT;
	}

	/* Initialise tklock driver */
	if (mce_tklock_init() == FALSE) {
		goto EXIT;
	}

	if( !mce_sensorfw_init() ) {
		goto EXIT;
	}

	if( !mce_common_init() )
		goto EXIT;

	/* Load all modules */
	if (mce_modules_init() == FALSE) {
		goto EXIT;
	}

	if( mce_args.show_module_info ) {
		mce_modules_dump_info();
		goto EXIT;
	}

	/* MCE startup succeeded */
	status = EXIT_SUCCESS;

	/* Tell systemd that we have started up */
	if( mce_args.systemd_notify ) {
		mce_log(LL_NOTICE, "notifying systemd");
		sd_notify(0, "READY=1");
	}
	/* Debug feature: exit after startup is finished */
	if( mce_args.auto_exit >= 0 ) {
		mce_log(LL_WARN, "auto-exit scheduled");
		g_idle_add(mce_auto_exit_cb, 0);
	}

	/* Use timerfd to detect resume from suspend */
	mce_io_init_resume_timer();

	/* Run the main loop */
	g_main_loop_run(mainloop);

	/* If we get here, the main loop has terminated;
	 * either because we requested or because of an error
	 */
EXIT:
	mce_io_quit_resume_timer();

	/* Unload all modules */
	mce_modules_exit();

	mce_common_quit();

	/* Call the exit function for all components */
	mce_sensorfw_quit();
	mce_tklock_exit();
	mce_switches_exit();
	mce_input_exit();
	mce_powerkey_exit();
	mce_dsme_exit();
	mce_mode_exit();
	mce_wltimer_quit();
	mce_hbtimer_quit();

	/* Free all datapipes */
	mce_datapipe_quit();

	/* Call the exit function for all subsystems */
	mce_setting_exit();
	mce_dbus_exit();
	mce_conf_exit();
	mce_worker_quit();
	mce_fbdev_quit();

	/* If the mainloop is initialised, unreference it */
	if (mainloop != NULL) {
		g_main_loop_unref(mainloop);
		mainloop = 0;
	}

	/* Close signal pipe & remove io watch for it */
	mce_quit_signal_pipe();

	/* Release multiplexed wakelock */
	mce_wakelock_quit();

	/* Log a farewell message and close the log */
	mce_log(LL_INFO, "Exiting...");

	/* No more logging expected */
	mce_log_close();

	return status;
}
예제 #2
0
파일: mce.c 프로젝트: ClementFan/mce
/**
 * Main
 *
 * @param argc Number of command line arguments
 * @param argv Array with command line arguments
 * @return 0 on success, non-zero on failure
 */
int main(int argc, char **argv)
{
	int optc;
	int opt_index;

	int verbosity = LL_DEFAULT;
	int logtype   = MCE_LOG_SYSLOG;

	gint status = EXIT_FAILURE;
	gboolean show_module_info = FALSE;
	gboolean daemonflag = FALSE;
	gboolean systembus = TRUE;
	gboolean debugmode = FALSE;

	const char optline[] = "dsTSMDqvhVt:";

	struct option const options[] = {
		{ "daemonflag",       no_argument,       0, 'd' },
		{ "force-syslog",     no_argument,       0, 's' },
		{ "force-stderr",     no_argument,       0, 'T' },
		{ "session",          no_argument,       0, 'S' },
		{ "show-module-info", no_argument,       0, 'M' },
		{ "debug-mode",       no_argument,       0, 'D' },
		{ "quiet",            no_argument,       0, 'q' },
		{ "verbose",          no_argument,       0, 'v' },
		{ "help",             no_argument,       0, 'h' },
		{ "version",          no_argument,       0, 'V' },
		{ "trace",            required_argument, 0, 't' },
		{ 0, 0, 0, 0 }
        };

	/* Initialise support for locales, and set the program-name */
	if (init_locales(PRG_NAME) != 0)
		goto EXIT;

	/* Parse the command-line options */
	while ((optc = getopt_long(argc, argv, optline,
				   options, &opt_index)) != -1) {
		switch (optc) {
		case 'd':
			daemonflag = TRUE;
			break;

		case 's':
			logtype = MCE_LOG_SYSLOG;
			break;

		case 'T':
			logtype = MCE_LOG_STDERR;
			break;

		case 'S':
			systembus = FALSE;
			break;

		case 'M':
			show_module_info = TRUE;
			break;

		case 'D':
			debugmode = TRUE;
			break;

		case 'q':
			if (verbosity > LL_NONE)
				verbosity--;
			break;

		case 'v':
			if (verbosity < LL_DEBUG)
				verbosity++;
			break;

		case 'h':
			usage();
			exit(EXIT_SUCCESS);

		case 'V':
			version();
			exit(EXIT_SUCCESS);
		case 't':
			if( !mce_enable_trace(optarg) )
				exit(EXIT_FAILURE);
			break;
		default:
			usage();
			exit(EXIT_FAILURE);
		}
	}

	/* We don't take any non-flag arguments */
	if ((argc - optind) > 0) {
		fprintf(stderr,
			_("%s: Too many arguments\n"
			  "Try: `%s --help' for more information.\n"),
			progname, progname);
		exit(EXIT_FAILURE);
	}

	mce_log_open(PRG_NAME, LOG_DAEMON, logtype);
	mce_log_set_verbosity(verbosity);

#ifdef ENABLE_WAKELOCKS
	/* Since mce enables automatic suspend, we must try to
	 * disable it when mce process exits */
	atexit(mce_cleanup_wakelocks);
#endif

	/* Daemonize if requested */
	if (daemonflag == TRUE)
		daemonize();

	/* Initialise GType system */
	g_type_init();

	/* Register a mainloop */
	mainloop = g_main_loop_new(NULL, FALSE);

	/* Signal handlers can be installed once we have a mainloop */
	if( !mce_init_signal_pipe() ) {
		mce_log(LL_CRIT, "Failed to initialise signal pipe");
		exit(EXIT_FAILURE);
	}
	install_signal_handlers();

	/* Initialise subsystems */

	/* Get configuration options */
	if( !mce_conf_init() ) {
		mce_log(LL_CRIT,
			"Failed to initialise configuration options");
		exit(EXIT_FAILURE);
	}

	/* Initialise D-Bus */
	if (mce_dbus_init(systembus) == FALSE) {
		mce_log(LL_CRIT,
			"Failed to initialise D-Bus");
		mce_log_close();
		exit(EXIT_FAILURE);
	}

	/* Initialise GConf
	 * pre-requisite: g_type_init()
	 */
	if (mce_gconf_init() == FALSE) {
		mce_log(LL_CRIT,
			"Cannot connect to default GConf engine");
		mce_log_close();
		exit(EXIT_FAILURE);
	}

	/* Setup all datapipes */
	setup_datapipe(&system_state_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(MCE_STATE_UNDEF));
	setup_datapipe(&master_radio_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&call_state_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(CALL_STATE_NONE));
	setup_datapipe(&call_type_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(NORMAL_CALL));
	setup_datapipe(&alarm_ui_state_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(MCE_ALARM_UI_INVALID_INT32));
	setup_datapipe(&submode_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(MCE_NORMAL_SUBMODE));
	setup_datapipe(&display_state_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(MCE_DISPLAY_UNDEF));
	setup_datapipe(&display_brightness_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&led_brightness_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&led_pattern_activate_pipe, READ_ONLY, FREE_CACHE,
		       0, NULL);
	setup_datapipe(&led_pattern_deactivate_pipe, READ_ONLY, FREE_CACHE,
		       0, NULL);
	setup_datapipe(&key_backlight_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&keypress_pipe, READ_ONLY, FREE_CACHE,
		       sizeof (struct input_event), NULL);
	setup_datapipe(&touchscreen_pipe, READ_ONLY, FREE_CACHE,
		       sizeof (struct input_event), NULL);
	setup_datapipe(&device_inactive_pipe, READ_WRITE, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(FALSE));
	setup_datapipe(&lockkey_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&keyboard_slide_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&lid_cover_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&lens_cover_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&proximity_sensor_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&tk_lock_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(LOCK_UNDEF));
	setup_datapipe(&charger_state_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&battery_status_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(BATTERY_STATUS_UNDEF));
	setup_datapipe(&battery_level_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(100));
	setup_datapipe(&camera_button_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(CAMERA_BUTTON_UNDEF));
	setup_datapipe(&inactivity_timeout_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(DEFAULT_INACTIVITY_TIMEOUT));
	setup_datapipe(&audio_route_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(AUDIO_ROUTE_UNDEF));
	setup_datapipe(&usb_cable_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&jack_sense_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&power_saving_mode_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));
	setup_datapipe(&thermal_state_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(THERMAL_STATE_UNDEF));
	setup_datapipe(&heartbeat_pipe, READ_ONLY, DONT_FREE_CACHE,
		       0, GINT_TO_POINTER(0));

	/* Initialise mode management
	 * pre-requisite: mce_gconf_init()
	 * pre-requisite: mce_dbus_init()
	 */
	if (mce_mode_init() == FALSE) {
		goto EXIT;
	}

	/* Initialise DSME
	 * pre-requisite: mce_gconf_init()
	 * pre-requisite: mce_dbus_init()
	 * pre-requisite: mce_mce_init()
	 */
	if (mce_dsme_init(debugmode) == FALSE) {
		if (debugmode == FALSE) {
			mce_log(LL_CRIT, "Cannot connect to DSME");
			goto EXIT;
		}
	}

	/* Initialise powerkey driver */
	if (mce_powerkey_init() == FALSE) {
		goto EXIT;
	}

	/* Initialise /dev/input driver
	 * pre-requisite: g_type_init()
	 */
	if (mce_input_init() == FALSE) {
		goto EXIT;
	}

	/* Initialise switch driver */
	if (mce_switches_init() == FALSE) {
		goto EXIT;
	}

	/* Initialise tklock driver */
	if (mce_tklock_init() == FALSE) {
		goto EXIT;
	}

	/* Load all modules */
	if (mce_modules_init() == FALSE) {
		goto EXIT;
	}

	if (show_module_info == TRUE) {
		mce_modules_dump_info();
		goto EXIT;
	}

	/* MCE startup succeeded */
	status = EXIT_SUCCESS;

	/* Run the main loop */
	g_main_loop_run(mainloop);

	/* If we get here, the main loop has terminated;
	 * either because we requested or because of an error
	 */
EXIT:
	/* Unload all modules */
	mce_modules_exit();

	/* Call the exit function for all components */
	mce_tklock_exit();
	mce_switches_exit();
	mce_input_exit();
	mce_powerkey_exit();
	mce_dsme_exit();
	mce_mode_exit();

	/* Free all datapipes */
	free_datapipe(&thermal_state_pipe);
	free_datapipe(&power_saving_mode_pipe);
	free_datapipe(&jack_sense_pipe);
	free_datapipe(&usb_cable_pipe);
	free_datapipe(&audio_route_pipe);
	free_datapipe(&inactivity_timeout_pipe);
	free_datapipe(&battery_level_pipe);
	free_datapipe(&battery_status_pipe);
	free_datapipe(&charger_state_pipe);
	free_datapipe(&tk_lock_pipe);
	free_datapipe(&proximity_sensor_pipe);
	free_datapipe(&lens_cover_pipe);
	free_datapipe(&lid_cover_pipe);
	free_datapipe(&keyboard_slide_pipe);
	free_datapipe(&lockkey_pipe);
	free_datapipe(&device_inactive_pipe);
	free_datapipe(&touchscreen_pipe);
	free_datapipe(&keypress_pipe);
	free_datapipe(&key_backlight_pipe);
	free_datapipe(&led_pattern_deactivate_pipe);
	free_datapipe(&led_pattern_activate_pipe);
	free_datapipe(&led_brightness_pipe);
	free_datapipe(&display_brightness_pipe);
	free_datapipe(&display_state_pipe);
	free_datapipe(&submode_pipe);
	free_datapipe(&alarm_ui_state_pipe);
	free_datapipe(&call_type_pipe);
	free_datapipe(&call_state_pipe);
	free_datapipe(&master_radio_pipe);
	free_datapipe(&system_state_pipe);
	free_datapipe(&heartbeat_pipe);

	/* Call the exit function for all subsystems */
	mce_gconf_exit();
	mce_dbus_exit();
	mce_conf_exit();

	/* If the mainloop is initialised, unreference it */
	if (mainloop != NULL) {
		g_main_loop_unref(mainloop);
		mainloop = 0;
	}

	/* Log a farewell message and close the log */
	mce_log(LL_INFO, "Exiting...");

	/* We do not need to explicitly close the log and doing so
	 * would not allow logging from atexit handlers */
	//mce_log_close();

	return status;
}