make syslog work

Signed-off-by: Michel-FK <michel.stempin@funkey-project.com>
This commit is contained in:
Michel-FK 2021-04-10 16:46:27 +02:00
parent 16b7a7b167
commit 53599f54fd
12 changed files with 148 additions and 263 deletions

View File

@ -4,7 +4,7 @@ TOOLS_CFLAGS := -Wall -std=c99 -D _DEFAULT_SOURCE
#
all: fkgpiod termfix
fkgpiod: main.o daemon.o to_log.o parse_config.o mapping_list.o gpio_mapping.o gpio_utils.o gpio_axp209.o gpio_pcal6416a.o smbus.o uinput.o keydefs.o
fkgpiod: main.o daemon.o parse_config.o mapping_list.o gpio_mapping.o gpio_utils.o gpio_axp209.o gpio_pcal6416a.o smbus.o uinput.o keydefs.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
termfix: termfix.o

View File

@ -88,7 +88,7 @@ void kill_daemon(char *pidfile)
}
/* Turn the running process into a daemon */
void daemonize(char *rundir, char *pidfile)
void daemonize(const char *ident, char *rundir, char *pidfile)
{
int pid, i;
char str[10];
@ -163,6 +163,9 @@ void daemonize(char *rundir, char *pidfile)
close(i);
}
/* Since we have no more stdout/stderr, open syslog */
openlog(ident, LOG_PID | LOG_NDELAY, LOG_DAEMON);
/* Make sure there is only one daemon running at a time using a lock file */
pid_lock_file = pidfile;
pid_fd = open(pidfile, O_RDWR | O_CREAT, 0600);
@ -177,7 +180,10 @@ void daemonize(char *rundir, char *pidfile)
}
sprintf(str, "%d\n", getpid());
if (write(pid_fd, str, strlen(str)) < 0) {
perror(pidfile);
syslog(LOG_ERR, "Could not write to lock file %s: %s. Exiting.",
strerror(errno), pidfile);
unlink(pidfile);
exit(EXIT_FAILURE);
}
syslog(LOG_INFO, "Daemon running.");
}

View File

@ -27,7 +27,7 @@
#ifndef _DAEMON_H_
#define _DAEMON_H_
void daemonize(char *rundir, char *pidfile);
void daemonize(const char *ident, char *rundir, char *pidfile);
void kill_daemon(char *pidfile);
#endif

View File

@ -25,29 +25,29 @@
* This is the userland GPIO driver for the AXP209 PMIC
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <syslog.h>
#include <unistd.h>
#include <linux/input.h>
#include <assert.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "smbus.h"
#include "gpio_axp209.h"
#include "smbus.h"
//#define DEBUG_AXP209
#define ERROR_AXP209
#ifdef DEBUG_AXP209
#define LOG_DEBUG(...) printf(__VA_ARGS__);
#define FK_DEBUG(...) syslog(LOG_DEBUG, __VA_ARGS__);
#else
#define LOG_DEBUG(...)
#define FK_DEBUG(...)
#endif
#ifdef ERROR_AXP209
#define LOG_ERROR(...) fprintf(stderr, "ERR: " __VA_ARGS__);
#define FK_ERROR(...) syslog(LOG_ERR, __VA_ARGS__);
#else
#define LOG_ERROR(...)
#define FK_ERROR(...)
#endif
/* AXP209 I2C PMIC pseudo-file descriptor */
@ -61,33 +61,33 @@ bool axp209_init(void)
{
/* Open the I2C bus pseudo-file */
if ((fd_axp209 = open(i2c0_sysfs_filename,O_RDWR)) < 0) {
LOG_ERROR("Failed to open the I2C bus %s", i2c0_sysfs_filename);
FK_ERROR("Failed to open the I2C bus %s", i2c0_sysfs_filename);
return false;
}
/* Acquire the bus access for the AXP209 PMIC chip */
if (ioctl(fd_axp209, I2C_SLAVE, AXP209_I2C_ADDR) < 0) {
LOG_DEBUG("Failed to acquire bus access and/or talk to slave, trying to force it\n");
FK_DEBUG("Failed to acquire bus access and/or talk to slave, trying to force it\n");
if (ioctl(fd_axp209, I2C_SLAVE_FORCE, AXP209_I2C_ADDR) < 0) {
LOG_ERROR("Failed to acquire FORCED bus access and/or talk to slave.\n");
FK_ERROR("Failed to acquire FORCED bus access and/or talk to slave.\n");
return false;
}
}
/* Set PEK Long press delay to 2.5s */
if (i2c_smbus_write_byte_data(fd_axp209, AXP209_REG_PEK_PARAMS, 0x9F) < 0) {
LOG_ERROR("Cannot set AXP209 PEK Long press delay to 2.5s\n");
FK_ERROR("Cannot set AXP209 PEK Long press delay to 2.5s\n");
}
/* Set N_OE Shutdown delay to 3s*/
if (i2c_smbus_write_byte_data(fd_axp209, AXP209_REG_32H, 0x47) < 0) {
LOG_ERROR("Cannot set AXP209 N_OE Shutdown delay to 3s\n");
FK_ERROR("Cannot set AXP209 N_OE Shutdown delay to 3s\n");
}
/* Enable only chosen interrupts (PEK short and long presses)*/
if (i2c_smbus_write_byte_data(fd_axp209, AXP209_INTERRUPT_BANK_3_ENABLE,
0x03) < 0) {
LOG_ERROR("Cannot intiialize interrupt bank 3 for AXP209\n");
FK_ERROR("Cannot intiialize interrupt bank 3 for AXP209\n");
}
return true;
}
@ -116,6 +116,6 @@ int axp209_read_interrupt_bank_3(void)
if (result < 0) {
return result;
}
LOG_DEBUG("READ AXP209_INTERRUPT_BANK_3_STATUS: 0x%02X\n", value);
FK_DEBUG("READ AXP209_INTERRUPT_BANK_3_STATUS: 0x%02X\n", value);
return value & 0xFF;
}

View File

@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
@ -48,21 +49,21 @@
#define ERROR_GPIO
#ifdef DEBUG_GPIO
#define LOG_DEBUG(...) printf(__VA_ARGS__);
#define FK_DEBUG(...) syslog(LOG_DEBUG, __VA_ARGS__);
#else
#define LOG_DEBUG(...)
#define FK_DEBUG(...)
#endif
#ifdef DEBUG_PERIODIC_CHECK
#define LOG_PERIODIC(...) printf(__VA_ARGS__);
#define FK_PERIODIC(...) syslog(LOG_DEBUG, __VA_ARGS__);
#else
#define LOG_PERIODIC(...)
#define FK_PERIODIC(...)
#endif
#ifdef ERROR_GPIO
#define LOG_ERROR(...) fprintf(stderr, "ERR: " __VA_ARGS__);
#define FK_ERROR(...) syslog(LOG_ERR, __VA_ARGS__);
#else
#define LOG_ERROR(...)
#define FK_ERROR(...)
#endif
#define FIFO_FILE "/tmp/fkgpiod.fifo"
@ -128,7 +129,7 @@ static void apply_mapping(mapping_list_t *list, uint32_t gpio_mask)
if ((mapping->gpio_mask & gpio_mask) == mapping->gpio_mask) {
/* If the current GPIO mask contains the mapping GPIO mask */
LOG_DEBUG("Found matching mapping:\n");
FK_DEBUG("Found matching mapping:\n");
#ifdef DEBUG_GPIO
dump_mapping(mapping);
#endif // DEBUG_GPIO
@ -139,12 +140,12 @@ static void apply_mapping(mapping_list_t *list, uint32_t gpio_mask)
if (mapping->type == MAPPING_KEY) {
/* Send the key down event */
LOG_DEBUG("\t--> Key press %d\n", mapping->value.keycode);
FK_DEBUG("\t--> Key press %d\n", mapping->value.keycode);
sendKey(mapping->value.keycode, 1);
} else if (mapping->type == MAPPING_COMMAND) {
/* Execute the corresponding Shell command */
LOG_DEBUG("\t--> Execute Shell command \"%s\"\n",
FK_DEBUG("\t--> Execute Shell command \"%s\"\n",
mapping->value.command);
system(mapping->value.command);
}
@ -157,7 +158,7 @@ static void apply_mapping(mapping_list_t *list, uint32_t gpio_mask)
} else if (mapping->activated) {
/* Non-matching activated mapping, deactivate it */
LOG_DEBUG("Found activated mapping:\n");
FK_DEBUG("Found activated mapping:\n");
#ifdef DEBUG_GPIO
dump_mapping(mapping);
#endif // DEBUG_GPIO
@ -165,7 +166,7 @@ static void apply_mapping(mapping_list_t *list, uint32_t gpio_mask)
if (mapping->type == MAPPING_KEY) {
/* Send the key up event */
LOG_DEBUG("\t--> Key release %d\n", mapping->value.keycode);
FK_DEBUG("\t--> Key release %d\n", mapping->value.keycode);
sendKey(mapping->value.keycode, 0);
}
}
@ -175,7 +176,7 @@ static void apply_mapping(mapping_list_t *list, uint32_t gpio_mask)
/* Initialize the GPIO interrupt for the I2C expander chip */
static bool init_gpio_interrupt(int gpio, int *fd, const char *edge)
{
LOG_DEBUG("Initializing interrupt for GPIO P%c%d (%d)\n",
FK_DEBUG("Initializing interrupt for GPIO P%c%d (%d)\n",
(gpio / 16) + '@', gpio % 16, gpio);
if (gpio_export(gpio) < 0) {
return false;
@ -190,7 +191,7 @@ static bool init_gpio_interrupt(int gpio, int *fd, const char *edge)
/* Open the GPIO pseudo-file */
*fd = gpio_fd_open(gpio, O_RDONLY);
LOG_DEBUG("GPIO fd is: %d\n", *fd);
FK_DEBUG("GPIO fd is: %d\n", *fd);
if (*fd < 0) {
return false;
}
@ -200,7 +201,7 @@ static bool init_gpio_interrupt(int gpio, int *fd, const char *edge)
/* Deinitialize the GPIO interrupt for the I2C expander chip */
static void deinit_gpio_interrupt(int fd)
{
LOG_DEBUG("DeInitializing interrupt for GPIO fd %d\n", fd);
FK_DEBUG("DeInitializing interrupt for GPIO fd %d\n", fd);
/* Close the GPIO pseudo-file */
gpio_fd_close(fd);
@ -234,7 +235,7 @@ bool init_gpio_mapping(const char *config_filename,
}
/* Initialize the GPIO interrupt for the I2C GPIO expander chip */
LOG_DEBUG("Initialize interrupt for GPIO_PIN_I2C_EXPANDER_INTERRUPT\n");
FK_DEBUG("Initialize interrupt for GPIO_PIN_I2C_EXPANDER_INTERRUPT\n");
init_gpio_interrupt(GPIO_PIN_I2C_EXPANDER_INTERRUPT, &fd_pcal6416a,
"both");
@ -244,22 +245,22 @@ bool init_gpio_mapping(const char *config_filename,
}
/* Initialize the GPIO interrupt for the AXP209 chip */
LOG_DEBUG("Initialize interrupt for GPIO_PIN_AXP209_INTERRUPT\n");
FK_DEBUG("Initialize interrupt for GPIO_PIN_AXP209_INTERRUPT\n");
init_gpio_interrupt(GPIO_PIN_AXP209_INTERRUPT, &fd_axp209, "");
/* Create the FIFO pseudo-file if it does not exist */
LOG_DEBUG("Create the FIFO pseudo-file if it does not exist\n");
FK_DEBUG("Create the FIFO pseudo-file if it does not exist\n");
if (mkfifo(FIFO_FILE, O_RDWR | 0640) < 0 && errno != EEXIST) {
LOG_ERROR("Cannot create the \"%s\" FIFO: %s\n", FIFO_FILE,
FK_ERROR("Cannot create the \"%s\" FIFO: %s\n", FIFO_FILE,
strerror(errno));
return false;
}
/* Open the FIFO pseudo-file */
LOG_DEBUG("Open the FIFO pseudo-file\n");
FK_DEBUG("Open the FIFO pseudo-file\n");
fd_fifo = open(FIFO_FILE, O_RDWR | O_NONBLOCK);
if (fd_fifo < 0) {
LOG_ERROR("Cannot open the \"%s\" FIFO: %s\n", FIFO_FILE,
FK_ERROR("Cannot open the \"%s\" FIFO: %s\n", FIFO_FILE,
strerror(errno));
return false;
}
@ -273,21 +274,21 @@ bool init_gpio_mapping(const char *config_filename,
void deinit_gpio_mapping(void)
{
/* Deinitialize the GPIO interrupt for the I2C GPIO expander chip */
LOG_DEBUG("DeInitiating interrupt for GPIO_PIN_I2C_EXPANDER_INTERRUPT\n");
FK_DEBUG("DeInitiating interrupt for GPIO_PIN_I2C_EXPANDER_INTERRUPT\n");
deinit_gpio_interrupt(fd_pcal6416a);
/* Deinitialize the I2C GPIO expander chip */
pcal6416a_deinit();
/* Deinitialize the GPIO interrupt for the AXP209 PMIC chip */
LOG_DEBUG("DeInitiating interrupt for GPIO_PIN_AXP209_INTERRUPT\n");
FK_DEBUG("DeInitiating interrupt for GPIO_PIN_AXP209_INTERRUPT\n");
deinit_gpio_interrupt(fd_axp209);
/* Deinitialize the AXP209 PMIC chip */
axp209_deinit();
/* Close the FIFO pseudo-file */
LOG_DEBUG("Close the FIFO pseudo-file \n");
FK_DEBUG("Close the FIFO pseudo-file \n");
close(fd_fifo);
}
@ -339,14 +340,14 @@ void handle_gpio_mapping(mapping_list_t *list)
if (result == 0) {
/* Timeout case */
LOG_PERIODIC("Timeout, forcing sanity check\n");
FK_PERIODIC("Timeout, forcing sanity check\n");
/* Timeout forces a "Found interrupt" event for sanity check */
pcal6416a_interrupt = axp209_interrupt = forced_interrupt = true;
} else if (result < 0) {
/* Error case */
perror("select");
FK_ERROR("select: %s\n", strerror(errno));
return;
} else {
@ -360,13 +361,13 @@ void handle_gpio_mapping(mapping_list_t *list)
} else if (errno == EWOULDBLOCK) {
/* Done reading */
LOG_DEBUG("Read %d bytes from FIFO: \"%.*s\"\n",
FK_DEBUG("Read %d bytes from FIFO: \"%.*s\"\n",
(int) total_bytes, (int) total_bytes, fifo_buffer);
if (strtok_r(fifo_buffer, "\r\n", &next_line) != NULL) {
LOG_DEBUG("Parse line \"%s\"\n", fifo_buffer);
FK_DEBUG("Parse line \"%s\"\n", fifo_buffer);
if (parse_config_line(fifo_buffer, list,
&monitored_gpio_mask) == false) {
LOG_ERROR("Error while parsing line \"%s\"\n",
FK_ERROR("Error while parsing line \"%s\"\n",
fifo_buffer);
}
total_bytes -= next_line - fifo_buffer;
@ -376,7 +377,7 @@ void handle_gpio_mapping(mapping_list_t *list)
}
break;
} else {
LOG_ERROR("Cannot read from FIFO: %s\n", strerror(errno));
FK_ERROR("Cannot read from FIFO: %s\n", strerror(errno));
return;
}
}
@ -389,16 +390,16 @@ void handle_gpio_mapping(mapping_list_t *list)
/* Rewind file and dummy read the current GPIO value */
lseek(fd, 0, SEEK_SET);
if (read(fd, &buffer, 2) != 2) {
perror("read");
FK_ERROR("read: %s\n", strerror(errno));
break;
}
/* Check if the interrupt is from I2C GPIO expander or AXP209 */
if (fd == fd_pcal6416a) {
LOG_DEBUG("Found interrupt generated by PCAL6416AHF\r\n");
FK_DEBUG("Found interrupt generated by PCAL6416AHF\r\n");
pcal6416a_interrupt = true;
} else if (fd == fd_axp209) {
LOG_DEBUG("Found interrupt generated by AXP209\r\n");
FK_DEBUG("Found interrupt generated by AXP209\r\n");
axp209_interrupt = true;
}
}
@ -408,33 +409,33 @@ void handle_gpio_mapping(mapping_list_t *list)
/* Process the AXP209 interrupts, if any */
if (axp209_interrupt) {
if (forced_interrupt) {
LOG_PERIODIC("Processing forced AXP209 interrupt\n");
FK_PERIODIC("Processing forced AXP209 interrupt\n");
} else {
LOG_DEBUG("Processing real AXP209 interrupt\n");
FK_DEBUG("Processing real AXP209 interrupt\n");
}
val_int_bank_3 = axp209_read_interrupt_bank_3();
if (val_int_bank_3 < 0) {
LOG_DEBUG("Could not read AXP209 by I2C\n");
FK_DEBUG("Could not read AXP209 by I2C\n");
return;
}
/* Proccess the Power Enable Key (PEK) short keypress */
if (val_int_bank_3 & AXP209_INTERRUPT_PEK_SHORT_PRESS) {
LOG_DEBUG("AXP209 short PEK key press detected\n");
FK_DEBUG("AXP209 short PEK key press detected\n");
mapping = find_mapping(list, SHORT_PEK_PRESS_GPIO_MASK);
if (mapping != NULL) {
LOG_DEBUG("Found matching mapping:\n");
FK_DEBUG("Found matching mapping:\n");
#ifdef DEBUG_GPIO
dump_mapping(mapping);
#endif // DEBUG_GPIO
if (mapping->type == MAPPING_KEY) {
LOG_DEBUG("\t--> Key press and release %d\n",
FK_DEBUG("\t--> Key press and release %d\n",
mapping->value.keycode);
sendKey(mapping->value.keycode, 1);
usleep(SHORT_PEK_PRESS_DURATION_US);
sendKey(mapping->value.keycode, 0);
} else if (mapping->type == MAPPING_COMMAND) {
LOG_DEBUG("\t--> Execute Shell command \"%s\"\n",
FK_DEBUG("\t--> Execute Shell command \"%s\"\n",
mapping->value.command);
system(mapping->value.command);
}
@ -445,8 +446,8 @@ void handle_gpio_mapping(mapping_list_t *list)
* will shutdown the system in 3s anyway
*/
if (val_int_bank_3 & AXP209_INTERRUPT_PEK_LONG_PRESS) {
LOG_DEBUG("AXP209 long PEK key press detected\n");
LOG_DEBUG("\t--> Execute Shell command \"%s\"\n",
FK_DEBUG("AXP209 long PEK key press detected\n");
FK_DEBUG("\t--> Execute Shell command \"%s\"\n",
SHELL_COMMAND_SHUTDOWN);
system(SHELL_COMMAND_SHUTDOWN);
}
@ -455,15 +456,15 @@ void handle_gpio_mapping(mapping_list_t *list)
/* Process the PCAL6416A interrupts, if any */
if (pcal6416a_interrupt) {
if (forced_interrupt) {
LOG_PERIODIC("Processing forced PCAL6416AHF interrupt\n");
FK_PERIODIC("Processing forced PCAL6416AHF interrupt\n");
} else {
LOG_DEBUG("Processing real PCAL6416AHF interrupt\n");
FK_DEBUG("Processing real PCAL6416AHF interrupt\n");
}
/* Read the interrupt mask */
int_status = pcal6416a_read_mask_interrupts();
if (int_status < 0) {
LOG_DEBUG("Could not read PCAL6416A interrupt status by I2C\n");
FK_DEBUG("Could not read PCAL6416A interrupt status by I2C\n");
return;
}
interrupt_mask = (uint32_t) int_status;
@ -471,7 +472,7 @@ void handle_gpio_mapping(mapping_list_t *list)
/* Read the GPIO mask */
current_gpio_mask = pcal6416a_read_mask_active_GPIOs();
if (current_gpio_mask < 0) {
LOG_DEBUG("Could not read PCAL6416A active GPIOS by I2C\n");
FK_DEBUG("Could not read PCAL6416A active GPIOS by I2C\n");
return;
}
@ -489,13 +490,13 @@ void handle_gpio_mapping(mapping_list_t *list)
if (interrupt_mask & (1 << gpio)) {
/* Found the GPIO in the interrupt mask */
LOG_DEBUG("\t--> Interrupt GPIO: %d\n", gpio);
FK_DEBUG("\t--> Interrupt GPIO: %d\n", gpio);
} else if ((current_gpio_mask ^ previous_gpio_mask) & (1 << gpio)) {
/* The GPIO is not in the interrupt mask, but has changed, force
* it
*/
LOG_DEBUG("\t--> No interrupt (missed) but value has changed on GPIO: %d\n",
FK_DEBUG("\t--> No interrupt (missed) but value has changed on GPIO: %d\n",
gpio);
interrupt_mask |= 1 << gpio;
}
@ -505,15 +506,15 @@ void handle_gpio_mapping(mapping_list_t *list)
/* No change */
return;
}
LOG_DEBUG("current_gpio_mask 0x%04X interrupt_mask 0x%04X\n",
FK_DEBUG("current_gpio_mask 0x%04X interrupt_mask 0x%04X\n",
current_gpio_mask, int_status);
/* Proccess the N_OE signal from the magnetic Reed switch, the
* AXP209 will shutdown the system in 3s anyway
*/
if (interrupt_mask & NOE_GPIO_MASK) {
LOG_DEBUG("NOE detected\n");
LOG_DEBUG("\t--> Execute Shell command \"%s\"\n",
FK_DEBUG("NOE detected\n");
FK_DEBUG("\t--> Execute Shell command \"%s\"\n",
SHELL_COMMAND_SHUTDOWN);
interrupt_mask &= ~NOE_GPIO_MASK;
system(SHELL_COMMAND_SHUTDOWN);

View File

@ -25,35 +25,29 @@
* This is userland GPIO driver for the PCAL6416AHB I2C GPIO expander chip
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/select.h>
#include <stdio.h>
#include <syslog.h>
#include <unistd.h>
#include <linux/input.h>
#include <assert.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "smbus.h"
#include "gpio_pcal6416a.h"
#include "smbus.h"
//#define DEBUG_PCAL6416A
#define ERROR_PCAL6416A
#ifdef DEBUG_PCAL6416A
#define LOG_DEBUG(...) printf(__VA_ARGS__);
#define FK_DEBUG(...) syslog(LOG_DEBUG, __VA_ARGS__);
#else
#define LOG_DEBUG(...)
#define FK_DEBUG(...)
#endif
#ifdef ERROR_PCAL6416A
#define LOG_ERROR(...) fprintf(stderr, "ERR: " __VA_ARGS__);
#define FK_ERROR(...) syslog(LOG_ERR, __VA_ARGS__);
#else
#define LOG_ERROR(...)
#define FK_ERROR(...)
#endif
/* Structure to map I2C address and I2C GPIO expander name */
@ -85,7 +79,7 @@ bool pcal6416a_init(void)
/* Open the I2C bus pseudo-file */
if ((fd_i2c_expander = open(i2c0_sysfs_filename,O_RDWR)) < 0) {
LOG_ERROR("Failed to open the I2C bus %s", i2c0_sysfs_filename);
FK_ERROR("Failed to open the I2C bus %s", i2c0_sysfs_filename);
return false;
}
@ -94,10 +88,10 @@ bool pcal6416a_init(void)
if (ioctl(fd_i2c_expander, I2C_SLAVE_FORCE, i2c_chip[i]) < 0 ||
pcal6416a_read_mask_interrupts() < 0) {
LOG_DEBUG("Failed to acquire bus access and/or talk to slave %s at address 0x%02X.\n",
FK_DEBUG("Failed to acquire bus access and/or talk to slave %s at address 0x%02X.\n",
i2c_chip[i].name, i2c_chip[i].address);
} else {
LOG_DEBUG("Found I2C gpio expander chip %s at address 0x%02X\n",
FK_DEBUG("Found I2C gpio expander chip %s at address 0x%02X\n",
i2c_chip[i].name, i2c_chip[i].address);
i2c_expander_addr = i2c_chip[i].address;
break;
@ -106,7 +100,7 @@ bool pcal6416a_init(void)
/* GPIO expander chip found? */
if (!i2c_expander_addr) {
LOG_ERROR("Failed to acquire bus access and/or talk to slave, exit\n");
FK_ERROR("Failed to acquire bus access and/or talk to slave, exit\n");
return false;
}
i2c_smbus_write_word_data ( fd_i2c_expander, PCAL6416A_CONFIG, 0xffff);
@ -137,7 +131,7 @@ int pcal6416a_read_mask_interrupts(void)
return val_int;
}
val = val_int & 0xFFFF;
LOG_DEBUG("READ PCAL6416A_INT_STATUS : 0x%04X\n", val);
FK_DEBUG("READ PCAL6416A_INT_STATUS : 0x%04X\n", val);
return (int) val;
}
@ -153,6 +147,6 @@ int pcal6416a_read_mask_active_GPIOs(void)
}
val = val_int & 0xFFFF;
val = 0xFFFF - val;
LOG_DEBUG("READ PCAL6416A_INPUT (active GPIOs) : 0x%04X\n", val);
FK_DEBUG("READ PCAL6416A_INPUT (active GPIOs) : 0x%04X\n", val);
return (int) val;
}

7
main.c
View File

@ -215,10 +215,11 @@ int main(int argc, char *argv[])
if (daemon) {
/* Run as a background daemon, redirect all output to syslog */
// to_log(&stdout);
// to_log(&stderr);
daemonize("fkgpiod", "/", PID_FILE);
} else {
openlog("fkgpiod", LOG_PERROR | LOG_PID | LOG_NDELAY, LOG_DAEMON);
to_log(&stdout);
to_log(&stderr);
daemonize("/", PID_FILE);
}
/* Initialize the uinput device */

View File

@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "mapping_list.h"
#include "parse_config.h"
@ -35,15 +36,15 @@
#define ERROR_MAPPING_LIST
#ifdef DEBUG_MAPPING_LIST
#define LOG_DEBUG(...) printf(__VA_ARGS__);
#define FK_DEBUG(...) syslog(LOG_DEBUG, __VA_ARGS__);
#else
#define LOG_DEBUG(...)
#define FK_DEBUG(...)
#endif
#ifdef ERROR_MAPPING_LIST
#define LOG_ERROR(...) fprintf(stderr, "ERR: " __VA_ARGS__);
#define FK_ERROR(...) syslog(LOG_ERR, __VA_ARGS__);
#else
#define LOG_ERROR(...)
#define FK_ERROR(...)
#endif
/* Compute the byte offset of a structure member */
@ -179,7 +180,7 @@ bool insert_mapping(mapping_list_t *list, mapping_t *mapping)
break;
default:
LOG_ERROR("Unknown mapping type %d\n", mapping->type);
FK_ERROR("Unknown mapping type %d\n", mapping->type);
return false;
}
@ -235,7 +236,7 @@ bool remove_mapping(mapping_list_t *list, mapping_t *mapping)
break;
default:
LOG_ERROR("Unknown mapping type %d\n", tmp->type);
FK_ERROR("Unknown mapping type %d\n", tmp->type);
return false;
}
free(tmp);
@ -273,7 +274,7 @@ void dump_mapping(mapping_t *mapping)
break;
default:
LOG_ERROR("Unknown mapping type %d\n", mapping->type);
FK_ERROR("Unknown mapping type %d\n", mapping->type);
break;
}
}

View File

@ -31,6 +31,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include "keydefs.h"
#include "mapping_list.h"
#include "parse_config.h"
@ -40,15 +41,15 @@
#define ERROR_CONFIG
#ifdef DEBUG_CONFIG
#define LOG_DEBUG(...) printf(__VA_ARGS__);
#define FK_DEBUG(...) syslog(LOG_DEBUG, __VA_ARGS__);
#else
#define LOG_DEBUG(...)
#define FK_DEBUG(...)
#endif
#ifdef ERROR_CONFIG
#define LOG_ERROR(...) fprintf(stderr, "ERR: " __VA_ARGS__);
#define FK_ERROR(...) syslog(LOG_ERR, __VA_ARGS__);
#else
#define LOG_ERROR(...)
#define FK_ERROR(...)
#endif
#define MAX_BUFFER_LENGTH 256
@ -111,7 +112,7 @@ static parse_state_t lookup_command(char *token)
return keyword;
}
}
LOG_ERROR("Invalid keyword \"%s\"\n", token);
FK_ERROR("Invalid keyword \"%s\"\n", token);
return STATE_INVALID;
}
@ -126,7 +127,7 @@ static parse_state_t lookup_function(char *token)
return valid_functions[command].state;
}
}
LOG_ERROR("Invalid keyword \"%s\"\n", token);
FK_ERROR("Invalid keyword \"%s\"\n", token);
return STATE_INVALID;
}
@ -137,12 +138,12 @@ static int lookup_gpio(char *token)
for (button = 0; gpio_names[button] != NULL; button++) {
if (strcasecmp(token, gpio_names[button]) == 0) {
LOG_DEBUG("Found button \"%s\" (GPIO %d)\n", gpio_names[button],
FK_DEBUG("Found button \"%s\" (GPIO %d)\n", gpio_names[button],
button);
return button;
}
}
LOG_ERROR("Unknown button \"%s\"\n", token);
FK_ERROR("Unknown button \"%s\"\n", token);
return -1;
}
@ -153,12 +154,12 @@ static int lookup_key(char *token)
for (key = 0; key_names[key].code >= 0; key++) {
if (strcasecmp(token, key_names[key].name) == 0) {
LOG_DEBUG("Found keycode \"%s\" (%d)\n", key_names[key].name,
FK_DEBUG("Found keycode \"%s\" (%d)\n", key_names[key].name,
key_names[key].code);
return key;
}
}
LOG_ERROR("Unknown key \"%s\"\n", token);
FK_ERROR("Unknown key \"%s\"\n", token);
return -1;
}
@ -210,18 +211,18 @@ bool parse_config_line(char *line, mapping_list_t *list,
case STATE_MAP:
if (strcasecmp(token, "TO") == 0) {
if (state != STATE_MAP) {
LOG_ERROR("Unexpected keyword \"TO\"\n");
FK_ERROR("Unexpected keyword \"TO\"\n");
return false;
}
if (expecting_button == true) {
/* Missing last button */
LOG_ERROR("Missing last button\n");
FK_ERROR("Missing last button\n");
return false;
} else if (button_count == 0) {
/* No button found */
LOG_ERROR("No button found\n");
FK_ERROR("No button found\n");
return false;
}
state = STATE_FUNCTION;
@ -236,12 +237,12 @@ bool parse_config_line(char *line, mapping_list_t *list,
if (button_count == 0) {
/* We need at least one button left of '+' */
LOG_ERROR("Missing first button\n");
FK_ERROR("Missing first button\n");
return false;
} else if (expecting_button == true) {
/* Exepecting a button, cannot have another '+' */
LOG_ERROR("Missing button\n");
FK_ERROR("Missing button\n");
return false;
} else {
@ -281,7 +282,7 @@ bool parse_config_line(char *line, mapping_list_t *list,
case STATE_SLEEP:
for (s = token; *s; s++) {
if (!isdigit(*s)) {
LOG_ERROR("Invalid delay \"%s\"\n", token);
FK_ERROR("Invalid delay \"%s\"\n", token);
return false;
}
}
@ -322,7 +323,7 @@ bool parse_config_line(char *line, mapping_list_t *list,
break;
default:
LOG_ERROR("Unknown state %d\n", state);
FK_ERROR("Unknown state %d\n", state);
return false;
}
if (!skip_read_token){
@ -332,16 +333,16 @@ bool parse_config_line(char *line, mapping_list_t *list,
}
switch (state) {
case STATE_UNMAP:
LOG_DEBUG("UNMAP gpio_mask 0x%04X button_count %d\n", gpio_mask,
FK_DEBUG("UNMAP gpio_mask 0x%04X button_count %d\n", gpio_mask,
button_count);
existing_mapping = find_mapping(list, gpio_mask);
if (existing_mapping == NULL) {
LOG_ERROR("Cannot find mapping with gpio_mask 0x%04X\n",
FK_ERROR("Cannot find mapping with gpio_mask 0x%04X\n",
gpio_mask);
return false;
}
if (remove_mapping(list, existing_mapping) == false) {
LOG_ERROR("Cannot remove mapping with gpio_mask 0x%04X\n",
FK_ERROR("Cannot remove mapping with gpio_mask 0x%04X\n",
gpio_mask);
return false;
}
@ -349,22 +350,22 @@ bool parse_config_line(char *line, mapping_list_t *list,
break;
case STATE_CLEAR:
LOG_DEBUG("CLEAR\n");
FK_DEBUG("CLEAR\n");
clear_mapping_list(list);
break;
case STATE_LOAD:
LOG_DEBUG("LOAD file \"%s\"\n", buffer);
FK_DEBUG("LOAD file \"%s\"\n", buffer);
return parse_config_file(buffer, list, monitored_gpio_mask);
break;
case STATE_SLEEP:
LOG_DEBUG("SLEEP delay %s ms\n", buffer);
FK_DEBUG("SLEEP delay %s ms\n", buffer);
usleep(atoi(buffer) * 1000);
break;
case STATE_TYPE:
LOG_DEBUG("TYPE \"%s\"\n", buffer);
FK_DEBUG("TYPE \"%s\"\n", buffer);
break;
case STATE_KEY:
@ -384,14 +385,14 @@ bool parse_config_line(char *line, mapping_list_t *list,
break;
case STATE_MAP:
LOG_DEBUG("MAP gpio_mask 0x%04X to key %d, button_count %d\n",
FK_DEBUG("MAP gpio_mask 0x%04X to key %d, button_count %d\n",
gpio_mask, key, button_count);
existing_mapping = find_mapping(list, gpio_mask);
if (existing_mapping != NULL) {
LOG_DEBUG("Existing mapping with gpio_mask 0x%04X found\n",
FK_DEBUG("Existing mapping with gpio_mask 0x%04X found\n",
gpio_mask);
if (remove_mapping(list, existing_mapping) == false) {
LOG_ERROR("Cannot remove mapping with gpio_mask 0x%04X\n",
FK_ERROR("Cannot remove mapping with gpio_mask 0x%04X\n",
gpio_mask);
return false;
}
@ -402,7 +403,7 @@ bool parse_config_line(char *line, mapping_list_t *list,
new_mapping.type = MAPPING_KEY;
new_mapping.value.keycode = key;
if (insert_mapping(list, &new_mapping) == false) {
LOG_ERROR("Cannot add mapping with gpio_mask 0x%04X\n",
FK_ERROR("Cannot add mapping with gpio_mask 0x%04X\n",
gpio_mask);
return false;
}
@ -410,22 +411,22 @@ bool parse_config_line(char *line, mapping_list_t *list,
break;
default:
LOG_ERROR("Invalid keyword %d\n", keyword);
FK_ERROR("Invalid keyword %d\n", keyword);
return false;
}
break;
case STATE_COMMAND:
LOG_DEBUG("MAP gpio_mask 0x%04X to command \"%s\", button_count %d\n",
FK_DEBUG("MAP gpio_mask 0x%04X to command \"%s\", button_count %d\n",
gpio_mask, buffer, button_count);
LOG_DEBUG("MAP gpio_mask 0x%04X to key %d, button_count %d\n",
FK_DEBUG("MAP gpio_mask 0x%04X to key %d, button_count %d\n",
gpio_mask, key, button_count);
existing_mapping = find_mapping(list, gpio_mask);
if (existing_mapping != NULL) {
LOG_DEBUG("Existing mapping with gpio_mask 0x%04X found\n",
FK_DEBUG("Existing mapping with gpio_mask 0x%04X found\n",
gpio_mask);
if (remove_mapping(list, existing_mapping) == false) {
LOG_ERROR("Cannot remove mapping with gpio_mask 0x%04X\n",
FK_ERROR("Cannot remove mapping with gpio_mask 0x%04X\n",
gpio_mask);
return false;
}
@ -436,7 +437,7 @@ bool parse_config_line(char *line, mapping_list_t *list,
new_mapping.type = MAPPING_COMMAND;
new_mapping.value.command = buffer;
if (insert_mapping(list, &new_mapping) == false) {
LOG_ERROR("Cannot add mapping with gpio_mask 0x%04X\n",
FK_ERROR("Cannot add mapping with gpio_mask 0x%04X\n",
gpio_mask);
return false;
}
@ -450,7 +451,7 @@ bool parse_config_line(char *line, mapping_list_t *list,
break;
default:
LOG_ERROR("Unknown result state %d\n", state);
FK_ERROR("Unknown result state %d\n", state);
return false;
}
return true;
@ -464,13 +465,13 @@ bool parse_config_file(const char *name, mapping_list_t *list,
int line_number = 0;
if ((fp = fopen(name, "r")) == NULL) {
LOG_ERROR("Cannot open file \"%s\"\n", name);
FK_ERROR("Cannot open file \"%s\"\n", name);
return false;
}
while (!feof(fp)) {
if (fgets(line, MAX_LINE_LENGTH, fp) != line) {
if (!feof(fp)) {
LOG_ERROR("Error reading file \"%s\": %s\n", name,
FK_ERROR("Error reading file \"%s\": %s\n", name,
strerror(errno));
fclose(fp);
return false;
@ -488,7 +489,7 @@ bool parse_config_file(const char *name, mapping_list_t *list,
/* Parse a configuration line */
if (parse_config_line(line, list, monitored_gpio_mask) == false) {
LOG_ERROR("line %d\n", line_number);
FK_ERROR("line %d\n", line_number);
break;
}
}

View File

@ -1,86 +0,0 @@
/*
Copyright (C) 2020-2021 Michel Stempin <michel.stempin@funkey-project.com>
This file is part of the FunKey S GPIO keyboard daemon.
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
*/
/**
* @file to_log.c
* This file contains the syslog redirection functions
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <syslog.h>
/* Ordered map of log priority level and string prefix */
static char const *priority[] = {
"EMERG: ",
"ALERT: ",
"CRIT: ",
"ERR: ",
"WARNING: ",
"NOTICE: ",
"INFO: ",
"DEBUG: "
};
/* Cookie I/O function to redirect file output to syslog */
static size_t writer(void *cookie, char const *data, size_t length)
{
(void) cookie;
int p = LOG_DEBUG, l;
/* Look for a priority prefix, if any */
do {
l = strlen(priority[p]);
} while (memcmp(data, priority[p], l) && --p >= 0);
if (p < 0) {
p = LOG_INFO;
} else {
data += l;
length -= l;
}
/* Strip leading spaces */
while (*data == ' ') {
++data;
--length;
}
syslog(p, "%.*s", (int) length, data);
return length;
}
/* Dummy Cookie IO function */
static int noop(void)
{
return 0;
}
/* Cookie I/O function structure */
static cookie_io_functions_t log_fns = {
(void *) noop, (void *) writer, (void *) noop, (void *) noop
};
/* Redirect given file output descriptor to syslog */
void to_log(FILE **pfp)
{
//setvbuf(*pfp = fopencookie(NULL, "w", log_fns), NULL, _IOLBF, 0); //not working with muslc
setvbuf(*pfp, NULL, _IOLBF, 0);
}

View File

@ -1,34 +0,0 @@
/*
Copyright (C) 2021 Michel Stempin <michel.stempin@funkey-project.com>
This file is part of the FunKey S GPIO keyboard daemon.
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
*/
/**
* @file to_log.h
* This file contains the syslog redirection functions
*/
#ifndef _TO_LOG_H_
#define _TO_LOG_H_
#include <stdio.h>
void to_log(FILE **pfp);
#endif // _TO_LOG_H_

View File

@ -29,6 +29,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <syslog.h>
#include <linux/input.h>
#include <linux/uinput.h>
//#include "uinput_linux.h"
@ -41,15 +42,15 @@
#define ERROR_UINPUT
#ifdef DEBUG_UINPUT
#define LOG_DEBUG(...) printf(__VA_ARGS__);
#define FK_DEBUG(...) syslog(LOG_DEBUG, __VA_ARGS__);
#else
#define LOG_DEBUG(...)
#define FK_DEBUG(...)
#endif
#ifdef ERROR_UINPUT
#define LOG_ERROR(...) fprintf(stderr, "ERR: " __VA_ARGS__);
#define FK_ERROR(...) syslog(LOG_ERR, __VA_ARGS__);
#else
#define LOG_DEBUG(...)
#define FK_DEBUG(...)
#endif
/* For compatibility with kernels having dates on 32 bits */
@ -204,7 +205,7 @@ int sendKey(int key, int value)
ie.value = value;
ie.time.tv_sec = 0;
ie.time.tv_usec = 0;
LOG_DEBUG("sendKey: %d = %d\n", key, value);
FK_DEBUG("sendKey: %d = %d\n", key, value);
if(write(uidev_fd, &ie, sizeof(struct input_event_compat)) < 0)
die("error: write");
@ -238,7 +239,7 @@ static int sendRel(int dx, int dy)
static int sendSync(void)
{
LOG_DEBUG("sendSync\n");
FK_DEBUG("sendSync\n");
//memset(&uidev_ev, 0, sizeof(struct input_event));
struct input_event ie;
ie.type = EV_SYN;