rendered paste body/*
* Copyright (C) 2004-2005 Marc Huber <Marc.Huber@web.de>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* gpioflicker
*
* Default behaviour: Enables the error LED on a Soekris Net4501 whenever
* a packet is logged to pflog0.
*
* $Id: gpioflicker.c,v 1.2 2005/07/30 20:58:43 root Exp root $
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/gpio.h>
#include <net/if.h>
#include <net/bpf.h>
#include <errno.h>
#include <err.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sysexits.h>
#include <util.h>
#include <unistd.h>
#define SNAPLEN 64
static struct gpio_pin_op op[8];
static int devfd = -1;
static int led_on_val = GPIO_PIN_LOW;
static int led_off_val = GPIO_PIN_HIGH;
static char *device = "/dev/gpio0";
extern char *__progname;
static void usage(char *device, int to_ms)
{
fprintf(stderr, "\nUsage: %s [options]\n"
" Options:\n"
" -f foreground [off]\n"
" -d device gpio device [%s]\n"
" -t milliseconds minimum period to keep LED active [%d]\n"
" -n don't monopolize gpio device\n"
" -r invert LED behavior\n"
" -P write pidfile [off]\n"
" -B basename pidfile basename (implies -P) [%s]\n"
" Version: 0.1\n",
__progname, device, to_ms, __progname);
exit(EX_USAGE);
}
#define LED_STD 1
#define LED_SIG 2
static int (*gpio_ioctl)(int, unsigned long, ...) = NULL;
static int my_ioctl(int d, unsigned long request, ...)
{
int res = d = open(device, O_RDWR);
if (d > -1)
{
va_list ap;
va_start(ap, request);
res = ioctl(d, request, va_arg(ap, struct gpio_pin_op *));
close (d);
va_end(ap);
}
return res;
}
static void mod_led(int led, int led_state)
{
if(led_state == 0) {
op[led].gp_value = led_on_val;
}
else if (led_state == 1) {
op[led].gp_value = led_off_val;
}
gpio_ioctl(devfd, GPIOPINWRITE, &op[led]);
}
static void bye(int unused)
{
exit(-1);
}
int main(int argc, char **argv)
{
char *pid_base = __progname;
int ch;
int foreground = 0;
int opt_ms = 100;
int opt_pidfile = 0;
gpio_ioctl = ioctl;
memset(&op, 0, sizeof(op));
op[0].gp_pin = 5;
op[1].gp_pin = 6;
op[2].gp_pin = 7;
op[3].gp_pin = 8;
op[4].gp_pin = 21;
op[5].gp_pin = 22;
op[6].gp_pin = 11;
op[7].gp_pin = 12;
while ((ch = getopt(argc, argv, "d:fhi:p:t:PB:I:rn")) != -1) {
switch (ch) {
case 'd':
device = optarg;
break;
case 'f':
foreground = 1;
break;
case 't':
opt_ms = atoi(optarg);
break;
case 'B':
pid_base = optarg;
case 'P':
opt_pidfile = 1;
break;
case 'n':
gpio_ioctl = my_ioctl;
break;
case 'r':
led_on_val = GPIO_PIN_HIGH;
led_off_val = GPIO_PIN_LOW;
break;
default:
usage(device, opt_ms);
}
}
if (argc > optind)
usage(device, opt_ms);
if ((gpio_ioctl == ioctl) && (devfd = open(device, O_RDWR)) < 0)
err(EX_IOERR, "%s", device);
if (!foreground)
daemon(1, 0);
if (opt_pidfile)
pidfile(pid_base);
int i;
for(i = 0; i<8; ++i) {
op[i].gp_value = GPIO_PIN_LOW;
if (gpio_ioctl(devfd, GPIOPINWRITE, &op[i]) == -1) err(1, "GPIOPINWRITE");
printf("PIO %d (GPIO %d) set %d.\n",op[i].gp_pin,i,op[i].gp_value);
}
signal(SIGQUIT, bye);
signal(SIGHUP, bye);
signal(SIGTERM, bye);
//struct timeval tv;
//tv.tv_sec = 1;
//while(1) {
// mod_led(5,1);
// sleep(1);
// mod_led(5,0);
//}
if (devfd > -1)
close(devfd);
exit(EX_IOERR);
}