Send commitlog mailing list submissions to
        commitlog@lists.openmoko.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.openmoko.org/mailman/listinfo/commitlog
or, via email, send a message with subject or body 'help' to
        commitlog-requ...@lists.openmoko.org

You can reach the person managing the list at
        commitlog-ow...@lists.openmoko.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of commitlog digest..."
Today's Topics:

   1. r4925 - in developers/werner: . athintd (wer...@docs.openmoko.org)
--- Begin Message ---
Author: werner
Date: 2009-02-23 15:23:31 +0100 (Mon, 23 Feb 2009)
New Revision: 4925

Added:
   developers/werner/athintd/
   developers/werner/athintd/Makefile
   developers/werner/athintd/athintd.c
Log:
Daemon to execute an arbitrary command when the AR6k driver signals
a firmware failure. Requires the AR6k driver to be compiled with
-DSEND_EVENT_TO_APP. Work in progress.



Added: developers/werner/athintd/Makefile
===================================================================
--- developers/werner/athintd/Makefile                          (rev 0)
+++ developers/werner/athintd/Makefile  2009-02-23 14:23:31 UTC (rev 4925)
@@ -0,0 +1,35 @@
+CC=arm-angstrom-linux-gnueabi-gcc
+
+CFLAGS=-Wall -Wshadow -g -O
+LDFLAGS=-lm
+
+PREFIX=/usr
+
+NAME=athintd
+OBJS=athintd.o
+
+.PHONY:                all install uninstall clean depend spotless
+
+all:           $(NAME)
+
+$(NAME):       $(OBJS)
+
+install:       $(NAME)
+               install -D $(NAME) $(PREFIX)/bin/$(NAME)
+
+uninstall:
+               rm -f $(PREFIX)/bin/$(NAME)
+
+depend:
+               $(CPP) $(CFLAGS) -MM -MG *.c >.depend || \
+                 { rm -f .depend; exit 1; }
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
+clean:
+               rm -f $(OBJS) .depend
+
+spotless:      clean
+               rm -f $(NAME)

Added: developers/werner/athintd/athintd.c
===================================================================
--- developers/werner/athintd/athintd.c                         (rev 0)
+++ developers/werner/athintd/athintd.c 2009-02-23 14:23:31 UTC (rev 4925)
@@ -0,0 +1,183 @@
+/*
+ * athintd.c - Atheros AR6k Interrupt Handling Daemon
+ *
+ * Copyright (C) 2009 by OpenMoko, Inc.
+ * Written by Werner Almesberger <wer...@openmoko.org>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/if.h>
+#include <linux/if_link.h>
+#include <linux/wireless.h>
+
+
+#define        WMI_ERROR_REPORT_EVENTID        (0x1001+1022-1010)
+
+
+/*
+ * struct iw_point is traditionally accessed with weird pointer operations.
+ * We keep it simple and just use what's there :-)
+ */
+
+struct iw_point_msg {
+       uint16_t        length;         /* number of fields or size in bytes */
+       uint16_t        flags;          /* Optional params */
+};
+
+
+static int debug;
+static const char *cmd;
+
+
+#if 0
+
+            ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
+                                     (A_UINT8 *)&errEvent,
+                                     sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
+
+    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+
+RTM_NEWLINK
+#endif
+
+
+static void custom(const void *data, int len)
+{
+       uint16_t id;
+
+       if (debug)
+               fprintf(stderr, "ID 0x%02x 0%02x\n",
+                   ((const uint8_t *) data)[0],
+                   ((const uint8_t *) data)[1]);
+       if (len < 2)
+               return;
+       memcpy(&id, data, 2);
+       if (id != WMI_ERROR_REPORT_EVENTID)
+               return;
+       syslog(LOG_ERR, "running %s", cmd);
+       system(cmd);
+}
+
+
+static void wireless(const void *data, int len)
+{
+       const void *pos, *end = data+len;
+       struct iw_event iwe;
+       struct iw_point_msg iw_point;
+       const void *payload;
+
+       for (pos = data; pos+IW_EV_LCP_LEN <= end; pos += iwe.len) {
+               memcpy(&iwe, pos, IW_EV_LCP_LEN);
+               if (debug)
+                       fprintf(stderr, "CMD 0x%04x\n", iwe.cmd);
+               if (iwe.len <= IW_EV_LCP_LEN)
+                       return;
+               if (iwe.cmd != IWEVCUSTOM)
+                       continue;
+               memcpy(&iw_point, pos+IW_EV_LCP_LEN, sizeof(iw_point));
+               if (debug)
+                       fprintf(stderr, "len %u flags 0x%x\n",
+                           iw_point.length, iw_point.flags);
+               payload = pos+IW_EV_LCP_LEN+sizeof(iw_point);
+               if (payload+iw_point.length > end)
+                       return;
+               custom(payload, iw_point.length);
+       }
+}
+
+
+static void newlink(const struct ifinfomsg *msg, ssize_t len)
+{
+       const struct rtattr *attr;
+
+       for (attr = IFLA_RTA(msg); RTA_OK(attr, len);
+           attr = RTA_NEXT(attr, len))
+               if (attr->rta_type == IFLA_WIRELESS)
+                       wireless(RTA_DATA(attr), RTA_PAYLOAD(attr));
+}
+
+
+static void msg(const void *buf, ssize_t len)
+{
+       const struct nlmsghdr *hdr;
+
+       for (hdr = buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
+               switch (hdr->nlmsg_type) {
+               case NLMSG_NOOP:
+               case NLMSG_OVERRUN:
+               case NLMSG_DONE:
+               case NLMSG_ERROR:
+                       return;
+               case RTM_NEWLINK:
+                       newlink(NLMSG_DATA(hdr), IFLA_PAYLOAD(hdr));
+                       break;
+               }
+       }
+}
+
+
+static void loop(void)
+{
+       struct sockaddr_nl addr;
+       int s;
+       ssize_t got;
+
+       s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+       if (s < 0) {
+               perror("socket");
+               exit(1);
+       }
+
+       memset(&addr, 0, sizeof(addr));
+       addr.nl_family = AF_NETLINK;
+       addr.nl_groups = RTMGRP_LINK;
+
+       if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               perror("bind");
+                exit(1);
+        }
+
+       while (1) {
+               char buf[4096];
+
+               got = read(s, buf, sizeof(buf));
+               if (got < 0) {
+                       perror("read");
+                       exit(1);
+               }
+               msg(buf, got);
+       }
+}
+
+
+static void usage(const char *name)
+{
+       fprintf(stderr, "usage: %s command\n", name);
+       exit(1);
+}
+
+
+int main(int argc, char **argv)
+{
+       if (argc != 2)
+               usage(*argv);
+       cmd = argv[1];
+       openlog("athintd", LOG_CONS, LOG_USER);
+       loop();
+       return 0;
+}




--- End Message ---
_______________________________________________
commitlog mailing list
commitlog@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/commitlog

Reply via email to