/* Polux projet {{{ * * Copyright (C) 2013 MStar Semiconductor * * <<>> * * }}} */ /** * \file polux/devkit/plcd/src/plcd_main.c * \ingroup polux_devkit_plcd */ #include "inc/plcd_main.h" #include "inc/plcd_autoswitch.h" #include "plc-drv/ioctl-interface.h" /* ioctl_plcd_t */ #include /* SIOCDEVPRIVATE for plc_ioctl.h */ #include "plc-drv/plc_ioctl.h" /* SIOC_PLC_DAEMON */ #include /* syslog */ #include /* EXIT_SUCCESS */ #include /* signal */ #include /* pid_t */ #include /* getpid */ #include #include volatile sig_atomic_t exit_requested; static int plc_sock; static int plcd_send_ioctl (ioctl_plcd_t *ioctl_plcd) { int fd; struct ifreq ifr; assert (plc_sock); memset (&ifr,0,sizeof(struct ifreq)); strcpy (ifr.ifr_name, "plc0"); ifr.ifr_data = (char *) ioctl_plcd; if (0 > ioctl (plc_sock, SIOC_PLC_DAEMON, &ifr)) { syslog (LOG_WARNING, "ioctl send failed"); return -1; } return 0; } static int plcd_register_to_plcdrv (void) { ioctl_plcd_t ioctl; ioctl.subcmd = IOC_PLCD_REGISTER; ioctl.pid = getpid (); plcd_send_ioctl (&ioctl); } static int plcd_unregister_to_plcdrv (void) { ioctl_plcd_t ioctl; ioctl.subcmd = IOC_PLCD_UNREGISTER; plcd_send_ioctl (&ioctl); } static void plcd_signal_handler (int event) { /* Check received signal. */ switch (event) { case SIGTERM: exit_requested = 1; break; default: syslog (LOG_WARNING, "PLCD: unexpected signal %d dropped\n", event); break; } } static int plcd_init (void) { exit_requested = 0; signal (SIGTERM, plcd_signal_handler); if (0 > (plc_sock = socket (AF_INET, SOCK_DGRAM, 0))) { syslog (LOG_WARNING, "socket open failed"); return -1; } return 0; } static void plcd_uninit (void) { close (plc_sock); } int main (int argc, char **argv) { if (0 > plcd_init ()) exit (EXIT_FAILURE); plcd_autoswitch_timer_init (); /* show PLCD version */ syslog (LOG_NOTICE, "PLC Daemon (%s) Running\n", PLCD_VERSION); /* Terminate the daemon when no feature is enable. */ if (plcd_autoswitch_timer_is_enable ()) { plcd_register_to_plcdrv (); while (!exit_requested) pause (); plcd_unregister_to_plcdrv (); } syslog (LOG_NOTICE, "PLC Daemon exiting\n"); plcd_autoswitch_timer_uninit (); plcd_uninit (); exit (EXIT_SUCCESS); }