diff --git a/collectd/Makefile b/collectd/Makefile
new file mode 100644
index 000000000..84d3f4407
--- /dev/null
+++ b/collectd/Makefile
@@ -0,0 +1,310 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=collectd
+PKG_VERSION:=4.10.7
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://collectd.org/files/
+PKG_MD5SUM:=f4193fdb5002ddac8159c88032a726bc
+
+PKG_FIXUP:=autoreconf
+PKG_REMOVE_FILES:=aclocal.m4 libltdl/aclocal.m4
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+COLLECTD_PLUGINS_DISABLED:= \
+ apple_sensors \
+ battery \
+ cpufreq \
+ curl_json \
+ entropy \
+ genericjmx \
+ gmond \
+ hddtemp \
+ ipmi \
+ ipvs \
+ java \
+ libvirt \
+ mbmon \
+ memcachec \
+ memcached \
+ monitorus \
+ multimeter \
+ netapp \
+ nfs \
+ notify_desktop \
+ notify_email \
+ openvz \
+ oracle \
+ perl \
+ pinba \
+ python \
+ routeros \
+ rrdcached \
+ serial \
+ swap \
+ tape \
+ tokyotyrant \
+ uuid \
+ vserver \
+ xmms \
+ zfs_arc \
+
+COLLECTD_PLUGINS_SELECTED:= \
+ apache \
+ apcups \
+ ascent \
+ bind \
+ conntrack \
+ contextswitch \
+ cpu \
+ csv \
+ curl \
+ dbi \
+ df \
+ disk \
+ dns \
+ email \
+ exec \
+ filecount \
+ fscache \
+ interface \
+ iptables \
+ irq \
+ iwinfo \
+ load \
+ logfile \
+ madwifi \
+ memory \
+ modbus \
+ mysql \
+ netlink \
+ network \
+ nginx \
+ ntpd \
+ nut \
+ olsrd \
+ onewire \
+ openvpn \
+ ping \
+ postgresql \
+ powerdns \
+ processes \
+ protocols \
+ rrdtool \
+ sensors \
+ snmp \
+ syslog \
+ tail \
+ table \
+ ted \
+ tcpconns \
+ teamspeak2 \
+ thermal \
+ unixsock \
+ uptime \
+ users \
+ vmem \
+ wireless \
+ write_http \
+
+PKG_CONFIG_DEPENDS:= \
+ $(patsubst %,CONFIG_PACKAGE_collectd-mod-%,$(subst _,-,$(COLLECTD_PLUGINS_SELECTED))) \
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+define Package/collectd/Default
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Lightweight system statistics collection daemon
+ URL:=http://verplant.org/collectd/
+endef
+
+define Package/collectd
+$(call Package/collectd/Default)
+ DEPENDS:= +libpthread +zlib +libltdl +libip4tc
+ MENU:=1
+endef
+
+define Package/collectd/description
+ collectd is a small daemon which collects system information periodically
+ and provides mechanismns to store the values in a variety of ways.
+endef
+
+ifneq ($(CONFIG_avr32),)
+ TARGET_CFLAGS += -fsigned-char
+endif
+
+# common configure args
+CONFIGURE_ARGS+= \
+ --disable-debug \
+ --enable-daemon \
+ --enable-getifaddrs \
+ --with-nan-emulation \
+ --without-libgcrypt
+
+CONFIGURE_VARS+= \
+ CFLAGS="$$$$CFLAGS $(FPIC)" \
+ LDFLAGS="$$$$LDFLAGS -lm -lz" \
+ KERNEL_DIR="$(LINUX_DIR)" \
+
+CONFIGURE_PLUGIN= \
+ $(foreach m, $(1), \
+ $(if $(CONFIG_PACKAGE_collectd-mod-$(subst _,-,$(m))),--enable-$(m),--disable-$(m)) \
+ )
+
+CONFIGURE_ARGS+= \
+ $(call CONFIGURE_PLUGIN,$(COLLECTD_PLUGINS_SELECTED)) \
+ $(call CONFIGURE_PLUGIN,$(COLLECTD_PLUGINS_DISABLED)) \
+
+# exception: mod-ascent needs libxml2
+ifneq ($(CONFIG_PACKAGE_collectd-mod-ascent),)
+ CONFIGURE_VARS+= \
+ CPPFLAGS="$$$$CPPFLAGS -I$(STAGING_DIR)/usr/include/libxml2"
+endif
+
+ifneq ($(CONFIG_BIG_ENDIAN),)
+ CONFIGURE_ARGS+= --with-fp-layout=endianflip
+else
+ CONFIGURE_ARGS+= --with-fp-layout=nothing
+endif
+
+ifneq ($(CONFIG_PACKAGE_collectd-mod-postgresql),)
+ CONFIGURE_ARGS+= --with-libpq="$(STAGING_DIR)/usr/"
+endif
+
+ifneq ($(CONFIG_PACKAGE_collectd-mod-mysql),)
+ CONFIGURE_ARGS+= --with-libmysql="$(STAGING_DIR)/usr/"
+endif
+
+# exception: mod-netlink needs libnetlink from iproute
+ifneq ($(CONFIG_PACKAGE_collectd-mod-netlink),)
+ CONFIGURE_ARGS+= --with-libnetlink="$(STAGING_DIR)/usr"
+endif
+
+# exception: mod-modbus needs libmodbus
+ifneq ($(CONFIG_PACKAGE_collectd-mod-modbus),)
+ CONFIGURE_ARGS+= --with-libmodbus="$(STAGING_DIR)/usr"
+endif
+
+# exception: mod-onewire needs libow-capi
+ifneq ($(CONFIG_PACKAGE_collectd-mod-onewire),)
+ CONFIGURE_ARGS+= --with-libowcapi="$(STAGING_DIR)/usr"
+endif
+
+# exception: mod-rrdtool needs rrdtool-1.0.x
+ifneq ($(CONFIG_PACKAGE_collectd-mod-rrdtool),)
+ CONFIGURE_ARGS+= --with-librrd="$(STAGING_DIR)/usr/lib/rrdtool-1.0"
+endif
+
+define Package/collectd/conffiles
+/etc/collectd.conf
+endef
+
+define Package/collectd/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/collectd $(1)/usr/sbin/
+ $(INSTALL_DIR) $(1)/usr/share/collectd
+ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/collectd/types.db $(1)/usr/share/collectd/
+ $(INSTALL_DIR) $(1)/etc
+ $(INSTALL_CONF) ./files/collectd.conf $(1)/etc/
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/collectd.init $(1)/etc/init.d/collectd
+endef
+
+# 1: plugin name
+# 2: plugin title/description
+# 3: files
+# 4: extra dependency
+define BuildPlugin
+
+ PKG_CONFIG_DEPENDS+= CONFIG_PACKAGE_collectd-mod-$(1)
+
+ define Package/collectd-mod-$(1)
+ $$(call Package/collectd/Default)
+ TITLE:=$(2) plugin
+ DEPENDS:= collectd $(4)
+ endef
+
+ define Package/collectd-mod-$(1)/install
+ $(INSTALL_DIR) $$(1)/usr/lib/collectd
+ for m in $(3); do \
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/lib/collectd/$$$$$$$${m}.so \
+ $$(1)/usr/lib/collectd/ ; \
+ done
+ endef
+
+ $$(eval $$(call BuildPackage,collectd-mod-$(1)))
+
+endef
+
+$(eval $(call BuildPackage,collectd))
+
+#$(eval $(call BuildPlugin,NAME,DESCRIPTION,FILES,DEPENDENCIES))
+$(eval $(call BuildPlugin,apache,apache status input,apache,+PACKAGE_collectd-mod-apache:libcurl))
+$(eval $(call BuildPlugin,apcups,apcups status input,apcups,))
+$(eval $(call BuildPlugin,ascent,ascent status input,ascent,+PACKAGE_collectd-mod-ascent:libcurl +PACKAGE_collectd-mod-ascent:libxml2))
+$(eval $(call BuildPlugin,bind,BIND server/zone input,bind,+PACKAGE_collectd-mod-bind:libcurl +PACKAGE_collectd-mod-bind:libxml2))
+$(eval $(call BuildPlugin,conntrack,connection tracking table size input,conntrack,))
+$(eval $(call BuildPlugin,contextswitch,context switch input,contextswitch,))
+$(eval $(call BuildPlugin,cpu,CPU input,cpu,))
+$(eval $(call BuildPlugin,csv,CSV output,csv,))
+$(eval $(call BuildPlugin,curl,cURL input,curl,+PACKAGE_collectd-mod-curl:libcurl))
+$(eval $(call BuildPlugin,dbi,relational database input,dbi,+PACKAGE_collectd-mod-dbi:libdbi))
+$(eval $(call BuildPlugin,df,disk space input,df,))
+$(eval $(call BuildPlugin,disk,disk usage/timing input,disk,))
+$(eval $(call BuildPlugin,dns,DNS traffic input,dns,+PACKAGE_collectd-mod-dns:libpcap))
+$(eval $(call BuildPlugin,email,email output,email,))
+$(eval $(call BuildPlugin,exec,process exec input,exec,))
+$(eval $(call BuildPlugin,filecount,file count input,filecount,))
+$(eval $(call BuildPlugin,fscache,file-system based caching framework input,fscache,))
+$(eval $(call BuildPlugin,interface,network interfaces input,interface,))
+$(eval $(call BuildPlugin,iptables,iptables status input,iptables,+PACKAGE_collectd-mod-iptables:iptables +libiptc))
+$(eval $(call BuildPlugin,irq,interrupt usage input,irq,))
+$(eval $(call BuildPlugin,iwinfo,libiwinfo wireless statistics,iwinfo,+PACKAGE_collectd-mod-iwinfo:libiwinfo))
+$(eval $(call BuildPlugin,load,system load input,load,))
+$(eval $(call BuildPlugin,logfile,log files output,logfile,))
+$(eval $(call BuildPlugin,madwifi,MadWifi status input,madwifi,))
+$(eval $(call BuildPlugin,mysql,MySQL status input,mysql,+PACKAGE_collectd-mod-mysql:libmysqlclient-r))
+$(eval $(call BuildPlugin,memory,physical memory usage input,memory,))
+$(eval $(call BuildPlugin,modbus,read variables through libmodbus,modbus,+PACKAGE_collectd-mod-modbus:libmodbus @BROKEN))
+$(eval $(call BuildPlugin,netlink,netlink input,netlink,+PACKAGE_collectd-mod-netlink:ip))
+$(eval $(call BuildPlugin,network,network input/output,network))
+$(eval $(call BuildPlugin,nginx,nginx status input,nginx,+PACKAGE_collectd-mod-nginx:libcurl))
+$(eval $(call BuildPlugin,ntpd,NTP daemon status input,ntpd,))
+$(eval $(call BuildPlugin,nut,UPS monitoring input,nut,@BROKEN))
+$(eval $(call BuildPlugin,olsrd,OLSRd status input,olsrd,))
+$(eval $(call BuildPlugin,onewire,onewire sensor input,onewire,+PACKAGE_collectd-mod-onewire:libow-capi @BROKEN))
+$(eval $(call BuildPlugin,openvpn,OpenVPN traffic/compression input,openvpn,))
+$(eval $(call BuildPlugin,ping,ping status input,ping,+PACKAGE_collectd-mod-ping:liboping))
+$(eval $(call BuildPlugin,postgresql,PostgreSQL status input,postgresql,+PACKAGE_collectd-mod-postgresql:libpq))
+$(eval $(call BuildPlugin,powerdns,PowerDNS server status input,powerdns,))
+$(eval $(call BuildPlugin,processes,process status input,processes,))
+$(eval $(call BuildPlugin,protocols,network protocols input,protocols,))
+$(eval $(call BuildPlugin,rrdtool,RRDtool output,rrdtool,+PACKAGE_collectd-mod-rrdtool:librrd1))
+$(eval $(call BuildPlugin,sensors,lm_sensors input,sensors,+PACKAGE_collectd-mod-sensors:libsensors @BROKEN))
+$(eval $(call BuildPlugin,snmp,SNMP input,snmp,+PACKAGE_collectd-mod-snmp:libnetsnmp))
+$(eval $(call BuildPlugin,syslog,syslog output,syslog,))
+$(eval $(call BuildPlugin,tail,tail input,tail,))
+$(eval $(call BuildPlugin,table,table-like structured file input,table,))
+$(eval $(call BuildPlugin,teamspeak2,TeamSpeak2 input,teamspeak2,))
+$(eval $(call BuildPlugin,ted,The Energy Detective input,ted,@((!TARGET_avr32)||BROKEN))) # fails on avr32 because of warnings treated as errors
+$(eval $(call BuildPlugin,tcpconns,TCP connection tracking input,tcpconns,))
+$(eval $(call BuildPlugin,thermal,system temperatures input,thermal,))
+$(eval $(call BuildPlugin,unixsock,unix socket output,unixsock,))
+$(eval $(call BuildPlugin,uptime,uptime status input,uptime,))
+$(eval $(call BuildPlugin,users,user logged in status input,users,))
+$(eval $(call BuildPlugin,vmem,virtual memory usage input,vmem,))
+$(eval $(call BuildPlugin,wireless,wireless status input,wireless,))
+$(eval $(call BuildPlugin,write-http,HTTP POST output,write_http,+PACKAGE_collectd-mod-write-http:libcurl))
diff --git a/collectd/files/collectd.conf b/collectd/files/collectd.conf
new file mode 100644
index 000000000..2ef78fe7f
--- /dev/null
+++ b/collectd/files/collectd.conf
@@ -0,0 +1,90 @@
+#
+# OpenWrt Config file for collectd(1).
+# Please read collectd.conf(5) for a list of options.
+# http://collectd.org/
+#
+
+#Hostname "localhost"
+#FQDNLookup true
+BaseDir "/var/lib/collectd"
+PIDFile "/var/run/collectd.pid"
+#PluginDir "/usr/lib/collectd"
+#TypesDB "/usr/share/collectd/types.db"
+Interval 30
+ReadThreads 2
+
+#LoadPlugin syslog
+#LoadPlugin logfile
+
+#
+# LogLevel info
+#
+
+#
+# LogLevel info
+# File STDOUT
+# Timestamp true
+#
+
+LoadPlugin cpu
+LoadPlugin df
+LoadPlugin disk
+LoadPlugin interface
+LoadPlugin load
+LoadPlugin memory
+LoadPlugin network
+#LoadPlugin ping
+#LoadPlugin processes
+#LoadPlugin rrdtool
+#LoadPlugin serial
+LoadPlugin wireless
+
+#
+# FSType tmpfs
+# IgnoreSelected true
+# ReportByDevice false
+# ReportReserved false
+# ReportInodes false
+#
+
+#
+# Disk "/^[hs]d[a-f][0-9]?$/"
+# IgnoreSelected false
+#
+
+#
+# Interface "eth0"
+# Interface "br-lan"
+# IgnoreSelected false
+#
+
+
+# Server "ff18::efc0:4a42" "25826"
+ Server "239.192.74.66" "25826"
+# Listen "ff18::efc0:4a42" "25826"
+# Listen "239.192.74.66" "25826"
+# TimeToLive "128"
+# Forward false
+# CacheFlush 1800
+# ReportStats false
+
+
+#
+# Host "host.foo.bar"
+# Interval 1.0
+# Timeout 0.9
+# TTL 255
+# SourceAddress "1.2.3.4"
+# Device "eth0"
+# MaxMissed -1
+#
+
+#
+# Process "name"
+#
+
+#
+# DataDir "/var/lib/collectd/rrd"
+# CacheTimeout 120
+# CacheFlush 900
+#
diff --git a/collectd/files/collectd.init b/collectd/files/collectd.init
new file mode 100644
index 000000000..8204c38ac
--- /dev/null
+++ b/collectd/files/collectd.init
@@ -0,0 +1,15 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006-2011 OpenWrt.org
+
+START=80
+
+SERVICE_USE_PID=1
+
+start() {
+ mkdir -m 0755 -p /var/lib/collectd
+ service_start /usr/sbin/collectd
+}
+
+stop() {
+ service_stop /usr/sbin/collectd
+}
diff --git a/collectd/patches/001-undefined-AM_PATH_LIBGCRYPT.patch b/collectd/patches/001-undefined-AM_PATH_LIBGCRYPT.patch
new file mode 100644
index 000000000..0e01744bb
--- /dev/null
+++ b/collectd/patches/001-undefined-AM_PATH_LIBGCRYPT.patch
@@ -0,0 +1,4 @@
+--- /dev/null
++++ b/fake-am_path_libgcrypt.m4
+@@ -0,0 +1 @@
++AC_DEFUN([AM_PATH_LIBGCRYPT],[:])
diff --git a/collectd/patches/003-remove-werror.patch b/collectd/patches/003-remove-werror.patch
new file mode 100644
index 000000000..5a4fb53e2
--- /dev/null
+++ b/collectd/patches/003-remove-werror.patch
@@ -0,0 +1,66 @@
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -7,7 +7,7 @@ SUBDIRS += liboconfig
+ endif
+
+ if COMPILER_IS_GCC
+-AM_CFLAGS = -Wall -Werror
++AM_CFLAGS = -Wall
+ endif
+
+ AM_CPPFLAGS = -DPREFIX='"${prefix}"'
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -1836,7 +1836,7 @@ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ SUBDIRS = libcollectdclient $(am__append_1) $(am__append_2)
+-@COMPILER_IS_GCC_TRUE@AM_CFLAGS = -Wall -Werror
++@COMPILER_IS_GCC_TRUE@AM_CFLAGS = -Wall
+ AM_CPPFLAGS = -DPREFIX='"${prefix}"' \
+ -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' \
+ -DLOCALSTATEDIR='"${localstatedir}"' \
+--- a/src/libcollectdclient/Makefile.am
++++ b/src/libcollectdclient/Makefile.am
+@@ -1,7 +1,7 @@
+ AUTOMAKE_OPTIONS = foreign no-dependencies
+
+ if COMPILER_IS_GCC
+-AM_CFLAGS = -Wall -Werror
++AM_CFLAGS = -Wall
+ endif
+
+ pkginclude_HEADERS = client.h lcc_features.h
+--- a/src/libcollectdclient/Makefile.in
++++ b/src/libcollectdclient/Makefile.in
+@@ -329,7 +329,7 @@ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ AUTOMAKE_OPTIONS = foreign no-dependencies
+-@COMPILER_IS_GCC_TRUE@AM_CFLAGS = -Wall -Werror
++@COMPILER_IS_GCC_TRUE@AM_CFLAGS = -Wall
+ pkginclude_HEADERS = client.h lcc_features.h
+ lib_LTLIBRARIES = libcollectdclient.la
+ nodist_pkgconfig_DATA = libcollectdclient.pc
+--- a/src/owniptc/Makefile.am
++++ b/src/owniptc/Makefile.am
+@@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = foreign no-dependenci
+ EXTRA_DIST = libiptc.c README.collectd
+
+ if COMPILER_IS_GCC
+-AM_CFLAGS = -Wall -Werror
++AM_CFLAGS = -Wall
+ endif
+
+ noinst_LTLIBRARIES = libiptc.la
+--- a/src/owniptc/Makefile.in
++++ b/src/owniptc/Makefile.in
+@@ -298,7 +298,7 @@ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ AUTOMAKE_OPTIONS = foreign no-dependencies
+ EXTRA_DIST = libiptc.c README.collectd
+-@COMPILER_IS_GCC_TRUE@AM_CFLAGS = -Wall -Werror
++@COMPILER_IS_GCC_TRUE@AM_CFLAGS = -Wall
+ noinst_LTLIBRARIES = libiptc.la
+ libiptc_la_SOURCES = libip4tc.c libip6tc.c \
+ ipt_kernel_headers.h libip6tc.h libiptc.h linux_list.h \
diff --git a/collectd/patches/100-rrdtool-add-rrasingle-option.patch b/collectd/patches/100-rrdtool-add-rrasingle-option.patch
new file mode 100644
index 000000000..ce1daa473
--- /dev/null
+++ b/collectd/patches/100-rrdtool-add-rrasingle-option.patch
@@ -0,0 +1,57 @@
+--- a/src/rrdtool.c
++++ b/src/rrdtool.c
+@@ -80,6 +80,7 @@ static const char *config_keys[] =
+ "HeartBeat",
+ "RRARows",
+ "RRATimespan",
++ "RRASingle",
+ "XFF",
+ "WritesPerSecond",
+ "RandomTimeout"
+@@ -101,6 +102,8 @@ static rrdcreate_config_t rrdcreate_conf
+ /* timespans = */ NULL,
+ /* timespans_num = */ 0,
+
++ /* rrasingle = */ 0,
++
+ /* consolidation_functions = */ NULL,
+ /* consolidation_functions_num = */ 0
+ };
+@@ -1027,6 +1030,14 @@ static int rrd_config (const char *key,
+
+ free (value_copy);
+ }
++ else if (strcasecmp ("RRASingle", key) == 0)
++ {
++ if (IS_TRUE (value))
++ {
++ rrdcreate_config.rrasingle = 1;
++ NOTICE ("rrdtool plugin: RRASingle = true: creating only AVERAGE RRAs");
++ }
++ }
+ else if (strcasecmp ("XFF", key) == 0)
+ {
+ double tmp = atof (value);
+--- a/src/utils_rrdcreate.c
++++ b/src/utils_rrdcreate.c
+@@ -122,6 +122,9 @@ static int rra_get (char ***ret, const v
+ rts_num = rra_timespans_num;
+ }
+
++ if (cfg->rrasingle)
++ rra_types_num = 1;
++
+ rra_max = rts_num * rra_types_num;
+
+ if ((rra_def = (char **) malloc ((rra_max + 1) * sizeof (char *))) == NULL)
+--- a/src/utils_rrdcreate.h
++++ b/src/utils_rrdcreate.h
+@@ -36,6 +36,8 @@ struct rrdcreate_config_s
+ int *timespans;
+ size_t timespans_num;
+
++ int rrasingle;
++
+ char **consolidation_functions;
+ size_t consolidation_functions_num;
+ };
diff --git a/collectd/patches/110-net-device-stats.patch b/collectd/patches/110-net-device-stats.patch
new file mode 100644
index 000000000..91e73aa37
--- /dev/null
+++ b/collectd/patches/110-net-device-stats.patch
@@ -0,0 +1,46 @@
+---
+ src/interface.c | 33 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 32 insertions(+), 1 deletion(-)
+
+--- a/src/interface.c
++++ b/src/interface.c
+@@ -203,7 +203,38 @@ static int interface_read (void)
+ # define IFA_RX_ERROR rx_errors
+ # define IFA_TX_ERROR tx_errors
+ #else
+-# error "No suitable type for `struct ifaddrs->ifa_data' found."
++struct net_device_stats {
++ unsigned long rx_packets;
++ unsigned long tx_packets;
++ unsigned long rx_bytes;
++ unsigned long tx_bytes;
++ unsigned long rx_errors;
++ unsigned long tx_errors;
++ unsigned long rx_dropped;
++ unsigned long tx_dropped;
++ unsigned long multicast;
++ unsigned long collisions;
++ unsigned long rx_length_errors;
++ unsigned long rx_over_errors;
++ unsigned long rx_crc_errors;
++ unsigned long rx_frame_errors;
++ unsigned long rx_fifo_errors;
++ unsigned long rx_missed_errors;
++ unsigned long tx_aborted_errors;
++ unsigned long tx_carrier_errors;
++ unsigned long tx_fifo_errors;
++ unsigned long tx_heartbeat_errors;
++ unsigned long tx_window_errors;
++ unsigned long rx_compressed;
++ unsigned long tx_compressed;
++};
++# define IFA_DATA net_device_stats
++# define IFA_RX_BYTES rx_bytes
++# define IFA_TX_BYTES tx_bytes
++# define IFA_RX_PACKT rx_packets
++# define IFA_TX_PACKT tx_packets
++# define IFA_RX_ERROR rx_errors
++# define IFA_TX_ERROR tx_errors
+ #endif
+
+ struct IFA_DATA *if_data;
diff --git a/collectd/patches/120-fix_kernel_2.6.37.patch b/collectd/patches/120-fix_kernel_2.6.37.patch
new file mode 100644
index 000000000..cca445af5
--- /dev/null
+++ b/collectd/patches/120-fix_kernel_2.6.37.patch
@@ -0,0 +1,78 @@
+--- a/src/owniptc/libiptc.c
++++ b/src/owniptc/libiptc.c
+@@ -81,11 +81,11 @@ static const char *hooknames[] = {
+ };
+
+ /* Convenience structures */
+-struct ipt_error_target
++ struct ipt_error_target2
+ {
+ STRUCT_ENTRY_TARGET t;
+ char error[TABLE_MAXNAMELEN];
+-};
++};
+
+ struct chain_head;
+ struct rule_head;
+@@ -1007,10 +1007,10 @@ static int parse_table(TC_HANDLE_T h)
+ /* Convenience structures */
+ struct iptcb_chain_start{
+ STRUCT_ENTRY e;
+- struct ipt_error_target name;
++ struct ipt_error_target2 name;
+ };
+ #define IPTCB_CHAIN_START_SIZE (sizeof(STRUCT_ENTRY) + \
+- ALIGN(sizeof(struct ipt_error_target)))
++ ALIGN(sizeof(struct ipt_error_target2)))
+
+ struct iptcb_chain_foot {
+ STRUCT_ENTRY e;
+@@ -1021,10 +1021,10 @@ struct iptcb_chain_foot {
+
+ struct iptcb_chain_error {
+ STRUCT_ENTRY entry;
+- struct ipt_error_target target;
++ struct ipt_error_target2 target;
+ };
+ #define IPTCB_CHAIN_ERROR_SIZE (sizeof(STRUCT_ENTRY) + \
+- ALIGN(sizeof(struct ipt_error_target)))
++ ALIGN(sizeof(struct ipt_error_target2)))
+
+
+
+@@ -1069,7 +1069,7 @@ static int iptcc_compile_chain(TC_HANDLE
+ head->e.next_offset = IPTCB_CHAIN_START_SIZE;
+ strcpy(head->name.t.u.user.name, ERROR_TARGET);
+ head->name.t.u.target_size =
+- ALIGN(sizeof(struct ipt_error_target));
++ ALIGN(sizeof(struct ipt_error_target2));
+ strcpy(head->name.error, c->name);
+ } else {
+ repl->hook_entry[c->hooknum-1] = c->head_offset;
+@@ -1113,7 +1113,7 @@ static int iptcc_compile_chain_offsets(T
+ if (!iptcc_is_builtin(c)) {
+ /* Chain has header */
+ *offset += sizeof(STRUCT_ENTRY)
+- + ALIGN(sizeof(struct ipt_error_target));
++ + ALIGN(sizeof(struct ipt_error_target2));
+ (*num)++;
+ }
+
+@@ -1153,7 +1153,7 @@ static int iptcc_compile_table_prep(TC_H
+ /* Append one error rule at end of chain */
+ num++;
+ offset += sizeof(STRUCT_ENTRY)
+- + ALIGN(sizeof(struct ipt_error_target));
++ + ALIGN(sizeof(struct ipt_error_target2));
+
+ /* ruleset size is now in offset */
+ *size = offset;
+@@ -1177,7 +1177,7 @@ static int iptcc_compile_table(TC_HANDLE
+ error->entry.target_offset = sizeof(STRUCT_ENTRY);
+ error->entry.next_offset = IPTCB_CHAIN_ERROR_SIZE;
+ error->target.t.u.user.target_size =
+- ALIGN(sizeof(struct ipt_error_target));
++ ALIGN(sizeof(struct ipt_error_target2));
+ strcpy((char *)&error->target.t.u.user.name, ERROR_TARGET);
+ strcpy((char *)&error->target.error, "ERROR");
+
diff --git a/collectd/patches/130-fix_netlink_kernel_3.3-patch b/collectd/patches/130-fix_netlink_kernel_3.3-patch
new file mode 100644
index 000000000..9cb88309d
--- /dev/null
+++ b/collectd/patches/130-fix_netlink_kernel_3.3-patch
@@ -0,0 +1,50 @@
+Index: collectd-4.10.7/src/netlink.c
+===================================================================
+--- collectd-4.10.7.orig/src/netlink.c 2012-04-01 16:20:24.000000000 +0200
++++ collectd-4.10.7/src/netlink.c 2012-06-07 17:22:16.212616882 +0200
+@@ -223,7 +223,7 @@
+
+ msg = NLMSG_DATA (nmh);
+
+- msg_len = nmh->nlmsg_len - sizeof (struct ifinfomsg);
++ msg_len = nmh->nlmsg_len - NLMSG_LENGTH(sizeof (struct ifinfomsg));
+ if (msg_len < 0)
+ {
+ ERROR ("netlink plugin: link_filter: msg_len = %i < 0;", msg_len);
+@@ -554,24 +554,19 @@
+
+ static int ir_read (void)
+ {
+- struct ifinfomsg im;
+ struct tcmsg tm;
+ int ifindex;
+
+ static const int type_id[] = { RTM_GETQDISC, RTM_GETTCLASS, RTM_GETTFILTER };
+ static const char *type_name[] = { "qdisc", "class", "filter" };
+
+- memset (&im, '\0', sizeof (im));
+- im.ifi_type = AF_UNSPEC;
+-
+- if (rtnl_dump_request (&rth, RTM_GETLINK, &im, sizeof (im)) < 0)
++ if (rtnl_wilddump_request (&rth, AF_UNSPEC, RTM_GETLINK) < 0)
+ {
+ ERROR ("netlink plugin: ir_read: rtnl_dump_request failed.");
+ return (-1);
+ }
+
+- if (rtnl_dump_filter (&rth, link_filter, /* arg1 = */ NULL,
+- NULL, NULL) != 0)
++ if (rtnl_dump_filter (&rth, link_filter, /* arg1 = */ NULL) != 0)
+ {
+ ERROR ("netlink plugin: ir_read: rtnl_dump_filter failed.");
+ return (-1);
+@@ -608,8 +603,7 @@
+ continue;
+ }
+
+- if (rtnl_dump_filter (&rth, qos_filter, (void *) &ifindex,
+- NULL, NULL) != 0)
++ if (rtnl_dump_filter (&rth, qos_filter, (void *) &ifindex) != 0)
+ {
+ ERROR ("netlink plugin: ir_read: rtnl_dump_filter failed.");
+ continue;
diff --git a/collectd/patches/200-fix-git-describe-error.patch b/collectd/patches/200-fix-git-describe-error.patch
new file mode 100644
index 000000000..09e914ab6
--- /dev/null
+++ b/collectd/patches/200-fix-git-describe-error.patch
@@ -0,0 +1,11 @@
+--- a/version-gen.sh
++++ b/version-gen.sh
+@@ -2,7 +2,7 @@
+
+ DEFAULT_VERSION="4.10.7.git"
+
+-VERSION="`git describe 2> /dev/null | sed -e 's/^collectd-//'`"
++#VERSION="`git describe 2> /dev/null | sed -e 's/^collectd-//'`"
+
+ if test -z "$VERSION"; then
+ VERSION="$DEFAULT_VERSION"
diff --git a/collectd/patches/400-fix-olsrd-get-all.patch b/collectd/patches/400-fix-olsrd-get-all.patch
new file mode 100644
index 000000000..b49a0e739
--- /dev/null
+++ b/collectd/patches/400-fix-olsrd-get-all.patch
@@ -0,0 +1,11 @@
+--- a/src/olsrd.c
++++ b/src/olsrd.c
+@@ -653,7 +653,7 @@ static int olsrd_read (void) /* {{{ */
+ if (fh == NULL)
+ return (-1);
+
+- fputs ("\r\n", fh);
++ fputs ("/all \r\n", fh);
+ fflush (fh);
+
+ while (fgets (buffer, sizeof (buffer), fh) != NULL)
diff --git a/collectd/patches/900-add-iwinfo-plugin.patch b/collectd/patches/900-add-iwinfo-plugin.patch
new file mode 100644
index 000000000..98945863c
--- /dev/null
+++ b/collectd/patches/900-add-iwinfo-plugin.patch
@@ -0,0 +1,275 @@
+--- a/configure.in
++++ b/configure.in
+@@ -490,6 +490,9 @@ AC_CHECK_HEADERS(netinet/if_ether.h, [],
+ have_termios_h="no"
+ AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"])
+
++# For the iwinfo plugin
++AC_CHECK_LIB(iwinfo, iwinfo_backend, [with_iwinfo="yes"], [with_iwinfo="no (libiwinfo not found)"], [])
++
+ #
+ # Checks for typedefs, structures, and compiler characteristics.
+ #
+@@ -4008,6 +4011,7 @@ plugin_interface="no"
+ plugin_ipmi="no"
+ plugin_ipvs="no"
+ plugin_irq="no"
++plugin_iwinfo="no"
+ plugin_libvirt="no"
+ plugin_load="no"
+ plugin_memory="no"
+@@ -4315,6 +4319,7 @@ AC_PLUGIN([ipmi], [$plugin_ipmi],
+ AC_PLUGIN([iptables], [$with_libiptc], [IPTables rule counters])
+ AC_PLUGIN([ipvs], [$plugin_ipvs], [IPVS connection statistics])
+ AC_PLUGIN([irq], [$plugin_irq], [IRQ statistics])
++AC_PLUGIN([iwinfo], [$with_iwinfo], [Common iwinfo wireless statistics])
+ AC_PLUGIN([java], [$with_java], [Embed the Java Virtual Machine])
+ AC_PLUGIN([libvirt], [$plugin_libvirt], [Virtual machine statistics])
+ AC_PLUGIN([load], [$plugin_load], [System load])
+@@ -4593,6 +4598,7 @@ Configuration:
+ protobuf-c . . . . . $have_protoc_c
+ oracle . . . . . . . $with_oracle
+ python . . . . . . . $with_python
++ iwinfo . . . . . . . $with_iwinfo
+
+ Features:
+ daemon mode . . . . . $enable_daemon
+@@ -4632,6 +4638,7 @@ Configuration:
+ iptables . . . . . . $enable_iptables
+ ipvs . . . . . . . . $enable_ipvs
+ irq . . . . . . . . . $enable_irq
++ iwinfo . . . . . . . $enable_iwinfo
+ java . . . . . . . . $enable_java
+ libvirt . . . . . . . $enable_libvirt
+ load . . . . . . . . $enable_load
+--- a/src/collectd.conf.in
++++ b/src/collectd.conf.in
+@@ -82,6 +82,7 @@ FQDNLookup true
+ #@BUILD_PLUGIN_IPMI_TRUE@LoadPlugin ipmi
+ #@BUILD_PLUGIN_IPVS_TRUE@LoadPlugin ipvs
+ #@BUILD_PLUGIN_IRQ_TRUE@LoadPlugin irq
++#@BUILD_PLUGIN_IWINFO_TRUE@LoadPlugin iwinfo
+ #@BUILD_PLUGIN_JAVA_TRUE@LoadPlugin java
+ #@BUILD_PLUGIN_LIBVIRT_TRUE@LoadPlugin libvirt
+ @BUILD_PLUGIN_LOAD_TRUE@@BUILD_PLUGIN_LOAD_TRUE@LoadPlugin load
+@@ -376,6 +377,12 @@ FQDNLookup true
+ # IgnoreSelected true
+ #
+
++#
++# Interface "ath0"
++# Interface "ra0"
++# Interface "wlan0"
++#
++
+ #
+ # JVMArg "-verbose:jni"
+ # JVMArg "-Djava.class.path=@prefix@/share/collectd/java/collectd-api.jar"
+--- a/src/collectd.conf.pod
++++ b/src/collectd.conf.pod
+@@ -1468,6 +1468,27 @@ and all other interrupts are collected.
+
+ =back
+
++=head2 Plugin C
++
++=over 4
++
++=item B I
++
++Select this interface. By default all detected wireless interfaces will be
++collected. For a more detailed description see B below.
++
++=item B I|I
++
++If no configuration if given, the B-plugin will collect data from all
++detected wireless interfaces. You can use the B-option to pick the
++interfaces you're interested in. Sometimes, however, it's easier/preferred to
++collect all interfaces I a few ones. This option enables you to do
++that: By setting B to I the effect of B is
++inverted: All selected interfaces are ignored and all other interfaces are
++collected.
++
++=back
++
+ =head2 Plugin C
+
+ The I plugin makes it possible to write extensions for collectd in Java.
+--- /dev/null
++++ b/src/iwinfo.c
+@@ -0,0 +1,150 @@
++/**
++ * collectd - src/iwinfo.c
++ * Copyright (C) 2011 Jo-Philipp Wich
++ *
++ * 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; only version 2 of the License is applicable.
++ *
++ * This program 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
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ **/
++
++#include "collectd.h"
++#include "common.h"
++#include "plugin.h"
++#include "utils_ignorelist.h"
++
++#include
++#include
++
++#define PROCNETDEV "/proc/net/dev"
++
++static const char *config_keys[] = {
++ "Interface",
++ "IgnoreSelected"
++};
++static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
++
++static ignorelist_t *ignorelist = NULL;
++
++static int iwinfo_config(const char *key, const char *value)
++{
++ if (ignorelist == NULL)
++ ignorelist = ignorelist_create(1);
++
++ if (ignorelist == NULL)
++ return 1;
++
++ if (strcasecmp(key, "Interface") == 0)
++ ignorelist_add(ignorelist, value);
++ else if (strcasecmp(key, "IgnoreSelected") == 0)
++ ignorelist_set_invert(ignorelist, IS_TRUE(value) ? 0 : 1);
++ else
++ return -1;
++
++ return 0;
++}
++
++static void iwinfo_submit(const char *ifname, const char *type, int value)
++{
++ value_t values[1];
++ value_list_t vl = VALUE_LIST_INIT;
++
++ values[0].gauge = value;
++
++ vl.values = values;
++ vl.values_len = 1;
++
++ sstrncpy(vl.host, hostname_g, sizeof(vl.host));
++ sstrncpy(vl.plugin, "iwinfo", sizeof(vl.plugin));
++ sstrncpy(vl.plugin_instance, ifname, sizeof(vl.plugin_instance));
++ sstrncpy(vl.type, type, sizeof(vl.type));
++ /*sstrncpy(vl.type_instance, "", sizeof(vl.type_instance));*/
++
++ plugin_dispatch_values(&vl);
++}
++
++static void iwinfo_process(const char *ifname)
++{
++ int val;
++ char buf[IWINFO_BUFSIZE];
++ const struct iwinfo_ops *iw = iwinfo_backend(ifname);
++
++ /* does appear to be a wifi iface */
++ if (iw)
++ {
++ if (iw->bitrate(ifname, &val))
++ val = 0;
++ iwinfo_submit(ifname, "bitrate", val * 1000);
++
++ if (iw->signal(ifname, &val))
++ val = 0;
++ iwinfo_submit(ifname, "signal_power", val);
++
++ if (iw->noise(ifname, &val))
++ val = 0;
++ iwinfo_submit(ifname, "signal_noise", val);
++
++ if (iw->quality(ifname, &val))
++ val = 0;
++ iwinfo_submit(ifname, "signal_quality", val);
++
++ if (iw->assoclist(ifname, buf, &val))
++ val = 0;
++ iwinfo_submit(ifname, "stations",
++ val / sizeof(struct iwinfo_assoclist_entry));
++ }
++
++ iwinfo_finish();
++}
++
++static int iwinfo_read(void)
++{
++ char line[1024];
++ char ifname[128];
++ FILE *f;
++
++ f = fopen(PROCNETDEV, "r");
++ if (f == NULL)
++ {
++ char err[1024];
++ WARNING("iwinfo: Unable to open " PROCNETDEV ": %s",
++ sstrerror(errno, err, sizeof(err)));
++ return -1;
++ }
++
++ while (fgets(line, sizeof(line), f))
++ {
++ if (!strchr(line, ':'))
++ continue;
++
++ if (!sscanf(line, " %127[^:]", ifname))
++ continue;
++
++ if (ignorelist_match(ignorelist, ifname))
++ continue;
++
++ if (strstr(ifname, "mon.") || strstr(ifname, ".sta") ||
++ strstr(ifname, "tmp.") || strstr(ifname, "wifi"))
++ continue;
++
++ iwinfo_process(ifname);
++ }
++
++ fclose(f);
++
++ return 0;
++}
++
++void module_register(void)
++{
++ plugin_register_config("iwinfo", iwinfo_config, config_keys, config_keys_num);
++ plugin_register_read("iwinfo", iwinfo_read);
++}
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -454,6 +454,15 @@ collectd_LDADD += "-dlopen" irq.la
+ collectd_DEPENDENCIES += irq.la
+ endif
+
++if BUILD_PLUGIN_IWINFO
++pkglib_LTLIBRARIES += iwinfo.la
++iwinfo_la_SOURCES = iwinfo.c
++iwinfo_la_LDFLAGS = -module -avoid-version
++iwinfo_la_LIBADD = -liwinfo
++collectd_LDADD += "-dlopen" iwinfo.la
++collectd_DEPENDENCIES += iwinfo.la
++endif
++
+ if BUILD_PLUGIN_JAVA
+ pkglib_LTLIBRARIES += java.la
+ java_la_SOURCES = java.c
+--- a/src/types.db
++++ b/src/types.db
+@@ -171,3 +171,4 @@ voltage value:GAUGE:U:U
+ vs_memory value:GAUGE:0:9223372036854775807
+ vs_processes value:GAUGE:0:65535
+ vs_threads value:GAUGE:0:65535
++stations value:GAUGE:0:256
diff --git a/dbus/Makefile b/dbus/Makefile
new file mode 100644
index 000000000..b47d40be4
--- /dev/null
+++ b/dbus/Makefile
@@ -0,0 +1,213 @@
+#
+# Copyright (C) 2007-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+# Make sure to also update the dbus-x package
+PKG_NAME:=dbus
+PKG_VERSION:=1.9.10
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://dbus.freedesktop.org/releases/dbus/
+PKG_MD5SUM:=72390a741009017258c00a3268daa728
+PKG_MAINTAINER:=Steven Barth
+PKG_LICENSE:=AFL-2.1
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+TARGET_LDFLAGS+= \
+ -Wl,-rpath-link=$(STAGING_DIR)/usr/lib \
+
+define Package/dbus/Default
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Simple interprocess messaging system
+ URL:=http://dbus.freedesktop.org/
+endef
+
+define Package/dbus/Default/description
+ D-Bus is a message bus system, a simple way for applications to talk to one
+ another. In addition to interprocess communication, D-Bus helps coordinate
+ process lifecycle; it makes it simple and reliable to code a "single instance"
+ application or daemon, and to launch applications and daemons on demand when
+ their services are needed.
+endef
+
+define Package/libdbus
+$(call Package/dbus/Default)
+ CATEGORY:=Libraries
+ TITLE+= (library)
+ DEPENDS:= +libpthread
+endef
+
+define Package/libdbus/Description
+$(call Package/dbus/Default/description)
+ This package contains the D-Bus shared library.
+endef
+
+define Package/dbus
+$(call Package/dbus/Default)
+ TITLE+= (daemon)
+ DEPENDS:= +libexpat +libdbus
+endef
+
+define Package/dbus/Description
+$(call Package/dbus/Default/description)
+ This package contains the D-Bus daemon.
+endef
+
+define Package/dbus-utils
+$(call Package/dbus/Default)
+ TITLE+= (utilities)
+ DEPENDS:= dbus
+endef
+
+define Package/dbus-utils/Description
+$(call Package/dbus/Default/description)
+ This package contains D-Bus utilities.
+endef
+
+
+define Build/Prepare
+ $(Build/Prepare/Default)
+ $(SED) 's/-Wl,--gc-sections/--gc-sections/' $(PKG_BUILD_DIR)/configure
+endef
+
+CONFIGURE_ARGS += \
+ --enable-shared \
+ --enable-static \
+ --disable-abstract-sockets \
+ --disable-ansi \
+ --disable-asserts \
+ --disable-console-owner-file \
+ --disable-doxygen-docs \
+ --disable-compiler_coverage \
+ --disable-selinux \
+ --disable-tests \
+ --disable-verbose-mode \
+ --disable-xml-docs \
+ --with-xml="expat" \
+ --with-dbus-user=root \
+ --with-dbus-daemondir="/usr/sbin" \
+ --with-system-socket="/var/run/dbus/system_bus_socket" \
+ --with-system-pid-file="/var/run/dbus.pid" \
+ --without-x \
+ --libexecdir=/usr/lib/dbus-1
+
+CONFIGURE_VARS+= \
+ ac_cv_have_abstract_sockets="yes" \
+ ac_cv_lib_expat_XML_ParserCreate_MM="yes" \
+
+HOST_CONFIGURE_ARGS+= \
+ --enable-shared \
+ --enable-static \
+ --disable-abstract-sockets \
+ --disable-ansi \
+ --disable-asserts \
+ --disable-console-owner-file \
+ --disable-docygen-docs \
+ --disable-compiler_coverage \
+ --disable-selinux \
+ --disable-tests \
+ --disable-verbose-mode \
+ --disable-xml-docs \
+ --with-dbus-user=root \
+ --with-dbus-daemondir="$(STAGIND_DIR_HOST)/bin" \
+ --with-system-socket="$(STAGING_DIR_HOST)/var/run/dbus/system_bus_socket" \
+ --with-system-pid-file="$(STAGING_DIR_HOST)/var/run/dbus.pid" \
+ --without-x \
+ --libexecdir="$(STAGING_DIR_HOST)/lib/dbus-1"
+
+HOST_CONFIGURE_VARS+= \
+ ac_cv_have_abstract_sockets="yes" \
+ ac_cv_lib_expat_XML_ParserCreate_MM="yes" \
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/include/dbus-1.0 \
+ $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib/dbus-1.0/include/dbus/
+ $(INSTALL_DATA) \
+ $(PKG_INSTALL_DIR)/usr/lib/dbus-1.0/include/dbus/*.h \
+ $(1)/usr/lib/dbus-1.0/include/dbus/
+
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(INSTALL_DATA) \
+ $(PKG_INSTALL_DIR)/usr/lib/libdbus-1.{so*,la,a} \
+ $(1)/usr/lib/
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/lib/dbus-1.0 \
+ $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(INSTALL_DATA) \
+ $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/dbus-1.pc \
+ $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/dbus/conffiles
+/etc/dbus-1/session.conf
+/etc/dbus-1/system.conf
+endef
+
+define Package/libdbus/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/lib/libdbus-1.so.* \
+ $(1)/usr/lib/
+endef
+
+define Package/dbus/install
+ $(INSTALL_DIR) $(1)/etc
+ $(CP) \
+ $(PKG_INSTALL_DIR)/etc/dbus-1 \
+ $(1)/etc/
+
+ $(INSTALL_DIR) $(1)/usr/lib/dbus-1
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/lib/dbus-1/dbus-daemon-launch-helper \
+ $(1)/usr/lib/dbus-1/
+
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/sbin/dbus-daemon \
+ $(1)/usr/sbin/
+
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/bin/dbus-uuidgen \
+ $(1)/usr/bin/
+
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/bin/dbus-launch \
+ $(1)/usr/bin/dbus-launch.real
+ $(INSTALL_BIN) \
+ ./files/dbus-launch \
+ $(1)/usr/bin/
+
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) \
+ ./files/dbus.init \
+ $(1)/etc/init.d/dbus
+endef
+
+define Package/dbus-utils/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/bin/dbus-{send,monitor,cleanup-sockets} \
+ $(1)/usr/bin/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,libdbus))
+$(eval $(call BuildPackage,dbus))
+$(eval $(call BuildPackage,dbus-utils))
diff --git a/dbus/files/dbus-launch b/dbus/files/dbus-launch
new file mode 100644
index 000000000..7c3f9228d
--- /dev/null
+++ b/dbus/files/dbus-launch
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Simple wrapper script which allows us to build dbus without general x support
+# If an application needs x support in dbus-launch it has to depend on the
+# dbus-launch-x package. The script is used to prefer dbus-launch with x over
+# the dbus-lauch without x.
+
+if [ -f /usr/bin/dbus-launch-x ]; then
+ exec /usr/bin/dbus-launch-x $@
+else
+ exec /usr/bin/dbus-launch.real $@
+fi
diff --git a/dbus/files/dbus.init b/dbus/files/dbus.init
new file mode 100644
index 000000000..429408377
--- /dev/null
+++ b/dbus/files/dbus.init
@@ -0,0 +1,17 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2007-2011 OpenWrt.org
+
+START=60
+
+SERVICE_PID_FILE=/var/run/dbus.pid
+
+start() {
+ mkdir -m 0755 -p /var/lib/dbus
+ mkdir -m 0755 -p /var/run/dbus
+ [ -x /usr/bin/dbus-uuidgen ] && /usr/bin/dbus-uuidgen --ensure
+ service_start /usr/sbin/dbus-daemon --system
+}
+
+stop() {
+ service_stop /usr/sbin/dbus-daemon && rm $SERVICE_PID_FILE
+}
diff --git a/dbus/patches/100-fix-poll-select.patch b/dbus/patches/100-fix-poll-select.patch
new file mode 100644
index 000000000..64f652517
--- /dev/null
+++ b/dbus/patches/100-fix-poll-select.patch
@@ -0,0 +1,13 @@
+Index: dbus-1.9.4/tools/tool-common.c
+===================================================================
+--- dbus-1.9.4.orig/tools/tool-common.c
++++ dbus-1.9.4/tools/tool-common.c
+@@ -29,6 +29,8 @@
+ #include
+ #include
+
++#include
++
+ #ifdef DBUS_WIN
+ #include
+ #endif
diff --git a/dectmngr/files/etc/config/dect b/dectmngr/files/etc/config/dect
index 23628de49..a36cb665e 100755
--- a/dectmngr/files/etc/config/dect
+++ b/dectmngr/files/etc/config/dect
@@ -1,3 +1,3 @@
config dect 'dect'
- option 'radio' '0'
+ option 'radio' 'auto'
diff --git a/layer2interface/broadcom/etc/init.d/layer2_interface_ethernet b/layer2interface/broadcom/etc/init.d/layer2_interface_ethernet
index 02c971ea8..4744e54bc 100755
--- a/layer2interface/broadcom/etc/init.d/layer2_interface_ethernet
+++ b/layer2interface/broadcom/etc/init.d/layer2_interface_ethernet
@@ -39,12 +39,26 @@ boot() {
local $baseifname
config_load layer2_interface_ethernet
config_get baseifname Wan baseifname
+
+ if [ "$(db get hw.board.hardware)" != "EG300" ]; then
+ get_current_status $baseifname
+ local ret=$?
+ if [ $ret -eq 1 ]; then
+ ethctl $baseifname phy-power down
+ ethctl $baseifname phy-power up
+ fi
+ fi
for interf in `db get hw.board.ethernetPortOrder`; do ethswctl -c wan -i $interf -o disable ; done
+ local tm=`db get hw.board.tm`
+ if [ "$tm" == "1" ]; then
+ for interf in `db get hw.board.ethernetPortOrder`; do tmctl porttminit --devtype ETH --if $interf --flag 1 ; done
+ fi
ethswctl -c pause -p 8 -v 1
ethswctl -c hw-switching -o enable
if [ $baseifname ]; then
ethswctl -c wan -i $baseifname -o enable
fi
+
ifconfig $baseifname up
}
diff --git a/ledmngr/Makefile b/ledmngr/Makefile
deleted file mode 100644
index 2c5f6b713..000000000
--- a/ledmngr/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-# Copyright (C) 2006-2010 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=ledmngr
-PKG_RELEASE:=1
-
-PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-STAMP_PREPARED := $(STAMP_PREPARED)_$(call confvar,CONFIG_MTD_REDBOOT_PARTS)
-
-export BUILD_DIR
-
-include $(INCLUDE_DIR)/package.mk
-
-LDFLAGS+= \
- -Wl,-rpath-link=$(STAGING_DIR)/usr/lib \
- -Wl,-rpath-link=$(STAGING_DIR)/lib
-
-
-define Package/ledmngr
- CATEGORY:=Utilities
- TITLE:=Application deamon for handling of leds
- URL:=
- DEPENDS:=+libuci +libubus +libblobmsg-json +bcmkernel
-endef
-
-define Package/ledmngr/description
- Application deamon for handling of leds
-endef
-
-define Build/Prepare
- mkdir -p $(PKG_BUILD_DIR)
- $(CP) ./src/* $(PKG_BUILD_DIR)/
- $(CP) ./files/* $(PKG_BUILD_DIR)/
-endef
-
-
-define Package/ledmngr/install
-# $(CP) ./files/* $(1)/
- $(INSTALL_DIR) $(1)/usr/lib
- $(INSTALL_DIR) $(1)/sbin/
- $(INSTALL_DIR) $(1)/etc/
- $(INSTALL_DIR) $(1)/etc/init.d/
-
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/etc/init.d/* $(1)/etc/init.d/
- cp $(PKG_BUILD_DIR)/ledmngr $(1)/sbin/
-endef
-
-$(eval $(call BuildPackage,ledmngr))
diff --git a/ledmngr/src/Makefile b/ledmngr/src/Makefile
deleted file mode 100644
index f6dd3ea11..000000000
--- a/ledmngr/src/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# Makefile for ledmngr
-
-CC = gcc
-CFLAGS += -Wall -g
-CFLAGS += -I$(STAGING_DIR)/usr/include/bcm963xx/shared/opensource/include/bcm963xx/
-CFLAGS += -I$(STAGING_DIR)/usr/include/bcm963xx/bcmdrivers/opensource/include/bcm963xx/
-OBJS = ucix.o brcmdaemon.o ledmngr.o smbus.o catv.o i2c.o sfp.o touch_sx9512.o led.o button.o spi.o
-
-ledmngr: $(OBJS)
- $(CC) $(LDFLAGS) -o ledmngr $(OBJS) -luci -lubus -lubox -lblobmsg_json -lm
-
-clean:
- rm -f *.o
-
diff --git a/ledmngr/src/brcmdaemon.c b/ledmngr/src/brcmdaemon.c
deleted file mode 100644
index e0ec21f13..000000000
--- a/ledmngr/src/brcmdaemon.c
+++ /dev/null
@@ -1,162 +0,0 @@
-#include "brcmdaemon.h"
-
-/* BUG: move me to header.*/
-void ledmngr( void );
-
-/**************************************************************************
- Function: Print Usage
-
- Description:
- Output the command-line options for this daemon.
-
- Params:
- @argc - Standard argument count
- @argv - Standard argument array
-
- Returns:
- returns void always
-**************************************************************************/
-void PrintUsage(int argc, char *argv[]) {
- if (argc >=1) {
- printf("Usage: %s -h -n\n", argv[0]);
- printf(" Options: \n");
- printf(" -n\tDon't fork off as a daemon.\n");
- printf(" -h\tShow this help screen.\n");
- printf("\n");
- }
-}
-
-/**************************************************************************
- Function: signal_handler
-
- Description:
- This function handles select signals that the daemon may
- receive. This gives the daemon a chance to properly shut
- down in emergency situations. This function is installed
- as a signal handler in the 'main()' function.
-
- Params:
- @sig - The signal received
-
- Returns:
- returns void always
-**************************************************************************/
-void signal_handler(int sig) {
-
- switch(sig) {
- case SIGHUP:
- syslog(LOG_WARNING, "Received SIGHUP signal.");
- return;
- case SIGINT:
- syslog(LOG_WARNING, "Received SIGINT signal.");
- break;
- case SIGTERM:
- syslog(LOG_WARNING, "Received SIGTERM signal.");
- break;
- default:
- syslog(LOG_WARNING, "Unhandled signal (%d)", sig);
- break;
- }
- syslog(LOG_INFO, "%s daemon exiting", DAEMON_NAME);
- exit(0);
-}
-
-/**************************************************************************
- Function: main
-
- Description:
- The c standard 'main' entry point function.
-
- Params:
- @argc - count of command line arguments given on command line
- @argv - array of arguments given on command line
-
- Returns:
- returns integer which is passed back to the parent process
-**************************************************************************/
-
-#if defined(DEBUG)
- int daemonize = 0;
-#else
- int daemonize = 1;
-#endif
-
-int main(int argc, char *argv[]) {
-
- // Setup signal handling before we start
- signal(SIGHUP, signal_handler);
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
- signal(SIGQUIT, signal_handler);
-
- int c;
- while( (c = getopt(argc, argv, "nh|help")) != -1) {
- switch(c){
- case 'h':
- PrintUsage(argc, argv);
- exit(0);
- break;
- case 'n':
- daemonize = 0;
- break;
- default:
- PrintUsage(argc, argv);
- exit(1);
- break;
- }
- }
-
- syslog(LOG_INFO, "%s daemon starting up", DAEMON_NAME);
-
- // Setup syslog logging - see SETLOGMASK(3)
-#if defined(DEBUG)
- setlogmask(LOG_UPTO(LOG_DEBUG));
- openlog(DAEMON_NAME, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
-#else
- setlogmask(LOG_UPTO(LOG_INFO));
- openlog(DAEMON_NAME, LOG_CONS, LOG_USER);
-#endif
-
- /* Our process ID and Session ID */
- pid_t pid, sid;
-
- if (daemonize) {
- syslog(LOG_INFO, "starting the daemonizing process");
-
- /* Fork off the parent process */
- pid = fork();
- if (pid < 0) {
- exit(EXIT_FAILURE);
- }
- /* If we got a good PID, then
- we can exit the parent process. */
- if (pid > 0) {
- exit(EXIT_SUCCESS);
- }
-
- /* Change the file mode mask */
- umask(0);
-
- /* Create a new SID for the child process */
- sid = setsid();
- if (sid < 0) {
- /* Log the failure */
- exit(EXIT_FAILURE);
- }
-
- /* Change the current working directory */
- if ((chdir("/")) < 0) {
- /* Log the failure */
- exit(EXIT_FAILURE);
- }
-
- /* Close out the standard file descriptors */
- //close(STDIN_FILENO);
- //close(STDOUT_FILENO);
- //close(STDERR_FILENO);
- }
-
- ledmngr();
- syslog(LOG_INFO, "%s daemon exiting", DAEMON_NAME);
- exit(0);
-}
diff --git a/ledmngr/src/i2c.c b/ledmngr/src/i2c.c
deleted file mode 100644
index b040d6090..000000000
--- a/ledmngr/src/i2c.c
+++ /dev/null
@@ -1,120 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "smbus.h"
-#include
-#include
-#include "ucix.h"
-#include "i2c.h"
-#include "log.h"
-
-void dump_i2c(int fd,int start,int stop)
-{
- int i;
- int res;
-
- for (i=start ; i < stop; i++) {
- res = i2c_smbus_read_byte_data(fd,i);
- if (res < 0){perror("i2c error\n");}
- DEBUG_PRINT("/dev/i2c-0 READ %d = 0x%02x\n",i,(unsigned char)res);
- }
-}
-
-int i2c_open_dev (const char *bus, int addr, unsigned long needed)
-{
- int fd = open(bus, O_RDWR);
- if (fd < 0) {
- syslog(LOG_INFO,"%s: could not open /dev/i2c-0\n",__func__);
- return -1;
- }
- if (ioctl(fd, I2C_SLAVE, addr) < 0) {
- syslog(LOG_INFO,"%s: could not set address %x for i2c chip\n",
- __func__, addr);
- error:
- close (fd);
- return -1;
- }
- if (needed) {
- unsigned long funcs;
- if (ioctl(fd, I2C_FUNCS, &funcs) < 0) {
- syslog(LOG_INFO,"%s: could not get I2C_FUNCS\n",__func__);
- goto error;
- }
- if ( (funcs & needed) != needed) {
- syslog(LOG_INFO,"%s: lacking I2C capabilities, have %lx, need %lx\n",
- __func__, funcs, needed);
- goto error;
- }
- }
- return fd;
-}
-
-void do_init_tab( struct i2c_touch *i2c_touch)
-{
- const struct i2c_reg_tab *tab;
- int i;
-
- tab = i2c_touch->init_tab;
-
- for (i = 0 ; i < i2c_touch->init_tab_len ; i++){
- int y;
- int ret;
- for ( y = 0 ; y <= tab[i].range; y++ ){
-// DEBUG_PRINT("%s: addr %02X = %02X \n",__func__,(unsigned char)tab[i].addr+y, (unsigned char)tab[i].value);
- ret = i2c_smbus_write_byte_data(i2c_touch->dev, tab[i].addr+y, tab[i].value);
- if (ret < 0){
- perror("write to i2c dev\n");
- }
- }
- }
-// dump_i2c(i2c_touch->dev,0,13);
-
-}
-
-
-struct i2c_touch * i2c_init(struct uci_context *uci_ctx, char* i2c_dev_name, struct i2c_touch* i2c_touch_list, int len)
-{
- const char *p;
- int i;
-
- p = ucix_get_option(uci_ctx, "hw", "board", "hardware");
- if (p == 0){
- syslog(LOG_INFO, "%s: Missing Hardware identifier in configuration. I2C is not started\n",__func__);
- return 0;
- }
-
- /* Here we match the hardware name to a init table, and get the
- i2c chip address */
- i2c_touch = NULL;
- for (i = 0; i < len; i++)
- if (!strcmp(i2c_touch_list[i].name, p)) {
- DEBUG_PRINT("I2C hardware platform %s found.\n", p);
- i2c_touch = &i2c_touch_list[i];
- break;
- }
- if (!i2c_touch) {
- DEBUG_PRINT("No I2C hardware found: %s.\n", p);
- return 0;
- }
-
- i2c_touch->dev = i2c_open_dev(i2c_dev_name, i2c_touch->addr,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE);
-
- if (i2c_touch->dev < 0) {
- syslog(LOG_INFO,"%s: could not open i2c touch device\n",__func__);
- i2c_touch->dev = 0;
- return 0;
- }
-
- DEBUG_PRINT("Opened device and selected address %x \n", i2c_touch->addr);
-
- do_init_tab(i2c_touch);
-
- return i2c_touch;
-}
diff --git a/ledmngr/src/ledmngr.c b/ledmngr/src/ledmngr.c
deleted file mode 100644
index ff407417d..000000000
--- a/ledmngr/src/ledmngr.c
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- * ledmngr.c -- Led and button manager for Inteno CPE's
- *
- * Copyright (C) 2012-2014 Inteno Broadband Technology AB. All rights reserved.
- *
- * Author: benjamin.larsson@inteno.se
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include "libubus.h"
-
-#include
-#include "ucix.h"
-
-#include "log.h"
-#include "catv.h"
-#include "sfp.h"
-
-
-#include "button.h"
-#include "led.h"
-#include "spi.h"
-#include "touch_sx9512.h"
-
-static struct ubus_context *ubus_ctx = NULL;
-static struct blob_buf bblob;
-
-static struct leds_configuration* led_cfg;
-static struct button_configuration* butt_cfg;
-static struct uci_context *uci_ctx = NULL;
-
-struct catv_handler *catv_h;
-struct sfp_handler *sfp_h;
-struct i2c_touch *i2c_touch;
-
-int brcmboard = -1;
-
-struct led_config led_config;
-
-/* Names for led_action_t */
-static const char * const fn_actions[LED_ACTION_MAX] =
-{ "off", "ok", "notice", "alert", "error",};
-
-static const char* const led_functions[LED_FUNCTIONS] =
-{ "dsl", "wifi", "wps", "lan", "status", "dect", "tv", "usb",
- "wan", "internet", "voice1", "voice2", "eco", "gbe"};
-
-/* Names for led_state_t */
-static const char* const led_states[LED_STATES_MAX] =
-{ "off", "on", "blink_slow", "blink_fast" };
-
-/* Names for leds_state_t */
-static const char* const leds_states[LEDS_MAX] =
-{ "normal", "proximity", "silent", "info", "test", "production", "reset", "allon" , "alloff"};
-
-
-int get_led_index_by_name(struct leds_configuration* led_cfg, char* led_name);
-int led_set(struct leds_configuration* led_cfg, int led_idx, int state);
-int board_ioctl(int ioctl_id, int action, int hex, char* string_buf, int string_buf_len, int offset);
-static void proximity_light(struct leds_configuration* led_cfg, int all);
-void proximity_dim(struct leds_configuration* led_cfg, int all);
-
-void sx9512_reset_handler(struct uloop_timeout *timeout);
-
-struct uloop_timeout i2c_touch_reset_timer = { .cb = sx9512_reset_handler };
-
-/* sx9512 needs a reset every 30 minutes. to recalibrate the touch detection */
-void sx9512_reset_handler(struct uloop_timeout *timeout)
-{
- int i;
-
- sx9512_reset(i2c_touch);
-
- for (i=0 ; ileds_nr ; i++)
- if (led_cfg->leds[i]->type == I2C)
- led_set(led_cfg, i, -1);
-
- uloop_timeout_set(&i2c_touch_reset_timer, I2C_RESET_TIME);
-}
-
-void open_ioctl() {
-
- brcmboard = open("/dev/brcmboard", O_RDWR);
- if ( brcmboard == -1 ) {
- DEBUG_PRINT("failed to open: /dev/brcmboard\n");
- return;
- }
- DEBUG_PRINT("fd %d allocated\n", brcmboard);
- return;
-}
-
-static int get_state_by_name(char* state_name) {
- int i;
-
- for (i=0 ; ileds_nr);
- for (i=0 ; ileds_nr ; i++) {
- led_set(led_cfg, i, OFF);
- }
-}
-
-
-static struct leds_configuration* get_led_config(void) {
- int i,j,k;
-
- const char *led_names;
- const char *led_config;
- const char *p;
- char *ptr, *rest;
-
- struct leds_configuration* led_cfg = malloc(sizeof(struct leds_configuration));
- memset(led_cfg,0,sizeof(struct leds_configuration));
-
- led_cfg->leds = malloc(MAX_LEDS * sizeof(struct led_config*));
- memset(led_cfg->leds, 0, MAX_LEDS * sizeof(struct led_config*));
-
- led_names = ucix_get_option(uci_ctx, "hw", "board", "lednames");
-
- led_cfg->button_feedback_led = -1;
-
- /* Populate led configuration structure */
- /* led_names is a space separated list of led names. */
- ptr = (char *)led_names;
- p = strtok_r(ptr, " ", &rest);
-
- while(p != NULL) {
- char led_name_color[256] = {0};
-
- DEBUG_PRINT("Add led colors for led name [%s]\n", p);
-
- snprintf(led_name_color, 256, "%s_green", p);
- led_config = ucix_get_option(uci_ctx, "hw", "leds", led_name_color);
- add_led(led_cfg, led_name_color, led_config, GREEN);
-
- snprintf(led_name_color, 256, "%s_red", p);
- led_config = ucix_get_option(uci_ctx, "hw", "leds", led_name_color);
- add_led(led_cfg, led_name_color, led_config, RED);
-
- snprintf(led_name_color, 256, "%s_blue", p);
- led_config = ucix_get_option(uci_ctx, "hw", "leds", led_name_color);
- add_led(led_cfg, led_name_color, led_config, BLUE);
-
- snprintf(led_name_color, 256, "%s_yellow", p);
- led_config = ucix_get_option(uci_ctx, "hw", "leds", led_name_color);
- add_led(led_cfg, led_name_color, led_config, YELLOW);
-
- snprintf(led_name_color, 256, "%s_white", p);
- led_config = ucix_get_option(uci_ctx, "hw", "leds", led_name_color);
- add_led(led_cfg, led_name_color, led_config, WHITE);
-
- /* Get next */
- p = strtok_r(NULL, " ", &rest);
- }
-
- //reset shift register states
- for (i=0 ; ishift_register_state[i] = 0;
- }
-
- //populate led mappings
- for (i=0 ; iled_map_config[i][j].led_actions[k].led_index = -1;
- led_cfg->led_map_config[i][j].led_actions[k].led_state = -1;
- }
-
- if (led_fn_actions) {
- int l=0;
- /* space separated list of actions */
- ptr = strtok_r((char *)led_fn_actions , " ", &rest);
- while(ptr != NULL) {
- sscanf(ptr, "%[^=]=%s", l1, s1);
- led_cfg->led_map_config[i][j].led_actions[l].led_index = get_led_index_by_name(led_cfg, l1);
- led_cfg->led_map_config[i][j].led_actions[l].led_state = get_state_by_name(s1);
- led_cfg->led_map_config[i][j].led_actions_nr++;
-
- DEBUG_PRINT("%-15s -> nr=%d idx=%d,state=%d -> %-15s = %s\n",
- fn_name_action,
- led_cfg->led_map_config[i][j].led_actions_nr,
- led_cfg->led_map_config[i][j].led_actions[l].led_index,
- led_cfg->led_map_config[i][j].led_actions[l].led_state,
- l1,
- s1);
-
- /* Get next */
- ptr = strtok_r(NULL, " ", &rest);
- l++;
- }
-
- }
- }
- }
-
- p = ucix_get_option(uci_ctx, "hw", "board", "hardware");
- if (p && !strcmp(p, "CG300"))
- led_cfg->leds_state = LEDS_PROXIMITY;
- else
- led_cfg->leds_state = LEDS_NORMAL;
- led_cfg->test_state = 0;
- led_cfg->proximity_timer = 0;
- led_cfg->proximity_all_timer = 0;
-
- /* Turn off all leds */
- DEBUG_PRINT("Turn off all leds\n");
- all_leds_off(led_cfg);
-
- /* Set all function states to off */
- DEBUG_PRINT("Set all function states to off\n");
- for (i=0 ; iled_fn_action[i] = LED_OFF;
- }
-
- return led_cfg;
-}
-
-#if 0
-static int led_need_type(const struct leds_configuration* led_cfg, led_type_t type)
-{
- int i;
- for (i=0 ; ileds_nr ; i++)
- if (led_cfg->leds[i]->type == type)
- return 1;
- return 0;
-}
-#endif
-
-void print_config(struct leds_configuration* led_cfg) {
- int i;
- DEBUG_PRINT("\n\n\n Leds: %d\n", led_cfg->leds_nr);
-
- for (i=0 ; ileds_nr ; i++) {
- struct led_config* lc = led_cfg->leds[i];
- DEBUG_PRINT("%s: type: %d, adr:%d, color:%d, act:%d\n", lc->name, lc->type, lc->address, lc->color, lc->active);
- }
-}
-
-
-int get_led_index_by_name(struct leds_configuration* led_cfg, char* led_name) {
- int i;
- for (i=0 ; ileds_nr ; i++) {
- struct led_config* lc = led_cfg->leds[i];
- if (!strcmp(led_name, lc->name))
- return i;
- }
- DEBUG_PRINT("Led name %s not found!\n", led_name);
- return -1;
-}
-
-#if 0
-static int get_led_index_by_function_color(struct leds_configuration* led_cfg, char* function, int color) {
- int i;
- for (i=0 ; ileds_nr ; i++) {
- struct led_config* lc = led_cfg->leds[i];
- if (!strcmp(function, lc->function) && (lc->color == color))
- return i;
- }
- return -1;
-}
-#endif
-
-int board_ioctl(int ioctl_id, int action, int hex, char* string_buf, int string_buf_len, int offset) {
- BOARD_IOCTL_PARMS IoctlParms = {0};
- IoctlParms.string = string_buf;
- IoctlParms.strLen = string_buf_len;
- IoctlParms.offset = offset;
- IoctlParms.action = action;
- IoctlParms.buf = "";
- if ( ioctl(brcmboard, ioctl_id, &IoctlParms) < 0 ) {
- syslog(LOG_INFO, "ioctl: %d failed\n", ioctl_id);
- exit(1);
- }
- return IoctlParms.result;
-}
-
-static void shift_register3_set(struct leds_configuration* led_cfg, int address, int state, int active) {
- int i;
-
- if (address>=SR_MAX-1) {
- DEBUG_PRINT("address index %d too large\n", address);
- return;
- }
- // Update internal register copy
- led_cfg->shift_register_state[address] = state^active;
-
- // pull down shift register load (load gpio 23)
- board_ioctl(BOARD_IOCTL_SET_GPIO, 0, 0, NULL, 23, 0);
-
- //for (i=0 ; ishift_register_state[SR_MAX-1-i]);
- //DEBUG_PRINT("\n");
-
- // clock in bits
- for (i=0 ; ishift_register_state[SR_MAX-1-i]);
- //set clock high
- board_ioctl( BOARD_IOCTL_SET_GPIO, 0, 0, NULL, 0, 1);
- }
-
- // issue shift register load
- board_ioctl( BOARD_IOCTL_SET_GPIO, 0, 0, NULL, 23, 1);
-}
-
-/* Sets a led on or off (doesn't handle the blinking states). state ==
- -1 means update from the led's stored state. */
-int led_set(struct leds_configuration* led_cfg, int led_idx, int state) {
- struct led_config* lc;
-
- if ((led_idx == -1) || (led_idx > led_cfg->leds_nr-1)) {
- DEBUG_PRINT("Led index: %d out of bounds, nr_leds = %d\n", led_idx, led_cfg->leds_nr);
- return 0;
- }
-
- lc = led_cfg->leds[led_idx];
-
- if (state < 0)
- state = (lc->state != OFF);
-
- //printf("Led index: %d\n", led_idx);
- // DEBUG_PRINT("Led index: %d\n", led_idx);
-
- if (lc->type == GPIO) {
- board_ioctl( BOARD_IOCTL_SET_GPIO, 0, 0, NULL, lc->address, state^lc->active);
- } else if (lc->type == SHIFTREG3) {
- shift_register3_set(led_cfg, lc->address, state, lc->active);
- } else if (lc->type == SHIFTREG2) {
- board_ioctl( BOARD_IOCTL_LED_CTRL, 0, 0, NULL, lc->address, state^lc->active);
- } else if (lc->type == I2C) {
- sx9512_led_set(lc, state);
- } else if (lc->type == SPI) {
- spi_led_set(lc, state);
- } else
- DEBUG_PRINT("Wrong type of bus (%d)\n",lc->type);
-
- lc->blink_state = state;
-
- return 0;
-}
-
-static void led_set_state(struct leds_configuration* led_cfg, int led_idx, led_state_t state) {
- struct led_config* lc;
-
- if ((led_idx == -1) || (led_idx > led_cfg->leds_nr-1)) {
- DEBUG_PRINT("Led index: %d out of bounds, nr_leds = %d\n", led_idx, led_cfg->leds_nr);
- return;
- }
-
- lc = led_cfg->leds[led_idx];
- lc->state = state;
-}
-
-static void all_leds_on(struct leds_configuration* led_cfg) {
- int i;
- for (i=0 ; ileds_nr ; i++) {
- led_set(led_cfg, i, ON);
- }
-}
-
-#if 0
-static void all_leds_test(struct leds_configuration* led_cfg) {
- int i;
- //all_leds_off(led_cfg);
- for (i=0 ; ileds_nr ; i++) {
- led_set(led_cfg, i, ON);
- sleep(1);
- led_set(led_cfg, i, OFF);
- }
- all_leds_off(led_cfg);
- sleep(1);
- all_leds_on(led_cfg);
- sleep(1);
- all_leds_off(led_cfg);
- sleep(1);
- all_leds_on(led_cfg);
- sleep(1);
- all_leds_off(led_cfg);
-}
-#endif
-
-void blink_led(struct leds_configuration* led_cfg, led_state_t state,
- int dimmed) {
- int i;
- for (i=0 ; ileds_nr ; i++) {
- struct led_config* lc = led_cfg->leds[i];
- if (lc->state == state
- && (!lc->use_proximity || !dimmed)) {
- //printf("Blinking %s\n", lc->name);
- led_set(led_cfg, i, lc->blink_state?0:1);
- }
- }
-}
-
-static void leds_test(struct leds_configuration* led_cfg) {
- if (led_cfg->test_state == 0)
- all_leds_on(led_cfg);
- if (led_cfg->test_state == 1)
- all_leds_off(led_cfg);
- if (led_cfg->test_state == 2)
- all_leds_on(led_cfg);
- if (led_cfg->test_state == 3)
- all_leds_off(led_cfg);
-
- if ((led_cfg->test_state > 4) && (led_cfg->test_state < led_cfg->leds_nr+4)) {
- led_set(led_cfg, led_cfg->test_state-5, OFF);
- }
-
- if ((led_cfg->test_state > 3) && (led_cfg->test_state < led_cfg->leds_nr+4)) {
- led_set(led_cfg, led_cfg->test_state-4, ON);
- }
-
- if (led_cfg->test_state == (led_cfg->leds_nr+5))
- all_leds_on(led_cfg);
- if (led_cfg->test_state == (led_cfg->leds_nr+6))
- all_leds_off(led_cfg);
- if (led_cfg->test_state == (led_cfg->leds_nr+7))
- all_leds_on(led_cfg);
- if (led_cfg->test_state == (led_cfg->leds_nr+8))
- all_leds_off(led_cfg);
-
- //printf("T state = %d\n", led_cfg->test_state);
-
- led_cfg->test_state++;
- if (led_cfg->test_state > led_cfg->leds_nr+8)
- led_cfg->test_state = 0;
-}
-
-static void leds_production(struct leds_configuration* led_cfg) {
- all_leds_off(led_cfg);
-}
-
-static void leds_reset(struct leds_configuration* led_cfg) {
- if (led_cfg->test_state == 0)
- all_leds_on(led_cfg);
- if (led_cfg->test_state == 1)
- all_leds_off(led_cfg);
-
- if (led_cfg->test_state == 2)
- all_leds_on(led_cfg);
- if (led_cfg->test_state == 3)
- all_leds_off(led_cfg);
-
- if (led_cfg->test_state == 4)
- all_leds_on(led_cfg);
- if (led_cfg->test_state == 5)
- all_leds_off(led_cfg);
-
- led_cfg->test_state++;
- if (led_cfg->test_state > 5) {
- led_cfg->test_state = 0;
-// led_cfg->leds_state = LEDS_NORMAL;
- }
-}
-
-static void blink_handler(struct uloop_timeout *timeout);
-static struct uloop_timeout blink_inform_timer = { .cb = blink_handler };
-static unsigned int cnt = 0;
-
-static void blink_handler(struct uloop_timeout *timeout)
-{
- cnt++;
-
- /* handle press indicator for touch */
- if(led_cfg->press_indicator) {
- static int times = 0;
- times++;
- if (times%2)
- proximity_light(led_cfg, 1);
- else
- proximity_dim(led_cfg, 1);
- }
-
- /* handle proximity timer */
- if (led_cfg->proximity_timer) {
- led_cfg->proximity_timer--;
- if (led_cfg->leds_state == LEDS_PROXIMITY
- && !led_cfg->proximity_timer)
- proximity_dim(led_cfg, 1);
- }
-
- /*handle proximity all timer */
- if (led_cfg->proximity_all_timer) {
- led_cfg->proximity_all_timer--;
- if (led_cfg->leds_state == LEDS_PROXIMITY
- && !led_cfg->proximity_all_timer)
- proximity_dim(led_cfg, !led_cfg->proximity_timer);
- }
-
- /* normal operation. */
- if (led_cfg->leds_state == LEDS_TEST) {
- if (!(cnt%3))
- leds_test(led_cfg);
- } else if (led_cfg->leds_state == LEDS_PROD) {
- if (!(cnt%16))
- leds_production(led_cfg);
- } else if (led_cfg->leds_state == LEDS_RESET) {
- leds_reset(led_cfg);
- } else if (led_cfg->leds_state != LEDS_INFO) {
- /* LEDS_NORMAL or LEDS_PROXIMITY */
- int dimmed = (led_cfg->leds_state == LEDS_PROXIMITY && !led_cfg->proximity_timer);
-
- if (!(cnt%4))
- blink_led(led_cfg, BLINK_FAST, dimmed);
-
- if (!(cnt%8))
- blink_led(led_cfg, BLINK_SLOW, dimmed);
- }
-
- /* check buttons every fourth run */
- if (!(cnt%4))
- check_buttons(led_cfg,butt_cfg, 0);
-
- uloop_timeout_set(&blink_inform_timer, 100);
-
- //printf("Timer\n");
-}
-
-static led_action_t index_from_action(const char* action) {
- int i;
- for (i=0 ; i%s)\n",fn_name, action);
- for (i=0 ; iled_fn_action[led_fn_idx] = action_idx;
-
- map = &led_cfg->led_map_config[led_fn_idx][action_idx];
- for (i=0 ; iled_actions_nr ; i++) {
- int led_idx = map->led_actions[i].led_index;
- DEBUG_PRINT("[%d] %d %d\n", map->led_actions_nr, led_idx, map->led_actions[i].led_state);
-
- /* In silent mode, we set lc->state to off. It might make more
- sense to maintain the desired state, and omit blinking it
- in the blink_handler, but then we would need some
- additional flag per led. In all cases,
- led_cfg->led_fn_action records the desired state, so it
- isn't lost when switching back to non-silent mode. */
- if (led_cfg->leds_state == LEDS_SILENT
- && led_cfg->leds[led_idx]->use_proximity
- && action_idx < LED_ALERT)
- led_set_state(led_cfg, led_idx, OFF);
- else
- led_set_state(led_cfg, led_idx,
- map->led_actions[i].led_state);
-
- if (led_cfg->leds_state != LEDS_INFO) {
- led_set(led_cfg, map->led_actions[i].led_index, -1);
-
- if (led_cfg->leds_state == LEDS_PROXIMITY &&
- led_cfg->leds[led_idx]->use_proximity) {
- /* Changing led status of any dimmed led should also
- light up the display. */
- if (!led_cfg->proximity_timer)
- proximity_light(led_cfg, 0);
- if (led_cfg->proximity_timer < 5*10)
- led_cfg->proximity_timer = 5*10;
- }
- }
- }
- DEBUG_PRINT("end\n");
-}
-
-/* Leds marked with use_proximity are lit up when led_cfg->state ==
- LEDS_NORMAL or led_cfg->proximity_timer > 0. */
-static void proximity_light(struct leds_configuration* led_cfg, int all)
-{
- int i;
- DEBUG_PRINT("\n");
- /* if led stored state is not OFF and the leds is used to indicate proximity turn on */
- for (i=0 ; ileds_nr ; i++) {
- struct led_config* lc = led_cfg->leds[i];
- if (lc->use_proximity && (lc->state || all))
- led_set(led_cfg, i, 1);
- }
-
-#if 0
- /* if we have a feedback led turn it on if state is PROXIMITY else set to internal state.*/
- if (led_cfg->button_feedback_led >= 0)
- led_set(led_cfg, led_cfg->button_feedback_led,
- led_cfg->leds_state == LEDS_PROXIMITY ? 1 : -1);
-#endif
-}
-
-void proximity_dim(struct leds_configuration* led_cfg, int all)
-{
- int i;
- DEBUG_PRINT("\n");
- for (i=0 ; ileds_nr ; i++) {
- struct led_config* lc = led_cfg->leds[i];
- if (lc->use_proximity && (!lc->state || all)
- && lc->blink_state)
- led_set(led_cfg, i, 0);
- }
-
- if (all && led_cfg->leds_state == LEDS_PROXIMITY
- && led_cfg->button_feedback_led >= 0) {
- led_set(led_cfg, led_cfg->button_feedback_led, -1);
- }
-}
-
-enum {
- LED_STATE,
- __LED_MAX
-};
-
-static const struct blobmsg_policy led_policy[] = {
- [LED_STATE] = { .name = "state", .type = BLOBMSG_TYPE_STRING },
-};
-
-
-static int led_set_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- struct blob_attr *tb[__LED_MAX];
- char* state;
- DEBUG_PRINT("led_set_method (%s)\n",method);
-
- blobmsg_parse(led_policy, ARRAY_SIZE(led_policy), tb, blob_data(msg), blob_len(msg));
-
- if (tb[LED_STATE]) {
- char *fn_name = strchr(obj->name, '.') + 1;
- state = blobmsg_data(tb[LED_STATE]);
-// fprintf(stderr, "Led %s method: %s state %s\n", fn_name, method, state);
- syslog(LOG_INFO, "Led %s method: %s state %s", fn_name, method, state);
- set_function_led(led_cfg, fn_name, state);
- }
-
- return 0;
-}
-
-static int led_status_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- int action, i, led_fn_idx=0;
- char *fn_name = strchr(obj->name, '.') + 1;
-
- for (i=0 ; iled_fn_action[led_fn_idx];
-
- DEBUG_PRINT( "Led %s method: %s action %d\n", fn_name, method, action);
-
- blob_buf_init (&bblob, 0);
- blobmsg_add_string(&bblob, "state", fn_actions[action]);
- ubus_send_reply(ubus_ctx, req, bblob.head);
-
- return 0;
-}
-
-static int leds_proximity_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- const struct blobmsg_policy proximity_policy[] = {
- /* FIXME: Can we use an integer type here? */
- { .name = "timeout", .type = BLOBMSG_TYPE_STRING, },
- { .name = "light-all", .type = BLOBMSG_TYPE_STRING, },
- };
- unsigned long timeout = 0;
- unsigned long light_all = 0;
- struct blob_attr *tb[ARRAY_SIZE(proximity_policy)];
- blobmsg_parse(proximity_policy, ARRAY_SIZE(proximity_policy),
- tb, blob_data(msg), blob_len(msg));
- if (tb[0]) {
- const char *digits = blobmsg_data(tb[0]);
- char *end;
- timeout = strtoul(digits, &end, 10);
- if (!*digits || *end) {
- syslog(LOG_INFO, "Leds proximity method: Invalid timeout %s\n", digits);
- return 1;
- }
- }
- if (tb[1]) {
- const char *digits = blobmsg_data(tb[1]);
- char *end;
- light_all = strtoul(digits, &end, 10);
- }
- DEBUG_PRINT ("proximity method: timeout %lu, light-all %lu\n", timeout, light_all);
- timeout *= 10;
- light_all *= 10;
- if (led_cfg->leds_state == LEDS_PROXIMITY) {
- if (light_all) {
- if (!led_cfg->proximity_all_timer && !led_cfg->proximity_timer) {
- proximity_light(led_cfg, 1);
- led_cfg->proximity_all_timer = light_all;
- }
- }
- else if (timeout && !led_cfg->proximity_timer)
- proximity_light(led_cfg, 0);
- }
- else
- /* Skip setup of this timer when not in proximity mode. */
- led_cfg->proximity_all_timer = 0;
-
- if (timeout > led_cfg->proximity_all_timer)
- led_cfg->proximity_timer = timeout;
-
- return 0;
-}
-
-static int leds_set_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- struct blob_attr *tb[__LED_MAX];
- char* state;
- int i,j;
- DEBUG_PRINT("\n");
-
- blobmsg_parse(led_policy, ARRAY_SIZE(led_policy), tb, blob_data(msg), blob_len(msg));
-
- if (tb[LED_STATE]) {
- leds_state_t old;
- state = blobmsg_data(tb[LED_STATE]);
-
- for (i=0 ; ileds_state;
- led_cfg->leds_state = i;
-
- if (i == LEDS_INFO) {
- all_leds_off(led_cfg);
- set_function_led(led_cfg, "eco", "off");
- set_function_led(led_cfg, "eco", "ok");
- }
-
- if (i == LEDS_TEST) {
- all_leds_off(led_cfg);
- }
- if (i == LEDS_ALLON) {
- all_leds_on(led_cfg);
- }
- if (i == LEDS_ALLOFF) {
- all_leds_off(led_cfg);
- }
-
- if (i <= LEDS_SILENT) {
- if (i == LEDS_SILENT || old >= LEDS_SILENT) {
- all_leds_off(led_cfg);
- set_function_led(led_cfg, "eco", "off");
- for (j=0 ; jled_fn_action[j]]);
- }
- }
- if (i == LEDS_NORMAL)
- proximity_light(led_cfg, 0);
- else if (i == LEDS_PROXIMITY) {
- if (led_cfg->proximity_timer)
- proximity_light(led_cfg, 0);
- else
- proximity_dim(led_cfg, 1);
- }
- }
- }
- else
- syslog(LOG_INFO, "leds_set_method: Unknown attribute.\n");
-
- return 0;
-}
-
-
-static int leds_status_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- DEBUG_PRINT("\n");
-
- blob_buf_init (&bblob, 0);
- blobmsg_add_string(&bblob, "state", leds_states[led_cfg->leds_state]);
- ubus_send_reply(ubus_ctx, req, bblob.head);
- return 0;
-}
-
-static const struct ubus_method led_methods[] = {
- UBUS_METHOD("set", led_set_method, led_policy),
- { .name = "status", .handler = led_status_method },
-};
-
-static struct ubus_object_type led_object_type =
- UBUS_OBJECT_TYPE("led", led_methods);
-
-
-
-static const struct ubus_method leds_methods[] = {
- UBUS_METHOD("set", leds_set_method, led_policy),
- { .name = "status", .handler = leds_status_method },
- { .name = "proximity", .handler = leds_proximity_method },
-};
-
-static struct ubus_object_type leds_object_type =
- UBUS_OBJECT_TYPE("leds", leds_methods);
-
-
-#define LED_OBJECTS 15
-
-static struct ubus_object led_objects[LED_OBJECTS] = {
- { .name = "leds", .type = &leds_object_type, .methods = leds_methods, .n_methods = ARRAY_SIZE(leds_methods), },
- { .name = "led.dsl", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.wifi", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.wps", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.lan", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.status", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.dect", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.tv", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.usb", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.wan", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.internet", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.voice1", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.voice2", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.eco", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
- { .name = "led.gbe", .type = &led_object_type, .methods = led_methods, .n_methods = ARRAY_SIZE(led_methods), },
-};
-
-static void server_main(struct leds_configuration* led_cfg)
-{
- int ret, i;
-
- for (i=0 ; i
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#include "smbus.h"
-#include
-#include
-
-#include "libubus.h"
-#include
-#include
-#include "ucix.h"
-
-#include "i2c.h"
-#include "sfp.h"
-#include "log.h"
-
-static struct blob_buf b;
-
-struct i2c_sfp {
- const char *bus;
- int rom_addr;
- int ddm_addr;
- const char *name;
-};
-
-const struct i2c_sfp i2c_sfp_list[] = {
- { .bus = "/dev/i2c-0",
- .rom_addr = 0x50,
- .ddm_addr = 0x51,
- .name = "EG200"
- },
- { .bus = "/dev/i2c-1",
- .rom_addr = 0x50,
- .ddm_addr = 0x51,
- .name = "EG300"
- },
-};
-
-const struct i2c_sfp *i2c_sfp;
-
-static int sfp_rom_fd = -1;
-static int sfp_ddm_fd = -1;
-
-static int sfp_rom_byte(unsigned addr)
-{
- int ret;
- if (!i2c_sfp)
- return -1;
-
- if (sfp_rom_fd >= 0) {
- ret = i2c_smbus_read_byte_data(sfp_rom_fd, addr);
- if (ret >= 0)
- return ret;
- /* Close and retry */
- close (sfp_rom_fd);
- goto open;
- }
- if (sfp_rom_fd < 0) {
- open:
- sfp_rom_fd = i2c_open_dev(i2c_sfp->bus, i2c_sfp->rom_addr, I2C_FUNC_SMBUS_READ_BYTE);
- if (sfp_rom_fd < 0)
- return -1;
- }
- ret = i2c_smbus_read_byte_data(sfp_rom_fd, addr);
- if (ret < 0) {
- DEBUG_PRINT ("%s: i2c_smbus_read_byte_data failed: addr %d\n", __func__, addr);
- }
- return ret;
-};
-
-static int sfp_rom_bytes(unsigned addr, char *p, size_t length)
-{
- int byte = sfp_rom_byte(addr);
- int i;
- if (byte < 0)
- return 0;
- p[0] = byte;
-
- for (i = 1; i < length; i++) {
- byte = i2c_smbus_read_byte_data(sfp_rom_fd, addr + i);
- if (byte < 0)
- return 0;
- p[i] = byte;
- }
- return 1;
-}
-
-static int sfp_rom_get_type(struct blob_buf *b)
-{
- int byte = sfp_rom_byte (0);
- char buf[20];
- const char *value;
-
- if (byte < 0)
- return 0;
-
- switch (byte) {
- case 0:
- value = "unspecified";
- break;
- case 1:
- value = "GBIC";
- break;
- case 2:
- value = "soldered module/connector";
- break;
- case 3:
- value = "SFP";
- break;
- default:
- snprintf(buf, sizeof(buf), "%s %d",
- byte < 0x80 ? "reserved" : "vendor specific",
- byte);
- value = buf;
- break;
- }
-
- blobmsg_add_string(b, "type", value);
- return 1;
-}
-
-static int sfp_rom_get_type_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_type(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-static int sfp_rom_get_connector(struct blob_buf *b)
-{
- int byte = sfp_rom_byte (2);
- char buf[20];
- const char *value;
-
- if (byte < 0)
- return 0;
-
- switch (byte) {
- case 0:
- value = "Unspecified";
- break;
- case 1:
- value = "SC";
- break;
- case 2:
- value = "Fiber Channel style 1";
- break;
- case 3:
- value = "Fiber Channel style 2";
- break;
- case 4:
- value = "TNC/BNC";
- break;
- case 5:
- value = "Fiber Channel coaxial";
- break;
- case 6:
- value = "FiberJack";
- break;
- case 7:
- value = "LC";
- break;
- case 8:
- value = "MT-RJ";
- break;
- case 9:
- value = "MU";
- break;
- case 10:
- value = "SG";
- break;
- case 11:
- value = "Optical pigtail";
- break;
- case 32:
- value = "HSSDC II";
- break;
- case 33:
- value = "Copper pigtail";
- break;
- default:
- snprintf(buf, sizeof(buf), "%s %d",
- byte < 0x80 ? "reserved" : "vendor specific",
- byte);
- value = buf;
- break;
- }
-
- blobmsg_add_string(b, "connector", value);
- return 1;
-}
-
-static int sfp_rom_get_connector_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_connector (&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_ethernet(struct blob_buf *b)
-{
- int byte = sfp_rom_byte (6);
- int i;
- char value[11];
- if (byte < 0)
- return 0;
-
- i = 0;
- if (byte & 8)
- value[i++] = 'T';
- if (byte & 4) {
- if (i)
- value[i++] = ',';
- strcpy(value+i, "CX");
- i += 2;
- }
- if (byte & 2) {
- if (i)
- value[i++] = ',';
- strcpy(value+i, "LX");
- i += 2;
- }
- if (byte & 1) {
- if (i)
- value[i++] = ',';
- strcpy(value+i, "SX");
- i += 2;
- }
- if (!i)
- return 0;
-
- value[i] = '\0';
- blobmsg_add_string(b, "ethernet", value);
- return 1;
-}
-
-static int sfp_rom_get_ethernet_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_ethernet(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_encoding(struct blob_buf *b)
-{
- int byte = sfp_rom_byte (11);
- char buf[20];
- const char *value;
-
- if (byte < 0)
- return 0;
-
- switch (byte) {
- case 0:
- value = "Unspecified";
- break;
- case 1:
- value = "8B10B";
- break;
- case 2:
- value = "4B5B";
- break;
- case 3:
- value = "NRZ";
- break;
- case 4:
- value = "Manchester";
- break;
- default:
- snprintf(buf, sizeof(buf), "%s %d",
- "reserved", byte);
- value = buf;
- break;
- }
-
- blobmsg_add_string(b, "encoding", value);
- return 1;
-}
-
-static int sfp_rom_get_encoding_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_encoding(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_rate(struct blob_buf *b)
-{
- int byte = sfp_rom_byte (12);
- int tol;
- if (byte < 0)
- return 0;
-
- /* Read byte is in units of 100 Mbit/s, scale to Mbit/s. */
- blobmsg_add_u32(b, "rate", 100*byte);
- tol = sfp_rom_byte (66);
- if (tol > 0)
- blobmsg_add_u32(b, "rate-max", (100 + tol)*byte);
-
- tol = sfp_rom_byte (67);
- if (tol > 0 && tol <= 100)
- blobmsg_add_u32(b, "rate-min", (100 - tol)*byte);
-
- return 1;
-}
-
-static int sfp_rom_get_rate_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_rate(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_length(struct blob_buf *b)
-{
- int sm_1000;
- int sm_100;
- int mm50;
- int mm62;
- int cu;
-
- if ( (sm_1000 = sfp_rom_byte (14)) < 0
- || (sm_100 = sfp_rom_byte (15)) < 0
- || (mm50 = sfp_rom_byte (16)) < 0
- || (mm62 = sfp_rom_byte (17)) < 0
- || (cu = sfp_rom_byte (18)) < 0)
- return 0;
-
- if (sm_1000 > 0)
- blobmsg_add_u32(b, "single-mode", sm_1000 * 1000);
- else if (sm_100 > 0)
- blobmsg_add_u32(b, "single-mode", sm_100 * 100);
- if (mm50 > 0)
- blobmsg_add_u32(b, "multi-mode-50", mm50 * 10);
- if (mm62 > 0)
- blobmsg_add_u32(b, "multi-mode-62.5", mm62 * 10);
- if (cu > 0)
- blobmsg_add_u32(b, "copper", cu);
- return 1;
-}
-
-static int sfp_rom_get_length_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_length(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_vendor(struct blob_buf *b)
-{
- char buf[17];
- int i;
- if (!sfp_rom_bytes(20, buf, 16))
- return 0;
-
- for (i = 16; i > 0 && buf[i-1] == ' '; i--)
- ;
- buf[i] = '\0';
-
- blobmsg_add_string(b, "vendor", buf);
- return 1;
-}
-
-static int sfp_rom_get_vendor_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_vendor(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_oui(struct blob_buf *b)
-{
- char buf[3];
- char value[9];
-
- if (!sfp_rom_bytes(37, buf, 3))
- return 0;
-
- snprintf(value, sizeof(value), "%02x:%02x:%02x",
- (unsigned char) buf[0], (unsigned char) buf[1], (unsigned char) buf[2]);
- blobmsg_add_string(b, "oui", value);
- return 1;
-}
-
-static int sfp_rom_get_oui_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_oui(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_pn(struct blob_buf *b)
-{
- char buf[17];
- int i;
- if (!sfp_rom_bytes(40, buf, 16))
- return 0;
-
- for (i = 16; i > 0 && buf[i-1] == ' '; i--)
- ;
- buf[i] = '\0';
-
- blobmsg_add_string(b, "pn", buf);
- return 1;
-}
-
-static int sfp_rom_get_pn_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_pn(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_rev(struct blob_buf *b)
-{
- char buf[5];
- int i;
- if (!sfp_rom_bytes(56, buf, 4))
- return 0;
-
- for (i = 4; i > 0 && buf[i-1] == ' '; i--)
- ;
- buf[i] = '\0';
-
- blobmsg_add_string(b, "rev", buf);
- return 1;
-}
-
-static int sfp_rom_get_rev_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_rev(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_sn(struct blob_buf *b)
-{
- char buf[17];
- int i;
- if (!sfp_rom_bytes(68, buf, 16))
- return 0;
-
- for (i = 16; i > 0 && buf[i-1] == ' '; i--)
- ;
- buf[i] = '\0';
-
- blobmsg_add_string(b, "sn", buf);
- return 1;
-}
-static int sfp_rom_get_sn_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_sn(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_date(struct blob_buf *b)
-{
- char buf[8];
- char value[14];
- int i;
- if (!sfp_rom_bytes(84, buf, 8))
- return 0;
-
- value[0] = '2';
- value[1] = '0';
- value[2] = buf[0];
- value[3] = buf[1];
- value[4] = '-';
- value[5] = buf[2];
- value[6] = buf[3];
- value[7] = '-';
- value[8] = buf[4];
- value[9] = buf[5];
- for (i = 8; i > 6 && buf[i-1] == ' '; i--)
- ;
- memset(value+10, 0, 4);
- if (i > 6) {
- value[10] = ' ';
- value[11] = buf[6];
- if (i > 7)
- value[12] = buf[7];
- }
-
- blobmsg_add_string(b, "date", value);
- return 1;
-}
-
-static int sfp_rom_get_date_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_date(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_ddm(struct blob_buf *b)
-{
- int byte = sfp_rom_byte(94);
- char buf[20];
- const char *value;
-
- if (byte < 0)
- return 0;
-
- switch (byte) {
- case 0:
- value = "none";
- break;
- case 1:
- value = "9.3";
- break;
- case 2:
- value = "9.5";
- break;
- case 3:
- value = "10.2";
- break;
- case 4:
- value = "10.4";
- break;
- case 5:
- value = "11.0";
- break;
- case 6:
- value = "11.3";
- break;
- default:
- snprintf(buf, sizeof(buf), "%s %d",
- "reserved", byte);
- value = buf;
- }
- blobmsg_add_string(b, "ddm", value);
- return 1;
-};
-
-static int sfp_rom_get_ddm_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_ddm(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_rom_get_all_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_rom_get_connector(&b);
- sfp_rom_get_ethernet(&b);
- sfp_rom_get_encoding(&b);
- sfp_rom_get_rate(&b);
- sfp_rom_get_length(&b);
- sfp_rom_get_vendor(&b);
- sfp_rom_get_oui(&b);
- sfp_rom_get_pn(&b);
- sfp_rom_get_rev(&b);
- sfp_rom_get_sn(&b);
- sfp_rom_get_date(&b);
- sfp_rom_get_ddm(&b);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-struct sfp_ddm {
- /* For checking when to reread calibration data. */
- time_t timestamp;
- unsigned type; /* From address 92 */
- unsigned version; /* From address 94 */
- /* Calibration constants, read from addresses 56-91 if bit 4 is
- set in ddm_type */
- float rx_pwr[5];
- float tx_i_slope;
- float tx_i_offset;
- float tx_pwr_slope;
- float tx_pwr_offset;
- float t_slope;
- float t_offset;
- float v_slope;
- float v_offset;
-};
-static struct sfp_ddm sfp_ddm;
-
-static int sfp_ddm_read_float(float *x, unsigned addr)
-{
- uint8_t buf[4];
- int32_t m;
- int e;
- unsigned i;
-
- if (!i2c_sfp || sfp_ddm_fd < 0)
- return 0;
- /* Used only for constant data, so byte accesses should be ok. And
- there should only be regular normalized numbers (or zero).
- */
- for (i = 0; i < 4; i++) {
- int byte = i2c_smbus_read_byte_data(sfp_ddm_fd, addr + i);
- if (byte < 0)
- return 0;
- buf[i] = byte;
- }
- e = (buf[0] & 0x7f) << 1 | buf[1] >> 7;
- m = (((int32_t) buf[1] & 0x7f) << 16) | ((int32_t) buf[2] << 8) | buf[3];
- if (e == 0 && m == 0) {
- *x = 0.0;
- return 1;
- }
- if (e == 0 || e == 0xff)
- /* NaN or infinity */
- return 0;
- m |= (1U << 23);
- if (buf[0] & 0x80)
- m = -m;
- *x = ldexpf ((float) m, e - (127 + 23));
-
- return 1;
-}
-
-/* Plain i2c_smbus_read_word_data use little-endian byteorder. We have
- msb first, so swap it. The swap should be a nop for the failure
- case w == -1. */
-static int i2c_smbus_read_word_swapped(int fd, unsigned addr)
-{
- int w = i2c_smbus_read_word_data(fd, addr);
- return (w >> 8) | ((w & 0xff) << 8);
-
-}
-static int sfp_ddm_read_fp(float *x, unsigned addr)
-{
- int w;
-
- if (!i2c_sfp || sfp_ddm_fd < 0)
- return 0;
- w = i2c_smbus_read_word_swapped(sfp_ddm_fd, addr);
- if (w < 0)
- return 0;
- *x = (float) w / 0x100;
- return 1;
-}
-
-static int sfp_ddm_read_si(float *x, unsigned addr)
-{
- int w;
-
- if (!i2c_sfp || sfp_ddm_fd < 0)
- return 0;
- w = i2c_smbus_read_word_swapped(sfp_ddm_fd, addr);
- if (w < 0)
- return 0;
- *x = (float) (int16_t) w;
- return 1;
-}
-
-static int sfp_ddm_read_ui(float *x, unsigned addr)
-{
- int w;
-
- if (!i2c_sfp || sfp_ddm_fd < 0)
- return 0;
- w = i2c_smbus_read_word_swapped(sfp_ddm_fd, addr);
- if (w < 0)
- return 0;
- *x = (float) w;
- return 1;
-}
-
-static int ddm_prepare(void)
-{
- int byte;
- int reread;
- time_t now = time(NULL);
-
- byte = sfp_rom_byte(92);
- if (byte < 0) {
- fail:
- if (sfp_ddm_fd >= 0)
- close(sfp_ddm_fd);
- sfp_ddm_fd = -1;
- return 0;
- }
- if ( (byte & 0xc0) != 0x40)
- goto fail;
-
- if (byte & 4) {
- syslog(LOG_INFO, "sfp: ddm requires address change, not implemented.\n");
- goto fail;
- }
- sfp_ddm.type = byte;
- byte = sfp_rom_byte(94);
- if (byte <= 0)
- goto fail;
- sfp_ddm.version = byte;
- if (sfp_ddm_fd < 0) {
- sfp_ddm_fd = i2c_open_dev(i2c_sfp->bus, i2c_sfp->ddm_addr,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_READ_WORD_DATA);
- if (sfp_ddm_fd < 0)
- return 0;
-
- reread = 1;
- }
- else if (sfp_ddm.type & 0x10)
- /* External calibration */
-
- /* We could check vendor, sn, etc, to try to figure out if the
- SFP has been replaced, but it's less work to just reread
- the calibration data. */
- reread = (now > sfp_ddm.timestamp + 120 || sfp_ddm.timestamp > now);
- else
- reread = 0;
-
- if (reread) {
- if (sfp_ddm.type & 0x10) {
- unsigned i;
- for (i = 0; i < 5; i++)
- if (!sfp_ddm_read_float(&sfp_ddm.rx_pwr[4-i], 56+4*i))
- goto fail;
- if (! (sfp_ddm_read_fp(&sfp_ddm.tx_i_slope, 76)
- && sfp_ddm_read_si(&sfp_ddm.tx_i_offset, 78)
- && sfp_ddm_read_fp(&sfp_ddm.tx_pwr_slope, 80)
- && sfp_ddm_read_si(&sfp_ddm.tx_pwr_offset, 82)
- && sfp_ddm_read_fp(&sfp_ddm.t_slope, 84)
- && sfp_ddm_read_si(&sfp_ddm.t_offset, 86)
- && sfp_ddm_read_fp(&sfp_ddm.v_slope, 88)
- && sfp_ddm_read_si(&sfp_ddm.v_offset, 89))) {
- syslog(LOG_INFO, "sfp: Reading ddm calibration data failed.\n");
- goto fail;
- }
- DEBUG_PRINT("Read ddm calibration data:\n"
- "rx_pwr: %g %g %g %g %g\n"
- "tx_i: %g %g\n"
- "tx_pwr: %g %g\n"
- "T: %g %g\n"
- "V: %g %g\n",
- sfp_ddm.rx_pwr[0], sfp_ddm.rx_pwr[1],
- sfp_ddm.rx_pwr[2], sfp_ddm.rx_pwr[3],
- sfp_ddm.rx_pwr[4],
- sfp_ddm.tx_i_slope, sfp_ddm.tx_i_offset,
- sfp_ddm.tx_pwr_slope, sfp_ddm.tx_pwr_offset,
- sfp_ddm.t_slope, sfp_ddm.t_offset,
- sfp_ddm.v_slope, sfp_ddm.v_offset);
-
- }
- else {
- sfp_ddm.rx_pwr[0] = sfp_ddm.rx_pwr[2]
- = sfp_ddm.rx_pwr[3] = sfp_ddm.rx_pwr[4] = 0.0;
- sfp_ddm.rx_pwr[1] = 1.0;
-
- sfp_ddm.tx_i_slope = sfp_ddm.tx_pwr_slope
- = sfp_ddm.t_slope = sfp_ddm.v_slope = 1.0;
- sfp_ddm.tx_i_offset = sfp_ddm.tx_pwr_offset
- = sfp_ddm.t_offset = sfp_ddm.v_offset = 0.0;
- }
- sfp_ddm.timestamp = now;
- }
- return 1;
-};
-
-static int sfp_ddm_get_temperature(struct blob_buf *b, int raw)
-{
- float x;
- char buf[15];
-
- if (!ddm_prepare())
- return 0;
-
- if (!sfp_ddm_read_si(&x, 96))
- return 0;
-
- x = sfp_ddm.t_slope * x + sfp_ddm.t_offset;
- if (raw) {
- blobmsg_add_u32(b, "raw", (uint32_t) (x+0.5));
- blobmsg_add_string(b, "unit", "1/256 °C");
- }
-
- snprintf(buf, sizeof(buf), "%.2f °C", x * (1.0/256));
- blobmsg_add_string(b, "temperature", buf);
- return 1;
-}
-
-static int sfp_ddm_get_temperature_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_ddm_get_temperature(&b, 1);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_ddm_get_voltage(struct blob_buf *b, int raw)
-{
- float x;
- char buf[10];
- if (!ddm_prepare())
- return 0;
-
- if (!sfp_ddm_read_ui(&x, 98))
- return 0;
-
- x = sfp_ddm.v_slope * x + sfp_ddm.v_offset;
- if (raw) {
- blobmsg_add_u32(b, "raw", (uint32_t) (x+0.5));
- blobmsg_add_string(b, "unit", "100uV");
- }
- snprintf(buf, sizeof(buf), "%.4f V", x * (1.0/10000));
- blobmsg_add_string(b, "voltage", buf);
- return 1;
-}
-
-static int sfp_ddm_get_voltage_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_ddm_get_voltage(&b, 1);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_ddm_get_current(struct blob_buf *b, int raw)
-{
- float x;
- char buf[10];
- if (!ddm_prepare())
- return 0;
-
- if (!sfp_ddm_read_ui(&x, 100))
- return 0;
-
- x = sfp_ddm.tx_i_slope * x + sfp_ddm.tx_i_offset;
- if (raw) {
- blobmsg_add_u32(b, "raw", (uint32_t) (x+0.5));
- blobmsg_add_string(b, "unit", "2 uA");
- }
- snprintf(buf, sizeof(buf), "%.3f mA", x * (1.0/500));
- blobmsg_add_string(b, "current", buf);
- return 1;
-}
-
-static int sfp_ddm_get_current_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_ddm_get_current(&b, 1);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static int sfp_ddm_get_tx_pwr(struct blob_buf *b, int raw)
-{
- float x;
- char buf[10];
- if (!ddm_prepare())
- return 0;
-
- if (!sfp_ddm_read_ui(&x, 102))
- return 0;
-
- x = sfp_ddm.tx_pwr_slope * x + sfp_ddm.tx_pwr_offset;
- if (raw) {
- blobmsg_add_u32(b, "raw", (uint32_t) (x+0.5));
- blobmsg_add_string(b, "unit", "0.1uW");
- }
- snprintf(buf, sizeof(buf), "%.4f mW", x * (1.0/10000));
- blobmsg_add_string(b, "tx-pwr", buf);
-
- return 1;
-}
-
-static int sfp_ddm_get_tx_pwr_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_ddm_get_tx_pwr(&b, 1);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-
-static int sfp_ddm_get_rx_pwr(struct blob_buf *b, int raw)
-{
- unsigned i;
- float x;
- char buf[10];
-
- if (!ddm_prepare())
- return 0;
-
- for (x = sfp_ddm.rx_pwr[0], i = 1; i < 5; i++) {
- float v;
- /* NOTE: There's only a single word to read. It's unclear how
- to get several values. However, typically, rx_pwr[2,3,4]
- are zero. */
- if (sfp_ddm.rx_pwr[i] != 0.0) {
- if (!sfp_ddm_read_ui(&v, 104))
- return 0;
- x += v*sfp_ddm.rx_pwr[i];
- }
- }
- if (raw) {
- blobmsg_add_u32(b, "raw", (uint32_t) (x+0.5));
- blobmsg_add_string(b, "unit", "0.1uW");
- }
-
- snprintf(buf, sizeof(buf), "%.4f mW", x * (1.0/10000));
- blobmsg_add_string(b, "rx-pwr", buf);
- blobmsg_add_string(b, "rx-pwr-type",
- (sfp_ddm.type & 8) ? "average" : "OMA");
- return 1;
-}
-
-static int sfp_ddm_get_rx_pwr_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_ddm_get_rx_pwr(&b, 1);
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-static int sfp_ddm_get_all_method(struct ubus_context *ubus_ctx, struct ubus_object *obj,
- struct ubus_request_data *req, const char *method,
- struct blob_attr *msg)
-{
- blob_buf_init (&b, 0);
- sfp_ddm_get_temperature(&b, 0);
- sfp_ddm_get_voltage(&b, 0);
- sfp_ddm_get_current(&b, 0);
- sfp_ddm_get_tx_pwr(&b, 0);
- sfp_ddm_get_rx_pwr(&b, 0);
-
- ubus_send_reply(ubus_ctx, req, b.head);
- return 0;
-}
-
-static const struct ubus_method sfp_rom_methods[] = {
- { .name = "get-type", .handler = sfp_rom_get_type_method },
- { .name = "get-connector", .handler = sfp_rom_get_connector_method },
- { .name = "get-ethernet", .handler = sfp_rom_get_ethernet_method },
- { .name = "get-encoding", .handler = sfp_rom_get_encoding_method },
- { .name = "get-rate", .handler = sfp_rom_get_rate_method },
- { .name = "get-length", .handler = sfp_rom_get_length_method },
- { .name = "get-vendor", .handler = sfp_rom_get_vendor_method },
- { .name = "get-oui", .handler = sfp_rom_get_oui_method },
- { .name = "get-pn", .handler = sfp_rom_get_pn_method },
- { .name = "get-rev", .handler = sfp_rom_get_rev_method },
- { .name = "get-sn", .handler = sfp_rom_get_sn_method },
- { .name = "get-date", .handler = sfp_rom_get_date_method },
- { .name = "get-ddm", .handler = sfp_rom_get_ddm_method },
- { .name = "get-all", .handler = sfp_rom_get_all_method },
-};
-
-static struct ubus_object_type sfp_rom_type =
- UBUS_OBJECT_TYPE("sfp.rom", sfp_rom_methods);
-
-static const struct ubus_method sfp_ddm_methods[] = {
- { .name = "get-rx-pwr", .handler = sfp_ddm_get_rx_pwr_method },
- { .name = "get-tx-pwr", .handler = sfp_ddm_get_tx_pwr_method },
- { .name = "get-temperature", .handler = sfp_ddm_get_temperature_method },
- { .name = "get-current", .handler = sfp_ddm_get_current_method },
- { .name = "get-voltage", .handler = sfp_ddm_get_voltage_method },
- { .name = "get-all", .handler = sfp_ddm_get_all_method },
-};
-
-static struct ubus_object_type sfp_ddm_type =
- UBUS_OBJECT_TYPE("sfp.ddm", sfp_ddm_methods);
-
-static struct ubus_object sfp_objects[] = {
- { .name = "sfp.rom", .type = &sfp_rom_type,
- .methods = sfp_rom_methods, ARRAY_SIZE(sfp_rom_methods) },
- { .name = "sfp.ddm", .type = &sfp_ddm_type,
- .methods = sfp_ddm_methods, ARRAY_SIZE(sfp_ddm_methods) },
-};
-
-struct sfp_handler * sfp_init( struct uci_context *uci_ctx)
-{
- const char *p;
- int i;
-
- p = ucix_get_option(uci_ctx, "hw", "board", "hardware");
- if (p == 0){
- syslog(LOG_INFO, "%s: Missing Hardware identifier in configuration. I2C is not started\n",__func__);
- return 0;
- }
-
- /* Here we match the hardware name to a init table, and get the
- i2c chip address */
- i2c_sfp = NULL;
- for (i = 0; i < sizeof(i2c_sfp_list) / sizeof(i2c_sfp_list[0]); i++) {
- DEBUG_PRINT("I2C hardware platform %s tested.\n", i2c_sfp_list[i].name);
- if (!strcmp(i2c_sfp_list[i].name, p)) {
- DEBUG_PRINT("I2C hardware platform %s found.\n", p);
- i2c_sfp = &i2c_sfp_list[i];
- break;
- }
- }
- if (!i2c_sfp) {
- DEBUG_PRINT("No sfp I2C hardware found: %s.\n", p);
- return 0;
- }
-
- /* just return something not NULL */
- return (struct sfp_handler *)4;
-}
-
-int sfp_ubus_populate( struct sfp_handler *h, struct ubus_context *ubus_ctx)
-{
- int i;
- int ret;
-
- for (i = 0; i < ARRAY_SIZE(sfp_objects); i++) {
- ret = ubus_add_object (ubus_ctx, &sfp_objects[i]);
- if (ret)
- DEBUG_PRINT("Failed to add sfp object: %s\n", ubus_strerror(ret));
- }
- return 0;
-}
diff --git a/ledmngr/src/ucix.c b/ledmngr/src/ucix.c
deleted file mode 100644
index 2a0d78a3f..000000000
--- a/ledmngr/src/ucix.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * 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.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) 2008 John Crispin
- */
-
-#include
-#include
-
-#include
-#include
-#include "ucix.h"
-
-static struct uci_ptr ptr;
-
-static inline int ucix_get_ptr(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t)
-{
- memset(&ptr, 0, sizeof(ptr));
- ptr.package = p;
- ptr.section = s;
- ptr.option = o;
- ptr.value = t;
- return uci_lookup_ptr(ctx, &ptr, NULL, true);
-}
-
-struct uci_context* ucix_init(const char *config_file)
-{
- struct uci_context *ctx = uci_alloc_context();
- uci_add_delta_path(ctx, "/var/state");
- if(uci_load(ctx, config_file, NULL) != UCI_OK)
- {
- printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file);
- return NULL;
- }
- return ctx;
-}
-
-struct uci_context* ucix_init_path(const char *path, const char *config_file)
-{
- struct uci_context *ctx = uci_alloc_context();
- if(path)
- uci_set_confdir(ctx, path);
- if(uci_load(ctx, config_file, NULL) != UCI_OK)
- {
- printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file);
- return NULL;
- }
- return ctx;
-}
-
-void ucix_cleanup(struct uci_context *ctx)
-{
- uci_free_context(ctx);
-}
-
-void ucix_save(struct uci_context *ctx)
-{
- uci_set_savedir(ctx, "/tmp/.uci/");
- uci_save(ctx, NULL);
-}
-
-void ucix_save_state(struct uci_context *ctx)
-{
- uci_set_savedir(ctx, "/var/state/");
- uci_save(ctx, NULL);
-}
-
-int ucix_get_option_list(struct uci_context *ctx, const char *p,
- const char *s, const char *o, struct list_head *l)
-{
- struct uci_element *e = NULL;
- if(ucix_get_ptr(ctx, p, s, o, NULL))
- return 1;
- if (!(ptr.flags & UCI_LOOKUP_COMPLETE))
- return 1;
- e = ptr.last;
- switch (e->type)
- {
- case UCI_TYPE_OPTION:
- switch(ptr.o->type) {
- case UCI_TYPE_LIST:
- uci_foreach_element(&ptr.o->v.list, e)
- {
- struct ucilist *ul = malloc(sizeof(struct ucilist));
- ul->val = strdup((e->name)?(e->name):(""));
- list_add_tail(&ul->list, l);
- }
- break;
- default:
- break;
- }
- break;
- default:
- return 1;
- }
-
- return 0;
-}
-
-const char* ucix_get_option(struct uci_context *ctx, const char *p, const char *s, const char *o)
-{
- struct uci_element *e = NULL;
- const char *value = NULL;
- if(ucix_get_ptr(ctx, p, s, o, NULL))
- return NULL;
- if (!(ptr.flags & UCI_LOOKUP_COMPLETE))
- return NULL;
- e = ptr.last;
- switch (e->type)
- {
- case UCI_TYPE_SECTION:
- value = uci_to_section(e)->type;
- break;
- case UCI_TYPE_OPTION:
- switch(ptr.o->type) {
- case UCI_TYPE_STRING:
- value = ptr.o->v.string;
- break;
- default:
- value = NULL;
- break;
- }
- break;
- default:
- return 0;
- }
-
- return value;
-}
-
-int ucix_get_option_int(struct uci_context *ctx, const char *p, const char *s, const char *o, int def)
-{
- const char *tmp = ucix_get_option(ctx, p, s, o);
- int ret = def;
-
- if (tmp)
- ret = atoi(tmp);
- return ret;
-}
-
-void ucix_add_section(struct uci_context *ctx, const char *p, const char *s, const char *t)
-{
- if(ucix_get_ptr(ctx, p, s, NULL, t))
- return;
- uci_set(ctx, &ptr);
-}
-
-void ucix_add_option(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t)
-{
- if(ucix_get_ptr(ctx, p, s, o, (t)?(t):("")))
- return;
- uci_set(ctx, &ptr);
-}
-
-void ucix_add_option_int(struct uci_context *ctx, const char *p, const char *s, const char *o, int t)
-{
- char tmp[64];
- snprintf(tmp, 64, "%d", t);
- ucix_add_option(ctx, p, s, o, tmp);
-}
-
-void ucix_del(struct uci_context *ctx, const char *p, const char *s, const char *o)
-{
- if(!ucix_get_ptr(ctx, p, s, o, NULL))
- uci_delete(ctx, &ptr);
-}
-
-void ucix_revert(struct uci_context *ctx, const char *p, const char *s, const char *o)
-{
- if(!ucix_get_ptr(ctx, p, s, o, NULL))
- uci_revert(ctx, &ptr);
-}
-
-void ucix_for_each_section_type(struct uci_context *ctx,
- const char *p, const char *t,
- void (*cb)(const char*, void*), void *priv)
-{
- struct uci_element *e;
- if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
- return;
- uci_foreach_element(&ptr.p->sections, e)
- if (!strcmp(t, uci_to_section(e)->type))
- cb(e->name, priv);
-}
-
-int ucix_commit(struct uci_context *ctx, const char *p)
-{
- if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
- return 1;
- return uci_commit(ctx, &ptr.p, false);
-}
-
diff --git a/minidlna/files/minidlna.config b/minidlna/files/minidlna.config
index 91a5cc330..32ef2d44e 100644
--- a/minidlna/files/minidlna.config
+++ b/minidlna/files/minidlna.config
@@ -2,7 +2,7 @@ config minidlna config
option 'enabled' '1'
option port '8200'
option interface 'br-lan'
- option friendly_name 'OpenWrt DLNA Server'
+ option friendly_name 'Inteno DLNA Server'
option db_dir '/var/run/minidlna'
option log_dir '/var/log'
option inotify '1'
diff --git a/peripheral_manager/src/src/i2c.h b/peripheral_manager/src/src/i2c.h
index 9d7480220..454057a42 100644
--- a/peripheral_manager/src/src/i2c.h
+++ b/peripheral_manager/src/src/i2c.h
@@ -1,28 +1,5 @@
#ifndef I2C_H
#define I2C_H
-/*
-struct i2c_reg_tab {
- char addr;
- char value;
- char range;
-};*/
-
-/*
-struct i2c_touch{
- int dev;
- int shadow_irq;
- int shadow_touch;
- int shadow_proximity;
- int addr;
- int irq_button;
- const struct i2c_reg_tab *init_tab;
- int init_tab_len;
- const char *name;
-} *i2c_touch;*/
-
-
-//void do_init_tab( struct i2c_touch *i2c_touch);
-//struct i2c_touch * i2c_init(struct uci_context *uci_ctx, char* i2c_dev_name, struct i2c_touch* i2c_touch_list, int len);
void dump_i2c(int fd,int start,int stop);
int i2c_open_dev (const char *bus, int addr, unsigned long needed);
diff --git a/speedtest-cli/Makefile b/speedtest-cli/Makefile
new file mode 100644
index 000000000..07910fc1f
--- /dev/null
+++ b/speedtest-cli/Makefile
@@ -0,0 +1,42 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+
+PKG_NAME:=speedtest-cli
+PKG_RELEASE:=1
+PKG_SOURCE:=speedtest_cli.py
+PKG_SOURCE_URL:=https://raw.githubusercontent.com/sivel/speedtest-cli/master
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/speedtest-cli
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=speedtest-cli utility
+ DEPENDS:=+python +python-mini +python-openssl +python-expat
+ URL:=https://github.com/sivel/speedtest-cli
+endef
+
+define Package/speedtest-cli/description
+ Command line interface for testing internet bandwidth using speedtest.net.
+endef
+
+define Build/Prepare
+endef
+
+define Build/Compile
+endef
+
+define Package/speedtest-cli/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(CP) $(DL_DIR)/speedtest_cli.py $(1)/sbin/
+ chmod 744 $(1)/sbin/speedtest_cli.py
+endef
+
+$(eval $(call BuildPackage,speedtest-cli))
diff --git a/teliasafety-misc/Makefile b/teliasafety-misc/Makefile
new file mode 100644
index 000000000..2f5b6a39e
--- /dev/null
+++ b/teliasafety-misc/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_RELEASE:=1
+PKG_VERSION:=1.0.1
+ifeq ($(CONFIG_PACKAGE_bcmkernel),y)
+PKG_SOURCE_URL:=git@iopsys.inteno.se:teliasafety-misc.git
+else
+PKG_SOURCE_URL:=http://ihgsp.inteno.se/git/teliasafety-misc.git
+endif
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=8feb071dc9c05b5580043718aaafe424ce557afe
+PKG_NAME:=teliasafety-misc
+
+
+LDFLAGS+= \
+ -Wl,-rpath-link=$(STAGING_DIR)/usr/lib \
+ -Wl,-rpath-link=$(STAGING_DIR)/lib
+
+RSTRIP:=true
+
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/teliasafety-misc
+ CATEGORY:=Utilities
+ TITLE:=Misc stuff for teliasafety
+ URL:=
+ DEPENDS:=
+endef
+
+define Package/teliasafety-misc/description
+ Broadcom endpoint test application
+endef
+
+
+define Package/teliasafety-misc/install
+ $(INSTALL_DIR) $(1)/etc/init.d/
+ cp $(PKG_BUILD_DIR)/files/etc/init.d/* $(1)/etc/init.d/
+endef
+
+$(eval $(call BuildPackage,teliasafety-misc))