Compare commits

..

1 Commits

Author SHA1 Message Date
Amit Kumar
b8bada4cf3 porttrigger: implementation of porttrigger
Added init script Makefile and library for rule installation
2024-01-18 10:01:26 +05:30
548 changed files with 10523 additions and 364700 deletions

23
bbfdm/Config_bbfdm.in Normal file
View File

@@ -0,0 +1,23 @@
config BBF_VENDOR_EXTENSION
bool "Enable Vendor Extension"
default y
config BBF_VENDOR_LIST
string "Vendor List"
default "iopsys"
config BBF_VENDOR_PREFIX
string "Vendor Prefix"
default "X_IOPSYS_EU_"
config BBF_TR143
bool "Enable TR-143 Data Model Support"
default y
config BBF_TR471
bool "Enable TR-471 Data Model Support"
default y
config BBF_MAX_OBJECT_INSTANCES
int "Maximum number of instances per object"
default 255

View File

@@ -1,10 +0,0 @@
if PACKAGE_bbfdmd
config BBF_VENDOR_PREFIX
string "Vendor Prefix"
default "X_IOWRT_EU_"
config BBF_OBFUSCATION_KEY
string "Obfuscation key"
default "371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04"
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bbfdm
PKG_VERSION:=1.16.6
PKG_VERSION:=1.5.4
USE_LOCAL:=0
ifneq ($(USE_LOCAL),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bbfdm.git
PKG_SOURCE_VERSION:=1615b42e405faceceac825f9c0387a58b90785ae
PKG_SOURCE_VERSION:=cd2066de6781ace66d3165937a138a0f12353d8c
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -19,84 +19,56 @@ endif
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
RSTRIP:=true
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
include bbfdm.mk
define Package/libbbfdm-api
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=BBF datamodel library, provides API to extend datamodel using DotSO plugins
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libcurl
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c
ABI_VERSION:=1.0
endef
define Package/libbbfdm-ubus
define Package/libbbfdm
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=BBF datamodel ubus library, provides API to expose datamodel over ubus
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api
TITLE:=Library for broadband forum data model support
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libcurl +libbbfdm-api \
+BBF_TR471:obudpst +libopenssl
endef
define Package/bbfdmd
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=Datamodel ubus backend to expose core tree
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +libopenssl +libbbfdm-ubus +bbf_configmngr
TITLE:=Datamodel ubus backend
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libbbfdm-api +libbbfdm
endef
define Package/dm-service
define Package/userinterface
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=Datamodel ubus backend to expose micro-service tree
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +libbbfdm-ubus +bbf_configmngr
TITLE:=Package to add Device.UserInterface. datamodel support
endef
define Package/bbf_configmngr
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:= BBF Config Manager
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json
define Package/userinterface/description
Package to add Device.UserInterface. datamodel support
endef
define Package/bbfdmd/config
source "$(SOURCE)/Config_bbfdmd.in"
endef
# Below config is a hack to force-recompile dependent micro-services
define Package/libbbfdm-api/config
if PACKAGE_bbfdmd
config BBF_LIBBBFDM_VERSION
string "Internal config variable to force recompile"
default "v${PKG_VERSION}"
endif
define Package/libbbfdm/config
source "$(SOURCE)/Config_bbfdm.in"
endef
define Package/libbbfdm-api/description
Library contains the API(UCI, UBUS, JSON, CLI and Browse) of libbbfdm
endef
define Package/libbbfdm-ubus/description
Library contains the APIs to expose data model over ubus
endef
define Package/bbfdmd/description
Daemon to expose Datamodel core tree
endef
define Package/dm-service/description
Daemon to expose Datamodel micro-service tree
endef
define Package/bbf_configmngr/description
Daemon for handling bbf reload services via ubus bbf.config
define Package/libbbfdm/description
Library contains the data model tree. It includes TR181, TR143 data models
endef
ifeq ($(USE_LOCAL),1)
@@ -106,112 +78,111 @@ endef
endif
CMAKE_OPTIONS += \
-DBBF_VENDOR_PREFIX:String="$(CONFIG_BBF_VENDOR_PREFIX)" \
-DBBFDMD_MAX_MSG_LEN:Integer=10485760 \
-DCMAKE_BUILD_TYPE:String="Debug" \
-DBBF_TR181=ON
-DBBF_WIFI_DATAELEMENTS=ON
ifeq ($(CONFIG_BBF_TR143),y)
CMAKE_OPTIONS += \
-DBBF_TR143=ON
endif
ifeq ($(CONFIG_BBF_TR471),y)
CMAKE_OPTIONS += \
-DBBF_TR471=ON
endif
ifeq ($(CONFIG_BBF_VENDOR_EXTENSION),y)
CMAKE_OPTIONS += \
-DBBF_VENDOR_EXTENSION=ON
CMAKE_OPTIONS += \
-DBBF_VENDOR_LIST:String="$(CONFIG_BBF_VENDOR_LIST)" \
-DBBF_VENDOR_PREFIX:String="$(CONFIG_BBF_VENDOR_PREFIX)" \
-DBBF_MAX_OBJECT_INSTANCES:Integer=$(CONFIG_BBF_MAX_OBJECT_INSTANCES)
endif ##CONFIG_BBF_VENDOR_EXTENSION
ifeq ($(CONFIG_PACKAGE_bbfdmd),y)
CMAKE_OPTIONS += \
-DBBFDMD_MAX_MSG_LEN:Integer=10485760
endif
define Package/libbbfdm-api/install
$(INSTALL_DIR) $(1)/lib
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/libbbfdm-api.so $(1)/lib/
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/version-2/libbbfdm-api-v2.so $(1)/lib/
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/libexec/rpcd/bbf.secure $(1)/usr/libexec/rpcd/bbf.secure
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/libexec/rpcd/bbf.diag $(1)/usr/libexec/rpcd/bbf.diag
$(INSTALL_DIR) $(1)/usr/share/bbfdm/scripts/
$(CP) $(PKG_BUILD_DIR)/utilities/files/usr/share/bbfdm/scripts/bbf_api $(1)/usr/share/bbfdm/scripts/
$(INSTALL_DIR) $(1)/etc/bbfdm/certificates
echo "$(CONFIG_BBF_OBFUSCATION_KEY)" > $(1)/etc/bbfdm/.secure_hash
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/libbbfdm-api.so $(1)/lib/
endef
define Package/libbbfdm-ubus/install
define Package/libbbfdm/install
$(INSTALL_DIR) $(1)/lib
$(CP) $(PKG_BUILD_DIR)/libbbfdm-ubus/libbbfdm-ubus.so $(1)/lib/
endef
define Package/bbfdmd/install
$(INSTALL_DIR) $(1)/etc/bbfdm
$(INSTALL_DIR) $(1)/etc/bbfdm/dmmap
$(INSTALL_DIR) $(1)/usr/share/bbfdm
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/bbfdm $(1)/etc/config/bbfdm
$(INSTALL_CONF) ./files/etc/config/schedules $(1)/etc/config/schedules
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bbfdmd/ubus/bbfdmd $(1)/usr/sbin/
$(STRIP) $(1)/usr/sbin/bbfdmd
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/bbfdmd $(1)/etc/init.d/bbfdmd
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_BIN) ./files/etc/hotplug.d/iface/85-bbfdm-sysctl $(1)/etc/hotplug.d/iface/85-bbfdm-sysctl
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/bbf $(1)/lib/upgrade/keep.d/bbf
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/91-fix-bbfdmd-enabled-option $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/ruleng.bbfdm $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/ruleng
$(INSTALL_BIN) ./files/etc/ruleng/bbfdm.json $(1)/etc/ruleng
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(CP) $(PKG_BUILD_DIR)/libbbfdm/libbbfdm.so $(1)/lib/
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/bbf $(1)/lib/upgrade/keep.d/bbf
$(INSTALL_BIN) ./files/etc/uci-defaults/95-portmap-firewall $(1)/etc/uci-defaults/95-portmap-firewall
$(INSTALL_BIN) ./files/etc/uci-defaults/97-firewall-service $(1)/etc/uci-defaults/97-firewall-service
$(INSTALL_BIN) ./files/etc/uci-defaults/99-link-core-plugins $(1)/etc/uci-defaults/99-link-core-plugins
$(INSTALL_BIN) ./files/etc/firewall.portmap $(1)/etc/firewall.portmap
$(INSTALL_BIN) ./files/etc/firewall.service $(1)/etc/firewall.service
ifeq ($(CONFIG_BBF_TR143),y)
$(INSTALL_DIR) $(1)/usr/share/bbfdm
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
$(INSTALL_BIN) $(PKG_BUILD_DIR)/libbbfdm/scripts/* $(1)/usr/share/bbfdm
$(LN) /usr/share/bbfdm/bbf.diag $(1)/usr/libexec/rpcd/bbf.diag
endif
endef
define Package/dm-service/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/bbfdm.services $(1)/etc/init.d/
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dm-service/dm-service $(1)/usr/sbin/
$(BBFDM_REGISTER_SERVICES) -v ${CONFIG_BBF_VENDOR_PREFIX} ./bbfdm_service.json $(1) core
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/libbbfdm/libcore.so $(1) core
endef
define Package/bbf_configmngr/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/bbfdm/
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/usr/share/bbfdm/scripts
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utilities/bbf_configd $(1)/usr/sbin/
$(STRIP) $(1)/usr/sbin/bbf_configd
$(INSTALL_BIN) ./files/etc/init.d/bbf_configd $(1)/etc/init.d/bbf_configd
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utilities/files/usr/share/bbfdm/scripts/bbf_config_notify.sh $(1)/usr/share/bbfdm/scripts/
$(INSTALL_DATA) ./files/etc/bbfdm/critical_services.json $(1)/etc/bbfdm/
endef
define Package/bbfdmd/prerm
define Package/libbbfdm/prerm
#!/bin/sh
rm -rf /etc/bbfdm/dmmap/*
exit 0
endef
define Package/bbfdmd/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/bbfdm
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bbfdmd/ubus/bbfdmd $(1)/usr/sbin/
$(INSTALL_DATA) ./files/etc/bbfdm/input.json $(1)/etc/bbfdm/
$(INSTALL_BIN) ./files/etc/init.d/bbfdmd $(1)/etc/init.d/bbfdmd
$(INSTALL_CONF) ./files/etc/config/bbfdm $(1)/etc/config/bbfdm
$(INSTALL_BIN) ./files/etc/bbfdm/bbfdm_services.sh $(1)/etc/bbfdm/
$(INSTALL_BIN) ./files/etc/hotplug.d/iface/85-bbfdm-sysctl $(1)/etc/hotplug.d/iface/85-bbfdm-sysctl
endef
define Package/userinterface/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(INSTALL_DATA) ./files/etc/config/userinterface $(1)/etc/config/userinterface
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/userinterface $(1)/lib/upgrade/keep.d/userinterface
$(INSTALL_BIN) ./files/etc/init.d/userinterface $(1)/etc/init.d/userinterface
$(INSTALL_BIN) ./files/etc/uci-defaults/93-userinterface-firewall $(1)/etc/uci-defaults/93-userinterface-firewall
$(INSTALL_BIN) ./files/etc/uci-defaults/94-userinterface-json $(1)/etc/uci-defaults/94-userinterface-json
$(INSTALL_BIN) ./files/etc/firewall.userinterface $(1)/etc/firewall.userinterface
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/include/libbbfdm
$(INSTALL_DIR) $(1)/usr/include/libbbfdm-api
$(INSTALL_DIR) $(1)/usr/include/libbbfdm-api/legacy
$(INSTALL_DIR) $(1)/usr/include/libbbfdm-api/version-2
$(INSTALL_DIR) $(1)/usr/include/libbbfdm-ubus
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/*.h $(1)/usr/include/libbbfdm-api/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/*.h $(1)/usr/include/libbbfdm-api/legacy/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/version-2/*.h $(1)/usr/include/libbbfdm-api/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/version-2/*.h $(1)/usr/include/libbbfdm-api/version-2/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-ubus/bbfdm-ubus.h $(1)/usr/include/libbbfdm-ubus/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/include/*.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/legacy/libbbfdm-api.so $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libbbfdm-api/version-2/libbbfdm-api-v2.so $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libbbfdm-ubus/libbbfdm-ubus.so $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/include/libbbf_api
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/include/*.h $(1)/usr/include/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm/dmtree/tr181/device.h $(1)/usr/include/libbbfdm/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm/dmtree/vendor/vendor.h $(1)/usr/include/libbbfdm/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/*.h $(1)/usr/include/libbbfdm-api/
# Work around for backward compatibility
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/*.h $(1)/usr/include/libbbf_api/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/libbbfdm-api/include/libbbfdm_api.h $(1)/usr/include/libbbf_api.h
endef
$(eval $(call BuildPackage,bbf_configmngr))
$(eval $(call BuildPackage,libbbfdm-api))
$(eval $(call BuildPackage,libbbfdm-ubus))
$(eval $(call BuildPackage,libbbfdm))
$(eval $(call BuildPackage,bbfdmd))
$(eval $(call BuildPackage,dm-service))
$(eval $(call BuildPackage,userinterface))

View File

@@ -1,38 +0,0 @@
# BBFDM configuration options and utilities
bbfdm provides few compile time configuration options and compile time help utility called [bbfdm.mk](./bbfdm.mk), this document aimed to explain the available usages and best practices.
## Compilation options
| Configuration option | Description | Default Value |
| ----------------------- | ------------- | ----------- |
| CONFIG_BBF_VENDOR_LIST | List of vendor extension directories | iopsys |
| CONFIG_BBF_VENDOR_PREFIX | Prefix for Vendor extension datamodel objects/parameters | X_IOPSYS_EU_ |
| CONFIG_BBF_MAX_OBJECT_INSTANCES | Maximum number of instances per object | 255 |
| BBF_OBFUSCATION_KEY | Hash used to encode/decode in `bbf.secure` object | 371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04 |
#### BBF_OBFUSCATION_KEY
`bbfdm` provides an ubus object called `bbf.secure` to allow encoding/decoding the values, `bbf.secure` currently support following methods internally to encode/decode
- Encode/Decode using a predefined SHA512 Hash key
- Encode/Decode using a private/public RSA key pair
The `BBF_OBFUSCATION_KEY` compile time configuration option used to defined the SHA512 HASH, if this option is undefined, then it usages a default value as mention in the above table.
User must override this parameter with their own hash value, to generate a hash user can run below command and copy the hash value to this option.
ex: User wants to use 'Sup3rS3cur3Passw0rd' as passkey, then can get the SHA512 sum with
```bash
$ echo -n "Sup3rS3cur3Passw0rd" | sha512sum
371d530c95a17d1ca223a29b7a6cdc97e1135c1e0959b51106cca91a0b148b5e42742d372a359760742803f2a44bd88fca67ccdcfaeed26d02ce3b6049cb1e04 -
```
> Note: Additionally, user can install RSA private key in '/etc/bbfdm/certificates/private_key.pem' path, if private key is present `bbf.secure` shall use rsa private certificate for encrypt/decrypt function. In case of key not present in the pre-defined path, hash will be used for the same.
## Helper utility (bbfdm.mk)
bbfdm provides a helper utility [bbfdm.mk](./bbfdm.mk) to install datamodel plugins in bbfdm core or in microservice directory.

View File

@@ -2,91 +2,8 @@
# Copyright (C) 2023 IOPSYS
#
BBFDM_BASE_DM_PATH=/usr/share/bbfdm
BBFDM_INPUT_PATH=/etc/bbfdm/micro_services
BBFDM_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PKG_CONFIG_DEPENDS += CONFIG_BBF_LIBBBFDM_VERSION
#BBFDM_VERSION:=$(shell grep -oP '(?<=^PKG_VERSION:=).*' ${BBFDM_DIR}/Makefile)
#BBFDM_TOOLS:=$(BUILD_DIR)/bbfdm-$(BBFDM_VERSION)/tools
# Utility to install the plugin in bbfdm core path with priority.
# Its now possible to overwrite/remove core datamodel with plugin, so, if some
# datamodel objects/parameters are present in more than one plugin, order in
# which they loaded into memory becomes crucial, this Utility help to configure
# a priority order in which they gets loaded in memory.
#
# ARGS:
# $1 => Plugin artifact
# $2 => package install directory
# $3 => Priority of the installed plugin (Optional)
#
# Note:
# - Last loaded plugin gets the highest priority
#
# Example:
# BBFDM_INSTALL_CORE_PLUGIN ./files/etc/bbfdm/json/CWMPManagementServer.json $(1)
#
# Example to install plugin with priority:
# BBFDM_INSTALL_CORE_PLUGIN ./files/etc/bbfdm/json/CWMPManagementServer.json $(1) 01
#
BBFDM_INSTALL_CORE_PLUGIN:=$(BBFDM_DIR)/tools/bbfdm.sh -p
# Utility to install the micro-service datamodel
# Use Case:
# user wants to run a datamodel micro-service, it required to install the
# DotSO/JSON plugin into a bbf shared directory, this utility helps in
# installing the DotSO/JSON plugin in bbfdm shared directory, and auto-generate
# input file for the micro-service
#
# ARGS:
# $1 => DotSo or Json plugin with complete path
# $2 => package install directory
# $3 => service name
#
# Note:
# - There could be only one main plugin file, so its bind to PKG_NAME
# - Micro-service input.json will be auto generated with this call
#
# Example:
# BBFDM_INSTALL_MS_DM $(PKG_BUILD_DIR)/libcwmp.so $(1) $(PKG_NAME)
#
BBFDM_INSTALL_MS_DM:=$(BBFDM_DIR)/tools/bbfdm.sh -m
# Utility to install a plugins in datamodel micro-service
#
# ARGS:
# $1 => DotSo or Json plugin with complete path
# $2 => package install directory
# $3 => service name
#
# Note:
# - Use the service_name/PKG_NAME of the service in which this has to run
#
# Example:
# BBFDM_INSTALL_MS_PLUGIN $(PKG_BUILD_DIR)/libxmpp.so $(1) icwmp
#
BBFDM_INSTALL_MS_PLUGIN:=$(BBFDM_DIR)/tools/bbfdm.sh -m -p
# Utility to install the helper scripts in default bbfdm script path
#
# Use Case:
# User want to install some script for running diagnostics
#
# ARGS:
# $1 => Script with complete path
# $2 => package install directory
#
# Note:
# - Use with -d option to install script in bbf.diag directory
#
# Example:
# BBFDM_INSTALL_SCRIPT $(PKG_BUILD_DIR)/download $(1)
# BBFDM_INSTALL_SCRIPT -d $(PKG_BUILD_DIR)/ipping $(1)
#
BBFDM_INSTALL_SCRIPT:=$(BBFDM_DIR)/tools/bbfdm.sh -s
BBFDM_REGISTER_SERVICES:=$(BBFDM_DIR)/tools/bbfdm.sh -t
define BbfdmInstallPlugin
$(INSTALL_DIR) $(1)/etc/bbfdm/plugins
$(INSTALL_DATA) $(2) $(1)/etc/bbfdm/plugins/
endef

View File

@@ -1,54 +0,0 @@
{
"daemon": {
"enable": "1",
"service_name": "core",
"unified_daemon": false,
"services": [
{
"parent_dm": "Device.",
"object": "LANConfigSecurity"
},
{
"parent_dm": "Device.",
"object": "Schedules"
},
{
"parent_dm": "Device.",
"object": "Security",
"proto": "cwmp"
},
{
"parent_dm": "Device.",
"object": "PacketCaptureDiagnostics"
},
{
"parent_dm": "Device.",
"object": "SelfTestDiagnostics"
},
{
"parent_dm": "Device.",
"object": "Syslog"
},
{
"parent_dm": "Device.",
"object": "{BBF_VENDOR_PREFIX}OpenVPN",
"proto": "usp"
},
{
"parent_dm": "Device.",
"object": "RootDataModelVersion"
},
{
"parent_dm": "Device.",
"object": "Reboot()"
},
{
"parent_dm": "Device.",
"object": "FactoryReset()"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -0,0 +1,47 @@
#!/bin/sh
BBFDMD="/usr/sbin/bbfdmd"
bbfdm_add_service()
{
local name path
name="${1}"
path="${2}"
if [ -z "${name}" -o -z "$path" ]; then
return 0;
fi
ubus call service add "{'name':'bbfdm.services','instances':{'$name':{'command':['$BBFDMD','-m','$path']}}}"
}
bbfdm_stop_service()
{
local name
name="${1}"
if [ -z "${name}" ]; then
return 0;
fi
if ubus call service list '{"name":"bbfdm.services"}' |grep -q "bbfdm.$name"; then
ubus call service delete "{'name':'bbfdm.services','instance':'bbfdm.$name'}"
fi
}
usages()
{
echo "Usages $0: <OPTIONS>..."
echo
echo " -h show help"
echo " -k micro-service name to stop"
echo
}
while getopts "s:k:h" opts; do
case "$opts" in
h) usages; exit 0;;
k) bbfdm_stop_service "${OPTARG}";;
esac
done

View File

@@ -1,23 +0,0 @@
{
"usp": [
"firewall",
"network",
"dhcp",
"time",
"wireless",
"ieee1905",
"mapcontroller",
"mosquitto",
"nginx",
"netmode"
],
"cwmp": [
"firewall",
"network",
"dhcp",
"mapcontroller",
"wireless",
"time",
"netmode"
]
}

View File

@@ -0,0 +1,28 @@
{
"daemon": {
"config": {
},
"input": {
"type": "DotSo",
"name": "/lib/libbbfdm.so",
"plugin_dir": "/etc/bbfdm/plugins"
},
"output": {
"type": "UBUS",
"name": "bbfdm"
}
},
"cli": {
"config": {
"proto": "both",
"instance_mode": 0
},
"input": {
"type": "UBUS",
"name": "bbfdm"
},
"output": {
"type": "CLI"
}
}
}

View File

@@ -1,12 +1,8 @@
config bbfdmd 'bbfdmd'
option enable '1'
option debug '0'
option loglevel '3'
option enabled '1'
option loglevel '1'
option refresh_time '10'
option transaction_timeout '30'
option subprocess_level '2'
config micro_services 'micro_services'
option enable '1'
option enable_core '0'
config reload_handler 'reload_handler'
option log_level '1'

View File

@@ -1,2 +0,0 @@
config global 'global'
option enable '1'

View File

@@ -0,0 +1,74 @@
#!/bin/sh
. /lib/functions.sh
log() {
echo "${@}"|logger -t firewall.dnat -p info
}
exec_cmd() {
if ! eval "$*"; then
log "Failed to run [$*]"
fi
}
reorder_dnat_rules() {
nat_chains=$(iptables -t nat -S | grep -E "^-N zone[a-zA-Z0-9_]+prerouting$" | cut -d' ' -f 2)
for chain in ${nat_chains}; do
# Collect empty remote host & empty dport rules
EMPTY_HOST_PORT=$(iptables -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep -v "\-\-dport" | grep -v "\-s ")
if [ -n "${EMPTY_HOST_PORT}" ]; then
echo "${EMPTY_HOST_PORT}" | while read cmd; do
cmd1="iptables -t nat $(echo $cmd | sed 's/-A /-D /g')"
exec_cmd $cmd1
done
fi
# Collect empty remote host but non empty dport rules
EMPTY_HOST=$(iptables -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep "\-\-dport" | grep -v "\-s ")
if [ -n "${EMPTY_HOST}" ]; then
echo "${EMPTY_HOST}" | while read cmd; do
cmd1="iptables -t nat $(echo $cmd | sed 's/-A /-D /g')"
exec_cmd $cmd1
done
fi
# Collect non empty remote host but empty dport rules
EMPTY_PORT=$(iptables -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep -v "\-\-dport" | grep "\-s ")
if [ -n "${EMPTY_PORT}" ]; then
echo "${EMPTY_PORT}" | while read cmd; do
cmd1="iptables -t nat $(echo $cmd | sed 's/-A /-D /g')"
exec_cmd $cmd1
done
fi
# Now add rules as per datamodel precedence shown below
## Non empty remote host, empty dport
## empty remote host, non empty dport
## empty remote host, empty dport
if [ -n "${EMPTY_PORT}" ]; then
echo "${EMPTY_PORT}" | while read cmd; do
cmd1="iptables -t nat $(echo $cmd)"
exec_cmd $cmd1
done
fi
if [ -n "${EMPTY_HOST}" ]; then
echo "${EMPTY_HOST}" | while read cmd; do
cmd1="iptables -t nat $(echo $cmd)"
exec_cmd $cmd1
done
fi
if [ -n "${EMPTY_HOST_PORT}" ]; then
echo "${EMPTY_HOST_PORT}" | while read cmd; do
cmd1="iptables -t nat $(echo $cmd)"
exec_cmd $cmd1
done
fi
done
}
# Re-order portmapping rules according to precedence hierarchy
reorder_dnat_rules

View File

@@ -2,14 +2,12 @@
. /lib/functions.sh
ZONE_NAME_FILE="/tmp/service_fw_zone"
log() {
echo "${@}"|logger -t firewall.service -p info
}
exec_cmd() {
if ! "$@"; then
if ! eval "$*"; then
log "Failed to run [$*]"
echo "-1"
return 0
@@ -19,37 +17,6 @@ exec_cmd() {
return 0
}
collect_zone_name() {
local name network
config_get name "${1}" name ""
if [ -z "${name}" ]; then
return
fi
config_get network "${1}" network ""
for i in ${network}; do
var="${i}_zone"
echo "${var}=${name}" >> "${ZONE_NAME_FILE}"
done
}
load_zone_names() {
rm -f "${ZONE_NAME_FILE}"
config_foreach collect_zone_name zone
}
get_firewall_zone() {
if [ ! -f "${ZONE_NAME_FILE}" ]; then
echo ""
return
fi
var="${1}_zone="
name="$(cat ${ZONE_NAME_FILE} | grep ${var} | head -n 1 | cut -d'=' -f 2)"
echo "${name}"
}
add_iptable_rule() {
chain_name=$1
protocol=$2
@@ -106,7 +73,7 @@ add_iptable_rule() {
fi
if [ -z "${src_prefix}" ]; then
res=$(exec_cmd iptables -w ${cmd} -m comment --comment IPtables_service_rule -j "${action}")
res=$(exec_cmd "iptables ${cmd} -m comment --comment IPtables_service_rule -j ${action}")
else
#Add ipv4 sources if any
src_list=""
@@ -119,7 +86,7 @@ add_iptable_rule() {
if [ -n "$src_list" ]; then
src_list=$(echo "${src_list}" | sed "s/,$//")
res=$(exec_cmd iptables -w -s "$src_list" ${cmd} -m comment --comment IPtables_service_rule -j "${action}")
res=$(exec_cmd "iptables -s $src_list ${cmd} -m comment --comment IPtables_service_rule -j ${action}")
fi
fi
fi
@@ -130,7 +97,7 @@ add_iptable_rule() {
fi
if [ -z "${src_prefix}" ]; then
res=$(exec_cmd ip6tables -w ${cmd} -m comment --comment IP6tables_service_rule -j "${action}")
res=$(exec_cmd "ip6tables ${cmd} -m comment --comment IP6tables_service_rule -j ${action}")
else
#Add ipv6 sources if any
src_list=""
@@ -143,7 +110,7 @@ add_iptable_rule() {
if [ -n "$src_list" ]; then
src_list=$(echo "${src_list}" | sed "s/,$//")
res=$(exec_cmd ip6tables -w -s "$src_list" ${cmd} -m comment --comment IP6tables_service_rule -j "${action}")
res=$(exec_cmd "ip6tables -s $src_list ${cmd} -m comment --comment IP6tables_service_rule -j ${action}")
fi
fi
fi
@@ -168,14 +135,9 @@ add_service() {
fi
action=$(echo "${target}" | tr a-z A-Z)
zone_name="$(get_firewall_zone ${interface})"
if [ -z "${zone_name}" ]; then
log "Rule can not be added without zone name for interface ${interface}"
return
fi
chain_name="zone_${zone_name}_input"
chain_name="zone_${interface}_input"
res=0
count=$(echo "${proto}" | sed -n "/-1/p" | wc -l)
if [ "${count}" -eq 0 ]; then
@@ -198,9 +160,4 @@ add_service() {
}
config_load firewall
load_zone_names
config_foreach add_service "service"
rm -f "${ZONE_NAME_FILE}"

View File

@@ -3,7 +3,6 @@
. /lib/functions.sh
IDENTIFIER="UI-REMOTE-ACCESS-WAN"
ZONE_NAME_FILE="/tmp/ui_fw_zone"
log() {
echo "${@}"|logger -t firewall.userinterface -p info
@@ -19,41 +18,9 @@ exec_cmd() {
fi
}
collect_zone_name() {
local name network
config_get name "${1}" name ""
if [ -z "${name}" ]; then
return
fi
config_get network "${1}" network ""
for i in ${network}; do
var="${i}_zone"
echo "${var}=${name}" >> "${ZONE_NAME_FILE}"
done
}
load_zone_names() {
rm -f "${ZONE_NAME_FILE}"
config_load firewall
config_foreach collect_zone_name zone
}
get_firewall_zone() {
if [ ! -f "${ZONE_NAME_FILE}" ]; then
echo ""
return
fi
var="${1}_zone="
name="$(cat ${ZONE_NAME_FILE} | grep ${var} | head -n 1 | cut -d'=' -f 2)"
echo "${name}"
}
delete_ui_firewall_rules() {
input_chains=$(iptables -w 1 -S | grep -E "^-N zone[a-zA-Z0-9_]+input$" | cut -d' ' -f 2)
output_chains=$(iptables -w 1 -S | grep -E "^-N zone[a-zA-Z0-9_]+output$" | cut -d' ' -f 2)
input_chains=$(iptables -S | grep -E "^-N zone[a-zA-Z0-9_]+input$" | cut -d' ' -f 2)
output_chains=$(iptables -S | grep -E "^-N zone[a-zA-Z0-9_]+output$" | cut -d' ' -f 2)
for chain in ${input_chains}; do
CMD="iptables -w 1 -t filter -nL ${chain} --line-numbers"
@@ -75,8 +42,8 @@ delete_ui_firewall_rules() {
done
done
input6_chains=$(ip6tables -w 1 -S | grep -E "^-N zone[a-zA-Z0-9_]+input$" | cut -d' ' -f 2)
output6_chains=$(ip6tables -w 1 -S | grep -E "^-N zone[a-zA-Z0-9_]+output$" | cut -d' ' -f 2)
input6_chains=$(ip6tables -S | grep -E "^-N zone[a-zA-Z0-9_]+input$" | cut -d' ' -f 2)
output6_chains=$(ip6tables -S | grep -E "^-N zone[a-zA-Z0-9_]+output$" | cut -d' ' -f 2)
for chain in ${input6_chains}; do
CMD="ip6tables -w 1 -t filter -nL ${chain} --line-numbers"
@@ -104,41 +71,43 @@ configure_ui_firewall_rule() {
local enabled access interface
local port=""
config_get_bool enabled "${sec}" enable '1'
config_get access "${sec}" access ""
config_get interface "${sec}" interface ""
config_get port "${sec}" port ""
config_get_bool enabled "${sec}" uci_enable '1'
config_get access "${sec}" uci_access ""
config_get interface "${sec}" uci_interface ""
if [ "${enabled}" -eq "1" ] && [ "${access}" == "remote" ] && [ -n "${interface}" ]; then
port_list=$(uci -q show nginx."${1}".listen|cut -d'=' -f 2|sed "s/'/ /g"|sed "s/\[\:\:\]\://g")
for item in ${port_list}; do
if [ -z "${item##[0-9]*}" ]; then
port="${item}"
break
fi
done
if [ -z "${port}" ]; then
return 0
fi
zone_name="$(get_firewall_zone ${interface})"
if [ -z "${zone_name}" ]; then
return 0
zone="zone_${interface}_input"
iptables -w 1 -t filter -nL ${zone} 2>/dev/null 1>&2
if [ "$?" -eq 0 ]; then
iptables -w 1 -I "${zone}" -p tcp -m multiport --dports "${port}" -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "${IDENTIFIER}" -j ACCEPT
fi
chain="zone_${zone_name}_input"
iptables -w 1 -t filter -nL ${chain} 2>/dev/null 1>&2
ip6tables -w 1 -t filter -nL ${zone} 2>/dev/null 1>&2
if [ "$?" -eq 0 ]; then
iptables -w 1 -I "${chain}" -p tcp -m multiport --dports "${port}" -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "${IDENTIFIER}" -j ACCEPT
ip6tables -w 1 -I "${zone}" -p tcp -m multiport --dports "${port}" -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "${IDENTIFIER}" -j ACCEPT
fi
ip6tables -w 1 -t filter -nL ${chain} 2>/dev/null 1>&2
zone="zone_${interface}_output"
iptables -w 1 -t filter -nL "${zone}" 2>/dev/null 1>&2
if [ "$?" -eq 0 ]; then
ip6tables -w 1 -I "${chain}" -p tcp -m multiport --dports "${port}" -m conntrack --ctstate NEW,ESTABLISHED -m comment --comment "${IDENTIFIER}" -j ACCEPT
iptables -w 1 -I "${zone}" -p tcp -m multiport --dports "${port}" -m conntrack --ctstate ESTABLISHED -m comment --comment "${IDENTIFIER}" -j ACCEPT
fi
chain="zone_${zone_name}_output"
iptables -w 1 -t filter -nL "${chain}" 2>/dev/null 1>&2
ip6tables -w 1 -t filter -nL "${zone}" 2>/dev/null 1>&2
if [ "$?" -eq 0 ]; then
iptables -w 1 -I "${chain}" -p tcp -m multiport --dports "${port}" -m conntrack --ctstate ESTABLISHED -m comment --comment "${IDENTIFIER}" -j ACCEPT
fi
ip6tables -w 1 -t filter -nL "${chain}" 2>/dev/null 1>&2
if [ "$?" -eq 0 ]; then
ip6tables -w 1 -I "${chain}" -p tcp -m multiport --dports "${port}" -m conntrack --ctstate ESTABLISHED -m comment --comment "${IDENTIFIER}" -j ACCEPT
ip6tables -w 1 -I "${zone}" -p tcp -m multiport --dports "${port}" -m conntrack --ctstate ESTABLISHED -m comment --comment "${IDENTIFIER}" -j ACCEPT
fi
fi
}
@@ -146,14 +115,11 @@ configure_ui_firewall_rule() {
# Delete existing remote access rules
delete_ui_firewall_rules
load_zone_names
config_load userinterface
config_get_bool serv_enable global enable 1
if [ "${serv_enable}" -eq "1" ]; then
config_load nginx
# Configure the User Interface rule
config_foreach configure_ui_firewall_rule http_access
config_foreach configure_ui_firewall_rule server
fi
rm -f "${ZONE_NAME_FILE}"

View File

@@ -1,41 +0,0 @@
#!/bin/sh /etc/rc.common
START=80
STOP=07
USE_PROCD=1
PROG=/usr/sbin/bbf_configd
log() {
echo "${@}"|logger -t bbf.config -p info
}
create_needed_directories()
{
mkdir -p /tmp/bbfdm/.cwmp
mkdir -p /tmp/bbfdm/.usp
mkdir -p /tmp/bbfdm/.bbfdm
}
start_service()
{
local log_level
create_needed_directories
config_load bbfdm
config_get log_level "reload_handler" log_level 2
procd_open_instance "bbf_configd"
procd_set_param command ${PROG}
procd_append_param command -l "${log_level}"
procd_set_param respawn
procd_close_instance "bbf_configd"
}
service_triggers() {
for config_file in /etc/config/*; do
config_name=$(basename "$config_file")
procd_add_config_trigger "config.change" "$config_name" /usr/share/bbfdm/scripts/bbf_config_notify.sh
done
}

View File

@@ -1,127 +0,0 @@
#!/bin/sh /etc/rc.common
START=97
STOP=05
USE_PROCD=1
PROG=/usr/sbin/dm-service
DM_AGENT_PROG=/usr/sbin/dm-agent
BBFDM_MICROSERVICE_DIR="/etc/bbfdm/services"
. /usr/share/libubox/jshn.sh
log() {
echo "${@}"|logger -t bbfdmd.services -p info
}
validate_bbfdm_micro_service_section()
{
uci_validate_section bbfdm micro_services "micro_services" \
'enable:bool:true' \
'enable_core:bool:false'
}
_add_microservice()
{
local name path loglevel
local enable enable_core unified_daemon dm_framework
local daemon_prog
# Check enable from micro-service
path="${1}"
enable_core="${2}"
name="$(basename ${path})"
name="${name//.json}"
json_load_file "${path}"
json_select daemon
json_get_var enable enable 1
if [ "${enable}" -eq "0" ]; then
log "datamodel micro-service ${name} not enabled"
return 0
fi
json_get_var unified_daemon unified_daemon 0
if [ "${unified_daemon}" -eq "1" ]; then
return 0
fi
json_get_var dm_framework dm-framework 0
if [ "${dm_framework}" -eq "1" ] || [ "${dm_framework}" = "true" ]; then
daemon_prog="${DM_AGENT_PROG}"
else
daemon_prog="${PROG}"
fi
json_select config
json_get_var loglevel loglevel 4
procd_open_instance "${name}"
procd_set_param command ${daemon_prog}
# Only add parameters for dm-service, not for dm-agent
if [ "${daemon_prog}" = "${PROG}" ]; then
procd_append_param command -m "${name}"
procd_append_param command -l "${loglevel}"
fi
if [ "${enable_core}" -eq "1" ]; then
procd_set_param limits core="unlimited"
procd_set_param stdout 1
procd_set_param stderr 1
fi
procd_set_param respawn
procd_close_instance "${name}"
}
configure_bbfdm_micro_services()
{
local enable enable_core
config_load bbfdm
validate_bbfdm_micro_service_section || {
log "Validation of micro_service section failed"
return 1;
}
[ "${enable}" -eq "0" ] && return 0
if [ -d "${BBFDM_MICROSERVICE_DIR}" ]; then
FILES="$(ls -1 ${BBFDM_MICROSERVICE_DIR}/*.json)"
for file in $FILES;
do
[ -e "$file" ] || continue
_add_microservice $file "${enable_core}"
done
fi
}
_start_single_service()
{
local service file
service="${1}"
if [ -d "${BBFDM_MICROSERVICE_DIR}" ]; then
file="$(ls -1 ${BBFDM_MICROSERVICE_DIR}/${service}.json)"
[ -e "$file" ] || return
_add_microservice $file "0"
fi
}
start_service()
{
if [ -n "${1}" ]; then
_start_single_service "${1}"
else
configure_bbfdm_micro_services
fi
}

View File

@@ -1,12 +1,13 @@
#!/bin/sh /etc/rc.common
START=97
STOP=06
START=65
STOP=10
USE_PROCD=1
PROG=/usr/sbin/bbfdmd
. /usr/share/libubox/jshn.sh
BBFDM_JSON_INPUT="/etc/bbfdm/input.json"
BBFDM_TEMP_JSON="/tmp/bbfdm/input.json"
log() {
echo "${@}"|logger -t bbfdmd.init -p info
@@ -15,39 +16,58 @@ log() {
validate_bbfdm_bbfdmd_section()
{
uci_validate_section bbfdm bbfdmd "bbfdmd" \
'enable:bool:true' \
'enabled:bool:true' \
'sock:string' \
'debug:bool:false' \
'loglevel:uinteger:4'
'loglevel:uinteger:1' \
'refresh_time:uinteger:0' \
'transaction_timeout:uinteger:30' \
'subprocess_level:uinteger'
}
configure_bbfdmd()
{
local enable debug
local enabled debug sock update
local jlog jrefresh jtimeout jlevel
update=0
config_load bbfdm
validate_bbfdm_bbfdmd_section || {
log "Validation of bbfdmd section failed"
return 1;
}
[ "${enable}" -eq 0 ] && return 0
[ "${enabled}" -eq 0 ] && return 0
if [ -f "${BBFDM_JSON_INPUT}" ]; then
echo "$(jq --arg log ${loglevel} --arg tran ${transaction_timeout} --arg refresh ${refresh_time} --arg level ${subprocess_level} '.daemon.config += {"loglevel": $log, "refresh_time": $refresh, "transaction_timeout": $tran, "subprocess_level": $level}' ${BBFDM_JSON_INPUT})" > ${BBFDM_TEMP_JSON}
fi
procd_set_param command ${PROG}
procd_append_param command -l "${loglevel}"
if [ "${debug}" -eq 1 ]; then
procd_set_param stdout 1
procd_set_param stderr 1
fi
if [ -f "${sock}" ]; then
procd_append_param command -s "${sock}"
fi
}
start_service()
{
mkdir -p /tmp/bbfdm
procd_open_instance "bbfdm"
configure_bbfdmd
procd_set_param respawn
procd_close_instance "bbfdm"
ubus call service state '{"name":"bbfdm.services", "spawn":true}'
}
stop_service()
{
ubus call service state '{"name":"bbfdm.services", "spawn":false}'
}
service_triggers()

View File

@@ -0,0 +1,33 @@
#!/bin/sh /etc/rc.common
START=99
STOP=01
USE_PROCD=1
start_service() {
local enable
config_load userinterface
config_get_bool enable global enable 1
if [ ! -f "/etc/config/nginx" ]; then
return 0
fi
if [ "${enable}" -eq "1" ]; then
ubus call service state '{"name":"nginx", "spawn":true}'
else
ubus call service state '{"name":"nginx", "spawn":false}'
fi
# Inject firewall rules
procd_open_instance userinterface
/etc/firewall.userinterface
procd_close_instance
}
service_triggers()
{
procd_add_reload_trigger "userinterface" "nginx"
}

View File

@@ -1,66 +0,0 @@
{
"hosts_refresh": {
"if" : [
{
"event": "host"
}
],
"then" : [
{
"object": "bbfdm.hostmngr",
"method":"refresh_references_db",
"args" : {},
"timeout": 1
}
]
},
"dhcp_refresh": {
"if_operator": "OR",
"if" : [
{
"event": "host"
},
{
"event": "wifi.dataelements.Associated"
}
],
"then" : [
{
"object": "bbfdm.dhcpmngr",
"method":"refresh_references_db",
"args" : {},
"timeout": 1
}
]
},
"ieee1905_refresh_add": {
"if" : [
{
"event": "ieee1905.neighbor.add"
}
],
"then" : [
{
"object": "bbfdm.ieee1905",
"method":"refresh_references_db",
"args" : {},
"timeout": 1
}
]
},
"ieee1905_refresh_del": {
"if" : [
{
"event": "ieee1905.neighbor.del"
}
],
"then" : [
{
"object": "bbfdm.ieee1905",
"method":"refresh_references_db",
"args" : {},
"timeout": 1
}
]
}
}

View File

@@ -1,11 +0,0 @@
#!/bin/sh
# rename bbfdmd enabled option to enable
val="$(uci -q get bbfdm.bbfdmd.enabled)"
if [ -n "${val}" ]; then
uci -q set bbfdm.bbfdmd.enabled=""
uci -q set bbfdm.bbfdmd.enable="${val}"
fi
exit 0

View File

@@ -0,0 +1,9 @@
#!/bin/sh
# This deletes the userinterface json plugin if exists in case of upgrade
if [ -f "/etc/bbfdm/json/UserInterface.json" ]; then
rm /etc/bbfdm/json/UserInterface.json
fi
exit 0

View File

@@ -51,6 +51,10 @@ parse_bbfdm_sysctl_conf_file() {
# Replace the original file with the modified content
mv "$tmpfile" "${bbfdm_sysctl_conf}"
# Apply the changes
uci commit network
sysctl -e -p "${bbfdm_sysctl_conf}" >&-
}
parse_bbfdm_sysctl_conf_file

View File

@@ -0,0 +1,18 @@
#!/bin/sh
UNIFIED_PATH="/etc/bbfdm/plugins/"
# Link JSON plugins
for f in `ls -1 /etc/bbfdm/json/*.json`; do
echo "# BBFDM JSON plugin ${f} not aligned #"
ln -s ${f} "${UNIFIED_PATH}"
done
# Link DotSo plugins
for f in `ls -1 /usr/lib/bbfdm/*.so`; do
echo "# BBFDM DotSO plugin ${f} not aligned #"
ln -s ${f} "${UNIFIED_PATH}"
done
exit 0

View File

@@ -1,2 +0,0 @@
uci -q set ruleng.bbfdm=rule
uci -q set ruleng.bbfdm.recipe='/etc/ruleng/bbfdm.json'

View File

@@ -0,0 +1 @@
/etc/nginx/allow_host_*

View File

@@ -1,203 +0,0 @@
#!/bin/bash
BBFDM_BASE_DM_PATH="usr/share/bbfdm"
BBFDM_INPUT_PATH="etc/bbfdm/micro_services"
INPUT_FILE="0"
MICRO_SERVICE=0
SCRIPT=0
DIAG=0
PLUGIN=0
DEST=""
VENDOR_EXTN=""
TOOLS="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
SRC=""
EXTRA_DATA=""
while getopts ":mpsdtv:" opt; do
case ${opt} in
m)
MICRO_SERVICE=1
;;
p)
PLUGIN=1
;;
s)
SCRIPT=1
;;
d)
DIAG=1
;;
t)
INPUT_FILE=1
;;
v)
VENDOR_EXTN=${OPTARG}
;;
?)
echo "Invalid option: ${OPTARG}"
exit 1
;;
esac
done
shift $((OPTIND-1))
SRC="${1}"
shift
DEST="${1}"
shift
DATA="${1}"
shift
EXTRA_DATA="${1}"
install_bin() {
if ! install -m0755 ${1} ${2}; then
echo "Failed to install bin ${1} => ${2}"
exit 1
fi
}
install_dir() {
if ! install -d -m0755 ${1}; then
echo "Failed to create directory ${1}"
exit 1
fi
}
install_data() {
if ! install -m0644 ${1} ${2}; then
echo "Failed to install ${1} => ${2}"
exit 1
fi
}
# Installing datamodel
bbfdm_install_dm()
{
local src dest minfile
src="$1"
dest="$2"
minfile=""
if [ -z ${src} ] || [ -z "${dest}" ] || [ -z "${TOOLS}" ]; then
echo "Invalid input option for install dm $@"
exit 1
fi
if [ ! -f "${src}" ]; then
echo "File $src does not exists..."
exit 1
fi
if [ "${src##*.}" = "json" ]; then
echo "Compacting BBFDM JSON file"
minfile=$(mktemp)
jq -c 'del(..|.description?)' ${src} > ${minfile}
if [ -n "${VENDOR_EXTN}" ]; then
sed -i "s/{BBF_VENDOR_PREFIX}/${VENDOR_EXTN}/g" ${minfile}
fi
src=${minfile}
if dpkg -s python3-jsonschema >/dev/null 2>&1; then
echo "Verifying bbfdm Datamodel JSON file"
if ! ${TOOLS}/validate_plugins.py ${src}; then
echo "Validation of the plugin failed ${src}"
exit 1
fi
else
echo "## Install python3-jsonschema to verify datamodel plugins"
fi
fi
install_bin ${src} ${dest}
if [ -f "${minfile}" ]; then
rm ${minfile}
fi
}
if [ -z "$SRC" ] || [ -z "${DEST}" ] ; then
echo "# BBFDM Null value in src[${SRC}], dest[${DEST}]"
exit 1
fi
if [ "${SCRIPT}" -eq "1" ]; then
if [ "${DIAG}" -eq "1" ]; then
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/scripts/bbf_diag
install_bin ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/scripts/bbf_diag/
else
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/scripts
install_bin ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/scripts/
fi
exit 0
fi
if [ "${INPUT_FILE}" -eq "1" ]; then
tempfile=""
if [ ! -f "${SRC}" ]; then
echo "# Datamodel Input file ${SRC} not available"
exit 1
fi
if ! cat ${SRC} |jq >/dev/null 2>&1; then
echo "# Invalid datamodel json input file"
exit 1
fi
service_name="$(cat ${SRC}|jq -r '.daemon.service_name')"
if [ -z "${service_name}" ]; then
echo "# service_name not defined in service json ...."
exit 1
fi
tempfile=$(mktemp)
cp ${SRC} ${tempfile}
if [ -n "${VENDOR_EXTN}" ]; then
sed -i "s/{BBF_VENDOR_PREFIX}/${VENDOR_EXTN}/g" ${tempfile}
fi
install_dir ${DEST}/etc/bbfdm/services
install_data ${tempfile} ${DEST}/etc/bbfdm/services/${service_name}.json
if [ -f "${tempfile}" ]; then
rm ${tempfile}
fi
exit 0
fi
if [ "${MICRO_SERVICE}" -eq "1" ]; then
if [ -z "${DATA}" ]; then
echo "# service_name[${DATA}] not provided"
exit 1
fi
if [ "${PLUGIN}" -ne "1" ]; then
extn="$(basename ${SRC})"
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/${DATA}.${extn##*.}
else
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/${DATA}
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/${DATA}/$(printf "%02d" ${EXTRA_DATA})$(basename ${SRC})
fi
else
if [ "${PLUGIN}" -eq "1" ]; then
echo "# WARNING: BBFDM_INSTALL_CORE_PLUGIN macro will be deprecated soon. Please use BBFDM_INSTALL_MS_PLUGIN macro instead, specifying 'core' as micro-service name #"
priority="${DATA:-0}"
install_dir ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/core
if [ "${priority}" -gt "0" ]; then
# install with priority if defined
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/core/${priority}_$(basename ${SRC})
elif [ "${priority}" -eq "0" ]; then
bbfdm_install_dm ${SRC} ${DEST}/${BBFDM_BASE_DM_PATH}/micro_services/core/$(basename ${SRC})
else
echo "# Priority should be an unsigned integer"
exit 1
fi
fi
fi

View File

@@ -1,333 +0,0 @@
#!/usr/bin/python3
# Copyright (C) 2024 iopsys Software Solutions AB
# Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
import sys
import json
from jsonschema import validate
JSON_PLUGIN_VERSION = 0
obj_schema = {
"definitions": {
"type_t": {
"type": "string",
"enum": [
"object"
]
},
"map_type_t": {
"type": "string",
"enum": [
"uci",
"ubus"
]
},
"protocols_t": {
"type": "string",
"enum": [
"none",
"cwmp",
"usp"
]
}
},
"type" : "object",
"properties" : {
"type" : {"$ref": "#/definitions/type_t"},
"version" : {"type": "string"},
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}},
"uniqueKeys" : {"type" : "array"},
"access" : {"type" : "boolean"},
"array" : {"type" : "boolean"},
"mapping" : {"type" : "object", "properties" : {
"type" : {"$ref": "#/definitions/map_type_t"},
"uci" : {"type" : "object", "properties" : {
"file" : {"type": "string"},
"section" : {"type": "object", "properties" : {
"type" : {"type": "string"}
}
},
"dmmapfile" : {"type": "string"}
}
},
"ubus" : {"type" : "object", "properties" : {
"object" : {"type": "string"},
"method" : {"type": "string"},
"args" : {"type": "object"},
"key" : {"type": "string"}
}
}
}
}
},
"required": [
"type",
"protocols",
"array",
"access"
]
}
obj_schema_v1 = {
"definitions": {
"type_t": {
"type": "string",
"enum": [
"object"
]
},
"map_type_t": {
"type": "string",
"enum": [
"uci",
"ubus"
]
},
"protocols_t": {
"type": "string",
"enum": [
"cwmp",
"usp",
"none"
]
}
},
"type" : "object",
"properties" : {
"type" : {"$ref": "#/definitions/type_t"},
"version" : {"type": "string"},
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}},
"uniqueKeys" : {"type" : "array"},
"access" : {"type" : "boolean"},
"array" : {"type" : "boolean"},
"mapping" : {"type" : "array", "items" : {
"type" : "object", "properties" : {
"type" : {"$ref": "#/definitions/map_type_t"},
"uci" : {"type" : "object", "properties" : {
"file" : {"type": "string"},
"section" : {"type": "object", "properties" : {
"type" : {"type": "string"}
}
},
"dmmapfile" : {"type": "string"}
}
},
"ubus" : {"type" : "object", "properties" : {
"object" : {"type": "string"},
"method" : {"type": "string"},
"args" : {"type": "object"},
"key" : {"type": "string"}
}
}
}
}
}
},
"required": [
"type",
"protocols",
"array",
"access"
]
}
param_schema = {
"definitions": {
"type_t": {
"type": "string",
"enum": [
"string",
"unsignedInt",
"unsignedLong",
"int",
"long",
"boolean",
"dateTime",
"hexBinary",
"base64",
"decimal"
]
},
"map_type_t": {
"type": "string",
"enum": [
"uci",
"ubus",
"procfs",
"sysfs",
"json",
"uci_sec"
]
},
"protocols_t": {
"type": "string",
"enum": [
"cwmp",
"usp",
"none"
]
}
},
"type" : "object",
"properties" : {
"type" : {"$ref": "#/definitions/type_t"},
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}},
"read" : {"type" : "boolean"},
"write" : {"type" : "boolean"},
"mapping" : {"type" : "array", "items" : {"type": "object", "properties" : {
"type" : {"$ref": "#/definitions/map_type_t"},
"uci" : {"type" : "object", "properties" : {
"file" : {"type": "string"},
"section" : {"type": "object", "properties" : {
"type" : {"type": "string"},
"index" : {"type": "string"}
}
},
"option" : {"type": "object", "properties" : {
"name" : {"type": "string"} }
}
}
},
"ubus" : {"type" : "object", "properties" : {
"object" : {"type": "string"},
"method" : {"type": "string"},
"args" : {"type": "object"},
"key" : {"type": "string"}
}
},
"procfs" : {"type" : "object", "properties" : {
"file" : {"type": "string"}
}
},
"sysfs" : {"type" : "object", "properties" : {
"file" : {"type": "string"}
}
}
}
}
}
},
"required": [
"type",
"protocols",
"read",
"write"
]
}
event_schema = {
"definitions": {
"type_t": {
"type": "string",
"enum": [
"event"
]
},
"protocols_t": {
"type": "string",
"enum": [
"none",
"usp"
]
}
},
"type" : "object",
"properties" : {
"type" : {"$ref": "#/definitions/type_t"},
"version" : {"type": "string"},
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}}
},
"required": [
"type",
"protocols"
]
}
command_schema = {
"definitions": {
"type_t": {
"type": "string",
"enum": [
"command"
]
},
"protocols_t": {
"type": "string",
"enum": [
"none",
"usp"
]
}
},
"type" : "object",
"properties" : {
"type" : {"$ref": "#/definitions/type_t"},
"async" : {"type" : "boolean"},
"protocols" : {"type" : "array", "items" : {"$ref": "#/definitions/protocols_t"}},
"input" : {"type" : "object"},
"output" : {"type" : "object"}
},
"required": [
"type",
"async",
"protocols"
]
}
def print_validate_json_usage():
print("Usage: " + sys.argv[0] + " <dm json file>")
print("Examples:")
print(" - " + sys.argv[0] + " datamodel.json")
print(" ==> Validate the json file")
print("")
exit(1)
def parse_value( key , value ):
if key.endswith('.') and not key.startswith('Device.'):
print(key + " is not a valid path")
exit(1)
if key.endswith('.') and (JSON_PLUGIN_VERSION == 1 or JSON_PLUGIN_VERSION == 2):
__schema = obj_schema_v1
elif key.endswith('.'):
__schema = obj_schema
elif key.endswith('!'):
__schema = event_schema
elif key.endswith('()'):
__schema = command_schema
else:
__schema = param_schema
validate(instance = value, schema = __schema)
for k, v in value.items():
if k != "list" and k != "mapping" and k != "input" and k != "output" and isinstance(v, dict):
parse_value(k, v)
### main ###
if len(sys.argv) < 2:
print_validate_json_usage()
json_file = open(sys.argv[1], "r", encoding='utf-8')
try:
json_data = json.loads(json_file.read())
except ValueError:
print(sys.argv[1] + " file has a wrong JSON format!!!!!")
exit(1)
for __key, __value in json_data.items():
if __key == "json_plugin_version":
if not isinstance(__value, int) or __value not in [0, 1, 2]:
raise ValueError("Invalid value for json_plugin_version")
JSON_PLUGIN_VERSION = __value
continue
parse_value(__key , __value)
print("JSON File is Valid")

View File

@@ -1,45 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2025 IOPSYS Software Solutions AB
include $(TOPDIR)/rules.mk
PKG_NAME:=blkpg-part
PKG_VERSION:=1
PKG_RELEASE:=1
PKG_SOURCE_VERSION:=5a4ec5f53ed904b37fba03f3797fbe2af3077f8d
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/gportay/blkpg-part.git
PKG_MIRROR_HASH:=skip
PKG_MAINTAINER:=Andreas Gnau <andreas.gnau@iopsys.eu>
PKG_LICENSE:=LGPL-2.1-or-later
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
MAKE_INSTALL_FLAGS += PREFIX=/usr
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=Disc
TITLE:=User space partition table and disk geometry handling utility
URL:=https://www.portay.io/blkpg-part/
endef
define Package/$(PKG_NAME)/description
blkpg-part creates temporary partitions that are not part of the GPT/MBR.
It makes a partition block device from any consecutive blocks that are
not partitioned. It creates, resizes and deletes partitions on the fly
without writing back the changes to the partition table.
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/blkpg-part $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -7,13 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bulkdata
PKG_VERSION:=2.1.20
PKG_VERSION:=2.1.5
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bulkdata.git
PKG_SOURCE_VERSION:=a5e57962938ca143ede65d92be90b6e9fce66e15
PKG_SOURCE_VERSION:=f03fb8682aa7efe760294e54c422f2eab856e08c
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -22,19 +22,13 @@ PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
define Package/bulkdata
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=BBF BulkData Collection
DEPENDS:=+ubus +libuci +libubox +libjson-c +libcurl +libblobmsg-json +zlib
DEPENDS+=+libbbfdm-api +libbbfdm-ubus
endef
define Package/bulkdata/description
BulkData daemon for TR069 with bbfdm backend.
DEPENDS:=+libubus +libuci +libubox +libjson-c +libcurl +libblobmsg-json +zlib
endef
TARGET_CFLAGS += \
@@ -47,15 +41,12 @@ define Build/Prepare
endef
endif
define Package/bulkdata/install
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bulkdatad $(1)/usr/sbin/
$(INSTALL_DATA) ./files/etc/config/bulkdata $(1)/etc/config/
$(INSTALL_BIN) ./files/etc/init.d/bulkdatad $(1)/etc/init.d/
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bulkdatad $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/etc/bulkdata
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bbf_plugin/*.json $(1)/etc/bulkdata
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,bulkdata))
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,17 +0,0 @@
{
"daemon": {
"enable": "1",
"service_name": "bulkdata",
"unified_daemon": true,
"proto": "cwmp",
"services": [
{
"parent_dm": "Device.",
"object": "BulkData"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -0,0 +1,15 @@
{
"daemon": {
"input": {
"type": "JSON",
"name": "/etc/bulkdata/bulkdata.json"
},
"output": {
"type": "UBUS",
"name": "bbfdm.bulkdata",
"parent_dm": "Device.",
"object": "BulkData",
"root_obj": "bbfdm"
}
}
}

View File

@@ -1,6 +1,6 @@
config bulkdata 'bulkdata'
option enable '0'
#Log levels: As per syslog 0-7, default 6=>LOG_INFO
option loglevel '3'
#Log levels: Error=1, Warning=2, Info=3, Debug=4
option log_level '3'

View File

@@ -3,39 +3,34 @@
START=60
STOP=10
. /etc/bbfdm/bbfdm_services.sh
USE_PROCD=1
PROG="/usr/sbin/bulkdatad"
validate_global_section() {
uci_validate_section bulkdata bulkdata bulkdata \
'enable:bool:1' \
'loglevel:uinteger:3'
}
BULKDATA_JSON_INPUT="/etc/bulkdata/input.json"
start_service() {
local enable loglevel
local enable
validate_global_section
config_load bulkdata
config_get_bool enable bulkdata enable 1
procd_open_instance "bulkdata"
procd_set_param command "$PROG"
procd_append_param command -l ${loglevel}
procd_set_param respawn
procd_close_instance "bulkdata"
[ "$enable" -eq "1" ] && {
procd_open_instance "bulkdata"
procd_set_param command "$PROG"
procd_set_param respawn
procd_close_instance "bulkdata"
}
bbfdm_add_service "bbfdm.bulkdata" "${BULKDATA_JSON_INPUT}"
}
reload_service() {
ret=$(ubus call service list '{"name":"bulkdatad"}' | jsonfilter -qe '@.bulkdatad.instances.bulkdata.running')
if [ "$ret" != "true" ]; then
stop
start
else
ubus send bulkdata.reload
fi
return 0
stop
start
}
service_triggers() {
service_triggers()
{
procd_add_reload_trigger bulkdata
}

View File

@@ -0,0 +1,75 @@
#!/bin/sh
. /lib/functions.sh
PROFILE_COUNT=1
get_next_count()
{
local config="$1"
local default_name="${2}"
local count=${3}
local found=0
if [ -z "$count" ]; then
count=1
fi
while [ "${found}" -ne 1 ]; do
uci -q get "${config}"."${default_name}"_${count} >/dev/null
if [ "$?" -eq 0 ]; then
count=$((count + 1))
else
found=1;
fi
done
echo "${default_name}_${count}"
}
translate_profile_id_to_profile_name() {
local section="${1}"
local profile_id="${2}"
local profile_name="${3}"
local curr_profile_id
config_get curr_profile_id "${section}" profile_id
[ -n "${curr_profile_id}" ] || return
[ "${curr_profile_id}" != "${profile_id}" ] && return
uci -q set bulkdata."${section}".profile_name="${profile_name}"
uci -q set bulkdata."${section}".profile_id=""
}
update_profile_sections() {
local section="${1}"
local default="${2}"
local profile_name
config_get profile_id "${section}" profile_id
[ -n "${profile_id}" ] || return
case "${section}" in
"cfg"*)
profile_name="$(get_next_count bulkdata "${default}" ${PROFILE_COUNT})"
uci_rename bulkdata "${section}" "${profile_name}"
;;
esac
PROFILE_COUNT=$((PROFILE_COUNT + 1))
[ -n "$profile_name" ] && section="${profile_name}"
uci -q set bulkdata."${section}".profile_id=""
config_foreach translate_profile_id_to_profile_name profile_parameter "${profile_id}" "${profile_name}"
config_foreach translate_profile_id_to_profile_name profile_http_request_uri_parameter "${profile_id}" "${profile_name}"
}
config_load bulkdata
config_foreach update_profile_sections profile profile
uci commit bulkdata
exit 0

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=capiagent
PKG_VERSION:=2.1.1
PKG_VERSION:=2.1.0
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=136cab3a9f1eec0132db9fa3f7bb1c8748ce1449
PKG_SOURCE_VERSION:=3e671db8f567b19c109fc13b25bc571c4c73a962
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/capiagent.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
@@ -31,7 +31,7 @@ include $(INCLUDE_DIR)/package.mk
define Package/capiagent
TITLE+= capiagent (daemon implementing Wi-Fi Alliance's CAPI commands)
DEPENDS= +libubox +libuci +libubus +libnl-genl +libeasy +libwifi \
+libjson-c +libblobmsg-json +ubus +libieee1905 +libwifiutils
+libjson-c +libblobmsg-json +ubus +libieee1905
endef
define Package/capiagent/description

View File

@@ -1,52 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=cmph
PKG_VERSION:=2.0.2
PKG_RELEASE:=1
PKG_SOURCE:=cmph-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/cmph/
PKG_MD5SUM:=51ec5329b47774d251a96eaaafdb409e
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
PKG_FIXUP:=autoreconf
PKG_LICENSE:=LGPLv2
PKG_LICENSE_FILES:=LGPL-2
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=libs
CATEGORY:=Libraries
TITLE:=C Minimal Perfect Hashing library
URL:=https://sourceforge.net/projects/cmph/
endef
define Package/$(PKG_NAME)/description
C Minimal Perfect Hashing (CMPH) library allows the creation of minimal perfect hash functions for large data sets.
endef
define Build/Configure
$(call Build/Configure/Default)
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DATA) $(PKG_BUILD_DIR)/src/cmph.h $(1)/usr/include/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/src/cmph_time.h $(1)/usr/include/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/src/cmph_types.h $(1)/usr/include/
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/src/.libs/libcmph.a $(1)/usr/lib/
$(CP) $(PKG_BUILD_DIR)/src/.libs/libcmph.so* $(1)/usr/lib/
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/src/.libs/libcmph.so* $(1)/usr/lib/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,64 +0,0 @@
#
# Copyright (C) 2020-2024 IOPSYS Software Solutions AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=csmngr
PKG_VERSION:=1.0.2
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=5e50fe388fff29b08d895c1c580152cccfa290ad
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/csmngr.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
PKG_CONFIG_DEPENDS := \
CONFIG_PACKAGE_libwifiutils \
CONFIG_PACKAGE_libwifi
PKG_BUILD_DEPENDS := libwifi
include $(INCLUDE_DIR)/package.mk
MAKE_PATH:=src
define Package/csmngr
SECTION:=utils
CATEGORY:=Utilities
TITLE:=WiFi channel selection manager
DEPENDS:=+libwifiutils +libwifi +libuci +libubox +ubus +libnl-genl
endef
define Package/csmngr/description
WiFi Auto Channel Selection manager.
endef
TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include \
-I$(STAGING_DIR)/usr/include/libnl3 \
-D_GNU_SOURCE
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
rsync -r --exclude=.* ~/git/csmngr/ $(PKG_BUILD_DIR)/
endef
endif
define Package/csmngr/install
$(CP) ./files/* $(1)/
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/csmngr $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,csmngr))

View File

@@ -1,21 +0,0 @@
#!/bin/sh /etc/rc.common
START=95
STOP=10
USE_PROCD=1
PROG=/usr/sbin/csmngr
start_service() {
procd_open_instance
procd_set_param command ${PROG}
# procd_set_param stderr 1 #for debugging only
# procd_set_param respawn
procd_close_instance
}
reload_service() {
stop
start
}

View File

@@ -1,16 +0,0 @@
if PACKAGE_ddnsmngr
choice
prompt "Select backend for dynamic DNS management"
default DDNSMNGR_BACKEND_DDNSSCRIPT
depends on PACKAGE_ddnsmngr
help
Select which package to use for dynamic DNS support
config DDNSMNGR_BACKEND_DDNSSCRIPT
bool "Use ddns_script"
config DDNSMNGR_BACKEND_INADYN
bool "Use inadyn"
endchoice
endif

View File

@@ -1,79 +0,0 @@
#
# Copyright (C) 2024 IOPSYS
#
include $(TOPDIR)/rules.mk
PKG_NAME:=ddnsmngr
PKG_VERSION:=1.0.12
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/ddnsmngr.git
PKG_SOURCE_VERSION:=44af9a7b3fec3929f8554af9633a5b8068189b48
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
PKG_CONFIG_DEPENDS:=CONFIG_DDNSMNGR_BACKEND_DDNSSCRIPT CONFIG_DDNSMNGR_BACKEND_INADYN
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=Dynamic DNS manager
DEPENDS:=+DDNSMNGR_BACKEND_DDNSSCRIPT:ddns-scripts +DDNSMNGR_BACKEND_INADYN:inadyn
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service
MENU:=1
endef
define Package/$(PKG_NAME)/config
source "$(SOURCE)/Config.in"
endef
MAKE_PATH:=src
define Package/$(PKG_NAME)/description
Manage dynamic DNS updation and provides Device.DynamicDNS. datamodel object based on TR181-2.16
endef
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -rf ~/git/ddnsmngr/* $(PKG_BUILD_DIR)/
endef
endif
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/ddnsmngr/ddns
$(INSTALL_DIR) $(1)/etc/ddnsmngr/servers
$(INSTALL_DIR) $(1)/usr/lib/ddnsmngr
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
$(INSTALL_DATA) ./files/etc/config/ddnsmngr $(1)/etc/config/ddnsmngr
$(INSTALL_BIN) ./files/etc/uci-defaults/01-ddns-config-migrate $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/init.d/ddnsmngr $(1)/etc/init.d/ddnsmngr
ifeq ($(CONFIG_DDNSMNGR_BACKEND_DDNSSCRIPT),y)
$(INSTALL_BIN) ./files/usr/lib/ddns_script/ddnsmngr_service.sh $(1)/usr/lib/ddnsmngr/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns-script/usr/lib/ddnsmngr/ddnsmngr_updater.sh $(1)/usr/lib/ddnsmngr/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/ddns-script/server/* $(1)/etc/ddnsmngr/servers
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/ddns-script/usr/libexec/rpcd/ddnsmngr $(1)/usr/libexec/rpcd/ddnsmngr
endif
ifeq ($(CONFIG_DDNSMNGR_BACKEND_INADYN),y)
$(INSTALL_BIN) ./files/usr/lib/inadyn/ddnsmngr_service.sh $(1)/usr/lib/ddnsmngr/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/files/inadyn/server/* $(1)/etc/ddnsmngr/servers
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/inadyn/usr/libexec/rpcd/ddnsmngr $(1)/usr/libexec/rpcd/ddnsmngr
endif
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/src/libddnsmngr.so $(1) $(PKG_NAME)
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,16 +0,0 @@
{
"daemon": {
"enable": "1",
"service_name": "ddnsmngr",
"unified_daemon": false,
"services": [
{
"parent_dm": "Device.",
"object": "DynamicDNS"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -1,23 +0,0 @@
config ddnsmngr 'global'
option configfile '/var/run/ddnsmngr/ddnsmngr.json'
option ddns_dateformat '%F %R'
option ddns_rundir '/var/run/ddnsmngr'
option ddns_logdir '/var/log/ddnsmngr'
option ddns_loglines '250'
option upd_privateip '0'
option use_curl '1'
config server 'ddns_server_1'
option enabled '1'
option service 'dynu.com'
option name 'dynu.com'
config server 'ddns_server_2'
option enabled '1'
option service 'dyndns.org'
option name 'dyndns.org'
config server 'ddns_server_3'
option enabled '1'
option service 'zoneedit.com'
option name 'zoneedit.com'

View File

@@ -1,26 +0,0 @@
#!/bin/sh /etc/rc.common
START=80
STOP=10
USE_PROCD=1
. /usr/lib/ddnsmngr/ddnsmngr_service.sh
start_service() {
start_ddnsmngr_service
}
stop_service() {
stop_ddnsmngr_service
}
reload_service() {
stop
sleep 1
start
}
service_triggers() {
procd_add_reload_trigger ddnsmngr
add_ddnsmngr_triggers
}

View File

@@ -1,170 +0,0 @@
#!/bin/sh
. /lib/functions.sh
cl_id=1
srv_id=1
function get_ddns_config_option() {
local val
val="$(uci -q get ddns.${1}.${2})"
if [ -z "${val}" ] && [ -n "${3}" ]; then
val="${3}"
fi
echo "${val}"
}
function config_supported_service() {
if ! uci -q get ddnsmngr.global >/dev/null 2>&1; then
uci -q set ddnsmngr.global="ddnsmngr"
fi
servers=""
for i in $(find /etc/ddnsmngr/servers/ -name '*.json' | cut -d'/' -f 5 | sed "s/.json//")
do
if [ -z "${servers}" ]; then
servers="${i}"
else
servers="${servers},${i}"
fi
done
uci -q set ddnsmngr.global.supported_services="${servers}"
}
function migrate_service_section() {
client_sec=""
enabled="$(get_ddns_config_option ${1} enabled "0")"
service_name="$(get_ddns_config_option ${1} service_name)"
interface="$(get_ddns_config_option ${1} interface)"
ip_network="$(get_ddns_config_option ${1} ip_network)"
username="$(get_ddns_config_option ${1} username)"
password="$(get_ddns_config_option ${1} password)"
lookup_host="$(get_ddns_config_option ${1} lookup_host)"
use_ipv6="$(get_ddns_config_option ${1} use_ipv6 "0")"
force_ipversion="$(get_ddns_config_option ${1} force_ipversion "0")"
use_https="$(get_ddns_config_option ${1} use_https "0")"
force_dnstcp="$(get_ddns_config_option ${1} force_dnstcp "0")"
if [ -z "${service_name}" ]; then
uci -q delete ddns."${1}"
return 0
fi
# check server file is present in device
if [ ! -f "/etc/ddnsmngr/servers/${service_name}.json" ]; then
uci -q delete ddns."${1}"
return 0
fi
# Check if client section is already added for this service
clients=$(uci -q show ddnsmngr | grep "=client")
client_count=$(echo "${clients}" | wc -l)
tmp=0
while [ $tmp -lt $client_count ]
do
mngr_serv="$(uci -q get ddnsmngr.@client[$tmp].service_name)"
mngr_intf="$(uci -q get ddnsmngr.@client[$tmp].interface)"
mngr_netw="$(uci -q get ddnsmngr.@client[$tmp].ip_network)"
mngr_user="$(uci -q get ddnsmngr.@client[$tmp].username)"
mngr_ipv6="$(uci -q get ddnsmngr.@client[$tmp].use_ipv6)"
mngr_forceip="$(uci -q get ddnsmngr.@client[$tmp].force_ipversion)"
mngr_https="$(uci -q get ddnsmngr.@client[$tmp].use_https)"
mngr_dnstcp="$(uci -q get ddnsmngr.@client[$tmp].force_dnstcp)"
[ -z "${mngr_ipv6}" ] && mngr_ipv6="0"
[ -z "${mngr_forceip}" ] && mngr_forceip="0"
[ -z "${mngr_https}" ] && mngr_https="0"
[ -z "${mngr_dnstcp}" ] && mngr_dnstcp="0"
if [ "${mngr_serv}" == "${service_name}" ] && [ "${mngr_intf}" == "${interface}" ] && \
[ "${mngr_netw}" == "${ip_network}" ] && [ "${mngr_user}" == "${username}" ] && \
[ "${mngr_ipv6}" == "${use_ipv6}" ] && [ "${mngr_forceip}" == "${force_ipversion}" ] && \
[ "${mngr_https}" == "${use_https}" ] && [ "${mngr_dnstcp}" == "${force_dnstcp}" ]; then
break
fi
tmp=$(( tmp + 1 ))
done
if [ $tmp -ne $client_count ]; then
i=0
for client in $clients; do
if [ $i -eq $tmp ]; then
client_sec="$(echo $client | cut -d'=' -f 1 | cut -d'.' -f 2)"
break
fi
i=$(( i + 1 ))
done
if [ $enabled -eq 1 ]; then
uci -q set ddnsmngr."${client_sec}".enabled="1"
fi
else
client_sec=ddns_mig_client_"${cl_id}"
uci -q set ddnsmngr."${client_sec}"="client"
uci -q set ddnsmngr."${client_sec}".enabled="${enabled}"
uci -q set ddnsmngr."${client_sec}".service_name="${service_name}"
uci -q set ddnsmngr."${client_sec}".interface="${interface}"
uci -q set ddnsmngr."${client_sec}".ip_network="${ip_network}"
uci -q set ddnsmngr."${client_sec}".username="${username}"
uci -q set ddnsmngr."${client_sec}".password="${password}"
uci -q set ddnsmngr."${client_sec}".use_ipv6="${use_ipv6}"
uci -q set ddnsmngr."${client_sec}".force_ipversion="${force_ipversion}"
uci -q set ddnsmngr."${client_sec}".use_https="${use_https}"
uci -q set ddnsmngr."${client_sec}".force_dnstcp="${force_dnstcp}"
cl_id=$(( cl_id + 1 ))
# add server section if not added
servers=$(uci -q show ddnsmngr | grep "service=\'${service_name}\'")
if [ -z "${servers}" ]; then
server_sec=ddns_mig_server_"${srv_id}"
uci -q set ddnsmngr."${server_sec}"="server"
uci -q set ddnsmngr."${server_sec}".enabled="1"
uci -q set ddnsmngr."${server_sec}".service="${service_name}"
uci -q set ddnsmngr."${server_sec}".name="${service_name}"
srv_id=$(( srv_id + 1 ))
fi
fi
# if lookup_host is set then add host section
if [ -n "${lookup_host}" ] && [ -n "${client_sec}" ]; then
# check number of hosts present for this client
host_count=$(uci -q show ddnsmngr | grep "dm_parent=\'${client_sec}\'" | wc -l)
host_ix=$(( host_count + 1 ))
host_sec="${client_sec}"_host_"${host_ix}"
uci -q set ddnsmngr."${host_sec}"="host"
uci -q set ddnsmngr."${host_sec}".enabled="${enabled}"
uci -q set ddnsmngr."${host_sec}".lookup_host="${lookup_host}"
uci -q set ddnsmngr."${host_sec}".dm_parent="${client_sec}"
fi
uci -q delete ddns."${1}"
}
function migrate_ddns_config() {
if [ ! -f "/etc/config/ddnsmngr" ]; then
# Create ddnsmngr config file
touch /etc/config/ddnsmngr
fi
config_supported_service
config_load ddns
config_foreach migrate_service_section service
uci -q commit ddns
uci -q commit ddnsmngr
}
migrate_ddns_config

View File

@@ -1,169 +0,0 @@
#! /bin/sh
RUNDIR="/var/run/ddnsmngr"
LOGDIR="/var/log/ddnsmngr"
PROG="/usr/lib/ddnsmngr/ddnsmngr_updater.sh"
CONFIGFILE="/var/run/ddnsmngr/ddnsmngr.json"
CLIENT_INTFS=""
. /usr/share/libubox/jshn.sh
log() {
echo "$*"|logger -t ddnsmngr.init -p debug
}
validate_host_section() {
uci_validate_section ddnsmngr host "${1}" \
'enabled:bool:0' \
'lookup_host:string' \
'dm_parent:string'
}
validate_client_section() {
uci_validate_section ddnsmngr client "${1}" \
'enabled:bool:0' \
'service_name:string' \
'interface:string' \
'ip_network:string' \
'username:string' \
'password:string' \
'use_https:bool:0' \
'force_dnstcp:bool:0' \
'use_ipv6:bool:0' \
'force_ipversion:bool:0'
}
add_object() {
local enabled lookup_host dm_parent use_ipv6 force_ipversion proc_info_file
local service_name interface ip_network username password use_https force_dnstcp
validate_host_section "${1}" || {
log "Validation of host section failed"
return 0
}
if [ "${enabled}" -ne 1 ] || [ -z "${dm_parent}" ]; then
return 0
fi
validate_client_section "${dm_parent}" || {
log "Validation of client section failed"
return 0
}
if [ "${enabled}" -ne 1 ]; then
return 0
fi
service_name=$(uci -q get ddnsmngr.${dm_parent}.service_name)
if [ -z "${service_name}" ]; then
return 0
fi
service_section=$(uci -q show ddnsmngr | grep "service=\'${service_name}\'" | cut -d'.' -f 2 | head -1)
if [ -z "${service_section}" ]; then
return 0
fi
service_enabled=$(uci -q get ddnsmngr.${service_section}.enabled)
if [ "${service_enabled}" -ne 1 ]; then
return 0
fi
json_add_object
json_add_string "interface" "${interface}"
json_add_string "service_name" "${service_name}"
json_add_string "username" "${username}"
json_add_string "password" "${password}"
json_add_string "lookup_host" "${lookup_host}"
json_add_string "ip_network" "${ip_network}"
json_add_string "proc_info_file" "${1}"
json_add_string "use_ipv6" "${use_ipv6}"
json_add_string "force_ipversion" "${force_ipversion}"
json_add_string "use_https" "${use_https}"
json_add_string "force_dnstcp" "${force_dnstcp}"
json_close_object
if [ -z "${interface}" ]; then
if [ "${use_ipv6}" -eq 0 ]; then
interface="wan"
else
interface="wan6"
fi
fi
for intf in $CLIENT_INTFS; do
if [ "${intf}" == "${interface}" ]; then
return 0
fi
done
CLIENT_INTFS="${CLIENT_INTFS} ${interface}"
}
start_ddnsmngr_service() {
run_dir=$(uci -q get ddnsmngr.global.ddns_rundir)
log_dir=$(uci -q get ddnsmngr.global.ddns_logdir)
if [ -n "${run_dir}" ]; then
RUNDIR="${run_dir}"
fi
if [ -n "${log_dir}" ]; then
LOGDIR="${log_dir}"
fi
mkdir -p "${RUNDIR}"
mkdir -p "${LOGDIR}"
conf_file=$(uci -q get ddnsmngr.global.configfile)
if [ -n "${conf_file}" ]; then
CONFIGFILE="${conf_file}"
fi
touch "${CONFIGFILE}"
if [ ! -f "${CONFIGFILE}" ]; then
log "Can not create ${CONFIGFILE}, exit"
exit 0
fi
json_init
json_add_array "services"
config_load ddnsmngr
config_foreach add_object host
json_close_array
json_dump > "${CONFIGFILE}"
procd_open_instance ddnsmngr
procd_set_param command "$PROG"
procd_append_param command -c "${CONFIGFILE}"
procd_append_param command -- start
procd_close_instance
}
stop_ddnsmngr_service() {
conf_file=$(uci -q get ddnsmngr.global.configfile)
if [ -n "${conf_file}" ]; then
CONFIGFILE="${conf_file}"
fi
if [ ! -f "${CONFIGFILE}" ]; then
log "${CONFIGFILE} not found, can't stop services if running any"
fi
"$PROG" -c "${CONFIGFILE}" -- stop
return 0
}
add_ddnsmngr_triggers() {
procd_open_trigger
for intf in $CLIENT_INTFS; do
# No need to handle other ifevents like ifupdate etc
procd_add_interface_trigger "interface.*.up" $intf /etc/init.d/ddnsmngr restart
procd_add_interface_trigger "interface.*.down" $intf /etc/init.d/ddnsmngr restart
done
procd_close_trigger
}

View File

@@ -1,311 +0,0 @@
#!/bin/sh
PROG="/usr/sbin/inadyn"
CONFIGPATH="/tmp/inadyn_config"
PIDPATH="/etc/inadyn_pid"
CLIENT_INTFS=""
CONFIG_FILES=""
SERVER_PATH="/etc/ddnsmngr/servers"
FORMAT="custom [SECTION] {\n\tusername\t= [USER]\n\tpassword\t= [PWD]\n\tddns-server\t= [SERV]\n\tddns-path\t= [URI]\n\tssl\t\t= [SSL]\n\thostname\t= [NAME]\n\tcheckip-command\t= [CMD]\n\tddns-response\t= [RESPONSES]\n}"
. /usr/share/libubox/jshn.sh
log() {
echo "$*"|logger -t ddnsmngr.init -p debug
}
get_service_data() {
local provider="$1"
shift
local dir="$1"
shift
local ipv6="$1"
shift
local name data url answer script
[ $# -ne 2 ] && {
return 1
}
[ -f "${dir}/${provider}.json" ] || {
eval "$1=\"\""
eval "$2=\"\""
return 1
}
json_load_file "${dir}/${provider}.json"
json_get_var name "name"
if [ "$ipv6" -eq "1" ]; then
json_select "ipv6"
else
json_select "ipv4"
fi
json_get_var data "url"
json_get_var answer "answer"
json_select ".."
json_cleanup
response=""
if [ -n "${answer}" ]; then
answer=$(echo "${answer}" | sed 's/|/ /g')
for ans in $answer; do
if [ -z "${response}" ]; then
response="${ans}"
else
response="${response}, ${ans}"
fi
done
response="{ ${response} }"
fi
eval "$1=\"$data\""
eval "$2=\"$response\""
return 0
}
generate_inadyn_config() {
json_load "${1}"
json_get_var service_name service_name
json_get_var use_ipv6 use_ipv6
json_get_var interface interface
json_get_var username username
json_get_var password password
json_get_var host lookup_host
json_get_var conf_file config_file
json_get_var conf_dir config_dir
json_get_var server_address server_address
json_cleanup
if [ -z "${service_name}" ] || [ -z "${host}" ]; then
return 1
fi
if [ -z "${conf_file}" ]; then
return 1
fi
if [ -z "${conf_dir}" ]; then
return 1
fi
# First look into custom path to load the url otherwise default path
get_service_data "${service_name}" "${SERVER_PATH}" "${use_ipv6}" server_url server_answer
if [ -z "${server_url}" ]; then
return 1
fi
# Need to pick proto, server address and request uri separately from the url
# format http://[server_address]/[update_Request_uri]
proto=$(echo $server_url | cut -d':' -f 1)
serv=$(echo $server_url | cut -d'/' -f 3 | cut -d'@' -f 2)
uri=${server_url#*$serv}
if [ -z $proto ] || [ -z $serv ] || [ -z $uri ]; then
return 1
fi
path=$(echo "$uri" | sed 's/&/\\&/g')
update_uri=$(echo $path | sed -e "s#\[DOMAIN\]#%h#g" -e "s#\[PASSWORD\]#%p#g" \
-e "s#\[USERNAME\]#%u#g" -e "s#\[IP\]#%i#g")
if [ -z "${interface}" ]; then
if [ "${use_ipv6}" -eq 0 ]; then
interface="wan"
else
interface="wan6"
fi
fi
# now get the physical interface name
intf=$(ifstatus "${interface}" | jsonfilter -e '@.device')
if [ -z "${intf}" ]; then
return 1
fi
# command to get ip of the interface
if [ "${use_ipv6}" -eq 0 ]; then
get_ip="\"ifstatus ${interface} | jsonfilter -e '@[\\\\\"ipv4-address\\\\\"][0].address'\""
else
get_ip="\"ifstatus ${interface} | jsonfilter -e '@[\\\\\"ipv6-address\\\\\"][0].address'\""
fi
if [ "${proto}" = "http" ]; then
ssl="false"
else
ssl="true"
fi
inadyn_ver=$(inadyn -v)
user_agent="inadyn/${inadyn_ver}"
config_file="${conf_dir}/${conf_file}"
touch "${config_file}"
echo "iface = ${intf}" > "${config_file}"
echo "period = 600" >> "${config_file}"
echo "user-agent = ${user_agent}" >> "${config_file}"
if [ "${use_ipv6}" -eq 1 ]; then
echo "allow-ipv6 = true" >> "${config_file}"
fi
if [ -z "${password}" ]; then
FORMAT=$(echo "${FORMAT}" | sed 's/\\tpassword\\t= \[PWD\]\\n//g')
fi
if [ -z "${server_answer}" ]; then
FORMAT=$(echo "${FORMAT}" | sed 's/\\tddns-response\\t= \[RESPONSES\]\\n//g')
fi
config=$(echo $FORMAT | sed -e "s#\[SECTION\]#$conf_file#g" -e "s#\[PWD\]#$password#g" \
-e "s#\[USER\]#$username#g" -e "s#\[SERV\]#$serv#g" \
-e "s#\[URI\]#\"$update_uri\"#g" -e "s#\[SSL\]#$ssl#g" \
-e "s#\[NAME\]#$host#g" -e "s#\[CMD\]#$get_ip#g" \
-e "s#\[RESPONSES\]#$server_answer#g")
echo -e "\n\n${config}" >> "${config_file}"
return 0
}
validate_host_section() {
uci_validate_section ddnsmngr host "${1}" \
'enabled:bool:0' \
'lookup_host:string' \
'dm_parent:string'
}
validate_client_section() {
uci_validate_section ddnsmngr client "${1}" \
'enabled:bool:0' \
'service_name:string' \
'interface:string' \
'ip_network:string' \
'username:string' \
'password:string' \
'use_https:bool:0' \
'force_dnstcp:bool:0' \
'use_ipv6:bool:0' \
'force_ipversion:bool:0'
}
add_object() {
local enabled lookup_host dm_parent use_ipv6 force_ipversion
local service_name interface ip_network username password use_https force_dnstcp
validate_host_section "${1}" || {
log "Validation of host section failed"
return
}
if [ "${enabled}" -ne 1 ] || [ -z "${dm_parent}" ]; then
return
fi
validate_client_section "${dm_parent}" || {
log "Validation of client section failed"
return
}
if [ "${enabled}" -ne 1 ]; then
return
fi
service_name=$(uci -q get ddnsmngr.${dm_parent}.service_name)
if [ -z "${service_name}" ]; then
return
fi
service_section=$(uci show ddnsmngr | grep "service=\'${service_name}\'" | cut -d'.' -f 2 | head -1)
if [ -z "${service_section}" ]; then
return
fi
service_enabled=$(uci -q get ddnsmngr.${service_section}.enabled)
if [ "${service_enabled}" -ne 1 ]; then
return
fi
json_init
json_add_string "interface" "${interface}"
json_add_string "service_name" "${service_name}"
json_add_string "username" "${username}"
json_add_string "password" "${password}"
json_add_string "lookup_host" "${lookup_host}"
json_add_string "ip_network" "${ip_network}"
json_add_string "use_ipv6" "${use_ipv6}"
json_add_string "force_ipversion" "${force_ipversion}"
json_add_string "use_https" "${use_https}"
json_add_string "force_dnstcp" "${force_dnstcp}"
json_add_string "config_file" "${1}"
json_add_string "config_dir" "${CONFIGPATH}"
json_str=$(json_dump)
json_cleanup
generate_inadyn_config "${json_str}"
if [ "$?" -ne 0 ]; then
return
fi
CONFIG_FILES="${CONFIG_FILES} ${1}"
if [ -z "${interface}" ]; then
if [ "${use_ipv6}" -eq 0 ]; then
interface="wan"
else
interface="wan6"
fi
fi
for intf in $CLIENT_INTFS; do
if [ "${intf}" == "${interface}" ]; then
return
fi
done
CLIENT_INTFS="${CLIENT_INTFS} ${interface}"
}
start_ddnsmngr_service() {
rm -rf $CONFIGPATH
mkdir $CONFIGPATH
mkdir -p $PIDPATH
config_load ddnsmngr
config_foreach add_object host
i=1
for conf in $CONFIG_FILES; do
instance="ddnsmngr_${i}"
i=$(( i + 1 ))
procd_open_instance $instance
procd_set_param command "$PROG"
procd_append_param command -f "${CONFIGPATH}/${conf}"
procd_append_param command -l debug
procd_append_param command -P "${PIDPATH}/${conf}"
procd_append_param command -n -C
procd_close_instance
done
}
stop_ddnsmngr_service() {
rm -rf $CONFIGPATH
return 0
}
add_ddnsmngr_triggers() {
procd_open_trigger
for intf in $CLIENT_INTFS; do
# No need to handle other ifevents like ifupdate etc
procd_add_interface_trigger "interface.*.up" $intf /etc/init.d/ddnsmngr restart
done
procd_close_trigger
}

View File

@@ -2,6 +2,6 @@ menu "Configuration"
config DECOLLECTOR_EASYMESH_VERSION
int "Support Easymesh version"
default 6
default 4
endmenu

View File

@@ -1,23 +1,22 @@
#
# Copyright (C) 2021-2024 IOPSYS Software Solutions AB
# Copyright (C) 2025 Genexis AB
# Copyright (C) 2021-2023 IOPSYS Software Solutions AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=decollector
PKG_VERSION:=6.2.1.7
PKG_VERSION:=4.2.1.1
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=ca92325ece080389ffb405c95048b64071eda653
PKG_SOURCE_VERSION:=ae836adb0779979686d0dad34b941f319ffed1b8
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/decollector.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@genexis.eu>
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
PKG_LICENSE:=BSD-3-Clause
@@ -30,7 +29,7 @@ define Package/decollector
CATEGORY:=Utilities
TITLE:=WiFi DataElements Collector Proxy
DEPENDS:=+libuci +libubox +ubus +libpthread +libnl-genl \
+libeasy +libwifiutils +libieee1905 +ieee1905-map-plugin
+libeasy +libwifiutils +libieee1905 +map-plugin
endef
define Package/decollector/description

View File

@@ -2,13 +2,13 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=dectmngr
PKG_RELEASE:=3
PKG_VERSION:=3.7.10
PKG_VERSION:=3.6.4
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/dectmngr.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=1f851980a6ba616df54f79930225f8bcd563b711
PKG_SOURCE_VERSION:=d9cc11c81ce1ff625e4e789afa180b301c7fcf74
PKG_MIRROR_HASH:=skip
endif
@@ -28,7 +28,7 @@ include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
CATEGORY:=Utilities
TITLE:=DECT Manager
DEPENDS:= +libubox +ubus +uci +libxml2 +libjson-c +gpiod-tools +voicemngr
DEPENDS:= +libubox +ubus +uci +libxml2 +libjson-c +gpiod-tools
endef
define Package/$(PKG_NAME)/description
@@ -56,14 +56,11 @@ endif
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/dspg
$(INSTALL_DIR) $(1)/etc
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/app/dectmngr $(1)/usr/sbin/
$(STRIP) $(1)/usr/sbin/dectmngr
ifeq ($(CONFIG_TARGET_airoha),)
$(CP) ./firmware/common/* $(1)/etc/dspg/
endif
$(CP) ./files/etc/* $(1)/etc/
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/dect $(1)/lib/upgrade/keep.d/dect
endef

View File

@@ -1,6 +1,3 @@
config dect 'global'
option log_dect_cmbs 'syslog'
option log_level 'realtime,warning,error'
config dect 'base'
option enable '1'
option log_dect_cmbs 'syslog'
option log_level 'realtime,warning,error'

View File

@@ -11,24 +11,7 @@ LOG_PATH=/var/log/dectmngr
DB_PATH=/etc/dect
DCX81_UART_DT_ALIAS=/proc/device-tree/aliases/dcx81-uart
get_extension_shift() {
local dect_exts
get_dect_extension() {
local ext=$1
local type
config_get type $ext type
[ "$type" == "dect" ] && echo $ext
}
config_load "asterisk"
dect_exts=$(config_foreach get_dect_extension "extension" |sort |head -n1)
echo "${dect_exts#extension}"
}
DECT_GPIO="$(gpiofind DCX81_RSTN | cut -d ' ' -f 2 2>/dev/null)"
# Ask dectmngr to exit nicely and wait for it to clean up, which is a slow process.
stop_and_wait_dectmngr() {
@@ -57,53 +40,13 @@ get_dcx81_device() {
device_name_line="$(grep '^DEVNAME=' "$uevent_file")" || return 1
readonly device="/dev/${device_name_line##DEVNAME=}"
[ -c "$device" ] || return 1
printf "%s" "$(basename $device)"
printf "%s" "$device"
return 0
fi
done
return 1
}
check_dcx81_firmware() {
local dcx81_uart=$1
local fw_link="/lib/firmware/dcx81_firmware"
local fw_file
[ -L "$fw_link" ] || return
fw_file=$(readlink -f $fw_link)
[ -f "$fw_file" ] || return
# the symbolic link is not needed
rm -f $fw_link
eval $(/sbin/cmbs_tcx -comname "$dcx81_uart" -fw_version |grep DCX81_FW_Version)
[ -n "$DCX81_FW_Version" ] || return
if echo $(basename $fw_file) | grep -qi "$DCX81_FW_Version" ; then
logger -t "$PROG" "DCX81 running expected $DCX81_FW_Version"
return;
fi
logger -t "$PROG" "DCX81 firmware upgrading to $fw_file"
/sbin/cmbs_tcx -comname "$dcx81_uart" -fwu "$fw_file" 2>&1 >/dev/null &
echo -n "Updrading DCX81 firmware.." >/dev/console
local wait_time=0
while pidof cmbs_tcx >/dev/null && [ "$wait_time" -lt "200" ] ; do
sleep 5
wait_time=$(($wait_time + 5))
echo -n "." >/dev/console
done
if pidof cmbs_tcx >/dev/null ; then
killall -9 cmbs_tcx
logger -t "$PROG" "DCX81 firmware upgrade timeout"
else
logger -t "$PROG" "DCX81 firmware upgrade done"
fi
}
start_service() {
local opt_ext=
local rfpi=
@@ -118,12 +61,10 @@ start_service() {
local dcx81_uart_device
if ! dcx81_uart_device="$(get_dcx81_device)"; then
logger -t "$PROG" -p daemon.warning "Could not determine DCX81 UART device. Falling back to default ttyH0."
dcx81_uart_device="ttyH0"
dcx81_uart_device=/dev/ttyH0
fi
check_dcx81_firmware $dcx81_uart_device
opt_ext="-extensionShift $(get_extension_shift)"
[ -n "$DECT_GPIO" ] && echo 1 > /sys/class/gpio/gpio${DECT_GPIO}/value
rfpi=$(db -q get hw.board.dect_rfpi)
[ -n "$rfpi" -a ${#rfpi} -eq 14 ] && opt_ext="$opt_ext -rfpi $rfpi"
@@ -140,27 +81,24 @@ start_service() {
config_load dect
config_get log_dect_cmbs global log_dect_cmbs syslog
config_get pcm_slot_start global pcm_slot_start
config_get pcm_fsync global pcm_fsync
[ -n "$pcm_fsync" ] && opt_ext="$opt_ext -sync $pcm_fsync"
[ -n "$pcm_slot_start" ] && opt_ext="$opt_ext -slotsShift $pcm_slot_start"
procd_open_instance
# dectmngr takes expects device without /dev
readonly dcx81_uart_device_wo_dev="${dcx81_uart_device##/dev/}"
case "$log_dect_cmbs" in
none)
echo "Starting dectmngr with cmbs logging disabled"
procd_set_param command "$PROG" -comname "$dcx81_uart_device" $opt_ext
procd_set_param command "$PROG" -comname "$dcx81_uart_device_wo_dev" $opt_ext
rm -f $LOG_PATH/*
;;
file)
echo "Starting dectmngr with cmbs logging enabled to file"
procd_set_param command "$PROG" -comname "$dcx81_uart_device" -log $LOG_PATH/dect-cmbs.log $opt_ext
procd_set_param command "$PROG" -comname "$dcx81_uart_device_wo_dev" -log $LOG_PATH/dect-cmbs.log $opt_ext
;;
*)
echo "Starting dectmngr with cmbs logging enabled to syslog"
procd_set_param command "$PROG" -comname "$dcx81_uart_device" -syslog $opt_ext
procd_set_param command "$PROG" -comname "$dcx81_uart_device_wo_dev" -syslog $opt_ext
rm -f $LOG_PATH/*
;;
esac
@@ -174,6 +112,7 @@ start_service() {
stop_service() {
has_dect || return 0
[ -n "$DECT_GPIO" ] && echo 0 > /sys/class/gpio/gpio${DECT_GPIO}/value
stop_and_wait_dectmngr
}
@@ -187,6 +126,11 @@ service_triggers() {
}
boot() {
[ -n "$DECT_GPIO" ] && {
echo ${DECT_GPIO} > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio${DECT_GPIO}/direction
}
[ ! -d $LOG_PATH ] && mkdir -p $LOG_PATH
[ ! -d $DB_PATH ] && mkdir -p $DB_PATH
start

View File

@@ -1,59 +0,0 @@
#
# Copyright (C) 2024 IOPSYS Software Solutions AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dhcpmngr
PKG_VERSION:=1.0.6
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/dhcpmngr.git
PKG_SOURCE_VERSION:=986f66608959f4f589009d580b046e250d8c620d
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include ../bbfdm/bbfdm.mk
MAKE_PATH:=src
define Package/dhcpmngr
SECTION:=net
CATEGORY:=Network
TITLE:=Package to add Device.DHCPv4 and v6 data model support.
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service
DEPENDS+=+DNSMNGR_DNS_SD:umdns
DEPENDS+=+DNSMNGR_BACKEND_DNSMASQ:dnsmasq
DEPENDS+=+DNSMNGR_BACKEND_UNBOUND:odhcpd
endef
define Package/dhcpmngr/description
Package to add Device.DHCPv4. and Device.DHCPv6. data model support.
endef
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -rf ~/git/dhcpmngr/* $(PKG_BUILD_DIR)/
endef
endif
define Package/dhcpmngr/install
$(INSTALL_DIR) $(1)/etc/udhcpc.user.d
$(INSTALL_BIN) ./files/etc/udhcpc.user.d/udhcpc_lease_start_time.user $(1)/etc/udhcpc.user.d/udhcpc_lease_start_time.user
ifeq ($(CONFIG_DNSMNGR_BACKEND_UNBOUND),y)
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DATA) ./files/etc/uci-defaults/unbound.odhcpd.uci_default $(1)/etc/uci-defaults/16-set-unbound-as-odhcpd-leasetrigger
endif
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/src/libdhcpmngr.so $(1) $(PKG_NAME)
endef
$(eval $(call BuildPackage,dhcpmngr))

View File

@@ -1,20 +0,0 @@
{
"daemon": {
"enable": "1",
"service_name": "dhcpmngr",
"unified_daemon": false,
"services": [
{
"parent_dm": "Device.",
"object": "DHCPv4"
},
{
"parent_dm": "Device.",
"object": "DHCPv6"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -1,17 +0,0 @@
#!/bin/sh
# update odhcpd uci to use unbound's script as leasetrigger
uci -q get dhcp.odhcpd >/dev/null 2>&1 && {
maindhcp="$(uci -q get dhcp.odhcpd.maindhcp)"
# if odhcpd is the main dhcp
[ "$maindhcp" = "1" ] || [ "$maindhcp" = "true" ] || [ "$maindhcp" = "on" ] && {
# if unbound daemon and unbound script file is present
[ -e /usr/lib/unbound/odhcpd.sh ] && [ -e /usr/sbin/unbound ] && {
# then set unbound script as leasetrigger in dhcp UCI
uci -q set dhcp.odhcpd.leasetrigger='/usr/lib/unbound/odhcpd.sh'
}
}
}
exit 0

View File

@@ -1,14 +0,0 @@
#!/bin/sh
leasestarttime="$(awk -F'.' '{print $1}' /proc/uptime 2> /dev/null)"
target_file=/tmp/dhcp_client_info
target_str="$INTERFACE $lease $leasestarttime"
# if this interface is present in file, then replace it
if grep -q "$INTERFACE" "$target_file" 2> /dev/null; then
# replace the whole line if pattern matches
sed -i "/${INTERFACE}/c\\${target_str}" "$target_file"
else
# interface info was not present, append it to the file
echo "$target_str" >> "$target_file"
fi

Binary file not shown.

View File

@@ -1,76 +0,0 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
include $(TOPDIR)/rules.mk
PKG_NAME:=datamodels
PKG_VERSION:=1.0.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Genexis
TITLE:=GeneOS Datamodel
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/$(PKG_NAME)/description
This package contains GeneOS datamodel.
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) -rf ./src/* $(PKG_BUILD_DIR)/
cd $(PKG_BUILD_DIR); \
npm install better-sqlite3 quickjs && \
node ./scripts/json2code.js && \
node ./scripts/qjs-handlers-validate.js
endef
TARGET_CFLAGS += $(FPIC) -I$(PKG_BUILD_DIR)
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)\
PROJECT_ROOT="$(PKG_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
all
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/dm_types.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/dm_node.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/dm.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libdm.so $(1)/usr/lib/
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/bbfdm
$(INSTALL_DIR) $(1)/usr/lib/dmf_handlers
$(INSTALL_BIN) $(PKG_BUILD_DIR)/default.db $(1)/etc/bbfdm/default_dm.db
$(INSTALL_BIN) $(PKG_BUILD_DIR)/libdm.so $(1)/usr/lib/
# Copy only .js handler files recursively, preserving folder structure (skip hidden files/folders)
( cd $(PKG_BUILD_DIR)/dm-files; \
find . -type d -not -path './.*' -exec $(INSTALL_DIR) $(1)/usr/lib/dmf_handlers/{} \; ; \
find . -type f -name '*.js' -not -path './.*' -exec $(INSTALL_BIN) {} $(1)/usr/lib/dmf_handlers/{} \; )
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,41 +0,0 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
PROG = libdm.so
SRCS = dm_node.c
# the next files are generated
SRCS += dm.c
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
CC = $(CROSS_COMPILE)gcc
STRIP = $(CROSS_COMPILE)strip
CFLAGS = -I$(STAGING_DIR)/usr/include $(EXTRA_CFLAGS)
CFLAGS += -MMD -MP
LDFLAGS = -shared
CFLAGS += -Wall -Werror -fpic
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $^ $(LDFLAGS) -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $^ -o $@
clean:
rm -f $(PROG) *.o core $(DEPS) dm.c dm.h
-include $(DEPS)

View File

@@ -1,443 +0,0 @@
[
{
"object": "Device.Bridging.",
"access": "readOnly",
"parameters": [
{
"name": "MaxBridgeEntries",
"access": "readOnly",
"dataType": "unsignedInt",
"const" : "4094"
},
{
"name": "MaxDBridgeEntries",
"access": "readOnly",
"dataType": "unsignedInt",
"const" : "4094"
},
{
"name": "MaxQBridgeEntries",
"access": "readOnly",
"dataType": "unsignedInt",
"const" : "4094"
},
{
"name": "MaxVLANEntries",
"access": "readOnly",
"dataType": "unsignedInt",
"const" : "4094"
},
{
"name": "BridgeNumberOfEntries",
"access": "readOnly",
"dataType": "unsignedInt"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.",
"uniqueKeys": "Name,Alias",
"access": "readWrite",
"uci": "network.device",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean",
"uci": "enabled",
"uci-default": "true"
},
{
"name": "Name",
"access": "readOnly",
"dataType": "string(:64)",
"set_on_create": "bridge_",
"db": true
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "Status",
"access": "readOnly",
"dataType": "enum",
"enum": [
"Disabled",
"Enabled",
"Error"
],
"default": "Disabled"
},
{
"name": "Standard",
"access": "readWrite",
"dataType": "enum",
"enum": [
"802.1D-2004",
"802.1Q-2005",
"802.1Q-2011"
],
"default": "802.1Q-2011"
},
{
"name": "PortNumberOfEntries",
"access": "readOnly",
"dataType": "unsignedInt"
},
{
"name": "VLANNumberOfEntries",
"access": "readOnly",
"dataType": "unsignedInt"
},
{
"name": "VLANPortNumberOfEntries",
"access": "readOnly",
"dataType": "unsignedInt"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.STP.",
"access": "readOnly",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean",
"uci": "stp"
},
{
"name": "Status",
"access": "readOnly",
"dataType": "enum",
"enum": [
"Disabled",
"Enabled",
"Error_Misconfigured",
"Error"
],
"default": "Disabled"
},
{
"name": "Protocol",
"access": "readWrite",
"dataType": "enum",
"enum": [
"STP",
"RSTP"
]
},
{
"name": "BridgePriority",
"access": "readWrite",
"dataType": "unsignedInt(0:61440)",
"default": "32768"
},
{
"name": "HelloTime",
"access": "readWrite",
"dataType": "unsignedInt(100:1000)",
"default": "200"
},
{
"name": "MaxAge",
"access": "readWrite",
"dataType": "unsignedInt(600:4000)",
"default": "2000"
},
{
"name": "ForwardingDelay",
"access": "readWrite",
"dataType": "unsignedInt(4:30)",
"default": "15"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.Port.{i}.",
"uniqueKeys": "Alias,Name",
"access": "readWrite",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "Status",
"access": "readOnly",
"dataType": "enum",
"enum": [
"Up",
"Down",
"Unknown",
"Dormant",
"NotPresent",
"LowerLayerDown",
"Error"
],
"default": "Down"
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "Name",
"access": "readOnly",
"dataType": "string(:64)",
"set_on_create": "port_",
"db": "true",
"flags": [
"linker"
],
"js-value": "ifname"
},
{
"name": "LastChange",
"access": "readOnly",
"dataType": "unsignedInt",
"const": "0"
},
{
"name": "LowerLayers",
"access": "readWrite",
"dataType": "pathRef[]",
"pathRef": [
"Device.Bridging.Bridge.{i}.Port."
],
"js-value": "ssidPath"
},
{
"name": "ManagementPort",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "PriorityRegeneration",
"access": "readWrite",
"dataType": "unsignedInt(0:7)[]",
"default": "0,1,2,3,4,5,6,7"
},
{
"name": "{BBF_VENDOR_PREFIX}EgressPriorityRegeneration",
"access": "readWrite",
"dataType": "unsignedInt(0:7)[]"
},
{
"name": "Type",
"access": "readWrite",
"dataType": "enum",
"enum": [
"ProviderNetworkPort",
"CustomerNetworkPort",
"CustomerEdgePort",
"CustomerVLANPort",
"VLANUnawarePort"
],
"default": "CustomerVLANPort"
},
{
"name": "PVID",
"access": "readWrite",
"dataType": "int(1:4094)",
"default": "1"
},
{
"name": "TPID",
"access": "readWrite",
"dataType": "unsignedInt",
"default": "33024"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.Port.{i}.Stats.",
"access": "readOnly",
"parameters": [
{
"name": "BytesSent",
"dataType": "unsignedLong"
},
{
"name": "BytesReceived",
"dataType": "unsignedLong"
},
{
"name": "PacketsSent",
"dataType": "unsignedLong"
},
{
"name": "PacketsReceived",
"dataType": "unsignedLong"
},
{
"name": "ErrorsSent",
"dataType": "StatsCounter32"
},
{
"name": "ErrorsReceived",
"dataType": "StatsCounter32"
},
{
"name": "UnicastPacketsSent",
"dataType": "unsignedLong"
},
{
"name": "DiscardPacketsSent",
"dataType": "StatsCounter32"
},
{
"name": "DiscardPacketsReceived",
"dataType": "StatsCounter32"
},
{
"name": "MulticastPacketsSent",
"dataType": "unsignedLong"
},
{
"name": "UnicastPacketsReceived",
"dataType": "unsignedLong"
},
{
"name": "MulticastPacketsReceived",
"dataType": "unsignedLong"
},
{
"name": "BroadcastPacketsSent",
"dataType": "unsignedLong"
},
{
"name": "BroadcastPacketsReceived",
"dataType": "unsignedLong"
},
{
"name": "UnknownProtoPacketsReceived",
"dataType": "StatsCounter32"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.VLAN.{i}.",
"uniqueKeys": "Alias,VLANID",
"access": "readWrite",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "Name",
"access": "readWrite",
"dataType": "string(:64)",
"set_on_create": "vlan_"
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "VLANID",
"access": "readWrite",
"dataType": "int(0:4094)"
}
]
},
{
"object": "Device.Bridging.Bridge.{i}.VLANPort.{i}.",
"uniqueKeys": "Alias,VLAN",
"access": "readWrite",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "VLAN",
"access": "readWrite",
"dataType": "pathRef",
"pathRef": [
"Device.Bridging.Bridge.{i}.VLAN."
]
},
{
"name": "Port",
"access": "readWrite",
"dataType": "pathRef",
"pathRef": [
"Device.Bridging.Bridge.{i}.Port."
]
},
{
"name": "Untagged",
"access": "readWrite",
"dataType": "boolean"
}
]
},
{
"object": "Device.Bridging.ProviderBridge.{i}.",
"uniqueKeys": "Alias",
"access": "readWrite",
"parameters": [
{
"name": "Enable",
"access": "readWrite",
"dataType": "boolean"
},
{
"name": "Status",
"access": "readOnly",
"dataType": "enum",
"enum": [
"Disabled",
"Enabled",
"Error_Misconfigured",
"Error"
],
"default": "Disabled"
},
{
"name": "Alias",
"access": "readWrite",
"dataType": "string(:64)"
},
{
"name": "Type",
"access": "readWrite",
"dataType": "enum",
"enum": [
"S-VLAN",
"PE"
]
},
{
"name": "SVLANcomponent",
"access": "readWrite",
"dataType": "pathRef",
"pathRef": [
"Device.Bridging.Bridge."
]
},
{
"name": "CVLANcomponents",
"access": "readWrite",
"dataType": "pathRef[]",
"pathRef": [
"Device.Bridging.Bridge."
]
}
]
}
]

View File

@@ -1,166 +0,0 @@
/*
* Copyright (c) 2025 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
import {
getUciOption, getUciByType, setUci, addUci, delUci
} from '../uci.js';
import * as dm from '../dm_consts.js';
import { getBridgeDeviceType } from './common.js';
function clearUnusedDevice(oldPorts, newPorts, devices) {
oldPorts?.forEach(port => {
if (port.includes('.') && !newPorts?.includes(port)) {
const dev = devices?.find(x => x.name === port);
if (dev?.['.name']) delUci('network', dev['.name']);
}
});
}
function applyBridge(bri, ports, VLANs, VLANPorts) {
const ifnames = [];
const devices = getUciByType('network', 'device')?.filter(x => x.type !== undefined);
const portsVal = getUciOption('network', bri._key, 'ports');
if (portsVal) delUci('network', bri._key, null, 'ports');
// get ports ethernet ifnames
for (const port of ports || []) {
if (port.ManagementPort || !port.LowerLayers.includes('Ethernet.Interface') || !port.Enable) {
continue;
}
let ifname = _dm_linker_value(port.LowerLayers);
if (!ifname) {
_log_error(`ifname not found for port: ${port.LowerLayers}`);
continue;
}
// check vlan
const portPath = `Device.Bridging.Bridge.${bri['.index']}.Port.${port['.index']}`;
const vp = VLANPorts?.find(x => x.Port === portPath);
if (!vp?.VLAN) {
ifnames.push(ifname);
continue;
}
// get index of the vlan
const [, indices] = _dm_node(vp.VLAN);
const vlanIdx = indices[indices.length - 1];
const vlan = VLANs?.find(x => x['.index'] === vlanIdx);
if (!vlan || vlan.VLANID <= 0) {
ifnames.push(ifname);
continue;
}
const eth = ifname;
ifname = `${ifname}.${vlan.VLANID}`;
const dev = devices?.find(x => x.name === ifname);
let devName;
if (dev) {
devName = dev['.name'];
} else {
devName = `br_${bri['.index']}_port_${vp['.index']}`;
addUci('network', 'device', devName, {
ifname: eth,
name: ifname,
vid: vlan.VLANID,
});
}
const uciConfigs = {};
// Handle Type parameter - determine device type based on port Type or default behavior
let deviceType = '';
if (port.Type) {
deviceType = getBridgeDeviceType(port.Type);
if (deviceType) uciConfigs.type = deviceType;
} else if (!vp.Untagged) {
uciConfigs.type = '8021q';
deviceType = '8021q';
}
// Handle TPID parameter
if (port.TPID) {
// If TPID is explicitly set, use it and derive device type if needed
uciConfigs.tpid = port.TPID;
// Set device type based on TPID if not already set
if (!deviceType) {
if (port.TPID === '33024') {
uciConfigs.type = '8021q';
} else if (port.TPID === '34984') {
uciConfigs.type = '8021ad';
}
}
}
uciConfigs.disabled = vlan.Enable && vp.Enable ? '0' : '1';
uciConfigs.ingress_qos_mapping = port.PriorityRegeneration !== '0,1,2,3,4,5,6,7'
? port.PriorityRegeneration.split(',').map((p, i) => `${i}:${p}`)
: '';
uciConfigs.egress_qos_mapping = port.X_IOPSYS_EU_EgressPriorityRegeneration !== ''
? port.X_IOPSYS_EU_EgressPriorityRegeneration.split(',').map((p, i) => `${i}:${p}`)
: '';
setUci('network', devName, uciConfigs);
ifnames.push(ifname);
}
clearUnusedDevice(portsVal, ifnames, devices);
if (ifnames.length > 0) {
setUci('network', bri._key, { ports: ifnames });
}
}
export function applyDeviceBridgingBridgePort(ports, bri) {
const vlans = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_VLAN, bri['.index']);
const vlanPorts = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_VLANPORT, bri['.index']);
applyBridge(bri, ports, vlans, vlanPorts);
}
export function applyDeviceBridgingBridgeVLAN(vlans, bri) {
const ports = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_PORT, bri['.index']);
const vlanPorts = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_VLANPORT, bri['.index']);
applyBridge(bri, ports, vlans, vlanPorts);
}
export function applyDeviceBridgingBridgeVLANPort(vlanPorts, bri) {
const ports = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_PORT, bri['.index']);
const vlans = _dm_get(dm.DM_DEVICE_BRIDGING_BRIDGE_VLAN, bri['.index']);
applyBridge(bri, ports, vlans, vlanPorts);
}
export function initDeviceBridgingBridge(bri) {
setUci('network', bri._key, {
type: 'bridge',
name: bri.Name,
enabled: '0',
});
// create empty interface for the bridge
addUci('network', 'interface', `itf_${bri._key}`, {
device: bri.Name,
bridge_empty: '1',
});
}
export const filterDeviceBridgingBridge = uci => uci.type === 'bridge';
export function deinitDeviceBridgingBridge(uci) {
const ports = getUciOption('network', uci, 'ports');
ports?.forEach(port => {
if (port.includes('.')) {
const dev = getUciByType('network', 'device', { match: { name: port } });
if (dev) delUci('network', dev[0]['.name']);
}
});
}

View File

@@ -1,125 +0,0 @@
/*
* Copyright (c) 2025 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
import { getUciByType } from '../uci.js';
import { getBridgePortType, getTPIDFromDeviceType } from './common.js';
function importBridge(dev, devices, bridges) {
const briPorts = [];
const briVLAN = [];
const briVLANPort = [];
// create the management port first
briPorts.push({
Alias: `cpe-${dev.name}`,
Enable: 1,
Name: dev.name,
ManagementPort: 1,
PVID: 1,
TPID: 37120,
Type: 'CustomerVLANPort',
});
bridges.push({
Name: dev.name,
Alias: `cpe-${dev.name}`,
Enable: 1,
'Port.': briPorts,
'VLAN.': briVLAN,
'VLANPort.': briVLANPort,
_key: dev['.name'],
});
const ethPorts = devices.filter(x => x.ifname?.startsWith('eth'));
for (const portName of (dev.ports || [])) {
let portIndex = ethPorts.findIndex(x => x.ifname === portName);
if (portIndex >= 0) {
// Regular ethernet port
const ethDevice = ethPorts[portIndex];
const portType = getBridgePortType(ethDevice.type) || 'CustomerVLANPort';
const tpid = getTPIDFromDeviceType(ethDevice.type, ethDevice.tpid);
briPorts.push({
Enable: 1,
Name: ethDevice['.name'],
Alias: `cpe-${ethDevice['.name']}`,
TPID: tpid,
PVID: 1,
Type: portType,
LowerLayers: `Device.Ethernet.Interface.${portIndex + 1}`,
_key: ethDevice['.name'],
});
} else {
// vlan device
const device = devices.find(x => x.name === portName);
if (!device) {
_log_error('device not found', portName);
continue;
}
if (device.type === '8021q' || device.type === 'untagged' || device.type === '8021ad' || device.type === 'transparent') {
let vlanIndex = briVLAN.findIndex(x => x.VLANID === device.vid);
if (vlanIndex < 0) {
briVLAN.push({ Enable: 1, VLANID: device.vid });
vlanIndex = briVLAN.length;
} else {
vlanIndex += 1;
}
// Get the base ethernet device to determine the correct port index
const baseEthDevice = ethPorts.find(x => device.ifname === x.ifname);
const basePortIndex = baseEthDevice ? ethPorts.indexOf(baseEthDevice) : 0;
const portType = getBridgePortType(device.type) || 'CustomerVLANPort';
const tpid = getTPIDFromDeviceType(device.type, device.tpid);
briPorts.push({
Enable: 1,
Name: device['.name'],
Alias: `cpe-${device['.name']}`,
TPID: tpid,
PVID: device.vid,
Type: portType,
LowerLayers: `Device.Ethernet.Interface.${basePortIndex + 1}`,
_key: device['.name'],
});
briVLANPort.push({
Enable: 1,
VLAN: `Device.Bridging.Bridge.${bridges.length}.VLAN.${vlanIndex}`,
Port: `Device.Bridging.Bridge.${bridges.length}.Port.${briPorts.length}`,
Untagged: device.type === 'untagged' ? 1 : 0,
_key: device['.name'],
});
} else {
_log_error('unknown device type:', device.type);
}
}
}
if (briPorts.length > 1) {
const indexes = Array.from({ length: briPorts.length - 1 }, (v, i) => i + 2);
briPorts[0].LowerLayers = indexes.map(i => `Device.Bridging.Bridge.${bridges.length}.Port.${i}`).join(',');
}
}
export function importDeviceBridgingBridge() {
const bridges = [];
const devices = getUciByType('network', 'device');
devices?.forEach(dev => {
if (dev.type === 'bridge') {
importBridge(dev, devices, bridges);
}
});
return bridges;
}

View File

@@ -1,133 +0,0 @@
/*
* Copyright (c) 2025 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
import * as std from 'std';
import { isTrue } from '../utils.js';
import { getUciByType } from '../uci.js';
function setMgmtPortLowerLayers(bri) {
if (!bri) return 0;
const portPath = `Device.Bridging.Bridge.${bri['.index']}.Port.`;
const mgmtPort = _dm_instances(portPath, '(ManagementPort="true" OR ManagementPort=1)');
if (mgmtPort.length !== 1) return 0;
const nonMgmtPort = _dm_instances(portPath, '(ManagementPort="false" OR ManagementPort=0)');
_dm_update(`${mgmtPort[0]}.LowerLayers`, nonMgmtPort.join(','));
return 0;
}
export function changedDeviceBridgingBridgePort(bri) {
return setMgmtPortLowerLayers(bri);
}
export function changedDeviceBridgingBridgePortManagementPort(bri) {
return setMgmtPortLowerLayers(bri);
}
export function getDeviceBridgingBridgeStatus(bri) {
const enable = _dm_get(`Device.Bridging.Bridge.${bri['.index']}.Enable`);
return enable ? 'Enabled' : 'Disabled';
}
export function getDeviceBridgingBridgeSTPStatus(bri) {
const stpState = std.loadFile(`/sys/class/net/${bri.Name}/bridge/stp_state`)?.trim();
return stpState === '1' ? 'Enabled' : 'Disabled';
}
export function getDeviceBridgingBridgePortStatus(bri, port) {
if (!port['.db']) return 'Up';
const enable = _dm_get(`Device.Bridging.Bridge.${bri['.index']}.Port.${port['.index']}.Enable`);
return enable ? 'Up' : 'Down';
}
export function infoDeviceBridgingBridgePort(path, port) {
const mgmtPort = _dm_get(`${path}.ManagementPort`);
if (typeof mgmtPort === 'undefined' || mgmtPort) return;
const lower = _dm_get(`${path}.LowerLayers`);
if (lower) {
port.ifname = _dm_linker_value(lower);
}
}
// Helper function to read network statistics
function getNetworkStat(port, statName) {
return std.loadFile(`/sys/class/net/${port.ifname}/statistics/${statName}`)?.trim();
}
export const getDeviceBridgingBridgePortStatsBytesSent = (bri, port) =>
getNetworkStat(port, 'tx_bytes');
export const getDeviceBridgingBridgePortStatsBytesReceived = (bri, port) =>
getNetworkStat(port, 'rx_bytes');
export const getDeviceBridgingBridgePortStatsPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_packets');
export const getDeviceBridgingBridgePortStatsPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_packets');
export const getDeviceBridgingBridgePortStatsErrorsSent = (bri, port) =>
getNetworkStat(port, 'tx_errors');
export const getDeviceBridgingBridgePortStatsErrorsReceived = (bri, port) =>
getNetworkStat(port, 'rx_errors');
export const getDeviceBridgingBridgePortStatsDiscardPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_dropped');
export const getDeviceBridgingBridgePortStatsDiscardPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_dropped');
export const getDeviceBridgingBridgePortStatsMulticastPacketsReceived = (bri, port) =>
getNetworkStat(port, 'multicast');
export const getDeviceBridgingBridgePortStatsUnicastPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_unicast_packets');
export const getDeviceBridgingBridgePortStatsUnicastPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_unicast_packets');
export const getDeviceBridgingBridgePortStatsMulticastPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_multicast_packets');
export const getDeviceBridgingBridgePortStatsBroadcastPacketsSent = (bri, port) =>
getNetworkStat(port, 'tx_broadcast_packets');
export const getDeviceBridgingBridgePortStatsBroadcastPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_broadcast_packets');
export const getDeviceBridgingBridgePortStatsUnknownProtoPacketsReceived = (bri, port) =>
getNetworkStat(port, 'rx_unknown_packets');
export function getDeviceBridgingBridgePort(bri) {
const networkName = bri.Name.startsWith('br-') ? bri.Name.slice(3) : bri.Name;
const wifiIfaces = getUciByType('wireless', 'wifi-iface', { match: { multi_ap: '2' } });
wifiIfaces?.forEach(x => {
const ssid = getUciByType('dmmap_wireless', 'ssid',
{ match: { device: x.device, ssid: x.ssid}, confdir: '/etc/bbfdm/dmmap'});
if (Array.isArray(ssid) && ssid.length > 0) {
x.ssidPath = _dm_linker_path("Device.WiFi.SSID.", "Name", ssid[0].name) ?? '';
}
});
return wifiIfaces?.filter(x => x.network === networkName);
}
export function setDeviceBridgingBridgePortManagementPort(val, bri, port) {
if (isTrue(val)) {
_db_set(`Device.Bridging.Bridge.${bri['.index']}.Port.${port['.index']}.Name`, bri.Name);
}
return 1;
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright (c) 2025 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
export const bridgePortTypeMap = [
{ portType: 'CustomerNetworkPort', devType: '8021ad' },
{ portType: 'CustomerVLANPort', devType: '8021q' },
{ portType: 'CustomerVLANPort', devType: 'untagged' },
{ portType: 'CustomerVLANPort', devType: '' },
{ portType: 'CustomerVLANPort', devType: undefined },
{ portType: 'VLANUnawarePort', devType: 'transparent' }
];
export function getBridgePortType(devType) {
const mapping = bridgePortTypeMap.find(map => map.devType === devType);
return mapping ? mapping.portType : null;
}
export function getBridgeDeviceType(portType) {
const mapping = bridgePortTypeMap.find(map => map.portType === portType);
return mapping ? mapping.devType : null;
}
export function getDefaultTPID(deviceType) {
switch (deviceType) {
case '8021q':
return '33024';
case '8021ad':
return '34984';
default:
return '37120';
}
}
export function getTPIDFromDeviceType(deviceType, explicitTPID) {
// If explicit TPID is set, use it
if (explicitTPID && explicitTPID !== '') {
return parseInt(explicitTPID, 10);
}
// Default TPID based on device type
switch (deviceType) {
case '8021q':
return 33024;
case '8021ad':
return 34984;
case 'untagged':
case 'transparent':
case '':
case undefined:
default:
return 37120;
}
}

View File

@@ -1,126 +0,0 @@
/* eslint-disable no-undef */
/*
* Wrapper around the native QuickJS C binding `_uci_call` which speaks to
* libuci directly (see qjs_uci_api.c). The exported helpers mimic the public
* API of the original uci.js module so that existing call-sites can switch to
* this implementation by simply importing uci2.js.
*/
export function uciBool(val) {
// by default enable is true if it is not defined
return (val === undefined || val === '1' || val === 'true' || val === 'enable' || val === 'yes');
}
function callUci(method, args) {
const [ret, res] = _uci_call(method, args);
if (ret !== 0) {
// Returning undefined on error keeps behaviour consistent with the
// original helpers which silently return undefined.
return [ret, undefined];
}
return [ret, res];
}
export function getUci(args) {
const [, res] = callUci('get', args);
if (res) {
if (res.values) {
if (!args.section) {
return Object.values(res.values);
}
return res.values;
}
if (res.value !== undefined) {
return res.value;
}
}
return undefined;
}
export function getUciOption(config, section, option, extraArgs) {
let args = { config, section, option };
if (extraArgs) {
args = { ...args, ...extraArgs };
}
return getUci(args);
}
export function getUciByType(config, type, extraArgs) {
let args = { config, type };
if (extraArgs) {
args = { ...args, ...extraArgs };
}
return getUci(args);
}
export function getUciSection(config, section, extraArgs) {
let args = { config, section };
if (extraArgs) {
args = { ...args, ...extraArgs };
}
return getUci(args);
}
export function setUci(cfg, section, values, type, match, extraArgs) {
let args = { config: cfg, section };
if (type) args.type = type;
if (values) args.values = values;
if (match) args.match = match;
if (extraArgs) args = { ...args, ...extraArgs };
const [ret] = callUci('set', args);
return ret;
}
export function addUci(cfg, type, name, values, extraArgs) {
let args = { config: cfg, type };
if (name) args.name = name;
if (values) args.values = values;
if (extraArgs) args = { ...args, ...extraArgs };
const [, res] = callUci('add', args);
return res || undefined;
}
export function delUci(cfg, section, type, option, options, match, extraArgs) {
let args = { config: cfg };
if (section) args.section = section;
if (type) args.type = type;
if (option) args.option = option;
if (options) args.options = options;
if (match) args.match = match;
if (extraArgs) args = { ...args, ...extraArgs };
const [, res] = callUci('delete', args);
return res || undefined;
}
export function delUciOption(config, section, option, match, extraArgs) {
let args = { config, section, option };
if (match) args.match = match;
if (extraArgs) args = { ...args, ...extraArgs };
const [, res] = callUci('delete', args);
return res || undefined;
}
export function uciChanges(cfg, extraArgs) {
let args = { config: cfg };
if (extraArgs) args = { ...args, ...extraArgs };
const [, res] = callUci('changes', args);
return res && res.changes ? res.changes : undefined;
}
export function commitUci(cfg, extraArgs) {
let args = { config: cfg };
if (extraArgs) args = { ...args, ...extraArgs };
const [ret] = callUci('commit', args);
return ret;
}
export function revertUci(cfg, extraArgs) {
let args = { config: cfg };
if (extraArgs) args = { ...args, ...extraArgs };
const [ret] = callUci('revert', args);
return ret;
}

View File

@@ -1,268 +0,0 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
/* eslint-disable no-undef */
/* eslint-disable no-bitwise */
import * as os from 'os';
import * as std from 'std';
export function macAddressToBase64(macAddress) {
// Split the MAC address into an array of bytes using the colon separator
const bytes = macAddress.split(':');
// Convert the bytes from hexadecimal to decimal
const decimalBytes = bytes.map((byte) => parseInt(byte, 16));
// Convert the decimal bytes into an array of 8-bit binary strings
const binaryBytes = decimalBytes.map((byte) => byte.toString(2).padStart(8, '0'));
// Concatenate the binary strings into a single string
const binaryString = binaryBytes.join('');
// Split the binary string into groups of 6 bits
const base64Chars = [];
for (let i = 0; i < binaryString.length; i += 6) {
base64Chars.push(binaryString.slice(i, i + 6));
}
// Convert each group of 6 bits to a decimal number
const decimalBase64 = base64Chars.map((char) => parseInt(char, 2));
// Create the base64 character set
const base64CharacterSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Map the decimal numbers to their corresponding base64 characters
const base64String = decimalBase64.map((num) => base64CharacterSet.charAt(num)).join('');
return base64String;
}
export function tr181Path(path, uciPath, keyName, keyVal) {
if (!keyVal) {
return '';
}
const [uciConfig, uciType] = uciPath.split('.');
const args = { config: uciConfig, type: uciType };
const [, res] = _ubus_call('uci', 'get', args);
if (!res || !res.values) {
_log_error('tr181Path: invalid result');
return '';
}
let insts = Object.values(res.values);
if (uciConfig === 'network' && uciType === 'interface') {
insts = insts.filter((x) => x.device !== 'lo' && !x.device?.startsWith('@') && x.proto !== 'dhcpv6');
}
const index = insts.findIndex((x) => x[keyName] === keyVal);
if (index < 0) {
return '';
}
if (path.startsWith('Device.')) {
return `${path}${index + 1}`;
}
return `Device.${path}${index + 1}`;
}
export function tr181IPInterface(uci) {
return tr181Path('IP.Interface.', 'network.interface', '.name', uci);
}
export function prefixLengthToSubnetMask(prefixLength) {
if (!prefixLength) {
return '';
}
const mask = 0xFFFFFFFF << (32 - prefixLength);
const subnetMask = [
(mask >>> 24) & 0xFF,
(mask >>> 16) & 0xFF,
(mask >>> 8) & 0xFF,
mask & 0xFF,
].join('.');
return subnetMask;
}
export function fileExists(path) {
let exists = false;
if (path !== '') {
// eslint-disable-next-line no-unused-vars
const [obj, err] = os.stat(path);
exists = (err === 0);
}
return exists;
}
export function waitUntilFileExists(path, timeoutMs = 10000) {
const startTime = Date.now();
while (!fileExists(path) && (Date.now() - startTime < timeoutMs)) {
os.sleep(100);
}
return fileExists(path);
}
export function runCommand(command) {
const fp = std.popen(command, 'r');
if (fp) {
const result = fp.readAsString();
if (fp.close() === 0)
return result;
else
return undefined;
}
return undefined;
}
export function fileExistsWithRegex(directory, regex) {
const [files, err] = os.readdir(directory);
if (err) {
_log_warn(`fileExistsWithRegex(): Could not read directory: ${directory}`);
}
for (let i = 0; i < files.length; i += 1) {
if (regex.test(files[i])) {
return true;
}
}
return false;
}
export function isIPv4Address(addr) {
return addr?.includes('.');
}
export function isIPv6Address(addr) {
return addr?.includes(':');
}
// find the pathname in LowerLayers
export function findPathInLowerlayer(path, inst, instKey) {
const lowerlayer = _dm_get(`${path}.LowerLayers`);
if (lowerlayer === '') {
return false;
}
if (lowerlayer.includes(instKey)) {
if (lowerlayer.includes(inst)) {
return true;
}
} else {
const layers = lowerlayer.split(',');
if (layers.find((x) => findPathInLowerlayer(x, inst, instKey))) {
return true;
}
}
return false;
}
export function hex2a(hex) {
let i = 0;
let str = '';
for (i = 0; i < hex.length; i += 2) {
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
}
return str;
}
export function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
export function lowercaseFirstLetter(string) {
return string.charAt(0).toLowerCase() + string.slice(1);
}
export function getIfnameOperState(ifname) {
if (!ifname) {
return 'Down';
}
const res = std.loadFile(`/sys/class/net/${ifname}/operstate`);
if (res) {
return capitalizeFirstLetter(res.trim());
}
return 'Down';
}
export function getIfnameState(ifname, name) {
if (!ifname) {
return '';
}
const res = std.loadFile(`/sys/class/net/${ifname}/${name}`);
return res?.trim();
}
export function strToHex(str) {
if (!str) {
return '';
}
let hex = '';
for (let i = 0; i < str.length; i += 1) {
hex += str.charCodeAt(i).toString(16);
}
return hex;
}
// transform the object of following object:
// {
// 'SSIDtoVIDMapping.1.SSID': 'abc',
// 'SSIDtoVIDMapping.1.VID': 100,
// 'SSIDtoVIDMapping.2.SSID': 'xyz',
// 'SSIDtoVIDMapping.2.VID': 200,
// Enable: 'true'
// }
// into:
// {
// SSIDtoVIDMapping: [ { SSID: 'abc', VID: 100 }, { SSID: 'xyz', VID: 200 } ],
// Enable: 'true'
// }
export function transformInputObject(obj) {
const result = {};
Object.entries(obj).forEach(([key, value]) => {
const splitKey = key.split('.');
if (splitKey.length < 3) {
result[key] = value; // add invalid keys directly to the result
return;
}
const mainKey = splitKey[0];
const index = parseInt(splitKey[1], 10) - 1;
const prop = splitKey[2];
if (!result[mainKey]) {
result[mainKey] = [];
}
if (!result[mainKey][index]) {
result[mainKey][index] = {};
}
result[mainKey][index][prop] = value;
});
return result;
}
export function isTrue(val) {
return val === 'true' || val === '1' || val === true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,290 +0,0 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DM_NODE_H
#define DM_NODE_H
#include "dm_types.h"
enum NODE_FLAG {
FLAG_NONE = 0x0,
FLAG_COUNTER = 0x40,
FLAG_HAS_MIN = 0x80,
FLAG_HAS_MAX = 0x100,
FLAG_HAS_ORDER = 0x400,
FLAG_WRITABLE = 0x800,
FLAG_CONFIDENTIAL = 0x1000,
FLAG_CWMP_ONLY = 0x4000,
FLAG_USP_ONLY = 0x8000,
FLAG_INTERNAL= 0x10000,
};
enum DM_UCI_MAP_TYPE {
DM_UCI_MAP_TYPE_NONE = 0,
DM_UCI_MAP_TYPE_SIMPLE = 0x01, // simple value 2 value
DM_UCI_MAP_TYPE_DISABLE = 0x02, // uci disable bool type
DM_UCI_MAP_TYPE_TABLE = 0x04, // a JSON object is used for mapping, {uci: dm}
DM_UCI_MAP_TYPE_INTERFACE = 0x08, // ip interface
DM_UCI_MAP_TYPE_JS = 0x10, // js code
};
struct dm_uci_map {
unsigned int type;
const char *map;
const char *key;
};
struct dm_node_info {
enum DM_NODE_TYPE type;
dm_node_id_t node_id;
const char *const name;
const struct dm_node_info *const parent;
const char *const table_name; // if NULL the value is not stored in the database
const char *pathname;
enum NODE_FLAG flag;
dm_node_id_t depends_node_id;
};
struct dm_parameter {
struct dm_node_info node;
enum DM_DATA_TYPE data_type;
long min;
long max;
int list;
union {
// for enum data type
const char **enum_strings;
// for counter data type
dm_node_id_t counter_object;
// for path data type
const dm_node_id_t *paths;
} data;
const char *set_on_create;
const char *js_val;
const char *const_val;
const char *default_val;
const char *default_uci_val;
struct dm_uci_map map;
};
struct command_arg {
const char *name;
enum DM_DATA_TYPE type;
int min;
int max;
int list;
const char **enum_values;
int mandatory;
};
struct dm_command {
struct dm_node_info node;
int async;
const struct command_arg *inputs;
int inputs_cnt;
const struct command_arg *outputs;
int outputs_cnt;
};
struct event_arg {
const char *name;
enum DM_DATA_TYPE type;
};
struct dm_event {
struct dm_node_info node;
const struct event_arg *args;
int args_cnt;
const char *ubus_event;
};
struct dm_object {
struct dm_node_info node;
int param_num;
const struct dm_node_info *const *const param_list;
int command_num;
const struct dm_node_info *const *const command_list;
int object_num;
const struct dm_node_info *const *const event_list;
int event_num;
const struct dm_node_info *const *const object_list;
int paths_refs_num;
const struct dm_node_info *const *const paths_refs_list;
const char *key_param_names;
struct dm_uci_map map;
const char *js_val;
int fixed_objects;
};
const struct dm_node_info *dm_node_get_root(void);
const struct dm_node_info *dm_node_get_info(dm_node_id_t id);
/**
* This function will look up a parameter by ID
* @pre None
* @post valid dm_parameter pointer returned or NULL if error
* @param id The actual id for which we want to retrieve a
* pointer to the dm_parameter struct
* @return NULL in case id is out of range or if id does not point
* to a parameter node, a pointer to the dm_parameter struct otherwise
*/
const struct dm_parameter *dm_node_get_parameter(dm_node_id_t id);
const struct dm_command *dm_node_get_command(dm_node_id_t id);
const struct dm_event *dm_node_get_event(dm_node_id_t id);
/**
* This function will look up a command by ID
* @pre None
* @post valid dm_command pointer returned or NULL if error
* @param id The actual id for which we want to retrieve a
* pointer to the dm_parameter struct
* @return NULL in case id is out of range or if id does not point
* to a command node, a pointer to the dm_command struct otherwise
*/
const struct dm_command *dm_node_get_command(dm_node_id_t id);
/**
* This function will look up an object by ID
* @pre None
* @post valid dm_object pointer returned or NULL if error
* @param id The actual id for which we want to retrieve a
* pointer to the dm_object struct
* @return NULL in case id is out of range or if id does not point
* to an object node, a pointer to the dm_object struct otherwise
* Note that if the id points to an object list a pointer to the
* first object is returned
*/
const struct dm_object *dm_node_get_object(dm_node_id_t id);
int dm_node_is_valid(dm_node_id_t id);
int dm_node_is_parameter(dm_node_id_t id);
int dm_node_is_command(dm_node_id_t id);
int dm_node_is_event(dm_node_id_t id);
int dm_node_is_writable(dm_node_id_t id);
int dm_node_is_object(dm_node_id_t id);
int dm_node_is_objectlist(dm_node_id_t id);
int dm_node_is_counter(dm_node_id_t id);
int dm_node_is_text_type(dm_node_id_t id);
int dm_node_is_bool_type(dm_node_id_t id);
int dm_node_is_ul_type(dm_node_id_t id);
int dm_node_is_unsigned_type(dm_node_id_t id);
int dm_node_is_confidential(dm_node_id_t id);
int dm_node_is_cwmp_only(dm_node_id_t id);
int dm_node_is_usp_only(dm_node_id_t id);
int dm_node_is_internal(dm_node_id_t id);
dm_node_id_t dm_node_counter_id(dm_node_id_t id);
int dm_node_has_db(dm_node_id_t id);
const char *dm_node_object_keys(dm_node_id_t id);
int dm_node_is_fixed_objects(dm_node_id_t id);
int dm_node_max_data_size(dm_node_id_t id);
int dm_node_param_mem_size(dm_node_id_t node_id);
const char *get_param_xsd_type(enum DM_DATA_TYPE type);
const char *dm_node_name(dm_node_id_t id);
dm_node_id_t dm_node_id_parent(dm_node_id_t id);
int dm_node_parent(const dm_node_t *node, dm_node_t *parent);
// get first multi-instance parent
int dm_node_i_parent(const dm_node_t *node, dm_node_t *parent);
dm_node_id_t dm_node_i_parent_id(const dm_node_id_t id);
int dm_node_index_cnt(dm_node_id_t id);
enum DM_DATA_TYPE dm_node_data_type(dm_node_id_t id);
dm_node_id_t dm_node_get_apply_depends(dm_node_id_t id);
dm_node_id_t dm_node_get_extends(dm_node_id_t id);
/*
Get the full name of a node.
@param node[in] Node ID whose name we want to retrieve
@param name[out] Location where the node name is written
@param name_len[in] Amount of space available in name
@return 0 in case of success, -1 in case of failure
*/
int dm_node2name(const dm_node_t *node, char *name, int name_len);
int dm_node2name_with_index(const dm_node_t *node, char *name, int name_len, const char *index_replacement);
int dm_name2node(const struct dm_node_info *parent, const char *name, dm_node_t *node);
int dm_path2node(const char *path, dm_node_t *node);
int dm_node_verify_param_data(dm_node_id_t id, const char *data);
// is parameter ancestor is the ancestor or parent of parameter id
int dm_node_is_ancestor(dm_node_id_t id, dm_node_id_t ancestor);
// is parameter data type a list (comman separated)
int dm_node_is_param_list(dm_node_id_t id);
dm_index_t dm_node_last_index(const dm_node_t *node);
int dm_node_is_index_complete(const dm_node_t *node);
/** Compare if two nodes are identical.
Two nodes are considered identical if their id, their index arrays and the cnt is the same
@param node1[in] first node for the comparison
@param node2[in] second node for the comparison
@return 1 if identical, 0 if not identical
*/
int dm_node_equal(const dm_node_t *node1, const dm_node_t *node2);
int dm_node_has_path(dm_node_id_t node_id, dm_node_id_t path);
// return 0-(max-1) for valid string, -1 for unknown enum string
int dm_node_get_enum_index(dm_node_id_t id, const char *enum_str);
// return the enum string for valid index: 0-(max-1), otherwise return NULL
const char *dm_node_get_enum_str(dm_node_id_t id, int index);
/** Remove path name from the path names separated with comma
@param paths path names separated with with comma
@param node node of path name that is to be removed
@return 0 if successful, -1 for failure
*/
int tr181_paths_remove(dm_path_t paths, const dm_node_t *node);
/** Append one path name to the path names separated with comma
@param paths path names separated with with comma
@param node node of path name that is to be appended
@return 0 if successful, -1 for failure
*/
int tr181_paths_add(dm_path_t paths, const dm_node_t *node);
// Find the "Order" parameter node from all its child nodes
int dm_node_find_order_param(const dm_node_t *obj_node, dm_node_t *order_node);
/** Return the database table for a node
@param node The node for which the database table is returned
@return pointer to the name of the database table (NULL if the node is not in the database
*/
const char *dm_node_get_table_name(const struct dm_node_info *node);
// Get child node id by its name
dm_node_id_t dm_node_get_child_id(dm_node_id_t id, const char *name);
// get child node by name
int dm_node_get_child(const dm_node_t *node, const char *name, dm_node_t *child);
const char *dm_node_str(const dm_node_t *node);
const char *dm_node_id_str(const dm_node_id_t id);
// compare if the nodes are compatible, this is if node1 and node2 have the same id and
// all indexes of node1 are a subset of node2 or vice versa
int dm_node_compatible(const dm_node_t *node1, const dm_node_t *node2);
// get the string xsd type of the data type
const char *dm_node_get_param_xsd_type(dm_node_id_t id);
/** Get the output argument type of the command node
@param [in] id node id
@param [in] arg_name argument name of the command
@return pointer of const string if successful, NULL for failure
*/
const struct command_arg *dm_node_get_command_output_arg(dm_node_id_t id, const char *arg_name);
// return 1 if verified, otherwise 0.
int dm_node_verify_command_input(dm_node_id_t id, const char *input_name, const char *input_value);
// Compare the command argument pathname with index (index part will be skipped for comparision)
// ex, "result.{i}.abc" == "result.100.abc"
// return 0 if equal, otherwise 1
int dm_node_compare_command_arg_name(const char* str1, const char* str2);
#endif

View File

@@ -1,97 +0,0 @@
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
#ifndef DM_TYPES_H
#define DM_TYPES_H
#define MAX_DM_NODE_DEPTH 8
#define INVALID_DM_INDEX ((dm_index_t)0)
#define INVALID_DM_NODE_ID ((dm_node_id_t)-1)
typedef unsigned int dm_node_id_t;
typedef unsigned int dm_index_t;
typedef dm_index_t dm_index_path_t[MAX_DM_NODE_DEPTH];
typedef struct
{
dm_index_path_t index;
} node_index_path_t;
typedef struct
{
dm_node_id_t id;
dm_index_path_t index;
int cnt;
} dm_node_t;
#define dm_init_node(id) \
{ \
id, {0}, 0 \
}
typedef unsigned int dm_uint_t;
typedef int dm_int_t;
typedef int dm_bool_t;
typedef char dm_enum_t[128];
typedef char dm_ip_t[64];
// IPv4 or IPv6 routing prefix in Classless Inter-Domain Routing (CIDR) notation [RFC4632].
// This is specified as an IP address followed by an appended "/n" suffix,
// where n (the prefix size) is an integer in the range 0-32 (for IPv4) or 0-128 (for IPv6)
// that indicates the number of (leftmost) '1' bits of the routing prefix.
// If the IP address part is unspecified or inapplicable, it MUST be an empty string unless
// otherwise specified by the parameter definition. In this case the IP prefix will be of the form "/n".
// IPv4 example: 192.168.1.0/24
// IPv6 example: 2001:edff:fe6a:f76::/64
typedef char dm_ip_prefix_t[64];
typedef char dm_mac_t[20]; // 18 would suffice but there can be word access when getting a value; hence rounded up to 20 */
typedef char dm_date_time_t[64];
typedef char dm_url_t[260];
typedef unsigned long dm_ulong_t;
typedef unsigned long long dm_ulonglong_t;
typedef char dm_path_t[1024];
typedef char dm_domain_t[256];
#define dm_true 1
#define dm_false 0
enum DM_DATA_TYPE {
DM_DATA_INT = 0,
DM_DATA_LONG,
DM_DATA_UINT,
DM_DATA_ULONG,
DM_DATA_BOOLEAN,
DM_DATA_STRING,
DM_DATA_HEXBINARY,
DM_DATA_BASE64,
DM_DATA_IP,
DM_DATA_IPV4,
DM_DATA_IPV6,
DM_DATA_IP_PREFIX,
DM_DATA_IPV6_PREFIX,
DM_DATA_MAC,
DM_DATA_DATETIME,
DM_DATA_ENUM,
DM_DATA_URL,
DM_PATH_NAME,
DM_DATA_UNKNOWN
};
enum DM_NODE_TYPE {
DM_NODE_PARAMETER = 0,
DM_NODE_OBJECT,
DM_NODE_OBJECT_LIST,
DM_NODE_COMMAND,
DM_NODE_EVENT
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,508 +0,0 @@
/* eslint-disable no-await-in-loop */
/*
* Copyright (c) 2023 Genexis B.V. All rights reserved.
*
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*
*/
const assert = require('assert');
const fs = require('fs');
const xml2js = require('xml2js');
const util = require('util');
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const parser = new xml2js.Parser();
const parseXML = util.promisify(parser.parseString);
const cwmpTr181XmlFile = 'tr-181-2-19-1-cwmp-full.xml';
const uspTr181XmlFile = 'tr-181-2-19-1-usp-full.xml';
const uspTr181VendorExtXmlFile = 'tr-181-vendor-extensions-usp.xml';
const Tr104USPXmlFile = 'tr-104-2-0-2-usp-full.xml';
const Tr104CWMPXmlFile = 'tr-104-2-0-2-cwmp-full.xml';
let cwmpModel;
let uspModel;
let uspVendorExtModel;
let tr181 = true;
async function saveFile(file, obj) {
await writeFile(file, JSON.stringify(obj, null, 4));
console.log('saved file:', file);
}
function getRange(attr) {
if (typeof attr[0] !== 'object') {
return '';
}
if (attr[0].range) {
const range = attr[0].range[0].$;
return `(${range.minInclusive ?? ''}:${range.maxInclusive ?? ''})`;
}
return '';
}
function objParent(obj) {
let parent;
if (obj.endsWith('}.')) {
parent = obj.slice(0, -5);
} else {
parent = obj.slice(0, -1);
}
return parent.substring(0, parent.lastIndexOf('.'));
}
function parsePathRef(obj, ref) {
let path = obj.$.name;
ref = ref.trim().replace(/\n$/, '');
if (ref.startsWith('.')) {
if (path.startsWith('Device.Services.VoiceService.') && !path.endsWith('()')) {
return `Device.Services.VoiceService.{i}${ref}`;
}
return `Device${ref}`;
}
if (ref.startsWith('#')) {
while (ref.startsWith('#')) {
path = objParent(path);
ref = ref.slice(1);
}
return path + ref;
}
if (ref.startsWith('Device.')) {
return ref;
}
return path + ref;
}
function getParamType(obj, res, syntaxType) {
const intTypes = [
'int',
'long',
'unsignedInt',
'unsignedLong',
];
const intType = intTypes.find((x) => Object.keys(syntaxType).includes(x));
if (intType) {
res.dataType = `${intType}${getRange(syntaxType[intType])}`;
} else if (syntaxType.boolean) {
res.dataType = 'boolean';
} else if (syntaxType.dateTime) {
res.dataType = 'dateTime';
} else if (syntaxType.string) {
const attr = syntaxType.string[0];
if (typeof attr === 'object') {
if (attr.enumeration) {
res.dataType = 'enum';
res.enum = attr.enumeration.map((x) => x.$.value);
} else if (attr.pathRef) {
res.dataType = 'pathRef';
if (attr.pathRef[0].$.targetParent) {
res.pathRef = attr.pathRef[0].$.targetParent.split(' ').filter((x) => x).map((x) => parsePathRef(obj, x));
}
} else if (attr.enumerationRef) {
res.dataType = 'enum';
res.enumerationRef = parsePathRef(obj, attr.enumerationRef[0].$.targetParam);
} else if (attr.size) {
res.dataType = `string(${attr.size[0].$?.minLength ?? ''}:${attr.size[0].$?.maxLength ?? ''})`;
} else if (attr.pattern) {
// handle it as enum
res.dataType = 'enum';
res.enum = attr.pattern.map((x) => x.$.value);
} else {
assert(false, `unknown string type: ${JSON.stringify(syntaxType, null, 2)}`);
}
} else {
res.dataType = 'string';
}
} else if (syntaxType.dataType) {
res.dataType = syntaxType.dataType[0].$.ref;
if (res.dataType === 'Alias') {
res.dataType = 'string(:64)';
} else if (res.dataType === 'DiagnosticsState') {
res.dataType = 'enum';
res.enum = ['None', 'Requested', 'Canceled', 'Complete', 'Error'];
} else if (res.dataType === 'StatsCounter64') {
res.dataType = 'unsignedLong';
}
} else if (syntaxType.hexBinary) {
res.dataType = 'hexBinary';
const { size } = syntaxType.hexBinary[0];
if (size) {
res.dataType += `(${size[0].$?.minLength ?? ''}:${size[0].$?.maxLength ?? ''})`;
}
} else if (syntaxType.base64) {
res.dataType = 'base64';
const { size } = syntaxType.base64[0];
if (size) {
res.dataType += `(${size[0].$?.minLength ?? ''}:${size[0].$?.maxLength ?? ''})`;
}
} else if (syntaxType.decimal) {
res.dataType = 'decimal';
const { size } = syntaxType.decimal[0];
if (size) {
res.dataType += `(${size[0].$?.minLength ?? ''}:${size[0].$?.maxLength ?? ''})`;
}
} else {
console.log(`unknown datatype:\n ${JSON.stringify(syntaxType, null, 4)}`);
res.dataType = 'unknown';
}
if (syntaxType.list) {
res.dataType += '[]';
}
}
function getParamObj(obj, param, proto) {
const res = {
name: param.$.name,
};
if (proto) {
res.proto = proto;
}
res.access = param.$.access;
const syntaxType = param.syntax[0];
getParamType(obj, res, syntaxType);
if (syntaxType.$?.hidden) {
res.hidden = true;
}
if (syntaxType.default && syntaxType.default[0].$?.value) {
const def = syntaxType.default[0].$?.value;
if (def !== 'false' && def !== '') {
res.default = syntaxType.default[0].$?.value;
}
}
return res;
}
let allObjects = [];
function generateCWMPObjects(objs) {
objs.forEach((obj) => {
const o = allObjects.find((x) => x.object === obj.$.name);
if (o) {
const params = obj.parameter.map((param) => getParamObj(obj, param, 'cwmp'));
o.parameters = o.parameters.concat(params);
} else {
allObjects.push({
object: obj.$.name,
proto: 'cwmp',
fixedObject: obj.$['dmr:fixedObject'],
uniqueKeys: obj.uniqueKey?.map((x) => x.parameter[0].$.ref).join(','),
// numEntriesParameter: obj.$.numEntriesParameter,
access: obj.$.access,
parameters: obj.parameter?.map((param) => (
getParamObj(obj, param, 'cwmp'))) ?? [],
});
}
});
}
function getCommandInput(cmdInfo) {
if (!cmdInfo.input) {
return [];
}
const objParams = [];
if (cmdInfo.input[0].object) {
cmdInfo.input[0].object.forEach((obj) => {
obj.parameter.forEach((p) => {
const inputParams = {
parameter: obj.$.name + p.$.name,
mandatory: p.$.mandatory === 'true',
};
getParamType(cmdInfo, inputParams, p.syntax[0]);
objParams.push(inputParams);
});
});
}
const params = cmdInfo.input[0].parameter?.map((p) => {
const inputParams = {
parameter: p.$.name,
mandatory: p.$.mandatory === 'true',
};
getParamType(cmdInfo, inputParams, p.syntax[0]);
return inputParams;
});
return objParams.concat(params ?? []);
}
function getCommandOutput(cmdInfo) {
if (!cmdInfo.output) {
return [];
}
const outParams = cmdInfo.output[0].parameter?.map((p) => {
const outputs = {
parameter: p.$.name,
};
getParamType(cmdInfo, outputs, p.syntax[0]);
return outputs;
}) ?? [];
const outObjs = cmdInfo.output[0].object?.map((obj) => {
const outputs = {
object: obj.$.name,
};
outputs.parameters = obj.parameter?.map((p) => {
const outs = {
parameter: p.$.name,
};
getParamType(cmdInfo, outs, p.syntax[0]);
return outs;
});
return outputs;
}) ?? [];
return outParams.concat(outObjs);
}
function generateUSPObjects(objs) {
objs.forEach((obj) => {
const o = allObjects.find((x) => x.object === obj.$.name);
if (o) {
delete o.proto;
obj.parameter?.forEach((p) => {
const param = o.parameters.find((x) => x.name === p.$.name);
if (param) {
delete param.proto;
} else {
o.parameters.push(getParamObj(obj, p, 'usp'));
}
});
if (obj.command) {
const cmds = obj.command.map((cmd) => ({
name: cmd.$.name,
async: !!cmd.$.async,
input: getCommandInput(cmd),
output: getCommandOutput(cmd),
}));
if (o.commands) {
o.commands = o.commands.concat(cmds);
} else {
o.commands = cmds;
}
}
if (obj.event) {
const events = obj.event.map((ev) => ({
name: ev.$.name,
parameter: ev.parameter?.map((p) => p.$.name),
}));
if (o.events) {
o.events = o.events.concat(events);
} else {
o.events = events;
}
}
} else {
const cwmpObj = cwmpModel.object.find((x) => x.$.name === obj.$.name);
const newObj = {
object: obj.$.name,
proto: cwmpObj ? undefined : 'usp',
uniqueKeys: obj.uniqueKey?.map((x) => x.parameter[0].$.ref).join(','),
// numEntriesParameter: obj.$.numEntriesParameter,
access: obj.$.access,
fixedObject: obj.$['dmr:fixedObject'],
parameters: obj.parameter?.map((param) => (
getParamObj(obj, param, (cwmpObj && cwmpObj.parameter?.find((x) => x.$.name === param.$.name)) ? undefined : 'usp'))) ?? [],
};
if (obj.command) {
newObj.commands = obj.command.map((cmd) => ({
name: cmd.$.name,
async: !!cmd.$.async,
input: getCommandInput(cmd),
output: getCommandOutput(cmd),
}));
}
if (obj.event) {
newObj.events = obj.event.map((ev) => ({
name: ev.$.name,
parameter: ev.parameter?.map((p) => p.$.name),
}));
}
allObjects.push(newObj);
}
});
}
function mergeProfileObjs(obj1, obj2) {
if (!obj1) {
return obj2;
}
if (!obj2) {
return obj1;
}
obj2.forEach((obj) => {
const o = obj1.find((x) => x.object === obj.object);
if (o) {
if (o.parameter) {
o.parameter = o.parameter.concat(obj.parameter ?? []);
} else {
o.parameter = obj.parameter;
}
if (o.command) {
o.command = o.command.concat(obj.command ?? []);
} else {
o.command = obj.command;
}
if (o.event) {
o.event = o.event.concat(obj.event ?? []);
} else {
o.event = obj.event;
}
} else {
obj1.push(obj);
}
});
return obj1;
}
function parseProfileObjects(model, profileName) {
const profile = model.profile.find((x) => x.$.name === profileName);
if (!profile) {
return [];
}
// assert(profile, `profile not found ${profileName}`);
const objs = profile.object?.map((o) => ({
object: o.$.ref,
parameter: o.parameter?.map((p) => p.$.ref),
command: o.command?.map((c) => c.$.ref),
event: o.event?.map((e) => e.$.ref),
}));
const exts = profile.$.extends ?? profile.$.base;
if (exts) {
let res = objs;
exts.split(' ').forEach((ext) => {
const extObjs = parseProfileObjects(model, ext);
res = mergeProfileObjs(res, extObjs);
});
return res;
}
return objs;
}
async function getProfileObjects(model, profileName) {
const profileObjs = parseProfileObjects(model, profileName);
const objs = [];
profileObjs.forEach((obj) => {
const targetObj = model.object.find((o) => o.$.name === obj.object);
assert(targetObj, `object not found ${obj.object}`);
const keys = targetObj.uniqueKey?.map((x) => x.parameter[0].$.ref);
targetObj.parameter = targetObj.parameter?.filter((x) => obj.parameter?.includes(x.$.name) || (keys?.includes(x.$.name)));
targetObj.command = targetObj.command?.filter((x) => obj.command?.includes(x.$.name));
objs.push(targetObj);
});
return objs;
}
async function loadXMLModel(file) {
const xmlData = await readFile(file, 'utf8');
const jsonData = await parseXML(xmlData);
const [model] = jsonData['dm:document'].model;
return model;
}
function printUsage() {
console.log('Usage:\nnode makeDM.js <tr181|tr104> [profile]');
}
(async () => {
try {
if (process.argv.length < 3 || (process.argv[2] !== 'tr181' && process.argv[2] !== 'tr104')) {
printUsage();
process.exit(-1);
}
if (process.argv[2] === 'tr104') {
tr181 = false;
}
if (tr181 && fs.existsSync(uspTr181VendorExtXmlFile)) {
uspVendorExtModel = await loadXMLModel(uspTr181VendorExtXmlFile);
} else if (tr181) {
console.warn(`Optional vendor extension file '${uspTr181VendorExtXmlFile}' not found, skipping.`);
}
if (tr181) {
cwmpModel = await loadXMLModel(cwmpTr181XmlFile);
uspModel = await loadXMLModel(uspTr181XmlFile);
} else {
cwmpModel = await loadXMLModel(Tr104CWMPXmlFile);
uspModel = await loadXMLModel(Tr104USPXmlFile);
cwmpModel.object.forEach((obj) => {
obj.$.name = `Device.Services.${obj.$.name}`;
});
cwmpModel.profile.forEach((prof) => {
prof.object?.forEach((obj) => {
obj.$.ref = `Device.Services.${obj.$.ref}`;
});
});
uspModel.object.forEach((obj) => {
obj.$.name = `Device.Services.${obj.$.name}`;
});
uspModel.profile.forEach((prof) => {
prof.object?.forEach((obj) => {
obj.$.ref = `Device.Services.${obj.$.ref}`;
});
});
}
if (process.argv.length === 3) {
generateCWMPObjects(cwmpModel.object);
generateUSPObjects(uspModel.object);
if (tr181 && uspVendorExtModel) {
generateUSPObjects(uspVendorExtModel.object);
}
const fileName = `${tr181 ? 'tr181' : 'tr104'}-full-objects.json`;
await saveFile(fileName, allObjects);
process.exit(0);
}
for (const arg of process.argv.slice(3)) {
// profile
const profile = arg;
const cwmpObjects = await getProfileObjects(cwmpModel, profile);
const uspObjects = await getProfileObjects(uspModel, profile);
generateCWMPObjects(cwmpObjects);
generateUSPObjects(uspObjects);
await saveFile(`${profile}.json`, allObjects);
allObjects = [];
}
} catch (error) {
console.error(`Error while reading file: ${error}`);
console.log(error.stack);
}
})();

View File

@@ -1,88 +0,0 @@
// This script is used to load and validate the js handlers code in dm-file.
(function () {
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
// Root directory (dm-files) relative to this script
const dmFilesRoot = path.resolve(__dirname, '../dm-files');
/**
* Recursively walk a directory and collect all *.js files that do not start with a dot.
* @param {string} dir - directory to walk
* @param {string[]} out - accumulator for file paths
*/
function collectJsFiles(dir, out) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
// Skip hidden files/directories (starting with ".")
if (entry.name.startsWith('.')) {
continue;
}
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
collectJsFiles(fullPath, out);
} else if (entry.isFile() && fullPath.endsWith('.js')) {
out.push(fullPath);
}
}
}
/**
* Validate a single JavaScript file with QuickJS (qjs).
* Exits the process with -1 on failure.
* @param {string} filePath - absolute path of the JS file
*/
function validateWithQjs(filePath) {
// Extract directory and filename for proper working directory
const fileDir = path.dirname(filePath);
const fileName = path.basename(filePath);
// Capture stdout/stderr so we can print them on failure
// Set the working directory to the file's directory
const result = spawnSync('qjs', [fileName], {
encoding: 'utf8',
cwd: fileDir
});
if (result.status === 0) {
return; // Validated successfully
}
// Show QuickJS output so user sees error details
console.error(`\n===== QuickJS validation failed: ${filePath} =====`);
if (result.stdout) {
console.error(result.stdout.trim());
}
if (result.stderr) {
console.error(result.stderr.trim());
}
console.error('===============================================');
process.exit(-1);
}
function main() {
if (!fs.existsSync(dmFilesRoot)) {
console.error(`dm-files directory not found at: ${dmFilesRoot}`);
process.exit(-1);
}
const jsFiles = [];
collectJsFiles(dmFilesRoot, jsFiles);
if (jsFiles.length === 0) {
console.log('No JavaScript files found to validate.');
return;
}
console.log(`Validating ${jsFiles.length} JavaScript file(s) with QuickJS...`);
jsFiles.forEach(validateWithQjs);
console.log('All files validated successfully.');
}
// Execute when run directly (not required when imported)
if (require.main === module) {
main();
}
})();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,64 +0,0 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
include $(TOPDIR)/rules.mk
PKG_NAME:=bridgemngr
PKG_VERSION:=1.0.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
PLATFORM_CONFIG:=$(TOPDIR)/.config
include $(INCLUDE_DIR)/package.mk
include ../../bbfdm/bbfdm.mk
define Package/$(PKG_NAME)
DEPENDS:=+dm-api +datamodels +libubox +libubus +ubus
CATEGORY:=Genexis
TITLE:=GeneOS agent
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/$(PKG_NAME)/description
This package contains GeneOS agent.
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) -rf ./src/* $(PKG_BUILD_DIR)/
endef
TARGET_CFLAGS += $(FPIC) -I$(PKG_BUILD_DIR)
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)\
PROJECT_ROOT="$(PKG_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
all
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_BIN) ./files/etc/init.d/bridging $(1)/etc/init.d/
$(INSTALL_DATA) ./files/etc/config/bridging $(1)/etc/config/
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
# $(INSTALL_BIN) ./files/etc/init.d/dm-agent $(1)/etc/init.d/dm-agent
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dm-agent $(1)/usr/sbin
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,17 +0,0 @@
{
"daemon": {
"enable": "1",
"service_name": "bridgemngr",
"dm-framework": true,
"unified_daemon": false,
"services": [
{
"parent_dm": "Device.",
"object": "Bridging"
}
],
"config": {
"loglevel": "3"
}
}
}

View File

@@ -1,33 +0,0 @@
#L2 filter UCI file
config chain 'qos_output'
option target 'qos_output'
option table 'nat'
option chain 'OUTPUT'
option policy 'RETURN'
config chain 'dscp2pbits'
option target 'dscp2pbits'
option table 'broute'
option chain 'BROUTING'
option policy 'RETURN'
config chain 'qos'
option target 'qos'
option table 'broute'
option chain 'BROUTING'
option policy 'RETURN'
config chain 'prevlanxlate'
option target 'prevlanxlate'
option table 'broute'
option chain 'BROUTING'
option policy 'RETURN'
option append 'false'
config chain 'mcsnooping'
option target 'mcsnooping'
option table 'broute'
option chain 'BROUTING'
option policy 'RETURN'
option append 'false'

View File

@@ -1,94 +0,0 @@
#!/bin/sh /etc/rc.common
# Start after bdmf shell, wanconf, and switch-script but before the network-script
START=20
STOP=10
USE_PROCD=1
. /lib/functions.sh
handle_ebtables_chain() {
local sid="$1"
local table
local chain
local target
local policy
local append
local enabled
local ret
config_get table "$sid" table filter
config_get chain "$sid" chain
config_get policy "$sid" policy RETURN
config_get target "$sid" target
config_get_bool append "$sid" append 1
config_get_bool enabled "$sid" enabled 1
[ "$enabled" = "0" ] && return
[ -z "${chain}" -o -z "${target}" ] && return
if [ "$append" != "0" ]; then
append="-A"
else
append="-I"
fi
ebtables --concurrent -t "$table" -N "$target" -P "$policy" 2> /dev/null
ret=$?
if [ $ret -eq 0 ]; then
ebtables --concurrent -t "$table" ${append} "$chain" -j "$target"
else
ebtables --concurrent -t "$table" -D "$chain" -j "$target"
ebtables --concurrent -t "$table" ${append} "$chain" -j "$target"
fi
}
handle_ebtables_rule() {
local sid="$1"
local table
local chain
local target
local match
local value
local enabled
local ret
config_get table "$sid" table filter
config_get chain "$sid" chain
config_get match "$sid" match
config_get value "$sid" value
config_get target "$sid" target RETURN
config_get_bool append "$sid" append 1
config_get_bool enabled "$sid" enabled 1
[ "$enabled" = "0" ] && return
[ -z "${chain}" -o -z "${target}" ] && return
if [ "$append" != "0" ]; then
append="-A"
else
append="-I"
fi
ebtables --concurrent -t "$table" -D "$chain" ${match} -j "$target" ${value} 2> /dev/null
ebtables --concurrent -t "$table" ${append} "$chain" ${match} -j "$target" ${value}
}
start_service() {
ubus -t 30 wait_for network.device uci
config_load bridging
config_foreach handle_ebtables_chain chain
config_foreach handle_ebtables_rule rule
}
reload_service() {
stop
start
}
service_triggers() {
procd_add_reload_trigger bridging
}

View File

@@ -1,37 +0,0 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
PROG = dm-agent
SRCS = dm_agent.c
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
CC = $(CROSS_COMPILE)gcc
STRIP = $(CROSS_COMPILE)strip
CFLAGS = -Wall -Werror $(EXTRA_CFLAGS)
CFLAGS += -MMD -MP -std=gnu99
LDFLAGS += -ldm -ldmapi -lubus -luci -lubox -ljson-c -lblobmsg_json
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $^ $(LDFLAGS) -o $@
%.o: %.c
$(CC) -c $(CFLAGS) $^ -o $@
clean:
rm -f $(PROG) *.o core $(DEPS)
-include $(DEPS)

File diff suppressed because it is too large Load Diff

View File

@@ -1,75 +0,0 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dm-api
PKG_VERSION:=1.0
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
PLATFORM_CONFIG:=$(TOPDIR)/.config
AUTO_CONF_H:=$(PKG_BUILD_DIR)/autoconf.h
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
CATEGORY:=Genexis
TITLE:=dm-api
PKG_BUILD_DEPENDS:=datamodels
DEPENDS:=+libsqlite3 \
+libjson-c +libstdcpp +quickjs \
+libubus +libubox +libuci
# Depedencies for RG products
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/$(PKG_NAME)/description
This package contains api for the dm-framework
endef
define Build/Prepare
$(CP) -rf ./src/* $(PKG_BUILD_DIR)/
endef
TARGET_CFLAGS += $(FPIC) -I$(PKG_BUILD_DIR)
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)\
PROJECT_ROOT="$(PKG_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
all
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/core/dm_api.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/core/dm_linker.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/core/dbmgr.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/include/dm_log.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/utils/dm_list.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libdmapi.so $(1)/usr/lib/
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/sbin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/libdmapi.so $(1)/usr/lib/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,64 +0,0 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
PROG = libdmapi.so
SRCS = \
core/dm_api.c \
core/dm_linker.c \
core/dbmgr.c \
core/inode_buf.c \
core/dm_apply.c \
core/dm_import.c \
core/db_upgrade.c \
utils/dm_list.c \
utils/dm_log.c \
utils/ubus_client.c \
utils/utils.c \
quickjs/qjs.c \
quickjs/qjs_log.c \
quickjs/qjs_dm_api.c \
quickjs/qjs_uci_api.c \
quickjs/qjs_ubus_api.c
OBJS = $(SRCS:.c=.o)
DEPS = $(SRCS:.c=.d)
CC = $(CROSS_COMPILE)gcc
STRIP = $(CROSS_COMPILE)strip
CFLAGS += \
-I core \
-I $(STAGING_DIR)/usr/include $(EXTRA_CFLAGS) \
-I handlers/common \
-I handlers/tr181 \
-I include \
-I utils \
-I quickjs
CFLAGS += -MMD -MP -std=gnu99
LDFLAGS = -shared
CFLAGS += -Wall -Werror -fpic
LDFLAGS += -lquickjs -lsqlite3 -latomic
# END for src from mgmt-agent
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $^ $(LDFLAGS) -o $@
%.o: %.c
$(CC) -c $(CFLAGS) $^ -o $@
clean:
rm -f $(PROG) *.o core $(DEPS)
-include $(DEPS)

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More