dcwifi: Update component versions 10170/head
authorCarey Sonsino <csonsino@gmail.com>
Mon, 30 Sep 2019 14:14:02 +0000 (14:14 +0000)
committerCarey Sonsino <csonsino@gmail.com>
Wed, 9 Oct 2019 14:53:01 +0000 (14:53 +0000)
update package versions and hashes
remove bzero patches
remove uclibc++ patch
refactor directory structure
relocate mrmctl in menuconfig
update macremapper patch

Signed-off-by: Carey Sonsino <careys@edgewaterwireless.com>
Signed-off-by: Carey Sonsino <csonsino@gmail.com>
39 files changed:
kernel/macremapper/Makefile [new file with mode: 0644]
kernel/macremapper/patches/01_fix_nf_hooks.patch [new file with mode: 0644]
libs/libdcwproto/Makefile [new file with mode: 0644]
libs/libdcwsocket/Makefile [new file with mode: 0644]
libs/libdcwsocket/patches/02_fix_storage_size_error.patch [new file with mode: 0644]
net/dcstad/Makefile [new file with mode: 0644]
net/dcwapd/Makefile [new file with mode: 0644]
net/dcwapd/files/dcwapd.inc [new file with mode: 0644]
net/dcwapd/files/dcwapd.init.d [new file with mode: 0755]
net/dcwapd/files/dcwapd.uci [new file with mode: 0644]
net/dcwapd/files/start_dcwapd.sh [new file with mode: 0755]
net/dcwapd/files/stop_dcwapd.sh [new file with mode: 0755]
net/dcwapd/patches/01_add_uci_config_provider.patch [new file with mode: 0644]
net/dcwapd/patches/02_use_uci_config_provider.patch [new file with mode: 0644]
net/dcwapd/patches/03_add_uci_config_provider_to_Makefile.patch [new file with mode: 0644]
net/dcwifi/README.md [deleted file]
net/dcwifi/dcstad/Makefile [deleted file]
net/dcwifi/dcstad/patches/01_replace_bzero.patch [deleted file]
net/dcwifi/dcwapd/Makefile [deleted file]
net/dcwifi/dcwapd/files/dcwapd.inc [deleted file]
net/dcwifi/dcwapd/files/dcwapd.init.d [deleted file]
net/dcwifi/dcwapd/files/dcwapd.uci [deleted file]
net/dcwifi/dcwapd/files/start_dcwapd.sh [deleted file]
net/dcwifi/dcwapd/files/stop_dcwapd.sh [deleted file]
net/dcwifi/dcwapd/patches/01_add_uci_config_provider.patch [deleted file]
net/dcwifi/dcwapd/patches/02_use_uci_config_provider.patch [deleted file]
net/dcwifi/dcwapd/patches/03_add_uci_config_provider_to_Makefile.patch [deleted file]
net/dcwifi/dcwapd/patches/04_uclibc++_fixes.patch [deleted file]
net/dcwifi/dcwapd/patches/05_replace_bzero.patch [deleted file]
net/dcwifi/libdcwproto/Makefile [deleted file]
net/dcwifi/libdcwproto/patches/01_replace_bzero.patch [deleted file]
net/dcwifi/libdcwsocket/Makefile [deleted file]
net/dcwifi/libdcwsocket/patches/01_replace_bzero.patch [deleted file]
net/dcwifi/libdcwsocket/patches/02_fix_storage_size_error.patch [deleted file]
net/dcwifi/macremapper/Makefile [deleted file]
net/dcwifi/macremapper/patches/01_fix_nf_hooks.patch [deleted file]
net/dcwifi/mrmctl/Makefile [deleted file]
net/dcwifi/mrmctl/patches/01_replace_bzero.patch [deleted file]
net/mrmctl/Makefile [new file with mode: 0644]

diff --git a/kernel/macremapper/Makefile b/kernel/macremapper/Makefile
new file mode 100644 (file)
index 0000000..fc242ee
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# Copyright (C) 2019 EWSI
+#
+# 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:=macremapper
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=f9580427803123d13d50f3422623a37212034a5d72a485f9c04904f19509e4bb
+
+PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
+PKG_LICENSE:=GPL-2.0-only
+PKG_LICENSE_FILES:=kernelmod/COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/macremapper
+  SUBMENU:=Network Support
+  URL:=https://www.edgewaterwireless.com
+  VERSION:=$(LINUX_VERSION)-$(BOARD)-$(PKG_RELEASE)
+  TITLE:=Dual Channel Wi-Fi macremapper Module
+  DEPENDS:= +kmod-cfg80211 +kmod-br-netfilter
+  FILES:=$(PKG_BUILD_DIR)/kernelmod/$(PKG_NAME).$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoProbe,macremapper)
+endef
+
+define KernelPackage/macremapper/description
+  Linux kernel module for implementation the DCW filtering mechanism
+endef
+
+MAKE_FLAGS += KERNEL_SRC=$(LINUX_DIR)
+MAKE_PATH:=kernelmod
+
+$(eval $(call KernelPackage,macremapper))
diff --git a/kernel/macremapper/patches/01_fix_nf_hooks.patch b/kernel/macremapper/patches/01_fix_nf_hooks.patch
new file mode 100644 (file)
index 0000000..29cb421
--- /dev/null
@@ -0,0 +1,27 @@
+--- a/kernelmod/main.c
++++ b/kernelmod/main.c
+@@ -98,8 +98,11 @@ modinit( void ) {
+   rv = mrm_rcdb_init();
+   if (rv != 0) return rv;
+-
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0)
+   nf_register_hook(&_hops);
++#else
++  nf_register_net_hook(&init_net, &_hops);
++#endif
+   mrm_init_ctlfile(); /* XXX not checking for failure! */
+   printk(KERN_INFO "MRM The MAC Address Re-Mapper is now in the kernel\n");
+@@ -110,7 +113,11 @@ modinit( void ) {
+ static void __exit
+ modexit( void ) {
+   mrm_destroy_ctlfile();
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0)
+   nf_unregister_hook(&_hops);
++#else
++  nf_unregister_net_hook(&init_net, &_hops);
++#endif
+   mrm_rcdb_destroy(); /* imperative that this happens last */
+   printk(KERN_INFO "MRM The MAC Address Re-Mapper gone bye-bye\n");
+ }
diff --git a/libs/libdcwproto/Makefile b/libs/libdcwproto/Makefile
new file mode 100644 (file)
index 0000000..37905b8
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2019 EWSI
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdcwproto
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=b3d12f2533eafbb293bbf27608ff39520508d955a084f33894c594f39d2f7c8e
+
+PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdcwproto
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Networking
+  TITLE:=Dual-Channel WiFi messaging library
+  URL:=https://www.edgewaterwireless.com
+  DEPENDS:=+kmod-macremapper
+endef
+
+define Package/libdcwproto/description
+  Platform-independent C library for marshaling and serializing DCW messages
+endef
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
+endef
+
+define Package/libdcwproto/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       # Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdcwproto))
diff --git a/libs/libdcwsocket/Makefile b/libs/libdcwsocket/Makefile
new file mode 100644 (file)
index 0000000..73a4c3a
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2019 EWSI
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdcwsocket
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_HASH:=71383c4d8c5f58c1299a3717d7de9a8b5dabfd51a2dcf9993248f2709908d23a
+
+PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdcwsocket
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Networking
+  TITLE:=Dual-Channel socket library
+  URL:=https://www.edgewaterwireless.com
+endef
+
+define Package/libdcwsocket/description
+  User-land C library for sending and receiving DCW "EtherType"d messages
+endef
+
+TARGET_CFLAGS += -std=c89 -ffunction-sections -fdata-sections -flto
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
+endef
+
+define Package/libdcwsocket/install
+       $(INSTALL_DIR) $(1)/usr/lib
+       # Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdcwsocket))
diff --git a/libs/libdcwsocket/patches/02_fix_storage_size_error.patch b/libs/libdcwsocket/patches/02_fix_storage_size_error.patch
new file mode 100644 (file)
index 0000000..431b093
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/src/dcwsocket.c.linux
++++ b/src/dcwsocket.c.linux
+@@ -31,6 +31,7 @@
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
++#include <linux/if.h>
+ #include <linux/if_packet.h>
+ #include <linux/if_ether.h>
+ #include <linux/filter.h>
diff --git a/net/dcstad/Makefile b/net/dcstad/Makefile
new file mode 100644 (file)
index 0000000..3112b0c
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2019 EWSI
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=dcstad
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=3bed8a5051c92cd41ba3477d2db211df8f10fd6e49946f0b74cf643464c1c201
+
+PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/dcstad
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=Routing and Redirection
+  TITLE:=Dual-Channel WiFi client daemon
+  URL:=https://www.edgewaterwireless.com
+  DEPENDS:=+libdcwsocket +libdcwproto
+endef
+
+define Package/dcstad/description
+Implementation of the Dual-Channel WiFi client daemon
+endef
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+define Package/dcstad/install
+       $(INSTALL_DIR) $(1)/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/dcstad $(1)/bin/
+endef
+
+$(eval $(call BuildPackage,dcstad))
diff --git a/net/dcwapd/Makefile b/net/dcwapd/Makefile
new file mode 100644 (file)
index 0000000..0fe3362
--- /dev/null
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2019 EWSI
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=dcwapd
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=58e52bf4e7526b2f26319740549dbcc6f6ab505f587815ee8731e40f7fecb625
+
+PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/uclibc++.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/dcwapd
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=Routing and Redirection
+  TITLE:=Dual-Channel WiFi AP daemon
+  URL:=https://www.edgewaterwireless.com
+  DEPENDS:=$(CXX_DEPENDS) +kmod-macremapper +libdcwsocket +libdcwproto +mrmctl +libuci
+endef
+
+define Package/dcwapd/description
+Implementation of the Dual-Channel WiFi AP daemon
+endef
+
+CONFIGURE_ARGS += \
+       --enable-platform=linuxjsonstatic \
+       --enable-shared
+
+TARGET_CXXFLAGS += -std=c++11 -DRAPIDJSON_HAS_CXX11_RVALUE_REFS=0 -ffunction-sections -fdata-sections -flto
+TARGET_LDFLAGS += -ldcwproto -ldcwsocket -lmrmfilterparser -luci -Wl,--gc-sections,--as-needed
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+endef
+
+define Package/dcwapd/install
+       $(INSTALL_DIR) $(1)/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/bin/
+       $(INSTALL_DIR) $(1)/usr/lib
+       # Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+
+#      Utility files
+       $(INSTALL_DIR) $(1)/etc/$(PKG_NAME)
+       $(INSTALL_DATA) ./files/*.inc $(1)/etc/$(PKG_NAME)/
+       $(INSTALL_BIN) ./files/*.sh $(1)/etc/$(PKG_NAME)/
+#      UCI config file copy - this is here for convenience and reference only
+       $(INSTALL_DATA) ./files/dcwapd.uci $(1)/etc/$(PKG_NAME)/
+
+#      UCI config file
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DATA) ./files/dcwapd.uci $(1)/etc/config/dcwapd
+
+#      Init script
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_BIN) ./files/dcwapd.init.d $(1)/etc/init.d/dcwapd
+endef
+$(eval $(call BuildPackage,dcwapd))
diff --git a/net/dcwapd/files/dcwapd.inc b/net/dcwapd/files/dcwapd.inc
new file mode 100644 (file)
index 0000000..c4b44f1
--- /dev/null
@@ -0,0 +1,256 @@
+#!/bin/sh
+
+#
+# Dual Channel Wi-Fi Startup Script
+#
+# This script creates the proper network bridge configuration
+#  necessary for Dual Channel Wi-Fi, and starts the dcwapd daemon
+#
+
+verbose=1
+
+uciconfig=dcwapd
+
+result=
+
+# NOTE: all functions write the result to the $result variable
+
+get_channelsets()
+{
+       # default to empty
+       result=
+       channelsets=$(uci show $uciconfig | grep "=channel-set$")
+       for channelset in $channelsets; do
+               channelset=$(echo "$channelset" | sed -rn "s/$uciconfig\.(.*)=.*/\1/p")
+               result="$result $channelset"
+       done
+       if [ $verbose -eq 1 ]; then
+               echo "Channel Sets: $result" 2>&1 | logger
+       fi
+}
+
+# $1 : the channel set name
+get_channelset_enabled()
+{
+       # default to disabled
+       result=0
+       if [ -n "$1" ]; then
+               result=$(uci get $uciconfig."$1".enabled)
+       fi
+       if [ $verbose -eq 1 ]; then
+               echo "Channel Set \"$1\" Enabled: $result" 2>&1 | logger
+       fi
+}
+
+# $1 : the channel set name
+get_primary_bridge()
+{
+       result=
+       if [ -n "$1" ]; then
+               result=$(uci get $uciconfig."$1".bridge)
+       fi
+       if [ $verbose -eq 1 ]; then
+               echo "Channel Set \"$1\" Primary Bridge: $result" 2>&1 | logger
+       fi
+}
+
+# $1 : the channel set name
+get_datachannels()
+{
+       # default to empty
+       result=
+       if [ -n "$1" ]; then
+               result=$(uci get $uciconfig."$1".data_channels)
+       fi
+       if [ $verbose -eq 1 ]; then
+               echo "Channel Set \"$1\" Data Channels: $result" 2>&1 | logger
+       fi
+}
+
+# $1 : the wlan interface name
+get_wifi_iface_num()
+{
+       result=
+       if [ -n "$1" ];then
+               #result=$(echo "$1" | sed -n "s/wlan//p")
+               result=$(echo "$1" | sed -rn "s/wlan([0-9]*).*/\1/p")
+       fi
+}
+
+# $1 : the bridge name
+get_bridge_network_name()
+{
+       result=
+       if [ -n "$1" ];then
+               result=$(echo "$1" | sed -n "s/br-//p")
+       fi
+}
+
+# $1 : the wlan interface name
+set_iface_init_state()
+{
+       result=
+       if [ -n "$1" ]; then
+               iface=$1
+               # need to extract the "X" from wlanX
+               get_wifi_iface_num "$iface"
+               iface_num=$result
+               if [ -n "$iface_num" ]; then
+                       # get the iface network
+                       init_net=$(uci get wireless.@wifi-iface[$iface_num].network)
+                       if [ -n "$init_net" ]; then
+                               # if the iface network is a bridge, but doesn't start with "br-"
+                               #  I think we need to prepend it?
+                               net_type=$(uci get network."$init_net".type)
+                               if [ -n "$net_type" ] && [ "$net_type" = "bridge" ]; then
+                                       prefix_ok=$(echo "$init_net" | grep "^br-")
+                                       if [ -z "$prefix_ok" ]; then
+                                               init_net="br-$init_net"
+                                       fi
+                               fi
+                       fi
+
+                       # make sure that the init_net section exists
+                       init_net_section=$(uci get dcwapd.init_net)
+                       if [ "$init_net_section" != "init_net" ]; then
+                               # the section did not exist
+                               uci set dcwapd.init_net=init_net
+                       fi
+
+                       # save the initial network
+                       if [ $verbose -eq 1 ]; then
+                               echo "Saving '$iface' initial network '$init_net'" 2>&1 | logger
+                       fi
+                       uci set $uciconfig.init_net."$iface"="$init_net"
+                       uci commit
+
+                       # save the initial network in the result variable
+                       result=$init_net
+               fi
+       fi
+}
+
+# $1 : the wlan interface name
+get_iface_init_state()
+{
+       result=
+       if [ -n "$1" ];then
+               init_net=$(uci get $uciconfig.init_net."$iface")
+
+               # if the response starts with "uci: ", it was an error not the real result
+               err=$(echo "$init_net" | grep "^uci: ")
+               if [ -z "$err" ]; then
+                       # no error, set the result
+                       result=$init_net
+
+                       if [ $verbose -eq 1 ]; then
+                               echo "Got '$iface' initial network '$init_net'" 2>&1 | logger
+                       fi
+               fi
+       fi
+}
+
+# $1 : the name of the data channel name to bring up
+datachannel_up()
+{
+       if [ -n "$1" ]; then
+               bridge=$(uci get $uciconfig."$1".bridge)
+               interfaces=$(uci get $uciconfig."$1".interfaces)
+                if [ $verbose -eq 1 ]; then
+                       echo "Creating Data Channel Bridge: $bridge" 2>&1 | logger
+               fi
+
+               get_bridge_network_name "$bridge"
+               netname=$result
+               if [ -n "$netname" ]; then
+                   uci set network."$netname"=interface
+                   uci set network."$netname".type=bridge
+                   uci set network."$netname".proto=static
+                   uci set network."$netname".bridge_empty='1'
+               fi
+
+               # create the bridge
+               uci commit
+               /etc/init.d/network reload
+
+               for iface in $interfaces; do
+                       # if iface is in a bridge, the bridge name should be stored in result
+                       set_iface_init_state "$iface"
+                       init_bridge=$result
+
+                       # update uci with the new bridge info
+                       get_wifi_iface_num "$iface"
+                       iface_num=$result
+                       if [ -n "$iface_num" ]; then
+                           uci set wireless.@wifi-iface[$iface_num].network="$netname"
+                       fi
+
+                       # manually put the interface into the data bridge
+                       # if iface is in a bridge, remove it before adding it to the data bridge
+                       if [ -n "$init_bridge" ]; then
+                               brctl delif "$init_bridge" "$iface" 2>&1 | logger
+                       fi
+                       brctl addif "$bridge" "$iface" 2>&1 | logger
+               done
+
+               # commit uci changes and reload the network
+               uci commit
+               /etc/init.d/network reload
+               #/etc/init.d/network restart
+               # while [ 1 ]; do
+               #       ifconfig "$bridge" > /dev/null 2>&1
+               #       if [ $? == 0 ]; then
+               #               break;
+               #       fi
+               #       sleep 1
+               # done
+       fi
+}
+
+# $1 : the name of the data channel to bring down
+datachannel_down()
+{
+       if [ -n "$1" ]; then
+               bridge=$(uci get $uciconfig."$1".bridge)
+               interfaces=$(uci get $uciconfig."$1".interfaces)
+               for iface in $interfaces; do
+                       if [ $verbose -eq 1 ]; then
+                               echo "Deconfiguring Data Channel Interface: $iface" 2>&1 | logger
+                       fi
+
+                       # manually remove the interface from the data bridge
+                       brctl delif "$bridge" "$iface" 2>&1 | logger
+
+                       get_iface_init_state "$iface"
+                       init_bridge=$result
+                       if [ -n "$init_bridge" ]; then
+                               # manually move the interface back to the original bridge
+                               brctl addif "$init_bridge" "$iface" 2>&1 | logger
+
+                               # update uci with the new bridge and interface configuration
+                               get_wifi_iface_num "$iface"
+                               iface_num=$result
+                               get_bridge_network_name "$init_bridge"
+                               netname=$result
+                               if [ -n "$iface_num" ] && [ -n "$netname" ]; then
+                                   uci set wireless.@wifi-iface[$iface_num].network="$netname"
+                               fi
+                       fi
+               done
+               if [ $verbose -eq 1 ]; then
+                       echo "Deconfiguring Data Channel Bridge: $bridge" 2>&1 | logger
+               fi
+
+               # delete the bridge from uci
+               get_bridge_network_name "$bridge"
+               netname=$result
+               if [ -n "$netname" ]; then
+                   uci delete network."$netname"
+               fi
+
+               # commit uci changes and reload the network
+               uci commit
+               /etc/init.d/network reload
+               #`/etc/init.d/network restart`
+       fi
+}
diff --git a/net/dcwapd/files/dcwapd.init.d b/net/dcwapd/files/dcwapd.init.d
new file mode 100755 (executable)
index 0000000..6f6a48f
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+# Setting the stop value makes the restart script unreliable when invoked by LuCI
+#STOP=0
+
+scriptdir=/etc/dcwapd
+
+#validate_section_dcwapd() {
+#      uci_validate_section dcwapd general "${1}" \
+#              'enabled:bool:1'
+#}
+
+start() {
+#      validate_section_dcwapd dcwapd
+
+       # only run the start script if the enabled uci option is set properly
+       enabled=$(uci get dcwapd.general.enabled)
+       if [ "${enabled}" = "1" ]; then
+               ${scriptdir}/start_dcwapd.sh
+       else
+               echo "dcwapd is disabled in UCI"
+               return 1
+       fi
+}
+
+stop() {
+        ${scriptdir}/stop_dcwapd.sh
+       # Add a sleep after stopping because an immediate restat will fail otherwise
+       sleep 1
+}
diff --git a/net/dcwapd/files/dcwapd.uci b/net/dcwapd/files/dcwapd.uci
new file mode 100644 (file)
index 0000000..b24ec6f
--- /dev/null
@@ -0,0 +1,116 @@
+######################################################
+# Copyright 2018 EWSI
+#
+# Licensed to the public under the Apache License 2.0.
+######################################################
+# Dual Channel Wi-Fi AP Daemon configuration
+
+###################
+# General Options #
+###################
+# The "enabled" option controls the run state of the Dual Channel Wi-Fi AP Daemon
+#  0 - disabled, 1 - enabled
+# The "tmpdir" option MUST be specified
+#  option tmpdir '<path_of_temp_dir>'
+
+config general 'general'
+       option enabled 0
+       option tmpdir '/tmp/dcwapd'
+
+################
+# Channel Sets #
+################
+# Sections of type "channel-set" define a Dual Channel Wi-Fi primary channel,
+#  along with it's associated data channels
+#
+# The "data_channels" option is a space-delimited list of "datachannel"-typed instance names
+
+config channel-set 'channelset0'
+       option enabled 0
+#      option enabled 1
+       option ssid 'OpenWrt'
+       option bridge 'br-lan'
+       option data_channels 'datachannel0'
+
+#config channel-set 'channelset1'
+#      option enabled 0
+#      option ssid 'OpenWrt2'
+#      option bridge 'br-lan'
+#      option data_channels 'datachannel1'
+
+#################
+# Data Channels #
+#################
+# Sections of type "datachannel" define a Dual Channel Wi-Fi data channel,
+#  along with it's associated bridge and wireless interfaces
+#
+# The "interfaces" option is a space-delimited list of wireless interface names 
+
+config datachannel 'datachannel0'
+       option ssid 'DCW0'
+       option bridge 'br-dc0'
+       option interfaces 'wlan2 wlan5'
+
+#config datachannel 'datachannel1'
+#      option ssid 'DCW1'
+#      option bridge 'br-dc1'
+#      option interfaces 'wlan4'
+
+####################
+# Init Net Options #
+####################
+# The "init_net" section MUST be specified
+#  This section will be used to save and restore the state of the data interfaces
+config init_net 'init_net'
+
+###############
+# Filter Sets #
+###############
+# Sections of type "filter-set" define a Dual Channel Wi-Fi group of filters,
+#  along with it's associated MAC address and filter rules
+# 
+# The "TFP_Default" filter set MUST be defined, although it is not required
+#  to have any associated filter rules
+# The "TFP_Default" filter mac option can have the value of '*', meaning match
+#  all MAC addresses
+#
+# The "filters" option is a space-delimited list of "filter"-typed instance names
+
+config filter-set 'TFP_Default'
+       option mac '*'
+       option filters 'filter0 filter1'
+
+#config filter-set 'filterset0'
+#      option mac '00:00:BE:EF:F0:0D'
+#      option filters 'filter2'
+
+
+################
+# Filter Rules #
+################
+# Sections of type "filter" define a Dual Channel Wi-Fi filter,
+#  along with it's associated filter parameters
+# 
+# Any or all of the filter options may be set to '*' to match
+#  all values
+
+config filter 'filter0'
+       option packet_size '*'
+       option source_ip '*'
+       option source_port '80'
+       option protocol 'tcp'
+       option dest_port '*'
+
+config filter 'filter1'
+       option packet_size '*'
+       option source_ip '*'
+       option source_port '443'
+       option protocol 'tcp'
+       option dest_port '*'
+
+#config filter 'filter2'
+#      option packet_size '*'
+#      option source_ip '*'
+#      option source_port '22'
+#      option protocol 'tcp'
+#      option dest_port '*'
diff --git a/net/dcwapd/files/start_dcwapd.sh b/net/dcwapd/files/start_dcwapd.sh
new file mode 100755 (executable)
index 0000000..8a8c11b
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+#
+# Dual Channel Wi-Fi Startup Script
+#
+# This script creates the proper network bridge configuration
+#  necessary for Dual Channel Wi-Fi, and starts the dcwapd daemon
+#
+
+# Note - shellcheck cannot deal with the dynamic sourcing
+# shellcheck disable=SC1090
+# which also messes with variables defined in the sourced file
+# shellcheck disable=SC2154
+scriptdir=$(dirname -- "$(readlink -f -- "$0")")
+. "$scriptdir"/dcwapd.inc
+
+get_channelsets
+# get the list of channel sets
+channelsets=$result
+
+for channelset in $channelsets; do
+       if [ -n "$channelset" ]; then
+               get_channelset_enabled "$channelset"
+               enabled=$result
+               if [ "$enabled" = "1" ]; then
+                       # the channel set is enabled
+
+                       # get the list of data channels used by the channel set
+                       get_datachannels "$channelset"
+                       datachannels=$result
+                       for datachannel in $datachannels; do
+                               datachannel_up "$datachannel"
+                       done
+               fi
+       fi
+done
+
+# start dcwapd, sending stdout and stderr to the system log
+dcwapd 2>&1 | logger &
diff --git a/net/dcwapd/files/stop_dcwapd.sh b/net/dcwapd/files/stop_dcwapd.sh
new file mode 100755 (executable)
index 0000000..a360a82
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+#
+# Dual Channel Wi-Fi Startup Script
+#
+# This script creates the proper network bridge configuration
+#  necessary for Dual Channel Wi-Fi, and starts the dcwapd daemon
+#
+
+# Note - shellcheck cannot deal with the dynamic sourcing
+# shellcheck disable=SC1090
+# which also messes with variables defined in the sourced file
+# shellcheck disable=SC2154
+scriptdir=$(dirname -- "$(readlink -f -- "$0")")
+. "$scriptdir"/dcwapd.inc
+
+pid=$(pidof dcwapd)
+if [ -n "$pid" ]; then
+       if [ "$verbose" -eq "1" ]; then
+               echo "Stopping dcwapd..." 2>&1 | logger
+       fi
+       kill "$pid"
+fi
+
+get_channelsets
+# get the list of channel sets
+channelsets=$result
+
+for channelset in $channelsets; do
+       if [ -n "$channelset" ]; then
+# we don't care if it is enabled, tear it down
+#              get_channelset_enabled $channelset
+#              enabled=$result
+#              if [ $enabled = "1" ]; then
+#                      # the channel set is enabled
+
+                       # get the list of data channels used by the channel set
+                       get_datachannels "$channelset"
+                       datachannels=$result
+                       for datachannel in $datachannels; do
+                               datachannel_down "$datachannel"
+                       done
+#              fi
+       fi
+done
diff --git a/net/dcwapd/patches/01_add_uci_config_provider.patch b/net/dcwapd/patches/01_add_uci_config_provider.patch
new file mode 100644 (file)
index 0000000..afb034b
--- /dev/null
@@ -0,0 +1,475 @@
+--- a/dev/null
++++ b/dcwlinux/uci_configuration_provider.h
+@@ -0,0 +1,104 @@
++#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
++#define UCI_CONFIGURATION_PROVIDER_H_INCLUDED
++
++#include "./ap_configuration.h"
++
++namespace dcwlinux {
++
++class UciConfigurationProvider : public APConfigurationProvider {
++
++  static const char *SECTION_TYPE_GENERAL;
++  static const char *SECTION_TYPE_CHANNEL_SET;
++  static const char *SECTION_TYPE_DATA_CHANNEL;
++  static const char *SECTION_TYPE_FILTER_SET;
++  static const char *SECTION_TYPE_FILTER;
++  static const char *DEFAULT_FILTER_SET_NAME;
++
++  static const char *OPTION_TMPDIR;
++  static const char *OPTION_ENABLED;
++  static const char *OPTION_SSID;
++  static const char *OPTION_BRIDGE;
++  static const char *OPTION_DATA_CHANNELS;
++  static const char *OPTION_INTERFACES;
++  static const char *OPTION_MAC_ADDRESS;
++  static const char *OPTION_FILTERS;
++  static const char *OPTION_PACKET_SIZE;
++  static const char *OPTION_SOURCE_IP;
++  static const char *OPTION_SOURCE_PORT;
++  static const char *OPTION_PROTOCOL;
++  static const char *OPTION_DEST_PORT;
++
++  static const char *FILTER_FILE_EXTENSION;
++
++  UciConfigurationProvider(const UciConfigurationProvider&); //no copy
++
++  typedef std::map<std::string, std::string>  DataChannelBridgeMap;
++  struct PrimaryChannel {
++    std::string            bridgeName;
++    DataChannelBridgeMap   dataChannels;
++  };
++  typedef std::map<std::string, PrimaryChannel>   PrimaryChannelMap;
++  typedef std::map<dcw::MacAddress, std::string>  StationFilterMap;
++
++  struct uci_context *_uciContext;
++  struct uci_package *_uciPackage;
++  const char *_uciConfig;
++
++  std::string        _filterDirectory;
++  PrimaryChannelMap  _primaryChannels;
++  StationFilterMap   _stationFilters;
++
++public:
++  UciConfigurationProvider(const char * const uciConfig); // the "config" part of UCI commands
++  virtual ~UciConfigurationProvider();
++
++  virtual void InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const;
++  virtual void GetPrimarySsids(SsidSet& output) const;
++  virtual void GetDataSsids(SsidSet& output, const char * const primarySsid) const;
++  virtual const char *GetSsidIfname(const char * const ssid) const;
++  virtual void GetStationTrafficFilterProfiles(StationTFPMap& output) const;
++};
++
++}; //namespace dcwlinux {
++
++#endif //#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
++#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
++#define UCI_CONFIGURATION_PROVIDER_H_INCLUDED
++
++#include "./ap_configuration.h"
++
++namespace dcwlinux {
++
++class UciConfigurationProvider : public APConfigurationProvider {
++  UciConfigurationProvider(const UciConfigurationProvider&); //no copy
++
++  typedef std::map<std::string, std::string>  DataChannelBridgeMap;
++  struct PrimaryChannel {
++    std::string            bridgeName;
++    DataChannelBridgeMap   dataChannels;
++  };
++  typedef std::map<std::string, PrimaryChannel>   PrimaryChannelMap;
++  typedef std::map<dcw::MacAddress, std::string>  StationFilterMap;
++
++  struct uci_context *_uciContext;
++  struct uci_package *_uciPackage;
++  const char *_uciConfig;
++
++  PrimaryChannelMap  _primaryChannels;
++  StationFilterMap   _stationFilters;
++  CFTFPList          _defaultFilters;
++
++public:
++  UciConfigurationProvider(const char * const uciConfig); // the "config" part of UCI commands
++  virtual ~UciConfigurationProvider();
++
++  virtual void InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const;
++  virtual void GetPrimarySsids(SsidSet& output) const;
++  virtual void GetDataSsids(SsidSet& output, const char * const primarySsid) const;
++  virtual const char *GetSsidIfname(const char * const ssid) const;
++  virtual void GetStationTrafficFilterProfiles(StationTFPMap& output) const;
++};
++
++}; //namespace dcwlinux {
++
++#endif //#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
+--- a/dev/null
++++ b/dcwlinux/uci_configuration_provider.cxx
+@@ -0,0 +1,365 @@
++
++#include <uci.h>
++#include <string.h>
++
++#include <stdlib.h>
++#include <stdexcept>
++#include <sys/stat.h>
++#include <cerrno>
++#include <iostream>
++#include <fstream>
++
++#include "./uci_configuration_provider.h"
++
++#include "dcwposix/filterdirscanner.h"
++#include "dcw/macaddress.h"
++#include "dcw/dcwlog.h"
++
++using namespace dcwlinux;
++
++  const char *UciConfigurationProvider::SECTION_TYPE_GENERAL = "general";
++  const char *UciConfigurationProvider::SECTION_TYPE_CHANNEL_SET = "channel-set";
++  const char *UciConfigurationProvider::SECTION_TYPE_DATA_CHANNEL = "datachannel";
++  const char *UciConfigurationProvider::SECTION_TYPE_FILTER_SET = "filter-set";
++  const char *UciConfigurationProvider::SECTION_TYPE_FILTER = "filter";
++  const char *UciConfigurationProvider::DEFAULT_FILTER_SET_NAME = "TFP_Default";
++
++  const char *UciConfigurationProvider::OPTION_TMPDIR = "tmpdir";
++  const char *UciConfigurationProvider::OPTION_ENABLED = "enabled";
++  const char *UciConfigurationProvider::OPTION_SSID = "ssid";
++  const char *UciConfigurationProvider::OPTION_BRIDGE = "bridge";
++  const char *UciConfigurationProvider::OPTION_DATA_CHANNELS = "data_channels";
++  const char *UciConfigurationProvider::OPTION_INTERFACES = "interfaces";
++  const char *UciConfigurationProvider::OPTION_MAC_ADDRESS = "mac";
++  const char *UciConfigurationProvider::OPTION_FILTERS = "filters";
++  const char *UciConfigurationProvider::OPTION_PACKET_SIZE = "packet_size";
++  const char *UciConfigurationProvider::OPTION_SOURCE_IP = "source_ip";
++  const char *UciConfigurationProvider::OPTION_SOURCE_PORT = "source_port";
++  const char *UciConfigurationProvider::OPTION_PROTOCOL = "protocol";
++  const char *UciConfigurationProvider::OPTION_DEST_PORT = "dest_port";
++
++  const char *UciConfigurationProvider::FILTER_FILE_EXTENSION = ".tfp";
++
++  UciConfigurationProvider::UciConfigurationProvider(const char * const uciConfig) : _uciConfig(uciConfig) {
++
++    //printf("*** Start UciConfigurationProvider(%s)\n", _uciConfig);
++    //printf("*** About to uci_alloc_context()\n");
++
++    _uciContext = uci_alloc_context();
++
++    //printf("*** uci_alloc_context() complete\n");
++    //printf("*** About to uci_load()\n");
++
++    if (_uciContext == NULL)
++    {
++      std::string err = "Error creating UCI context ";
++      throw std::runtime_error(err);
++    }
++
++    uci_load(_uciContext, _uciConfig, &_uciPackage);
++
++    //printf("*** uci_load complete()\n");
++
++    if (_uciPackage == NULL)
++    {
++      std::string err = "Error loading UCI package " + std::string(_uciConfig);
++      throw std::runtime_error(err);
++    }
++    
++    uci_section *generalSection = uci_lookup_section(_uciContext, _uciPackage, UciConfigurationProvider::SECTION_TYPE_GENERAL);
++    if (generalSection == NULL)
++    {
++      std::string err = "Error: A general section (" + std::string(UciConfigurationProvider::SECTION_TYPE_GENERAL) + ") must be specified!";
++      throw std::runtime_error(err);
++    }
++
++    uci_option *opt_tmpdir = uci_lookup_option(_uciContext, generalSection, UciConfigurationProvider::OPTION_TMPDIR);
++    if (opt_tmpdir == NULL)
++    {
++      std::string err = "Error: A temporary directory (" + std::string(UciConfigurationProvider::OPTION_TMPDIR) + ") must be specified!";
++      throw std::runtime_error(err);
++    }
++    char *tmpdir = opt_tmpdir->v.string;
++    //printf(" *** Set tmpdir: %s\n", tmpdir);
++
++    // make sure that tmpdir exists
++    int status = mkdir(tmpdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
++    if ((status != 0) && // failure
++      (errno != EEXIST)) // the failure was not that the directory already existed
++    {
++      std::string err = "Error: Unable to create the temporary directory (tmpdir), error # " + errno;
++      throw std::runtime_error(err);
++    }
++    _filterDirectory = std::string(tmpdir);
++    
++    if (uci_lookup_section(_uciContext, _uciPackage, UciConfigurationProvider::DEFAULT_FILTER_SET_NAME) == NULL)
++    {
++      std::string err = "Error: A default traffic filter profile named " + std::string(UciConfigurationProvider::DEFAULT_FILTER_SET_NAME) + " MUST exist!";
++      throw std::runtime_error(err);
++    }
++
++    // iterate over all of the sections in the package
++    uci_element *elem;
++    uci_foreach_element(&_uciPackage->sections, elem)
++    {
++      //printf("--==-- element.type: %d\n", elem->type);
++      //printf("--==-- element.name: %s\n", elem->name);
++
++      if (elem->type == UCI_TYPE_SECTION)
++      {
++      // look up the section and get it's type
++      
++      uci_section *section = NULL;
++        //printf("*** Looking up section: %s\n", elem->name);
++
++      section = uci_lookup_section(_uciContext, _uciPackage, elem->name);
++
++      if ((section != NULL) && (section->type != NULL))
++      {
++        //printf(" *** Section type: %s\n", section->type);
++        if (strcmp(elem->name, UciConfigurationProvider::SECTION_TYPE_GENERAL) == 0)
++        {
++          // we already processed the general section for the tmpdir
++        }
++        else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_CHANNEL_SET) == 0)
++        {
++          // the section is a channel set, populate it with the specified values
++          
++          uci_option *enabled = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_ENABLED);
++          if ((enabled == NULL) || (strcmp(enabled->v.string, "1") != 0))
++          {
++            // found a disabled channel set, ignore it
++            continue;
++          }
++
++          uci_option *ssid = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_SSID);
++          uci_option *bridge = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_BRIDGE);
++          uci_option *dataChannels = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_DATA_CHANNELS);
++          
++          if ((ssid != NULL) && (bridge != NULL) && (dataChannels != NULL))
++          {
++            PrimaryChannel &pc = _primaryChannels[ssid->v.string];
++            pc.bridgeName = bridge->v.string;
++            
++            char dataChannels_list[255];
++            // The dataChannels option is not a list
++            //if (dataChannels->type == UCI_TYPE_LIST)
++            if (dataChannels->v.string != NULL)
++            {
++              strcpy(dataChannels_list, dataChannels->v.string);
++              std::string str_dataChannels = dataChannels->v.string;
++              size_t start_pos = 0;
++              size_t pos = 0;
++              while(start_pos != std::string::npos)
++              {
++                pos = str_dataChannels.find(" ", start_pos);
++                //printf("****** start_pos: %u, pos: %u\n", start_pos, pos);
++                std::string str_dataChannel = str_dataChannels.substr(start_pos,
++                                                                      pos == std::string::npos ? pos : pos-start_pos);
++                //printf("*** dataChannel: %s\n", str_dataChannel.c_str());
++                
++                // update the start position for next loop
++                start_pos = (pos == std::string::npos ? pos : pos+1);
++
++                uci_section *dcSection = uci_lookup_section(_uciContext, _uciPackage, str_dataChannel.c_str());
++                if (dcSection != NULL)
++                {
++                  uci_option *dcSsid = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_SSID);
++                  uci_option *dcBridge = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_BRIDGE);
++                  
++                  // TODO: configure dcBridge and dcInterfaces
++                  //uci_option *dcInterfaces = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_INTERFACES);
++                  
++                  if ((dcSsid != NULL) && (dcBridge != NULL))
++                  {
++                    pc.dataChannels[dcSsid->v.string];
++                    pc.dataChannels[dcSsid->v.string] = dcBridge->v.string;
++                  }
++                }
++              }
++            }
++            
++            //printf("Section: %s, SSID: %s, Bridge: %s, Data Channels: %s\n", section->e.name, ssid->v.string, bridge->v.string, dataChannels_list);
++          }
++        }
++        else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_DATA_CHANNEL) == 0)
++        {
++          // data channels are processed by the channel set
++        }
++        else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_FILTER_SET) == 0)
++        {
++          // the section is a filter set, populate it with the specified values
++          //printf("*** filter set: %s\n", elem->name);
++          
++          // create a tfp file for the sectionName
++          std::ofstream tfpFile;
++          std::string tfpFilePath =
++            tmpdir + std::string("/") +
++            std::string(elem->name) +
++            std::string(UciConfigurationProvider::FILTER_FILE_EXTENSION);
++          tfpFile.open(tfpFilePath.c_str(), std::ios::out | std::ios::trunc);
++          if (!tfpFile.is_open())
++          {
++            std::string err = "Error: Unable to open the filter file: " + tfpFilePath;
++            throw std::runtime_error(err);
++          }
++          
++          const char *filterDelimiter = "\n";
++          char sFilterContents[2048];
++          sFilterContents[0] = '\0';
++          
++          uci_option *filters = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_FILTERS);
++          // The filters option is not a list
++          //if ((filters != NULL) && (filters->type == UCI_TYPE_LIST))
++          if (filters != NULL)
++          {
++            //printf("*** %s.filters is a list.\n", elem->name);
++            //struct uci_element *e;
++            //uci_foreach_element(&filters->v.list, e)
++ 
++            std::string str_filters = filters->v.string;
++            //printf("*** STR_FILTERS: %s\n", str_filters.c_str());
++            size_t start_pos = 0;
++            size_t pos = 0;
++            while(start_pos != std::string::npos)
++            {
++              pos = str_filters.find(" ", start_pos);
++              //printf("****** start_pos: %u, pos: %u\n", start_pos, pos);
++              std::string str_filter = str_filters.substr(start_pos,
++                                                          pos == std::string::npos ? pos : pos-start_pos);
++              //printf("*** Looking for filter section named: %s ...\n", str_filter.c_str());
++
++              // update the start position for next loop
++              start_pos = (pos == std::string::npos ? pos : pos+1);
++              
++              uci_section *fSection = uci_lookup_section(_uciContext, _uciPackage, str_filter.c_str());
++              if (fSection != NULL)
++              {
++                uci_option *fPacketSize = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_PACKET_SIZE);
++                uci_option *fSourceIp = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_SOURCE_IP);
++                uci_option *fSourcePort = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_SOURCE_PORT);
++                uci_option *fProtocol = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_PROTOCOL);
++                uci_option *fDestPort = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_DEST_PORT);
++
++                if ((fPacketSize != NULL) &&
++                    (fSourceIp != NULL) &&
++                    (fSourcePort != NULL) &&
++                    (fProtocol != NULL) &&
++                    (fDestPort != NULL))
++                {
++                  //printf("*** filter: %s  %s:%s:%s:%s:%s\n", e->name,
++                  //      fPacketSize->v.string, fSourceIp->v.string, fSourcePort->v.string,
++                  //      fProtocol->v.string, fDestPort->v.string);
++                  
++                  strcpy(sFilterContents, fPacketSize->v.string);
++                  strcat(sFilterContents, ":");
++                  strcat(sFilterContents, fSourceIp->v.string);
++                  strcat(sFilterContents, ":");
++                  strcat(sFilterContents, fSourcePort->v.string);
++                  strcat(sFilterContents, ":");
++                  strcat(sFilterContents, fProtocol->v.string);
++                  strcat(sFilterContents, ":");
++                  strcat(sFilterContents, fDestPort->v.string);
++                  strcat(sFilterContents, filterDelimiter);
++                  
++                  //printf("*** Writing filter contents to file: %s\n", sFilterContents);
++                  tfpFile << sFilterContents;
++                }
++                else
++                {
++                  std::string err = "Error parsing filter: " + str_filter;
++                  throw std::runtime_error(err);
++                }
++              }
++            }
++          }
++          tfpFile.close();
++          
++          // if there is a MAC address for the filter set, we need to add it to the station filters list
++          uci_option *mac = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_MAC_ADDRESS);
++          if (mac != NULL)
++          {
++            // ignore wildcard MAC address
++            if (strcmp(mac->v.string,"*") != 0)
++            {
++              //printf(" *** MAC Address: %s\n", mac->v.string);
++              _stationFilters[::dcw::MacAddress(mac->v.string)] = elem->name;
++            }
++          }
++        }
++        else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_FILTER) == 0)
++        {
++          // filters are processed by the filter set
++        }
++        else
++        {
++          //std::string err = "Error: Unknown UCI section type: " + std::string(section->type);
++          //throw std::runtime_error(err);
++          
++          // Don't throw an exception. It is fine for UCI to contain things that we do not know about
++          //  that it may use for other purposes, like UI or internal state
++          dcwlogdbgf("Ignoring UCI section type: %s\n", section->type);
++        }
++      }
++      }
++    }
++  }
++
++  UciConfigurationProvider::~UciConfigurationProvider() {
++    uci_free_context(_uciContext);
++  }
++
++  void UciConfigurationProvider::InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const {
++    ::dcwposix::FilterdirScanner::FileFilterProfileList ffpl;
++    ::dcwposix::FilterdirScanner dirScanner(_filterDirectory.c_str());
++    dirScanner.Scan(ffpl);
++
++    for (::dcwposix::FilterdirScanner::FileFilterProfileList::const_iterator i = ffpl.begin(); i != ffpl.end(); i++) {
++      output.push_back(new ::dcw::FileTrafficFilterProfile(*i));
++    }
++  }
++
++
++  void UciConfigurationProvider::GetPrimarySsids(SsidSet& output) const {
++    for (PrimaryChannelMap::const_iterator i = _primaryChannels.begin(); i != _primaryChannels.end(); i++) {
++      output.insert(i->first);
++    }
++  }
++
++  void UciConfigurationProvider::GetDataSsids(SsidSet& output, const char * const primarySsid) const {
++    const PrimaryChannelMap::const_iterator pssid = _primaryChannels.find(primarySsid);
++    if (pssid == _primaryChannels.end()) return;
++
++    for (DataChannelBridgeMap::const_iterator i = pssid->second.dataChannels.begin(); i != pssid->second.dataChannels.end(); i++) {
++      output.insert(i->first);
++    }
++  }
++
++  const char *UciConfigurationProvider::GetSsidIfname(const char * const ssid) const {
++    PrimaryChannelMap::const_iterator pssid = _primaryChannels.find(ssid);
++    if (pssid != _primaryChannels.end()) {
++      if (pssid->second.bridgeName.empty()) {
++        return NULL;
++      }
++      return pssid->second.bridgeName.c_str();
++    }
++
++    for (pssid = _primaryChannels.begin(); pssid != _primaryChannels.end(); pssid++) {
++      const DataChannelBridgeMap& dataChannels = pssid->second.dataChannels;
++      const DataChannelBridgeMap::const_iterator dc = dataChannels.find(ssid);
++      if (dc == dataChannels.end()) continue;
++      if (dc->second.empty()) {
++        return NULL;
++      }
++      return dc->second.c_str();
++    }
++
++    return NULL;
++  }
++
++  void UciConfigurationProvider::GetStationTrafficFilterProfiles(StationTFPMap& output) const {
++    for (StationFilterMap::const_iterator i = _stationFilters.begin(); i != _stationFilters.end(); i++) {
++      output[i->first] = i->second;
++    }
++
++  }
diff --git a/net/dcwapd/patches/02_use_uci_config_provider.patch b/net/dcwapd/patches/02_use_uci_config_provider.patch
new file mode 100644 (file)
index 0000000..db1037d
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/dcwapd.linuxjsonstatic/main.cxx
++++ b/dcwapd.linuxjsonstatic/main.cxx
+@@ -10,6 +10,7 @@
+ #include "dcwlinux/ap_configuration.h"
+ #include "dcwlinux/vap_manager.h"
+ #include "dcwlinux/json_configuration_provider.h"
++#include "dcwlinux/uci_configuration_provider.h"
+ #include "dcw/dcwlog.h"
+@@ -19,7 +20,8 @@ int
+ main( void ) {
+   try {
+-    dcwlinux::JsonConfigurationProvider      configProvider("./dcwapdconf.json");
++    //dcwlinux::JsonConfigurationProvider      configProvider("./dcwapdconf.json");
++    dcwlinux::UciConfigurationProvider      configProvider("dcwapd");
+     dcwposix::ProcessSignalManager           sigman;
+     dcwposix::SelectEventReactor             eventReactor;
diff --git a/net/dcwapd/patches/03_add_uci_config_provider_to_Makefile.patch b/net/dcwapd/patches/03_add_uci_config_provider_to_Makefile.patch
new file mode 100644 (file)
index 0000000..2980c85
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/dcwlinux/Makefile.am
++++ b/dcwlinux/Makefile.am
+@@ -6,6 +6,7 @@ libdcwlinux_la_SOURCES =
+   ap_configuration.cxx                  \
+   brctlnetwork.cxx                      \
+   json_configuration_provider.cxx       \
++  uci_configuration_provider.cxx        \
+   macremapper_driver.cxx                \
+   vap_manager.cxx                       \
+   virtual_ap.cxx
diff --git a/net/dcwifi/README.md b/net/dcwifi/README.md
deleted file mode 100644 (file)
index 6513933..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# Description
-
-This directory contains package files for including Dual Channel Wi-Fi (dcwifi) components in an OpenWrt build.
-
-# dcwifi Packages
-
-The dcwifi packages can be found in the menuconfig in the following locations:
-
-  * dcstad: `Network -> Routing and Redirection`
-  * dcwapd: `Network -> Routing and Redirection`
-  * libdcwproto: `Libraries -> Networking`
-  * libdcwsocket: `Libraries -> Networking`
-  * macremapper: `Kernel modules -> Network Support` (listed as `kmod-macremapper`)
-  * mrmctl: `Utilities`
diff --git a/net/dcwifi/dcstad/Makefile b/net/dcwifi/dcstad/Makefile
deleted file mode 100644 (file)
index 150eb62..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# Copyright (C) 2019 EWSI
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=dcstad
-PKG_VERSION:=1.0.0
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=3b146ea22bc5480d8264c5ea269831d25993673aa90a9e82dc2dc601a111da55
-
-PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
-PKG_LICENSE:=Apache-2.0
-PKG_LICENSE_FILES:=COPYING
-
-PKG_FIXUP:=autoreconf
-PKG_INSTALL:=1
-PKG_BUILD_PARALLEL:=1
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/dcstad
-  SECTION:=net
-  CATEGORY:=Network
-  SUBMENU:=Routing and Redirection
-  TITLE:=Dual-Channel WiFi client daemon
-  URL:=https://www.edgewaterwireless.com
-  DEPENDS:=+libdcwsocket +libdcwproto
-endef
-
-define Package/dcstad/description
-Implementation of the Dual-Channel WiFi client daemon
-endef
-
-TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
-TARGET_LDFLAGS += -Wl,--gc-sections
-
-define Package/dcstad/install
-       $(INSTALL_DIR) $(1)/bin
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/dcstad $(1)/bin/
-endef
-
-$(eval $(call BuildPackage,dcstad))
diff --git a/net/dcwifi/dcstad/patches/01_replace_bzero.patch b/net/dcwifi/dcstad/patches/01_replace_bzero.patch
deleted file mode 100644 (file)
index db924f7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/src/main.c
-+++ b/src/main.c
-@@ -190,7 +190,7 @@ main( int argc, char *argv[] ) {
-   rv = 1; /* failure unless proven otherwise */
-   /* first initialize and parse the command line */
--  bzero(&cfg, sizeof(cfg));
-+  memset(&cfg, 0, sizeof(cfg));
-   parse_cmdline(&cfg, argc, argv);
-   dcwloginfof("%s\n", "DCW Station Daemon Starting Up...");
diff --git a/net/dcwifi/dcwapd/Makefile b/net/dcwifi/dcwapd/Makefile
deleted file mode 100644 (file)
index 9e35d31..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# Copyright (C) 2019 EWSI
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=dcwapd
-PKG_VERSION:=1.0.0
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=750a08abccd88d9aeda942307f76ce5711181c06f9f3e8fded5cb5ce42bac323
-
-PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
-PKG_LICENSE:=Apache-2.0
-PKG_LICENSE_FILES:=COPYING
-
-PKG_FIXUP:=autoreconf
-PKG_INSTALL:=1
-PKG_BUILD_PARALLEL:=1
-
-include $(INCLUDE_DIR)/uclibc++.mk
-include $(INCLUDE_DIR)/package.mk
-
-define Package/dcwapd
-  SECTION:=net
-  CATEGORY:=Network
-  SUBMENU:=Routing and Redirection
-  TITLE:=Dual-Channel WiFi AP daemon
-  URL:=https://www.edgewaterwireless.com
-  DEPENDS:=$(CXX_DEPENDS) +kmod-macremapper +libdcwsocket +libdcwproto +mrmctl +libuci
-endef
-
-define Package/dcwapd/description
-Implementation of the Dual-Channel WiFi AP daemon
-endef
-
-CONFIGURE_ARGS += \
-       --enable-platform=linuxjsonstatic \
-       --enable-shared
-
-TARGET_CXXFLAGS += -std=c++11 -DRAPIDJSON_HAS_CXX11_RVALUE_REFS=0 -ffunction-sections -fdata-sections -flto
-TARGET_LDFLAGS += -ldcwproto -ldcwsocket -lmrmfilterparser -luci -Wl,--gc-sections,--as-needed
-
-define Build/InstallDev
-       $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
-endef
-
-define Package/dcwapd/install
-       $(INSTALL_DIR) $(1)/bin
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/bin/
-       $(INSTALL_DIR) $(1)/usr/lib
-       # Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
-
-#      Utility files
-       $(INSTALL_DIR) $(1)/etc/$(PKG_NAME)
-       $(INSTALL_DATA) ./files/*.inc $(1)/etc/$(PKG_NAME)/
-       $(INSTALL_BIN) ./files/*.sh $(1)/etc/$(PKG_NAME)/
-#      UCI config file copy - this is here for convenience and reference only
-       $(INSTALL_DATA) ./files/dcwapd.uci $(1)/etc/$(PKG_NAME)/
-
-#      UCI config file
-       $(INSTALL_DIR) $(1)/etc/config
-       $(INSTALL_DATA) ./files/dcwapd.uci $(1)/etc/config/dcwapd
-
-#      Init script
-       $(INSTALL_DIR) $(1)/etc/init.d
-       $(INSTALL_BIN) ./files/dcwapd.init.d $(1)/etc/init.d/dcwapd
-endef
-$(eval $(call BuildPackage,dcwapd))
diff --git a/net/dcwifi/dcwapd/files/dcwapd.inc b/net/dcwifi/dcwapd/files/dcwapd.inc
deleted file mode 100644 (file)
index c4b44f1..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-#!/bin/sh
-
-#
-# Dual Channel Wi-Fi Startup Script
-#
-# This script creates the proper network bridge configuration
-#  necessary for Dual Channel Wi-Fi, and starts the dcwapd daemon
-#
-
-verbose=1
-
-uciconfig=dcwapd
-
-result=
-
-# NOTE: all functions write the result to the $result variable
-
-get_channelsets()
-{
-       # default to empty
-       result=
-       channelsets=$(uci show $uciconfig | grep "=channel-set$")
-       for channelset in $channelsets; do
-               channelset=$(echo "$channelset" | sed -rn "s/$uciconfig\.(.*)=.*/\1/p")
-               result="$result $channelset"
-       done
-       if [ $verbose -eq 1 ]; then
-               echo "Channel Sets: $result" 2>&1 | logger
-       fi
-}
-
-# $1 : the channel set name
-get_channelset_enabled()
-{
-       # default to disabled
-       result=0
-       if [ -n "$1" ]; then
-               result=$(uci get $uciconfig."$1".enabled)
-       fi
-       if [ $verbose -eq 1 ]; then
-               echo "Channel Set \"$1\" Enabled: $result" 2>&1 | logger
-       fi
-}
-
-# $1 : the channel set name
-get_primary_bridge()
-{
-       result=
-       if [ -n "$1" ]; then
-               result=$(uci get $uciconfig."$1".bridge)
-       fi
-       if [ $verbose -eq 1 ]; then
-               echo "Channel Set \"$1\" Primary Bridge: $result" 2>&1 | logger
-       fi
-}
-
-# $1 : the channel set name
-get_datachannels()
-{
-       # default to empty
-       result=
-       if [ -n "$1" ]; then
-               result=$(uci get $uciconfig."$1".data_channels)
-       fi
-       if [ $verbose -eq 1 ]; then
-               echo "Channel Set \"$1\" Data Channels: $result" 2>&1 | logger
-       fi
-}
-
-# $1 : the wlan interface name
-get_wifi_iface_num()
-{
-       result=
-       if [ -n "$1" ];then
-               #result=$(echo "$1" | sed -n "s/wlan//p")
-               result=$(echo "$1" | sed -rn "s/wlan([0-9]*).*/\1/p")
-       fi
-}
-
-# $1 : the bridge name
-get_bridge_network_name()
-{
-       result=
-       if [ -n "$1" ];then
-               result=$(echo "$1" | sed -n "s/br-//p")
-       fi
-}
-
-# $1 : the wlan interface name
-set_iface_init_state()
-{
-       result=
-       if [ -n "$1" ]; then
-               iface=$1
-               # need to extract the "X" from wlanX
-               get_wifi_iface_num "$iface"
-               iface_num=$result
-               if [ -n "$iface_num" ]; then
-                       # get the iface network
-                       init_net=$(uci get wireless.@wifi-iface[$iface_num].network)
-                       if [ -n "$init_net" ]; then
-                               # if the iface network is a bridge, but doesn't start with "br-"
-                               #  I think we need to prepend it?
-                               net_type=$(uci get network."$init_net".type)
-                               if [ -n "$net_type" ] && [ "$net_type" = "bridge" ]; then
-                                       prefix_ok=$(echo "$init_net" | grep "^br-")
-                                       if [ -z "$prefix_ok" ]; then
-                                               init_net="br-$init_net"
-                                       fi
-                               fi
-                       fi
-
-                       # make sure that the init_net section exists
-                       init_net_section=$(uci get dcwapd.init_net)
-                       if [ "$init_net_section" != "init_net" ]; then
-                               # the section did not exist
-                               uci set dcwapd.init_net=init_net
-                       fi
-
-                       # save the initial network
-                       if [ $verbose -eq 1 ]; then
-                               echo "Saving '$iface' initial network '$init_net'" 2>&1 | logger
-                       fi
-                       uci set $uciconfig.init_net."$iface"="$init_net"
-                       uci commit
-
-                       # save the initial network in the result variable
-                       result=$init_net
-               fi
-       fi
-}
-
-# $1 : the wlan interface name
-get_iface_init_state()
-{
-       result=
-       if [ -n "$1" ];then
-               init_net=$(uci get $uciconfig.init_net."$iface")
-
-               # if the response starts with "uci: ", it was an error not the real result
-               err=$(echo "$init_net" | grep "^uci: ")
-               if [ -z "$err" ]; then
-                       # no error, set the result
-                       result=$init_net
-
-                       if [ $verbose -eq 1 ]; then
-                               echo "Got '$iface' initial network '$init_net'" 2>&1 | logger
-                       fi
-               fi
-       fi
-}
-
-# $1 : the name of the data channel name to bring up
-datachannel_up()
-{
-       if [ -n "$1" ]; then
-               bridge=$(uci get $uciconfig."$1".bridge)
-               interfaces=$(uci get $uciconfig."$1".interfaces)
-                if [ $verbose -eq 1 ]; then
-                       echo "Creating Data Channel Bridge: $bridge" 2>&1 | logger
-               fi
-
-               get_bridge_network_name "$bridge"
-               netname=$result
-               if [ -n "$netname" ]; then
-                   uci set network."$netname"=interface
-                   uci set network."$netname".type=bridge
-                   uci set network."$netname".proto=static
-                   uci set network."$netname".bridge_empty='1'
-               fi
-
-               # create the bridge
-               uci commit
-               /etc/init.d/network reload
-
-               for iface in $interfaces; do
-                       # if iface is in a bridge, the bridge name should be stored in result
-                       set_iface_init_state "$iface"
-                       init_bridge=$result
-
-                       # update uci with the new bridge info
-                       get_wifi_iface_num "$iface"
-                       iface_num=$result
-                       if [ -n "$iface_num" ]; then
-                           uci set wireless.@wifi-iface[$iface_num].network="$netname"
-                       fi
-
-                       # manually put the interface into the data bridge
-                       # if iface is in a bridge, remove it before adding it to the data bridge
-                       if [ -n "$init_bridge" ]; then
-                               brctl delif "$init_bridge" "$iface" 2>&1 | logger
-                       fi
-                       brctl addif "$bridge" "$iface" 2>&1 | logger
-               done
-
-               # commit uci changes and reload the network
-               uci commit
-               /etc/init.d/network reload
-               #/etc/init.d/network restart
-               # while [ 1 ]; do
-               #       ifconfig "$bridge" > /dev/null 2>&1
-               #       if [ $? == 0 ]; then
-               #               break;
-               #       fi
-               #       sleep 1
-               # done
-       fi
-}
-
-# $1 : the name of the data channel to bring down
-datachannel_down()
-{
-       if [ -n "$1" ]; then
-               bridge=$(uci get $uciconfig."$1".bridge)
-               interfaces=$(uci get $uciconfig."$1".interfaces)
-               for iface in $interfaces; do
-                       if [ $verbose -eq 1 ]; then
-                               echo "Deconfiguring Data Channel Interface: $iface" 2>&1 | logger
-                       fi
-
-                       # manually remove the interface from the data bridge
-                       brctl delif "$bridge" "$iface" 2>&1 | logger
-
-                       get_iface_init_state "$iface"
-                       init_bridge=$result
-                       if [ -n "$init_bridge" ]; then
-                               # manually move the interface back to the original bridge
-                               brctl addif "$init_bridge" "$iface" 2>&1 | logger
-
-                               # update uci with the new bridge and interface configuration
-                               get_wifi_iface_num "$iface"
-                               iface_num=$result
-                               get_bridge_network_name "$init_bridge"
-                               netname=$result
-                               if [ -n "$iface_num" ] && [ -n "$netname" ]; then
-                                   uci set wireless.@wifi-iface[$iface_num].network="$netname"
-                               fi
-                       fi
-               done
-               if [ $verbose -eq 1 ]; then
-                       echo "Deconfiguring Data Channel Bridge: $bridge" 2>&1 | logger
-               fi
-
-               # delete the bridge from uci
-               get_bridge_network_name "$bridge"
-               netname=$result
-               if [ -n "$netname" ]; then
-                   uci delete network."$netname"
-               fi
-
-               # commit uci changes and reload the network
-               uci commit
-               /etc/init.d/network reload
-               #`/etc/init.d/network restart`
-       fi
-}
diff --git a/net/dcwifi/dcwapd/files/dcwapd.init.d b/net/dcwifi/dcwapd/files/dcwapd.init.d
deleted file mode 100755 (executable)
index 6f6a48f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh /etc/rc.common
-
-START=99
-# Setting the stop value makes the restart script unreliable when invoked by LuCI
-#STOP=0
-
-scriptdir=/etc/dcwapd
-
-#validate_section_dcwapd() {
-#      uci_validate_section dcwapd general "${1}" \
-#              'enabled:bool:1'
-#}
-
-start() {
-#      validate_section_dcwapd dcwapd
-
-       # only run the start script if the enabled uci option is set properly
-       enabled=$(uci get dcwapd.general.enabled)
-       if [ "${enabled}" = "1" ]; then
-               ${scriptdir}/start_dcwapd.sh
-       else
-               echo "dcwapd is disabled in UCI"
-               return 1
-       fi
-}
-
-stop() {
-        ${scriptdir}/stop_dcwapd.sh
-       # Add a sleep after stopping because an immediate restat will fail otherwise
-       sleep 1
-}
diff --git a/net/dcwifi/dcwapd/files/dcwapd.uci b/net/dcwifi/dcwapd/files/dcwapd.uci
deleted file mode 100644 (file)
index b24ec6f..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-######################################################
-# Copyright 2018 EWSI
-#
-# Licensed to the public under the Apache License 2.0.
-######################################################
-# Dual Channel Wi-Fi AP Daemon configuration
-
-###################
-# General Options #
-###################
-# The "enabled" option controls the run state of the Dual Channel Wi-Fi AP Daemon
-#  0 - disabled, 1 - enabled
-# The "tmpdir" option MUST be specified
-#  option tmpdir '<path_of_temp_dir>'
-
-config general 'general'
-       option enabled 0
-       option tmpdir '/tmp/dcwapd'
-
-################
-# Channel Sets #
-################
-# Sections of type "channel-set" define a Dual Channel Wi-Fi primary channel,
-#  along with it's associated data channels
-#
-# The "data_channels" option is a space-delimited list of "datachannel"-typed instance names
-
-config channel-set 'channelset0'
-       option enabled 0
-#      option enabled 1
-       option ssid 'OpenWrt'
-       option bridge 'br-lan'
-       option data_channels 'datachannel0'
-
-#config channel-set 'channelset1'
-#      option enabled 0
-#      option ssid 'OpenWrt2'
-#      option bridge 'br-lan'
-#      option data_channels 'datachannel1'
-
-#################
-# Data Channels #
-#################
-# Sections of type "datachannel" define a Dual Channel Wi-Fi data channel,
-#  along with it's associated bridge and wireless interfaces
-#
-# The "interfaces" option is a space-delimited list of wireless interface names 
-
-config datachannel 'datachannel0'
-       option ssid 'DCW0'
-       option bridge 'br-dc0'
-       option interfaces 'wlan2 wlan5'
-
-#config datachannel 'datachannel1'
-#      option ssid 'DCW1'
-#      option bridge 'br-dc1'
-#      option interfaces 'wlan4'
-
-####################
-# Init Net Options #
-####################
-# The "init_net" section MUST be specified
-#  This section will be used to save and restore the state of the data interfaces
-config init_net 'init_net'
-
-###############
-# Filter Sets #
-###############
-# Sections of type "filter-set" define a Dual Channel Wi-Fi group of filters,
-#  along with it's associated MAC address and filter rules
-# 
-# The "TFP_Default" filter set MUST be defined, although it is not required
-#  to have any associated filter rules
-# The "TFP_Default" filter mac option can have the value of '*', meaning match
-#  all MAC addresses
-#
-# The "filters" option is a space-delimited list of "filter"-typed instance names
-
-config filter-set 'TFP_Default'
-       option mac '*'
-       option filters 'filter0 filter1'
-
-#config filter-set 'filterset0'
-#      option mac '00:00:BE:EF:F0:0D'
-#      option filters 'filter2'
-
-
-################
-# Filter Rules #
-################
-# Sections of type "filter" define a Dual Channel Wi-Fi filter,
-#  along with it's associated filter parameters
-# 
-# Any or all of the filter options may be set to '*' to match
-#  all values
-
-config filter 'filter0'
-       option packet_size '*'
-       option source_ip '*'
-       option source_port '80'
-       option protocol 'tcp'
-       option dest_port '*'
-
-config filter 'filter1'
-       option packet_size '*'
-       option source_ip '*'
-       option source_port '443'
-       option protocol 'tcp'
-       option dest_port '*'
-
-#config filter 'filter2'
-#      option packet_size '*'
-#      option source_ip '*'
-#      option source_port '22'
-#      option protocol 'tcp'
-#      option dest_port '*'
diff --git a/net/dcwifi/dcwapd/files/start_dcwapd.sh b/net/dcwifi/dcwapd/files/start_dcwapd.sh
deleted file mode 100755 (executable)
index 8a8c11b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-
-#
-# Dual Channel Wi-Fi Startup Script
-#
-# This script creates the proper network bridge configuration
-#  necessary for Dual Channel Wi-Fi, and starts the dcwapd daemon
-#
-
-# Note - shellcheck cannot deal with the dynamic sourcing
-# shellcheck disable=SC1090
-# which also messes with variables defined in the sourced file
-# shellcheck disable=SC2154
-scriptdir=$(dirname -- "$(readlink -f -- "$0")")
-. "$scriptdir"/dcwapd.inc
-
-get_channelsets
-# get the list of channel sets
-channelsets=$result
-
-for channelset in $channelsets; do
-       if [ -n "$channelset" ]; then
-               get_channelset_enabled "$channelset"
-               enabled=$result
-               if [ "$enabled" = "1" ]; then
-                       # the channel set is enabled
-
-                       # get the list of data channels used by the channel set
-                       get_datachannels "$channelset"
-                       datachannels=$result
-                       for datachannel in $datachannels; do
-                               datachannel_up "$datachannel"
-                       done
-               fi
-       fi
-done
-
-# start dcwapd, sending stdout and stderr to the system log
-dcwapd 2>&1 | logger &
diff --git a/net/dcwifi/dcwapd/files/stop_dcwapd.sh b/net/dcwifi/dcwapd/files/stop_dcwapd.sh
deleted file mode 100755 (executable)
index a360a82..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-
-#
-# Dual Channel Wi-Fi Startup Script
-#
-# This script creates the proper network bridge configuration
-#  necessary for Dual Channel Wi-Fi, and starts the dcwapd daemon
-#
-
-# Note - shellcheck cannot deal with the dynamic sourcing
-# shellcheck disable=SC1090
-# which also messes with variables defined in the sourced file
-# shellcheck disable=SC2154
-scriptdir=$(dirname -- "$(readlink -f -- "$0")")
-. "$scriptdir"/dcwapd.inc
-
-pid=$(pidof dcwapd)
-if [ -n "$pid" ]; then
-       if [ "$verbose" -eq "1" ]; then
-               echo "Stopping dcwapd..." 2>&1 | logger
-       fi
-       kill "$pid"
-fi
-
-get_channelsets
-# get the list of channel sets
-channelsets=$result
-
-for channelset in $channelsets; do
-       if [ -n "$channelset" ]; then
-# we don't care if it is enabled, tear it down
-#              get_channelset_enabled $channelset
-#              enabled=$result
-#              if [ $enabled = "1" ]; then
-#                      # the channel set is enabled
-
-                       # get the list of data channels used by the channel set
-                       get_datachannels "$channelset"
-                       datachannels=$result
-                       for datachannel in $datachannels; do
-                               datachannel_down "$datachannel"
-                       done
-#              fi
-       fi
-done
diff --git a/net/dcwifi/dcwapd/patches/01_add_uci_config_provider.patch b/net/dcwifi/dcwapd/patches/01_add_uci_config_provider.patch
deleted file mode 100644 (file)
index afb034b..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
---- a/dev/null
-+++ b/dcwlinux/uci_configuration_provider.h
-@@ -0,0 +1,104 @@
-+#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
-+#define UCI_CONFIGURATION_PROVIDER_H_INCLUDED
-+
-+#include "./ap_configuration.h"
-+
-+namespace dcwlinux {
-+
-+class UciConfigurationProvider : public APConfigurationProvider {
-+
-+  static const char *SECTION_TYPE_GENERAL;
-+  static const char *SECTION_TYPE_CHANNEL_SET;
-+  static const char *SECTION_TYPE_DATA_CHANNEL;
-+  static const char *SECTION_TYPE_FILTER_SET;
-+  static const char *SECTION_TYPE_FILTER;
-+  static const char *DEFAULT_FILTER_SET_NAME;
-+
-+  static const char *OPTION_TMPDIR;
-+  static const char *OPTION_ENABLED;
-+  static const char *OPTION_SSID;
-+  static const char *OPTION_BRIDGE;
-+  static const char *OPTION_DATA_CHANNELS;
-+  static const char *OPTION_INTERFACES;
-+  static const char *OPTION_MAC_ADDRESS;
-+  static const char *OPTION_FILTERS;
-+  static const char *OPTION_PACKET_SIZE;
-+  static const char *OPTION_SOURCE_IP;
-+  static const char *OPTION_SOURCE_PORT;
-+  static const char *OPTION_PROTOCOL;
-+  static const char *OPTION_DEST_PORT;
-+
-+  static const char *FILTER_FILE_EXTENSION;
-+
-+  UciConfigurationProvider(const UciConfigurationProvider&); //no copy
-+
-+  typedef std::map<std::string, std::string>  DataChannelBridgeMap;
-+  struct PrimaryChannel {
-+    std::string            bridgeName;
-+    DataChannelBridgeMap   dataChannels;
-+  };
-+  typedef std::map<std::string, PrimaryChannel>   PrimaryChannelMap;
-+  typedef std::map<dcw::MacAddress, std::string>  StationFilterMap;
-+
-+  struct uci_context *_uciContext;
-+  struct uci_package *_uciPackage;
-+  const char *_uciConfig;
-+
-+  std::string        _filterDirectory;
-+  PrimaryChannelMap  _primaryChannels;
-+  StationFilterMap   _stationFilters;
-+
-+public:
-+  UciConfigurationProvider(const char * const uciConfig); // the "config" part of UCI commands
-+  virtual ~UciConfigurationProvider();
-+
-+  virtual void InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const;
-+  virtual void GetPrimarySsids(SsidSet& output) const;
-+  virtual void GetDataSsids(SsidSet& output, const char * const primarySsid) const;
-+  virtual const char *GetSsidIfname(const char * const ssid) const;
-+  virtual void GetStationTrafficFilterProfiles(StationTFPMap& output) const;
-+};
-+
-+}; //namespace dcwlinux {
-+
-+#endif //#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
-+#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
-+#define UCI_CONFIGURATION_PROVIDER_H_INCLUDED
-+
-+#include "./ap_configuration.h"
-+
-+namespace dcwlinux {
-+
-+class UciConfigurationProvider : public APConfigurationProvider {
-+  UciConfigurationProvider(const UciConfigurationProvider&); //no copy
-+
-+  typedef std::map<std::string, std::string>  DataChannelBridgeMap;
-+  struct PrimaryChannel {
-+    std::string            bridgeName;
-+    DataChannelBridgeMap   dataChannels;
-+  };
-+  typedef std::map<std::string, PrimaryChannel>   PrimaryChannelMap;
-+  typedef std::map<dcw::MacAddress, std::string>  StationFilterMap;
-+
-+  struct uci_context *_uciContext;
-+  struct uci_package *_uciPackage;
-+  const char *_uciConfig;
-+
-+  PrimaryChannelMap  _primaryChannels;
-+  StationFilterMap   _stationFilters;
-+  CFTFPList          _defaultFilters;
-+
-+public:
-+  UciConfigurationProvider(const char * const uciConfig); // the "config" part of UCI commands
-+  virtual ~UciConfigurationProvider();
-+
-+  virtual void InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const;
-+  virtual void GetPrimarySsids(SsidSet& output) const;
-+  virtual void GetDataSsids(SsidSet& output, const char * const primarySsid) const;
-+  virtual const char *GetSsidIfname(const char * const ssid) const;
-+  virtual void GetStationTrafficFilterProfiles(StationTFPMap& output) const;
-+};
-+
-+}; //namespace dcwlinux {
-+
-+#endif //#ifndef UCI_CONFIGURATION_PROVIDER_H_INCLUDED
---- a/dev/null
-+++ b/dcwlinux/uci_configuration_provider.cxx
-@@ -0,0 +1,365 @@
-+
-+#include <uci.h>
-+#include <string.h>
-+
-+#include <stdlib.h>
-+#include <stdexcept>
-+#include <sys/stat.h>
-+#include <cerrno>
-+#include <iostream>
-+#include <fstream>
-+
-+#include "./uci_configuration_provider.h"
-+
-+#include "dcwposix/filterdirscanner.h"
-+#include "dcw/macaddress.h"
-+#include "dcw/dcwlog.h"
-+
-+using namespace dcwlinux;
-+
-+  const char *UciConfigurationProvider::SECTION_TYPE_GENERAL = "general";
-+  const char *UciConfigurationProvider::SECTION_TYPE_CHANNEL_SET = "channel-set";
-+  const char *UciConfigurationProvider::SECTION_TYPE_DATA_CHANNEL = "datachannel";
-+  const char *UciConfigurationProvider::SECTION_TYPE_FILTER_SET = "filter-set";
-+  const char *UciConfigurationProvider::SECTION_TYPE_FILTER = "filter";
-+  const char *UciConfigurationProvider::DEFAULT_FILTER_SET_NAME = "TFP_Default";
-+
-+  const char *UciConfigurationProvider::OPTION_TMPDIR = "tmpdir";
-+  const char *UciConfigurationProvider::OPTION_ENABLED = "enabled";
-+  const char *UciConfigurationProvider::OPTION_SSID = "ssid";
-+  const char *UciConfigurationProvider::OPTION_BRIDGE = "bridge";
-+  const char *UciConfigurationProvider::OPTION_DATA_CHANNELS = "data_channels";
-+  const char *UciConfigurationProvider::OPTION_INTERFACES = "interfaces";
-+  const char *UciConfigurationProvider::OPTION_MAC_ADDRESS = "mac";
-+  const char *UciConfigurationProvider::OPTION_FILTERS = "filters";
-+  const char *UciConfigurationProvider::OPTION_PACKET_SIZE = "packet_size";
-+  const char *UciConfigurationProvider::OPTION_SOURCE_IP = "source_ip";
-+  const char *UciConfigurationProvider::OPTION_SOURCE_PORT = "source_port";
-+  const char *UciConfigurationProvider::OPTION_PROTOCOL = "protocol";
-+  const char *UciConfigurationProvider::OPTION_DEST_PORT = "dest_port";
-+
-+  const char *UciConfigurationProvider::FILTER_FILE_EXTENSION = ".tfp";
-+
-+  UciConfigurationProvider::UciConfigurationProvider(const char * const uciConfig) : _uciConfig(uciConfig) {
-+
-+    //printf("*** Start UciConfigurationProvider(%s)\n", _uciConfig);
-+    //printf("*** About to uci_alloc_context()\n");
-+
-+    _uciContext = uci_alloc_context();
-+
-+    //printf("*** uci_alloc_context() complete\n");
-+    //printf("*** About to uci_load()\n");
-+
-+    if (_uciContext == NULL)
-+    {
-+      std::string err = "Error creating UCI context ";
-+      throw std::runtime_error(err);
-+    }
-+
-+    uci_load(_uciContext, _uciConfig, &_uciPackage);
-+
-+    //printf("*** uci_load complete()\n");
-+
-+    if (_uciPackage == NULL)
-+    {
-+      std::string err = "Error loading UCI package " + std::string(_uciConfig);
-+      throw std::runtime_error(err);
-+    }
-+    
-+    uci_section *generalSection = uci_lookup_section(_uciContext, _uciPackage, UciConfigurationProvider::SECTION_TYPE_GENERAL);
-+    if (generalSection == NULL)
-+    {
-+      std::string err = "Error: A general section (" + std::string(UciConfigurationProvider::SECTION_TYPE_GENERAL) + ") must be specified!";
-+      throw std::runtime_error(err);
-+    }
-+
-+    uci_option *opt_tmpdir = uci_lookup_option(_uciContext, generalSection, UciConfigurationProvider::OPTION_TMPDIR);
-+    if (opt_tmpdir == NULL)
-+    {
-+      std::string err = "Error: A temporary directory (" + std::string(UciConfigurationProvider::OPTION_TMPDIR) + ") must be specified!";
-+      throw std::runtime_error(err);
-+    }
-+    char *tmpdir = opt_tmpdir->v.string;
-+    //printf(" *** Set tmpdir: %s\n", tmpdir);
-+
-+    // make sure that tmpdir exists
-+    int status = mkdir(tmpdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
-+    if ((status != 0) && // failure
-+      (errno != EEXIST)) // the failure was not that the directory already existed
-+    {
-+      std::string err = "Error: Unable to create the temporary directory (tmpdir), error # " + errno;
-+      throw std::runtime_error(err);
-+    }
-+    _filterDirectory = std::string(tmpdir);
-+    
-+    if (uci_lookup_section(_uciContext, _uciPackage, UciConfigurationProvider::DEFAULT_FILTER_SET_NAME) == NULL)
-+    {
-+      std::string err = "Error: A default traffic filter profile named " + std::string(UciConfigurationProvider::DEFAULT_FILTER_SET_NAME) + " MUST exist!";
-+      throw std::runtime_error(err);
-+    }
-+
-+    // iterate over all of the sections in the package
-+    uci_element *elem;
-+    uci_foreach_element(&_uciPackage->sections, elem)
-+    {
-+      //printf("--==-- element.type: %d\n", elem->type);
-+      //printf("--==-- element.name: %s\n", elem->name);
-+
-+      if (elem->type == UCI_TYPE_SECTION)
-+      {
-+      // look up the section and get it's type
-+      
-+      uci_section *section = NULL;
-+        //printf("*** Looking up section: %s\n", elem->name);
-+
-+      section = uci_lookup_section(_uciContext, _uciPackage, elem->name);
-+
-+      if ((section != NULL) && (section->type != NULL))
-+      {
-+        //printf(" *** Section type: %s\n", section->type);
-+        if (strcmp(elem->name, UciConfigurationProvider::SECTION_TYPE_GENERAL) == 0)
-+        {
-+          // we already processed the general section for the tmpdir
-+        }
-+        else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_CHANNEL_SET) == 0)
-+        {
-+          // the section is a channel set, populate it with the specified values
-+          
-+          uci_option *enabled = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_ENABLED);
-+          if ((enabled == NULL) || (strcmp(enabled->v.string, "1") != 0))
-+          {
-+            // found a disabled channel set, ignore it
-+            continue;
-+          }
-+
-+          uci_option *ssid = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_SSID);
-+          uci_option *bridge = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_BRIDGE);
-+          uci_option *dataChannels = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_DATA_CHANNELS);
-+          
-+          if ((ssid != NULL) && (bridge != NULL) && (dataChannels != NULL))
-+          {
-+            PrimaryChannel &pc = _primaryChannels[ssid->v.string];
-+            pc.bridgeName = bridge->v.string;
-+            
-+            char dataChannels_list[255];
-+            // The dataChannels option is not a list
-+            //if (dataChannels->type == UCI_TYPE_LIST)
-+            if (dataChannels->v.string != NULL)
-+            {
-+              strcpy(dataChannels_list, dataChannels->v.string);
-+              std::string str_dataChannels = dataChannels->v.string;
-+              size_t start_pos = 0;
-+              size_t pos = 0;
-+              while(start_pos != std::string::npos)
-+              {
-+                pos = str_dataChannels.find(" ", start_pos);
-+                //printf("****** start_pos: %u, pos: %u\n", start_pos, pos);
-+                std::string str_dataChannel = str_dataChannels.substr(start_pos,
-+                                                                      pos == std::string::npos ? pos : pos-start_pos);
-+                //printf("*** dataChannel: %s\n", str_dataChannel.c_str());
-+                
-+                // update the start position for next loop
-+                start_pos = (pos == std::string::npos ? pos : pos+1);
-+
-+                uci_section *dcSection = uci_lookup_section(_uciContext, _uciPackage, str_dataChannel.c_str());
-+                if (dcSection != NULL)
-+                {
-+                  uci_option *dcSsid = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_SSID);
-+                  uci_option *dcBridge = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_BRIDGE);
-+                  
-+                  // TODO: configure dcBridge and dcInterfaces
-+                  //uci_option *dcInterfaces = uci_lookup_option(_uciContext, dcSection, UciConfigurationProvider::OPTION_INTERFACES);
-+                  
-+                  if ((dcSsid != NULL) && (dcBridge != NULL))
-+                  {
-+                    pc.dataChannels[dcSsid->v.string];
-+                    pc.dataChannels[dcSsid->v.string] = dcBridge->v.string;
-+                  }
-+                }
-+              }
-+            }
-+            
-+            //printf("Section: %s, SSID: %s, Bridge: %s, Data Channels: %s\n", section->e.name, ssid->v.string, bridge->v.string, dataChannels_list);
-+          }
-+        }
-+        else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_DATA_CHANNEL) == 0)
-+        {
-+          // data channels are processed by the channel set
-+        }
-+        else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_FILTER_SET) == 0)
-+        {
-+          // the section is a filter set, populate it with the specified values
-+          //printf("*** filter set: %s\n", elem->name);
-+          
-+          // create a tfp file for the sectionName
-+          std::ofstream tfpFile;
-+          std::string tfpFilePath =
-+            tmpdir + std::string("/") +
-+            std::string(elem->name) +
-+            std::string(UciConfigurationProvider::FILTER_FILE_EXTENSION);
-+          tfpFile.open(tfpFilePath.c_str(), std::ios::out | std::ios::trunc);
-+          if (!tfpFile.is_open())
-+          {
-+            std::string err = "Error: Unable to open the filter file: " + tfpFilePath;
-+            throw std::runtime_error(err);
-+          }
-+          
-+          const char *filterDelimiter = "\n";
-+          char sFilterContents[2048];
-+          sFilterContents[0] = '\0';
-+          
-+          uci_option *filters = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_FILTERS);
-+          // The filters option is not a list
-+          //if ((filters != NULL) && (filters->type == UCI_TYPE_LIST))
-+          if (filters != NULL)
-+          {
-+            //printf("*** %s.filters is a list.\n", elem->name);
-+            //struct uci_element *e;
-+            //uci_foreach_element(&filters->v.list, e)
-+ 
-+            std::string str_filters = filters->v.string;
-+            //printf("*** STR_FILTERS: %s\n", str_filters.c_str());
-+            size_t start_pos = 0;
-+            size_t pos = 0;
-+            while(start_pos != std::string::npos)
-+            {
-+              pos = str_filters.find(" ", start_pos);
-+              //printf("****** start_pos: %u, pos: %u\n", start_pos, pos);
-+              std::string str_filter = str_filters.substr(start_pos,
-+                                                          pos == std::string::npos ? pos : pos-start_pos);
-+              //printf("*** Looking for filter section named: %s ...\n", str_filter.c_str());
-+
-+              // update the start position for next loop
-+              start_pos = (pos == std::string::npos ? pos : pos+1);
-+              
-+              uci_section *fSection = uci_lookup_section(_uciContext, _uciPackage, str_filter.c_str());
-+              if (fSection != NULL)
-+              {
-+                uci_option *fPacketSize = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_PACKET_SIZE);
-+                uci_option *fSourceIp = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_SOURCE_IP);
-+                uci_option *fSourcePort = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_SOURCE_PORT);
-+                uci_option *fProtocol = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_PROTOCOL);
-+                uci_option *fDestPort = uci_lookup_option(_uciContext, fSection, UciConfigurationProvider::OPTION_DEST_PORT);
-+
-+                if ((fPacketSize != NULL) &&
-+                    (fSourceIp != NULL) &&
-+                    (fSourcePort != NULL) &&
-+                    (fProtocol != NULL) &&
-+                    (fDestPort != NULL))
-+                {
-+                  //printf("*** filter: %s  %s:%s:%s:%s:%s\n", e->name,
-+                  //      fPacketSize->v.string, fSourceIp->v.string, fSourcePort->v.string,
-+                  //      fProtocol->v.string, fDestPort->v.string);
-+                  
-+                  strcpy(sFilterContents, fPacketSize->v.string);
-+                  strcat(sFilterContents, ":");
-+                  strcat(sFilterContents, fSourceIp->v.string);
-+                  strcat(sFilterContents, ":");
-+                  strcat(sFilterContents, fSourcePort->v.string);
-+                  strcat(sFilterContents, ":");
-+                  strcat(sFilterContents, fProtocol->v.string);
-+                  strcat(sFilterContents, ":");
-+                  strcat(sFilterContents, fDestPort->v.string);
-+                  strcat(sFilterContents, filterDelimiter);
-+                  
-+                  //printf("*** Writing filter contents to file: %s\n", sFilterContents);
-+                  tfpFile << sFilterContents;
-+                }
-+                else
-+                {
-+                  std::string err = "Error parsing filter: " + str_filter;
-+                  throw std::runtime_error(err);
-+                }
-+              }
-+            }
-+          }
-+          tfpFile.close();
-+          
-+          // if there is a MAC address for the filter set, we need to add it to the station filters list
-+          uci_option *mac = uci_lookup_option(_uciContext, section, UciConfigurationProvider::OPTION_MAC_ADDRESS);
-+          if (mac != NULL)
-+          {
-+            // ignore wildcard MAC address
-+            if (strcmp(mac->v.string,"*") != 0)
-+            {
-+              //printf(" *** MAC Address: %s\n", mac->v.string);
-+              _stationFilters[::dcw::MacAddress(mac->v.string)] = elem->name;
-+            }
-+          }
-+        }
-+        else if (strcmp(section->type, UciConfigurationProvider::SECTION_TYPE_FILTER) == 0)
-+        {
-+          // filters are processed by the filter set
-+        }
-+        else
-+        {
-+          //std::string err = "Error: Unknown UCI section type: " + std::string(section->type);
-+          //throw std::runtime_error(err);
-+          
-+          // Don't throw an exception. It is fine for UCI to contain things that we do not know about
-+          //  that it may use for other purposes, like UI or internal state
-+          dcwlogdbgf("Ignoring UCI section type: %s\n", section->type);
-+        }
-+      }
-+      }
-+    }
-+  }
-+
-+  UciConfigurationProvider::~UciConfigurationProvider() {
-+    uci_free_context(_uciContext);
-+  }
-+
-+  void UciConfigurationProvider::InstanciateCFileTrafficFilterProfiles(CFTFPList& output) const {
-+    ::dcwposix::FilterdirScanner::FileFilterProfileList ffpl;
-+    ::dcwposix::FilterdirScanner dirScanner(_filterDirectory.c_str());
-+    dirScanner.Scan(ffpl);
-+
-+    for (::dcwposix::FilterdirScanner::FileFilterProfileList::const_iterator i = ffpl.begin(); i != ffpl.end(); i++) {
-+      output.push_back(new ::dcw::FileTrafficFilterProfile(*i));
-+    }
-+  }
-+
-+
-+  void UciConfigurationProvider::GetPrimarySsids(SsidSet& output) const {
-+    for (PrimaryChannelMap::const_iterator i = _primaryChannels.begin(); i != _primaryChannels.end(); i++) {
-+      output.insert(i->first);
-+    }
-+  }
-+
-+  void UciConfigurationProvider::GetDataSsids(SsidSet& output, const char * const primarySsid) const {
-+    const PrimaryChannelMap::const_iterator pssid = _primaryChannels.find(primarySsid);
-+    if (pssid == _primaryChannels.end()) return;
-+
-+    for (DataChannelBridgeMap::const_iterator i = pssid->second.dataChannels.begin(); i != pssid->second.dataChannels.end(); i++) {
-+      output.insert(i->first);
-+    }
-+  }
-+
-+  const char *UciConfigurationProvider::GetSsidIfname(const char * const ssid) const {
-+    PrimaryChannelMap::const_iterator pssid = _primaryChannels.find(ssid);
-+    if (pssid != _primaryChannels.end()) {
-+      if (pssid->second.bridgeName.empty()) {
-+        return NULL;
-+      }
-+      return pssid->second.bridgeName.c_str();
-+    }
-+
-+    for (pssid = _primaryChannels.begin(); pssid != _primaryChannels.end(); pssid++) {
-+      const DataChannelBridgeMap& dataChannels = pssid->second.dataChannels;
-+      const DataChannelBridgeMap::const_iterator dc = dataChannels.find(ssid);
-+      if (dc == dataChannels.end()) continue;
-+      if (dc->second.empty()) {
-+        return NULL;
-+      }
-+      return dc->second.c_str();
-+    }
-+
-+    return NULL;
-+  }
-+
-+  void UciConfigurationProvider::GetStationTrafficFilterProfiles(StationTFPMap& output) const {
-+    for (StationFilterMap::const_iterator i = _stationFilters.begin(); i != _stationFilters.end(); i++) {
-+      output[i->first] = i->second;
-+    }
-+
-+  }
diff --git a/net/dcwifi/dcwapd/patches/02_use_uci_config_provider.patch b/net/dcwifi/dcwapd/patches/02_use_uci_config_provider.patch
deleted file mode 100644 (file)
index db1037d..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/dcwapd.linuxjsonstatic/main.cxx
-+++ b/dcwapd.linuxjsonstatic/main.cxx
-@@ -10,6 +10,7 @@
- #include "dcwlinux/ap_configuration.h"
- #include "dcwlinux/vap_manager.h"
- #include "dcwlinux/json_configuration_provider.h"
-+#include "dcwlinux/uci_configuration_provider.h"
- #include "dcw/dcwlog.h"
-@@ -19,7 +20,8 @@ int
- main( void ) {
-   try {
--    dcwlinux::JsonConfigurationProvider      configProvider("./dcwapdconf.json");
-+    //dcwlinux::JsonConfigurationProvider      configProvider("./dcwapdconf.json");
-+    dcwlinux::UciConfigurationProvider      configProvider("dcwapd");
-     dcwposix::ProcessSignalManager           sigman;
-     dcwposix::SelectEventReactor             eventReactor;
diff --git a/net/dcwifi/dcwapd/patches/03_add_uci_config_provider_to_Makefile.patch b/net/dcwifi/dcwapd/patches/03_add_uci_config_provider_to_Makefile.patch
deleted file mode 100644 (file)
index 2980c85..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/dcwlinux/Makefile.am
-+++ b/dcwlinux/Makefile.am
-@@ -6,6 +6,7 @@ libdcwlinux_la_SOURCES =
-   ap_configuration.cxx                  \
-   brctlnetwork.cxx                      \
-   json_configuration_provider.cxx       \
-+  uci_configuration_provider.cxx        \
-   macremapper_driver.cxx                \
-   vap_manager.cxx                       \
-   virtual_ap.cxx
diff --git a/net/dcwifi/dcwapd/patches/04_uclibc++_fixes.patch b/net/dcwifi/dcwapd/patches/04_uclibc++_fixes.patch
deleted file mode 100644 (file)
index a8721c4..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
---- a/dcw/controller.cxx
-+++ b/dcw/controller.cxx
-@@ -195,7 +195,7 @@ void Controller::OnStationUnjoin(const MacAddress& primaryMacAddr, const Message
-   //remove any channel bondings matching the provided data channel mac addresses
-   for (unsigned i = 0; i < m.data_macaddr_count; i++) {
-     const ::dcw::MacAddress dcaddr(m.data_macaddrs[i]);
--    const ::dcw::TrafficPolicy::DataChannelMap::iterator dcmEntry = state.policy.dataChannels.find(dcaddr);
-+    ::dcw::TrafficPolicy::DataChannelMap::iterator dcmEntry = state.policy.dataChannels.find(dcaddr);
-     if (dcmEntry == state.policy.dataChannels.end()) continue;
-     if (dcmEntry->second == NULL) {
-       dcwlogwarnf("Data channel MAC address %s on client %s is not currently bonded\n", dcaddr.ToString().c_str(), primaryMacAddr.ToString().c_str());
-@@ -238,7 +238,7 @@ void Controller::OnStationAck(const MacAddress& primaryMacAddr, const Message& m
-   dcwlogdbgf("Got a station ACK from %s\n", primaryMacAddr.ToString().c_str());
-   // first make sure this client has actually sent a join first...
--  const ClientStateMap::iterator client = _clients.find(primaryMacAddr);
-+  ClientStateMap::iterator client = _clients.find(primaryMacAddr);
-   if (client == _clients.end()) {
-     dcwlogerrf("Got a client ACK without a station join from %s\n", primaryMacAddr.ToString().c_str());
-     Message reply(DCWMSG_AP_REJECT_STA);
---- a/dcwposix/processsignalmanager.cxx
-+++ b/dcwposix/processsignalmanager.cxx
-@@ -40,7 +40,7 @@ ProcessSignalManager::~ProcessSignalManager() {
- }
- void ProcessSignalManager::RegisterEventHandler(const int signum, ::dcwposix::ProcessSignalManager::EventHandler& eventHandler) {
--  const SignalMap::iterator i = _sigmap.find(signum);
-+  SignalMap::iterator i = _sigmap.find(signum);
-   if (i == _sigmap.end()) {
-     //be sure to preseve the old signal when inserting a new "unseen" signal
-     _sigmap[signum].insert(&eventHandler);
-@@ -53,7 +53,7 @@ void ProcessSignalManager::RegisterEventHandler(const int signum, ::dcwposix::Pr
- }
- void ProcessSignalManager::UnRegisterEventHandler(const int signum, ::dcwposix::ProcessSignalManager::EventHandler& eventHandler) {
--  const SignalMap::iterator i = _sigmap.find(signum);
-+  SignalMap::iterator i = _sigmap.find(signum);
-   if (i == _sigmap.end()) {
-     dcwlogwarnf("Attempting to unregister handler %p non-registered process signal #%d\n", &eventHandler, signum);
\ No newline at end of file
diff --git a/net/dcwifi/dcwapd/patches/05_replace_bzero.patch b/net/dcwifi/dcwapd/patches/05_replace_bzero.patch
deleted file mode 100644 (file)
index ffd9ee0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/dcwlinux/macremapper_driver.cxx
-+++ b/dcwlinux/macremapper_driver.cxx
-@@ -174,7 +174,7 @@ void MacRemapperDriver::ApplyClientTrafficPolicy(const dcw::MacAddress& primaryA
-   }
-   //populate our remap ioctl()
--  bzero(&re, sizeof(re));
-+  memset(&re, 0, sizeof(re));
-   strncpy(re.filter_name, policy.trafficFilterProfile->GetName(), sizeof(re.filter_name));
-   memcpy(re.match_macaddr, primaryAddr.Value, sizeof(re.match_macaddr));
diff --git a/net/dcwifi/libdcwproto/Makefile b/net/dcwifi/libdcwproto/Makefile
deleted file mode 100644 (file)
index 2216e1f..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# Copyright (C) 2019 EWSI
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=libdcwproto
-PKG_VERSION:=1.0.0
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=5bda395c648aa12eb90515c29024029738fde1a8f73a2cbc553be1c6962c2629
-
-PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
-PKG_LICENSE:=Apache-2.0
-PKG_LICENSE_FILES:=COPYING
-
-PKG_INSTALL:=1
-PKG_BUILD_PARALLEL:=1
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/libdcwproto
-  SECTION:=libs
-  CATEGORY:=Libraries
-  SUBMENU:=Networking
-  TITLE:=Dual-Channel WiFi messaging library
-  URL:=https://www.edgewaterwireless.com
-  DEPENDS:=+kmod-macremapper
-endef
-
-define Package/libdcwproto/description
-  Platform-independent C library for marshaling and serializing DCW messages
-endef
-
-TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
-TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
-
-define Build/InstallDev
-       $(INSTALL_DIR) $(1)/usr/include
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
-       $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
-endef
-
-define Package/libdcwproto/install
-       $(INSTALL_DIR) $(1)/usr/lib
-       # Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
-endef
-
-$(eval $(call BuildPackage,libdcwproto))
diff --git a/net/dcwifi/libdcwproto/patches/01_replace_bzero.patch b/net/dcwifi/libdcwproto/patches/01_replace_bzero.patch
deleted file mode 100644 (file)
index bfcbf75..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
---- a/src/dcwproto.c
-+++ b/src/dcwproto.c
-@@ -20,12 +20,8 @@
-
-
-
--#ifdef WIN32
--#define bzero(ptr, size) memset(ptr, 0, size)
--#else
- #include <config.h>
- #include <strings.h>
--#endif
- #include <dcwproto.h>
-
- #include <string.h>
-@@ -95,7 +91,7 @@ dcwmsg_marshal_sta_ack(struct dcwmsg_sta_ack * const output, const unsigned char
-
-     /* copy in the data ssid string bytes */
-     if (buf_len < copy_size) return 0;
--    bzero(output->bonded_data_channels[i].ssid, sizeof(output->bonded_data_channels[i].ssid));
-+    memset(output->bonded_data_channels[i].ssid, 0, sizeof(output->bonded_data_channels[i].ssid));
-     memcpy(output->bonded_data_channels[i].ssid, buf, copy_size);
-     buf_len -= copy_size;
-     buf += copy_size;
-@@ -134,7 +130,7 @@ dcwmsg_marshal_ap_accept_sta(struct dcwmsg_ap_accept_sta * const output, const u
-
-     /* copy in the data ssid string bytes */
-     if (buf_len < copy_size) return 0;
--    bzero(output->data_ssids[i], sizeof(output->data_ssids[i]));
-+    memset(output->data_ssids[i], 0, sizeof(output->data_ssids[i]));
-     memcpy(output->data_ssids[i], buf, copy_size);
-     buf_len -= copy_size;
-     buf += copy_size;
diff --git a/net/dcwifi/libdcwsocket/Makefile b/net/dcwifi/libdcwsocket/Makefile
deleted file mode 100644 (file)
index ff21bce..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# Copyright (C) 2019 EWSI
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=libdcwsocket
-PKG_VERSION:=1.0.0
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
-PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_HASH:=c7f6c69a5246fe1f184c21585f0805ceaca09c3c087ae439ded7ed4d25c7a3fa
-
-PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
-PKG_LICENSE:=Apache-2.0
-PKG_LICENSE_FILES:=COPYING
-
-PKG_INSTALL:=1
-PKG_BUILD_PARALLEL:=1
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/libdcwsocket
-  SECTION:=libs
-  CATEGORY:=Libraries
-  SUBMENU:=Networking
-  TITLE:=Dual-Channel socket library
-  URL:=https://www.edgewaterwireless.com
-endef
-
-define Package/libdcwsocket/description
-  User-land C library for sending and receiving DCW "EtherType"d messages
-endef
-
-TARGET_CFLAGS += -std=c89 -ffunction-sections -fdata-sections -flto
-TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
-
-define Build/InstallDev
-       $(INSTALL_DIR) $(1)/usr/include
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
-       $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
-endef
-
-define Package/libdcwsocket/install
-       $(INSTALL_DIR) $(1)/usr/lib
-       # Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
-endef
-
-$(eval $(call BuildPackage,libdcwsocket))
diff --git a/net/dcwifi/libdcwsocket/patches/01_replace_bzero.patch b/net/dcwifi/libdcwsocket/patches/01_replace_bzero.patch
deleted file mode 100644 (file)
index 9b799e1..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
---- a/src/dcwsocket.c.linux
-+++ b/src/dcwsocket.c.linux
-@@ -100,10 +100,10 @@ dcwsock_open(const char * const ifname) {
-   }
-   /* sanitize our data structs... defensive */
--  bzero(rv, sizeof(*rv));
--  bzero(&ifr, sizeof(ifr));
--  bzero(&sall, sizeof(sall));
--  bzero(&sfp, sizeof(sfp));
-+  memset(rv, 0, sizeof(*rv));
-+  memset(&ifr, 0, sizeof(ifr));
-+  memset(&sall, 0, sizeof(sall));
-+  memset(&sfp, 0, sizeof(sfp));
-   /* open a raw socket... "ETH_P_ALL" says take EVERYTHING 
-      (this means that it is IMPERATIVE to apply a filter)
-diff --git a/src/dcwsocket.c.osx b/src/dcwsocket.c.osx
-index abead10..75cda2f 100644
---- a/src/dcwsocket.c.osx
-+++ b/src/dcwsocket.c.osx
-@@ -90,10 +90,10 @@ dcwsock_open(const char * const ifname) {
-   }
-   /* sanitize our data structs... defensive */
--  bzero(rv, sizeof(*rv));
--  bzero(&dmx_desc, sizeof(dmx_desc));
--  bzero(&proto_desc, sizeof(proto_desc));
--  bzero(&snd, sizeof(snd));
-+  memset(rv, 0, sizeof(*rv));
-+  memset(&dmx_desc, 0, sizeof(dmx_desc));
-+  memset(&proto_desc, 0, sizeof(proto_desc));
-+  memset(&snd, 0, sizeof(snd));
-   /* open a "NDRV" socket... */
-   rv->fd = socket(PF_NDRV, SOCK_RAW, 0);
-@@ -201,7 +201,7 @@ dcwsock_send( dcw_socket_t s, const void * const buf, const unsigned buf_size, c
-      fill out a link-level sockaddr cause we can only 
-      use sendto() with PF_NDRV...
-   */
--  bzero(&sdl, sizeof(sdl));
-+  memset(&sdl, 0, sizeof(sdl));
-   sdl.sdl_len   = sizeof(sdl);
-   sdl.sdl_index = 0;
-   sdl.sdl_type  = IFT_ETHER;
diff --git a/net/dcwifi/libdcwsocket/patches/02_fix_storage_size_error.patch b/net/dcwifi/libdcwsocket/patches/02_fix_storage_size_error.patch
deleted file mode 100644 (file)
index 431b093..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/src/dcwsocket.c.linux
-+++ b/src/dcwsocket.c.linux
-@@ -31,6 +31,7 @@
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <net/if.h>
-+#include <linux/if.h>
- #include <linux/if_packet.h>
- #include <linux/if_ether.h>
- #include <linux/filter.h>
diff --git a/net/dcwifi/macremapper/Makefile b/net/dcwifi/macremapper/Makefile
deleted file mode 100644 (file)
index 85e39f3..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-# Copyright (C) 2019 EWSI
-#
-# 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:=macremapper
-PKG_VERSION:=1.0.0
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=f054201dd805ce005b89606a507b58a5717d383a4339c69dfdc02f0202935437
-
-PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
-PKG_LICENSE:=GPL-2.0-only
-PKG_LICENSE_FILES:=kernelmod/COPYING
-
-include $(INCLUDE_DIR)/package.mk
-
-define KernelPackage/macremapper
-  SUBMENU:=Network Support
-  URL:=https://www.edgewaterwireless.com
-  VERSION:=$(LINUX_VERSION)-$(BOARD)-$(PKG_RELEASE)
-  TITLE:=Dual Channel Wi-Fi macremapper Module
-  DEPENDS:= +kmod-cfg80211 +kmod-br-netfilter
-  FILES:=$(PKG_BUILD_DIR)/kernelmod/$(PKG_NAME).$(LINUX_KMOD_SUFFIX)
-  AUTOLOAD:=$(call AutoProbe,macremapper)
-endef
-
-define KernelPackage/macremapper/description
-  Linux kernel module for implementation the DCW filtering mechanism
-endef
-
-MAKE_FLAGS += KERNEL_SRC=$(LINUX_DIR)
-MAKE_PATH:=kernelmod
-
-$(eval $(call KernelPackage,macremapper))
diff --git a/net/dcwifi/macremapper/patches/01_fix_nf_hooks.patch b/net/dcwifi/macremapper/patches/01_fix_nf_hooks.patch
deleted file mode 100644 (file)
index 570d781..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
---- a/kernelmod/main.c
-+++ b/kernelmod/main.c
-@@ -91,8 +91,11 @@ modinit( void ) {
-   rv = mrm_rcdb_init();
-   if (rv != 0) return rv;
--
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0)
-   nf_register_hook(&_hops);
-+#else
-+  nf_register_net_hook(&init_net, &_hops);
-+#endif
-   mrm_init_ctlfile(); /* XXX not checking for failure! */
-   printk(KERN_INFO "MRM The MAC Address Re-Mapper is now in the kernel\n");
-@@ -103,7 +106,11 @@ modinit( void ) {
- static void __exit
- modexit( void ) {
-   mrm_destroy_ctlfile();
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0)
-   nf_unregister_hook(&_hops);
-+#else
-+  nf_unregister_net_hook(&init_net, &_hops);
-+#endif
-   mrm_rcdb_destroy(); /* imperative that this happens last */
-   printk(KERN_INFO "MRM The MAC Address Re-Mapper gone bye-bye\n");
- }
diff --git a/net/dcwifi/mrmctl/Makefile b/net/dcwifi/mrmctl/Makefile
deleted file mode 100644 (file)
index 4c587ab..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# Copyright (C) 2019 EWSI
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=mrmctl
-PKG_VERSION:=1.0.0
-PKG_RELEASE:=1
-
-PKG_SOURCE:=macremapper-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://codeload.github.com/ewsi/macremapper/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=f054201dd805ce005b89606a507b58a5717d383a4339c69dfdc02f0202935437
-PKG_BUILD_DIR:=$(BUILD_DIR)/macremapper-$(PKG_VERSION)
-
-PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
-PKG_LICENSE:=Apache-2.0
-PKG_LICENSE_FILES:=userland/COPYING
-
-PKG_INSTALL:=1
-PKG_BUILD_PARALLEL:=1
-
-include $(INCLUDE_DIR)/package.mk
-
-define Package/mrmctl
-  SECTION:=utils
-  CATEGORY:=Utilities
-  TITLE:=mrmctl utility (macremapper kernel module)
-  URL:=https://www.edgewaterwireless.com
-  DEPENDS:= +kmod-macremapper
-endef
-
-define Package/mrmctl/description
-  Command-line utility to manually manipulate the macremapper kernel module
-endef
-
-MAKE_PATH:=userland
-CONFIGURE_PATH:=userland
-CONFIGURE_ARGS += \
-       --enable-shared
-
-TARGET_CFLAGS += -std=c89 -ffunction-sections -fdata-sections -flto
-TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
-
-define Build/InstallDev
-       $(INSTALL_DIR) $(1)/usr/include
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
-       $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
-endef
-
-define Package/mrmctl/install
-       $(INSTALL_DIR) $(1)/bin
-       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/bin/
-
-       $(INSTALL_DIR) $(1)/usr/lib
-       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
-endef
-
-$(eval $(call BuildPackage,mrmctl))
diff --git a/net/dcwifi/mrmctl/patches/01_replace_bzero.patch b/net/dcwifi/mrmctl/patches/01_replace_bzero.patch
deleted file mode 100644 (file)
index 0f67ab4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
---- a/userland/mrmctl/mrmctl.c
-+++ b/userland/mrmctl/mrmctl.c
-@@ -139,7 +139,7 @@ remap(int argc, char **argv) {
-   if (argc < 5) return 1; /* defensive */
-   /* initialize variables and put things into human-readable variable names */
--  bzero(&re, sizeof(re));
-+  memset(&re, 0, sizeof(re));
-   filter_name   = argv[2];
-   match_macaddr = argv[3];
-diff --git a/userland/mrmfilterparser/mrm_filter_conf_parser.c b/userland/mrmfilterparser/mrm_filter_conf_parser.c
-index 926fa76..f5c54c1 100644
---- a/userland/mrmfilterparser/mrm_filter_conf_parser.c
-+++ b/userland/mrmfilterparser/mrm_filter_conf_parser.c
-@@ -319,7 +319,7 @@ filter_file_loadf(struct mrm_filter_config * const output, FILE * const f) {
-     return -1;
-   output->rules_active = 0;
--  bzero(output->rules, sizeof(output->rules)); /* defensive */
-+  memset(output->rules, 0, sizeof(output->rules)); /* defensive */
-   for (linenum = 1; fgets(buf, sizeof(buf), f) != NULL; linenum++) {
diff --git a/net/mrmctl/Makefile b/net/mrmctl/Makefile
new file mode 100644 (file)
index 0000000..a595cec
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2019 EWSI
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mrmctl
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=macremapper-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ewsi/macremapper/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=f9580427803123d13d50f3422623a37212034a5d72a485f9c04904f19509e4bb
+PKG_BUILD_DIR:=$(BUILD_DIR)/macremapper-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=userland/COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mrmctl
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=Routing and Redirection
+  TITLE:=Dual-Channel WiFi macremapper utility
+  URL:=https://www.edgewaterwireless.com
+  DEPENDS:= +kmod-macremapper
+endef
+
+define Package/mrmctl/description
+  Command-line utility to manually manipulate the macremapper kernel module
+endef
+
+MAKE_PATH:=userland
+CONFIGURE_PATH:=userland
+CONFIGURE_ARGS += \
+       --enable-shared
+
+TARGET_CFLAGS += -std=c89 -ffunction-sections -fdata-sections -flto
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
+
+define Build/InstallDev
+       $(INSTALL_DIR) $(1)/usr/include
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+define Package/mrmctl/install
+       $(INSTALL_DIR) $(1)/bin
+       $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/bin/
+
+       $(INSTALL_DIR) $(1)/usr/lib
+       $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,mrmctl))