int main(int argc, char *argv[])
{
	pid_t pid;
	/* Reset signal handlers */
	if (daemon_reset_sigs(-1) < 0) {
		daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s",
			strerror(errno));
		return 1;
	}
	/* Unblock signals */
	if (daemon_unblock_sigs(-1) < 0) {
		daemon_log(LOG_ERR, "Failed to unblock all signals: %s",
			strerror(errno));
	}
	/* Set indetification string for the daemon for both syslog and PID file */
	daemon_log_ident = daemon_ident_from_argv0(argv[0]);
	daemon_pid_file_ident = daemon_log_ident;
	//(LOG_ERR, "The log ident is %s\n",daemon_log_ident);
	daemon_pid_file_proc = get_pid_file_proc;
	sprintf (image_pid_file, "/var/run/%s.pid", daemon_pid_file_ident);
	/* Check if we are called with -k parameter */
	if (argc >= 2 && !strcmp(argv[1], "-k")) {
		int ret;
		/* Kill daemon with SIGTERM */
		/* Check if the new function daemon_pid_file_kill_wait() is available,
			if it is, use it. */
		if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
			daemon_log(LOG_WARNING, "Failed to kill daemon: %s",
				strerror(errno));
		return ret < 0 ? 1 : 0;
	}
	/* Check that the daemon is not rung twice a the same time */
	if ((pid = daemon_pid_file_is_running()) >= 0) {
		daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
		return 1;
	}
	/* Prepare for return value passing from the initialization procedure
		of the daemon process */
	if (daemon_retval_init() < 0) {
		daemon_log(LOG_ERR, "Failed to create pipe.");
		return 1;
	}
	/* Do the fork */
	if ((pid = daemon_fork()) < 0) {
		/* Exit on error */
		daemon_retval_done();
		return 1;
	} else if (pid) {  /* The parent */
		int ret;
		/* Wait for 20 seconds for the return value passed from the daemon
			process */
		if ((ret = daemon_retval_wait(20)) < 0) {
			daemon_log(LOG_ERR, "Count not receive return value from daemon"
				"process: %s", strerror(errno));
		}
		//daemon_log(ret != 0 ? LOG_ERR : LOG_INFO,
		//	"Daemon returned %i as return value.", ret);
		return ret;
	} else {  /* The daemon */
		int fd, quit = 0;
		fd_set fds;
		pthread_t sock_thread;
		pthread_t nl_thread;
		/* Close FDs */
		if (daemon_close_all(-1) < 0) {
			daemon_log(LOG_ERR, "Failed to close all file descriptors: %s",
				strerror(errno));
			/* Send the error condition to the parent process */
			daemon_retval_send(1);
			goto finish;
		}
		/* Create the PID file */
		if (daemon_pid_file_create() < 0) {
			daemon_log(LOG_ERR, "Could not create PID file (%s).",
				strerror(errno));
			daemon_retval_send(2);
			goto finish;
		}
		/* Initialize signal handling */
		if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
			daemon_log(LOG_ERR, "Could not register signal handlers (%s).",
				strerror(errno));
			daemon_retval_send(3);
			goto finish;
		}
		/* Init task */
		init_image_config(argc, argv);
		init_netlink();
		/* Send OK to parent process */
		daemon_retval_send(0);
		daemon_log(LOG_INFO, "Sucessfully started");
		/* Main task*/
		pthread_create(&nl_thread, NULL, (void *)netlink_loop, (void *)NULL);
		#if 0
		pthread_create(&sock_thread, NULL, (void *)socket_loop, (void *)NULL);
		#endif
		pthread_create(&sock_thread, NULL, (void *)mq_loop, (void *)NULL);
		/* Prepare for select() on the signal fd */
		FD_ZERO(&fds);
		fd = daemon_signal_fd();
		FD_SET(fd, &fds);
		while (!quit) {
			fd_set fds2 = fds;
			/* Wait for an incoming signal */
			if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) {
				/* If we've been interrupted by an incoming signal, continue */
				if (errno == EINTR)
					continue;
				daemon_log(LOG_ERR, "select(): %s", strerror(errno));
				break;
			}
			/* Check if a signal has been recieved */
			if (FD_ISSET(fd, &fds2)) {
				int sig;
				/* Get signal */
				if ((sig = daemon_signal_next()) <= 0) {
					daemon_log(LOG_ERR, "daemon_signal_next() failed: %s",
						strerror(errno));
					break;
				}
				/* Dispatch signal */
				switch (sig) {
					case SIGINT:
					case SIGQUIT:
					case SIGTERM:
						daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or"
							"SIGTERM.");
						if (nl_image_config.nl_connected == 1) {
							nl_image_config.nl_connected = 0;
							if (nl_send_image_session_cmd(
								IMAGE_SESSION_CMD_DISCONNECT) < 0) {
								printf("Failed to remove connection with"
									"kernel!\n");
							}
						}
						quit = 1;
						break;
					case SIGHUP:
						daemon_log(LOG_INFO, "Got a HUP");
						daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
						break;
				}
			}
		}
		/* Do a cleanup */
finish:
		delete_pid_file(IMAGE_SERVER_PROC);
		daemon_log(LOG_INFO, "Exiting...");
		daemon_retval_send(255);
		daemon_signal_done();
		daemon_pid_file_remove();
		return 0;
	}
}
/** Punto de entrada de la aplicacion de navegacion.
 * @return Estado de la aplicacion al terminar.
 */
int main(int argc, char *argv[]) {
	pid_t pid;

	/* Reset signal handlers */
	if (daemon_reset_sigs(-1) < 0) {
		daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s",
				strerror(errno));
		return 1;
	}

	/* Unblock signals */
	if (daemon_unblock_sigs(-1) < 0) {
		daemon_log(LOG_ERR, "Failed to unblock all signals: %s",
				strerror(errno));
		return 1;
	}

	/* Set indetification string for the daemon for both syslog and PID file */
	daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);

	/* Check if we are called with -k parameter */
	if (argc >= 2 && !strcmp(argv[1], "-k")) {
		int ret;

		/* Kill daemon with SIGTERM */

		/* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */
		if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
			daemon_log(LOG_WARNING, "Failed to kill daemon: %s",
					strerror(errno));

		return ret < 0 ? 1 : 0;
	}

	/* Check that the daemon is not rung twice a the same time */
	if ((pid = daemon_pid_file_is_running()) >= 0) {
		daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
		return 1;
	}

	/* Prepare for return value passing from the initialization procedure of the daemon process */
	if (daemon_retval_init() < 0) {
		daemon_log(LOG_ERR, "Failed to create pipe.");
		return 1;
	}

	/* Do the fork */
	if ((pid = daemon_fork()) < 0) {

		/* Exit on error */
		daemon_retval_done();
		return 1;

	} else if (pid) { /* The parent */
		int ret;

		/* Wait for 20 seconds for the return value passed from the daemon process */
		if ((ret = daemon_retval_wait(20)) < 0) {
			daemon_log(LOG_ERR,
					"Could not recieve return value from daemon process: %s",
					strerror(errno));
			return 255;
		}

		daemon_log(ret != 0 ? LOG_ERR : LOG_INFO,
				"Daemon returned %i as return value.", ret);
		return ret;

	} else { /* The daemon */
		int fd, quit = 0;
		fd_set fds;

		char * config_file;

		config_t cfg;
		config_setting_t *setting;

		/* Base de Datos de Tiempo Real */
		struct rtdb rtdb;

		/* Controlador de estado de la MTi-G */
		struct mti_g mti_g;

		struct time_tracker tracker;

		struct sharksoft sharksoft;

		/* Close FDs */
		if (daemon_close_all(-1) < 0) {
			daemon_log(LOG_ERR, "Failed to close all file descriptors: %s",
					strerror(errno));

			/* Send the error condition to the parent process */
			daemon_retval_send(1);
			goto finish;
		}

		/* Create the PID file */
		if (daemon_pid_file_create() < 0) {
			daemon_log(LOG_ERR, "Could not create PID file (%s).",
					strerror(errno));
			daemon_retval_send(2);
			goto finish;
		}

		/* Initialize signal handling */
		if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
			daemon_log(LOG_ERR, "Could not register signal handlers (%s).",
					strerror(errno));
			daemon_retval_send(3);
			goto finish;
		}

		/*... do some further init work here */

		daemon_log(LOG_INFO, "Starting");

		/* cargar la configuración de la aplicación */
		config_init(&cfg);

		config_file = malloc(strlen(CONFIG_PATH) + strlen(CONFIG_FILE) + 1);
		assert(config_file != NULL);
		strcpy(config_file, CONFIG_PATH);
		strcpy(config_file + strlen(CONFIG_PATH), CONFIG_FILE);


		/* Read the file. If there is an error, report it and exit. */
		if (!config_read_file(&cfg, CONFIG_FILE)) {
			daemon_log(LOG_ERR, "%s:%d - %s\n", config_error_file(&cfg),
					config_error_line(&cfg), config_error_text(&cfg));
			daemon_retval_send(4);
			goto finish;
		}

		daemon_log(LOG_INFO, "Config file readed");

		/* Inicializar el controlador de estado de la MTi-G, enlazando
		 * la RTDB como area de almacenamiento */
		setting = config_lookup(&cfg, "mti_g");
		mti_g_init(&mti_g, setting, &(rtdb.imu), &(rtdb.gps));

		daemon_log(LOG_INFO, "MTi-G state controller inited");

		setting = config_lookup(&cfg, "time_tracker");
		time_tracker_init(&tracker, setting);

		daemon_log(LOG_INFO, "Time Tracker service inited");

		setting = config_lookup(&cfg, "sharksoft");
		sharksoft_init(&sharksoft, setting, &(rtdb.imu), &(rtdb.gps));

		daemon_log(LOG_INFO, "Sharksoft data provider service inited");

		/* Send OK to parent process */
		daemon_retval_send(0);

		daemon_log(LOG_INFO, "Sucessfully started");

		/* Prepare for select() on the signals */
		FD_ZERO(&fds);
		fd = daemon_signal_fd();
		FD_SET(fd, &fds);

		FD_SET(mti_g.fd, &fds);
		FD_SET(sharksoft.fd, &fds);

		while (!quit) {
			fd_set fds2 = fds;

			/* Wait for an incoming signal */
			if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) {

				/* If we've been interrupted by an incoming signal, continue */
				if (errno == EINTR)
					continue;

				daemon_log(LOG_ERR, "select(): %s", strerror(errno));
				break;
			}

			/* Check if a signal has been recieved */
			if (FD_ISSET(fd, &fds2)) {
				int sig;

				/* Get signal */
				if ((sig = daemon_signal_next()) <= 0) {
					daemon_log(LOG_ERR, "daemon_signal_next() failed: %s",
							strerror(errno));
					break;
				}

				/* Dispatch signal */
				switch (sig) {

				case SIGINT:
				case SIGQUIT:
				case SIGTERM:
					daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or SIGTERM.");
					quit = 1;
					break;

				case SIGHUP:
					daemon_log(LOG_INFO, "Got a HUP");
					daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
					break;
				}
			}

			/* Procesar señales desde la MTi-G */
			if (FD_ISSET(mti_g.fd, &fds2)) {
				mti_g_handle_request(&mti_g);

				//sharksoft_handle_getdata(&sharksoft);

				//time_tracker_handle(&tracker);
			}

			/* Procesar señales desde el HMI Sharksoft */
			if (FD_ISSET(sharksoft.fd, &fds2)) {
				//time_tracker_handle(&tracker);
				sharksoft_handle_request(&sharksoft);

			}
		}

		time_tracker_dispose(&tracker);

		config_destroy(&cfg);

		/* Do a cleanup */
		finish: daemon_log(LOG_INFO, "Exiting...");
		daemon_retval_send(255);
		daemon_signal_done();
		daemon_pid_file_remove();

		return 0;
	}
}