mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2026-01-01 09:08:56 +08:00
Compare commits
330 Commits
release-5.
...
obhp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6033a1ad5f | ||
|
|
8f0e98f50b | ||
|
|
d3cf57ef77 | ||
|
|
036e27876a | ||
|
|
69f8fcb047 | ||
|
|
c344fbe2ea | ||
|
|
0a29c12e09 | ||
|
|
68ca5f7fb8 | ||
|
|
8cb7c61007 | ||
|
|
61359cb291 | ||
|
|
4a439783c8 | ||
|
|
cd1ad2ec7a | ||
|
|
9a25147997 | ||
|
|
ad4c0f5cf1 | ||
|
|
3f6076369f | ||
|
|
fbc699524a | ||
|
|
f7c45760da | ||
|
|
e03c14ae2b | ||
|
|
355e042820 | ||
|
|
53d2088715 | ||
|
|
833c97d216 | ||
|
|
59d2324acd | ||
|
|
e3cb3586d7 | ||
|
|
a5e43567b3 | ||
|
|
e03568f9b1 | ||
|
|
ea23e1489c | ||
|
|
32db63deb0 | ||
|
|
5211a49f67 | ||
|
|
907f2fc59b | ||
|
|
cf8571b217 | ||
|
|
86bab4da22 | ||
|
|
3bdf2ba11b | ||
|
|
4ee3a92064 | ||
|
|
f1b4cbc520 | ||
|
|
dff5045437 | ||
|
|
80a057b727 | ||
|
|
84a8afe5da | ||
|
|
609035d250 | ||
|
|
bb0299fe26 | ||
|
|
57f6e54646 | ||
|
|
859a2af38e | ||
|
|
477284e1a6 | ||
|
|
a9d10a8642 | ||
|
|
01cf113338 | ||
|
|
7da94735b5 | ||
|
|
baccd9ad56 | ||
|
|
1642841acd | ||
|
|
c3157ef44e | ||
|
|
127f732831 | ||
|
|
be91f797dc | ||
|
|
ae7a3e329f | ||
|
|
ef37f8d9c1 | ||
|
|
07ca78f548 | ||
|
|
10a11f0cb8 | ||
|
|
4c11cdac89 | ||
|
|
8b51e8c03b | ||
|
|
2d9f03d6ab | ||
|
|
e19674ea70 | ||
|
|
0af09b123c | ||
|
|
6e6f7289ad | ||
|
|
25f6109691 | ||
|
|
7e0fe946cd | ||
|
|
c831c34a94 | ||
|
|
a9180d3a2b | ||
|
|
3ad8ef4b40 | ||
|
|
17fd0ab28a | ||
|
|
8ae15aa39b | ||
|
|
1ed5f0c0f6 | ||
|
|
939ff109c2 | ||
|
|
5c9469589c | ||
|
|
d6dae7cd0b | ||
|
|
0872d45d63 | ||
|
|
14e54fbf04 | ||
|
|
105edbfada | ||
|
|
a77deb3f36 | ||
|
|
38f737fa20 | ||
|
|
600209795d | ||
|
|
6819ccef9c | ||
|
|
8d257729ef | ||
|
|
78c84db435 | ||
|
|
1b1e071b1b | ||
|
|
38bf0e3c89 | ||
|
|
2506c9874a | ||
|
|
ee486af38b | ||
|
|
bf871111a5 | ||
|
|
1388b566bc | ||
|
|
a63295be52 | ||
|
|
450b9eaee9 | ||
|
|
e22a60c637 | ||
|
|
32817656e1 | ||
|
|
da017f98e2 | ||
|
|
1e3c338abb | ||
|
|
034f69408a | ||
|
|
d86e277461 | ||
|
|
2f333148b2 | ||
|
|
8a275944e3 | ||
|
|
76d40e2e1e | ||
|
|
e00394f158 | ||
|
|
64944425f5 | ||
|
|
9d996bdf9e | ||
|
|
5c8e7cb740 | ||
|
|
201fb45c6c | ||
|
|
7e2cdb88fb | ||
|
|
f750ab67d7 | ||
|
|
1ba812351d | ||
|
|
efc11f8c6d | ||
|
|
69cf19cc8e | ||
|
|
085ec84436 | ||
|
|
faec0f002a | ||
|
|
436a57f8d6 | ||
|
|
e3d0362d1f | ||
|
|
3135ad4865 | ||
|
|
12f4a5380b | ||
|
|
3887bab7f7 | ||
|
|
a6a54316e8 | ||
|
|
0273969b9c | ||
|
|
0781d5620d | ||
|
|
d8d42400b1 | ||
|
|
c3ee0a2d8a | ||
|
|
d66c3c0bbf | ||
|
|
a57d03d7e9 | ||
|
|
ec35396ffc | ||
|
|
7e9a109466 | ||
|
|
21c9d13b7a | ||
|
|
f467f2a90f | ||
|
|
8ffe458009 | ||
|
|
a9122f9909 | ||
|
|
cea453c91c | ||
|
|
4b707a26f4 | ||
|
|
81a39308cc | ||
|
|
73d7e51afa | ||
|
|
557f2693d3 | ||
|
|
c9b2973ac8 | ||
|
|
6f15e7ff27 | ||
|
|
f431a3ddf5 | ||
|
|
4ce6578aa7 | ||
|
|
39ab8e9282 | ||
|
|
e5694c1429 | ||
|
|
0c998dbb66 | ||
|
|
d8b5f3e1f0 | ||
|
|
0b39626067 | ||
|
|
5665076321 | ||
|
|
db5c1613f5 | ||
|
|
c82cf9ebb0 | ||
|
|
1f7565536d | ||
|
|
1922fa2560 | ||
|
|
fe86ade858 | ||
|
|
f49c4f4a64 | ||
|
|
ac7491c010 | ||
|
|
63db10eb1f | ||
|
|
651ad4ce22 | ||
|
|
51a3b0ad35 | ||
|
|
0c8b1ea046 | ||
|
|
104805a36e | ||
|
|
a1bfb1b568 | ||
|
|
5c744f71e3 | ||
|
|
20ca483d80 | ||
|
|
7a466c989c | ||
|
|
ff63939e84 | ||
|
|
3b283b8f3a | ||
|
|
d93d72587e | ||
|
|
b098ef3dc2 | ||
|
|
8c69fc062a | ||
|
|
8ad4f32786 | ||
|
|
71b66376f0 | ||
|
|
48525b051a | ||
|
|
753e894b69 | ||
|
|
ce701702c5 | ||
|
|
11550d140a | ||
|
|
f622a96054 | ||
|
|
3f19a43df2 | ||
|
|
d2fedc407a | ||
|
|
783fd44680 | ||
|
|
614774cb8b | ||
|
|
84521942ca | ||
|
|
bbbbdf9650 | ||
|
|
98071d157d | ||
|
|
d829f00e07 | ||
|
|
640535a2ef | ||
|
|
7837417219 | ||
|
|
269cbe364e | ||
|
|
54cc458a2d | ||
|
|
fdc882b6e0 | ||
|
|
346eaf0414 | ||
|
|
d946f11c32 | ||
|
|
c0957a425a | ||
|
|
8015a503ac | ||
|
|
a7d09f5ede | ||
|
|
8a5b49d585 | ||
|
|
ac69ea616e | ||
|
|
f358d6338d | ||
|
|
c514903145 | ||
|
|
dd69c371ae | ||
|
|
4a1ab17bd4 | ||
|
|
208b2cc8e5 | ||
|
|
2e934a7169 | ||
|
|
b06980688a | ||
|
|
29b9605e02 | ||
|
|
0afa721bca | ||
|
|
3c0de388d1 | ||
|
|
aa1741e87a | ||
|
|
3040359e85 | ||
|
|
237286f42d | ||
|
|
7758b30397 | ||
|
|
7b0dce915c | ||
|
|
b6fdd0115a | ||
|
|
392e08e2fc | ||
|
|
2ae2110799 | ||
|
|
773e7af7f6 | ||
|
|
75e9a5360f | ||
|
|
db5e42434e | ||
|
|
00fd7efa3b | ||
|
|
34f495f0a5 | ||
|
|
e3b7c9c238 | ||
|
|
e3f2e715c1 | ||
|
|
4c149ff680 | ||
|
|
959b0546bc | ||
|
|
e39430ceaf | ||
|
|
6ea9942320 | ||
|
|
a5e812f785 | ||
|
|
a604987a3e | ||
|
|
7b2d8edacf | ||
|
|
47b2b4fc51 | ||
|
|
6b3e6bcd11 | ||
|
|
52726289cc | ||
|
|
6c2aac5db5 | ||
|
|
bfc2b17a72 | ||
|
|
e98422f81e | ||
|
|
841a76a7e6 | ||
|
|
1760ea526c | ||
|
|
b5a493e540 | ||
|
|
7f00d0419f | ||
|
|
64da6686af | ||
|
|
8cc1877efd | ||
|
|
6673a85a21 | ||
|
|
3e07ea7f8d | ||
|
|
8b4ef46681 | ||
|
|
f35e41cc0c | ||
|
|
0aff258e29 | ||
|
|
d919f4440e | ||
|
|
9d20839041 | ||
|
|
36ec134e33 | ||
|
|
ea57418313 | ||
|
|
c61aa804ce | ||
|
|
19bbb87682 | ||
|
|
3ee01927b1 | ||
|
|
d9f6b37bd7 | ||
|
|
c3dd0a996b | ||
|
|
90c5c5c52c | ||
|
|
f7cb4c8aac | ||
|
|
07cbf0938e | ||
|
|
a31bb99c30 | ||
|
|
80e3d89d9a | ||
|
|
d26eaf0ef0 | ||
|
|
e437fc821e | ||
|
|
c86d16daf9 | ||
|
|
a91b41d70a | ||
|
|
847b27c879 | ||
|
|
89fe5115f0 | ||
|
|
aba88e359d | ||
|
|
84b594e9bf | ||
|
|
e3dd402d4e | ||
|
|
a06ffa00ce | ||
|
|
c3c5d4ff8b | ||
|
|
bb996c64df | ||
|
|
adbb8b70c1 | ||
|
|
34b3478d77 | ||
|
|
181dd5039e | ||
|
|
10e83915c7 | ||
|
|
59e0b78e84 | ||
|
|
c1e7c8f103 | ||
|
|
de9a7c447d | ||
|
|
8cbcc039d7 | ||
|
|
044dd31be4 | ||
|
|
48b286031a | ||
|
|
ee3dceb433 | ||
|
|
aa1353f08e | ||
|
|
682497f68c | ||
|
|
bfb98073c1 | ||
|
|
a8960be7b5 | ||
|
|
6255b9b2df | ||
|
|
4e11dda2c0 | ||
|
|
c898217717 | ||
|
|
4d2358aa2a | ||
|
|
d3fb4ec562 | ||
|
|
b06ca2b5e5 | ||
|
|
30928e5eb9 | ||
|
|
c75d639a69 | ||
|
|
0bb19c25f7 | ||
|
|
64a826896d | ||
|
|
eee9c7a70c | ||
|
|
0c0e9f15f2 | ||
|
|
48ab39fa31 | ||
|
|
6914c0548f | ||
|
|
ffe74261d9 | ||
|
|
1b5630c67e | ||
|
|
2bf5014aeb | ||
|
|
279a583d23 | ||
|
|
0a0cad9715 | ||
|
|
74618b9377 | ||
|
|
5ff2854490 | ||
|
|
7ae3a29d08 | ||
|
|
68e4189d05 | ||
|
|
c0f7c0ecf1 | ||
|
|
825f1ff76d | ||
|
|
7fa1bf30c1 | ||
|
|
ee3e6d5975 | ||
|
|
96d0a3fba8 | ||
|
|
7b158a918a | ||
|
|
6bad87c47f | ||
|
|
c73ae26618 | ||
|
|
d73a60a4f3 | ||
|
|
0c52946965 | ||
|
|
e89485f19c | ||
|
|
bfb73ba4b5 | ||
|
|
b3e19722b7 | ||
|
|
908ef455c2 | ||
|
|
950687c88b | ||
|
|
5675ff87de | ||
|
|
ae0213ce8c | ||
|
|
a45957e872 | ||
|
|
2c67b66e15 | ||
|
|
bf5b932a93 | ||
|
|
3f6c55a86d | ||
|
|
133c45e91d | ||
|
|
fce1fa2eae | ||
|
|
986fc5ea78 | ||
|
|
95e887087f | ||
|
|
0082d26141 | ||
|
|
2306b1e76f |
@@ -16,12 +16,4 @@ config BBF_TR143
|
||||
bool "Compile with tr143 diagnostics features"
|
||||
default y
|
||||
|
||||
config BBF_TR157
|
||||
bool "Compile with tr157 bulkdata collector features"
|
||||
default y
|
||||
|
||||
config BBF_TR064
|
||||
bool "Compile with tr064 features"
|
||||
default n
|
||||
|
||||
endif
|
||||
|
||||
29
bbf/Makefile
29
bbf/Makefile
@@ -5,11 +5,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libbbfdm
|
||||
PKG_VERSION:=1.6-2020-08-25
|
||||
PKG_VERSION:=3.2.7
|
||||
PKG_FIXUP:=autoreconf
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/bbf.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=bfe14a431d408614ed30e2d831ebd927eab719e2
|
||||
PKG_SOURCE_VERSION:=ae196c54590dc343db14a70879f21ef88203c426
|
||||
PKG_RELEASE=$(PKG_SOURCE_VERSION)
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
@@ -44,7 +44,7 @@ define Package/libbbf_api/description
|
||||
endef
|
||||
|
||||
define Package/libbbfdm/description
|
||||
Library contains the data model tree. It includes TR181, TR104, TR143, TR157 and TR064 data models
|
||||
Library contains the data model tree. It includes TR181, TR104 and TR143 data models
|
||||
endef
|
||||
|
||||
USE_LOCAL=$(shell ls ./src/ 2>/dev/null >/dev/null && echo 1)
|
||||
@@ -74,16 +74,6 @@ CONFIGURE_ARGS += \
|
||||
--enable-tr143
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BBF_TR157),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-tr157
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BBF_TR064),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-tr064
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PACKAGE_libopenssl),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-libopenssl
|
||||
@@ -102,20 +92,23 @@ endef
|
||||
define Package/libbbfdm/install
|
||||
$(INSTALL_DIR) $(1)/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/bin/.libs/libbbfdm.so* $(1)/lib/
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm/json
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/dmmap $(1)/etc/bbfdm
|
||||
$(INSTALL_DIR) $(1)/usr/share/bbfdm
|
||||
$(CP) $(PKG_BUILD_DIR)/scripts/functions $(1)/usr/share/bbfdm
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm/json
|
||||
$(INSTALL_DIR) $(1)/usr/lib/bbfdm
|
||||
endef
|
||||
|
||||
define Package/libbbfdm/prerm
|
||||
#!/bin/sh
|
||||
rm -rf /etc/bbfdm/*
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include/libbbfdm
|
||||
$(INSTALL_DIR) $(1)/usr/include/libbbf_api
|
||||
$(CP) $(PKG_BUILD_DIR)/*.h $(1)/usr/include/libbbfdm/
|
||||
$(CP) $(PKG_BUILD_DIR)/dmtree/tr181/*.h $(1)/usr/include/libbbfdm/
|
||||
$(CP) $(PKG_BUILD_DIR)/dmtree/tr157/*.h $(1)/usr/include/libbbfdm/
|
||||
$(CP) $(PKG_BUILD_DIR)/libbbf_api/*.h $(1)/usr/include/libbbf_api/
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/bin/.libs/libbbfdm.{a,so*} $(1)/usr/lib/
|
||||
|
||||
44
bulkdata/Makefile
Executable file
44
bulkdata/Makefile
Executable file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (C) 2020 iopsys Software Solutions AB
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=bulkdata
|
||||
PKG_VERSION:=1.0.0
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=BBF BulkData Collection
|
||||
DEPENDS:=+libubus +libuci +libubox +libjson-c +libcurl +curl +libblobmsg-json +libbbfdm +libbbf_api
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
BBF BulkData Collection
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bulkdatad $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/bbfdm
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/*.so $(1)/usr/lib/bbfdm
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
43
bulkdata/files/etc/config/bulkdata
Normal file
43
bulkdata/files/etc/config/bulkdata
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
config bulkdata 'bulkdata'
|
||||
option enable '0'
|
||||
#Log levels: Critical=0, Warning=1, Notice=2, Info=3, Debug=4
|
||||
option log_level '3'
|
||||
|
||||
config profile
|
||||
option profile_id '1'
|
||||
option enable '0'
|
||||
option name ''
|
||||
option nbre_of_retained_failed_reports '0'
|
||||
option protocol 'http'
|
||||
option encoding_type ''
|
||||
option reporting_interval '86400'
|
||||
option time_reference '0'
|
||||
option csv_encoding_field_separator ','
|
||||
option csv_encoding_row_separator ' '
|
||||
option csv_encoding_escape_character '"'
|
||||
option csv_encoding_report_format 'column'
|
||||
option csv_encoding_row_time_stamp 'unix'
|
||||
option json_encoding_report_format 'objecthierarchy'
|
||||
option json_encoding_report_time_stamp 'unix'
|
||||
option http_url ''
|
||||
option http_username ''
|
||||
option http_password ''
|
||||
option http_compression 'none'
|
||||
option http_method 'post'
|
||||
option http_use_date_header '1'
|
||||
option http_retry_enable '0'
|
||||
option http_retry_minimum_wait_interval '5'
|
||||
option http_retry_interval_multiplier '2000'
|
||||
option http_persist_across_reboot '0'
|
||||
|
||||
config profile_parameter
|
||||
option profile_id '1'
|
||||
option name ''
|
||||
option reference ''
|
||||
|
||||
config profile_http_request_uri_parameter
|
||||
option profile_id '1'
|
||||
option name ''
|
||||
option reference ''
|
||||
|
||||
34
bulkdata/files/etc/init.d/bulkdatad
Executable file
34
bulkdata/files/etc/init.d/bulkdatad
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Bulkdata Software
|
||||
# Copyright (C) 2020 iopsys Software Solutions AB
|
||||
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
|
||||
USE_PROCD=1
|
||||
PROG="/usr/sbin/bulkdatad"
|
||||
|
||||
start_service() {
|
||||
local bulkdata_enable=`uci -q get bulkdata.bulkdata.enable`
|
||||
if [ "$bulkdata_enable" = "1" ]; then
|
||||
procd_open_instance
|
||||
procd_set_param command "$PROG"
|
||||
procd_set_param respawn "3" "7" "0"
|
||||
procd_close_instance
|
||||
fi
|
||||
}
|
||||
|
||||
boot() {
|
||||
start
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger bulkdata
|
||||
}
|
||||
23
bulkdata/src/Makefile
Normal file
23
bulkdata/src/Makefile
Normal file
@@ -0,0 +1,23 @@
|
||||
PROG = bulkdatad
|
||||
LIB = libbulkdata.so
|
||||
|
||||
PROG_OBJS = bulkdata.o common.o config.o http.o log.o report.o times.o buci.o
|
||||
LIB_OBJS = datamodel.o
|
||||
|
||||
PROG_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC
|
||||
PROG_LDFLAGS = $(LDFLAGS) -lubus -luci -lubox -ljson-c -lcurl -lblobmsg_json -lbbfdm -lbbf_api
|
||||
LIB_LDFLAGS = $(LDFLAGS) -lbbf_api
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
|
||||
|
||||
all: $(PROG) $(LIB)
|
||||
|
||||
$(PROG): $(PROG_OBJS)
|
||||
$(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS)
|
||||
|
||||
$(LIB): $(LIB_OBJS)
|
||||
$(CC) $(PROG_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f *.o $(PROG) $(LIB)
|
||||
265
bulkdata/src/buci.c
Normal file
265
bulkdata/src/buci.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "buci.h"
|
||||
|
||||
struct uci_context *uci_ctx = NULL;
|
||||
|
||||
int buci_init(void)
|
||||
{
|
||||
uci_ctx = uci_alloc_context();
|
||||
if (!uci_ctx) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int buci_fini(void)
|
||||
{
|
||||
if (uci_ctx) {
|
||||
uci_free_context(uci_ctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool buci_validate_section(const char *str)
|
||||
{
|
||||
if (!*str)
|
||||
return false;
|
||||
|
||||
for (; *str; str++) {
|
||||
unsigned char c = *str;
|
||||
|
||||
if (isalnum(c) || c == '_')
|
||||
continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int buci_init_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value)
|
||||
{
|
||||
memset(ptr, 0, sizeof(struct uci_ptr));
|
||||
|
||||
/* value */
|
||||
if (value) {
|
||||
ptr->value = value;
|
||||
}
|
||||
ptr->package = package;
|
||||
if (!ptr->package)
|
||||
goto error;
|
||||
|
||||
ptr->section = section;
|
||||
if (!ptr->section) {
|
||||
ptr->target = UCI_TYPE_PACKAGE;
|
||||
goto lastval;
|
||||
}
|
||||
|
||||
ptr->option = option;
|
||||
if (!ptr->option) {
|
||||
ptr->target = UCI_TYPE_SECTION;
|
||||
goto lastval;
|
||||
} else {
|
||||
ptr->target = UCI_TYPE_OPTION;
|
||||
}
|
||||
|
||||
lastval:
|
||||
if (ptr->section && !buci_validate_section(ptr->section))
|
||||
ptr->flags |= UCI_LOOKUP_EXTENDED;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct uci_section *buci_walk_section(char *package, char *section_type, struct uci_section *prev_section)
|
||||
{
|
||||
struct uci_ptr ptr;
|
||||
struct uci_element *e;
|
||||
struct uci_section *next_section;
|
||||
|
||||
if (section_type == NULL) {
|
||||
if (prev_section) {
|
||||
e = &prev_section->e;
|
||||
if (e->list.next == &prev_section->package->sections)
|
||||
return NULL;
|
||||
e = container_of(e->list.next, struct uci_element, list);
|
||||
next_section = uci_to_section(e);
|
||||
return next_section;
|
||||
}
|
||||
else {
|
||||
if (buci_init_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) {
|
||||
return NULL;
|
||||
}
|
||||
if (ptr.p->sections.next == &ptr.p->sections)
|
||||
return NULL;
|
||||
e = container_of(ptr.p->sections.next, struct uci_element, list);
|
||||
next_section = uci_to_section(e);
|
||||
|
||||
return next_section;
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct uci_list *ul, *shead = NULL;
|
||||
|
||||
if (prev_section) {
|
||||
ul = &prev_section->e.list;
|
||||
shead = &prev_section->package->sections;
|
||||
}
|
||||
else {
|
||||
if (buci_init_ptr(uci_ctx, &ptr, package, NULL, NULL, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) {
|
||||
return NULL;
|
||||
}
|
||||
ul = &ptr.p->sections;
|
||||
shead = &ptr.p->sections;
|
||||
}
|
||||
while (ul->next != shead) {
|
||||
e = container_of(ul->next, struct uci_element, list);
|
||||
next_section = uci_to_section(e);
|
||||
if (strcmp(next_section->type, section_type) == 0)
|
||||
return next_section;
|
||||
ul = ul->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void buci_print_list(struct uci_list *uh, char **val, char *delimiter)
|
||||
{
|
||||
struct uci_element *e;
|
||||
static char buffer[512];
|
||||
char *buf = buffer;
|
||||
*buf = '\0';
|
||||
|
||||
uci_foreach_element(uh, e) {
|
||||
if (*buf) {
|
||||
strcat(buf, delimiter);
|
||||
strcat(buf, e->name);
|
||||
}
|
||||
else {
|
||||
strcpy(buf, e->name);
|
||||
}
|
||||
}
|
||||
*val = buf;
|
||||
}
|
||||
|
||||
struct uci_element *buci_lookup_list(struct uci_list *list, const char *name)
|
||||
{
|
||||
struct uci_element *e;
|
||||
|
||||
uci_foreach_element(list, e) {
|
||||
if (!strcmp(e->name, name))
|
||||
return e;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int uci_lookup_ptr_bysection(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *section, char *option, char *value)
|
||||
{
|
||||
struct uci_element *e;
|
||||
memset(ptr, 0, sizeof(struct uci_ptr));
|
||||
|
||||
ptr->package = section->package->e.name;
|
||||
ptr->section = section->e.name;
|
||||
ptr->option = option;
|
||||
ptr->value = value;
|
||||
ptr->flags |= UCI_LOOKUP_DONE;
|
||||
|
||||
ptr->p = section->package;
|
||||
ptr->s = section;
|
||||
|
||||
if (ptr->option) {
|
||||
e = buci_lookup_list(&ptr->s->options, ptr->option);
|
||||
if (!e)
|
||||
return UCI_OK;
|
||||
ptr->o = uci_to_option(e);
|
||||
ptr->last = e;
|
||||
ptr->target = UCI_TYPE_OPTION;
|
||||
}
|
||||
else {
|
||||
ptr->last = &ptr->s->e;
|
||||
ptr->target = UCI_TYPE_SECTION;
|
||||
}
|
||||
|
||||
ptr->flags |= UCI_LOOKUP_COMPLETE;
|
||||
|
||||
return UCI_OK;
|
||||
}
|
||||
|
||||
char *buci_get_value_bysection(struct uci_section *section, char *option)
|
||||
{
|
||||
struct uci_ptr ptr;
|
||||
char *val = "";
|
||||
|
||||
if (uci_lookup_ptr_bysection(uci_ctx, &ptr, section, option, NULL) != UCI_OK) {
|
||||
return val;
|
||||
}
|
||||
|
||||
if (!ptr.o)
|
||||
return val;
|
||||
|
||||
if(ptr.o->type == UCI_TYPE_LIST) {
|
||||
buci_print_list(&ptr.o->v.list, &val, " ");
|
||||
return val;
|
||||
}
|
||||
|
||||
if (ptr.o->v.string)
|
||||
return ptr.o->v.string;
|
||||
else
|
||||
return val;
|
||||
}
|
||||
|
||||
char *buci_get_value(char *package, char *section, char *option)
|
||||
{
|
||||
struct uci_ptr ptr;
|
||||
char *val = "";
|
||||
|
||||
if (!section || !option)
|
||||
return val;
|
||||
|
||||
if (buci_init_ptr(uci_ctx, &ptr, package, section, option, NULL)) {
|
||||
return val;
|
||||
}
|
||||
if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK) {
|
||||
return val;
|
||||
}
|
||||
|
||||
if (!ptr.o)
|
||||
return val;
|
||||
|
||||
if(ptr.o->type == UCI_TYPE_LIST) {
|
||||
buci_print_list(&ptr.o->v.list, &val, " ");
|
||||
return val;
|
||||
}
|
||||
|
||||
if (ptr.o->v.string)
|
||||
return ptr.o->v.string;
|
||||
else
|
||||
return val;
|
||||
}
|
||||
31
bulkdata/src/buci.h
Normal file
31
bulkdata/src/buci.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __BUCI_H
|
||||
#define __BUCI_H
|
||||
|
||||
#include <uci.h>
|
||||
|
||||
int buci_init(void);
|
||||
int buci_fini(void);
|
||||
struct uci_section *buci_walk_section(char *package, char *section_type, struct uci_section *prev_section);
|
||||
void buci_print_list(struct uci_list *uh, char **val, char *delimiter);
|
||||
struct uci_element *buci_lookup_list(struct uci_list *list, const char *name);
|
||||
int uci_lookup_ptr_bysection(struct uci_context *ctx, struct uci_ptr *ptr, struct uci_section *section, char *option, char *value);
|
||||
char *buci_get_value_bysection(struct uci_section *section, char *option);
|
||||
char *buci_get_value(char *package, char *section, char *option);
|
||||
|
||||
#define buci_foreach_section(package, section_type, section) \
|
||||
for (section = buci_walk_section(package, section_type, NULL); \
|
||||
section != NULL; \
|
||||
section = buci_walk_section(package, section_type, section))
|
||||
|
||||
#endif //__BUCI_H
|
||||
144
bulkdata/src/bulkdata.c
Normal file
144
bulkdata/src/bulkdata.c
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
* Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libubox/uloop.h>
|
||||
|
||||
#include "http.h"
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "common.h"
|
||||
#include "report.h"
|
||||
#include "times.h"
|
||||
#include "bulkdata.h"
|
||||
|
||||
struct bulkdata bulkdata_main = {0};
|
||||
int profiles_number = 0;
|
||||
|
||||
void bulkdata_profile_cb(struct uloop_timeout *timeout);
|
||||
|
||||
int get_retry_period(int min)
|
||||
{
|
||||
srand(time(NULL));
|
||||
return rand()%min + min;
|
||||
}
|
||||
|
||||
static void bulkdata_run_profiles(struct bulkdata *bulkdata)
|
||||
{
|
||||
unsigned int next_period;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < profiles_number; i++) {
|
||||
bulkdata->profile[i].utimer.cb = bulkdata_profile_cb;
|
||||
LIST_HEAD(failedreports);
|
||||
bulkdata->profile[i].failed_reports = &failedreports;
|
||||
next_period = get_next_period(bulkdata->profile[i].time_reference, bulkdata->profile[i].reporting_interval);
|
||||
bulkdata_log(SINFO, "The session of profile_id %d will be start in %d sec", bulkdata->profile[i].profile_id, next_period);
|
||||
uloop_timeout_set(&bulkdata->profile[i].utimer, next_period * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
int http_send_report(struct profile *profile, char *report)
|
||||
{
|
||||
char *msg_in = NULL;
|
||||
int http_code;
|
||||
|
||||
http_client_init(profile);
|
||||
bulkdata_log(SINFO, "Send the report of profile_id %d to Bulkdata Collector", profile->profile_id);
|
||||
http_code = http_send_message(profile, report, strlen(report), &msg_in);
|
||||
http_client_exit();
|
||||
return http_code;
|
||||
}
|
||||
|
||||
void bulkdata_profile_cb(struct uloop_timeout *timeout)
|
||||
{
|
||||
struct profile *profile;
|
||||
unsigned int http_code, retry_period;
|
||||
char *report = NULL;
|
||||
|
||||
profile = container_of(timeout, struct profile, utimer);
|
||||
time_t now = time(NULL);
|
||||
|
||||
bulkdata_log(SINFO, "New session of profile_id %d started", profile->profile_id);
|
||||
if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) //Perdiodic execution
|
||||
create_encoding_bulkdata_report(profile, &report);
|
||||
else
|
||||
create_failed_report(profile, &report);
|
||||
|
||||
bulkdata_log(SDEBUG, "The content of the profile_id report %d is :\n==========\n%s\n==========\n", profile->profile_id, report);
|
||||
http_code= http_send_report(profile, report);
|
||||
if(http_code != 200){
|
||||
if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) { //Perdiodic execution
|
||||
retry_period = get_retry_period(profile->http_retry_minimum_wait_interval);
|
||||
profile->next_period = now + profile->reporting_interval;
|
||||
profile->next_retry = now + retry_period;
|
||||
profile->retry_count = 1;
|
||||
profile->min_retry = profile->http_retry_minimum_wait_interval * 2;
|
||||
if((profile->next_retry < profile->next_period) && profile->http_retry_enable) {
|
||||
bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, retry_period);
|
||||
uloop_timeout_set(timeout, 1000 * retry_period);
|
||||
}
|
||||
else {
|
||||
bulkdata_log(SINFO, "Start New session of profile_id %d in %d sec", profile->profile_id, profile->reporting_interval);
|
||||
uloop_timeout_set(timeout, 1000 * profile->reporting_interval);
|
||||
}
|
||||
} else { //Retry execution
|
||||
retry_period= get_retry_period(profile->min_retry);
|
||||
profile->min_retry*=2;
|
||||
profile->next_retry+=retry_period;
|
||||
profile->retry_count++;
|
||||
if(profile->next_retry < profile->next_period) {
|
||||
bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, retry_period);
|
||||
uloop_timeout_set(timeout, 1000 * retry_period);
|
||||
}
|
||||
else {
|
||||
bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, (profile->next_period-profile->next_retry+retry_period));
|
||||
uloop_timeout_set(timeout, 1000 * (profile->next_period-profile->next_retry+retry_period));
|
||||
}
|
||||
}
|
||||
if(profile->new_report){
|
||||
bulkdata_add_failed_report(profile, profile->new_report);
|
||||
FREE(profile->new_report);
|
||||
}
|
||||
FREE(report);
|
||||
} else {
|
||||
if(profile->retry_count == 0 || profile->next_retry > now || !profile->http_retry_enable) {
|
||||
bulkdata_log(SINFO, "Start New session of profile_id %d in %d sec", profile->profile_id, profile->reporting_interval);
|
||||
uloop_timeout_set(timeout, 1000 * profile->reporting_interval);
|
||||
}
|
||||
else {
|
||||
bulkdata_log(SINFO, "Retry session of profile_id %d in %d sec", profile->profile_id, (profile->next_period-profile->next_retry));
|
||||
uloop_timeout_set(timeout, 1000 * (profile->next_period-profile->next_retry));
|
||||
}
|
||||
FREE(profile->new_report);
|
||||
FREE(report);
|
||||
empty_failed_reports_list(profile);
|
||||
profile->retry_count= 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct bulkdata *bulkdata = &bulkdata_main;
|
||||
if (bulkdata_config_init(bulkdata) == -1)
|
||||
return -1;
|
||||
bulkdata_log(SINFO, "Start bulkdatad daemon");
|
||||
|
||||
uloop_init();
|
||||
bulkdata_run_profiles(bulkdata);
|
||||
uloop_run();
|
||||
uloop_done();
|
||||
|
||||
bulkdata_config_fini(bulkdata);
|
||||
bulkdata_log(SINFO, "Stop bulkdatad daemon");
|
||||
return 0;
|
||||
}
|
||||
18
bulkdata/src/bulkdata.h
Normal file
18
bulkdata/src/bulkdata.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __BULKDATA_H
|
||||
#define __BULKDATA_H
|
||||
|
||||
extern struct bulkdata bulkdata_main;
|
||||
extern int profiles_number;
|
||||
|
||||
#endif /* __BULKDATA_H */
|
||||
105
bulkdata/src/bulkdata.md
Normal file
105
bulkdata/src/bulkdata.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# README #
|
||||
|
||||
bulkdatad is an implementation of The HTTP bulk data collection mechanism which is an extended feature of CPE and other agents implementing TR-069(CWMP) or TR-369(USP), defined by the Broadband Forum. It provides a means by which an Auto-Configuration Server (ACS), or USP Controller, can configure an agent to periodically send a JSON or CSV formatted set of Device information to an HTTP server running a data collection application.
|
||||
|
||||
## Configuration File ##
|
||||
|
||||
The bulkdatad UCI configuration is located in **'/etc/config/bulkdata'**, and contains 4 sections: **bulkdata**, **profile**, **profile\_parameter** and **profile\_http\_request\_uri\_parameter**.
|
||||
|
||||
```
|
||||
config bulkdata 'bulkdata'
|
||||
option enable '0'
|
||||
option log_level '3'
|
||||
|
||||
config profile
|
||||
option profile_id '1'
|
||||
option enable '0'
|
||||
option csv_encoding_row_time_stamp 'unix'
|
||||
option json_encoding_report_time_stamp 'unix'
|
||||
option http_retry_minimum_wait_interval '5'
|
||||
option http_retry_interval_multiplier '2000'
|
||||
|
||||
config profile_parameter
|
||||
option profile_id '1'
|
||||
option name ''
|
||||
option reference ''
|
||||
|
||||
config profile_http_request_uri_parameter
|
||||
option profile_id '1'
|
||||
option name ''
|
||||
option reference ''
|
||||
```
|
||||
|
||||
### bulkdata section ###
|
||||
|
||||
It defines **bulkdata configuration**: enable and log\_level.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ----------- | ------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `enable` | boolean | Enables the BulkData feature if set to **1**. |
|
||||
| `log_level` | integer | Specifies the log type to use, by default **'INFO'**. The possible types are **'EMERG', 'ALERT', 'CRITIC' ,'ERROR', 'WARNING', 'NOTICE', 'INFO' and 'DEBUG'**. |
|
||||
|
||||
### profile section ###
|
||||
|
||||
It defines **the profile section configuration**: enable, name,... The possible options for **profile** section are listed below:
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---------------------------------- | ------- | ---------------------------------------------- |
|
||||
| `profile_id` | integer | The profile id to use. |
|
||||
| `enable` | boolean | If set to **1**, enables the bulkdata profile. |
|
||||
| `name` | string | The name of the profile. |
|
||||
| `nbre_of_retained_failed_reports` | integer | The number of failed reports to be retained and transmitted at the end of the current reporting interval. |
|
||||
| `protocol` | string | The protocol used for the collection profile. |
|
||||
| `encoding_type` | string | The encoding type used for the collection profile. |
|
||||
| `reporting_interval` | integer | The reporting interval in seconds. |
|
||||
| `time_reference` | integer | The time reference to determine when the profile will be transmitted to the ACS collector. |
|
||||
| `csv_encoding_field_separator` | string | The field separator to use when encoding CSV data. |
|
||||
| `csv_encoding_row_separator` | string | The row separator to use when encoding CSV data. |
|
||||
| `csv_encoding_escape_character` | string | The escape character to use when encoding CSV data. |
|
||||
| `csv_encoding_report_format` | string | Describes how reports will be formatted. Two possible formats are supported: **'ParameterPerRow' and 'ParameterPerColumn'**. |
|
||||
| `csv_encoding_row_time_stamp` | string | The format of the timestamp to use for data inserted into the row. The row time stamp supported are **'Unix-Epoch', 'ISO-8601' and 'None'**. |
|
||||
| `json_encoding_report_format` | string | Describes the report format. The supported report formats are **'ObjectHierarchy' and 'NameValuePair'**. |
|
||||
| `json_encoding_report_time_stamp` | string | The format of the timestamp to use for the JSON Object named "CollectionTime". The supported timestamp are **'Unix-Epoch', 'ISO-8601' and 'None'**. |
|
||||
| `http_url` | string | The URL of the collection server. |
|
||||
| `http_username` | string | The username of the collection server. |
|
||||
| `http_password` | string | The password of the collection server. |
|
||||
| `http_compression` | string | The HTTP Compression mechanism used by the collection server. The supported compression mechanism are **'GZIP', 'Compress' and 'Deflate'**. |
|
||||
| `http_method` | string | The HTTP method used by the collection server. Two methods are supported: **'POST' and 'PUT'**. |
|
||||
| `http_use_date_header` | boolean | If set to **1**, the CPE encodes the HTTP Date Header. |
|
||||
| `http_retry_enable` | boolean | If set to **1**, the CPE retries unsuccessful attempts to transfer data. |
|
||||
| `http_retry_minimum_wait_interval` | integer | The data transfer retry wait interval. |
|
||||
| `http_retry_interval_multiplier` | integer | The retry interval multiplier. |
|
||||
| `http_persist_across_reboot` | boolean | If set to **1**, failed data transfers must be persisted across reboots. |
|
||||
|
||||
### profile_parameter section ###
|
||||
|
||||
It defines **the profile\_parameter section configuration**: profile\_id, name, reference.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | ------- | --------------------------------------- |
|
||||
| `profile_id` | integer | The id of the used profile. |
|
||||
| `name` | string | The name of the profile parameter. |
|
||||
| `reference` | string | The reference of the profile parameter. |
|
||||
|
||||
### profile_http_request_uri_parameter section ###
|
||||
|
||||
It defines **the profile\_http\_request\_uri\_parameter section configuration**: profile\_id, name, reference.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------------ | ------- | --------------------------------------- |
|
||||
| `profile_id` | integer | The id of the used profile. |
|
||||
| `name` | string | The name of the Request-URI parameter. |
|
||||
| `reference` | string | The reference of the profile parameter. |
|
||||
|
||||
## Dependencies ##
|
||||
|
||||
To successfully build bulkdatad, the following libraries are needed:
|
||||
|
||||
| Dependency | Link | License |
|
||||
| ----------- | ------------------------------------------- | -------------- |
|
||||
| libuci | https://git.openwrt.org/project/uci.git | LGPL 2.1 |
|
||||
| libubox | https://git.openwrt.org/project/libubox.git | BSD |
|
||||
| libjson-c | https://s3.amazonaws.com/json-c_releases | MIT |
|
||||
| libcurl | https://dl.uxnr.de/mirror/curl | MIT |
|
||||
| libbbfdm | https://dev.iopsys.eu/iopsys/bbf.git | LGPL 2.1 |
|
||||
|
||||
450
bulkdata/src/common.c
Normal file
450
bulkdata/src/common.c
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
* Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static pathnode *head = NULL;
|
||||
static pathnode *temphead = NULL;
|
||||
|
||||
int bulkdata_dm_ctx_init(struct dmctx *ctx)
|
||||
{
|
||||
struct bulkdata *bulkdata = &bulkdata_main;
|
||||
dm_ctx_init(ctx, bulkdata->instance_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bulkdata_dm_ctx_clean(struct dmctx *ctx)
|
||||
{
|
||||
dm_ctx_clean(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char **str_split(const char* str, const char* delim, size_t* numtokens)
|
||||
{
|
||||
char *s = strdup(str);
|
||||
size_t tokens_alloc = 1;
|
||||
size_t tokens_used = 0;
|
||||
char **tokens = calloc(tokens_alloc, sizeof(char*));
|
||||
char *token, *strtok_ctx;
|
||||
for (token = strtok_r(s, delim, &strtok_ctx); token != NULL; token = strtok_r(NULL, delim, &strtok_ctx)) {
|
||||
if (tokens_used == tokens_alloc) {
|
||||
tokens_alloc *= 2;
|
||||
tokens = realloc(tokens, tokens_alloc * sizeof(char*));
|
||||
}
|
||||
tokens[tokens_used++] = strdup(token);
|
||||
}
|
||||
// cleanup
|
||||
if (tokens_used == 0) {
|
||||
FREE(tokens);
|
||||
} else {
|
||||
tokens = realloc(tokens, tokens_used * sizeof(char*));
|
||||
}
|
||||
*numtokens = tokens_used;
|
||||
FREE(s);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
static bool bulkdata_match(const char *string, const char *pattern)
|
||||
{
|
||||
regex_t re;
|
||||
if (regcomp(&re, pattern, REG_EXTENDED) != 0) return 0;
|
||||
int status = regexec(&re, string, 0, NULL, 0);
|
||||
regfree(&re);
|
||||
if (status != 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_res_required(char *str, int *start, int *len)
|
||||
{
|
||||
char temp_char[NAME_MAX] = {'\0'};
|
||||
|
||||
if (bulkdata_match(str, GLOB_CHAR)) {
|
||||
int s_len = strlen(str);
|
||||
int b_len = s_len, p_len = s_len;
|
||||
|
||||
char *star = strchr(str, '*');
|
||||
if(star)
|
||||
s_len = star - str;
|
||||
*start = MIN(MIN(s_len, p_len), b_len);
|
||||
if (*start == s_len)
|
||||
*len = 1;
|
||||
|
||||
strncpy(temp_char, str+*start, *len);
|
||||
|
||||
if (bulkdata_match(temp_char, "[*+]+"))
|
||||
return true;
|
||||
}
|
||||
*start = strlen(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void insert(char *data, bool active)
|
||||
{
|
||||
pathnode *link = (pathnode*) calloc(1, sizeof(pathnode));
|
||||
if(!link) {
|
||||
return;
|
||||
}
|
||||
|
||||
link->ref_path = data;
|
||||
|
||||
if(active) {
|
||||
link->next = head;
|
||||
head = link;
|
||||
} else {
|
||||
link->next = temphead;
|
||||
temphead = link;
|
||||
}
|
||||
}
|
||||
|
||||
static void swap_heads(void)
|
||||
{
|
||||
pathnode *temp = head;
|
||||
head = temphead;
|
||||
temphead = temp;
|
||||
}
|
||||
|
||||
static void deleteList(void)
|
||||
{
|
||||
pathnode *ptr = head, *temp;
|
||||
while(ptr != NULL) {
|
||||
temp = ptr;
|
||||
free(ptr->ref_path);
|
||||
if(ptr->next != NULL) {
|
||||
ptr = ptr->next;
|
||||
} else {
|
||||
ptr = NULL;
|
||||
}
|
||||
free(temp);
|
||||
}
|
||||
head = NULL;
|
||||
swap_heads();
|
||||
}
|
||||
|
||||
void bulkdata_add_data_to_list(struct list_head *dup_list, char *name, char *value, char *type)
|
||||
{
|
||||
struct resultsnode *link;
|
||||
link = calloc(1, sizeof(struct resultsnode));
|
||||
list_add_tail(&link->list, dup_list);
|
||||
link->name = strdup(name);
|
||||
link->data = strdup(value);
|
||||
link->type = strdup(type);
|
||||
}
|
||||
|
||||
void bulkdata_delete_data_from_list(struct resultsnode *link)
|
||||
{
|
||||
list_del(&link->list);
|
||||
FREE(link->name);
|
||||
FREE(link->data);
|
||||
FREE(link->type);
|
||||
FREE(link);
|
||||
}
|
||||
|
||||
void bulkdata_free_data_from_list(struct list_head *dup_list)
|
||||
{
|
||||
struct resultsnode *link;
|
||||
while (dup_list->next != dup_list) {
|
||||
link = list_entry(dup_list->next, struct resultsnode, list);
|
||||
bulkdata_delete_data_from_list(link);
|
||||
}
|
||||
}
|
||||
|
||||
static bool bulkdata_get(int operation, char *path, struct dmctx *dm_ctx)
|
||||
{
|
||||
int fault = 0;
|
||||
|
||||
switch(operation) {
|
||||
case CMD_GET_NAME:
|
||||
fault = dm_entry_param_method(dm_ctx, CMD_GET_NAME, path, "true", NULL);
|
||||
break;
|
||||
case CMD_GET_VALUE:
|
||||
fault = dm_entry_param_method(dm_ctx, CMD_GET_VALUE, path, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dm_ctx->list_fault_param.next != &dm_ctx->list_fault_param) {
|
||||
return false;
|
||||
}
|
||||
if (fault) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
char *bulkdata_get_value_param(char *path)
|
||||
{
|
||||
struct dmctx ctx = {0};
|
||||
struct dm_parameter *n;
|
||||
char *value = NULL;
|
||||
|
||||
bulkdata_dm_ctx_init(&ctx);
|
||||
if(bulkdata_get(CMD_GET_VALUE, path, &ctx)) {
|
||||
list_for_each_entry(n, &ctx.list_parameter, list) {
|
||||
value = strdup(n->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
bulkdata_dm_ctx_clean(&ctx);
|
||||
return value;
|
||||
}
|
||||
|
||||
void bulkdata_get_value(char *path, struct list_head *list)
|
||||
{
|
||||
struct dmctx ctx = {0};
|
||||
struct dm_parameter *n;
|
||||
|
||||
bulkdata_dm_ctx_init(&ctx);
|
||||
if(bulkdata_get(CMD_GET_VALUE, path, &ctx)) {
|
||||
list_for_each_entry(n, &ctx.list_parameter, list) {
|
||||
bulkdata_add_data_to_list(list, n->name, n->data, n->type);
|
||||
}
|
||||
}
|
||||
bulkdata_dm_ctx_clean(&ctx);
|
||||
}
|
||||
|
||||
bool bulkdata_get_name(char *path)
|
||||
{
|
||||
struct dmctx ctx = {0};
|
||||
struct dm_parameter *n;
|
||||
bool ret = false;
|
||||
|
||||
bulkdata_dm_ctx_init(&ctx);
|
||||
if(bulkdata_get(CMD_GET_NAME, path, &ctx)) {
|
||||
list_for_each_entry(n, &ctx.list_parameter, list) {
|
||||
insert(strdup(n->name), false);
|
||||
}
|
||||
ret = true;
|
||||
}
|
||||
bulkdata_dm_ctx_clean(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void fill_node_path(void)
|
||||
{
|
||||
pathnode *p=head;
|
||||
while(p!=NULL) {
|
||||
bulkdata_get_name(p->ref_path);
|
||||
p=p->next;
|
||||
}
|
||||
deleteList();
|
||||
}
|
||||
|
||||
static void bulkdata_filter_results(char *path, int start, int end)
|
||||
{
|
||||
int startpos = start, m_index = 0, m_len = 0;
|
||||
char *pp = path + startpos;
|
||||
char exp[NAME_MAX] = {'\0'};
|
||||
|
||||
if(start >= end) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is_res_required(pp, &m_index, &m_len)) {
|
||||
//append rest of the path to the final list
|
||||
if(pp == path ) {
|
||||
insert(strdup(pp), true);
|
||||
return;
|
||||
}
|
||||
|
||||
pathnode *p = head;
|
||||
while(p != NULL) {
|
||||
char name[NAME_MAX] = {'\0'};
|
||||
strcpy(name, p->ref_path);
|
||||
strcat(name, pp);
|
||||
insert(strdup(name), false);
|
||||
p = p->next;
|
||||
}
|
||||
deleteList();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the string before the match
|
||||
char name[NAME_MAX]={'\0'};
|
||||
strncpy(name, pp, m_index);
|
||||
|
||||
pathnode *p = head;
|
||||
if(p == NULL) {
|
||||
insert(strdup(name), false);
|
||||
}
|
||||
|
||||
while(p != NULL) {
|
||||
char ref_name[NAME_MAX] = {'\0'};
|
||||
sprintf(ref_name, "%s%s", p->ref_path, name);
|
||||
insert(strdup(ref_name), false);
|
||||
p = p->next;
|
||||
}
|
||||
deleteList();
|
||||
|
||||
startpos += m_index;
|
||||
strncpy(exp, pp+m_index, m_len);
|
||||
pp = path + startpos;
|
||||
fill_node_path();
|
||||
startpos += 2;
|
||||
bulkdata_filter_results(path, startpos, end);
|
||||
}
|
||||
|
||||
static void bulkdata_parse_results(struct list_head *list)
|
||||
{
|
||||
pathnode *p = head;
|
||||
while(p != NULL) {
|
||||
bulkdata_get_value(p->ref_path, list);
|
||||
p = p->next;
|
||||
}
|
||||
deleteList();
|
||||
}
|
||||
|
||||
void bulkdata_get_value_results(char *path, struct list_head *list)
|
||||
{
|
||||
bulkdata_filter_results(path, 0, strlen(path));
|
||||
bulkdata_parse_results(list);
|
||||
}
|
||||
|
||||
char *create_request_url(struct profile *profile)
|
||||
{
|
||||
int i = 0, http_uri_number = profile->profile_http_request_uri_parameter_number;
|
||||
char *value, *uri_param = NULL, *uri_tmp = NULL, *http_url = NULL;
|
||||
|
||||
for (i = 0; i < http_uri_number; i++)
|
||||
{
|
||||
if((profile->profile_http_uri_parameter[i].reference == NULL) || (profile->profile_http_uri_parameter[i].name == NULL))
|
||||
continue;
|
||||
value = bulkdata_get_value_param(profile->profile_http_uri_parameter[i].reference);
|
||||
if(!uri_param) {
|
||||
asprintf(&uri_param, "&%s=%s", profile->profile_http_uri_parameter[i].name, value);
|
||||
free(value);
|
||||
}
|
||||
else {
|
||||
uri_tmp = strdup(uri_param);
|
||||
free(uri_param);
|
||||
asprintf(&uri_param, "%s&%s=%s", uri_tmp, profile->profile_http_uri_parameter[i].name, value);
|
||||
free(value);
|
||||
free(uri_tmp);
|
||||
}
|
||||
}
|
||||
if(uri_param) {
|
||||
asprintf(&http_url, "%s%s", profile->http_url, uri_param);
|
||||
free(uri_param);
|
||||
} else {
|
||||
asprintf(&http_url, "%s", profile->http_url);
|
||||
}
|
||||
return http_url;
|
||||
}
|
||||
|
||||
char *get_bulkdata_profile_parameter_name(char *paramref, char *paramname, char *param)
|
||||
{
|
||||
char **paramarr, *idx1 = NULL, *idx2 = NULL, *res = NULL, *instance = NULL, *tmp = NULL, *retparam = NULL, *s = NULL;
|
||||
int i, j = 0;
|
||||
size_t length;
|
||||
|
||||
if(paramname == NULL || strlen(paramname) <= 0)
|
||||
return strdup(param);
|
||||
paramarr = str_split(paramref, "*", &length);
|
||||
res = strdup(paramname);
|
||||
for(i = 0; i < length; i++) {
|
||||
if(i == length - 1)
|
||||
break;
|
||||
j++;
|
||||
idx1 = strstr(param, paramarr[i]);
|
||||
idx2 = strstr(param, paramarr[i+1]);
|
||||
instance = (char*)calloc(idx2 - idx1 - strlen(paramarr[i]) + 1, sizeof(char));
|
||||
memcpy(instance, idx1 + strlen(paramarr[i]), idx2 - idx1 - strlen(paramarr[i]));
|
||||
tmp = strdup(res);
|
||||
FREE(res);
|
||||
asprintf(&res, "%s.%s", tmp, instance);
|
||||
FREE(tmp);
|
||||
FREE(instance);
|
||||
}
|
||||
if ((s = strstr(param,paramarr[j]) ) != NULL && strlen(s) == strlen(paramarr[j]))
|
||||
asprintf(&retparam, "%s", res);
|
||||
else
|
||||
asprintf(&retparam, "%s.%s", res, strstr(param, paramarr[j]) + strlen(paramarr[j]));
|
||||
|
||||
FREE(res);
|
||||
for(int k = 0; k < length; k++)
|
||||
FREE(paramarr[k]);
|
||||
FREE(paramarr);
|
||||
|
||||
return retparam;
|
||||
}
|
||||
|
||||
void append_string_to_string(char *strappend, char **target)
|
||||
{
|
||||
char *tmp = NULL;
|
||||
|
||||
if(strappend == NULL || strlen(strappend) <= 0)
|
||||
return;
|
||||
if(*target == NULL || strlen(*target) <= 0) {
|
||||
*target = strdup(strappend);
|
||||
return;
|
||||
} else {
|
||||
tmp = strdup(*target);
|
||||
FREE(*target);
|
||||
}
|
||||
asprintf(target, "%s%s", tmp, strappend);
|
||||
FREE(tmp);
|
||||
}
|
||||
|
||||
void bulkdata_add_failed_report(struct profile *profile, char *freport)
|
||||
{
|
||||
struct failed_reports *report, *retreport, *rtmp;
|
||||
|
||||
if(profile->nbre_failed_reports < profile->nbre_of_retained_failed_reports || profile->nbre_of_retained_failed_reports < 0) {
|
||||
profile->nbre_failed_reports++;
|
||||
} else {
|
||||
list_for_each_entry_safe(retreport, rtmp, profile->failed_reports, list) {
|
||||
bulkdata_delete_failed_report(retreport);
|
||||
break;
|
||||
}
|
||||
}
|
||||
report = calloc(1, sizeof(struct failed_reports));
|
||||
list_add_tail(&report->list, profile->failed_reports);
|
||||
report->freport= strdup(freport);
|
||||
}
|
||||
|
||||
void bulkdata_delete_failed_report(struct failed_reports *report)
|
||||
{
|
||||
if(report != NULL) {
|
||||
list_del(&report->list);
|
||||
FREE(report->freport);
|
||||
FREE(report);
|
||||
}
|
||||
}
|
||||
|
||||
struct failed_reports* empty_failed_reports_list(struct profile *profile)
|
||||
{
|
||||
struct failed_reports *report, *rtmp;
|
||||
|
||||
if(list_empty(profile->failed_reports))
|
||||
return NULL;
|
||||
list_for_each_entry_safe(report, rtmp, profile->failed_reports, list) {
|
||||
list_del(&report->list);
|
||||
FREE(report->freport);
|
||||
FREE(report);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void add_failed_reports_to_report_csv(struct profile *profile, char **report, int isnext)
|
||||
{
|
||||
struct failed_reports *retreport = NULL;
|
||||
int j = 0;
|
||||
|
||||
if(list_empty(profile->failed_reports))
|
||||
return;
|
||||
list_for_each_entry(retreport, profile->failed_reports, list) {
|
||||
if(!j && isnext) {
|
||||
j = 1;
|
||||
continue;
|
||||
}
|
||||
append_string_to_string(retreport->freport, report);
|
||||
}
|
||||
}
|
||||
69
bulkdata/src/common.h
Normal file
69
bulkdata/src/common.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COMMON_H
|
||||
#define __COMMON_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <regex.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <libubox/blobmsg.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
#include <libubox/utils.h>
|
||||
#include <libubus.h>
|
||||
|
||||
#include <libbbfdm/dmentry.h>
|
||||
#include <libbbfdm/dmbbfcommon.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "bulkdata.h"
|
||||
|
||||
typedef struct pathnode {
|
||||
char *ref_path;
|
||||
struct pathnode *next;
|
||||
} pathnode;
|
||||
|
||||
typedef struct resultsnode {
|
||||
struct list_head list;
|
||||
char *name;
|
||||
char *data;
|
||||
char *type;
|
||||
} resultsnode;
|
||||
|
||||
struct failed_reports {
|
||||
struct list_head list;
|
||||
char *freport;
|
||||
};
|
||||
|
||||
#define GLOB_CHAR "[[+*]+"
|
||||
|
||||
int bulkdata_dm_ctx_init(struct dmctx *ctx);
|
||||
int bulkdata_dm_ctx_clean(struct dmctx *ctx);
|
||||
|
||||
char *bulkdata_get_value_param(char *path);
|
||||
void bulkdata_get_value(char *path, struct list_head *list);
|
||||
|
||||
void bulkdata_free_data_from_list(struct list_head *dup_list);
|
||||
void bulkdata_get_value_results(char *path, struct list_head *list);
|
||||
char *create_request_url(struct profile *profile);
|
||||
char *get_bulkdata_profile_parameter_name(char *paramref, char *paramname, char *param);
|
||||
void append_string_to_string(char *strappend, char **target);
|
||||
void bulkdata_add_failed_report(struct profile *profile, char *freport);
|
||||
void bulkdata_delete_failed_report(struct failed_reports *report);
|
||||
|
||||
struct failed_reports *empty_failed_reports_list(struct profile *profile);
|
||||
void add_failed_reports_to_report_csv(struct profile *profile, char **report, int isnext);
|
||||
|
||||
#endif //__COMMON_H
|
||||
523
bulkdata/src/config.c
Normal file
523
bulkdata/src/config.c
Normal file
@@ -0,0 +1,523 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
* Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "config.h"
|
||||
#include "buci.h"
|
||||
#include "common.h"
|
||||
#include "bulkdata.h"
|
||||
|
||||
int get_log_level_config(struct bulkdata *bulkdata)
|
||||
{
|
||||
char *value = NULL;
|
||||
|
||||
buci_init();
|
||||
value = buci_get_value("bulkdata", "bulkdata", "log_level");
|
||||
if(value != NULL && *value != '\0')
|
||||
bulkdata->log_level = atoi(value);
|
||||
else
|
||||
bulkdata->log_level = DEFAULT_LOGLEVEL;
|
||||
bulkdata_log(SDEBUG,"Log Level of Bulkdata is : %d", bulkdata->log_level);
|
||||
buci_fini();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_amd_version_config(struct bulkdata *bulkdata)
|
||||
{
|
||||
char *value = NULL;
|
||||
|
||||
buci_init();
|
||||
value = buci_get_value("cwmp", "cpe", "amd_version");
|
||||
if(value != NULL && *value != '\0')
|
||||
bulkdata->amd_version = atoi(value);
|
||||
else
|
||||
bulkdata->amd_version = DEFAULT_AMD_VERSION;
|
||||
bulkdata_log(SDEBUG,"CWMP Amendment Version is : %d", bulkdata->amd_version);
|
||||
buci_fini();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_instance_mode_config(struct bulkdata *bulkdata)
|
||||
{
|
||||
char *value = NULL;
|
||||
|
||||
buci_init();
|
||||
value = buci_get_value("cwmp", "cpe", "instance_mode");
|
||||
if(value != NULL && *value != '\0') {
|
||||
if(!strcmp(value, "InstanceNumber"))
|
||||
bulkdata->instance_mode = INSTANCE_MODE_NUMBER;
|
||||
else
|
||||
bulkdata->instance_mode = INSTANCE_MODE_ALIAS;
|
||||
}
|
||||
else
|
||||
bulkdata->instance_mode = DEFAULT_INSTANCE_MODE;
|
||||
bulkdata_log(SDEBUG,"CWMP Instance Mode is : %d", bulkdata->instance_mode);
|
||||
buci_fini();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_device_id_config(struct bulkdata *bulkdata)
|
||||
{
|
||||
struct dmctx dmctx = {0};
|
||||
|
||||
bulkdata_dm_ctx_init(&dmctx);
|
||||
bulkdata->device_id.manufacturer_oui = bulkdata_get_value_param("Device.DeviceInfo.ManufacturerOUI");
|
||||
bulkdata->device_id.product_class = bulkdata_get_value_param("Device.DeviceInfo.ProductClass");
|
||||
bulkdata->device_id.serial_number = bulkdata_get_value_param("Device.DeviceInfo.SerialNumber");
|
||||
bulkdata_dm_ctx_clean(&dmctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_profile_config(struct bulkdata *bulkdata, struct uci_section *s, int i)
|
||||
{
|
||||
char *value = NULL;
|
||||
|
||||
value = buci_get_value_bysection(s, "profile_id");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].profile_id = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The profile_id of profile_id %d is : %d", i, bulkdata->profile[i].profile_id);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "nbre_of_retained_failed_reports");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].nbre_of_retained_failed_reports = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The nombre of retained failed reports of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].nbre_of_retained_failed_reports);
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "protocol");
|
||||
if(value != NULL && *value != '\0' && strcasecmp(value, "http")==0) {
|
||||
bulkdata->profile[i].protocol = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The protocol of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].protocol);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "encoding_type");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].encoding_type = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The encoding type of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].encoding_type);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "reporting_interval");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].reporting_interval = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The reporting interval of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].reporting_interval);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "time_reference");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].time_reference = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The time reference of profile_id %d is : %ld", bulkdata->profile[i].profile_id, bulkdata->profile[i].time_reference);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "csv_encoding_field_separator");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].csv_encoding_field_separator = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The csv encoding field separator of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_field_separator);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "csv_encoding_row_separator");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].csv_encoding_row_separator = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The csv encoding row separator of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_row_separator);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "csv_encoding_escape_character");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].csv_encoding_escape_character = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The csv encoding escape character of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_escape_character);
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "csv_encoding_report_format");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].csv_encoding_report_format = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The csv encoding report format of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_report_format);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "csv_encoding_row_time_stamp");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].csv_encoding_row_time_stamp = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The csv encoding row time stamp of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].csv_encoding_row_time_stamp);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "json_encoding_report_format");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].json_encoding_report_format = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The json encoding report format of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].json_encoding_report_format);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "json_encoding_report_time_stamp");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].json_encoding_report_time_stamp = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The json encoding report time stamp of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].json_encoding_report_time_stamp);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "http_url");
|
||||
if(value != NULL && *value != '\0') {
|
||||
char *url = NULL;
|
||||
asprintf(&url, "%s?oui=%s&pc=%s&sn=%s", value, bulkdata->device_id.manufacturer_oui, bulkdata->device_id.serial_number, bulkdata->device_id.serial_number);
|
||||
bulkdata->profile[i].http_url = strdup(url);
|
||||
free(url);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP url of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_url);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "http_username");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_username = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP username of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_username);
|
||||
} else {
|
||||
bulkdata->profile[i].http_username = NULL;
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "http_password");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_password = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP password of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_password);
|
||||
} else {
|
||||
bulkdata->profile[i].http_password = NULL;
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "http_compression");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_compression = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP compression of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_compression);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "http_method");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_method = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP method of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_method);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "http_use_date_header");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_use_date_header = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP use date header of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_use_date_header);
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "http_retry_enable");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_retry_enable = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP retry enable of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_enable);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "http_retry_minimum_wait_interval");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_retry_minimum_wait_interval = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP retry minimum wait interval of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_minimum_wait_interval);
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "http_retry_interval_multiplier");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_retry_interval_multiplier = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP retry interval multiplier of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_retry_interval_multiplier);
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "http_persist_across_reboot");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_persist_across_reboot = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP persist across reboot of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_persist_across_reboot);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "http_ssl_capath");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_ssl_capath = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP ssl capath of profile_id %d is : %s", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_ssl_capath);
|
||||
} else {
|
||||
bulkdata->profile[i].http_ssl_capath = NULL;
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "http_insecure_enable");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].http_insecure_enable = atoi(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP insecure enable of profile_id %d is : %d", bulkdata->profile[i].profile_id, bulkdata->profile[i].http_insecure_enable);
|
||||
}
|
||||
|
||||
bulkdata->profile[i].retry_count = 0;
|
||||
bulkdata->profile[i].nbre_failed_reports = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_profiles_enable(struct bulkdata *bulkdata)
|
||||
{
|
||||
struct uci_section *s;
|
||||
char *enable;
|
||||
int i = 0, nbr_profiles = 0;
|
||||
|
||||
buci_init();
|
||||
|
||||
buci_foreach_section("bulkdata", "profile", s) {
|
||||
enable = buci_get_value_bysection(s, "enable");
|
||||
if(strcmp(enable, "1") == 0) {
|
||||
nbr_profiles++;
|
||||
}
|
||||
}
|
||||
|
||||
if(nbr_profiles != 0)
|
||||
bulkdata->profile = calloc(2, sizeof(struct profile));
|
||||
|
||||
buci_foreach_section("bulkdata", "profile", s) {
|
||||
enable = buci_get_value_bysection(s, "enable");
|
||||
if(strcmp(enable, "1") == 0) {
|
||||
if(load_profile_config(bulkdata, s, i) == -1) {
|
||||
bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile must be set");
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
profiles_number = nbr_profiles;
|
||||
|
||||
buci_fini();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_profile_parameter_config(struct bulkdata *bulkdata, struct uci_section *s, int i, int j)
|
||||
{
|
||||
char *value = NULL;
|
||||
|
||||
value = buci_get_value_bysection(s, "name");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].profile_parameter[j].name = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The parameter name %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_parameter[j].name);
|
||||
} else {
|
||||
bulkdata->profile[i].profile_parameter[j].name = NULL;
|
||||
}
|
||||
|
||||
value = buci_get_value_bysection(s, "reference");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].profile_parameter[j].reference = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The parameter reference %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_parameter[j].reference);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_profiles_parameters(struct bulkdata *bulkdata)
|
||||
{
|
||||
struct uci_section *s;
|
||||
char *profile_id;
|
||||
int i, j, nbr_profile_parameters;
|
||||
|
||||
buci_init();
|
||||
|
||||
for (i = 0; i < profiles_number; i++) {
|
||||
j = 0;
|
||||
nbr_profile_parameters = 0;
|
||||
buci_foreach_section("bulkdata", "profile_parameter", s) {
|
||||
profile_id = buci_get_value_bysection(s, "profile_id");
|
||||
if(bulkdata->profile[i].profile_id != atoi(profile_id))
|
||||
continue;
|
||||
nbr_profile_parameters++;
|
||||
if(nbr_profile_parameters == 1) {
|
||||
bulkdata->profile[i].profile_parameter = calloc(1, sizeof(struct profile_parameter));
|
||||
} else {
|
||||
bulkdata->profile[i].profile_parameter = realloc(bulkdata->profile[i].profile_parameter, nbr_profile_parameters * sizeof(struct profile_parameter));
|
||||
}
|
||||
if(load_profile_parameter_config(bulkdata, s, i, j) == -1) {
|
||||
bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile_parameter must be set");
|
||||
return -1;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
bulkdata->profile[i].profile_parameter_number = nbr_profile_parameters;
|
||||
}
|
||||
|
||||
buci_fini();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_profile_http_request_uri_parameter_config(struct bulkdata *bulkdata, struct uci_section *s, int i, int j)
|
||||
{
|
||||
char *value = NULL;
|
||||
|
||||
value = buci_get_value_bysection(s, "name");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].profile_http_uri_parameter[j].name = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP resuest URI parameter name %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_http_uri_parameter[j].name);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
value = buci_get_value_bysection(s, "reference");
|
||||
if(value != NULL && *value != '\0') {
|
||||
bulkdata->profile[i].profile_http_uri_parameter[j].reference = strdup(value);
|
||||
value = NULL;
|
||||
bulkdata_log(SDEBUG,"The HTTP resuest URI parameter reference %d of profile_id %d is : %s", j+1, bulkdata->profile[i].profile_id, bulkdata->profile[i].profile_http_uri_parameter[j].reference);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_profile_http_request_uri_parameter(struct bulkdata *bulkdata)
|
||||
{
|
||||
struct uci_section *s;
|
||||
char *profile_id;
|
||||
int i, j, nbr_profile_http_request_uri_parameter;
|
||||
|
||||
buci_init();
|
||||
|
||||
for (i = 0; i < profiles_number; i++) {
|
||||
j = 0;
|
||||
nbr_profile_http_request_uri_parameter = 0;
|
||||
buci_foreach_section("bulkdata", "profile_http_request_uri_parameter", s) {
|
||||
profile_id = buci_get_value_bysection(s, "profile_id");
|
||||
if(bulkdata->profile[i].profile_id != atoi(profile_id))
|
||||
continue;
|
||||
nbr_profile_http_request_uri_parameter++;
|
||||
if(nbr_profile_http_request_uri_parameter == 1) {
|
||||
bulkdata->profile[i].profile_http_uri_parameter = calloc(1, sizeof(struct profile_http_request_uri_parameter));
|
||||
} else {
|
||||
bulkdata->profile[i].profile_http_uri_parameter = realloc(bulkdata->profile[i].profile_http_uri_parameter, nbr_profile_http_request_uri_parameter * sizeof(struct profile_http_request_uri_parameter));
|
||||
}
|
||||
if(load_profile_http_request_uri_parameter_config(bulkdata, s, i, j)== -1) {
|
||||
bulkdata_log(SCRIT,"Not able to start bulkdata: some required bulkdata configurations in profile_http_request_uri_parameter must be set");
|
||||
return -1;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
bulkdata->profile[i].profile_http_request_uri_parameter_number = nbr_profile_http_request_uri_parameter;
|
||||
}
|
||||
|
||||
buci_fini();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bulkdata_config_init(struct bulkdata *bulkdata)
|
||||
{
|
||||
get_log_level_config(bulkdata);
|
||||
get_amd_version_config(bulkdata);
|
||||
get_instance_mode_config(bulkdata);
|
||||
get_device_id_config(bulkdata);
|
||||
if (get_profiles_enable(bulkdata) == -1)
|
||||
return -1;
|
||||
if (get_profiles_parameters(bulkdata) == -1)
|
||||
return -1;
|
||||
if (get_profile_http_request_uri_parameter(bulkdata) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int free_device_id_config(struct bulkdata *bulkdata)
|
||||
{
|
||||
FREE(bulkdata->device_id.manufacturer_oui);
|
||||
FREE(bulkdata->device_id.product_class);
|
||||
FREE(bulkdata->device_id.serial_number);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int free_profiles_enable(struct bulkdata *bulkdata)
|
||||
{
|
||||
for(int i = 0; i < profiles_number; i++) {
|
||||
FREE(bulkdata->profile[i].protocol);
|
||||
FREE(bulkdata->profile[i].encoding_type);
|
||||
FREE(bulkdata->profile[i].csv_encoding_field_separator);
|
||||
FREE(bulkdata->profile[i].csv_encoding_row_separator);
|
||||
FREE(bulkdata->profile[i].csv_encoding_escape_character);
|
||||
FREE(bulkdata->profile[i].csv_encoding_report_format);
|
||||
FREE(bulkdata->profile[i].csv_encoding_row_time_stamp);
|
||||
FREE(bulkdata->profile[i].json_encoding_report_format);
|
||||
FREE(bulkdata->profile[i].json_encoding_report_time_stamp);
|
||||
FREE(bulkdata->profile[i].http_url);
|
||||
FREE(bulkdata->profile[i].http_username);
|
||||
FREE(bulkdata->profile[i].http_password);
|
||||
FREE(bulkdata->profile[i].http_compression);
|
||||
FREE(bulkdata->profile[i].http_method);
|
||||
FREE(bulkdata->profile[i].http_ssl_capath);
|
||||
}
|
||||
FREE(bulkdata->profile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int free_profiles_parameters(struct bulkdata *bulkdata)
|
||||
{
|
||||
for(int i = 0; i < profiles_number; i++) {
|
||||
for(int j = 0; j < bulkdata->profile[i].profile_parameter_number; j++) {
|
||||
FREE(bulkdata->profile[i].profile_parameter[j].name);
|
||||
FREE(bulkdata->profile[i].profile_parameter[j].reference);
|
||||
}
|
||||
FREE(bulkdata->profile[i].profile_parameter);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int free_profile_http_request_uri_parameter(struct bulkdata *bulkdata)
|
||||
{
|
||||
for(int i = 0; i < profiles_number; i++) {
|
||||
for(int j = 0; j < bulkdata->profile[i].profile_http_request_uri_parameter_number; j++) {
|
||||
FREE(bulkdata->profile[i].profile_http_uri_parameter[j].name);
|
||||
FREE(bulkdata->profile[i].profile_http_uri_parameter[j].reference);
|
||||
}
|
||||
FREE(bulkdata->profile[i].profile_http_uri_parameter);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bulkdata_config_fini(struct bulkdata *bulkdata)
|
||||
{
|
||||
free_device_id_config(bulkdata);
|
||||
free_profiles_parameters(bulkdata);
|
||||
free_profile_http_request_uri_parameter(bulkdata);
|
||||
free_profiles_enable(bulkdata);
|
||||
return 0;
|
||||
}
|
||||
103
bulkdata/src/config.h
Normal file
103
bulkdata/src/config.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <libubox/uloop.h>
|
||||
|
||||
#define DEFAULT_AMD_VERSION 2
|
||||
#define DEFAULT_INSTANCE_MODE 0
|
||||
|
||||
typedef struct device_id {
|
||||
char *manufacturer_oui;
|
||||
char *product_class;
|
||||
char *serial_number;
|
||||
} device_id;
|
||||
|
||||
typedef struct profile_parameter {
|
||||
int profile_id;
|
||||
char *name;
|
||||
char *reference;
|
||||
} profile_parameter;
|
||||
|
||||
typedef struct profile_http_request_uri_parameter {
|
||||
int profile_id;
|
||||
char *name;
|
||||
char *reference;
|
||||
} profile_http_request_uri_parameter;
|
||||
|
||||
typedef struct profile {
|
||||
struct uloop_timeout utimer;
|
||||
int profile_id;
|
||||
int nbre_of_retained_failed_reports;
|
||||
int nbre_failed_reports;
|
||||
int reporting_interval;
|
||||
int profile_parameter_number;
|
||||
int profile_http_request_uri_parameter_number;
|
||||
int http_retry_minimum_wait_interval;
|
||||
int http_retry_interval_multiplier;
|
||||
int min_retry;
|
||||
int retry_count;
|
||||
char *protocol;
|
||||
char *encoding_type;
|
||||
char *csv_encoding_field_separator;
|
||||
char *csv_encoding_row_separator;
|
||||
char *csv_encoding_escape_character;
|
||||
char *csv_encoding_report_format;
|
||||
char *csv_encoding_row_time_stamp;
|
||||
char *json_encoding_report_format;
|
||||
char *json_encoding_report_time_stamp;
|
||||
char *http_url;
|
||||
char *http_username;
|
||||
char *http_password;
|
||||
char *http_compression;
|
||||
char *http_method;
|
||||
char *http_ssl_capath;
|
||||
char *new_report;
|
||||
time_t time_reference;
|
||||
time_t next_retry;
|
||||
time_t next_period;
|
||||
bool http_persist_across_reboot;
|
||||
bool http_insecure_enable;
|
||||
bool enable;
|
||||
bool http_use_date_header;
|
||||
bool http_retry_enable;
|
||||
struct profile_parameter *profile_parameter;
|
||||
struct profile_http_request_uri_parameter *profile_http_uri_parameter;
|
||||
struct list_head *failed_reports;
|
||||
} profile;
|
||||
|
||||
typedef struct bulkdata {
|
||||
struct device_id device_id;
|
||||
struct profile *profile;
|
||||
int log_level;
|
||||
int amd_version;
|
||||
unsigned int instance_mode;
|
||||
} bulkdata;
|
||||
|
||||
int bulkdata_config_init(struct bulkdata *bulkdata);
|
||||
int bulkdata_config_fini(struct bulkdata *bulkdata);
|
||||
|
||||
#ifndef FREE
|
||||
#define FREE(x) do { if(x) {free(x); x = NULL;} } while (0)
|
||||
#endif
|
||||
|
||||
#endif //__CONFIG_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1293
bulkdata/src/datamodel.c
Normal file
1293
bulkdata/src/datamodel.c
Normal file
File diff suppressed because it is too large
Load Diff
29
bulkdata/src/datamodel.h
Normal file
29
bulkdata/src/datamodel.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#ifndef _BULKDATA_H_
|
||||
#define _BULKDATA_H_
|
||||
|
||||
#include <libbbf_api/dmcommon.h>
|
||||
|
||||
extern DMOBJ tDeviceBulkDataObj[];
|
||||
extern DMOBJ tBulkDataObj[];
|
||||
extern DMLEAF tBulkDataParams[];
|
||||
extern DMOBJ tBulkDataProfileObj[];
|
||||
extern DMLEAF tBulkDataProfileParams[];
|
||||
extern DMLEAF tBulkDataProfileParameterParams[];
|
||||
extern DMLEAF tBulkDataProfileCSVEncodingParams[];
|
||||
extern DMLEAF tBulkDataProfileJSONEncodingParams[];
|
||||
extern DMOBJ tBulkDataProfileHTTPObj[];
|
||||
extern DMLEAF tBulkDataProfileHTTPParams[];
|
||||
extern DMLEAF tBulkDataProfileHTTPRequestURIParameterParams[];
|
||||
|
||||
#endif //__BULKDATA_H_
|
||||
|
||||
196
bulkdata/src/http.c
Normal file
196
bulkdata/src/http.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
* Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#include "http.h"
|
||||
|
||||
static struct http_client http_c;
|
||||
static CURL *curl;
|
||||
|
||||
int http_client_init(struct profile *profile)
|
||||
{
|
||||
char *url = create_request_url(profile);
|
||||
if(url) {
|
||||
asprintf(&http_c.url, "%s", url);
|
||||
free(url);
|
||||
}
|
||||
bulkdata_log(SINFO, "ACS url: %s", http_c.url);
|
||||
|
||||
curl_global_init(CURL_GLOBAL_SSL);
|
||||
curl = curl_easy_init();
|
||||
if (!curl) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void http_client_exit(void)
|
||||
{
|
||||
FREE(http_c.url);
|
||||
|
||||
if (http_c.header_list) {
|
||||
curl_slist_free_all(http_c.header_list);
|
||||
http_c.header_list = NULL;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
}
|
||||
|
||||
static size_t http_get_response(void *buffer, size_t size, size_t rxed, char **msg_in)
|
||||
{
|
||||
char *c;
|
||||
|
||||
if (asprintf(&c, "%s%.*s", *msg_in, (int) (size * rxed), (char *)buffer) == -1) {
|
||||
FREE(*msg_in);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(*msg_in);
|
||||
*msg_in = c;
|
||||
|
||||
return size * rxed;
|
||||
}
|
||||
|
||||
int http_send_message(struct profile *profile, char *msg_out, int msg_out_len, char **msg_in)
|
||||
{
|
||||
CURLcode res;
|
||||
long http_code = 0;
|
||||
char errbuf[CURL_ERROR_SIZE];
|
||||
|
||||
http_c.header_list = NULL;
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "User-Agent: iopsys-bulkdata");
|
||||
if (!http_c.header_list) return -1;
|
||||
|
||||
if (profile->http_use_date_header) {
|
||||
if (bulkdata_get_time() != NULL) {
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, bulkdata_get_time());
|
||||
if (!http_c.header_list) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(profile->encoding_type, "json") == 0) {
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: application/json; charset=\"utf-8\"");
|
||||
if (!http_c.header_list) return -1;
|
||||
|
||||
if(strcmp (profile->json_encoding_report_format, "objecthierarchy") == 0) {
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ObjectHierarchy\"");
|
||||
if (!http_c.header_list) return -1;
|
||||
} else if(strcmp(profile->json_encoding_report_format, "namevaluepair") == 0) {
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"NameValuePair\"");
|
||||
if (!http_c.header_list) return -1;
|
||||
}
|
||||
} else if(strcmp(profile->encoding_type, "csv") == 0) {
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: text/csv; charset=\"utf-8\"");
|
||||
if (!http_c.header_list) return -1;
|
||||
|
||||
if(strcmp (profile->csv_encoding_report_format, "row") == 0) {
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ParameterPerRow\"");
|
||||
if (!http_c.header_list) return -1;
|
||||
} else if(strcmp (profile->csv_encoding_report_format, "column") == 0) {
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "BBF-Report-Format: \"ParameterPerColumn\"");
|
||||
if (!http_c.header_list) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, http_c.url);
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, profile->http_username);
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, profile->http_password);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC|CURLAUTH_DIGEST);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_TIMEOUT);
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, HTTP_TIMEOUT);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
||||
|
||||
if(strcasecmp(profile->http_compression, "gzip") == 0) {
|
||||
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: gzip");
|
||||
} else if(strcasecmp(profile->http_compression, "compress") == 0) {
|
||||
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "compress");
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: compress");
|
||||
} else if(strcasecmp(profile->http_compression, "deflate") == 0) {
|
||||
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate");
|
||||
http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: deflate");
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_c.header_list);
|
||||
if(strcasecmp(profile->http_method, "put") == 0)
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg_out);
|
||||
if (msg_out)
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) msg_out_len);
|
||||
else
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_response);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, msg_in);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
|
||||
|
||||
if (profile->http_ssl_capath)
|
||||
curl_easy_setopt(curl, CURLOPT_CAPATH, profile->http_ssl_capath);
|
||||
if (profile->http_insecure_enable) {
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
*msg_in = (char *) calloc (1, sizeof(char));
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(res != CURLE_OK) {
|
||||
size_t len = strlen(errbuf);
|
||||
if(len) {
|
||||
if (errbuf[len - 1] == '\n') errbuf[len - 1] = '\0';
|
||||
bulkdata_log(SCRIT, "libcurl: (%d) %s", res, errbuf);
|
||||
} else {
|
||||
bulkdata_log(SCRIT, "libcurl: (%d) %s", res, curl_easy_strerror(res));
|
||||
}
|
||||
}
|
||||
|
||||
if (!strlen(*msg_in))
|
||||
FREE(*msg_in);
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
if(http_code == 200)
|
||||
bulkdata_log(SINFO, "Receive HTTP 200 OK from Bulkdata Collector");
|
||||
else if(http_code == 401)
|
||||
bulkdata_log(SINFO, "Receive HTTP 401 Unauthorized from Bulkdata Collector");
|
||||
else if(http_code == 204)
|
||||
bulkdata_log(SINFO, "Receive HTTP 204 No Content from Bulkdata Collector");
|
||||
else
|
||||
bulkdata_log(SINFO, "Receive HTTP %d from Bulkdata Collector", http_code);
|
||||
|
||||
if(http_code == 415)
|
||||
{
|
||||
strcpy(profile->http_compression, "None");
|
||||
goto error;
|
||||
}
|
||||
if (http_code != 200 && http_code != 204)
|
||||
goto error;
|
||||
|
||||
curl_easy_reset(curl);
|
||||
if (http_c.header_list) {
|
||||
curl_slist_free_all(http_c.header_list);
|
||||
http_c.header_list = NULL;
|
||||
}
|
||||
|
||||
if (res) goto error;
|
||||
|
||||
return http_code;
|
||||
|
||||
error:
|
||||
FREE(*msg_in);
|
||||
if (http_c.header_list) {
|
||||
curl_slist_free_all(http_c.header_list);
|
||||
http_c.header_list = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
37
bulkdata/src/http.h
Normal file
37
bulkdata/src/http.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __HTTP_H
|
||||
#define __HTTP_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <curl/curl.h>
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "times.h"
|
||||
#include "common.h"
|
||||
|
||||
#define HTTP_TIMEOUT 30
|
||||
|
||||
struct http_client
|
||||
{
|
||||
struct curl_slist *header_list;
|
||||
char *url;
|
||||
};
|
||||
|
||||
int http_client_init(struct profile *profile);
|
||||
void http_client_exit(void);
|
||||
int http_send_message(struct profile *profile, char *msg_out, int msg_out_len, char **msg_in);
|
||||
|
||||
#endif //__HTTP_H
|
||||
57
bulkdata/src/log.c
Normal file
57
bulkdata/src/log.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "bulkdata.h"
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
|
||||
static const int log_syslogmap[] = {
|
||||
[SCRIT] = LOG_CRIT,
|
||||
[SWARNING] = LOG_WARNING,
|
||||
[SNOTICE] = LOG_NOTICE,
|
||||
[SINFO] = LOG_INFO,
|
||||
[SDEBUG] = LOG_DEBUG
|
||||
};
|
||||
|
||||
static const char* log_str[] = {
|
||||
[SCRIT] = "CRITICAL",
|
||||
[SWARNING] = "WARNING",
|
||||
[SNOTICE] = "NOTICE",
|
||||
[SINFO] = "INFO",
|
||||
[SDEBUG] = "DEBUG"
|
||||
};
|
||||
|
||||
void bulkdata_log(int priority, const char *format, ...)
|
||||
{
|
||||
va_list vl;
|
||||
|
||||
if (priority <= bulkdata_main.log_level) {
|
||||
time_t t = time(NULL);
|
||||
struct tm tm = *localtime(&t);
|
||||
va_start(vl, format);
|
||||
printf("%d-%02d-%02d %02d:%02d:%02d [bulkdata] %s - ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, log_str[priority]);
|
||||
vprintf(format, vl);
|
||||
va_end(vl);
|
||||
printf("\n");
|
||||
|
||||
openlog("bulkdata", 0, LOG_DAEMON);
|
||||
va_start(vl, format);
|
||||
vsyslog(log_syslogmap[priority], format, vl);
|
||||
va_end(vl);
|
||||
closelog();
|
||||
}
|
||||
}
|
||||
28
bulkdata/src/log.h
Normal file
28
bulkdata/src/log.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LOG_H
|
||||
#define __LOG_H
|
||||
|
||||
#define DEFAULT_LOGLEVEL SINFO
|
||||
|
||||
enum bulkdata_log_level_enum {
|
||||
SCRIT,
|
||||
SWARNING,
|
||||
SNOTICE,
|
||||
SINFO,
|
||||
SDEBUG,
|
||||
__MAX_SLOG
|
||||
};
|
||||
|
||||
void bulkdata_log(int priority, const char *format, ...);
|
||||
|
||||
#endif //__LOG_H
|
||||
336
bulkdata/src/report.c
Normal file
336
bulkdata/src/report.c
Normal file
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "report.h"
|
||||
|
||||
static void add_new_json_obj(json_object *json_obj, char *name, char *data, char *type)
|
||||
{
|
||||
json_object *jobj;
|
||||
if(strstr(type, "unsignedInt") || strstr(type, "int") || strstr(type, "long"))
|
||||
jobj = json_object_new_int64(atoi(data));
|
||||
else if(strstr(type, "bool"))
|
||||
jobj = json_object_new_boolean(atoi(data));
|
||||
else
|
||||
jobj = json_object_new_string(data);
|
||||
|
||||
json_object_object_add(json_obj, name, jobj);
|
||||
}
|
||||
|
||||
static void create_json_bulkdata_report_object_hierarchy(struct profile *profile, char **report)
|
||||
{
|
||||
struct json_object *json_obj, *json_obj1, *json_obj2;
|
||||
struct resultsnode *p;
|
||||
int i, j, profile_param_number = profile->profile_parameter_number;
|
||||
char *param_name, *result, *pch, *pchr, *collection_time = NULL;
|
||||
char buf[1024] = {0};
|
||||
|
||||
json_obj = json_object_new_object();
|
||||
get_time_stamp(profile->json_encoding_report_time_stamp, &collection_time);
|
||||
if(collection_time) {
|
||||
if(strcmp(profile->json_encoding_report_time_stamp, "iso8601") == 0)
|
||||
json_object_object_add(json_obj, "CollectionTime", json_object_new_string(collection_time));
|
||||
else
|
||||
json_object_object_add(json_obj, "CollectionTime", json_object_new_int64(atoi(collection_time)));
|
||||
free(collection_time);
|
||||
}
|
||||
json_obj2 = json_obj;
|
||||
for (i = 0; i < profile_param_number; i++) {
|
||||
LIST_HEAD(results_list);
|
||||
bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list);
|
||||
list_for_each_entry(p, &results_list, list) {
|
||||
char *argv[128] = {0};
|
||||
j = 0;
|
||||
param_name = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name);
|
||||
strcpy(buf, param_name);
|
||||
for (pch = strtok_r(buf, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) {
|
||||
argv[j] = pch;
|
||||
json_obj1 = (json_object *)bbf_api_dmjson_select_obj(json_obj, argv);
|
||||
if (json_obj1)
|
||||
json_obj2 = json_obj1;
|
||||
else {
|
||||
if (pchr != NULL && *pchr != '\0') {
|
||||
json_object *new_obj = json_object_new_object();
|
||||
json_object_object_add(json_obj2, pch, new_obj);
|
||||
json_obj2 = new_obj;
|
||||
}
|
||||
else
|
||||
add_new_json_obj(json_obj2, pch, p->data, p->type);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
bulkdata_free_data_from_list(&results_list);
|
||||
FREE(param_name);
|
||||
}
|
||||
result = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY);
|
||||
*report = strdup(result);
|
||||
json_object_put(json_obj);
|
||||
}
|
||||
|
||||
static void create_json_bulkdata_report_name_value_pair(struct profile *profile, char **report)
|
||||
{
|
||||
struct json_object *json_obj;
|
||||
struct resultsnode *p;
|
||||
char *param_name, *result, *collection_time = NULL;
|
||||
int i = 0, profile_param_number = profile->profile_parameter_number;
|
||||
|
||||
json_obj = json_object_new_object();
|
||||
get_time_stamp(profile->json_encoding_report_time_stamp, &collection_time);
|
||||
if(collection_time) {
|
||||
if(strcmp(profile->json_encoding_report_time_stamp, "iso8601") == 0)
|
||||
json_object_object_add(json_obj, "CollectionTime", json_object_new_string(collection_time));
|
||||
else
|
||||
json_object_object_add(json_obj, "CollectionTime", json_object_new_int64(atoi(collection_time)));
|
||||
free(collection_time);
|
||||
}
|
||||
for (i = 0; i < profile_param_number; i++) {
|
||||
LIST_HEAD(results_list);
|
||||
bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list);
|
||||
list_for_each_entry(p, &results_list, list) {
|
||||
param_name = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name);
|
||||
add_new_json_obj(json_obj, param_name, p->data, p->type);
|
||||
FREE(param_name);
|
||||
}
|
||||
bulkdata_free_data_from_list(&results_list);
|
||||
}
|
||||
result = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY);
|
||||
*report = strdup(result);
|
||||
json_object_put(json_obj);
|
||||
}
|
||||
|
||||
static void add_failed_reports_to_report_json(struct profile *profile, char *new_report, char **report, int isnext)
|
||||
{
|
||||
json_object *json_obj, *json_array, *json_string;
|
||||
struct failed_reports *retreport = NULL;
|
||||
char *msgout = NULL;
|
||||
int j = 0;
|
||||
|
||||
json_obj = json_object_new_object();
|
||||
json_array = json_object_new_array();
|
||||
json_object_object_add(json_obj,"Report", json_array);
|
||||
|
||||
if(list_empty(profile->failed_reports))
|
||||
goto new_report;
|
||||
|
||||
list_for_each_entry(retreport, profile->failed_reports, list) {
|
||||
if(!j && isnext) {
|
||||
j = 1;
|
||||
continue;
|
||||
}
|
||||
json_string = json_tokener_parse(retreport->freport);
|
||||
json_object_array_add(json_array, json_string);
|
||||
}
|
||||
|
||||
new_report :
|
||||
if(new_report) {
|
||||
json_string = json_tokener_parse(new_report);
|
||||
json_object_array_add(json_array, json_string);
|
||||
}
|
||||
|
||||
msgout = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY);
|
||||
*report = strdup(msgout);
|
||||
json_object_put(json_obj);
|
||||
}
|
||||
|
||||
static void create_report_json(char *new_report, char **report)
|
||||
{
|
||||
json_object *json_obj, *json_array, *json_string;
|
||||
char *msgout = NULL;
|
||||
|
||||
json_obj = json_object_new_object();
|
||||
json_array = json_object_new_array();
|
||||
json_object_object_add(json_obj,"Report", json_array);
|
||||
|
||||
if(new_report) {
|
||||
json_string = json_tokener_parse(new_report);
|
||||
json_object_array_add(json_array, json_string);
|
||||
}
|
||||
|
||||
msgout = (char *)json_object_to_json_string_ext(json_obj, JSON_C_TO_STRING_PRETTY);
|
||||
*report = strdup(msgout);
|
||||
json_object_put(json_obj);
|
||||
}
|
||||
|
||||
int create_json_bulkdata_report(struct profile *profile, char **report)
|
||||
{
|
||||
/*
|
||||
* create json msg of current report
|
||||
* parse failed reports list and add it to the report
|
||||
* then add new report to the report
|
||||
*/
|
||||
char *msgout;
|
||||
|
||||
profile->new_report = NULL;
|
||||
if(strcmp(profile->json_encoding_report_format, "objecthierarchy") == 0) {
|
||||
create_json_bulkdata_report_object_hierarchy(profile, &msgout);
|
||||
} else if(strcmp(profile->json_encoding_report_format, "namevaluepair") == 0) {
|
||||
create_json_bulkdata_report_name_value_pair(profile, &msgout);
|
||||
}
|
||||
|
||||
if(profile->nbre_of_retained_failed_reports != 0) {
|
||||
if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0)
|
||||
add_failed_reports_to_report_json(profile, msgout, report, 1);
|
||||
else
|
||||
add_failed_reports_to_report_json(profile, msgout, report, 0);
|
||||
} else {
|
||||
create_report_json(msgout, report);
|
||||
}
|
||||
|
||||
append_string_to_string(msgout, &profile->new_report);
|
||||
FREE(msgout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_csv_bulkdata_report(struct profile *profile, char **report)
|
||||
{
|
||||
/*
|
||||
* create csv msg of current report
|
||||
* parse failed reports list and add it to the report
|
||||
*/
|
||||
int i;
|
||||
struct resultsnode *p;
|
||||
char *str1 = NULL, *str2 = NULL, *str = NULL, *paramprofilename, *timestamp = NULL, *type = NULL, rowseparator = '\0', separator = '\0';
|
||||
|
||||
if(strcmp(profile->csv_encoding_row_separator, " ") == 0)
|
||||
rowseparator = '\n';
|
||||
else if(strcmp(profile->csv_encoding_row_separator, " ") == 0)
|
||||
rowseparator = '\r';
|
||||
|
||||
if(profile->csv_encoding_field_separator)
|
||||
separator = profile->csv_encoding_field_separator[0];
|
||||
|
||||
get_time_stamp(profile->csv_encoding_row_time_stamp, ×tamp);
|
||||
/*
|
||||
* Create header ReportTimestamp,ParameterName,ParameterValue,ParameterType in case of ParameterPerRow
|
||||
*/
|
||||
if(strcmp(profile->csv_encoding_report_format, "row") == 0) {
|
||||
if(timestamp == NULL)
|
||||
asprintf(&str, "ParameterName%cParameterValue%cParameterType%c", separator, separator, rowseparator);
|
||||
else
|
||||
asprintf(&str, "ReportTimestamp%cParameterName%cParameterValue%cParameterType%c", separator, separator, separator, rowseparator);
|
||||
append_string_to_string(str, report);
|
||||
FREE(str);
|
||||
if(profile->nbre_of_retained_failed_reports != 0) {
|
||||
if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0)
|
||||
add_failed_reports_to_report_csv(profile, report, 1);
|
||||
else
|
||||
add_failed_reports_to_report_csv(profile, report, 0);
|
||||
}
|
||||
}
|
||||
if(strcmp(profile->csv_encoding_report_format, "column") == 0 && timestamp != NULL) {
|
||||
if(profile->nbre_of_retained_failed_reports != 0) {
|
||||
if(profile->nbre_failed_reports >= profile->nbre_of_retained_failed_reports && profile->nbre_of_retained_failed_reports > 0)
|
||||
add_failed_reports_to_report_csv(profile, report, 1);
|
||||
else
|
||||
add_failed_reports_to_report_csv(profile, report, 0);
|
||||
}
|
||||
append_string_to_string("ReportTimestamp", &str1);
|
||||
append_string_to_string(timestamp, &str2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add New reports
|
||||
*/
|
||||
profile->new_report = NULL;
|
||||
for(i = 0; i < profile->profile_parameter_number; i++) {
|
||||
LIST_HEAD(results_list);
|
||||
bulkdata_get_value_results(profile->profile_parameter[i].reference, &results_list);
|
||||
list_for_each_entry(p, &results_list, list) {
|
||||
paramprofilename = get_bulkdata_profile_parameter_name(profile->profile_parameter[i].reference, profile->profile_parameter[i].name, p->name);
|
||||
if(strcmp(profile->csv_encoding_report_format, "row") == 0) {
|
||||
type = strstr(p->type, ":");
|
||||
if(timestamp == NULL)
|
||||
asprintf(&str, "%s%c%s%c%s%c", paramprofilename, separator, p->data, separator, type+1, rowseparator);
|
||||
else
|
||||
asprintf(&str, "%s%c%s%c%s%c%s%c", timestamp, separator, paramprofilename, separator, p->data, separator, type+1, rowseparator);
|
||||
append_string_to_string(str, report);
|
||||
append_string_to_string(str, &profile->new_report);
|
||||
FREE(str);
|
||||
} else if(strcmp(profile->csv_encoding_report_format, "column") == 0) {
|
||||
if(str1 == NULL || strlen(str1) <= 0)
|
||||
asprintf(&str, "%s", paramprofilename);
|
||||
else
|
||||
asprintf(&str, "%c%s", separator, paramprofilename);
|
||||
append_string_to_string(str, &str1);
|
||||
FREE(str);
|
||||
if(str2 == NULL || strlen(str2) <= 0)
|
||||
asprintf(&str, "%s", p->data);
|
||||
else
|
||||
asprintf(&str, "%c%s", separator, p->data);
|
||||
append_string_to_string(str, &str2);
|
||||
FREE(str);
|
||||
}
|
||||
FREE(paramprofilename);
|
||||
}
|
||||
bulkdata_free_data_from_list(&results_list);
|
||||
}
|
||||
if(strcmp(profile->csv_encoding_report_format, "column") == 0) {
|
||||
asprintf(&str, "%c", rowseparator);
|
||||
append_string_to_string(str, &str1);
|
||||
append_string_to_string(str, &str2);
|
||||
append_string_to_string(str1, report);
|
||||
append_string_to_string(str2, report);
|
||||
append_string_to_string(str1, &profile->new_report);
|
||||
append_string_to_string(str2, &profile->new_report);
|
||||
}
|
||||
FREE(str);
|
||||
FREE(str1);
|
||||
FREE(str2);
|
||||
FREE(timestamp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void create_json_failed_report(struct profile *profile, char **report)
|
||||
{
|
||||
add_failed_reports_to_report_json(profile, NULL, report, 0);
|
||||
}
|
||||
|
||||
static void create_csv_failed_report(struct profile *profile, char **report)
|
||||
{
|
||||
char rowseparator = '\0', separator = '\0', *timestamp = NULL;
|
||||
|
||||
if(strcmp(profile->csv_encoding_row_separator, " ") == 0) {
|
||||
rowseparator = '\n';
|
||||
} else if(strcmp(profile->csv_encoding_row_separator, " ") == 0) {
|
||||
rowseparator = '\r';
|
||||
}
|
||||
|
||||
if(profile->csv_encoding_field_separator)
|
||||
separator = profile->csv_encoding_field_separator[0];
|
||||
|
||||
get_time_stamp(profile->csv_encoding_row_time_stamp, ×tamp);
|
||||
if(strcmp(profile->csv_encoding_report_format, "row") == 0) {
|
||||
if(timestamp == NULL)
|
||||
asprintf(report, "ParameterName%cParameterValue%cParameterType%c", separator, separator, rowseparator);
|
||||
else
|
||||
asprintf(report, "ReportTimestamp%cParameterName%cParameterValue%cParameterType%c", separator, separator, separator, rowseparator);
|
||||
}
|
||||
add_failed_reports_to_report_csv(profile, report, 0);
|
||||
}
|
||||
|
||||
void create_encoding_bulkdata_report(struct profile *profile, char **report)
|
||||
{
|
||||
if(strcasecmp(profile->encoding_type, "json") == 0) {
|
||||
create_json_bulkdata_report(profile, report);
|
||||
} else if(strcasecmp(profile->encoding_type, "csv") == 0) {
|
||||
create_csv_bulkdata_report(profile, report);
|
||||
}
|
||||
}
|
||||
|
||||
void create_failed_report(struct profile *profile, char **report)
|
||||
{
|
||||
if(strcasecmp(profile->encoding_type, "json") == 0) {
|
||||
create_json_failed_report(profile, report);
|
||||
} else if(strcasecmp(profile->encoding_type, "csv") == 0) {
|
||||
create_csv_failed_report(profile, report);
|
||||
}
|
||||
}
|
||||
24
bulkdata/src/report.h
Normal file
24
bulkdata/src/report.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __REPORT_H_
|
||||
#define __REPORT_H_
|
||||
|
||||
#include <json-c/json.h>
|
||||
#include "common.h"
|
||||
#include "times.h"
|
||||
#include "config.h"
|
||||
|
||||
void create_encoding_bulkdata_report(struct profile *profile, char **report);
|
||||
void create_failed_report(struct profile *profile, char **report);
|
||||
|
||||
#endif /* __REPORT_H_ */
|
||||
62
bulkdata/src/times.c
Normal file
62
bulkdata/src/times.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "times.h"
|
||||
|
||||
const char *bulkdata_get_time(void)
|
||||
{
|
||||
static char local_time[64];
|
||||
|
||||
time_t t_time = time(NULL);
|
||||
struct tm *t_tm = localtime(&t_time);
|
||||
if (t_tm == NULL)
|
||||
return NULL;
|
||||
|
||||
if (strftime(local_time, sizeof(local_time),"Date: %a, %d %b %Y %X%z GMT", t_tm) == 0)
|
||||
return NULL;
|
||||
|
||||
return local_time;
|
||||
}
|
||||
|
||||
void get_time_stamp(const char *format, char **timestamp)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (strcmp(format, "unix") == 0) {
|
||||
asprintf(timestamp, "%ld", now);
|
||||
} else if (strcmp(format, "iso8601") == 0) {
|
||||
char buf[32] = {0};
|
||||
struct tm *ts = localtime(&now);
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%Z", ts);
|
||||
asprintf(timestamp, "%s", buf);
|
||||
} else
|
||||
timestamp = NULL;
|
||||
}
|
||||
|
||||
unsigned int get_next_period(time_t time_reference, int reporting_interval)
|
||||
{
|
||||
unsigned int next_period;
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (now > time_reference)
|
||||
next_period = reporting_interval - ((now - time_reference) % reporting_interval);
|
||||
else
|
||||
next_period = (time_reference - now) % reporting_interval;
|
||||
|
||||
if (next_period == 0)
|
||||
next_period = reporting_interval;
|
||||
|
||||
return next_period;
|
||||
}
|
||||
19
bulkdata/src/times.h
Normal file
19
bulkdata/src/times.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB
|
||||
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __TIMES_H
|
||||
#define __TIMES_H
|
||||
|
||||
const char *bulkdata_get_time(void);
|
||||
void get_time_stamp(const char *format, char **timestamp);
|
||||
unsigned int get_next_period(time_t time_reference, int reporting_interval);
|
||||
|
||||
#endif /* __TIMES_H */
|
||||
@@ -1,7 +1,4 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#
|
||||
# Copyright (C) 2015 inteno.org
|
||||
#
|
||||
|
||||
START=71
|
||||
USE_PROCD=1
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=cifsd-tools
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/namjaejeon/cifsd-tools.git
|
||||
PKG_SOURCE_DATE:=2019-02-14
|
||||
PKG_SOURCE_VERSION:=a7d7dfc40524b88dbcb2052034a75f446b3cefdd
|
||||
PKG_MIRROR_HASH:=a74f95a79c3cdcc78e66c080729141abee0d821e21a326d88b11d849738314fb
|
||||
|
||||
PKG_MAINTAINER:=Andy Walsh <andy.walsh44+github@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_INSTALL:=1
|
||||
PKG_FIXUP:=autoreconf
|
||||
PKG_REMOVE_FILES:=autogen.sh aclocal.m4
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/nls.mk
|
||||
|
||||
define Package/cifsd-tools
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Filesystem
|
||||
TITLE:=Kernel CIFS/SMB server support and userspace tools
|
||||
DEPENDS:=+kmod-fs-cifsd +glib2 +libnl-core +libnl-genl $(ICONV_DEPENDS)
|
||||
endef
|
||||
|
||||
define Package/cifsd-tools/description
|
||||
Userspace tools (cifsd, cifsadmin) for the CIFS/SMB kernel fileserver.
|
||||
The config file location is /etc/cifs/smb.conf
|
||||
endef
|
||||
|
||||
define Package/cifsd-tools/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcifsdtools.so* $(1)/usr/lib/
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/cifs
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/smb.conf.example $(1)/etc/cifs
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./files/cifsd.config $(1)/etc/config/cifsd
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/cifsd.init $(1)/etc/init.d/cifsd
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{cifsadmin,cifsd} $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,cifsd-tools))
|
||||
@@ -1,9 +0,0 @@
|
||||
config global 'global'
|
||||
option server_string 'CIFSD on OpenWRT'
|
||||
option ipc_timeout '8' # IPC timeout is used as a workaround for uninterruptible sleep until this is fixed upstream.
|
||||
|
||||
config share
|
||||
option name 'share'
|
||||
option comment 'Default guest share'
|
||||
option path '/mnt'
|
||||
option guest_ok 'yes'
|
||||
@@ -1,161 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=90
|
||||
USE_PROCD=1
|
||||
PROG=/usr/sbin/cifsd
|
||||
USER_DB=/etc/cifs/cifsdpwd.db
|
||||
CIFS_ADMIN=cifsadmin
|
||||
|
||||
EXTRA_COMMANDS="users"
|
||||
EXTRA_HELP=" users Show list of users created by cifsadmin"
|
||||
|
||||
users() {
|
||||
[ -f "$USER_DB" ] && cut -d ':' $USER_DB -f1 || \
|
||||
printf "No users available.\n"
|
||||
}
|
||||
|
||||
validate_cifsd_global() {
|
||||
uci_validate_section cifsd global global \
|
||||
'server_string:string' \
|
||||
'workgroup:string' \
|
||||
'netbios_name:string' \
|
||||
'interface:string' \
|
||||
'ipc_timeout:uinteger'
|
||||
}
|
||||
|
||||
validate_cifsd_share() {
|
||||
uci_validate_section cifsd share "${1}" \
|
||||
'name:string' \
|
||||
'comment:string' \
|
||||
'path:string' \
|
||||
'guest_ok:bool' \
|
||||
'read_only:bool' \
|
||||
'allow_hosts:list' \
|
||||
'deny_hosts:list' \
|
||||
'users:string' \
|
||||
'invalid_users:string' \
|
||||
'create_mask:string' \
|
||||
'dir_mask:string' \
|
||||
'max_connections:uinteger' \
|
||||
'veto_files:list'
|
||||
}
|
||||
|
||||
validate_cifsd_users() {
|
||||
uci_validate_section cifsd users "${1}" \
|
||||
'user:string' \
|
||||
'password:string' \
|
||||
'desc:string'
|
||||
}
|
||||
|
||||
load_cifsd_global() {
|
||||
local server_string
|
||||
local workgroup
|
||||
local netbios_name
|
||||
local ipc_timeout
|
||||
|
||||
validate_cifsd_global
|
||||
|
||||
echo -e "[global]" >> /var/etc/cifsd.conf
|
||||
[ -n "$server_string" ] && echo -e "\tserver string = $server_string" >> /var/etc/cifsd.conf
|
||||
[ -n "$workgroup" ] && echo -e "\tworkgroup = $workgroup" >> /var/etc/cifsd.conf
|
||||
[ -n "$netbios_name" ] && echo -e "\tnetbios name = $netbios_name" >> /var/etc/cifsd.conf
|
||||
[ -n "$ipc_timeout" ] && echo -e "\tipc timeout name = $ipc_timeout" >> /var/etc/cifsd.conf || \
|
||||
echo -e "\tipc timeout name = 8" >> /var/etc/cifsd.conf
|
||||
}
|
||||
|
||||
load_cifsd_share() {
|
||||
local name
|
||||
local comment
|
||||
local path
|
||||
local guest_ok
|
||||
local allow_hosts
|
||||
local deny_hosts
|
||||
local users
|
||||
local invalid_users
|
||||
local max_connections
|
||||
local veto_files
|
||||
local dir_mask
|
||||
local create_mask
|
||||
local read_only
|
||||
|
||||
validate_cifsd_share ${1}
|
||||
|
||||
if [ -z "$name" -o -z "$path" ]; then
|
||||
logread -t ${0} "Missing name or path."
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "\n[$name]\n\tpath = $path" >> /var/etc/cifsd.conf
|
||||
[ -n "$comment" ] && echo -e "\tcomment = $comment" >> /var/etc/cifsd.conf
|
||||
[ -n "$guest_ok" ] && echo -e "\tguest ok = $guest_ok" >> /var/etc/cifsd.conf
|
||||
[ -n "$allow_hosts" ] && echo -e "\tallow hosts = $allow_hosts" >> /var/etc/cifsd.conf
|
||||
[ -n "$deny_hosts" ] && echo -e "\tdeny hosts = $deny_hosts" >> /var/etc/cifsd.conf
|
||||
[ -n "$users" ] && echo -e "\tvalid users = $users" >> /var/etc/cifsd.conf
|
||||
[ -n "$invalid_users" ] && echo -e "\tinvalid users = $invalid_users" >> /var/etc/cifsd.conf
|
||||
[ -n "$max_connections" ] && echo -e "\tmax connections = $max_connections" >> /var/etc/cifsd.conf
|
||||
[ -n "$create_mask" ] && echo -e "\tcreate mask = $create_mask" >> /var/etc/cifsd.conf
|
||||
[ -n "$dir_mask" ] && echo -e "\tdirectory mask = $dir_mask" >> /var/etc/cifsd.conf
|
||||
|
||||
if [ -n "$read_only" ]; then
|
||||
echo -e "\tread only = $read_only" >> /var/etc/cifsd.conf
|
||||
if [ "${read_only}" -eq "0" ]; then
|
||||
echo -e "\twrite ok = 1" >> /var/etc/cifsd.conf
|
||||
fi
|
||||
else
|
||||
echo -e "\twrite ok = 1" >> /var/etc/cifsd.conf
|
||||
fi
|
||||
|
||||
[ -n "$veto_files" ] && echo -e "\tveto files = $veto_files" >> /var/etc/cifsd.conf
|
||||
}
|
||||
|
||||
load_cifsd_users() {
|
||||
local user
|
||||
local password
|
||||
local desc
|
||||
|
||||
validate_cifsd_users ${1}
|
||||
[ $(which ${CIFS_ADMIN}) ] || {
|
||||
logread -t ${0} "${CIFS_ADMIN} tools is not available"
|
||||
return;
|
||||
}
|
||||
|
||||
cifsadmin -a "${user}" -p "${password}"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
logread -t ${0} "Failed to create/update ${user}"
|
||||
fi
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_config_trigger "config.change" "cifsd" /etc/init.d/cifsd restart
|
||||
}
|
||||
|
||||
init_config() {
|
||||
[ -f "/var/etc/cifsd.conf" ] && rm /var/etc/cifsd.conf
|
||||
|
||||
config_load cifsd
|
||||
load_cifsd_global
|
||||
|
||||
# Delete existing users
|
||||
[ -f "${USER_DB}" ] && {
|
||||
rm -f "${USER_DB}"
|
||||
}
|
||||
config_foreach load_cifsd_users users
|
||||
config_foreach load_cifsd_share share
|
||||
}
|
||||
|
||||
start_service() {
|
||||
. /lib/functions.sh
|
||||
init_config
|
||||
|
||||
[ ! "$(grep cifsd /proc/modules)" ] && modprobe cifsd
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/bin/env LANG=en_US.UTF-8 $PROG -c /var/etc/cifsd.conf
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
killall cifsd
|
||||
# IPC timeout will kill the remaining processes.
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
For some reason, fs.h on Inteno kernel is missing inode->i_mutex nesting subclasses for the lock validator
|
||||
which is triggering implicit declaration error. To workaround this hardcore use of mutex_lock by removing
|
||||
kernel version check.
|
||||
---
|
||||
--- a/vfs.c
|
||||
+++ b/vfs.c
|
||||
@@ -544,15 +544,9 @@ int cifsd_vfs_setattr(struct cifsd_work
|
||||
|
||||
attrs->ia_valid |= ATTR_CTIME;
|
||||
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_lock(inode);
|
||||
- err = notify_change(dentry, attrs, NULL);
|
||||
- inode_unlock(inode);
|
||||
-#else
|
||||
mutex_lock(&inode->i_mutex);
|
||||
err = notify_change(dentry, attrs, NULL);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
-#endif
|
||||
|
||||
if (update_size)
|
||||
put_write_access(inode);
|
||||
@@ -753,11 +747,8 @@ int cifsd_vfs_remove_file(char *name)
|
||||
if (!dir->d_inode)
|
||||
goto out;
|
||||
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_lock_nested(dir->d_inode, I_MUTEX_PARENT);
|
||||
-#else
|
||||
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
|
||||
-#endif
|
||||
+
|
||||
dentry = lookup_one_len(last, dir, strlen(last));
|
||||
if (IS_ERR(dentry)) {
|
||||
err = PTR_ERR(dentry);
|
||||
@@ -783,11 +774,7 @@ int cifsd_vfs_remove_file(char *name)
|
||||
|
||||
dput(dentry);
|
||||
out_err:
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_unlock(dir->d_inode);
|
||||
-#else
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
-#endif
|
||||
out:
|
||||
path_put(&parent);
|
||||
return err;
|
||||
@@ -1302,11 +1289,8 @@ int cifsd_vfs_unlink(struct dentry *dir,
|
||||
int err = 0;
|
||||
|
||||
dget(dentry);
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_lock(dir->d_inode);
|
||||
-#else
|
||||
mutex_lock(&dir->d_inode->i_mutex);
|
||||
-#endif
|
||||
+
|
||||
if (!dentry->d_inode || !dentry->d_inode->i_nlink) {
|
||||
err = -ENOENT;
|
||||
goto out;
|
||||
@@ -1318,11 +1302,8 @@ int cifsd_vfs_unlink(struct dentry *dir,
|
||||
err = vfs_unlink(dir->d_inode, dentry, NULL);
|
||||
|
||||
out:
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_unlock(dir->d_inode);
|
||||
-#else
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
-#endif
|
||||
+
|
||||
dput(dentry);
|
||||
if (err)
|
||||
cifsd_debug("failed to delete, err %d\n", err);
|
||||
@@ -1,60 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=cifsd
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/namjaejeon/cifsd.git
|
||||
PKG_SOURCE_DATE:=2019-03-05
|
||||
PKG_SOURCE_VERSION:=e1715ce125d55b125b1b58a6f1819ef8e54cc3ba
|
||||
PKG_MIRROR_HASH:=521585ebfda0ecc02372b1a38ebf762fbbcead6d0b754a47599a5bf6bfdb3fb6
|
||||
|
||||
PKG_MAINTAINER:=Andy Walsh <andy.walsh44+github@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/fs-cifsd
|
||||
SUBMENU:=Filesystems
|
||||
TITLE:=CIFS/SMB kernel server support
|
||||
FILES:=$(PKG_BUILD_DIR)/cifsd.$(LINUX_KMOD_SUFFIX)
|
||||
DEPENDS+= \
|
||||
+kmod-nls-base \
|
||||
+kmod-nls-utf8 \
|
||||
+kmod-crypto-md4 \
|
||||
+kmod-crypto-md5 \
|
||||
+kmod-crypto-hmac \
|
||||
+kmod-crypto-ecb \
|
||||
+kmod-crypto-des \
|
||||
+kmod-crypto-sha256 \
|
||||
+kmod-crypto-cmac \
|
||||
+kmod-crypto-sha512 \
|
||||
+kmod-crypto-aead \
|
||||
+kmod-crypto-ccm
|
||||
KCONFIG:= \
|
||||
CONFIG_KEYS=y \
|
||||
CONFIG_CRYPTO_ARC4=y
|
||||
endef
|
||||
|
||||
define KernelPackage/fs-cifsd/description
|
||||
Kernel module for a CIFS/SMBv2,3 fileserver.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS+= -DCONFIG_CIFSD_ACL
|
||||
|
||||
MAKE_OPTS:=\
|
||||
ARCH="$(LINUX_KARCH)" \
|
||||
CROSS_COMPILE="$(TARGET_CROSS)" \
|
||||
M="$(PKG_BUILD_DIR)"
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C "$(LINUX_DIR)" \
|
||||
$(MAKE_OPTS) \
|
||||
CFLAGS="$(TARGET_CFLAGS)" \
|
||||
CONFIG_CIFS_SERVER=m \
|
||||
modules
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,fs-cifsd))
|
||||
@@ -1,69 +0,0 @@
|
||||
--- a/vfs.c
|
||||
+++ b/vfs.c
|
||||
@@ -544,15 +544,9 @@ int cifsd_vfs_setattr(struct cifsd_work
|
||||
|
||||
attrs->ia_valid |= ATTR_CTIME;
|
||||
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_lock(inode);
|
||||
- err = notify_change(dentry, attrs, NULL);
|
||||
- inode_unlock(inode);
|
||||
-#else
|
||||
mutex_lock(&inode->i_mutex);
|
||||
err = notify_change(dentry, attrs, NULL);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
-#endif
|
||||
|
||||
if (update_size)
|
||||
put_write_access(inode);
|
||||
@@ -753,11 +747,8 @@ int cifsd_vfs_remove_file(char *name)
|
||||
if (!dir->d_inode)
|
||||
goto out;
|
||||
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_lock_nested(dir->d_inode, I_MUTEX_PARENT);
|
||||
-#else
|
||||
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
|
||||
-#endif
|
||||
+
|
||||
dentry = lookup_one_len(last, dir, strlen(last));
|
||||
if (IS_ERR(dentry)) {
|
||||
err = PTR_ERR(dentry);
|
||||
@@ -783,11 +774,7 @@ int cifsd_vfs_remove_file(char *name)
|
||||
|
||||
dput(dentry);
|
||||
out_err:
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_unlock(dir->d_inode);
|
||||
-#else
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
-#endif
|
||||
out:
|
||||
path_put(&parent);
|
||||
return err;
|
||||
@@ -1302,11 +1289,8 @@ int cifsd_vfs_unlink(struct dentry *dir,
|
||||
int err = 0;
|
||||
|
||||
dget(dentry);
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_lock(dir->d_inode);
|
||||
-#else
|
||||
mutex_lock(&dir->d_inode->i_mutex);
|
||||
-#endif
|
||||
+
|
||||
if (!dentry->d_inode || !dentry->d_inode->i_nlink) {
|
||||
err = -ENOENT;
|
||||
goto out;
|
||||
@@ -1318,11 +1302,8 @@ int cifsd_vfs_unlink(struct dentry *dir,
|
||||
err = vfs_unlink(dir->d_inode, dentry, NULL);
|
||||
|
||||
out:
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
- inode_unlock(dir->d_inode);
|
||||
-#else
|
||||
mutex_unlock(&dir->d_inode->i_mutex);
|
||||
-#endif
|
||||
+
|
||||
dput(dentry);
|
||||
if (err)
|
||||
cifsd_debug("failed to delete, err %d\n", err);
|
||||
@@ -24,7 +24,7 @@ What we need is the public key for the clients.
|
||||
For dropbear "dropbearkey -y -f files/etc/dropbear/logid" will generate the public key.
|
||||
|
||||
----------
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwn9RaDAzxW1dTmIhXgFBnpi1lhj8xhYpCVQiPxxdk9IEmH8zjo4y9j3sPkqKOlRnkwjpZIpLEKBnpQTwVIMCU/AG7nDJX3OH9RfS9mLJQLfFL8HyGCyqDezFWldbyovhJZvdUeK4tAXJWv2W3OVHiz2L8IlncBgP/E9DJElsyhhQHsM96UE6tBkXsvXkoDbMSYXFcLbgiUwBKfmM2BF/aPDL45iznGur7/2j9v95PwJ0gtMu9jjNRq+pXCXhTh3bsnczm0MpZC1aiRc9nJAeGIMmhrf15E4jBKgTnrstzJxGVAdajKeR954KcNsS33cS2Wmui2YjmPbBXjqf1frzJ log@inteno
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwn9RaDAzxW1dTmIhXgFBnpi1lhj8xhYpCVQiPxxdk9IEmH8zjo4y9j3sPkqKOlRnkwjpZIpLEKBnpQTwVIMCU/AG7nDJX3OH9RfS9mLJQLfFL8HyGCyqDezFWldbyovhJZvdUeK4tAXJWv2W3OVHiz2L8IlncBgP/E9DJElsyhhQHsM96UE6tBkXsvXkoDbMSYXFcLbgiUwBKfmM2BF/aPDL45iznGur7/2j9v95PwJ0gtMu9jjNRq+pXCXhTh3bsnczm0MpZC1aiRc9nJAeGIMmhrf15E4jBKgTnrstzJxGVAdajKeR954KcNsS33cS2Wmui2YjmPbBXjqf1frzJ log@iopsys
|
||||
----------
|
||||
|
||||
The public key should be just one line. Add that line to the
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dslmngr
|
||||
PKG_VERSION:=1.0.1
|
||||
PKG_VERSION:=1.1.0
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=63525fe43aa57a710bb097e4c0ed496c4032db6d
|
||||
PKG_SOURCE_VERSION:=400cc66081f2b10b481d5a745bc505b78af098bd
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/dslmngr.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
endif
|
||||
@@ -25,9 +25,7 @@ PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_mips),y)
|
||||
TARGET_PLATFORM=BROADCOM
|
||||
else ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_arm),y)
|
||||
ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_arm),y)
|
||||
TARGET_PLATFORM=BROADCOM
|
||||
else ifeq ($(CONFIG_TARGET_iopsys_ramips),y)
|
||||
TARGET_PLATFORM=MEDIATEK
|
||||
|
||||
@@ -19,7 +19,7 @@ define Package/easy-qos
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Easy QoS
|
||||
DEPENDS:=@(TARGET_intel_mips||TARGET_iopsys_brcm63xx_arm||TARGET_iopsys_brcm63xx_mips)
|
||||
DEPENDS:=@(TARGET_intel_mips||TARGET_iopsys_brcm63xx_arm)
|
||||
endef
|
||||
|
||||
define Package/easy-qos/description
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=easy-soc-libs
|
||||
PKG_VERSION:=3.3.12
|
||||
PKG_VERSION:=6.0.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=f508577fae01c4820fad884a5a0847d26104721c
|
||||
PKG_SOURCE_VERSION:=fee575f414324c68d0916fab06d10eccb78541fd
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/easy-soc-libs.git
|
||||
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
|
||||
@@ -57,24 +57,11 @@ define Package/libethernet
|
||||
DEPENDS+=+libnl +libnl-route +libeasy +TARGET_iopsys_ramips:swconfig
|
||||
endef
|
||||
|
||||
ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_mips),y)
|
||||
ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_arm),y)
|
||||
TARGET_PLATFORM=BROADCOM
|
||||
TARGET_CFLAGS +=-DIOPSYS_BROADCOM -DCONFIG_BCM963138 \
|
||||
CHIP_ID=$(patsubst "%",%,$(CONFIG_BCM_CHIP_ID))
|
||||
TARGET_CFLAGS +=-DIOPSYS_BROADCOM -DCHIP_$(CHIP_ID) -DCONFIG_BCM9$(CHIP_ID) \
|
||||
-I$(STAGING_DIR)/usr/include/bcm963xx/bcmdrivers/opensource/include/bcm963xx
|
||||
KERNEL_DIR:=$(BUILD_DIR)/bcmkernel/bcm963xx
|
||||
else ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_arm),y)
|
||||
TARGET_PLATFORM=BROADCOM
|
||||
TARGET_CFLAGS +=-DIOPSYS_BROADCOM \
|
||||
-I$(STAGING_DIR)/usr/include/bcm963xx/bcmdrivers/opensource/include/bcm963xx
|
||||
ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_arm_panther),y)
|
||||
TARGET_CFLAGS +=-DCONFIG_BCM96846
|
||||
else ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_arm_tiger),y)
|
||||
TARGET_CFLAGS +=-DCONFIG_BCM96858
|
||||
else ifeq ($(CONFIG_TARGET_iopsys_brcm63xx_arm_eagle),y)
|
||||
TARGET_CFLAGS +=-DCONFIG_BCM963178
|
||||
else
|
||||
TARGET_CFLAGS +=-DCONFIG_BCM963138
|
||||
endif
|
||||
else ifeq ($(CONFIG_TARGET_iopsys_ramips),y)
|
||||
TARGET_PLATFORM=MEDIATEK
|
||||
TARGET_CFLAGS +=-DIOPSYS_MEDIATEK
|
||||
@@ -136,6 +123,7 @@ define Build/InstallDev/libeasy
|
||||
$(CP) $(PKG_BUILD_DIR)/libeasy/easy.h $(1)/usr/include/easy/
|
||||
$(CP) $(PKG_BUILD_DIR)/libeasy/event.h $(1)/usr/include/easy/
|
||||
$(CP) $(PKG_BUILD_DIR)/libeasy/utils.h $(1)/usr/include/easy/
|
||||
$(CP) $(PKG_BUILD_DIR)/libeasy/debug.h $(1)/usr/include/easy/
|
||||
$(CP) $(PKG_BUILD_DIR)/libeasy/libeasy*.so* $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
|
||||
@@ -7,17 +7,18 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_RELEASE:=1
|
||||
PKG_VERSION:=0.3
|
||||
PKG_SOURCE_VERSION:=34ae1996beda98691d779e49f231bd662fc87cda
|
||||
PKG_VERSION:=0.4
|
||||
PKG_SOURCE_VERSION:=d87c1def50d9672dbeb9d5972f36a364b29334b9
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
ifeq ($(CONFIG_ENDPT_OPEN),y)
|
||||
BRCM_KERNEL_PROFILE=$(shell echo $(CONFIG_BCM_KERNEL_PROFILE) | sed s/\"//g)
|
||||
PKG_SOURCE:=endptmngr-$(BRCM_KERNEL_PROFILE)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://download.iopsys.eu/iopsys/opensdk/
|
||||
PKG_SOURCE_URL:=https://download.iopsys.eu/iopsys/opensdk/
|
||||
PKG_NAME:=endptmngr-open
|
||||
PATCH_DIR:=
|
||||
PKG_HASH:=skip
|
||||
else
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/endptmngr.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
@@ -30,6 +31,16 @@ export BUILD_DIR
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
# All config variable that are passed to the make invocation, directly or
|
||||
# indirectly. This ensures that the package is rebuilt on config-changes.
|
||||
PKG_CONFIG_DEPENDS := \
|
||||
CONFIG_TARGET_BOARD
|
||||
|
||||
export CONFIG_BRCM_SDK_VER_504001
|
||||
export CONFIG_BRCM_SDK_VER_504002
|
||||
export CONFIG_BRCM_SDK_VER_504003
|
||||
export CONFIG_BRCM_SDK_VER_504004
|
||||
export CONFIG_BRCM_SDK_VER_504005
|
||||
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
@@ -42,7 +53,7 @@ define Package/endptmngr
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=Brcmslic
|
||||
URL:=
|
||||
DEPENDS:= +libubox +ubus +libpicoevent +bcmkernel @TARGET_HAS_VOICE
|
||||
DEPENDS:= +libubox +ubus +libpicoevent +bcmkernel @TARGET_HAS_VOICE @BCM_VOICE
|
||||
endef
|
||||
|
||||
define Package/endptmngr/description
|
||||
|
||||
@@ -129,6 +129,8 @@ static int canyon_led_probe(struct platform_device *pdev)
|
||||
if (ret < 0) {
|
||||
dev_warn(&pdev->dev, "Could not read led-count property\n");
|
||||
leds->led_count = SK9822_DEFAULT_NUM_LEDS;
|
||||
} else {
|
||||
printk(KERN_INFO "Got led count: %u\n", leds->led_count);
|
||||
}
|
||||
|
||||
leds->led_colors = devm_kzalloc(&pdev->dev,
|
||||
@@ -140,7 +142,7 @@ static int canyon_led_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, leds);
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 16, 0)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
|
||||
leds->clock_gpio = gpiod_get_index(&pdev->dev, "led", 0);
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
||||
leds->clock_gpio = gpiod_get_index(&pdev->dev, "led", 0, GPIOD_OUT_HIGH);
|
||||
@@ -148,6 +150,12 @@ static int canyon_led_probe(struct platform_device *pdev)
|
||||
dev_warn(&pdev->dev, "Kernel version Not supported\n");
|
||||
exit(1);
|
||||
#endif
|
||||
if (IS_ERR(leds->clock_gpio)) {
|
||||
dev_err(&pdev->dev, "Failed to acquire clock GPIO %ld\n",
|
||||
PTR_ERR(leds->clock_gpio));
|
||||
leds->clock_gpio = NULL;
|
||||
return PTR_ERR(leds->clock_gpio);
|
||||
}
|
||||
|
||||
gpiod_direction_output(leds->clock_gpio, 1);
|
||||
if (IS_ERR(leds->clock_gpio)) {
|
||||
@@ -160,7 +168,7 @@ static int canyon_led_probe(struct platform_device *pdev)
|
||||
gpiod_set_value(leds->clock_gpio, 0);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 16, 0)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
|
||||
leds->data_gpio = gpiod_get_index(&pdev->dev, "led", 1);
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
|
||||
leds->data_gpio = gpiod_get_index(&pdev->dev, "led", 1, GPIOD_OUT_HIGH);
|
||||
@@ -168,6 +176,12 @@ static int canyon_led_probe(struct platform_device *pdev)
|
||||
dev_warn(&pdev->dev, "Kernel version Not supported\n");
|
||||
exit(1);
|
||||
#endif
|
||||
if (IS_ERR(leds->data_gpio)) {
|
||||
dev_err(&pdev->dev, "Failed to acquire data GPIO %ld\n",
|
||||
PTR_ERR(leds->data_gpio));
|
||||
leds->data_gpio = NULL;
|
||||
return PTR_ERR(leds->data_gpio);
|
||||
}
|
||||
|
||||
gpiod_direction_output(leds->data_gpio, 1);
|
||||
if (IS_ERR(leds->data_gpio)) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
if PACKAGE_icwmp-curl || PACKAGE_icwmp-zstream
|
||||
if PACKAGE_icwmp
|
||||
|
||||
config CWMP_SCRIPTS_FULL
|
||||
bool "Install all icwmp scripts"
|
||||
@@ -22,6 +22,6 @@ config CWMP_DEBUG
|
||||
config CWMP_DEVEL_DEBUG
|
||||
bool "Compile with development debug options"
|
||||
default n
|
||||
|
||||
|
||||
endif
|
||||
|
||||
|
||||
188
icwmp/Makefile
188
icwmp/Makefile
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 iopsys Software Solutions AB
|
||||
# Copyright (C) 2020 iopsys Software Solutions AB
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
@@ -8,11 +8,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=icwmp
|
||||
PKG_VERSION:=4.0-2020-06-25
|
||||
PKG_VERSION:=6.3.2-2020-12-21
|
||||
PKG_FIXUP:=autoreconf
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/icwmp.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=7a6da73ae20abc27baf3aa4c1b2c1c0c0ecac82e
|
||||
PKG_SOURCE_VERSION:=495e905c30ac7423035a8c0c2c67effc0c607475
|
||||
PKG_RELEASE=$(PKG_SOURCE_VERSION)
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
@@ -26,80 +26,25 @@ PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_CWMP_DEBUG \
|
||||
CONFIG_CWMP_DEVEL_DEBUG
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
CWMP_REVISION=$(shell svnversion ./src/ -n|cut -f2 -d:)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/icwmp_stun
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=TR-069 stun Client
|
||||
DEPENDS:=+PACKAGE_icwmp_stun:libubus +PACKAGE_icwmp_stun:libuci +PACKAGE_icwmp_stun:libubox +PACKAGE_icwmp_stun:libjson-c +PACKAGE_icwmp_stun:libopenssl +PACKAGE_icwmp_stun:libblobmsg-json
|
||||
endef
|
||||
|
||||
define Package/icwmp_xmpp
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=TR-069 xmpp feature
|
||||
DEPENDS:=+PACKAGE_icwmp_xmpp:libuci +PACKAGE_icwmp_xmpp:libubox +PACKAGE_icwmp_xmpp:libexpat +PACKAGE_icwmp_xmpp:libstrophe
|
||||
endef
|
||||
|
||||
define Package/icwmp_twamp
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=TR-069 twamp feature
|
||||
DEPENDS:=+PACKAGE_icwmp_twamp:libuci
|
||||
endef
|
||||
|
||||
define Package/icwmp_udpechoserver
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=TR-069 udpechoserver feature
|
||||
DEPENDS:=+PACKAGE_icwmp_udpechoserver:libuci
|
||||
endef
|
||||
|
||||
define Package/icwmp_bulkdata
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=TR-069 BulkData Collection
|
||||
DEPENDS:=+PACKAGE_icwmp_bulkdata:libubus +PACKAGE_icwmp_bulkdata:libuci +PACKAGE_icwmp_bulkdata:libubox +PACKAGE_icwmp_bulkdata:libjson-c +PACKAGE_icwmp_bulkdata:libcurl +PACKAGE_icwmp_bulkdata:curl +PACKAGE_icwmp_bulkdata:libblobmsg-json +PACKAGE_icwmp_bulkdata:libbbfdm
|
||||
endef
|
||||
|
||||
define Package/icwmp-tr098
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=CWMP client for TR-098 Data Model
|
||||
DEPENDS:=+PACKAGE_icwmp-tr098:libuci +PACKAGE_icwmp-tr098:libmicroxml +PACKAGE_icwmp-tr098:libubox +PACKAGE_icwmp-tr098:jshn +PACKAGE_icwmp-tr098:libubus +PACKAGE_icwmp-tr098:libblobmsg-json +PACKAGE_icwmp-tr098:libpthread +PACKAGE_icwmp-tr098:ubusd +PACKAGE_icwmp-tr098:shflags +PACKAGE_icwmp-tr098:getopt +PACKAGE_icwmp-tr098:zlib +PACKAGE_icwmp-tr098:libjson-c +PACKAGE_icwmp-tr098:libopenssl +PACKAGE_icwmp-tr098:curl +PACKAGE_icwmp-tr098:libcurl +PACKAGE_icwmp-tr098:libtr098
|
||||
endef
|
||||
|
||||
define Package/icwmp/Default
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=CWMP client
|
||||
DEPENDS:=+libuci +libmicroxml +libubox +jshn +libubus +libblobmsg-json +libpthread +ubusd +shflags +getopt +zlib +libjson-c +libopenssl +curl +libbbfdm +libbbf_api
|
||||
DEPENDS:=+libuci +libmicroxml +libubox +jshn +libubus +libblobmsg-json +libpthread +ubusd +shflags +getopt +zlib +libjson-c +libopenssl +curl +libcurl +libbbfdm +libbbf_api
|
||||
endef
|
||||
|
||||
define Package/icwmp/description
|
||||
define Package/$(PKG_NAME)/description
|
||||
A free client implementation of CWMP (TR-069) protocol
|
||||
endef
|
||||
|
||||
define Package/icwmp-curl
|
||||
$(call Package/icwmp/Default)
|
||||
TITLE+= (using libcurl)
|
||||
DEPENDS+= +PACKAGE_icwmp-curl:libcurl
|
||||
VARIANT:=curl
|
||||
endef
|
||||
|
||||
define Package/icwmp-zstream
|
||||
$(call Package/icwmp/Default)
|
||||
TITLE+= (using libzstream)
|
||||
DEPENDS+= +PACKAGE_icwmp-zstream:libzstream
|
||||
VARIANT:=zstream
|
||||
endef
|
||||
|
||||
define Package/icwmp-curl/config
|
||||
define Package/$(PKG_NAME)/config
|
||||
source "$(SOURCE)/Config_cwmp.in"
|
||||
endef
|
||||
|
||||
@@ -113,36 +58,6 @@ endif
|
||||
TARGET_CFLAGS += \
|
||||
-D_GNU_SOURCE -D_AADJ
|
||||
|
||||
ifeq ($(CONFIG_PACKAGE_icwmp-tr098),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-icwmp_tr098
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PACKAGE_icwmp_xmpp),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-icwmp_xmpp
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PACKAGE_icwmp_stun),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-icwmp_stun
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PACKAGE_icwmp_udpechoserver),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-icwmp_udpechoserver
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PACKAGE_icwmp_twamp),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-icwmp_twamp
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PACKAGE_icwmp_bulkdata),y)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-icwmp_bulkdata
|
||||
endif
|
||||
|
||||
ifneq ($(CWMP_REVISION)_,_)
|
||||
ifneq ($(CWMP_REVISION),exported)
|
||||
ifneq ($(CWMP_REVISION),Unversioned directory)
|
||||
@@ -159,17 +74,6 @@ CONFIGURE_ARGS += \
|
||||
--with-uci-include-path=$(STAGING_DIR)/usr/include \
|
||||
--with-libubox-include-path=$(STAGING_DIR)/usr/include \
|
||||
--with-libubus-include-path=$(STAGING_DIR)/usr/include
|
||||
|
||||
ifeq ($(BUILD_VARIANT),zstream)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-http=zstream \
|
||||
--with-zstream-include-path=$(STAGING_DIR)/usr/include
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_VARIANT),curl)
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-http=curl
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CWMP_ACS_MULTI),y)
|
||||
CONFIGURE_ARGS += \
|
||||
@@ -191,17 +95,10 @@ CONFIGURE_ARGS += \
|
||||
--enable-devel
|
||||
endif
|
||||
|
||||
define Package/icwmp-$(BUILD_VARIANT)/install
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/etc/icwmpd
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(CP) $(PKG_BUILD_DIR)/bin/icwmpd $(1)/usr/sbin
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/cwmp $(1)/etc/config
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/firewall.cwmp $(1)/etc/firewall.cwmp
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/init/icwmpd.init $(1)/etc/init.d/icwmpd
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/uci-defaults/* $(1)/etc/uci-defaults/
|
||||
ifeq ($(CONFIG_CWMP_SCRIPTS_FULL),y)
|
||||
$(INSTALL_DIR) $(1)/usr/share/icwmp
|
||||
$(CP) $(PKG_BUILD_DIR)/scripts/defaults $(1)/usr/share/icwmp
|
||||
@@ -212,60 +109,8 @@ endif
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
define Package/icwmp-tr098/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(CP) $(PKG_BUILD_DIR)/bin/icwmp_tr098d $(1)/usr/sbin
|
||||
endef
|
||||
|
||||
define Package/icwmp_stun/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/icwmp_stund $(1)/usr/sbin/icwmp_stund
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/init/icwmp_stund $(1)/etc/init.d/icwmp_stund
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/cwmp_stun $(1)/etc/config
|
||||
endef
|
||||
|
||||
define Package/icwmp_xmpp/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/icwmp_xmppd $(1)/usr/sbin/icwmp_xmppd
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/init/icwmp_xmppd $(1)/etc/init.d/icwmp_xmppd
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/cwmp_xmpp $(1)/etc/config
|
||||
$(CP) ./xmpp-files/* $(1)/
|
||||
endef
|
||||
|
||||
define Package/icwmp_udpechoserver/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/icwmp_udpechoserverd $(1)/usr/sbin/icwmp_udpechoserverd
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/init/icwmp_udpechoserverd $(1)/etc/init.d/icwmp_udpechoserverd
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/cwmp_udpechoserver $(1)/etc/config
|
||||
endef
|
||||
|
||||
define Package/icwmp_twamp/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/icwmp_twampd $(1)/usr/sbin/icwmp_twampd
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/init/icwmp_twampd $(1)/etc/init.d/icwmp_twampd
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/cwmp_twamp $(1)/etc/config
|
||||
endef
|
||||
|
||||
define Package/icwmp_bulkdata/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/icwmp_bulkdatad $(1)/usr/sbin/icwmp_bulkdatad
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/init/icwmp_bulkdatad $(1)/etc/init.d/icwmp_bulkdatad
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/config/cwmp_bulkdata $(1)/etc/config
|
||||
endef
|
||||
|
||||
define Package/icwmp-$(BUILD_VARIANT)/postinst
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
echo "$(CWMP_BKP_FILE)" >> $${IPKG_INSTROOT}/etc/sysupgrade.conf
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
echo "Enabling rc.d symlink for icwmpd"
|
||||
/etc/init.d/icwmpd enable
|
||||
@@ -273,7 +118,7 @@ define Package/icwmp-$(BUILD_VARIANT)/postinst
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/icwmp-$(BUILD_VARIANT)/prerm
|
||||
define Package/$(PKG_NAME)/prerm
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
echo "Disabling rc.d symlink for icwmpd"
|
||||
@@ -282,11 +127,4 @@ define Package/icwmp-$(BUILD_VARIANT)/prerm
|
||||
exit 0
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,icwmp-curl))
|
||||
$(eval $(call BuildPackage,icwmp_stun))
|
||||
$(eval $(call BuildPackage,icwmp_xmpp))
|
||||
$(eval $(call BuildPackage,icwmp_udpechoserver))
|
||||
$(eval $(call BuildPackage,icwmp_twamp))
|
||||
$(eval $(call BuildPackage,icwmp_bulkdata))
|
||||
$(eval $(call BuildPackage,icwmp-tr098))
|
||||
#$(eval $(call BuildPackage,icwmp-zstream))
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
|
||||
48
icwmp/files/etc/config/cwmp
Normal file
48
icwmp/files/etc/config/cwmp
Normal file
@@ -0,0 +1,48 @@
|
||||
config acs 'acs'
|
||||
option url ''
|
||||
option userid '' #$OUI-$SER
|
||||
option passwd 'iopsys'
|
||||
option periodic_inform_enable 'true'
|
||||
option periodic_inform_interval '1800'
|
||||
option periodic_inform_time '0'
|
||||
option ParameterKey ''
|
||||
option dhcp_discovery 'enable'
|
||||
# compression possible configs: GZIP, Deflate, Disabled
|
||||
option compression 'Disabled'
|
||||
# possible configs interval :[1:65535]
|
||||
option retry_min_wait_interval '5'
|
||||
# possible configs interval :[1000:65535]
|
||||
option retry_interval_multiplier '2000'
|
||||
option https_ssl_capath ''
|
||||
option ipv6_enable '0'
|
||||
option ip_version '4'
|
||||
|
||||
config cpe 'cpe'
|
||||
option interface 'eth0.1'
|
||||
option default_wan_interface 'wan'
|
||||
option log_to_console 'disable'
|
||||
option log_to_file 'enable'
|
||||
# log_severity: INFO (Default)
|
||||
# log_severity possible configs: EMERG, ALERT, CRITIC ,ERROR, WARNING, NOTICE, INFO, DEBUG
|
||||
option log_severity 'INFO'
|
||||
option log_file_name '/var/log/icwmpd.log'
|
||||
option log_max_size '102400'
|
||||
option userid '' #$OUI-$SER
|
||||
option passwd 'iopsys'
|
||||
option port '7547'
|
||||
option ubus_socket '/var/run/ubus.sock'
|
||||
option provisioning_code ''
|
||||
option amd_version '5'
|
||||
# compression possible configs: InstanceNumber, InstanceAlias
|
||||
option instance_mode 'InstanceNumber'
|
||||
option session_timeout '60'
|
||||
option notification '1'
|
||||
option datamodel 'tr181'
|
||||
option exec_download '0'
|
||||
option periodic_notify_enable '1'
|
||||
option periodic_notify_interval '10'
|
||||
|
||||
config lwn 'lwn'
|
||||
option enable '1'
|
||||
option hostname ''
|
||||
option port '0'
|
||||
21
icwmp/files/etc/firewall.cwmp
Normal file
21
icwmp/files/etc/firewall.cwmp
Normal file
@@ -0,0 +1,21 @@
|
||||
#created by the icwmp package
|
||||
zone_name=""
|
||||
port=""
|
||||
if [ "$zone_name" = "" ]; then
|
||||
exit 0
|
||||
elif [ "$zone_name" = "icwmp" ]; then
|
||||
iptables -nL zone_icwmp_input 2> /dev/null
|
||||
if [ $? != 0 ]; then
|
||||
iptables -N zone_icwmp_input
|
||||
iptables -t filter -A INPUT -j zone_icwmp_input
|
||||
iptables -I zone_icwmp_input -p tcp --dport $port -j REJECT
|
||||
else
|
||||
iptables -F zone_icwmp_input
|
||||
iptables -I zone_icwmp_input -p tcp --dport $port -j REJECT
|
||||
fi
|
||||
else
|
||||
iptables -F zone_icwmp_input 2> /dev/null
|
||||
iptables -t filter -D INPUT -j zone_icwmp_input 2> /dev/null
|
||||
iptables -X zone_icwmp_input 2> /dev/null
|
||||
fi
|
||||
#iptables -I FW_ZONE -p tcp -s ACS_ADDRESS --dport PORT -j ACCEPT --comment "Open ACS port"
|
||||
197
icwmp/files/etc/init.d/icwmpd
Executable file
197
icwmp/files/etc/init.d/icwmpd
Executable file
@@ -0,0 +1,197 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2015-2019 iopsys Software Solutions AB
|
||||
|
||||
. /lib/functions.sh
|
||||
include /lib/network
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
|
||||
USE_PROCD=1
|
||||
PROG="/usr/sbin/icwmpd"
|
||||
|
||||
EXTRA_COMMANDS="notify"
|
||||
EXTRA_HELP=" start [GetRPCMethods] Start icwmpd service and send GetRPCMethods"
|
||||
|
||||
validate_url() {
|
||||
# SCHEMA_LIST: contain list of possible schemas that could be present in the acs url
|
||||
# Example: SCHEMA_LIST="http https"
|
||||
SCHEMA_LIST="http"
|
||||
|
||||
for schema in $SCHEMA_LIST; do
|
||||
dest=`echo $1 | sed 's/$schema:\/\///g' | cut -f1 -d \/ | cut -f1 -d:`
|
||||
if [ "_$dest" != "_" ]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
get_acs_url() {
|
||||
local default_acs="http://10.10.1.6:8000/openacs/acs"
|
||||
local acs_dhcp_discovery="$(uci -q get cwmp.acs.dhcp_discovery)"
|
||||
local url="$(uci -q get cwmp.acs.url)"
|
||||
local dhcp_url="$(uci -P /var/state -q get cwmp.acs.dhcp_url)"
|
||||
|
||||
if [ "$acs_dhcp_discovery" == "enable" -a -n "$dhcp_url" -o -z "$url" ]; then
|
||||
url="$dhcp_url"
|
||||
echo "ACS URL from DHCP server: $url"
|
||||
[ -n "$url" ] && uci -P /var/state -q set cwmp.acs.url="$url" || url="$default_acs"
|
||||
elif [ -n "$url" ];then
|
||||
url="$(uci -q get cwmp.acs.url)"
|
||||
echo "ACS URL from configuration: $url"
|
||||
else
|
||||
url="$default_acs"
|
||||
echo "Using default ACS URL: $url"
|
||||
[ -n "$url" ] && uci -P /var/state -q set cwmp.acs.url="$url"
|
||||
fi
|
||||
|
||||
validate_url "$url"
|
||||
if [ "$?" != "0" ];then
|
||||
echo "Invalid ACS URL: $url"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
enable_dhcp_option43() {
|
||||
local wan=$1
|
||||
local discovery=0
|
||||
case $2 in
|
||||
enable|1) discovery=1 ;;
|
||||
esac
|
||||
|
||||
### Ask for DHCP Option 43 only if CWMP is enabled ###
|
||||
local enabled
|
||||
local newreqopts=
|
||||
local baseopts=
|
||||
local reqopts="$(uci -q get network.$wan.reqopts)"
|
||||
local proto="$(uci -q get network.$wan.proto)"
|
||||
local tropts="43"
|
||||
local oldreqopts="$reqopts"
|
||||
local ropt iopt
|
||||
for ropt in $reqopts; do
|
||||
case $ropt in
|
||||
43) ;;
|
||||
*) baseopts="$baseopts $ropt" ;;
|
||||
esac
|
||||
done
|
||||
ropt=""
|
||||
reqopts="$baseopts $tropts"
|
||||
for ropt in $reqopts; do
|
||||
case $ropt in
|
||||
43) [ $discovery -eq 1 ] && newreqopts="$newreqopts $ropt" ;;
|
||||
*) newreqopts="$newreqopts $ropt" ;;
|
||||
esac
|
||||
done
|
||||
if [ $proto == "dhcp" ]; then
|
||||
newreqopts="$(echo $newreqopts | tr ' ' '\n' | sort -n | tr '\n' ' ' | sed 's/^[ \t]*//;s/[ \t]*$//')"
|
||||
oldreqopts="$(echo $oldreqopts | tr ' ' '\n' | sort -n | tr '\n' ' ' | sed 's/^[ \t]*//;s/[ \t]*$//')"
|
||||
[ "$newreqopts" == "$oldreqopts" ] && return
|
||||
uci -q set network.$wan.reqopts="$newreqopts"
|
||||
uci commit network
|
||||
ubus call network reload
|
||||
fi
|
||||
########################################################
|
||||
}
|
||||
|
||||
wait_for_option43() {
|
||||
local time=$1
|
||||
local default_wan_interface dhcp_discovery url
|
||||
|
||||
config_get default_wan_interface cpe default_wan_interface "wan"
|
||||
config_get dhcp_discovery acs dhcp_discovery "0"
|
||||
config_get url acs url
|
||||
|
||||
enable_dhcp_option43 $default_wan_interface $dhcp_discovery
|
||||
|
||||
local tm=0
|
||||
|
||||
if [ "$dhcp_discovery" == "enable" -o "$dhcp_discovery" == "1" ]
|
||||
then
|
||||
echo "Waiting for discovery of ACS URL from dhcp server ..."
|
||||
while [ $tm -le $time ]
|
||||
do
|
||||
acs_url=`uci -P /var/state -q get cwmp.acs.dhcp_url`
|
||||
if [ "$acs_url" != "" ]
|
||||
then
|
||||
break
|
||||
else
|
||||
sleep 1
|
||||
fi
|
||||
tm=$((tm+1))
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_resolvfile() {
|
||||
local time=$1
|
||||
local tm=1
|
||||
|
||||
local resolvfile="$(uci -q get dhcp.@dnsmasq[0].resolvfile)"
|
||||
[ -n "$resolvfile" ] || return
|
||||
|
||||
while [ ! -f $resolvfile ]; do
|
||||
sleep 1
|
||||
[ $tm -ge $time ] && break
|
||||
tm=$((tm+1))
|
||||
done
|
||||
}
|
||||
|
||||
set_wan_interface() {
|
||||
local l3_device=""
|
||||
local default_wan_interface=""
|
||||
|
||||
config_get default_wan_interface cpe default_wan_interface "wan"
|
||||
json_load "$(ifstatus $default_wan_interface)"
|
||||
json_get_var l3_device l3_device
|
||||
if [ "$l3_device" != "" ];then
|
||||
uci -q set cwmp.cpe.interface="$l3_device"
|
||||
uci -q commit cwmp
|
||||
fi
|
||||
}
|
||||
|
||||
start_service() {
|
||||
if [ ! -f /tmp/.icwmpd_boot ]; then
|
||||
touch /etc/icwmpd/.icwmpd_boot
|
||||
touch /tmp/.icwmpd_boot
|
||||
else
|
||||
[ -f /sbin/netifd ] && echo "Waiting for Network to be started ..." && ubus -t 5 wait_for network.interface
|
||||
[ -f /etc/config/wireless ] && echo "Waiting for WiFi to be started ..." && ubus -t 5 wait_for network.wireless
|
||||
[ -f /usr/sbin/dnsmasq ] && echo "Waiting for DNS Proxy to be started ..." && ubus -t 5 wait_for dnsmasq
|
||||
[ -f /etc/config/dhcp ] && echo "Waiting for DNS Server(s) ..." && wait_for_resolvfile 20
|
||||
[ -f /usr/sbin/asterisk ] && echo "Waiting for Voice to be started ..." && ubus -t 5 wait_for asterisk
|
||||
|
||||
config_load cwmp
|
||||
set_wan_interface
|
||||
wait_for_option43 20
|
||||
get_acs_url
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command "$PROG"
|
||||
if [ "$1" = "GetRPCMethods" ];then
|
||||
procd_append_param command -g
|
||||
elif [ -f /etc/icwmpd/.icwmpd_boot ]; then
|
||||
procd_append_param command -b
|
||||
fi
|
||||
procd_set_param respawn "3" "7" "0"
|
||||
procd_close_instance
|
||||
#procd_open_instance
|
||||
#[ "$(uci -q get cwmp.cpe.notification)" == "1" ] && procd_append_param command "/usr/sbin/icwmp_notifd"
|
||||
#procd_close_instance
|
||||
fi
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
notify() {
|
||||
ubus -t 1 call tr069 notify >/dev/null 2>&1 &
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_config_trigger "config.change" "cwmp" /etc/init.d/icwmpd reload
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# Copy defaults by the factory to the cwmp UCI user section.
|
||||
|
||||
|
||||
@@ -15,10 +14,19 @@ mac=$(printf "%12.12X" $((0x$baseMac)))
|
||||
# Get system serial number.
|
||||
serial=$(db -q get hw.board.serial_number)
|
||||
|
||||
uci -q batch <<-EOF
|
||||
set cwmp.acs.userid="${mac:0:6}-${serial}"
|
||||
set cwmp.cpe.userid="${mac:0:6}-${serial}"
|
||||
EOF
|
||||
# Get userid values
|
||||
acs_userid=$(uci -q get cwmp.acs.userid)
|
||||
cpe_userid=$(uci -q get cwmp.cpe.userid)
|
||||
|
||||
# Only set if they are empty
|
||||
if [ -z "$acs_userid" ]
|
||||
then
|
||||
uci -q set cwmp.acs.userid="${mac:0:6}-${serial}"
|
||||
fi
|
||||
|
||||
if [ -z "$cpe_userid" ]
|
||||
then
|
||||
uci -q set cwmp.cpe.userid="${mac:0:6}-${serial}"
|
||||
fi
|
||||
|
||||
# No need for commit here, it is done by uci_apply_defaults().
|
||||
|
||||
12
icwmp/files/etc/uci-defaults/90-cwmpfirewall
Normal file
12
icwmp/files/etc/uci-defaults/90-cwmpfirewall
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOT
|
||||
delete firewall.cwmp
|
||||
set firewall.cwmp=include
|
||||
set firewall.cwmp.path=/etc/firewall.cwmp
|
||||
set firewall.cwmp.reload=1
|
||||
commit firewall
|
||||
EOT
|
||||
|
||||
exit 0
|
||||
|
||||
1
icwmp/files/lib/upgrade/keep.d/icwmp
Normal file
1
icwmp/files/lib/upgrade/keep.d/icwmp
Normal file
@@ -0,0 +1 @@
|
||||
/etc/icwmpd/.icwmpd_backup_session.xml
|
||||
29
icwmp/files/lib/upgrade/post-rootfs-fixup.d/215-icwmp
Executable file
29
icwmp/files/lib/upgrade/post-rootfs-fixup.d/215-icwmp
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
|
||||
# As part of sysupgrade we copy CWMP Backup Session XML file.
|
||||
|
||||
|
||||
# Abort on any error.
|
||||
set -e
|
||||
|
||||
|
||||
# Do nothing if user want to discard old settings.
|
||||
if [ -n "$SAVE_CONFIG" ] && [ $SAVE_CONFIG -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Source functions.
|
||||
for f in /lib/upgrade/iopsys*.sh; do
|
||||
[ -r "$f" -a -s "$f" ] || continue
|
||||
source $f
|
||||
done
|
||||
|
||||
|
||||
if [ -s "${2}/etc/icwmpd/.icwmpd_backup_session.xml" ]; then
|
||||
cat "${2}/etc/icwmpd/.icwmpd_backup_session.xml" > "/etc/icwmpd/.icwmpd_backup_session.xml"
|
||||
fi
|
||||
|
||||
# Report success.
|
||||
log "post-hooks" "CWMP Backup Session XML file migrated"
|
||||
|
||||
exit 0
|
||||
@@ -21,8 +21,8 @@ menu "developer/debug options"
|
||||
config IEEE1905_ALME_OVER_UBUS
|
||||
bool "ALME methods supported over ubus"
|
||||
|
||||
config IEEE1905_ALME_OVER_TCP
|
||||
bool "ALME server over TCP port"
|
||||
#config IEEE1905_ALME_OVER_TCP
|
||||
# bool "ALME server over TCP port"
|
||||
|
||||
endchoice
|
||||
endmenu
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ieee1905
|
||||
PKG_VERSION:=2.0.18
|
||||
PKG_VERSION:=2.1.32
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=44035a3bb0dd7e9fc1feb037c72c2c0d33692a98
|
||||
PKG_SOURCE_VERSION:=2bb1c564d31a99d80a3f977c1f817777722a601d
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/ieee1905.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
endif
|
||||
@@ -23,7 +23,7 @@ define Package/ieee1905
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=IEEE1905 daemon
|
||||
DEPENDS:= +libuci +libjson-c +lib1905 +ubox +libpcap +libopenssl +libwifi +libeasy
|
||||
DEPENDS:= +libuci +libjson-c +libieee1905 +ubox +libpcap +libopenssl +libwifi +libeasy
|
||||
endef
|
||||
|
||||
define Package/ieee1905/config
|
||||
@@ -34,18 +34,28 @@ define Package/ieee1905/description
|
||||
IEEE1905 stack with extended functionalities.
|
||||
endef
|
||||
|
||||
define Package/lib1905
|
||||
define Package/libieee1905
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=IEEE1905 cmdu tlv utility library
|
||||
endef
|
||||
|
||||
define Package/libwsc
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=Wifi Simple Configuration building and processing library
|
||||
DEPENDS= +libopenssl +libuci +libubus
|
||||
endef
|
||||
|
||||
define Package/lib1905hle
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=IEEE1905 hle stack library
|
||||
endef
|
||||
|
||||
LIBS := \
|
||||
$(if $(CONFIG_PACKAGE_libwsc),libwsc.so)
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include \
|
||||
-D_GNU_SOURCE \
|
||||
@@ -53,6 +63,9 @@ TARGET_CFLAGS += \
|
||||
-Wall \
|
||||
-Wextra
|
||||
|
||||
MAKE_FLAGS += \
|
||||
LIBS="$(LIBS)"
|
||||
|
||||
ifeq ($(CONFIG_IEEE1905_SPEED_UP_DISCOVERY),y)
|
||||
TARGET_CFLAGS += -DSPEED_UP_DISCOVERY
|
||||
endif
|
||||
@@ -79,6 +92,7 @@ define Package/ieee1905/install
|
||||
$(INSTALL_DIR) $(1)/etc
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DIR) $(1)/etc/ieee1905
|
||||
$(INSTALL_DIR) $(1)/usr/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) ./files/etc/init.d/ieee1905 $(1)/etc/init.d/ieee1905
|
||||
@@ -91,23 +105,37 @@ define Package/lib1905hle/install
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/lib1905hle.so $(1)/usr/lib/lib1905hle.so
|
||||
endef
|
||||
|
||||
define Package/lib1905/install
|
||||
define Package/libieee1905/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/lib1905.so $(1)/usr/lib/lib1905.so
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/libieee1905.so $(1)/usr/lib/libieee1905.so
|
||||
endef
|
||||
|
||||
define Package/libwsc/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/libwsc.so $(1)/usr/lib/libwsc.so
|
||||
endef
|
||||
|
||||
define Build/InstallDev/libwsc.so
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/libwsc/include/wsc.h $(1)/usr/include/
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/libwsc.so $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(INSTALL_DIR) $(1)/usr/include/lib1905
|
||||
$(INSTALL_DIR) $(1)/usr/include/ieee1905
|
||||
$(INSTALL_DIR) $(1)/usr/include/ieee1905
|
||||
$(INSTALL_DIR) $(1)/usr/include/lib1905hle
|
||||
$(CP) $(PKG_BUILD_DIR)/include/*.h $(1)/usr/include/ieee1905/
|
||||
$(CP) $(PKG_BUILD_DIR)/lib1905/include/*.h $(1)/usr/include/lib1905/
|
||||
$(CP) $(PKG_BUILD_DIR)/libieee1905/include/*.h $(1)/usr/include/ieee1905/
|
||||
$(CP) $(PKG_BUILD_DIR)/lib1905hle/include/*.h $(1)/usr/include/lib1905hle/
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/lib1905.so $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/lib/libieee1905.so $(1)/usr/lib
|
||||
$(foreach lib,$(LIBS),$(call Build/InstallDev/$(lib),$(1),$(2));)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,lib1905))
|
||||
$(eval $(call BuildPackage,libieee1905))
|
||||
$(eval $(call BuildPackage,lib1905hle))
|
||||
$(eval $(call BuildPackage,libwsc))
|
||||
$(eval $(call BuildPackage,ieee1905))
|
||||
|
||||
@@ -5,13 +5,10 @@ config ieee1905 'ieee1905'
|
||||
option macaddress 'auto'
|
||||
option registrar 0
|
||||
option cmdu_event 1
|
||||
option map_plugin 0
|
||||
option map_plugin 1
|
||||
|
||||
config security 'security'
|
||||
list method 'PBC'
|
||||
option ssid ''
|
||||
option encryption ''
|
||||
option key 'TESTPASSWORD'
|
||||
|
||||
config al-iface
|
||||
option enabled 1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
START=96
|
||||
STOP=22
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/usr/sbin/ieee1905d
|
||||
@@ -43,7 +43,14 @@ configure_network()
|
||||
fi
|
||||
}
|
||||
|
||||
service_running() {
|
||||
ubus -t 2 wait_for wifi
|
||||
}
|
||||
|
||||
start_service() {
|
||||
|
||||
[ -d /usr/lib/ieee1905 ] || mkdir -p /usr/lib/ieee1905
|
||||
|
||||
procd_open_instance ieee1905
|
||||
procd_set_param command ${PROG}
|
||||
configure_ieee1905 "ieee1905"
|
||||
@@ -61,4 +68,5 @@ service_triggers() {
|
||||
procd_add_reload_trigger "network"
|
||||
procd_add_reload_trigger "wireless"
|
||||
procd_add_reload_trigger "netmode"
|
||||
procd_add_reload_trigger "ieee1905"
|
||||
}
|
||||
|
||||
40
iop/config
40
iop/config
@@ -7,6 +7,9 @@ CONFIG_PACKAGE_6in4=y
|
||||
CONFIG_PACKAGE_6rd=y
|
||||
CONFIG_PACKAGE_6to4=y
|
||||
CONFIG_PACKAGE_alsa-lib=y
|
||||
CONFIG_PACKAGE_atftp=m
|
||||
CONFIG_PACKAGE_atftpd=m
|
||||
CONFIG_PACKAGE_bulkdata=y
|
||||
CONFIG_PACKAGE_chat=y
|
||||
CONFIG_PACKAGE_comgt=y
|
||||
CONFIG_PACKAGE_comgt-directip=y
|
||||
@@ -14,13 +17,18 @@ CONFIG_PACKAGE_comgt-ncm=y
|
||||
CONFIG_PACKAGE_ddns-scripts=y
|
||||
CONFIG_PACKAGE_ds-lite=y
|
||||
CONFIG_PACKAGE_ethtool=y
|
||||
CONFIG_PACKAGE_gdb=m
|
||||
CONFIG_PACKAGE_getopt=y
|
||||
CONFIG_PACKAGE_glib2=y
|
||||
CONFIG_PACKAGE_icwmp-curl=y
|
||||
CONFIG_PACKAGE_icwmp=y
|
||||
CONFIG_PACKAGE_ieee1905=y
|
||||
CONFIG_PACKAGE_map-1905=y
|
||||
CONFIG_PACKAGE_map-topology=y
|
||||
CONFIG_PACKAGE_mosquitto-client-ssl=y
|
||||
CONFIG_PACKAGE_mosquitto-ssl=y
|
||||
CONFIG_PACKAGE_wfadatad=y
|
||||
CONFIG_PACKAGE_imonitor=m
|
||||
CONFIG_PACKAGE_inbd=y
|
||||
CONFIG_PACKAGE_iopupgrade=m
|
||||
CONFIG_PACKAGE_iopupgrade=y
|
||||
CONFIG_PACKAGE_ip-full=y
|
||||
CONFIG_PACKAGE_iperf3=y
|
||||
CONFIG_PACKAGE_ipset=y
|
||||
@@ -43,8 +51,8 @@ CONFIG_PACKAGE_juci-theme-iopsys=y
|
||||
CONFIG_PACKAGE_libdaemon=y
|
||||
CONFIG_PACKAGE_libgmp=y
|
||||
CONFIG_PACKAGE_libreadline=y
|
||||
CONFIG_PACKAGE_libreswan=m
|
||||
CONFIG_PACKAGE_libwifi=y
|
||||
CONFIG_PACKAGE_loop-detector=m
|
||||
CONFIG_PACKAGE_lscpu=y
|
||||
CONFIG_PACKAGE_map=y
|
||||
CONFIG_PACKAGE_miniupnpd=y
|
||||
@@ -61,6 +69,7 @@ CONFIG_PACKAGE_openssl-util=y
|
||||
CONFIG_OPENSSL_WITH_COMPRESSION=y
|
||||
CONFIG_PACKAGE_openvpn-easy-rsa=y
|
||||
CONFIG_PACKAGE_openvpn-openssl=y
|
||||
CONFIG_PACKAGE_owsd=y
|
||||
CONFIG_PACKAGE_peripheral_manager=y
|
||||
CONFIG_PACKAGE_port-management=y
|
||||
CONFIG_PACKAGE_ppp-mod-pppoa=y
|
||||
@@ -85,11 +94,13 @@ CONFIG_PACKAGE_tc=y
|
||||
CONFIG_PACKAGE_tcpdump=y
|
||||
CONFIG_PACKAGE_terminfo=y
|
||||
CONFIG_PACKAGE_traceroute6=y
|
||||
CONFIG_PACKAGE_uledd=y
|
||||
CONFIG_PACKAGE_umbim=y
|
||||
CONFIG_PACKAGE_uqmi=y
|
||||
CONFIG_PACKAGE_usb-modeswitch=y
|
||||
CONFIG_PACKAGE_usbreset=y
|
||||
CONFIG_PACKAGE_uspd=y
|
||||
CONFIG_PACKAGE_vsftpd-tls=m
|
||||
CONFIG_PACKAGE_wget=y
|
||||
CONFIG_PACKAGE_wwan=y
|
||||
CONFIG_PACKAGE_wifimngr=y
|
||||
@@ -102,13 +113,14 @@ CONFIG_USE_STRIP=y
|
||||
CONFIG_BUILD_LOG=y
|
||||
CONFIG_BUSYBOX_CONFIG_ADDUSER=y
|
||||
CONFIG_BUSYBOX_CONFIG_ARPING=y
|
||||
CONFIG_BUSYBOX_CONFIG_ASH_IDLE_TIMEOUT=y
|
||||
CONFIG_BUSYBOX_CONFIG_ASH_RANDOM_SUPPORT=y
|
||||
CONFIG_BUSYBOX_CONFIG_CTTYHACK=y
|
||||
CONFIG_BUSYBOX_CONFIG_DELUSER=y
|
||||
# CONFIG_BUSYBOX_CONFIG_DEVMEM is not set
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_UDHCP_8021Q=y
|
||||
CONFIG_BUSYBOX_CONFIG_FIRST_SYSTEM_ID=100
|
||||
CONFIG_BUSYBOX_CONFIG_HTTPD=y
|
||||
# CONFIG_BUSYBOX_CONFIG_HTTPD is not set
|
||||
# CONFIG_BUSYBOX_CONFIG_INSMOD is not set
|
||||
# CONFIG_BUSYBOX_CONFIG_MODINFO is not set
|
||||
# CONFIG_BUSYBOX_CONFIG_MODPROBE is not set
|
||||
@@ -164,6 +176,22 @@ CONFIG_BUSYBOX_CONFIG_FLOAT_DURATION=y
|
||||
CONFIG_BUSYBOX_CONFIG_USLEEP=y
|
||||
CONFIG_BUSYBOX_CONFIG_REALPATH=y
|
||||
CONFIG_BUSYBOX_CONFIG_TTY=y
|
||||
CONFIG_BUSYBOX_CONFIG_BLOCKDEV=y
|
||||
CONFIG_BUSYBOX_CONFIG_PARTPROBE=y
|
||||
CONFIG_BUSYBOX_CONFIG_LFS=y
|
||||
CONFIG_BUSYBOX_CONFIG_FDISK=y
|
||||
CONFIG_BUSYBOX_CONFIG_FDISK_SUPPORT_LARGE_DISKS=y
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_FDISK_WRITABLE=y
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_GPT_LABEL=y
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_FDISK_ADVANCED=y
|
||||
CONFIG_BUSYBOX_CONFIG_IONICE=y
|
||||
CONFIG_BUSYBOX_CONFIG_RENICE=y
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_VOLUMEID_BTRFS=y
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_VOLUMEID_F2FS=y
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_VOLUMEID_SQUASHFS=y
|
||||
CONFIG_BUSYBOX_CONFIG_FEATURE_VOLUMEID_UBIFS=y
|
||||
CONFIG_BUSYBOX_CONFIG_TIMEOUT=y
|
||||
CONFIG_LIBCURL_CRYPTO_AUTH=y
|
||||
# CONFIG_LIBCURL_MBEDTLS is not set
|
||||
CONFIG_LIBCURL_OPENSSL=y
|
||||
@@ -172,7 +200,7 @@ CONFIG_OPENVPN_openssl_ENABLE_IPROUTE2=y
|
||||
CONFIG_KERNEL_DEVTMPFS=y
|
||||
CONFIG_KERNEL_DEVTMPFS_MOUNT=y
|
||||
# CONFIG_BUSYBOX_CONFIG_IP is not set
|
||||
CONFIG_LOCALMIRROR="http://download.iopsys.eu/iopsys/mirror/"
|
||||
CONFIG_LOCALMIRROR="https://download.iopsys.eu/iopsys/mirror/"
|
||||
|
||||
# Generation of /etc/banner.
|
||||
CONFIG_IMAGEOPT=y
|
||||
|
||||
@@ -35,7 +35,7 @@ _iop()
|
||||
iopcmds="bootstrap cfe_upgrade cfe_upgrade_latest extract_core \
|
||||
feeds_update genconfig generate_tarballs install_key \
|
||||
scp_changes setup_host ssh_install_key status \
|
||||
update_package update_feed_branches ssh_upgrade"
|
||||
update_package update_feed_branches ssh_upgrade smoketest"
|
||||
|
||||
if [ $COMP_CWORD -eq 1 ] ; then
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ function feeds_update {
|
||||
fi
|
||||
|
||||
# targets need to be installed explicitly
|
||||
targets="iopsys-brcm63xx-mips iopsys-brcm63xx-arm iopsys-ramips intel_mips iopsys-x86 iopsys-armvirt"
|
||||
targets="iopsys-brcm63xx-arm iopsys-ramips intel_mips iopsys-x86 iopsys-armvirt iopsys-bcm27xx"
|
||||
for target in $targets
|
||||
do
|
||||
rm -f target/linux/$target
|
||||
|
||||
@@ -5,7 +5,7 @@ function genconfig {
|
||||
export IMPORT=1
|
||||
export SRCTREEOVERR=0
|
||||
export FILEDIR="files/"
|
||||
export THEMEDIR="themes"
|
||||
export THEMEDIR="tmp/juci-themes"
|
||||
CURRENT_CONFIG_FILE=".current_config_file"
|
||||
export CONFIGPATH="package/feeds/iopsys/iop"
|
||||
CUSTPATH="customerconfigs"
|
||||
@@ -13,8 +13,8 @@ function genconfig {
|
||||
export VERBOSE=0
|
||||
export DEVELOPER=0
|
||||
target="bogus"
|
||||
config_path=""
|
||||
brcm63xx_mips="target/linux/iopsys-brcm63xx-mips"
|
||||
target_config_path=""
|
||||
bcm27xx="target/linux/iopsys-bcm27xx"
|
||||
brcm63xx_arm="target/linux/iopsys-brcm63xx-arm"
|
||||
ramips="target/linux/iopsys-ramips"
|
||||
intel_mips="target/linux/intel_mips"
|
||||
@@ -103,14 +103,12 @@ function genconfig {
|
||||
|
||||
if [ $pfound -eq 1 ]; then
|
||||
target="$(echo $TARGET | tr '-' '_')"
|
||||
config_path="$targetpath/config"
|
||||
target_config_path="$targetpath/config"
|
||||
fi
|
||||
|
||||
return
|
||||
fi
|
||||
|
||||
[ -e $brcm63xx_mips/genconfig ] &&
|
||||
iopsys_brcm63xx_mips=$(cd $brcm63xx_mips; ./genconfig)
|
||||
[ -e $brcm63xx_arm/genconfig ] &&
|
||||
iopsys_brcm63xx_arm=$(cd $brcm63xx_arm; ./genconfig)
|
||||
[ -e $ramips/genconfig ] &&
|
||||
@@ -121,9 +119,11 @@ function genconfig {
|
||||
iopsys_x86=$(cd $x86; ./genconfig)
|
||||
[ -e $armvirt/genconfig ] &&
|
||||
iopsys_armvirt=$(cd $armvirt; ./genconfig)
|
||||
[ -e $bcm27xx/genconfig ] &&
|
||||
iopsys_bcm27xx=$(cd $bcm27xx; ./genconfig)
|
||||
|
||||
if [ "$profile" == "LIST" ]; then
|
||||
for list in iopsys_brcm63xx_mips iopsys_brcm63xx_arm iopsys_ramips iopsys_intel_mips iopsys_x86 iopsys_armvirt; do
|
||||
for list in iopsys_brcm63xx_arm iopsys_ramips iopsys_intel_mips iopsys_x86 iopsys_armvirt iopsys_bcm27xx; do
|
||||
echo "$list based boards:"
|
||||
for b in ${!list}; do
|
||||
echo -e "\t$b"
|
||||
@@ -132,18 +132,10 @@ function genconfig {
|
||||
return
|
||||
fi
|
||||
|
||||
for p in $iopsys_brcm63xx_mips; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_brcm63xx_mips"
|
||||
config_path="$brcm63xx_mips/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
for p in $iopsys_brcm63xx_arm; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_brcm63xx_arm"
|
||||
config_path="$brcm63xx_arm/config"
|
||||
target_config_path="$brcm63xx_arm/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
@@ -151,7 +143,7 @@ function genconfig {
|
||||
for p in $iopsys_ramips; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_ramips"
|
||||
config_path="$ramips/config"
|
||||
target_config_path="$ramips/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
@@ -159,7 +151,7 @@ function genconfig {
|
||||
for p in $iopsys_intel_mips; do
|
||||
if [ $p == $profile ]; then
|
||||
target="intel_mips"
|
||||
config_path="$intel_mips/config"
|
||||
target_config_path="$intel_mips/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
@@ -167,7 +159,7 @@ function genconfig {
|
||||
for p in $iopsys_x86; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_x86"
|
||||
config_path="$x86/config"
|
||||
target_config_path="$x86/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
@@ -175,23 +167,31 @@ function genconfig {
|
||||
for p in $iopsys_armvirt; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_armvirt"
|
||||
config_path="$armvirt/config"
|
||||
target_config_path="$armvirt/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
for p in $iopsys_bcm27xx; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_bcm27xx"
|
||||
target_config_path="$bcm27xx/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
git remote -v | grep -q http || {
|
||||
git remote -v | grep -qE '(git@|ssh://)' && {
|
||||
DEVELOPER=1
|
||||
|
||||
bcmAllowed=0
|
||||
endptAllowed=0
|
||||
natalieAllowed=0
|
||||
mediatekAllowed=0
|
||||
#mediatekAllowed=0
|
||||
|
||||
git ls-remote git@dev.iopsys.eu:broadcom/bcmcreator.git -q 2>/dev/null && bcmAllowed=1
|
||||
git ls-remote git@dev.iopsys.eu:mediatek/linux.git -q 2>/dev/null && mediatekAllowed=1
|
||||
#git ls-remote git@dev.iopsys.eu:mediatek/linux.git -q 2>/dev/null && mediatekAllowed=1
|
||||
git ls-remote git@dev.iopsys.eu:dialog/natalie-dect-12.26.git -q 2>/dev/null && natalieAllowed=1
|
||||
git ls-remote git@dev.iopsys.eu:iopsys/endptmngr.git -q 2>/dev/null && endptAllowed=1
|
||||
}
|
||||
@@ -339,11 +339,13 @@ function genconfig {
|
||||
v "cp $CONFIGPATH/config .config"
|
||||
cp $CONFIGPATH/config .config
|
||||
|
||||
if [ -f $config_path/config ]; then
|
||||
cat $config_path/config >> .config
|
||||
if [ -f $target_config_path/config ]; then
|
||||
cat $target_config_path/config >> .config
|
||||
echo "" >> .config
|
||||
fi
|
||||
if [ -f $config_path/$BOARDTYPE/config ]; then
|
||||
cat $config_path/$BOARDTYPE/config >> .config
|
||||
if [ -f $target_config_path/$BOARDTYPE/config ]; then
|
||||
cat $target_config_path/$BOARDTYPE/config >> .config
|
||||
echo "" >> .config
|
||||
fi
|
||||
|
||||
#special handling for intel_mips/iopsys_ramips which use TARGET_DEVICES
|
||||
@@ -360,6 +362,13 @@ function genconfig {
|
||||
echo "CONFIG_TARGET_${target}=y" >> .config
|
||||
echo "CONFIG_TARGET_${target}_${subtarget}=y" >> .config
|
||||
echo "CONFIG_TARGET_${target}_${subtarget}_DEVICE_${BOARDTYPE}=y" >> .config
|
||||
elif [ "$target" = "iopsys_bcm27xx" ]; then
|
||||
subtarget="iopsys_bcm2711"
|
||||
echo "CONFIG_TARGET_${target}=y" >> .config
|
||||
echo "CONFIG_TARGET_${target}_${subtarget}=y" >> .config
|
||||
echo "CONFIG_TARGET_MULTI_PROFILE=y" >> .config
|
||||
echo "CONFIG_TARGET_PER_DEVICE_ROOTFS=y" >> .config
|
||||
echo "CONFIG_TARGET_DEVICE_${target}_${subtarget}_DEVICE_${BOARDTYPE}=y" >> .config
|
||||
else
|
||||
echo "CONFIG_TARGET_${target}=y" >> .config
|
||||
echo "CONFIG_TARGET_${target}_${BOARDTYPE}=y" >> .config
|
||||
@@ -386,10 +395,12 @@ function genconfig {
|
||||
if [ -e "$CUSTCONF/$CUSTOMER/common/common.diff" ]; then
|
||||
v "Apply $CUSTCONF/$CUSTOMER/common/common.diff"
|
||||
cat $CUSTCONF/$CUSTOMER/common/common.diff >> .config
|
||||
echo "" >> .config
|
||||
fi
|
||||
if [ -e "$CUSTCONF/$CUSTOMER/$BOARDTYPE/$BOARDTYPE.diff" ]; then
|
||||
v "Apply $CUSTCONF/$CUSTOMER/$BOARDTYPE/$BOARDTYPE.diff"
|
||||
cat $CUSTCONF/$CUSTOMER/$BOARDTYPE/$BOARDTYPE.diff >> .config
|
||||
echo "" >> .config
|
||||
fi
|
||||
done
|
||||
fi
|
||||
@@ -411,13 +422,13 @@ function genconfig {
|
||||
[ $bcmAllowed -eq 0 ] && echo "CONFIG_BCM_OPEN=y" >> .config
|
||||
[ $endptAllowed -eq 0 ] && echo "CONFIG_ENDPT_OPEN=y" >> .config
|
||||
[ $natalieAllowed -eq 0 ] && echo "CONFIG_NATALIE_OPEN=y" >> .config
|
||||
[ $mediatekAllowed -eq 0 ] && echo "CONFIG_MEDIATEK_OPEN=y" >> .config
|
||||
#[ $mediatekAllowed -eq 0 ] && echo "CONFIG_MEDIATEK_OPEN=y" >> .config
|
||||
else
|
||||
echo "# CONFIG_GITMIRROR_REWRITE is not set" >>.config
|
||||
echo "CONFIG_BCM_OPEN=y" >> .config
|
||||
echo "CONFIG_ENDPT_OPEN=y" >> .config
|
||||
echo "CONFIG_NATALIE_OPEN=y" >> .config
|
||||
echo "CONFIG_MEDIATEK_OPEN=y" >> .config
|
||||
#echo "CONFIG_MEDIATEK_OPEN=y" >> .config
|
||||
fi
|
||||
|
||||
if [ -n "$BRCM_MAX_JOBS" ]
|
||||
@@ -433,7 +444,7 @@ function genconfig {
|
||||
touch package/kernel/linux/Makefile
|
||||
|
||||
# we need to signal to bradcom SDK that we have changed the board id
|
||||
# currently boardparms.c and boardparms_voice.c is the only place that is depending on inteno boardid name
|
||||
# currently boardparms.c and boardparms_voice.c is the only place that is depending on boardid name
|
||||
# so just touch that file.
|
||||
[ -d ./build_dir ] && find build_dir/ -name "boardparms*c" -print0 2>/dev/null | xargs -0 touch 2>/dev/null
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ function genconfig_min {
|
||||
export DEVELOPER=0
|
||||
target="bogus"
|
||||
config_path=""
|
||||
brcm63xx_mips="target/linux/iopsys-brcm63xx-mips"
|
||||
bcm27xx="target/linux/iopsys-bcm27xx"
|
||||
brcm63xx_arm="target/linux/iopsys-brcm63xx-arm"
|
||||
ramips="target/linux/iopsys-ramips"
|
||||
intel_mips="target/linux/intel_mips"
|
||||
@@ -108,8 +108,6 @@ function genconfig_min {
|
||||
return
|
||||
fi
|
||||
|
||||
[ -e $brcm63xx_mips/genconfig ] &&
|
||||
iopsys_brcm63xx_mips=$(cd $brcm63xx_mips; ./genconfig)
|
||||
[ -e $brcm63xx_arm/genconfig ] &&
|
||||
iopsys_brcm63xx_arm=$(cd $brcm63xx_arm; ./genconfig)
|
||||
[ -e $ramips/genconfig ] &&
|
||||
@@ -120,9 +118,11 @@ function genconfig_min {
|
||||
iopsys_x86=$(cd $x86; ./genconfig)
|
||||
[ -e $armvirt/genconfig ] &&
|
||||
iopsys_armvirt=$(cd $armvirt; ./genconfig)
|
||||
[ -e $bcm27xx/genconfig ] &&
|
||||
iopsys_bcm27xx=$(cd $bcm27xx; ./genconfig)
|
||||
|
||||
if [ "$profile" == "LIST" ]; then
|
||||
for list in iopsys_brcm63xx_mips iopsys_brcm63xx_arm iopsys_ramips iopsys_intel_mips iopsys_x86 iopsys_armvirt; do
|
||||
for list in iopsys_brcm63xx_arm iopsys_ramips iopsys_intel_mips iopsys_x86 iopsys_armvirt iopsys_bcm27xx; do
|
||||
echo "$list based boards:"
|
||||
for b in ${!list}; do
|
||||
echo -e "\t$b"
|
||||
@@ -131,14 +131,6 @@ function genconfig_min {
|
||||
return
|
||||
fi
|
||||
|
||||
for p in $iopsys_brcm63xx_mips; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_brcm63xx_mips"
|
||||
config_path="$brcm63xx_mips/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
for p in $iopsys_brcm63xx_arm; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_brcm63xx_arm"
|
||||
@@ -179,6 +171,14 @@ function genconfig_min {
|
||||
fi
|
||||
done
|
||||
|
||||
for p in $iopsys_bcm27xx; do
|
||||
if [ $p == $profile ]; then
|
||||
target="iopsys_bcm27xx"
|
||||
config_path="$bcm27xx/config"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
git remote -v | grep -q http || {
|
||||
@@ -337,6 +337,14 @@ function genconfig_min {
|
||||
echo "CONFIG_TARGET_${target}=y" >> .config
|
||||
echo "CONFIG_TARGET_${target}_${subtarget}=y" >> .config
|
||||
echo "CONFIG_TARGET_${target}_${subtarget}_DEVICE_${BOARDTYPE}=y" >> .config
|
||||
elif [ "$target" = "iopsys_bcm27xx" ]; then
|
||||
subtarget="iopsys_bcm2711"
|
||||
echo "CONFIG_TARGET_${target}=y" >> .config
|
||||
echo "CONFIG_TARGET_${target}_${subtarget}=y" >> .config
|
||||
echo "CONFIG_TARGET_MULTI_PROFILE=y" >> .config
|
||||
echo "CONFIG_TARGET_PER_DEVICE_ROOTFS=y" >> .config
|
||||
device=$(echo $BOARDTYPE | tr a-z A-Z)
|
||||
echo "CONFIG_TARGET_DEVICE_${target}_${subtarget}_DEVICE_${BOARDTYPE}=y" >> .config
|
||||
else
|
||||
echo "CONFIG_TARGET_${target}=y" >> .config
|
||||
echo "CONFIG_TARGET_${target}_${BOARDTYPE}=y" >> .config
|
||||
@@ -389,7 +397,7 @@ function genconfig_min {
|
||||
touch package/kernel/linux/Makefile
|
||||
|
||||
# we need to signal to bradcom SDK that we have changed the board id
|
||||
# currently boardparms.c and boardparms_voice.c is the only place that is depending on inteno boardid name
|
||||
# currently boardparms.c and boardparms_voice.c is the only place that is depending on boardid name
|
||||
# so just touch that file.
|
||||
[ -d ./build_dir ] && find build_dir/ -name "boardparms*c" -print0 2>/dev/null | xargs -0 touch 2>/dev/null
|
||||
|
||||
|
||||
@@ -1,21 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
# shellcheck disable=SC2029
|
||||
|
||||
build_bcmkernel_consumer() {
|
||||
local tarfile bcmkernelcommith sdkversion
|
||||
sdkversion=$(grep "CONFIG_BRCM_SDK_VER.*=y" .config | awk -F'[_,=]' '{print$5}')
|
||||
sdkversion=${sdkversion:0:4}${sdkversion:(-1)}
|
||||
bcmkernelcommith=$(grep -w "PKG_SOURCE_VERSION:" $curdir/feeds/broadcom/bcmkernel/${sdkversion:0:5}*.mk | cut -d'=' -f2)
|
||||
local tarfile bcmkernelcommith sdkversion serverpath serverlink
|
||||
|
||||
sdkversion="$(grep "CONFIG_BRCM_SDK_VER.*=y" .config | awk -F'[_,=]' '{print$5}')"
|
||||
sdkversion="${sdkversion:0:4}${sdkversion:(-1)}"
|
||||
bcmkernelcommith="$(grep -w "PKG_SOURCE_VERSION:" "$curdir/feeds/broadcom/bcmkernel/${sdkversion:0:5}"*".mk" | cut -d'=' -f2)"
|
||||
|
||||
[ -n "$board" ] && [ -n "$bcmkernelcommith" ] || return
|
||||
|
||||
serverpath="$FPATH/bcmopen-$board-$bcmkernelcommith.tar.gz"
|
||||
serverlink="$FPATH/bcmopen-$board-$majver.$minver-latest"
|
||||
|
||||
# do not build bcmopen sdk if it was already built before
|
||||
[ -n "$board" -a -n "$bcmkernelcommith" ] || return
|
||||
ssh $SERVER "test -f $FPATH/bcmopen-$board-$bcmkernelcommith.tar.gz" && return
|
||||
cd ./build_dir/target-*/bcmkernel-*-${sdkversion:0:4}*/bcm963xx/release
|
||||
bash do_consumer_release -p $profile -y -F
|
||||
# if it was, check if there's a symlink in place and create it if missing
|
||||
ssh "$SERVER" "test -f '$serverpath' && { test -L '$serverlink' || ln -sf '$serverpath' '$serverlink'; }" && return
|
||||
|
||||
cd "./build_dir/target-"*"/bcmkernel-"*"-${sdkversion:0:4}"*"/bcm963xx/release"
|
||||
bash do_consumer_release -p "$profile" -y -F
|
||||
|
||||
tarfile='out/bcm963xx_*_consumer.tar.gz'
|
||||
[ $(ls -1 $tarfile |wc -l) -ne 1 ] && echo "Too many tar files: '$tarfile'" && return
|
||||
scp -pv $tarfile $SERVER:$FPATH/bcmopen-$board-$bcmkernelcommith.tar.gz
|
||||
ssh $SERVER "[ -f $FPATH/bcmopen-$board-$bcmkernelcommith.tar.gz ] && ln -sf $FPATH/bcmopen-$board-$bcmkernelcommith.tar.gz $FPATH/bcmopen-$board-$majver.$minver-latest"
|
||||
[ $(ls -1 $tarfile | wc -l) -ne 1 ] && echo "Too many tar files: '$tarfile'" && return
|
||||
|
||||
scp -pv $tarfile "$SERVER":"$serverpath"
|
||||
ssh "$SERVER" "test -f '$serverpath' && ln -sf '$serverpath' '$serverlink'"
|
||||
rm -f $tarfile
|
||||
|
||||
cd "$curdir"
|
||||
}
|
||||
|
||||
@@ -25,7 +36,7 @@ build_natalie_consumer() {
|
||||
grep -q "CONFIG_TARGET_NO_DECT=y" .config && return
|
||||
natalieversion=$(grep -w "PKG_VERSION:" ./feeds/iopsys/natalie-dect/Makefile | cut -d'=' -f2)
|
||||
nataliecommith=$(grep -w "PKG_SOURCE_VERSION:" ./feeds/iopsys/natalie-dect/Makefile | cut -d'=' -f2)
|
||||
[ -n "$profile" -a -n "$natalieversion" -a -n "$nataliecommith" ] || return
|
||||
[ -n "$profile" ] && [ -n "$natalieversion" ] && [ -n "$nataliecommith" ] || return
|
||||
ssh $SERVER "test -f $FPATH/natalie-dect-$profile-$natalieversion-$nataliecommith.tar.gz" && return
|
||||
cd ./build_dir/target-*/natalie-dect-$natalieversion/
|
||||
mkdir natalie-dect-open-$natalieversion
|
||||
@@ -44,7 +55,7 @@ build_endptmngr_consumer() {
|
||||
grep -q "CONFIG_TARGET_NO_VOICE=y" .config && return
|
||||
endptversion=$(grep -w "PKG_VERSION:" ./feeds/iopsys/endptmngr/Makefile | cut -d'=' -f2)
|
||||
endptcommith=$(grep -w "PKG_SOURCE_VERSION:" ./feeds/iopsys/endptmngr/Makefile | cut -d'=' -f2)
|
||||
[ -n "$profile" -a -n "$endptversion" -a -n "$endptcommith" ] || return
|
||||
[ -n "$profile" ] && [ -n "$endptversion" ] && [ -n "$endptcommith" ] || return
|
||||
ssh $SERVER "test -f $FPATH/endptmngr-$profile-$endptversion-$endptcommith.tar.gz" && return
|
||||
cd ./build_dir/target-*/endptmngr-$endptversion/
|
||||
mkdir endptmngr-open-$endptversion
|
||||
@@ -85,7 +96,7 @@ build_mediatek_wifi_consumer() {
|
||||
|
||||
ver=$(grep -w "PKG_VERSION:" ./feeds/mediatek/mt${chip}/Makefile | cut -d'=' -f2)
|
||||
commit=$(grep -w "PKG_SOURCE_VERSION:" ./feeds/mediatek/mt${chip}/Makefile | cut -d'=' -f2)
|
||||
[ -n "$ver" -a -n "$commit" ] || return
|
||||
[ -n "$ver" ] && [ -n "$commit" ] || return
|
||||
ssh $SERVER "test -f $FPATH/mtk${chip}e-${ver}_${commit}.tar.xz" && return
|
||||
cd build_dir/target-mipsel_1004kc*/linux-iopsys-ramips*/mtk${chip}e-$ver/ipkg-*
|
||||
mkdir -p mtk${chip}e-$ver/src
|
||||
@@ -112,7 +123,6 @@ function generate_tarballs {
|
||||
set -e
|
||||
git remote -v | grep -q http && return # do not continue if this is an open SDK environment
|
||||
|
||||
target=$(grep CONFIG_TARGET_BOARD .config | cut -d'=' -f2 | tr -d '"')
|
||||
board=$(grep CONFIG_TARGET_FAMILY .config | cut -d'=' -f2 | tr -d '"')
|
||||
profile=$(grep CONFIG_BCM_KERNEL_PROFILE .config | cut -d'=' -f2 | tr -d '"')
|
||||
majver=$(grep CONFIG_TARGET_VERSION .config | cut -d'=' -f2 | tr -d '"' | cut -f1 -d .)
|
||||
@@ -137,7 +147,7 @@ function generate_tarballs {
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -n "$stk_target" ]; then
|
||||
if [ -z "$stk_target" ]; then
|
||||
print_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -230,7 +230,7 @@ function ssh_upgrade {
|
||||
upd_fw_base=""
|
||||
upd_fw=""
|
||||
upd_host="192.168.1.1"
|
||||
upd_sysupgrade=0
|
||||
upd_sysupgrade=1
|
||||
do_dialog=0
|
||||
|
||||
while getopts "f:hnxt:iscb" opt; do
|
||||
@@ -280,6 +280,14 @@ function ssh_upgrade {
|
||||
set_config_string CONFIG_TARGET_BOARD
|
||||
firmwares=$(cd bin/targets/$CONFIG_TARGET_BOARD/generic/; ls -t *[0-9].y[3])
|
||||
|
||||
# if target uses pkgtb
|
||||
if [ -z "$firmwares"]
|
||||
then
|
||||
# pkgtb files can not be streamed so copy over the file witch scp
|
||||
use_scp=1
|
||||
firmwares=$(cd bin/targets/$CONFIG_TARGET_BOARD/generic/; ls -t last.pkgtb)
|
||||
fi
|
||||
|
||||
for upd_fw_base in $firmwares
|
||||
do
|
||||
#echo "firmware $upd_fw"
|
||||
@@ -313,10 +321,20 @@ function ssh_upgrade {
|
||||
[ $upd_forceboot -eq 1 ] && extra_args="$extra_args -b"
|
||||
|
||||
file_size_kb=`du -k "$upd_fw" | cut -f1`
|
||||
cat $upd_fw | pv -s ${file_size_kb}k | ssh root@$upd_host "iopu $extra_args"
|
||||
if [ "$use_scp" == "1" ]
|
||||
then
|
||||
scp $upd_fw root@$upd_host:/tmp/ &&
|
||||
ssh -o ConnectTimeout=60 root@$upd_host "iopu $extra_arg -f /tmp/$upd_fw_base"
|
||||
else
|
||||
cat $upd_fw | pv -s ${file_size_kb}k | ssh root@$upd_host "iopu $extra_args"
|
||||
fi
|
||||
else
|
||||
extra_args=""
|
||||
[ $upd_noreboot -eq 1 ] && extra_args="$extra_args -d"
|
||||
[ $upd_keepconf -eq 0 ] && extra_args="$extra_args -n"
|
||||
|
||||
scp $upd_fw root@$upd_host:/tmp/ &&
|
||||
ssh -o ConnectTimeout=60 root@$upd_host "sysupgrade -v $3 /tmp/$upd_fw_base" &&
|
||||
ssh -o ConnectTimeout=60 root@$upd_host "sysupgrade -v $extra_args /tmp/$upd_fw_base" &&
|
||||
echo "sysupgrade done!"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
# this is a developer helper script to SCP changed files to remote host
|
||||
|
||||
ROOT=build_dir/target-mips_uClibc-0.9.33.2/root-iopsys-brcm63xx-mips/
|
||||
ROOT_OLD=tmp/root_old/
|
||||
ROOT_TMP=tmp/root_tmp/
|
||||
|
||||
function scp_changes_reset {
|
||||
{ cd `dirname $0`
|
||||
rm -rf "$ROOT_OLD"
|
||||
mkdir -p "$ROOT_OLD"
|
||||
cp -a "$ROOT"* "$ROOT_OLD"
|
||||
}
|
||||
}
|
||||
|
||||
function scp_changes {
|
||||
if [ -z "$1" ] ; then
|
||||
echo "usage: $0 scp_changes <host/-r(eset)/-p(retend)>"
|
||||
echo "Error: host required"
|
||||
exit 1
|
||||
fi
|
||||
{ cd `dirname $0`
|
||||
if [ ! -d $ROOT ]; then
|
||||
echo "$ROOT does not exist"
|
||||
echo "please build the project first"
|
||||
exit 1;
|
||||
fi
|
||||
if [ "$1" = "-r" ]; then
|
||||
echo "reset changes"
|
||||
scp_changes_reset
|
||||
exit 0
|
||||
fi
|
||||
if [ ! -d $ROOT_OLD ]; then
|
||||
echo "$ROOT_OLD does not exist"
|
||||
echo "you didn't store state of previous buildroot"
|
||||
#echo "please run ./scp_changes_reset.sh"
|
||||
echo "doing it now"
|
||||
scp_changes_reset
|
||||
exit 1;
|
||||
fi
|
||||
FILES=`diff -rq "$ROOT" "$ROOT_OLD" 2>&1 | sed -ne "s?^Files .* and $ROOT_OLD\\(.*\\) differ?\\1?p" -ne "s?^Only in $ROOT\\(.*\\): \\(.*\\)?\\1/\\2?p"`
|
||||
if [ "$1" = "-p" ]; then
|
||||
echo "files that would be copied:"
|
||||
echo $FILES
|
||||
exit 0
|
||||
fi
|
||||
for f in $FILES
|
||||
do
|
||||
mkdir -p "$ROOT_TMP`dirname $f`"
|
||||
cp -af "$ROOT$f" "$ROOT_TMP$f"
|
||||
done
|
||||
if [ -d "$ROOT_TMP" ]; then
|
||||
echo "scp changed files to $1"
|
||||
pushd "$ROOT_TMP" 2>&1 >/dev/null
|
||||
scp -r * root@$1:/
|
||||
RETVAL=$?
|
||||
popd 2>&1 >/dev/null
|
||||
rm -rf "$ROOT_TMP"
|
||||
if [ "$RETVAL" -eq 0 ]; then
|
||||
scp_changes_reset
|
||||
else
|
||||
echo "scp error"
|
||||
exit $RETVAL
|
||||
fi
|
||||
else
|
||||
echo "no change"
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
register_command "scp_changes" "<host/-r(eset)/-p(retend)> SCP only changed files to device"
|
||||
95
iop/scripts/taas.sh
Normal file
95
iop/scripts/taas.sh
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
# Shorthand command for doing a HIL runtime smoketest on the
|
||||
# latest built image. Does the image boot up correctly?
|
||||
# More info here:
|
||||
# https://dev.iopsys.eu/iopsys/iopsys-taas
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
function taas-init() {
|
||||
local f
|
||||
|
||||
# Path to TaaS binarys. Try some likely ones.
|
||||
if ! which taas-smoketest >/dev/null; then
|
||||
PATH="${PATH}:${PWD}/../iopsys-taas/bin"
|
||||
PATH="${PATH}:${PWD}/../taas/bin"
|
||||
PATH="${PATH}:${HOME}/iopsys-taas/bin"
|
||||
PATH="${PATH}:${HOME}/taas/bin"
|
||||
PATH="${PATH}:${HOME}/bin"
|
||||
PATH="${PATH}:/opt/iopsys-taas/bin"
|
||||
PATH="${PATH}:/opt/taas/bin"
|
||||
fi
|
||||
|
||||
if ! which taas-smoketest >/dev/null; then
|
||||
echo "Error; TaaS is missing! Install it with:"
|
||||
echo "git clone git@dev.iopsys.eu:iopsys/iopsys-taas.git ../iopsys-taas"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# NAND erase block size.
|
||||
nandBlkSz=$(grep CONFIG_TARGET_NAND_BLOCKSZ .config | \
|
||||
tr -s "=\"" " " | cut -d " " -f 2)
|
||||
nandBlkSz=$((nandBlkSz / 1024))
|
||||
|
||||
# Create a list of all images which might be of use.
|
||||
for f in ${PWD}/bin/targets/iopsys-*/generic/last.* \
|
||||
${PWD}/build_dir/target-arm*/bcmkernel/bcm963xx/targets/9*/bcm*_linux_raw_image_${nandBlkSz}.bin; do
|
||||
[[ -s "$f" ]] && images+=("$f")
|
||||
done
|
||||
|
||||
# Convert Iopsys target name to the TaaS product name format
|
||||
# according to what is available in the remote lab for HIL.
|
||||
# Also find a suitable image.
|
||||
product=$(grep CONFIG_TARGET_PROFILE .config | \
|
||||
tr -s "=\"" " " | cut -d " " -f 2) || exit
|
||||
case "$product" in
|
||||
smarthub3)
|
||||
export product="SmartHub3a"
|
||||
;;
|
||||
dg400prime|eg400|ex600)
|
||||
export product=$(echo -n "$product" | tr [[:lower:]] [[:upper:]])
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported target; skipping!"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ ${#images[@]} -eq 0 ]]; then
|
||||
echo "No image found"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
function taas-smoketest {
|
||||
declare -a images
|
||||
|
||||
taas-init || return
|
||||
echo "Testing a $product with ${images[@]}..."
|
||||
command taas-smoketest "${images[@]}" "$product" "$@"
|
||||
}
|
||||
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
function taas-bootstrap {
|
||||
declare -a images
|
||||
|
||||
if [[ -n "$1" ]]; then
|
||||
taas-init || return
|
||||
echo "Flashing $1..."
|
||||
command taas-bootstrap "${images[@]}" "$@"
|
||||
else
|
||||
echo "Usage: ./iop taas-bootstrap dutX"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
register_command "taas-bootstrap" "Write image to a remote lab device."
|
||||
register_command "taas-smoketest" "Write image to a remote lab device and test it."
|
||||
|
||||
@@ -163,6 +163,7 @@ function usage {
|
||||
echo " -x Force install even if firmware is not for this board"
|
||||
echo " -b Force install of bootloader regardless of version installed"
|
||||
echo " -r Jump into chroot env of other system"
|
||||
echo " -f Firmware file to use"
|
||||
echo " -C \"command\" Execute command in chroot env of other system"
|
||||
}
|
||||
|
||||
@@ -177,6 +178,64 @@ function newroot_exec {
|
||||
|
||||
}
|
||||
|
||||
function system_is_y_image {
|
||||
|
||||
# find out what rootfs volume is active.
|
||||
cur_vol=$(get_flashbank_current)
|
||||
upd_vol=$(get_flashbank_next)
|
||||
|
||||
# convert volume name "rootfs_$upd_vol" into ubi volume id
|
||||
upd_ubi_id=$(ubinfo -d 0 -N rootfs_$upd_vol | awk "/Volume ID:/ {print \$3}")
|
||||
log "installing Root Fileystem into UBI volume rootfs_$upd_vol"
|
||||
|
||||
# prepare to match dsl.
|
||||
function_call upd_conf_dsl
|
||||
|
||||
log "now starting writing data to flash with [ iopupgrade $cmdline -M "$cmdline_match" -u ubi0_$upd_ubi_id ]"
|
||||
run_cleanup=1 # When we start to actually write data there might be some
|
||||
# things that need cleanup if we get an error/crash
|
||||
if ! iopupgrade $cmdline -M "$cmdline_match" -u ubi0_$upd_ubi_id; then
|
||||
log "iopupgrade program Failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Firmware programmed to flash."
|
||||
|
||||
# Force upgrade of boot loader
|
||||
[ $upd_forceboot -eq 1 ] && chroot_cmdline="$chroot_cmdline -b"
|
||||
|
||||
if [ $upd_keepconfig -eq 1 ]; then
|
||||
log "Transfering configuration to new system."
|
||||
chroot_cmdline="$chroot_cmdline -c"
|
||||
fi
|
||||
|
||||
mount_newroot
|
||||
if ! chroot /tmp/newroot_overlay /sbin/iopu_chroot $chroot_cmdline; then
|
||||
log "Configuration migration failed!"
|
||||
exit 1
|
||||
fi
|
||||
umount_newroot
|
||||
|
||||
log "New firmware fully installed."
|
||||
run_cleanup=0
|
||||
|
||||
|
||||
# Now make sure that we actually boot the new system on the next reboot
|
||||
upd_finnish
|
||||
|
||||
}
|
||||
|
||||
function system_is_FIT_image {
|
||||
|
||||
# prepare to match dsl.
|
||||
#function_call upd_conf_dsl
|
||||
|
||||
#here we write data
|
||||
bcm_flasher $firmware_file
|
||||
bcm_bootstate 1
|
||||
log "Firmware programmed to flash."
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
# just one instance
|
||||
@@ -194,7 +253,7 @@ trap ctrl_c INT
|
||||
trap timeout SIGALRM
|
||||
trap sig_pipe SIGPIPE
|
||||
|
||||
while getopts "nrxbhcC:" opt; do
|
||||
while getopts "nrxbhcC:f:" opt; do
|
||||
case $opt in
|
||||
n)
|
||||
upd_noreboot=1
|
||||
@@ -216,6 +275,9 @@ while getopts "nrxbhcC:" opt; do
|
||||
newroot_exec "${OPTARG}"
|
||||
exit
|
||||
;;
|
||||
f)
|
||||
firmware_file="${OPTARG}"
|
||||
;;
|
||||
h)
|
||||
usage
|
||||
exit 1
|
||||
@@ -235,59 +297,18 @@ log "Firmware upgrade started"
|
||||
# Should board name be checked
|
||||
if [ $upd_forceimage -eq 0 ]
|
||||
then
|
||||
board=$(db get hw.board.iopVerBoard)
|
||||
board=$(db get hw.board.model_name)
|
||||
cmdline_match="board=$board"
|
||||
fi
|
||||
|
||||
# find out what rootfs volume is active.
|
||||
cur_vol=$(get_flashbank_current)
|
||||
upd_vol=$(get_flashbank_next)
|
||||
|
||||
# convert volume name "rootfs_$upd_vol" into ubi volume id
|
||||
upd_ubi_id=$(ubinfo -d 0 -N rootfs_$upd_vol | awk "/Volume ID:/ {print \$3}")
|
||||
log "installing Root Fileystem into UBI volume rootfs_$upd_vol"
|
||||
|
||||
# prepare to match dsl.
|
||||
function_call upd_conf_dsl
|
||||
|
||||
# prepare to update CFE if it exists
|
||||
function_call upd_conf_cfe
|
||||
|
||||
# prepare to update kernel if it is stored in MTD/JFFS2
|
||||
function_call upd_conf_kernel
|
||||
|
||||
log "now starting writing data to flash with [ iopupgrade $cmdline -M "$cmdline_match" -u ubi0_$upd_ubi_id ]"
|
||||
run_cleanup=1 # When we start to actually write data there might be some
|
||||
# things that need cleanup if we get an error/crash
|
||||
if ! iopupgrade $cmdline -M "$cmdline_match" -u ubi0_$upd_ubi_id; then
|
||||
log "iopupgrade program Failed"
|
||||
exit 1
|
||||
# BUG: should probably read a config file.
|
||||
if [ -f /proc/nvram/boardid ]
|
||||
then
|
||||
system_is_FIT_image
|
||||
else
|
||||
system_is_y_image
|
||||
fi
|
||||
|
||||
log "Firmware programmed to flash."
|
||||
|
||||
# Force upgrade of boot loader
|
||||
[ $upd_forceboot -eq 1 ] && chroot_cmdline="$chroot_cmdline -b"
|
||||
|
||||
if [ $upd_keepconfig -eq 1 ]; then
|
||||
log "Transfering configuration to new system."
|
||||
chroot_cmdline="$chroot_cmdline -c"
|
||||
fi
|
||||
|
||||
mount_newroot
|
||||
if ! chroot /tmp/newroot_overlay /sbin/iopu_chroot $chroot_cmdline; then
|
||||
log "Configuration migration failed!"
|
||||
exit 1
|
||||
fi
|
||||
umount_newroot
|
||||
|
||||
log "New firmware fully installed."
|
||||
run_cleanup=0
|
||||
|
||||
|
||||
# Now make sure that we actually boot the new system on the next reboot
|
||||
upd_finnish
|
||||
|
||||
# spawn the reboot to a subshell to allow the main program to quit before reset
|
||||
# to avoid any hanged network connection like ssh
|
||||
if [ $upd_noreboot -eq 0 ]
|
||||
|
||||
@@ -11,7 +11,7 @@ PKG_RELEASE:=1
|
||||
PKG_VERSION:=0.3
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/libpicoevent.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=f4ab03b22fca57cec6c959fb5c54bcdd64c32467
|
||||
PKG_SOURCE_VERSION:=f446f186102539cceedaa15a95a33547ac3c1fd7
|
||||
PKG_NAME:=libpicoevent
|
||||
|
||||
PKG_LICENSE:=LGPL-2.1-only
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=map-1905
|
||||
PKG_VERSION:=0.0.4
|
||||
PKG_VERSION:=0.0.15
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=5fed40b905a673e41eee05fc60e4a424a9826b56
|
||||
PKG_SOURCE_VERSION:=405e44f14d623db7a5f03e76945315774d2b6deb
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/map-1905.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
endif
|
||||
@@ -43,18 +43,6 @@ TARGET_CFLAGS += \
|
||||
-Wall \
|
||||
-Wextra
|
||||
|
||||
ifeq ($(CONFIG_IEEE1905_SEND_EMPTY_TLVS),y)
|
||||
TARGET_CFLAGS += -DSEND_EMPTY_TLVS
|
||||
endif
|
||||
ifeq ($(CONFIG_IEEE1905_FIX_BROKEN_TLVS),y)
|
||||
TARGET_CFLAGS += -DFIX_BROKEN_TLVS
|
||||
endif
|
||||
ifeq ($(CONFIG_IEEE1905_SPEED_UP_DISCOVERY),y)
|
||||
TARGET_CFLAGS += -DSPEED_UP_DISCOVERY
|
||||
endif
|
||||
ifeq ($(CONFIG_IEEE1905_DO_NOT_ACCEPT_UNAUTHENTICATED_COMMANDS),y)
|
||||
TARGET_CFLAGS += -DDO_NOT_ACCEPT_UNAUTHENTICATED_COMMANDS
|
||||
endif
|
||||
|
||||
ifeq ($(LOCAL_DEV),1)
|
||||
define Build/Prepare
|
||||
@@ -63,8 +51,10 @@ endef
|
||||
endif
|
||||
|
||||
define Package/map-1905/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/libwifimap2.so $(1)/usr/lib/
|
||||
$(INSTALL_DIR) $(1)/usr/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/ieee1905
|
||||
$(CP) $(PKG_BUILD_DIR)/libwifimap2.so $(1)/usr/lib/ieee1905/
|
||||
endef
|
||||
|
||||
define Package/libmaputils/install
|
||||
@@ -77,7 +67,6 @@ define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include/map1905
|
||||
$(CP) $(PKG_BUILD_DIR)/include/*.h $(1)/usr/include/map1905/
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/libwifimap2.so $(1)/usr/lib/
|
||||
$(CP) $(PKG_BUILD_DIR)/libmaputils.so $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=map-agent
|
||||
PKG_VERSION:=2.0.1
|
||||
PKG_VERSION:=3.1.3
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=362ddbaf2b9a5510c89b740fcc23d8425770da3d
|
||||
PKG_SOURCE_VERSION:=1f9e4c5beafa216ff16110f3715dc901a25eb897
|
||||
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
|
||||
|
||||
PKG_LICENSE:=PROPRIETARY IOPSYS
|
||||
@@ -23,7 +23,7 @@ define Package/map-agent
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=WiFi multi-AP Agent (EasyMesh R2)
|
||||
DEPENDS:=+libwifi +libuci +libubox +ubus
|
||||
DEPENDS:=+libwifi +libuci +libubox +ubus +libmaputils +libwsc
|
||||
endef
|
||||
|
||||
define Package/map-agent/description
|
||||
@@ -51,6 +51,7 @@ endef
|
||||
|
||||
define Package/map-agent/install
|
||||
$(INSTALL_DIR) $(1)/etc
|
||||
$(CP) ./files/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(CP) $(PKG_BUILD_DIR)/src/utils/*.so* $(1)/usr/lib/
|
||||
|
||||
62
map-agent/files/etc/config/mapagent
Normal file
62
map-agent/files/etc/config/mapagent
Normal file
@@ -0,0 +1,62 @@
|
||||
config wifiagent
|
||||
option enabled '1'
|
||||
option debug '6'
|
||||
option profile '2'
|
||||
|
||||
config fh-iface
|
||||
option ifname 'wl0'
|
||||
option steer 'rssi bssload'
|
||||
list exclude '00:11:22:33:44:55'
|
||||
list exclude_btm '00:aa:bb:cc:dd:ee'
|
||||
list assoc_ctrl '00:10:20:30:40:50'
|
||||
option btm_retry '3'
|
||||
option btm_retry_secs '180'
|
||||
option fallback_legacy '1'
|
||||
option steer_legacy_reassoc_secs '30'
|
||||
option steer_legacy_retry_secs '3600'
|
||||
option assoc_ctrl_secs '30'
|
||||
option band '2'
|
||||
|
||||
config fh-iface
|
||||
option ifname 'wl1'
|
||||
option steer 'rssi bssload'
|
||||
list exclude '00:11:22:33:44:55'
|
||||
list exclude_btm '00:aa:bb:cc:dd:ee'
|
||||
option band '5'
|
||||
|
||||
#config bk-iface
|
||||
# option ifname 'apclii0'
|
||||
# option enabled '1'
|
||||
# option onboarded '0'
|
||||
# option disallow_bsta '1 # bitmap, 1 for disallow p1, 2 to disallow p2, 3 to disallow both (probably never applicable)
|
||||
|
||||
config steer-param 'rssi'
|
||||
option priority '0'
|
||||
option rssi_threshold '-68'
|
||||
option hysteresis '5'
|
||||
option margin '3'
|
||||
option diffsnr '8'
|
||||
|
||||
config steer-param 'bssload'
|
||||
option priority '0'
|
||||
option bssload_threshold '80'
|
||||
|
||||
### custom rules follows ###
|
||||
config rule-custom
|
||||
option action steer
|
||||
option sta 'd8:32:e3:4d:35:d2'
|
||||
option bss '00:22:07:11:22:33'
|
||||
|
||||
config rule-custom
|
||||
option action restrict
|
||||
option sta 'd8:32:e3:4d:35:d2'
|
||||
option bss '00:22:07:11:22:33'
|
||||
|
||||
#config bk-iface
|
||||
# option ifname 'wlan1_1'
|
||||
#
|
||||
#config fh-iface
|
||||
# option ifname 'wlan0'
|
||||
#
|
||||
#config fh-iface
|
||||
# option ifname 'wlan1'
|
||||
25
map-agent/files/etc/init.d/mapagent
Executable file
25
map-agent/files/etc/init.d/mapagent
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=98
|
||||
STOP=20
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command "/usr/sbin/mapagent" "-d"
|
||||
procd_set_param respawn
|
||||
# procd_set_param stdout 1
|
||||
# procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "ieee1905"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
50
map-controller/Makefile
Normal file
50
map-controller/Makefile
Normal file
@@ -0,0 +1,50 @@
|
||||
#
|
||||
# Copyright (C) 2020 IOPSYS Software Solutions AB
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=map-controller
|
||||
PKG_VERSION:=2.0.3
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=ae4d7c0279cf2f40b8f3ae0afa3e0f004e27e1f5
|
||||
|
||||
PKG_LICENSE:=PROPRIETARY IOPSYS
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=git@dev.iopsys.eu:iopsys/map-controller.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/map-controller
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=WiFi Multi-AP Controller (EasyMesh R2)
|
||||
DEPENDS:=+libuci +libubox +ubus +libmaputils +libwsc
|
||||
endef
|
||||
|
||||
define Package/map-controller/description
|
||||
This package provides WiFi MultiAP Controller as per the EasyMesh-R2 specs.
|
||||
endef
|
||||
|
||||
define Package/map-controller/config
|
||||
#source "$(SOURCE)/Config.in"
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include \
|
||||
-I$(STAGING_DIR)/usr/include/libnl3 \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
MAKE_PATH:=src
|
||||
|
||||
define Package/map-controller/install
|
||||
$(INSTALL_DIR) $(1)/etc
|
||||
$(CP) ./files/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/mapcontroller $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,map-controller))
|
||||
111
map-controller/files/etc/config/mapcontroller
Normal file
111
map-controller/files/etc/config/mapcontroller
Normal file
@@ -0,0 +1,111 @@
|
||||
config wificntlr
|
||||
option enabled '1'
|
||||
option registrar '5 2' #bands on which wps registrar supported
|
||||
option debug '6'
|
||||
|
||||
config fh-credentials
|
||||
option band '5'
|
||||
option encryption 'psk2'
|
||||
option key '1234567890'
|
||||
option ssid 'map-net5'
|
||||
option vlan '101'
|
||||
|
||||
config fh-credentials
|
||||
option band '2'
|
||||
option encryption 'psk2'
|
||||
option key '1234567890'
|
||||
option ssid 'map-net2'
|
||||
option vlan '0' # 0 - 2 rsvd, 3 - 4094 => vlan id
|
||||
|
||||
config bk-credentials
|
||||
option band '5'
|
||||
option encryption 'psk2'
|
||||
option key '5555555555'
|
||||
option ssid 'map-bkhaul-5'
|
||||
option multi_ap '2'
|
||||
# option multi_ap_backhaul_sta '1' # possible future TODO
|
||||
# option multi_ap_backhaul_key 'multiap_key123' # possible future TODO
|
||||
# option multi_ap_backhaul_ssid 'MultiAP-0022077E9CD6' # possible future TODO
|
||||
option disallow_bsta '1' # bitmap, 1 for disallow p1, 2 to disallow p2, 3 to disallow both (probably never applicable)
|
||||
|
||||
config bk-credentials
|
||||
option band '2'
|
||||
option encryption 'psk2'
|
||||
option key '2222222222'
|
||||
option ssid 'map-bkhaul-2'
|
||||
option multi_ap '2'
|
||||
# option multi_ap_backhaul_sta '1' # possible future TODO
|
||||
# option multi_ap_backhaul_key 'multiap_key123' # possible future TODO
|
||||
# option multi_ap_backhaul_ssid 'MultiAP-0022077E9CD6' # possible future TODO
|
||||
option disallow_bsta '0' # 0 or 1 profile-1 bSTA
|
||||
|
||||
config agent-policy
|
||||
option agent_id '00:22:07:7E:9C:D6' # 1905al macaddress of agent
|
||||
list steer_exclude '00:11:22:33:44:55'
|
||||
list steer_exclude_btm '00:aa:bb:cc:dd:ee'
|
||||
option steer_policy '2' # 0, 1, 2 - see MultiAP spec
|
||||
option util_threshold '200' # channel-util as in BSS load
|
||||
option rcpi_threshold '30' # 0 - 220 valid range
|
||||
option report_scan '0' # 0 or 1 for independent sc include_sta_metric '0' # sta metric in AP metric resp
|
||||
option pvid '100' # primary vlan id
|
||||
option pcp_default '5' # default vlan pcp
|
||||
option disallow_bsta_p1 '0' # 0 or 1 profile20 valid range
|
||||
option report_scan '0' # 0 or 1 for independent scans
|
||||
option report_sta_assocfails '1' # 0 or 1 - stas assoc failure
|
||||
option report_metric_periodic '0' # 0, or 1 - 255 in secs
|
||||
option report_rcpi_threshold '30' # 0 - 220 valid range
|
||||
option report_scan '0' # 0 or 1 for independent scans
|
||||
option report_sta_assocfails '1' # 0 or 1 - stas assoc failure
|
||||
option report_metric_periodic '0' # 0, or 1 - 255 in secs
|
||||
option report_rcpi_threshold '0' # 0, or 1 - 220
|
||||
option report_util_threshold '0' # 0, or channel-util value
|
||||
option include_sta_stats '0' # sta stats in AP metric resp
|
||||
option include_sta_metric '0' # sta metric in AP metric resp
|
||||
option pvid '100' # primary vlan id
|
||||
option pcp_default '5' # default vlan pcp
|
||||
option disallow_bsta_p1 '0' # 0 or 1 profile-1 bSTA
|
||||
option disallow_bsta_p2 '0' # 0 or 1 profile-2 bSTA
|
||||
|
||||
config agent-policy
|
||||
option agent_id '00:00:00:00:00:00'
|
||||
list steer_exclude '00:11:22:33:44:55'
|
||||
list steer_exclude_btm '00:aa:bb:cc:dd:ee'
|
||||
option steer_policy '2' # 0, 1, 2 - see MultiAP spec
|
||||
option util_threshold '200' # channel-util as in BSS load
|
||||
option rcpi_threshold '30' # 0 - 220 valid range
|
||||
option report_scan '0' # 0 or 1 for independent sc include_sta_metric '0' # sta metric in AP metric resp
|
||||
option pvid '100' # primary vlan id
|
||||
option pcp_default '5' # default vlan pcp
|
||||
option disallow_bsta_p1 '0' # 0 or 1 profile20 valid range
|
||||
option report_scan '0' # 0 or 1 for independent scans
|
||||
option report_sta_assocfails '1' # 0 or 1 - stas assoc failure
|
||||
option report_metric_periodic '0' # 0, or 1 - 255 in secs
|
||||
option report_rcpi_threshold '30' # 0 - 220 valid range
|
||||
option report_scan '0' # 0 or 1 for independent scans
|
||||
option report_sta_assocfails '1' # 0 or 1 - stas assoc failure
|
||||
option report_metric_periodic '0' # 0, or 1 - 255 in secs
|
||||
option report_rcpi_threshold '0' # 0, or 1 - 220
|
||||
option report_util_threshold '0' # 0, or channel-util value
|
||||
option include_sta_stats '0' # sta stats in AP metric resp
|
||||
option include_sta_metric '0' # sta metric in AP metric resp
|
||||
option pvid '100' # primary vlan id
|
||||
option pcp_default '5' # default vlan pcp
|
||||
option disallow_bsta_p1 '0' # 0 or 1 profile-1 bSTA
|
||||
option disallow_bsta_p2 '0' # 0 or 1 profile-2 bSTA
|
||||
|
||||
config agent-policy
|
||||
option agent_id '00:22:07:A3:6C:DA' # 1905al macaddress of agent
|
||||
list steer_exclude '00:11:22:33:44:55'
|
||||
list steer_exclude_btm '00:aa:bb:cc:dd:ee'
|
||||
option steer_policy '2' # 0, 1, 2 - see MultiAP spec
|
||||
option util_threshold '200' # channel-util as in BSS load
|
||||
option report_metric_periodic '0' # 0, or 1 - 255 in secs
|
||||
option report_rcpi_threshold '0' # 0, or 1 - 220
|
||||
option report_util_threshold '0' # 0, or channel-util value
|
||||
option include_sta_stats '0' # sta stats in 3:4d:35:d2'
|
||||
option bss '00:22:07:11:22:33'
|
||||
|
||||
config rule-custom
|
||||
option action restrict
|
||||
option sta 'd8:32:e3:4d:35:d2'
|
||||
option bss '00:22:07:11:22:33'
|
||||
25
map-controller/files/etc/init.d/mapcontroller
Executable file
25
map-controller/files/etc/init.d/mapcontroller
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=98
|
||||
STOP=20
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command "/usr/sbin/mapcontroller" "-d"
|
||||
procd_set_param respawn
|
||||
# procd_set_param stdout 1
|
||||
# procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "ieee1905"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
52
map-topology/Makefile
Normal file
52
map-topology/Makefile
Normal file
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# Copyright (C) 2020 iopsys
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=map-topology
|
||||
PKG_VERSION:=1.5.6
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_VERSION:=8d008ef712227986263e9a2a1b188ce3a27e17f8
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/map-topology.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
|
||||
endif
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_LICENSE:=PROPRIETARY IOPSYS
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/map-topology
|
||||
CATEGORY:=Utilities
|
||||
DEPENDS:=+libubox +ubus +libpthread +libuci +libeasy \
|
||||
+libieee1905 +libavahi-nodbus-support
|
||||
TITLE:=Utility to build topology of a multi-AP network
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include
|
||||
|
||||
define Package/map-topology/description
|
||||
Constructs network topology and show it as json structure over UBUS
|
||||
endef
|
||||
|
||||
MAKE_PATH:=src
|
||||
|
||||
ifeq ($(LOCAL_DEV),1)
|
||||
define Build/Prepare
|
||||
$(CP) -rf ~/git/map-topology/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
endif
|
||||
|
||||
define Package/map-topology/install
|
||||
$(CP) ./files/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/topologyd $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,map-topology))
|
||||
6
map-topology/files/etc/config/topology
Normal file
6
map-topology/files/etc/config/topology
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
config topology 'topology'
|
||||
option enabled '1'
|
||||
option depth '8'
|
||||
option interval '60'
|
||||
option maxlog '32'
|
||||
25
map-topology/files/etc/init.d/topologyd
Executable file
25
map-topology/files/etc/init.d/topologyd
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=97
|
||||
STOP=21
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command "/usr/sbin/topologyd"
|
||||
procd_set_param respawn
|
||||
# procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "ieee1905"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
@@ -11,6 +11,10 @@ PROG_EXE=/usr/sbin/mcpd
|
||||
# Parameters available in snooping configuration
|
||||
igmp_s_enable=0
|
||||
igmp_s_version=2
|
||||
igmp_s_query_interval=125
|
||||
igmp_s_q_resp_interval=100
|
||||
igmp_s_last_mem_q_int=10
|
||||
igmp_s_fast_leave=1
|
||||
igmp_s_robustness=2
|
||||
igmp_s_mode=0
|
||||
igmp_s_iface=""
|
||||
@@ -77,6 +81,10 @@ read_snooping() {
|
||||
if [ "$proto" == "igmp" ]; then
|
||||
igmp_s_enable=$sec_enable
|
||||
config_get igmp_s_version "$config" version 2
|
||||
config_get igmp_s_query_interval "$config" query_interval 125
|
||||
config_get igmp_s_q_resp_interval "$config" query_response_interval 100
|
||||
config_get igmp_s_last_mem_q_int "$config" last_member_query_interval 10
|
||||
config_get igmp_s_fast_leave "$config" fast_leave 1
|
||||
config_get igmp_s_robustness "$config" robustness 2
|
||||
config_get igmp_s_mode "$config" snooping_mode 0
|
||||
config_get igmp_s_iface "$config" interface
|
||||
@@ -88,6 +96,10 @@ read_snooping() {
|
||||
if [ "$proto" == "mld" ]; then
|
||||
mld_s_enable=$sec_enable
|
||||
config_get mld_s_version "$config" version 2
|
||||
config_get mld_s_query_interval "$config" query_interval 125
|
||||
config_get mld_s_q_resp_interval "$config" query_response_interval 100
|
||||
config_get mld_s_last_mem_q_int "$config" last_member_query_interval 10
|
||||
config_get mld_s_fast_leave "$config" fast_leave 1
|
||||
config_get mld_s_robustness "$config" robustness 2
|
||||
config_get mld_s_mode "$config" snooping_mode 0
|
||||
config_get mld_s_iface "$config" interface
|
||||
@@ -248,23 +260,28 @@ configure_mcpd_snooping() {
|
||||
local protocol="$1"
|
||||
local exceptions
|
||||
local filter_ip=""
|
||||
local fast_leave=0
|
||||
|
||||
# Configure snooping related params
|
||||
if [ "$protocol" == "igmp" ]; then
|
||||
config_snooping_common_params $protocol $igmp_p_version $igmp_p_robustness $igmp_s_mode
|
||||
config_mcast_querier_params $protocol $igmp_query_interval $igmp_q_resp_interval $igmp_last_mem_q_int
|
||||
config_snooping_common_params $protocol $igmp_s_version $igmp_s_robustness $igmp_s_mode
|
||||
config_mcast_querier_params $protocol $igmp_s_query_interval $igmp_s_q_resp_interval $igmp_s_last_mem_q_int
|
||||
config_mcast_proxy_interface $protocol "$igmp_s_iface"
|
||||
config_snooping_on_bridge $protocol $igmp_s_iface $igmp_s_mode
|
||||
exceptions=$igmp_s_exceptions
|
||||
fast_leave=$igmp_s_fast_leave
|
||||
elif [ "$protocol" == "mld" ]; then
|
||||
config_snooping_common_params $protocol $mld_p_version $mld_p_robustness $mld_s_mode
|
||||
config_mcast_querier_params $protocol $mld_query_interval $mld_q_resp_interval $mld_last_mem_q_int
|
||||
config_snooping_common_params $protocol $mld_s_version $mld_s_robustness $mld_s_mode
|
||||
config_mcast_querier_params $protocol $mld_s_query_interval $mld_s_q_resp_interval $mld_s_last_mem_q_int
|
||||
config_mcast_proxy_interface $protocol "$mld_s_iface"
|
||||
config_snooping_on_bridge $protocol $mld_s_iface $mld_s_mode
|
||||
exceptions=$mld_s_exceptions
|
||||
fast_leave=$mld_s_fast_leave
|
||||
fi
|
||||
|
||||
echo "${protocol}-proxy-enable 0" >> $CONFFILE
|
||||
echo "${protocol}-fast-leave $fast_leave" >> $CONFFILE
|
||||
|
||||
if [ -n "$exceptions" ]; then
|
||||
IFS=" "
|
||||
for excp in $exceptions; do
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2013 Inteno
|
||||
# Copyright (C) 2020 IOPSYS
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
@@ -11,7 +11,7 @@ PKG_SOURCE_VERSION:=378c404fba3efc8f1bcde54370a5370670fa1853
|
||||
ifeq ($(CONFIG_NATALIE_OPEN),y)
|
||||
BRCM_KERNEL_PROFILE=$(shell echo $(CONFIG_BCM_KERNEL_PROFILE) | sed s/\"//g)
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(BRCM_KERNEL_PROFILE)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://download.iopsys.eu/iopsys/opensdk/
|
||||
PKG_SOURCE_URL:=https://download.iopsys.eu/iopsys/opensdk/
|
||||
PKG_NAME:=natalie-dect-open
|
||||
else
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=obuspa
|
||||
PKG_VERSION:=2.0.20
|
||||
PKG_VERSION:=3.0.0.9
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=44fa7f29682e89ca3992a9c88c5bdefa1cacdc52
|
||||
PKG_SOURCE_VERSION:=09c1959e36f7084486a4d39548cef422a1ece483
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/fork/obuspa.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
endif
|
||||
@@ -22,14 +22,13 @@ PKG_FIXUP:=autoreconf
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/obuspa
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=USP agent
|
||||
DEPENDS:=+libcoap +libopenssl +libcurl +libsqlite3 +libcares +libubox +libubus +libblobmsg-json +uspd
|
||||
DEPENDS:=+libopenssl +libcurl +libsqlite3 +libubox +libubus +uspd +libmosquitto
|
||||
endef
|
||||
|
||||
define Package/obuspa/description
|
||||
@@ -38,18 +37,7 @@ endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include \
|
||||
-D_GNU_SOURCE \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-fstrict-aliasing \
|
||||
-Werror=format-overflow \
|
||||
-Wno-error=unused-parameter \
|
||||
-Wno-error=sign-compare
|
||||
|
||||
|
||||
ifneq ($(CONFIG_USE_MUSL),)
|
||||
TARGET_CFLAGS += -DUSE_MUSL
|
||||
endif
|
||||
-D_GNU_SOURCE
|
||||
|
||||
ifeq ($(LOCAL_DEV),1)
|
||||
define Build/Prepare
|
||||
|
||||
@@ -1,44 +1,43 @@
|
||||
# controller, mtp, connection makes a group and related to one another
|
||||
# ex: first controller will be mapped to first mtp and first connection
|
||||
# details, always defined in groups
|
||||
|
||||
config obuspa
|
||||
option enable 'true'
|
||||
option cert '/etc/obuspa/rootCA.pem'
|
||||
config obuspa 'global'
|
||||
option enabled 'true'
|
||||
option interface 'wan'
|
||||
#option ifname 'eth0.1'
|
||||
option debug 'false'
|
||||
option log_level '1'
|
||||
#option db_file '/tmp/usp.db'
|
||||
#option trust_cert '/etc/obuspa/rootCA.pem'
|
||||
#option client_cert '/etc/obuspa/client.pem'
|
||||
#option log_dest '/var/log/obuspa'
|
||||
|
||||
config controller
|
||||
option endpointid 'self::usp-controller.com'
|
||||
option enable 'true'
|
||||
# Trust cerificate number
|
||||
option AssignedRole 1
|
||||
option PeriodicNotifInterval "86400"
|
||||
option PeriodicNotifTime "0001-01-01T00:00:00Z"
|
||||
option USPRetryMinimumWaitInterval "5"
|
||||
option USPRetryIntervalMultiplier "2000"
|
||||
option ControllerCode ""
|
||||
option protocol 'STOMP'
|
||||
config localagent 'localagent'
|
||||
option Enable 'true'
|
||||
|
||||
# Adds Device.LocalAgent.Controller.
|
||||
config controller 'localcontroller'
|
||||
option EndpointID 'proto::interop-usp-controller'
|
||||
option Protocol 'MQTT'
|
||||
option Topic '/usp/controller'
|
||||
option mqtt 'localmqtt'
|
||||
|
||||
# Adds Device.LocalAgent.MTP.
|
||||
config mtp
|
||||
option enable 'true'
|
||||
option protocol 'STOMP'
|
||||
option destination ''
|
||||
option Protocol 'MQTT'
|
||||
option ResponseTopicConfigured '/usp/endpoint'
|
||||
option mqtt 'localmqtt'
|
||||
|
||||
config connection
|
||||
option host 'usp-controller.com'
|
||||
option username 'username'
|
||||
option password 'password'
|
||||
option encryption 'true'
|
||||
option enable 'true'
|
||||
option port 61613
|
||||
option virtualhost '/'
|
||||
option EnableHeartbeats "true"
|
||||
option OutgoingHeartbeat "30000"
|
||||
option IncomingHeartbeat "300000"
|
||||
option ServerRetryInitialInterval "60"
|
||||
option ServerRetryIntervalMultiplier "2000"
|
||||
option ServerRetryMaxInterval "30720"
|
||||
# Adds Device.MQTT.Client.
|
||||
config mqtt 'localmqtt'
|
||||
option BrokerAddress '127.0.0.1'
|
||||
option BrokerPort '1883'
|
||||
option TransportProtocol 'TCP/IP'
|
||||
option Username 'admin'
|
||||
option Password 'admin'
|
||||
|
||||
# Add Device.LocalAgent.Subscription.
|
||||
config subscription
|
||||
option ID 'default-boot-event-ACS'
|
||||
option NotifType 'Event'
|
||||
option ReferenceList 'Device.Boot!'
|
||||
option Persistent 'true'
|
||||
option controller 'localcontroller'
|
||||
|
||||
|
||||
31
obuspa/files/etc/hotplug.d/iface/85-obuspa
Normal file
31
obuspa/files/etc/hotplug.d/iface/85-obuspa
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions/network.sh
|
||||
|
||||
[ "$ACTION" == "ifup" ] || exit 0
|
||||
|
||||
[ -f /etc/config/obuspa ] || exit 0
|
||||
|
||||
handle_obuspa_restart() {
|
||||
[ "$INTERFACE" == "loopback" ] && exit 0
|
||||
|
||||
local interface=$(uci -q get obuspa.global.interface)
|
||||
[ "$interface" == "$INTERFACE" ] || exit 0
|
||||
|
||||
mkdir -p /tmp/ipv4
|
||||
|
||||
network_flush_cache
|
||||
|
||||
local previpaddr=""
|
||||
local curipaddr=""
|
||||
local ipaddrfile=/tmp/ipv4/$INTERFACE-ipaddr
|
||||
previpaddr=$(cat $ipaddrfile 2>/dev/null)
|
||||
network_get_ipaddr curipaddr $INTERFACE
|
||||
[ -n "$curipaddr" ] && echo $curipaddr > $ipaddrfile || rm -f $ipaddrfile
|
||||
|
||||
[ "$previpaddr" == "$curipaddr" ] && exit 0
|
||||
|
||||
/etc/init.d/obuspa reload &
|
||||
}
|
||||
|
||||
handle_obuspa_restart
|
||||
@@ -2,14 +2,23 @@
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
PROG=/usr/sbin/obuspa
|
||||
l3device=""
|
||||
certificate=""
|
||||
|
||||
EXTRA_COMMANDS="remove_db"
|
||||
EXTRA_HELP=" remove_db Removes obuspa persistent db before restarting"
|
||||
|
||||
PARAM_FILE="/tmp/obuspa_param_reset.txt"
|
||||
conn_num=1
|
||||
mtp_num=1
|
||||
stomp_num=1
|
||||
CONFIGURATION=obuspa
|
||||
KEEP_FILES="/lib/upgrade/keep.d/obuspa"
|
||||
USP_TEMP_FILE="/tmp/usp.tmp"
|
||||
controller_num=0
|
||||
mtp_num=0
|
||||
stomp_num=0
|
||||
mqtt_num=0
|
||||
subs_num=0
|
||||
index=0
|
||||
|
||||
. /lib/functions/network.sh
|
||||
|
||||
log() {
|
||||
echo "${@}"|logger -t obuspa -p debug
|
||||
@@ -23,54 +32,113 @@ db_set() {
|
||||
fi
|
||||
}
|
||||
|
||||
get_index() {
|
||||
index=$(( index + 1 ))
|
||||
if [ "$1" = "$2" ]; then
|
||||
echo "${index}" > ${USP_TEMP_FILE}
|
||||
fi
|
||||
}
|
||||
|
||||
get_uci_ref_index() {
|
||||
local val;
|
||||
|
||||
[ -f ${USP_TEMP_FILE} ] && rm -f ${USP_TEMP_FILE}
|
||||
|
||||
index=0
|
||||
config_load $CONFIGURATION
|
||||
config_foreach get_index $1 $2
|
||||
val=$(cat ${USP_TEMP_FILE})
|
||||
|
||||
if [ -z $val ]; then
|
||||
val=0
|
||||
fi
|
||||
|
||||
rm -f ${USP_TEMP_FILE}
|
||||
|
||||
echo $val
|
||||
}
|
||||
|
||||
validate_obuspa_section()
|
||||
{
|
||||
uci_validate_section obuspa obuspa "${1}" \
|
||||
'enable:bool:true' \
|
||||
'cert:string:"/etc/obuspa/rootCA.pem"' \
|
||||
'interface:string:wan' \
|
||||
uci_validate_section ${CONFIGURATION} obuspa "${1}" \
|
||||
'enabled:bool:true' \
|
||||
'trust_cert:string' \
|
||||
'client_cert:string' \
|
||||
'interface:string' \
|
||||
'ifname:string:"br-lan"' \
|
||||
'debug:bool:false' \
|
||||
'log_level:uinteger:2' \
|
||||
'log_dest:string:stdout'
|
||||
'log_level:uinteger' \
|
||||
'log_dest:string' \
|
||||
'db_file:string'
|
||||
}
|
||||
|
||||
validate_localagent_section()
|
||||
{
|
||||
uci_validate_section ${CONFIGURATION} localagent "${1}" \
|
||||
'Enable:bool:true' \
|
||||
'ParameterName:string:Device.DeviceInfo.SoftwareVersion' \
|
||||
'EndpointID:string'
|
||||
}
|
||||
|
||||
validate_controller_section()
|
||||
{
|
||||
uci_validate_section obuspa controller "${1}" \
|
||||
'endpointid:string:"self:usp-controller.com"' \
|
||||
'enable:bool:true' \
|
||||
'AssignedRole:uinteger:1' \
|
||||
uci_validate_section ${CONFIGURATION} controller "${1}" \
|
||||
'EndpointID:string' \
|
||||
'Enable:bool:true' \
|
||||
'AssignedRole:string:Device.LocalAgent.ControllerTrust.Role.1' \
|
||||
'PeriodicNotifInterval:uinteger:86400' \
|
||||
'PeriodicNotifTime:string:"0001-01-01T00:00:00Z"' \
|
||||
'USPRetryMinimumWaitInterval:uinteger:5' \
|
||||
'USPRetryIntervalMultiplier:uinteger:2000' \
|
||||
'PeriodicNotifTime:string' \
|
||||
'USPNotifRetryMinimumWaitInterval:uinteger:5' \
|
||||
'USPNotifRetryIntervalMultiplier:uinteger:2000' \
|
||||
'ControllerCode:string' \
|
||||
'protocol:or("STOMP","CoAP")' \
|
||||
'CoAPHost:string' \
|
||||
'CoAPPath:string' \
|
||||
'CoAPPort:uinteger'
|
||||
'Protocol:or("STOMP","CoAP","MQTT")' \
|
||||
'Reference:string' \
|
||||
'Destination:string:controller-notify-dest' \
|
||||
'Topic:string' \
|
||||
'coap_host:string' \
|
||||
'coap_path:string' \
|
||||
'coap_port:uinteger' \
|
||||
'mqtt:string' \
|
||||
'stomp:string'
|
||||
}
|
||||
|
||||
validate_subscription_section()
|
||||
{
|
||||
uci_validate_section ${CONFIGURATION} subscription "${1}" \
|
||||
'Enable:bool:true' \
|
||||
'ID:string' \
|
||||
'NotifType:string' \
|
||||
'ReferenceList:string' \
|
||||
'Persistent:bool:true' \
|
||||
'Recipient:string' \
|
||||
'controller:string'
|
||||
}
|
||||
|
||||
validate_mtp_section()
|
||||
{
|
||||
uci_validate_section obuspa mtp "${1}" \
|
||||
'enable:bool:true' \
|
||||
'protocol:or("STOMP","CoAP")' \
|
||||
'destination:string' \
|
||||
'CoAPPath:string' \
|
||||
'CoAPPort:uinteger'
|
||||
uci_validate_section ${CONFIGURATION} mtp "${1}" \
|
||||
'Enable:bool:true' \
|
||||
'Protocol:or("STOMP","CoAP","MQTT")' \
|
||||
'Reference:string' \
|
||||
'ResponseTopicConfigured:string' \
|
||||
'PublishQoS:uinteger' \
|
||||
'Destination:string' \
|
||||
'coap_path:string' \
|
||||
'coap_port:uinteger' \
|
||||
'mqtt:string' \
|
||||
'stomp:string'
|
||||
}
|
||||
|
||||
validate_connection_section()
|
||||
validate_stomp_connection_section()
|
||||
{
|
||||
uci_validate_section obuspa connection "${1}" \
|
||||
'host:string:"usp-controller.com"' \
|
||||
'username:string:""' \
|
||||
'password:string:""' \
|
||||
uci_validate_section ${CONFIGURATION} stomp "${1}" \
|
||||
'Host:string:usp-controller.com' \
|
||||
'Username:string' \
|
||||
'Password:string' \
|
||||
'encryption:bool:true' \
|
||||
'enable:bool:true' \
|
||||
'port:uinteger:61613' \
|
||||
'virtualhost:string:"/"' \
|
||||
'Enable:bool:true' \
|
||||
'Port:uinteger:61613' \
|
||||
'VirtualHost:string:/' \
|
||||
'EnableHeartbeats:bool:true' \
|
||||
'OutgoingHeartbeat:uinteger:30000' \
|
||||
'IncomingHeartbeat:uinteger:300000' \
|
||||
@@ -79,82 +147,227 @@ validate_connection_section()
|
||||
'ServerRetryMaxInterval:uinteger:30720'
|
||||
}
|
||||
|
||||
configure_controller() {
|
||||
local endpointid enable AssignedRole PeriodicNotifInterval PeriodicNotifTime USPRetryMinimumWaitInterval
|
||||
local USPRetryIntervalMultiplier ControllerCode protocol CoAPHost CoAPPath CoAPPort
|
||||
validate_mqtt_client_section()
|
||||
{
|
||||
uci_validate_section ${CONFIGURATION} mqtt "${1}" \
|
||||
'BrokerAddress:string' \
|
||||
'BrokerPort:uinteger:1883' \
|
||||
'Enable:bool:true' \
|
||||
'Username:string' \
|
||||
'Password:string' \
|
||||
'ProtocolVersion:string:5.0' \
|
||||
'TransportProtocol:string:TCP/IP' \
|
||||
'KeepAliveTime:uinteger:60' \
|
||||
'ClientID:string' \
|
||||
'ConnectRetryTime:uinteger:5' \
|
||||
'ConnectRetryIntervalMultiplier:uinteger:2000' \
|
||||
'ConnectRetryMaxInterval:uinteger:60'
|
||||
}
|
||||
|
||||
validate_controller_section "${1}" || {
|
||||
log "Validation of section failed"
|
||||
configure_localagent() {
|
||||
local Enable ParameterName EndpointID
|
||||
local _num
|
||||
|
||||
validate_localagent_section 'localagent' || {
|
||||
log "Validation of localagent section failed"
|
||||
return 1;
|
||||
}
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.EndpointID "${endpointid}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.Alias "cpe-${conn_num}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.Enable "true"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.AssignedRole "Device.LocalAgent.ControllerTrust.Role.${AssignedRole}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.PeriodicNotifInterval "${PeriodicNotifInterval}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.PeriodicNotifTime "${PeriodicNotifTime}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.USPRetryMinimumWaitInterval "${USPRetryMinimumWaitInterval}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.USPRetryIntervalMultiplier "${USPRetryIntervalMultiplier}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.ControllerCode "${ControllerCode}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.MTP.${conn_num}.Alias "cpe-${conn_num}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.MTP.${conn_num}.Enable "${enable}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.MTP.${conn_num}.Protocol "${protocol}"
|
||||
if [ "${protocol}"=="STOMP" ]; then
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.MTP.${conn_num}.STOMP.Reference "Device.STOMP.Connection.${conn_num}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.MTP.${conn_num}.STOMP.Destination "controller-notify-dest"
|
||||
elif [ "${protocol}"=="CoAP" ]; then
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.MTP.${conn_num}.CoAP.Host "${CoAPHost}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.MTP.${conn_num}.CoAP.Path "${CoAPPath}"
|
||||
db_set Device.LocalAgent.Controller.${conn_num}.MTP.${conn_num}.CoAP.Port "${CoAPPort}"
|
||||
else
|
||||
log "Unsupported protocol ${protocol}"
|
||||
|
||||
if [ -n "${EndpointID}" ]; then
|
||||
db_set Device.LocalAgent.EndpointID "${EndpointID}"
|
||||
fi
|
||||
|
||||
_num=1
|
||||
while [ ${_num} -le ${controller_num} ]
|
||||
do
|
||||
db_set Device.LocalAgent.Controller.${_num}.BootParameter.1.Alias "cpe-1"
|
||||
db_set Device.LocalAgent.Controller.${_num}.BootParameter.1.Enable "${Enable}"
|
||||
db_set Device.LocalAgent.Controller.${_num}.BootParameter.1.ParameterName "${ParameterName}"
|
||||
_num=$(( ${_num} + 1 ))
|
||||
done
|
||||
|
||||
db_set
|
||||
conn_num=$((conn_num+1))
|
||||
}
|
||||
|
||||
configure_controller() {
|
||||
local EndpointID Enable AssignedRole PeriodicNotifInterval PeriodicNotifTime USPNotifRetryMinimumWaitInterval
|
||||
local USPNotifRetryIntervalMultiplier ControllerCode Protocol Destination coap_host coap_path coap_port
|
||||
local Reference Topic mqtt stomp
|
||||
|
||||
validate_controller_section "${1}" || {
|
||||
log "Validation of controller section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
if [ -z ${EndpointID} -o -z ${Protocol} ]; then
|
||||
log "controller:: EndpointID id and Protocol cannot be empty"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
if [ -z "${stomp}" -a -z "${Reference}" -a -z "${mqtt}" -a -z "${coap_path}" ]; then
|
||||
log "controller:: Invalid configuration"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
if [ -z ${Reference} ]; then
|
||||
if [ ${Protocol} = "STOMP" ]; then
|
||||
val=$(get_uci_ref_index stomp ${stomp})
|
||||
if [ ${val} -eq 0 ]; then
|
||||
log "Not able to find the referred stomp section"
|
||||
return 1;
|
||||
fi
|
||||
Reference="Device.STOMP.Connection.${val}"
|
||||
elif [ ${Protocol} = "MQTT" ]; then
|
||||
val=$(get_uci_ref_index mqtt ${mqtt})
|
||||
if [ ${val} -eq 0 ]; then
|
||||
log "Not able to find the referred mqtt section"
|
||||
return 1;
|
||||
fi
|
||||
Reference="Device.MQTT.Client.${val}"
|
||||
fi
|
||||
fi
|
||||
|
||||
controller_num=$(( controller_num + 1 ))
|
||||
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.Alias "cpe-${controller_num}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.Enable "${Enable}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.EndpointID "${EndpointID}"
|
||||
#db_set Device.LocalAgent.Controller.${controller_num}.AssignedRole "${AssignedRole}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.PeriodicNotifInterval "${PeriodicNotifInterval}"
|
||||
if [ -n "${PeriodicNotifTime}" ]; then
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.PeriodicNotifTime "${PeriodicNotifTime}"
|
||||
else
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.PeriodicNotifTime "0001-01-01T00:00:00Z"
|
||||
fi
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.USPNotifRetryMinimumWaitInterval "${USPNotifRetryMinimumWaitInterval}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.USPNotifRetryIntervalMultiplier "${USPNotifRetryIntervalMultiplier}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.ControllerCode "${ControllerCode}"
|
||||
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.Alias "cpe-${controller_num}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.Enable "${Enable}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.Protocol "${Protocol}"
|
||||
# only support configuration of one mtp path per controller using uci
|
||||
if [ "${Protocol}" = "MQTT" ]; then
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.MQTT.Reference "${Reference}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.MQTT.Topic "${Topic}"
|
||||
elif [ "${Protocol}" = "STOMP" ]; then
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.STOMP.Reference "${Reference}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.STOMP.Destination "${Destination}"
|
||||
elif [ "${Protocol}" = "CoAP" ]; then
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.CoAP.Host "${coap_host}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.CoAP.Path "${coap_path}"
|
||||
db_set Device.LocalAgent.Controller.${controller_num}.MTP.1.CoAP.Port "${coap_port}"
|
||||
else
|
||||
log "Unsupported Protocol ${Protocol}"
|
||||
fi
|
||||
|
||||
db_set
|
||||
}
|
||||
|
||||
configure_subscription(){
|
||||
local ID Enable NotifType ReferenceList Persistent Recipient
|
||||
local controller
|
||||
|
||||
validate_subscription_section "${1}" || {
|
||||
log "Validation of subscription section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
if [ -z "${Recipient}" -a -z "${controller}" ]; then
|
||||
log "No recipient for subscription"
|
||||
fi
|
||||
|
||||
if [ -z ${Recipient} ]; then
|
||||
val=$(get_uci_ref_index controller ${controller})
|
||||
if [ ${val} -eq 0 ]; then
|
||||
log "Not able to find the referred controller section"
|
||||
return 1;
|
||||
fi
|
||||
Recipient="Device.LocalAgent.Controller.${val}"
|
||||
fi
|
||||
|
||||
subs_num=$(( subs_num + 1))
|
||||
|
||||
db_set Device.LocalAgent.Subscription.${subs_num}.Alias "cpe-${subs_num}"
|
||||
db_set Device.LocalAgent.Subscription.${subs_num}.Enable "${Enable}"
|
||||
db_set Device.LocalAgent.Subscription.${subs_num}.ID "${ID}"
|
||||
db_set Device.LocalAgent.Subscription.${subs_num}.NotifType "${NotifType}"
|
||||
db_set Device.LocalAgent.Subscription.${subs_num}.ReferenceList "${ReferenceList}"
|
||||
db_set Device.LocalAgent.Subscription.${subs_num}.Persistent "${Persistent}"
|
||||
db_set Device.LocalAgent.Subscription.${subs_num}.Recipient "${Recipient}"
|
||||
}
|
||||
|
||||
configure_mtp() {
|
||||
local protocol enable destination CoAPPath CoAPPort
|
||||
local Enable Protocol Reference ResponseTopicConfigured PublishQoS
|
||||
local stomp mqtt
|
||||
|
||||
validate_mtp_section "${1}" || {
|
||||
log "Validation of section failed"
|
||||
log "Validation of mtp section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
if [ -z ${Reference} ]; then
|
||||
if [ ${Protocol} = "STOMP" ]; then
|
||||
val=$(get_uci_ref_index stomp ${stomp})
|
||||
if [ ${val} -eq 0 ]; then
|
||||
log "Referred stomp section not found"
|
||||
return 1;
|
||||
fi
|
||||
Reference="Device.STOMP.Connection.${val}"
|
||||
elif [ ${Protocol} = "MQTT" ]; then
|
||||
val=$(get_uci_ref_index mqtt ${mqtt})
|
||||
if [ ${val} -eq 0 ]; then
|
||||
log "Referred mqtt section not found"
|
||||
return 1;
|
||||
fi
|
||||
Reference="Device.MQTT.Client.${val}"
|
||||
fi
|
||||
fi
|
||||
mtp_num=$(( mtp_num + 1 ))
|
||||
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.Alias "cpe-${mtp_num}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.Enable "${enable}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.Protocol "${protocol}"
|
||||
if [ "${protocol}"=="STOMP" ]; then
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.STOMP.Reference "Device.STOMP.Connection.${mtp_num}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.STOMP.Destination "${destination}"
|
||||
elif [ "${protocol}"=="CoAP" ]; then
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.CoAP.Path "${CoAPPath}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.CoAP.Port "${CoAPPort}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.Enable "${Enable}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.Protocol "${Protocol}"
|
||||
if [ "${Protocol}" = "MQTT" ]; then
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.MQTT.Reference "${Reference}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.MQTT.ResponseTopicConfigured "${ResponseTopicConfigured}"
|
||||
if [ -n "${PublishQoS}" ]; then
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.MQTT.PublishQoS "${PublishQoS}"
|
||||
fi
|
||||
elif [ "${Protocol}" = "STOMP" ]; then
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.STOMP.Reference "${Reference}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.STOMP.Destination "${Destination}"
|
||||
elif [ "${Protocol}" = "CoAP" ]; then
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.CoAP.Path "${coap_path}"
|
||||
db_set Device.LocalAgent.MTP.${mtp_num}.CoAP.Port "${coap_port}"
|
||||
else
|
||||
log "Unsupported protocol ${protocol}"
|
||||
log "Unsupported Protocol ${Protocol} in mtp"
|
||||
fi
|
||||
db_set
|
||||
mtp_num=$((mtp_num+1))
|
||||
}
|
||||
|
||||
configure_connection() {
|
||||
local host username password encryption enable port virtualhost EnableHeartbeats
|
||||
configure_stomp_connection() {
|
||||
local Host Username Password Enable Port VirtualHost EnableHeartbeats
|
||||
local OutgoingHeartbeat IncomingHeartbeat ServerRetryInitialInterval
|
||||
local ServerRetryIntervalMultiplier ServerRetryMaxInterval
|
||||
local encryption
|
||||
|
||||
validate_connection_section "${1}" || {
|
||||
log "Validation of section failed"
|
||||
validate_stomp_connection_section "${1}" || {
|
||||
log "Validation of stomp section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Host "${host}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Username "${username}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Password "${password}"
|
||||
stomp_num=$(( stomp_num + 1 ))
|
||||
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Host "${Host}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Username "${Username}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Password "${Password}"
|
||||
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Alias "cpe-${stomp_num}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Enable "${enable}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Port "${port}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Enable "${Enable}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.Port "${Port}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.X_ARRIS-COM_EnableEncryption "${encryption}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.VirtualHost "${virtualhost}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.VirtualHost "${VirtualHost}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.EnableHeartbeats "${EnableHeartbeats}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.OutgoingHeartbeat "${OutgoingHeartbeat}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.IncomingHeartbeat "${IncomingHeartbeat}"
|
||||
@@ -162,20 +375,51 @@ configure_connection() {
|
||||
db_set Device.STOMP.Connection.${stomp_num}.ServerRetryIntervalMultiplier "${ServerRetryIntervalMultiplier}"
|
||||
db_set Device.STOMP.Connection.${stomp_num}.ServerRetryMaxInterval "${ServerRetryMaxInterval}"
|
||||
db_set
|
||||
stomp_num=$((stomp_num+1))
|
||||
}
|
||||
|
||||
configure_obuspa() {
|
||||
local enable cert interface debug log_level log_dest
|
||||
configure_mqtt_client(){
|
||||
local BrokerAddress BrokerPort Enable Username Password ProtocolVersion KeepAliveTime
|
||||
local TransportProtocol ConnectRetryTime ConnectRetryMaxInterval ConnectRetryIntervalMultiplier
|
||||
|
||||
validate_obuspa_section "${1}" || {
|
||||
log "Validation of section failed"
|
||||
validate_mqtt_client_section "${1}" || {
|
||||
log "Validation of mqtt section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
[ ${enable} -eq 0 ] && \
|
||||
echo "obuspa not enabled" >>/dev/console && \
|
||||
exit
|
||||
if [ -z "${BrokerAddress}" ]; then
|
||||
log "Broker address can not be empty for mqtt"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
mqtt_num=$(( mqtt_num + 1 ))
|
||||
|
||||
db_set Device.MQTT.Client.${mqtt_num}.Alias "cpe-${mqtt_num}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.Enable "${Enable}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.BrokerAddress "${BrokerAddress}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.BrokerPort "${BrokerPort}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.Username "${Username}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.Password "${Password}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.ProtocolVersion "${ProtocolVersion}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.TransportProtocol "${TransportProtocol}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.KeepAliveTime "${KeepAliveTime}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.ClientID "${ClientID}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.ConnectRetryTime "${ConnectRetryTime}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.ConnectRetryIntervalMultiplier "${ConnectRetryIntervalMultiplier}"
|
||||
db_set Device.MQTT.Client.${mqtt_num}.ConnectRetryMaxInterval "${ConnectRetryMaxInterval}"
|
||||
|
||||
db_set
|
||||
}
|
||||
|
||||
|
||||
configure_obuspa() {
|
||||
local enabled trust_cert ifname interface debug log_level db_file log_dest
|
||||
|
||||
validate_obuspa_section "global" || {
|
||||
log "Validation of global section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
[ ${enabled} -eq 0 ] && exit 0
|
||||
|
||||
if [ ${debug} -eq 1 ]; then
|
||||
# Forward stdout of the command to logd
|
||||
@@ -184,42 +428,92 @@ configure_obuspa() {
|
||||
procd_set_param stderr 1
|
||||
procd_append_param command -p
|
||||
fi
|
||||
procd_append_param command -v ${log_level} -l ${log_dest}
|
||||
|
||||
# Get wan L3 interface
|
||||
json_load "$(ubus -t 2 call network.interface.${interface} status)"
|
||||
json_get_var l3device l3_device
|
||||
export USP_BOARD_IFNAME=${l3device}
|
||||
if [ -n ${log_level} ]; then
|
||||
procd_append_param command -v ${log_level}
|
||||
fi
|
||||
|
||||
# Set this variable for root user
|
||||
grep -q USP_BOARD_IFNAME /root/.profile || \
|
||||
echo "export USP_BOARD_IFNAME=${l3device}" >> /root/.profile
|
||||
if [ -n "${log_dest}" ]; then
|
||||
procd_append_param command -l ${log_dest}
|
||||
fi
|
||||
|
||||
[ -f $cert ] && certificate=$cert
|
||||
if [ -n "${interface}" ]; then
|
||||
network_get_device ifname ${interface}
|
||||
log "ifname from ${interface} is ${ifname}"
|
||||
fi
|
||||
|
||||
# Set this variable for root user and obuspa -c tool
|
||||
grep -q "export USP_BOARD_IFNAME=${ifname}" /root/.profile || \
|
||||
echo "export USP_BOARD_IFNAME=${ifname}" >> /root/.profile
|
||||
|
||||
if [ -n "${db_file}" ]; then
|
||||
echo "${db_file}" >>${KEEP_FILES}
|
||||
procd_append_param command -f ${db_file}
|
||||
fi
|
||||
|
||||
if [ -n "${trust_cert}" ]; then
|
||||
echo "${trust_cert}" >>${KEEP_FILES}
|
||||
if [ -f "${trust_cert}" ]; then
|
||||
procd_append_param command -t ${trust_cert}
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${client_cert}" ]; then
|
||||
echo "${client_cert}" >>${KEEP_FILES}
|
||||
if [ -f "${client_cert}" ]; then
|
||||
procd_append_param command -a ${client_cert}
|
||||
fi
|
||||
fi
|
||||
|
||||
procd_set_param env USP_BOARD_IFNAME=${ifname}
|
||||
}
|
||||
|
||||
# Create factory reset file
|
||||
db_init() {
|
||||
[ -f ${PARAM_FILE} ] && rm -f ${PARAM_FILE}
|
||||
[ -f /tmp/usp.db ] && rm -f /tmp/usp.db
|
||||
[ -f ${KEEP_FILES} ] && rm -f ${KEEP_FILES}
|
||||
|
||||
config_load obuspa
|
||||
# Load configuration
|
||||
config_load $CONFIGURATION
|
||||
config_foreach configure_obuspa obuspa
|
||||
config_foreach configure_controller controller
|
||||
config_foreach configure_connection connection
|
||||
config_foreach configure_localagent localagent
|
||||
config_foreach configure_mtp mtp
|
||||
config_foreach configure_stomp_connection stomp
|
||||
config_foreach configure_mqtt_client mqtt
|
||||
config_foreach configure_subscription subscription
|
||||
|
||||
db_set Internal.Reboot.Cause "LocalFactoryReset"
|
||||
}
|
||||
|
||||
# if uci changes for obuspa remove persistent db and then reload
|
||||
remove_db() {
|
||||
local db_file
|
||||
|
||||
config_load obuspa
|
||||
config_get db_file global db_file
|
||||
|
||||
log "Removing db file (${db_file})"
|
||||
[ -f ${db_file} ] && rm -f ${db_file}
|
||||
|
||||
sed -i "g/export USP_BOARD_IFNAME/d" /root/.profile
|
||||
|
||||
log "Restarting service"
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
start_service() {
|
||||
procd_open_instance obuspa
|
||||
procd_set_param env USP_BOARD_IFNAME=${l3device}
|
||||
procd_open_instance ${CONFIGURATION}
|
||||
procd_set_param command ${PROG}
|
||||
db_init
|
||||
procd_append_param command -r ${PARAM_FILE}
|
||||
if [ -f "${certificate}" ]; then
|
||||
procd_append_param command -t ${certificate}
|
||||
fi
|
||||
procd_set_param respawn
|
||||
procd_set_param respawn \
|
||||
${respawn_threshold:-5} \
|
||||
${respawn_timeout:-10} ${respawn_retry:-3}
|
||||
|
||||
procd_set_param watch usp.raw
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
@@ -233,5 +527,11 @@ reload_service() {
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_config_trigger "config.change" "obuspa" /etc/init.d/obuspa restart
|
||||
procd_add_reload_trigger "uspd"
|
||||
procd_add_config_trigger "config.change" "${CONFIGURATION}" /etc/init.d/obuspa remove_db
|
||||
|
||||
# local interface
|
||||
# config_load obuspa
|
||||
# config_get interface global interface
|
||||
# [ -n "$interface" ] && procd_add_interface_trigger "interface.*" "$interface" /etc/init.d/obuspa reload
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/owsd.git
|
||||
PKG_SOURCE_VERSION:=e606e7d389ae516d213344e503e76a5de2cf9d33
|
||||
PKG_SOURCE_VERSION:=fd696e9d1be8278db3eb1d9be97e1a66afd6e1f6
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_SOURCE_SUBDIR:=${PKG_NAME}-${PKG_VERSION}
|
||||
PKG_INSTALL:=1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2013 Inteno
|
||||
# Copyright (C) 2020 IOPSYS
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
@@ -12,7 +12,7 @@ PKG_NAME:=peripheral_manager
|
||||
PKG_VERSION:=1.0.5
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_VERSION:=0513e171013512bc14ef8b650c715e3fd9c59820
|
||||
PKG_SOURCE_VERSION:=dd4a72aca663bf3c9a57f20e889e43a55d3da1b3
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/peripheral-manager
|
||||
|
||||
@@ -51,7 +51,7 @@ TARGET_CFLAGS := \
|
||||
|
||||
PERIPHERAL_OPTONS:=-DSELECT_BRCM_BOARD=0
|
||||
|
||||
ifneq ($(CONFIG_TARGET_iopsys_brcm63xx_arm)$(CONFIG_TARGET_iopsys_brcm63xx_mips),)
|
||||
ifneq ($(CONFIG_TARGET_iopsys_brcm63xx_arm),)
|
||||
PERIPHERAL_OPTONS:= -DSELECT_BRCM_BOARD=1
|
||||
endif
|
||||
|
||||
|
||||
@@ -37,4 +37,4 @@ populate_config(){
|
||||
[ $DEBUG ] && cat /etc/config/ports
|
||||
}
|
||||
|
||||
[ -f /sbin/db -a -f /lib/db/config/hw ] && populate_config
|
||||
[ -f /sbin/db -a -f /etc/board-db/config/hw ] && populate_config
|
||||
|
||||
@@ -24,15 +24,17 @@ generate_queue(){
|
||||
fi
|
||||
|
||||
i=0
|
||||
local total_q=$((${no_of_q##* } + 1))
|
||||
for i in $no_of_q; do
|
||||
order=$((total_q - i))
|
||||
uci add qos queue
|
||||
uci rename qos.@queue[-1]="q_${i}_${ifname}"
|
||||
uci set qos.@queue[-1].enable="1"
|
||||
uci set qos.@queue[-1].ifname="$ifname"
|
||||
uci set qos.@queue[-1].precedence="$i"
|
||||
uci set qos.@queue[-1].precedence="$order"
|
||||
uci set qos.@queue[-1].scheduling="SP"
|
||||
uci set qos.@queue[-1].rate="0"
|
||||
uci set qos.@queue[-1].burst_size="-1"
|
||||
uci set qos.@queue[-1].burst_size="0"
|
||||
uci set qos.@queue[-1].weight="1"
|
||||
done
|
||||
|
||||
|
||||
@@ -4,25 +4,143 @@
|
||||
IP_RULE=""
|
||||
BR_RULE=""
|
||||
|
||||
#function to handle a queue section
|
||||
handle_queue() {
|
||||
POLICER_SKIP=0
|
||||
POLICER_COUNT=0
|
||||
INTF_NAME=""
|
||||
Q_COUNT=0
|
||||
ITER=0
|
||||
PREV_ORDER=""
|
||||
CURR_ORDER=""
|
||||
MAX_ORDER=""
|
||||
|
||||
# Function to handle a queue order and
|
||||
# update total number of queues
|
||||
handle_q_order() {
|
||||
qid="$1" #queue section ID
|
||||
|
||||
config_get is_enable "$qid" "enable"
|
||||
|
||||
#no need to configure disabled queues
|
||||
# No need to configure disabled queues
|
||||
if [ $is_enable == '0' ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
config_get ifname "$qid" "ifname"
|
||||
#if ifname is empty that is good enough to break
|
||||
# If ifname is empty that is good enough to break
|
||||
if [ -z "$ifname" ];then
|
||||
return
|
||||
fi
|
||||
|
||||
#lower the value, lower the priority of queue on this chip
|
||||
config_get order "$qid" "precedence"
|
||||
# Create precedence file containing queue order per
|
||||
# interface.
|
||||
local precedence_file="/tmp/qos/$ifname/q_order"
|
||||
local q_no=$(cat /tmp/qos/queue_stats/$ifname/q_idx)
|
||||
|
||||
config_get precedence "$qid" "precedence"
|
||||
value=${precedence}_q${q_no}
|
||||
echo $value >> $precedence_file
|
||||
|
||||
# Update the number of queues per interface.
|
||||
q_no=$((q_no + 1))
|
||||
echo $q_no > /tmp/qos/queue_stats/$ifname/q_idx
|
||||
}
|
||||
|
||||
# Function to check if values are greater than (total number
|
||||
# of queue -1) and map them to corresponding value.
|
||||
configure_precedence_to_file() {
|
||||
order="$1"
|
||||
line="$2"
|
||||
order_file="$3"
|
||||
|
||||
if [ $order == $PREV_ORDER ]; then
|
||||
queue_id=${line#*_}
|
||||
val=${CURR_ORDER}_${queue_id}
|
||||
echo $val >> $order_file
|
||||
else
|
||||
PREV_ORDER=$order
|
||||
queue_id=${line#*_}
|
||||
val=${MAX_ORDER}_${queue_id}
|
||||
echo $val >> $order_file
|
||||
CURR_ORDER=$MAX_ORDER
|
||||
MAX_ORDER=$((MAX_ORDER - 1))
|
||||
fi
|
||||
}
|
||||
|
||||
# Fucntion to map queue precedence per interface
|
||||
# ranging from 1-X to 0-(no of queues -1)
|
||||
map_queue_precedence() {
|
||||
ifname="$1"
|
||||
total_q=$(cat /tmp/qos/queue_stats/$ifname/q_idx)
|
||||
q_no=`expr $total_q - 1`
|
||||
|
||||
MAX_ORDER=$q_no
|
||||
|
||||
local precedence_file="/tmp/qos/$ifname/q_precedence"
|
||||
local order_file="/tmp/qos/$ifname/q_order"
|
||||
|
||||
sort -n -r -k1 $order_file >> $precedence_file
|
||||
rm $order_file
|
||||
|
||||
while read line
|
||||
do
|
||||
order=${line%_*}
|
||||
if [ $order -gt $q_no ]; then
|
||||
ITER=$((ITER + 1))
|
||||
configure_precedence_to_file $order $line $order_file
|
||||
else
|
||||
if [ $ITER == '0' ]; then
|
||||
echo $line >> $order_file
|
||||
else
|
||||
configure_precedence_to_file $order $line $order_file
|
||||
fi
|
||||
fi
|
||||
|
||||
done < $precedence_file
|
||||
}
|
||||
|
||||
map_precedence() {
|
||||
for interf in $(db -q get hw.board.ethernetPortOrder); do
|
||||
map_queue_precedence $interf
|
||||
done
|
||||
}
|
||||
|
||||
# function to handle a queue section
|
||||
handle_queue() {
|
||||
qid="$1" #queue section ID
|
||||
|
||||
config_get is_enable "$qid" "enable"
|
||||
|
||||
# no need to configure disabled queues
|
||||
if [ $is_enable == '0' ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
config_get ifname "$qid" "ifname"
|
||||
# if ifname is empty that is good enough to break
|
||||
if [ -z "$ifname" ];then
|
||||
return
|
||||
fi
|
||||
|
||||
# This is to get the qid per interface.
|
||||
if [ $INTF_NAME == $ifname ]; then
|
||||
Q_COUNT=$((Q_COUNT + 1))
|
||||
else
|
||||
Q_COUNT='0'
|
||||
fi
|
||||
|
||||
INTF_NAME=$ifname
|
||||
|
||||
local total_q=$(cat /tmp/qos/queue_stats/$ifname/q_idx)
|
||||
q_no=`expr $total_q - 1` local
|
||||
precedence_file="/tmp/qos/$ifname/q_order"
|
||||
|
||||
# TR181 suggests lower the precedence value higher the priority
|
||||
# but in the chip its the opposite ie lower the value, lower
|
||||
# the priority of queue on this chip. So we need to reverse the
|
||||
# precedence value.
|
||||
precedence="$(grep -i q${Q_COUNT} $precedence_file)"
|
||||
precedence=${precedence%_*}
|
||||
order=`expr $q_no - $precedence`
|
||||
|
||||
config_get sc_alg "$qid" "scheduling"
|
||||
config_get wgt "$qid" "weight"
|
||||
@@ -43,8 +161,56 @@ handle_queue() {
|
||||
;;
|
||||
esac
|
||||
|
||||
# ignore precedence value in case of WRR
|
||||
if [ $salg -eq 2 ]; then
|
||||
order=0
|
||||
fi
|
||||
|
||||
# Call tmctl which is a broadcomm command to configure queues on a port.
|
||||
tmctl setqcfg --devtype 0 --if $ifname --qid $order --priority $order --qsize $qsize --weight $wgt --schedmode $salg --shapingrate $rate --burstsize $bs
|
||||
tmctl setqcfg --devtype 0 --if $ifname --qid $Q_COUNT --priority $order --qsize $qsize --weight $wgt --schedmode $salg --shapingrate $rate --burstsize $bs
|
||||
|
||||
# In BCM968 chips, the counters for queues are read, on other model, its read and reset. So, to maintain counter
|
||||
# value and uniform behaviour, we are storing counter value for each queue in files
|
||||
local d_name="/tmp/qos/queue_stats/${ifname}/q_${Q_COUNT}"
|
||||
mkdir $d_name
|
||||
local f_name="$d_name/txPackets"
|
||||
touch $f_name
|
||||
echo 0 > $f_name
|
||||
f_name="$d_name/txBytes"
|
||||
touch $f_name
|
||||
echo 0 > $f_name
|
||||
f_name="$d_name/droppedPackets"
|
||||
touch $f_name
|
||||
echo 0 > $f_name
|
||||
f_name="$d_name/droppedBytes"
|
||||
touch $f_name
|
||||
echo 0 > $f_name
|
||||
|
||||
}
|
||||
|
||||
#function to handle a policer section
|
||||
handle_policer() {
|
||||
local p_sec="$1" # policer section ID
|
||||
local dir=1 # default direction, upstream
|
||||
|
||||
config_get is_enable "$p_sec" "enable"
|
||||
|
||||
#no need to configure disabled policer
|
||||
if [ $is_enable == '0' ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
config_get cir "$p_sec" "committed_rate"
|
||||
config_get cbs "$p_sec" "committed_burst_size" -1
|
||||
config_get ebs "$p_sec" "excess_burst_size" 0
|
||||
config_get pir "$p_sec" "peak_rate" 0
|
||||
config_get pbs "$p_sec" "peak_burst_size" 0
|
||||
config_get meter "$p_sec" "meter_type" 0
|
||||
|
||||
# Call tmctl which is a broadcomm command to configure policer.
|
||||
tmctl createpolicer --dir $dir --pid $POLICER_COUNT --ptype $meter --cir $cir --cbs $cbs --ebs $ebs --pir $pir --pbs $pbs
|
||||
|
||||
POLICER_COUNT=$((POLICER_COUNT + 1))
|
||||
}
|
||||
|
||||
#function to handle a shaper section
|
||||
@@ -72,7 +238,12 @@ handle_shaper() {
|
||||
setup_qos() {
|
||||
ebtables -t broute -N qos
|
||||
ret=$?
|
||||
[ $ret -eq 0 ] && ebtables -t broute -I BROUTING -j qos
|
||||
if [ $ret -eq 0 ]; then
|
||||
ebtables -t broute -I BROUTING -j qos
|
||||
else
|
||||
ebtables -t broute -D BROUTING -j qos
|
||||
ebtables -t broute -I BROUTING -j qos
|
||||
fi
|
||||
|
||||
iptables -t mangle -N qos_forward
|
||||
ret=$?
|
||||
@@ -150,6 +321,8 @@ broute_append_rule() {
|
||||
handle_ebtables_rules() {
|
||||
sid=$1
|
||||
local is_l2_rule=0
|
||||
local src_dhcp_options=""
|
||||
local dst_dhcp_options=""
|
||||
|
||||
init_broute_rule
|
||||
|
||||
@@ -159,6 +332,14 @@ handle_ebtables_rules() {
|
||||
config_get pcp_check "$sid" "pcp_check"
|
||||
config_get eth_type "$sid" "ethertype"
|
||||
config_get vid "$sid" "vid_check"
|
||||
config_get dhcp_type "$sid" "dhcp_type" # dhcpv4 or v6
|
||||
config_get src_vcid "$sid" "src_vendor_class_id" # dhcp option 60
|
||||
config_get dst_vcid "$sid" "dst_vendor_class_id" # dhcp option 60
|
||||
config_get src_clid "$sid" "src_client_id" # dhcp option 61
|
||||
config_get dst_clid "$sid" "dst_client_id" # dhcp option 61
|
||||
config_get src_ucid "$sid" "src_user_class_id" # dhcp option 77
|
||||
config_get dst_ucid "$sid" "dst_user_class_id" # dhcp option 77
|
||||
|
||||
config_get traffic_class "$sid" "traffic_class"
|
||||
|
||||
if [ -n "$src_if" ]; then
|
||||
@@ -196,6 +377,70 @@ handle_ebtables_rules() {
|
||||
is_l2_rule=1
|
||||
fi
|
||||
|
||||
# first process options that will help figure our source mac address
|
||||
# dhcp option for "vendor class id"
|
||||
if [ -n "$src_vcid" ]; then
|
||||
src_dhcp_options="$src_dhcp_options vcid=$src_vcid"
|
||||
is_l2_rule=1
|
||||
fi
|
||||
|
||||
# dhcp option for "client id"
|
||||
if [ -n "$src_clid" ]; then
|
||||
src_dhcp_options="$src_dhcp_options clid=$src_clid"
|
||||
is_l2_rule=1
|
||||
fi
|
||||
|
||||
# dhcp option for "user class id"
|
||||
if [ -n "$src_ucid" ]; then
|
||||
src_dhcp_options="$src_dhcp_options ucid=$src_ucid"
|
||||
is_l2_rule=1
|
||||
fi
|
||||
|
||||
# if src mac is already a classification criteria, then it
|
||||
# does not really make sense to add it as a criteria to
|
||||
# filter packets again based on source mac
|
||||
if [ -n "$src_dhcp_options" -a -z "$src_mac" ]; then
|
||||
comp="$(grep -i "$src_dhcp_options" /tmp/dhcp.client.options)"
|
||||
if [ -n "$comp" ]; then
|
||||
s_mac_add="$(echo $comp | head -n1 | awk '{print $1;}')"
|
||||
if [ -n "$s_mac_add" ]; then
|
||||
broute_filter_on_src_mac $s_mac_add
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Now process options that will help figure our destination mac address
|
||||
# dhcp option for "vendor class id"
|
||||
if [ -n "$dst_vcid" ]; then
|
||||
dst_dhcp_options="$dst_dhcp_options vcid=$dst_vcid"
|
||||
is_l2_rule=1
|
||||
fi
|
||||
|
||||
# dhcp option for "client id"
|
||||
if [ -n "$dst_clid" ]; then
|
||||
dst_dhcp_options="$dst_dhcp_options clid=$dst_clid"
|
||||
is_l2_rule=1
|
||||
fi
|
||||
|
||||
# dhcp option for "user class id"
|
||||
if [ -n "$dst_ucid" ]; then
|
||||
dst_dhcp_options="$dst_dhcp_options ucid=$dst_ucid"
|
||||
is_l2_rule=1
|
||||
fi
|
||||
|
||||
# if dst mac is already a classification criteria, then it
|
||||
# does not really make sense to add it as a criteria to
|
||||
# filter packets again based on dstination mac
|
||||
if [ -n "$dst_dhcp_options" -a -z "$dst_mac" ]; then
|
||||
comp="$(grep -i "$dst_dhcp_options" /tmp/dhcp.client.options)"
|
||||
if [ -n "$comp" ]; then
|
||||
d_mac_add="$(echo $comp | head -n1 | awk '{print $1;}')"
|
||||
if [ -n "$d_mac_add" ]; then
|
||||
broute_filter_on_dst_mac $d_mac_add
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $is_l2_rule -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
@@ -395,6 +640,107 @@ handle_iptables_rules() {
|
||||
fi
|
||||
}
|
||||
|
||||
assign_policer_to_port() {
|
||||
local ifname="$1"
|
||||
local pindex="$2"
|
||||
local portorder="$(db -q get hw.board.ethernetPortOrder)"
|
||||
local wanport="$(db -q get hw.board.ethernetWanPort)"
|
||||
|
||||
local i=0
|
||||
for port in $portorder; do
|
||||
if [ "$ifname" == "$port" ]; then
|
||||
if [ "$wanport" == "$port" ]; then
|
||||
bs /b/configure port/index=wan0 ingress_rate_limit={traffic_types=8,policer={policer/dir=us,index=$pindex}}
|
||||
else
|
||||
bs /b/configure port/index=lan$i ingress_rate_limit={traffic_types=8,policer={policer/dir=us,index=$pindex}}
|
||||
fi
|
||||
break
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done
|
||||
}
|
||||
|
||||
handle_policer_rules() {
|
||||
local c_sec=$1
|
||||
local policer_name
|
||||
local ifname
|
||||
local pname
|
||||
local pindex=-1
|
||||
local ingress_rate=0
|
||||
local in_burst_size=0
|
||||
|
||||
config_get policer_name "$c_sec" "policer"
|
||||
if [ -z "$policer_name" ];then
|
||||
# no need to apply policer if policer not present in this
|
||||
# classification rule
|
||||
return
|
||||
fi
|
||||
|
||||
config_get ifname "$c_sec" "ifname"
|
||||
if [ -z "$ifname" ]; then
|
||||
# cannot associate policer as interface is not mentioned
|
||||
return
|
||||
fi
|
||||
|
||||
local i=0
|
||||
local max_policer_inst=$(cat /tmp/qos/max_policer_inst)
|
||||
while :
|
||||
do
|
||||
if [ $i -eq $max_policer_inst ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
pname="$(uci -q get qos.@policer[$i].name)"
|
||||
if [ "$policer_name" == "$pname" ]; then
|
||||
pindex=$i
|
||||
ingress_rate=$(uci -q get qos.@policer[$i].committed_rate)
|
||||
in_burst_rate=$(uci -q get qos.@policer[$i].committed_burst_size)
|
||||
break
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
if [ $pindex -lt 0 ]; then
|
||||
# policer not found, no need to proceed further
|
||||
return
|
||||
fi
|
||||
|
||||
# The policer object is not available on non BCM968* chips
|
||||
if [ $POLICER_SKIP -eq 1 ]; then
|
||||
assign_policer_to_port $ifname $pindex
|
||||
else
|
||||
config_ingress_rate_limit $ifname $ingress_rate $in_burst_size
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
config_ingress_rate_limit() {
|
||||
local ifname="$1"
|
||||
local ingress_rate=$2
|
||||
local in_burst_size=$3
|
||||
local wanport="$(db -q get hw.board.ethernetWanPort)"
|
||||
|
||||
if [ "$ifname" == "$wanport" ]; then
|
||||
logger -t qosmngr "policing is not support on port $ifname"
|
||||
return
|
||||
fi
|
||||
|
||||
# Unit in uci file is in bps while that accepted by ethswctl is kbits
|
||||
if [ $ingress_rate -lt 1000 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
ingress_rate=$((ingress_rate / 1000))
|
||||
|
||||
if [ $in_burst_size -eq 0 ]; then
|
||||
in_burst_size=$ingress_rate
|
||||
else
|
||||
in_burst_size=$((in_burst_size / 1000))
|
||||
fi
|
||||
|
||||
ethswctl -c rxratectrl -n 1 -p $ifname -x $ingress_rate -y $in_burst_size
|
||||
}
|
||||
|
||||
#function to handle a classify section
|
||||
handle_classify() {
|
||||
cid="$1" #classify section ID
|
||||
@@ -407,9 +753,14 @@ handle_classify() {
|
||||
|
||||
handle_ebtables_rules $cid
|
||||
handle_iptables_rules $cid
|
||||
handle_policer_rules $cid
|
||||
}
|
||||
|
||||
configure_shaper() {
|
||||
# Delete existing shaper
|
||||
for intf in $(db get hw.board.ethernetPortOrder); do
|
||||
tmctl setportshaper --devtype 0 --if $intf --shapingrate 0 --burstsize -1
|
||||
done
|
||||
# Load UCI file
|
||||
config_load qos
|
||||
# Processing shaper section(s)
|
||||
@@ -439,30 +790,90 @@ configure_classify() {
|
||||
sh /tmp/qos/classify.ebtables
|
||||
sh /tmp/qos/classify.iptables
|
||||
sh /tmp/qos/classify.ip6tables
|
||||
# broadcom recommends that each time traffic class is set,
|
||||
# the flows should be flushed for the new mapping to take
|
||||
# effect, it then makes sense to make it a part of the
|
||||
# qosmngr package itself.
|
||||
fcctl flush
|
||||
}
|
||||
|
||||
configure_queue() {
|
||||
# Delete queues
|
||||
rm -rf /tmp/qos/queue_stats
|
||||
|
||||
for intf in $(db get hw.board.ethernetPortOrder); do
|
||||
rm -rf /tmp/qos/$intf
|
||||
|
||||
mkdir -p /tmp/qos/queue_stats/$intf
|
||||
touch /tmp/qos/queue_stats/$intf/q_idx
|
||||
echo 0 > /tmp/qos/queue_stats/$intf/q_idx
|
||||
i=0
|
||||
for i in 0 1 2 3 4 5 6 7; do
|
||||
tmctl delqcfg --devtype 0 --if $intf --qid $i &>/dev/null
|
||||
done
|
||||
|
||||
mkdir -p /tmp/qos/$intf
|
||||
touch /tmp/qos/$intf/q_order
|
||||
touch /tmp/qos/$intf/q_precedence
|
||||
done
|
||||
|
||||
# Load UCI file
|
||||
config_load qos
|
||||
config_foreach handle_q_order queue
|
||||
map_precedence
|
||||
config_foreach handle_queue queue
|
||||
}
|
||||
|
||||
configure_policer() {
|
||||
# The policer object is not available on non BCM968* chips, just clean up
|
||||
# the old config if any and return
|
||||
if [ $POLICER_SKIP -eq 0 ]; then
|
||||
for intf in $(db get hw.board.ethernetPortOrder); do
|
||||
# setting rate and burst size to 0 disables rate limiting
|
||||
ethswctl -c rxratectrl -n 1 -p $intf -x 0 -y 0
|
||||
done
|
||||
return
|
||||
fi
|
||||
|
||||
# Delete policer
|
||||
local i=0
|
||||
local max_p_inst=0
|
||||
if [ -f "/tmp/qos/max_policer_inst" ]; then
|
||||
max_p_inst=$(cat /tmp/qos/max_policer_inst)
|
||||
fi
|
||||
|
||||
while :
|
||||
do
|
||||
if [ $i -eq $max_p_inst ]; then
|
||||
break
|
||||
fi
|
||||
tmctl deletepolicer --dir 1 --pid $i &>/dev/null
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
# reset the policer counter
|
||||
echo 0 > /tmp/qos/max_policer_inst
|
||||
# Load UCI file
|
||||
config_load qos
|
||||
config_foreach handle_policer policer
|
||||
echo $POLICER_COUNT > /tmp/qos/max_policer_inst
|
||||
}
|
||||
|
||||
configure_qos() {
|
||||
configure_queue
|
||||
configure_shaper
|
||||
configure_policer
|
||||
configure_classify
|
||||
}
|
||||
|
||||
reload_qos() {
|
||||
local service_name="$1"
|
||||
local cpu_model="$(brcm_fw_tool -k info)"
|
||||
|
||||
case $cpu_model in
|
||||
68*|6755) POLICER_SKIP=1 ;;
|
||||
esac
|
||||
|
||||
if [ -z "$service_name" ]; then
|
||||
configure_qos
|
||||
elif [ "$service_name" == "shaper" ]; then
|
||||
@@ -471,77 +882,143 @@ reload_qos() {
|
||||
configure_queue
|
||||
elif [ "$service_name" == "classify" ]; then
|
||||
configure_classify
|
||||
elif [ "$service_name" == "policer" ]; then
|
||||
configure_policer
|
||||
fi
|
||||
}
|
||||
|
||||
get_queue_stats() {
|
||||
local ifname
|
||||
local f_name
|
||||
local tmp_val
|
||||
local q_index=0
|
||||
local max_q_index=0
|
||||
|
||||
json_init
|
||||
json_add_array "queues"
|
||||
i=0
|
||||
while :
|
||||
do
|
||||
ifname=$(uci -q get qos.@queue[$i].ifname)
|
||||
|
||||
# if ifname is empty that is good enough to break
|
||||
if [ -z "$ifname" ];then
|
||||
break
|
||||
fi
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
if [ "$ifname" != "$1" ]; then
|
||||
i=$((i + 1))
|
||||
if [ -n "$1" ]; then
|
||||
ifname=$1
|
||||
max_q_index=$(cat /tmp/qos/queue_stats/${ifname}/q_idx)
|
||||
while :
|
||||
do
|
||||
if [ $q_index -eq $max_q_index ]; then
|
||||
break
|
||||
fi
|
||||
stats="$(tmctl getqstats --devtype 0 --if $ifname --qid $q_index)"
|
||||
ret="$(echo $stats | awk '{print substr($0,0,5)}')"
|
||||
#check tmctl ERROR condition
|
||||
if [ $ret == 'ERROR' ]; then
|
||||
q_index=$((q_index + 1))
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
json_add_object ""
|
||||
json_add_int "qid" "$q_index"
|
||||
json_add_string "iface" "$ifname"
|
||||
|
||||
order=$(uci -q get qos.@queue[$i].precedence)
|
||||
stats="$(tmctl getqstats --devtype 0 --if $ifname --qid $order)"
|
||||
ret="$(echo $stats | awk '{print substr($0,0,5)}')"
|
||||
IFS=$'\n'
|
||||
for stat in $stats; do
|
||||
pname="$(echo $stat | awk '{print$1}')"
|
||||
if [ $pname == 'ret' ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
#check tmctl ERROR condition
|
||||
if [ $ret == 'ERROR' ]; then
|
||||
i=$((i + 1))
|
||||
continue
|
||||
fi
|
||||
val="$(echo $stat | awk '{print$2}')"
|
||||
|
||||
json_add_object ""
|
||||
json_add_int "qid" "$order"
|
||||
json_add_string "iface" "$ifname"
|
||||
# remove trailing : from the name
|
||||
pname="${pname::-1}"
|
||||
local f_name="/tmp/qos/queue_stats/${ifname}/q_${q_index}/${pname}"
|
||||
# In non BCM968* chips, read operation on queues is actually a read and reset,
|
||||
# so values need to be maintained to present cumulative value
|
||||
if [ $POLICER_SKIP -eq 0 ]; then
|
||||
tmp_val=$(cat $f_name)
|
||||
val=$((val + tmp_val))
|
||||
fi
|
||||
echo $val > $f_name
|
||||
|
||||
IFS=$'\n'
|
||||
for stat in $stats; do
|
||||
pname="$(echo $stat | awk '{print$1}')"
|
||||
if [ $pname == 'ret' ]; then
|
||||
continue
|
||||
fi
|
||||
# convert to iopsyswrt names
|
||||
case "$pname" in
|
||||
txPackets)
|
||||
json_add_int "tx_packets" "$val"
|
||||
;;
|
||||
txBytes)
|
||||
json_add_int "tx_bytes" "$val"
|
||||
;;
|
||||
droppedPackets)
|
||||
json_add_int "tx_dropped_packets" "$val"
|
||||
;;
|
||||
droppedBytes)
|
||||
json_add_int "tx_dropped_bytes" "$val"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
json_close_object
|
||||
|
||||
val="$(echo $stat | awk '{print$2}')"
|
||||
|
||||
# remove trailing : from the name
|
||||
pname="${pname::-1}"
|
||||
|
||||
# convert to iopsyswrt names
|
||||
case "$pname" in
|
||||
txPackets)
|
||||
json_add_int "tx_packets" "$val"
|
||||
;;
|
||||
txBytes)
|
||||
json_add_int "tx_bytes" "$val"
|
||||
;;
|
||||
droppedPackets)
|
||||
json_add_int "tx_dropped_packets" "$val"
|
||||
;;
|
||||
droppedBytes)
|
||||
json_add_int "tx_dropped_bytes" "$val"
|
||||
;;
|
||||
esac
|
||||
q_index=$((q_index + 1))
|
||||
done
|
||||
else
|
||||
for intf in $(db get hw.board.ethernetPortOrder); do
|
||||
ifname=$intf
|
||||
q_index=0
|
||||
max_q_index=$(cat /tmp/qos/queue_stats/${ifname}/q_idx)
|
||||
while :
|
||||
do
|
||||
if [ $q_index -eq $max_q_index ]; then
|
||||
break
|
||||
fi
|
||||
stats="$(tmctl getqstats --devtype 0 --if $ifname --qid $q_index)"
|
||||
ret="$(echo $stats | awk '{print substr($0,0,5)}')"
|
||||
#check tmctl ERROR condition
|
||||
if [ $ret == 'ERROR' ]; then
|
||||
q_index=$((q_index + 1))
|
||||
continue
|
||||
fi
|
||||
json_add_object ""
|
||||
json_add_int "qid" "$q_index"
|
||||
json_add_string "iface" "$ifname"
|
||||
|
||||
json_close_object
|
||||
IFS=$'\n'
|
||||
for stat in $stats; do
|
||||
pname="$(echo $stat | awk '{print$1}')"
|
||||
if [ $pname == 'ret' ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
i=$((i + 1))
|
||||
done
|
||||
val="$(echo $stat | awk '{print$2}')"
|
||||
|
||||
# remove trailing : from the name
|
||||
pname="${pname::-1}"
|
||||
local f_name="/tmp/qos/queue_stats/${ifname}/q_${q_index}/${pname}"
|
||||
# In non BCM968* chips, read operation on queues is actually a read and reset,
|
||||
# so values need to be maintained to present cumulative value
|
||||
if [ $POLICER_SKIP -eq 0 ]; then
|
||||
tmp_val=$(cat $f_name)
|
||||
val=$((val + tmp_val))
|
||||
fi
|
||||
echo $val > $f_name
|
||||
|
||||
# convert to iopsyswrt names
|
||||
case "$pname" in
|
||||
txPackets)
|
||||
json_add_int "tx_packets" "$val"
|
||||
;;
|
||||
txBytes)
|
||||
json_add_int "tx_bytes" "$val"
|
||||
;;
|
||||
droppedPackets)
|
||||
json_add_int "tx_dropped_packets" "$val"
|
||||
;;
|
||||
droppedBytes)
|
||||
json_add_int "tx_dropped_bytes" "$val"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
json_close_object
|
||||
|
||||
q_index=$((q_index + 1))
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
json_close_array
|
||||
json_dump
|
||||
@@ -552,6 +1029,7 @@ get_eth_q_stats() {
|
||||
json_add_array "queues"
|
||||
|
||||
ifname="$1"
|
||||
local tmp_val=0
|
||||
|
||||
# if ifname is empty that is good enough to break
|
||||
if [ -z "$ifname" ];then
|
||||
@@ -586,6 +1064,14 @@ get_eth_q_stats() {
|
||||
|
||||
# remove trailing : from the name
|
||||
pname="${pname::-1}"
|
||||
local f_name="/tmp/qos/queue_stats/${ifname}/q_${qid}/${pname}"
|
||||
# In non BCM968* chips, read operation on queues is actually a read and reset,
|
||||
# so values need to be maintained to present cumulative value
|
||||
if [ $POLICER_SKIP -eq 0 ]; then
|
||||
tmp_val=$(cat $f_name)
|
||||
val=$((val + tmp_val))
|
||||
fi
|
||||
echo $val > $f_name
|
||||
|
||||
# convert to iopsyswrt names
|
||||
case "$pname" in
|
||||
@@ -613,6 +1099,11 @@ get_eth_q_stats() {
|
||||
read_queue_stats() {
|
||||
itf="$1"
|
||||
q_idx="$2"
|
||||
local cpu_model="$(brcm_fw_tool -k info)"
|
||||
|
||||
case $cpu_model in
|
||||
68*|6755) POLICER_SKIP=1 ;;
|
||||
esac
|
||||
|
||||
if [ -n "$itf" -a -n "$q_idx" ]; then
|
||||
get_eth_q_stats $itf $q_idx
|
||||
|
||||
@@ -6,9 +6,9 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=questd
|
||||
PKG_VERSION:=5.1.11
|
||||
PKG_VERSION:=5.2.1
|
||||
|
||||
PKG_SOURCE_VERSION:=6b64dafae52d0cd28a31d364aeed80380875293b
|
||||
PKG_SOURCE_VERSION:=d4ac29b535bf1ec0f58c4c9eea08ec7db08775d1
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/questd
|
||||
|
||||
|
||||
42
stun/Makefile
Executable file
42
stun/Makefile
Executable file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (C) 2020 iopsys Software Solutions AB
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=stun
|
||||
PKG_VERSION:=1.0.0
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=TRx69
|
||||
TITLE:=BBF stun Client
|
||||
DEPENDS:=+libubus +libuci +libubox +libjson-c +libopenssl +libblobmsg-json
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
CWMP STUN Client
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/stund $(1)/usr/sbin/
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
14
stun/files/etc/config/stun
Normal file
14
stun/files/etc/config/stun
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
config stun 'stun'
|
||||
option enable '0'
|
||||
option username 'stun'
|
||||
option password 'stun'
|
||||
option server_address 'stun.l.google.com'
|
||||
option server_port '19302'
|
||||
option min_keepalive '30'
|
||||
option max_keepalive '3600'
|
||||
# option client_port 7547
|
||||
#if client_port option is not set or < 0 then use a random port for connection request source port
|
||||
#Log levels: Critical=0, Warning=1, Notice=2, Info=3, Debug=4
|
||||
option log_level '3'
|
||||
|
||||
36
stun/files/etc/init.d/stund
Executable file
36
stun/files/etc/init.d/stund
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# STUN client software
|
||||
# Copyright (C) 2020 iopsys Software Solutions AB
|
||||
# Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
|
||||
START=90
|
||||
|
||||
USE_PROCD=1
|
||||
PROG="/usr/sbin/stund"
|
||||
|
||||
start_service() {
|
||||
local enable=`uci -q get stun.stun.enable`
|
||||
if [ "$enable" == "1" ]; then
|
||||
local server=`uci -q get stun.stun.server_address`
|
||||
[ "$server" = "" ] && exit 0
|
||||
procd_open_instance
|
||||
procd_set_param command "$PROG"
|
||||
procd_set_param respawn "3" "7" "0"
|
||||
procd_close_instance
|
||||
fi
|
||||
}
|
||||
|
||||
boot() {
|
||||
start
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
logger -p crit -t "stun" "reloading service()"
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger stun
|
||||
}
|
||||
16
stun/src/Makefile
Normal file
16
stun/src/Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
PROG = stund
|
||||
OBJS = stun.o config.o log.o ubus.o
|
||||
|
||||
PROG_CFLAGS = $(CFLAGS) -Wall -Werror
|
||||
PROG_LDFLAGS = $(LDFLAGS) -lubus -luci -lubox -ljson-c -lcrypto -lblobmsg_json
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(CC) $(PROG_CFLAGS) -o $@ $^ $(PROG_LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(PROG)
|
||||
297
stun/src/config.c
Normal file
297
stun/src/config.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* config.c -- contains functions that allows reading and loading of uci config parameters of stun
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static struct uci_context *uci_ctx = NULL;
|
||||
static struct uci_context *uci_ctx_state = NULL;
|
||||
struct stun_config conf;
|
||||
|
||||
int config_fini(void)
|
||||
{
|
||||
free(conf.server_address);
|
||||
free(conf.password);
|
||||
free(conf.username);
|
||||
conf.server_address = NULL;
|
||||
conf.username = NULL;
|
||||
conf.password = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_init(void)
|
||||
{
|
||||
char *v;
|
||||
suci_init();
|
||||
memset(&conf, 0, sizeof(struct stun_config));
|
||||
|
||||
v = suci_get_value("stun", "stun", "server_address");
|
||||
if (!*v) {
|
||||
stun_log(SCRIT, "Missing Server Address in the STUN config");
|
||||
goto error;
|
||||
}
|
||||
conf.server_address = strdup(v);
|
||||
|
||||
v = suci_get_value("stun", "stun", "username");
|
||||
if (*v)
|
||||
conf.username = strdup(v);
|
||||
|
||||
v = suci_get_value("stun", "stun", "password");
|
||||
if (*v)
|
||||
conf.password = strdup(v);
|
||||
|
||||
v = suci_get_value("stun", "stun", "server_port");
|
||||
if (*v)
|
||||
conf.server_port = atoi(v);
|
||||
else
|
||||
conf.server_port = DEFAULT_SERVERPORT;
|
||||
|
||||
v = suci_get_value("stun", "stun", "log_level");
|
||||
if (*v)
|
||||
conf.loglevel = atoi(v);
|
||||
else
|
||||
conf.loglevel = DEFAULT_LOGLEVEL;
|
||||
|
||||
v = suci_get_value("stun", "stun", "min_keepalive");
|
||||
if (*v)
|
||||
conf.min_keepalive = atoi(v);
|
||||
else
|
||||
conf.min_keepalive = DEFAULT_MINKEEPALIVE;
|
||||
|
||||
v = suci_get_value("stun", "stun", "max_keepalive");
|
||||
if (*v)
|
||||
conf.max_keepalive = atoi(v);
|
||||
else
|
||||
conf.max_keepalive = DEFAULT_MAXKEEPALIVE;
|
||||
|
||||
v = suci_get_value("stun", "stun", "client_port");
|
||||
if (*v)
|
||||
conf.client_port = atoi(v);
|
||||
|
||||
if (conf.max_keepalive <= 0)
|
||||
conf.max_keepalive = DEFAULT_MAXKEEPALIVE;
|
||||
|
||||
if (conf.min_keepalive <= 0)
|
||||
conf.min_keepalive = DEFAULT_MINKEEPALIVE;
|
||||
|
||||
if (conf.server_port <= 0)
|
||||
conf.server_port = DEFAULT_SERVERPORT;
|
||||
|
||||
if (conf.loglevel >= __MAX_SLOG || conf.loglevel < 0) {
|
||||
conf.loglevel = DEFAULT_LOGLEVEL;
|
||||
}
|
||||
|
||||
stun_log(SINFO, "STUN CONFIG - Server Address: %s", conf.server_address);
|
||||
stun_log(SINFO, "STUN CONFIG - Username: %s", conf.username ? conf.username : "<not defined>");
|
||||
stun_log(SINFO, "STUN CONFIG - Server port: %d", conf.server_port);
|
||||
stun_log(SINFO, "STUN CONFIG - min keepalive: %d", conf.min_keepalive);
|
||||
stun_log(SINFO, "STUN CONFIG - max keepalive: %d", conf.max_keepalive);
|
||||
stun_log(SINFO, "STUN CONFIG - Client port: %d", (conf.client_port > 0) ? conf.client_port : -1);
|
||||
stun_log(SINFO, "STUN CONFIG - LOG Level: %d (Critical=0, Warning=1, Notice=2, Info=3, Debug=4)", conf.loglevel);
|
||||
suci_fini();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
suci_fini();
|
||||
config_fini();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int suci_init(void)
|
||||
{
|
||||
uci_ctx = uci_alloc_context();
|
||||
if (!uci_ctx) {
|
||||
return -1;
|
||||
}
|
||||
uci_ctx_state = uci_alloc_context();
|
||||
if (!uci_ctx_state) {
|
||||
return -1;
|
||||
}
|
||||
uci_add_delta_path(uci_ctx_state, uci_ctx_state->savedir);
|
||||
uci_set_savedir(uci_ctx_state, VAR_STATE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int suci_fini(void)
|
||||
{
|
||||
if (uci_ctx) {
|
||||
uci_free_context(uci_ctx);
|
||||
}
|
||||
if (uci_ctx_state) {
|
||||
uci_free_context(uci_ctx_state);
|
||||
}
|
||||
uci_ctx = NULL;
|
||||
uci_ctx_state = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool suci_validate_section(const char *str)
|
||||
{
|
||||
if (!*str)
|
||||
return false;
|
||||
|
||||
for (; *str; str++) {
|
||||
unsigned char c = *str;
|
||||
|
||||
if (isalnum(c) || c == '_')
|
||||
continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int suci_init_ptr(struct uci_context *ctx, struct uci_ptr *ptr, char *package, char *section, char *option, char *value)
|
||||
{
|
||||
memset(ptr, 0, sizeof(struct uci_ptr));
|
||||
|
||||
/* value */
|
||||
if (value) {
|
||||
ptr->value = value;
|
||||
}
|
||||
ptr->package = package;
|
||||
if (!ptr->package)
|
||||
goto error;
|
||||
|
||||
ptr->section = section;
|
||||
if (!ptr->section) {
|
||||
ptr->target = UCI_TYPE_PACKAGE;
|
||||
goto lastval;
|
||||
}
|
||||
|
||||
ptr->option = option;
|
||||
if (!ptr->option) {
|
||||
ptr->target = UCI_TYPE_SECTION;
|
||||
goto lastval;
|
||||
} else {
|
||||
ptr->target = UCI_TYPE_OPTION;
|
||||
}
|
||||
|
||||
lastval:
|
||||
if (ptr->section && !suci_validate_section(ptr->section))
|
||||
ptr->flags |= UCI_LOOKUP_EXTENDED;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void suci_print_list(struct uci_list *uh, char **val, char *delimiter)
|
||||
{
|
||||
struct uci_element *e;
|
||||
static char buffer[512];
|
||||
char *buf = buffer;
|
||||
*buf = '\0';
|
||||
|
||||
uci_foreach_element(uh, e) {
|
||||
if (*buf) {
|
||||
strcat(buf, delimiter);
|
||||
strcat(buf, e->name);
|
||||
}
|
||||
else {
|
||||
strcpy(buf, e->name);
|
||||
}
|
||||
}
|
||||
*val = buf;
|
||||
}
|
||||
|
||||
char *suci_get_value(char *package, char *section, char *option)
|
||||
{
|
||||
struct uci_ptr ptr;
|
||||
char *val = "";
|
||||
|
||||
if (!section || !option)
|
||||
return val;
|
||||
|
||||
if (suci_init_ptr(uci_ctx, &ptr, package, section, option, NULL))
|
||||
return val;
|
||||
|
||||
if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK)
|
||||
return val;
|
||||
|
||||
if (!ptr.o)
|
||||
return val;
|
||||
|
||||
if(ptr.o->type == UCI_TYPE_LIST) {
|
||||
suci_print_list(&ptr.o->v.list, &val, " ");
|
||||
return val;
|
||||
}
|
||||
|
||||
if (ptr.o->v.string)
|
||||
return ptr.o->v.string;
|
||||
else
|
||||
return val;
|
||||
}
|
||||
|
||||
char *suci_set_value(char *package, char *section, char *option, char *value)
|
||||
{
|
||||
struct uci_ptr ptr;
|
||||
int ret = UCI_OK;
|
||||
|
||||
if (!section)
|
||||
return "";
|
||||
|
||||
if (suci_init_ptr(uci_ctx, &ptr, package, section, option, value))
|
||||
return "";
|
||||
|
||||
if (uci_lookup_ptr(uci_ctx, &ptr, NULL, true) != UCI_OK)
|
||||
return "";
|
||||
|
||||
uci_set(uci_ctx, &ptr);
|
||||
|
||||
if (ret == UCI_OK)
|
||||
ret = uci_save(uci_ctx, ptr.p);
|
||||
|
||||
if (ptr.o && ptr.o->v.string)
|
||||
return ptr.o->v.string;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/*************************---/var/state--***************************/
|
||||
|
||||
char *suci_get_value_state(char *package, char *section, char *option)
|
||||
{
|
||||
char *val;
|
||||
struct uci_context *save_uci_ctx = uci_ctx;
|
||||
uci_ctx = uci_ctx_state;
|
||||
val = suci_get_value(package, section, option);
|
||||
uci_ctx = save_uci_ctx;
|
||||
return val;
|
||||
}
|
||||
|
||||
char *suci_set_value_state(char *package, char *section, char *option, char *value)
|
||||
{
|
||||
char *val;
|
||||
struct uci_context *save_uci_ctx = uci_ctx;
|
||||
uci_ctx = uci_ctx_state;
|
||||
val = suci_set_value(package, section, option, value);
|
||||
uci_ctx = save_uci_ctx;
|
||||
return val;
|
||||
}
|
||||
44
stun/src/config.h
Normal file
44
stun/src/config.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* TR-069 STUN client software
|
||||
* Copyright (C) 2020 PIVA SOFTWARE <www.pivasoftware.com> - All Rights Reserved
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#include <uci.h>
|
||||
#include "log.h"
|
||||
|
||||
#define VAR_STATE "/var/state"
|
||||
#define DEFAULT_SERVERPORT 3478
|
||||
#define DEFAULT_CLIENTPORT 7547
|
||||
#define DEFAULT_MINKEEPALIVE 30
|
||||
#define DEFAULT_RETRYTIME 3
|
||||
#define DEFAULT_MAXKEEPALIVE 3600
|
||||
#define DEFAULT_LOGLEVEL SINFO
|
||||
|
||||
struct stun_config {
|
||||
char *server_address;
|
||||
char *username;
|
||||
char *password;
|
||||
int server_port;
|
||||
int client_port;
|
||||
int max_keepalive;
|
||||
int min_keepalive;
|
||||
int loglevel;
|
||||
};
|
||||
|
||||
extern struct stun_config conf;
|
||||
|
||||
int config_init(void);
|
||||
int config_fini(void);
|
||||
|
||||
int suci_init(void);
|
||||
int suci_fini(void);
|
||||
void suci_print_list(struct uci_list *uh, char **val, char *delimiter);
|
||||
char *suci_get_value(char *package, char *section, char *option);
|
||||
char *suci_set_value(char *package, char *section, char *option, char *value);
|
||||
char *suci_get_value_state(char *package, char *section, char *option);
|
||||
char *suci_set_value_state(char *package, char *section, char *option, char *value);
|
||||
|
||||
#endif //__CONFIG_H
|
||||
68
stun/src/log.c
Normal file
68
stun/src/log.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* log.c : conatains function used log traces
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "config.h"
|
||||
|
||||
static const int log_syslogmap[] = {
|
||||
[SCRIT] = LOG_CRIT,
|
||||
[SWARNING] = LOG_WARNING,
|
||||
[SNOTICE] = LOG_NOTICE,
|
||||
[SINFO] = LOG_INFO,
|
||||
[SDEBUG] = LOG_DEBUG
|
||||
};
|
||||
|
||||
static const char* log_str[] = {
|
||||
[SCRIT] = "CRITICAL",
|
||||
[SWARNING] = "WARNING",
|
||||
[SNOTICE] = "NOTICE",
|
||||
[SINFO] = "INFO",
|
||||
[SDEBUG] = "DEBUG"
|
||||
};
|
||||
|
||||
void stun_log(int priority, const char *format, ...)
|
||||
{
|
||||
va_list vl;
|
||||
|
||||
if (priority <= conf.loglevel) {
|
||||
time_t t = time(NULL);
|
||||
struct tm tm = *localtime(&t);
|
||||
va_start(vl, format);
|
||||
printf("%d-%02d-%02d %02d:%02d:%02d [stun] %s - ", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, log_str[priority]);
|
||||
vprintf(format, vl);
|
||||
va_end(vl);
|
||||
printf("\n");
|
||||
|
||||
openlog("stun", 0, LOG_DAEMON);
|
||||
va_start(vl, format);
|
||||
vsyslog(log_syslogmap[priority], format, vl);
|
||||
va_end(vl);
|
||||
closelog();
|
||||
}
|
||||
}
|
||||
20
stun/src/log.h
Normal file
20
stun/src/log.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/* TR-069 STUN client software
|
||||
* Copyright (C) 2020 PIVA SOFTWARE <www.pivasoftware.com> - All Rights Reserved
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#ifndef __SLOG_H
|
||||
#define __SLOG_H
|
||||
|
||||
enum stun_log_level_enum {
|
||||
SCRIT,
|
||||
SWARNING,
|
||||
SNOTICE,
|
||||
SINFO,
|
||||
SDEBUG,
|
||||
__MAX_SLOG
|
||||
};
|
||||
|
||||
void stun_log(int priority, const char *format, ...);
|
||||
|
||||
#endif //__SLOG_H
|
||||
687
stun/src/stun.c
Normal file
687
stun/src/stun.c
Normal file
@@ -0,0 +1,687 @@
|
||||
/*
|
||||
* stun.c -- the main file of stun application
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* TR-069 STUN client software
|
||||
* Copyright (C) 2020 PIVA SOFTWARE <www.pivasoftware.com> - All Rights Reserved
|
||||
* Author: Mohamed Kallel <mohamed.kallel@pivasoftware.com>
|
||||
* Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
* Anis Ellouze <anis.ellouze@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdlib.h>
|
||||
#include <libubox/uloop.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <string.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include "stun.h"
|
||||
#include "config.h"
|
||||
#include "ubus.h"
|
||||
|
||||
struct env_var env = {0};
|
||||
int keepalive_timeout = DEFAULT_MINKEEPALIVE;
|
||||
int retry_timeout = DEFAULT_RETRYTIME;
|
||||
int bindcrreusaddr = 1;
|
||||
int bindcrreusport = 1;
|
||||
const char *BBFCR = "dslforum.org/TR-111 ";
|
||||
|
||||
static void stun_notify_cb(struct uloop_timeout *timeout);
|
||||
static void stun_inform_cb(struct uloop_timeout *timeout);
|
||||
static void listening_crport_cb(struct uloop_timeout *timeout);
|
||||
static void binding_request_crport_cb(struct uloop_timeout *timeout);
|
||||
|
||||
|
||||
static struct udp_listen listen_crport = {
|
||||
.fd = -1,
|
||||
.utimer = {.cb = listening_crport_cb}
|
||||
};
|
||||
static struct binding_request br_crport = {
|
||||
.binding_cr = 1,
|
||||
.udp_listen = &listen_crport,
|
||||
.utimer = {.cb = binding_request_crport_cb}
|
||||
};
|
||||
static struct binding_request br_crport_keepalive = {
|
||||
.is_keealive = 1,
|
||||
.binding_cr = 1,
|
||||
.udp_listen = &listen_crport,
|
||||
.utimer = {.cb = binding_request_crport_cb}
|
||||
};
|
||||
|
||||
struct uloop_timeout stun_notify_timer = {.cb = stun_notify_cb};
|
||||
struct uloop_timeout stun_inform_timer = {.cb = stun_inform_cb};
|
||||
|
||||
void stun_notify(int afterms)
|
||||
{
|
||||
uloop_timeout_set(&stun_notify_timer, afterms);
|
||||
}
|
||||
|
||||
void stun_inform(int afterms)
|
||||
{
|
||||
uloop_timeout_set(&stun_inform_timer, afterms);
|
||||
}
|
||||
|
||||
|
||||
static void stun_notify_cb(struct uloop_timeout *timeout)
|
||||
{
|
||||
stun_log(SINFO, "ubus call tr069 notify");
|
||||
if (subus_call("tr069", "notify", 0, UBUS_ARGS{}) < 0) {
|
||||
stun_log(SINFO, "ubus call tr069 notify failed! retry after 1s");
|
||||
stun_notify(1000);
|
||||
}
|
||||
}
|
||||
|
||||
static void stun_inform_cb(struct uloop_timeout *timeout)
|
||||
{
|
||||
stun_log(SINFO, "ubus call tr069 inform '{\"event\": \"6 connection request\"}'");
|
||||
if (subus_call("tr069", "inform", 1, UBUS_ARGS{{"event", "6 connection request"}}) < 0) {
|
||||
stun_log(SINFO, "ubus call tr069 inform '{\"event\": \"6 connection request\"}' failed! retry after 1s");
|
||||
stun_inform(1000);
|
||||
}
|
||||
}
|
||||
|
||||
static int stunid_cmp(stunid *left, stunid *right)
|
||||
{
|
||||
return memcmp(left, right, sizeof(*left));
|
||||
}
|
||||
|
||||
static void *stunid_cpy(stunid *left, stunid *right)
|
||||
{
|
||||
return memcpy(left, right, sizeof(*left));
|
||||
}
|
||||
|
||||
static void stunid_rand(stunid *id)
|
||||
{
|
||||
int i;
|
||||
srand(time(NULL));
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
id->id[i] = rand();
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t timeout_recvfrom(int sock, char *buf, int length, struct sockaddr_in *connection, int timeoutinseconds)
|
||||
{
|
||||
fd_set socks;
|
||||
ssize_t r = 0;
|
||||
struct timeval t = {0};
|
||||
int clen = sizeof(*connection);
|
||||
|
||||
stun_log(SDEBUG, "udp revcfrom, timeout: %ds", timeoutinseconds);
|
||||
|
||||
FD_ZERO(&socks);
|
||||
FD_SET(sock, &socks);
|
||||
t.tv_sec = timeoutinseconds;
|
||||
if (select(sock + 1, &socks, NULL, NULL, &t) &&
|
||||
(r = recvfrom(sock, buf, length, 0, (struct sockaddr *)connection, (socklen_t *)&clen)) != -1) {
|
||||
return r;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int stun_send(int s, char *buf)
|
||||
{
|
||||
struct stun_header *sh;
|
||||
struct hostent *he;
|
||||
struct sockaddr_in dst = {0};
|
||||
|
||||
sh = (struct stun_header *)buf;
|
||||
if ((he = gethostbyname(conf.server_address)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(&(dst.sin_addr), he->h_addr_list[0], he->h_length);
|
||||
dst.sin_port = htons(conf.server_port);
|
||||
dst.sin_family = AF_INET;
|
||||
|
||||
stun_log(SINFO, "send STUN message to %s:%u (%s:%u)", conf.server_address, conf.server_port, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port));
|
||||
|
||||
return sendto(s, buf, ntohs(sh->len) + sizeof(*sh), 0, (struct sockaddr *)&dst, sizeof(dst));
|
||||
}
|
||||
|
||||
static int net_socket(int srcport)
|
||||
{
|
||||
int sock = -1;
|
||||
stun_log(SINFO, "Open UDP socket");
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (sock >= 0) {
|
||||
if (srcport > 0) {
|
||||
struct sockaddr_in bindcraddr = {0};
|
||||
int i = 0;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &bindcrreusaddr, sizeof(int)) < 0) {
|
||||
stun_log(SWARNING, "setsockopt(SO_REUSEADDR) failed");
|
||||
}
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &bindcrreusport, sizeof(int)) < 0) {
|
||||
stun_log(SWARNING, "setsockopt(SO_REUSEPORT) failed");
|
||||
}
|
||||
bindcraddr.sin_family = AF_INET;
|
||||
bindcraddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
bindcraddr.sin_port = htons((unsigned short)srcport);
|
||||
for(;i<9;i++)
|
||||
{
|
||||
if (bind(sock, (struct sockaddr *)&bindcraddr, sizeof(bindcraddr)) < 0) {
|
||||
continue;
|
||||
}
|
||||
stun_log(SINFO, "binding socket source port to %u", srcport);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fcntl(sock, F_SETFD, fcntl(sock, F_GETFD) | FD_CLOEXEC);
|
||||
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
static void stun_close_socket(struct udp_listen *udp_listen)
|
||||
{
|
||||
uloop_timeout_cancel(&udp_listen->utimer);
|
||||
if (udp_listen->fd > 0) {
|
||||
stun_log(SINFO, "STUN close socket %d", udp_listen->fd);
|
||||
close(udp_listen->fd);
|
||||
}
|
||||
udp_listen->fd = -1;
|
||||
}
|
||||
|
||||
static void stun_socket(struct udp_listen *udp_listen)
|
||||
{
|
||||
|
||||
if (udp_listen->fd > 0) {
|
||||
stun_close_socket(udp_listen);
|
||||
}
|
||||
udp_listen->fd = net_socket(conf.client_port);
|
||||
stun_log(SINFO, "STUN new socket %d", udp_listen->fd);
|
||||
uloop_timeout_set(&udp_listen->utimer, 0);
|
||||
}
|
||||
|
||||
static int trailing_buffer_alloc(int mp, char *buf, int len, char trail, char **bufm, int *mlen)
|
||||
{
|
||||
*bufm = NULL;
|
||||
*mlen = len % mp;
|
||||
*mlen = len + (*mlen ? (mp - *mlen) : 0);
|
||||
*bufm = calloc(1, *mlen);
|
||||
if (*bufm == NULL)
|
||||
return -1;
|
||||
memcpy(*bufm, buf, len);
|
||||
if (trail) {
|
||||
while(len < *mlen) {
|
||||
(*bufm)[len++] = trail;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int append_attribute_buffer(unsigned char **start, char *buf, int len, unsigned short attr_type, int free)
|
||||
{
|
||||
if ((sizeof(struct stun_attribute) + len) > free)
|
||||
return -1;
|
||||
struct stun_attribute *sa = (struct stun_attribute *)*start;
|
||||
sa->len = htons((unsigned short)len);
|
||||
sa->type = htons(attr_type);
|
||||
memcpy(sa->value, buf, len);
|
||||
*start += sizeof(struct stun_attribute) + len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stun_hmac(int trailing_mp, unsigned char *data, int len, char *password, char *hmac)
|
||||
{
|
||||
char *bufmp = NULL;
|
||||
int lenmp;
|
||||
unsigned char* digest;
|
||||
|
||||
if (trailing_mp) {
|
||||
if (trailing_buffer_alloc(trailing_mp, (char *)data, len, 0, &bufmp, &lenmp))
|
||||
return -1;
|
||||
digest = HMAC(EVP_sha1(), password, strlen(password), (unsigned char *)bufmp, lenmp, NULL, NULL);
|
||||
free(bufmp);
|
||||
}
|
||||
else {
|
||||
digest = HMAC(EVP_sha1(), password, strlen(password), data, len, NULL, NULL);
|
||||
}
|
||||
|
||||
memcpy(hmac, digest, 20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hex_to_str(char *hex, int len, char *str)
|
||||
{
|
||||
while (len--) {
|
||||
sprintf(str, "%02X", *hex++);
|
||||
str += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static int generate_stun_packet(struct binding_request *br, char *req_buf, int maxlen)
|
||||
{
|
||||
struct stun_header *req;
|
||||
unsigned char *stunmsg;
|
||||
|
||||
req = (struct stun_header *) req_buf;
|
||||
stunmsg = req->stunmsg;
|
||||
|
||||
stun_log(SINFO, "STUN generate BINDING-REQUEST");
|
||||
req->type = htons(BINDING_REQUSET);
|
||||
stunid_rand(&(req->id));
|
||||
stunid_cpy(&(br->id), &(req->id));
|
||||
stun_log(SINFO, "STUN request id: %d%d%d%d", req->id.id[0], req->id.id[1], req->id.id[2], req->id.id[3]);
|
||||
if (conf.username) {
|
||||
char *buf4;
|
||||
int len4;
|
||||
if (trailing_buffer_alloc(4, conf.username, strlen(conf.username), ' ', &buf4, &len4))
|
||||
return -1;
|
||||
append_attribute_buffer(&stunmsg, buf4, len4, ATTR_USERNAME, (maxlen - (stunmsg - (unsigned char *)req)));
|
||||
stun_log(SINFO, "STUN append USERNAME: **%.*s**", len4, buf4);
|
||||
free(buf4);
|
||||
}
|
||||
if (br->binding_cr) {
|
||||
stun_log(SINFO, "STUN append CONNECTION-REQUEST-BINDING: **%s**", BBFCR);
|
||||
append_attribute_buffer(&stunmsg, (char *)BBFCR, strlen(BBFCR), ATTR_CONNECTION_REQUEST_BINDING, (maxlen - (stunmsg - (unsigned char *)req)));
|
||||
}
|
||||
if (br->binding_change) {
|
||||
stun_log(SINFO, "STUN append BINDING-CHANGE");
|
||||
append_attribute_buffer(&stunmsg, "", 0, ATTR_BINDING_CHANGE, (maxlen - (stunmsg - (unsigned char *)req)));
|
||||
}
|
||||
if (br->msg_integrity) {
|
||||
if (conf.username) {
|
||||
char *password;
|
||||
char hmac[20] = {0};
|
||||
char hmacstr[64];
|
||||
req->len = htons((stunmsg - (unsigned char *)req) - sizeof(struct stun_header) + sizeof(struct stun_attribute) + 20);
|
||||
password = conf.password ? conf.password : "";
|
||||
stun_hmac(64, (unsigned char *)req, stunmsg - (unsigned char *)req, password, hmac);
|
||||
append_attribute_buffer(&stunmsg, hmac, sizeof(hmac), ATTR_MESSAGE_INTEGRITY, (maxlen - (stunmsg - (unsigned char *)req)));
|
||||
hex_to_str(hmac, 20, hmacstr);
|
||||
stun_log(SINFO, "STUN append MESSAGE-INTEGRITY: ***%s***", hmacstr);
|
||||
}
|
||||
else {
|
||||
req->len = htons((stunmsg - (unsigned char *)req) - sizeof(struct stun_header));
|
||||
br->msg_integrity = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
req->len = htons((stunmsg - (unsigned char *)req) - sizeof(struct stun_header));
|
||||
}
|
||||
stun_log(SINFO, "STUN request length: %d", ntohs(req->len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stun_get_mapped_address(char *buf, unsigned int *ip, unsigned short *port)
|
||||
{
|
||||
struct stun_header *sh = (struct stun_header *)buf;
|
||||
struct stun_attribute *sa = (struct stun_attribute *)sh->stunmsg;
|
||||
char *p;
|
||||
while (((char *)sa - (char *)sh - sizeof(*sh)) < ntohs(sh->len)) {
|
||||
if(ntohs(sa->type) == ATTR_MAPPED_ADDRESS) {
|
||||
struct stun_address *ma = (struct stun_address *)sa->value;
|
||||
*port = ma->port;
|
||||
*ip = ma->address;
|
||||
return 0;
|
||||
}
|
||||
p = (char *)sa;
|
||||
p += sizeof(struct stun_attribute) + ntohs(sa->len);
|
||||
sa = (struct stun_attribute *)p;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stun_get_error_code(char *buf)
|
||||
{
|
||||
struct stun_header *sh = (struct stun_header *)buf;
|
||||
struct stun_attribute *sa = (struct stun_attribute *)sh->stunmsg;
|
||||
char *p;
|
||||
|
||||
while (((char *)sa - (char *)sh - sizeof(*sh)) < ntohs(sh->len)) {
|
||||
if(ntohs(sa->type) == ATTR_ERROR_CODE) {
|
||||
unsigned int class, number;
|
||||
unsigned int ui = ntohl(*((unsigned int *)sa->value));
|
||||
class = (ui >> 8) & 0x7;
|
||||
number = ui & 0xff;
|
||||
return (int)(class * 100 + number);
|
||||
}
|
||||
p = (char *)sa;
|
||||
p += sizeof(struct stun_attribute) + ntohs(sa->len);
|
||||
sa = (struct stun_attribute *)p;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_udp_cr(char *resp_buf)
|
||||
{
|
||||
char *str;
|
||||
char un[64], cn[64], sig[64], buf[256];
|
||||
char *crusername;
|
||||
char *crpassword;
|
||||
unsigned int crid = 0, ts = 0;
|
||||
int valid = 1;
|
||||
|
||||
stun_log(SINFO, "Handle UDP Connection Request");
|
||||
|
||||
if ((str = strstr(resp_buf, "ts="))) {
|
||||
sscanf(str, "ts=%u", &ts);
|
||||
stun_log(SINFO, "UDP CR ts = %u", ts);
|
||||
}
|
||||
else {
|
||||
stun_log(SWARNING, "UDP CR ts not found");
|
||||
return;
|
||||
}
|
||||
if ((str = strstr(resp_buf, "id="))) {
|
||||
sscanf(str, "id=%u", &crid);
|
||||
stun_log(SINFO, "UDP CR id = %u", crid);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
stun_log(SWARNING, "UDP CR id not found");
|
||||
}
|
||||
if (crid && ts && crid != env.last_crid && ts > env.last_ts) {
|
||||
stun_log(SINFO, "NEW UDP CR");
|
||||
env.last_crid = crid;
|
||||
env.last_ts = ts;
|
||||
if ((str = strstr(resp_buf, "un="))) {
|
||||
sscanf(str, "un=%63[^?& \t\n\r]", un);
|
||||
stun_log(SINFO, "UDP CR un = %s", un);
|
||||
}
|
||||
else {
|
||||
stun_log(SWARNING, "UDP CR un not found");
|
||||
return;
|
||||
}
|
||||
if ((str = strstr(resp_buf, "cn="))) {
|
||||
sscanf(str, "cn=%63[^?& \t\n\r]", cn);
|
||||
stun_log(SINFO, "UDP CR cn = %s", cn);
|
||||
}
|
||||
else {
|
||||
stun_log(SWARNING, "UDP CR cn not found");
|
||||
return;
|
||||
}
|
||||
if ((str = strstr(resp_buf, "sig="))) {
|
||||
sscanf(str, "sig=%63[^?& \t\n\r]",sig);
|
||||
stun_log(SINFO, "UDP CR sig = %s", sig);
|
||||
}
|
||||
else {
|
||||
stun_log(SWARNING, "UDP CR sig not found");
|
||||
return;
|
||||
}
|
||||
suci_init();
|
||||
crusername = suci_get_value("cwmp", "cpe", "userid");
|
||||
crpassword = suci_get_value("cwmp", "cpe", "password");
|
||||
if (*crusername && *crpassword) {
|
||||
if (strcmp(crusername, un) != 0) {
|
||||
stun_log(SINFO, "UDP CR username mismatch!");
|
||||
valid = 0;
|
||||
}
|
||||
else {
|
||||
char hmac[20], hmacstr[64];
|
||||
snprintf(buf, sizeof(buf), "%u%u%s%s", ts, crid, un, cn);
|
||||
stun_hmac(0, (unsigned char *)buf, strlen(buf), crpassword, hmac);
|
||||
hex_to_str(hmac, 20, hmacstr);
|
||||
if (strcasecmp(hmacstr, sig) != 0) {
|
||||
stun_log(SINFO, "UDP CR sig mismatch!");
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
suci_fini();
|
||||
if (valid) {
|
||||
stun_inform(0);
|
||||
}
|
||||
} else {
|
||||
if (!ts || !crid)
|
||||
stun_log(SINFO, "UDP CR ts or id not found");
|
||||
else
|
||||
stun_log(SINFO, "UDP CR ts is old or id is already received");
|
||||
}
|
||||
}
|
||||
|
||||
static void save_udpcr_var_state(unsigned int ip, unsigned short port)
|
||||
{
|
||||
struct in_addr ip_addr;
|
||||
char buf[64];
|
||||
|
||||
ip_addr.s_addr = env.address;
|
||||
snprintf(buf, sizeof(buf), "%s:%d", inet_ntoa(ip_addr), ntohs(env.port));
|
||||
stun_log(SINFO, "Save New UDPConnectionRequestAddress to /var/state %s", buf);
|
||||
suci_init();
|
||||
suci_set_value_state("stun", "stun", "crudp_address", buf);
|
||||
suci_fini();
|
||||
}
|
||||
|
||||
static int is_udpcr_changed(unsigned int ip, unsigned short port)
|
||||
{
|
||||
struct in_addr ip_addr;
|
||||
char buf[64];
|
||||
char *v;
|
||||
int changed = 0;
|
||||
|
||||
ip_addr.s_addr = ip;
|
||||
snprintf(buf, sizeof(buf), "%s:%d", inet_ntoa(ip_addr), ntohs(port));
|
||||
suci_init();
|
||||
v = suci_get_value_state("stun", "stun", "crudp_address");
|
||||
if (strcmp(buf, v) != 0)
|
||||
changed = 1;
|
||||
suci_fini();
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void save_natdetected_var_state(unsigned int ip)
|
||||
{
|
||||
struct ifaddrs * ifaddrlist = NULL;
|
||||
struct ifaddrs * ifa = NULL;
|
||||
int islocal = 0;
|
||||
char *nd;
|
||||
|
||||
getifaddrs(&ifaddrlist);
|
||||
|
||||
for (ifa = ifaddrlist; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (ifa ->ifa_addr && ifa ->ifa_addr->sa_family == AF_INET) {
|
||||
if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == ip) {
|
||||
islocal = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ifaddrlist != NULL)
|
||||
freeifaddrs(ifaddrlist);
|
||||
|
||||
suci_init();
|
||||
nd = suci_get_value_state("stun", "stun", "nat_detected");
|
||||
|
||||
if (islocal && *nd != '\0') {
|
||||
stun_log(SINFO, "Device is not behind NAT, set NATDetected to false");
|
||||
suci_set_value_state("stun", "stun", "nat_detected", "");
|
||||
}
|
||||
else if (!islocal && *nd == '\0') {
|
||||
stun_log(SINFO, "Device is behind NAT, set NATDetected to true");
|
||||
suci_set_value_state("stun", "stun", "nat_detected", "1");
|
||||
}
|
||||
suci_fini();
|
||||
}
|
||||
|
||||
static void binding_request_crport_cb(struct uloop_timeout *timeout)
|
||||
{
|
||||
struct binding_request *br;
|
||||
struct udp_listen *udp_listen;
|
||||
char req_buf[2048] = {0};
|
||||
int r;
|
||||
|
||||
|
||||
br = binding_request_entry(timeout);
|
||||
udp_listen = br->udp_listen;
|
||||
|
||||
udp_listen->br = br;
|
||||
|
||||
stun_log(SINFO, "Binding Request cb start %s", br->is_keealive ? "(KeepAlive)" : "");
|
||||
|
||||
if (udp_listen->fd <= 0) {
|
||||
stun_socket(udp_listen);
|
||||
}
|
||||
|
||||
if (br->resp_success > 0)
|
||||
br->resp_success = 0;
|
||||
|
||||
if (generate_stun_packet(br, req_buf, sizeof(req_buf) - 1)) {
|
||||
br->retry_interval = (br->retry_interval) ? 2 * br->retry_interval : retry_timeout;
|
||||
br->retry_interval = (br->retry_interval > 1500) ? 1500 : br->retry_interval;
|
||||
uloop_timeout_set(&br->utimer, br->retry_interval * 1000);
|
||||
return;
|
||||
}
|
||||
r = stun_send(udp_listen->fd, req_buf);
|
||||
if (r < 0) {
|
||||
stun_close_socket(udp_listen);
|
||||
udp_listen->br = NULL;
|
||||
br->retry_interval = (br->retry_interval) ? 2 * br->retry_interval : retry_timeout;
|
||||
br->retry_interval = (br->retry_interval > 1500) ? 1500 : br->retry_interval;
|
||||
stun_log(SINFO, "Failed send of Binding Request! retry in %ds", br->retry_interval);
|
||||
uloop_timeout_set(timeout, br->retry_interval * 1000);
|
||||
}
|
||||
else {
|
||||
br->retry_interval = 0;
|
||||
stun_log(SINFO, "Success send of Binding Request.");
|
||||
stun_log(SINFO, "Start KeepAlive Binding Request in %ds.", keepalive_timeout);
|
||||
uloop_timeout_set(&br_crport_keepalive.utimer, keepalive_timeout * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
static void listening_crport_cb(struct uloop_timeout *timeout)
|
||||
{
|
||||
struct udp_listen *udp_listen;
|
||||
struct sockaddr_in src = {0};
|
||||
char resp_buf[2048] = {0};
|
||||
unsigned int ip = 0;
|
||||
unsigned short port = 0;
|
||||
int r;
|
||||
|
||||
stun_log(SDEBUG, "Binding listening CR cb start");
|
||||
udp_listen = udp_listen_entry(timeout);
|
||||
if (udp_listen->fd < 0) {
|
||||
stun_log(SINFO, "Binding listening CR: Socket = -1");
|
||||
uloop_timeout_set(timeout, 19);
|
||||
return;
|
||||
}
|
||||
r = timeout_recvfrom(udp_listen->fd, resp_buf, sizeof(resp_buf) - 1, &src, 1);
|
||||
if (r > 0) {
|
||||
stun_log(SINFO, "Binding listening CR: get UDP packet");
|
||||
struct stun_header *sh = (struct stun_header *)resp_buf;
|
||||
if (ntohs(sh->type) == BINDING_ERROR) {
|
||||
int code = stun_get_error_code(resp_buf);
|
||||
stun_log(SINFO, "get BINDING-ERROR: code is %d", code);
|
||||
if (udp_listen->br != NULL && stunid_cmp(&(sh->id), &(udp_listen->br->id)) == 0 && code == 401) {
|
||||
udp_listen->br->msg_integrity = 1;
|
||||
udp_listen->br->auth_fail++;
|
||||
stun_log(SINFO, "Cancel scheduled Keepalive Binding Request");
|
||||
uloop_timeout_cancel(&br_crport_keepalive.utimer);
|
||||
stun_log(SINFO, "Trying new Binding Request in %ds",
|
||||
(udp_listen->br->auth_fail < 3) ? 0 : (udp_listen->br->auth_fail - 2)*3);
|
||||
uloop_timeout_set(&udp_listen->br->utimer,
|
||||
(udp_listen->br->auth_fail < 3) ? 0 : ((udp_listen->br->auth_fail - 2) * 3000));
|
||||
udp_listen->br = NULL;
|
||||
}
|
||||
else if (code != 401) {
|
||||
stun_log(SINFO, "Unsupported error code");
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
else if (ntohs(sh->type) == BINDING_RESPONSE) {
|
||||
struct in_addr ip_addr;
|
||||
stun_log(SINFO, "get BINDING-RESPONSE");
|
||||
if (udp_listen->br != NULL && stunid_cmp(&(sh->id), &(udp_listen->br->id)) == 0) {
|
||||
udp_listen->br->resp_success = 1;
|
||||
udp_listen->br->msg_integrity = 0;
|
||||
udp_listen->br->auth_fail = 0;
|
||||
stun_get_mapped_address(resp_buf, &ip, &port);
|
||||
ip_addr.s_addr = ip;
|
||||
stun_log(SINFO, "Mapped Address is: %s:%u", inet_ntoa(ip_addr), ntohs(port));
|
||||
save_natdetected_var_state(ip);
|
||||
if (is_udpcr_changed(ip, port)) {
|
||||
env.address = ip;
|
||||
env.port = port;
|
||||
udp_listen->br->resp_success = 0;
|
||||
udp_listen->br->binding_change = 1;
|
||||
uloop_timeout_set(&udp_listen->br->utimer, 0);
|
||||
save_udpcr_var_state(ip, port);
|
||||
stun_notify(0);
|
||||
}
|
||||
else {
|
||||
udp_listen->br = NULL;
|
||||
}
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
else if (strstr(resp_buf, "http") || strstr(resp_buf, "HTTP")) {
|
||||
stun_log(SINFO, "get UDP Connection Request");
|
||||
handle_udp_cr(resp_buf);
|
||||
}
|
||||
else {
|
||||
stun_log(SINFO, "get non supported STUN/UDP message");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* timed out */
|
||||
if (!udp_listen->br || udp_listen->br->resp_success == 1)
|
||||
goto end;
|
||||
stun_log(SINFO, "Timed OUT!");
|
||||
udp_listen->br->resp_success--;
|
||||
if (udp_listen->br->resp_success < -2) {
|
||||
int rs = -udp_listen->br->resp_success;
|
||||
if ((rs % 9) == 0) {
|
||||
stun_log(SINFO, "Retry sending in a new socket");
|
||||
stun_close_socket(udp_listen);
|
||||
uloop_timeout_set(&udp_listen->br->utimer, 0);
|
||||
udp_listen->br = NULL;
|
||||
}
|
||||
else if ((rs % 3) == 0) {
|
||||
stun_log(SINFO, "Retry sending.");
|
||||
uloop_timeout_set(&udp_listen->br->utimer, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
uloop_timeout_set(timeout, 1);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
stun_log(SINFO, "Start stund daemon");
|
||||
config_init();
|
||||
keepalive_timeout = conf.min_keepalive;
|
||||
|
||||
uloop_init();
|
||||
uloop_timeout_set(&br_crport.utimer, 100);
|
||||
uloop_run();
|
||||
uloop_done();
|
||||
|
||||
config_fini();
|
||||
stun_log(SINFO, "Stop stund daemon");
|
||||
return 0;
|
||||
}
|
||||
106
stun/src/stun.h
Normal file
106
stun/src/stun.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef _STUN_H
|
||||
#define _STUN_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <libubox/uloop.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef container_of
|
||||
#define container_of(ptr, type, member) \
|
||||
({ \
|
||||
const typeof(((type *) NULL)->member) *__mptr = (ptr); \
|
||||
(type *) ((char *) __mptr - offsetof(type, member)); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#define binding_request_entry(X) container_of(X, struct binding_request, utimer)
|
||||
#define udp_listen_entry(X) container_of(X, struct udp_listen, utimer)
|
||||
|
||||
#define BINDING_REQUSET 0x0001
|
||||
#define BINDING_RESPONSE 0x0101
|
||||
#define BINDING_ERROR 0x0111
|
||||
|
||||
#define ATTR_MAPPED_ADDRESS 0x0001
|
||||
#define ATTR_RESPONSE_ADDRESS 0x0002
|
||||
#define ATTR_CHANGE_REQUEST 0x0003
|
||||
#define ATTR_SOURCE_ADDRESS 0x0004
|
||||
#define ATTR_CHANGED_ADDRESS 0x0005
|
||||
#define ATTR_USERNAME 0x0006
|
||||
#define ATTR_PASSWORD 0x0007
|
||||
#define ATTR_MESSAGE_INTEGRITY 0x0008
|
||||
#define ATTR_ERROR_CODE 0x0009
|
||||
#define ATTR_UNKNOWN_ATTRIBUTES 0x000a
|
||||
#define ATTR_REFLECTED_FROM 0x000b
|
||||
#define ATTR_CONNECTION_REQUEST_BINDING 0xC001
|
||||
#define ATTR_BINDING_CHANGE 0xC002
|
||||
|
||||
#define STUN_HEADER_LEN 20
|
||||
|
||||
struct binding_request;
|
||||
|
||||
typedef struct { unsigned int id[4]; } __attribute__((packed)) stunid;
|
||||
|
||||
struct udp_listen {
|
||||
stunid expected_id;
|
||||
int fd;
|
||||
struct uloop_timeout utimer;
|
||||
struct binding_request *br;
|
||||
};
|
||||
|
||||
struct binding_request {
|
||||
stunid id;
|
||||
unsigned char is_keealive;
|
||||
unsigned char msg_integrity; /* if true ==> MESSAGE-INTEGRITY should be append in the STUN msg */
|
||||
unsigned char binding_change; /* if true ==> BINDING-CHANGE should be append in the STUN msg */
|
||||
unsigned char binding_cr; /* if true ==> CONNECTION-REQUEST-BINDING should be append in the STUN msg */
|
||||
int resp_success;
|
||||
int auth_fail;
|
||||
int retry_interval;
|
||||
struct udp_listen *udp_listen;
|
||||
struct uloop_timeout utimer;
|
||||
};
|
||||
|
||||
|
||||
struct stun_header {
|
||||
unsigned short type;
|
||||
unsigned short len;
|
||||
stunid id;
|
||||
unsigned char stunmsg[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct stun_attribute {
|
||||
unsigned short type;
|
||||
unsigned short len;
|
||||
unsigned char value[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct stun_address {
|
||||
unsigned char na;
|
||||
unsigned char family;
|
||||
unsigned short port;
|
||||
unsigned int address;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct env_var {
|
||||
unsigned short port;
|
||||
unsigned int address;
|
||||
unsigned int last_ts;
|
||||
unsigned int last_crid;
|
||||
};
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _STUN_H */
|
||||
49
stun/src/stun.md
Normal file
49
stun/src/stun.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# README #
|
||||
|
||||
In order to reach the devices that are connected behind NAT, the cwmp protocol introduces alternative method of executing Connection Request via NAT based on STUN. The stund is an implementation of STUN functionality that performs this feature.
|
||||
|
||||
## Configuration File ##
|
||||
|
||||
The stund UCI configuration is located in **'/etc/config/stun'** and contains only one section **stun**:
|
||||
|
||||
```
|
||||
config stun 'stun'
|
||||
option enable '0'
|
||||
option username 'stun'
|
||||
option password 'stun'
|
||||
option server_address 'stun.l.google.com'
|
||||
option server_port '19302'
|
||||
option min_keepalive '30'
|
||||
option max_keepalive '3600'
|
||||
option client_port 7547
|
||||
option log_level '1'
|
||||
```
|
||||
|
||||
### stun section ###
|
||||
|
||||
It defines **the stun section configuration** (like username, password, etc...). The possible options for **stun** section are listed in the table below.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---------------- | ------- | ------------------------------------------------- |
|
||||
| `enable` | boolean | if set to **1**, the STUN client will be enabled. |
|
||||
| `username` | string | The STUN username to be used in Binding Requests. |
|
||||
| `password` | string | The STUN Password to be used in computing the MESSAGE-INTEGRITY. |
|
||||
| `server_address` | string | The host name or IP address of the STUN server to send Binding Requests. |
|
||||
| `server_port` | integer | The port number of the STUN server to send Binding Requests. |
|
||||
| `min_keepalive` | integer | The minimum period that STUN Binding Requests must be sent by the CPE for the purpose of maintaining the binding in the Gateway. |
|
||||
| `max_keepalive` | integer | The maximum period that STUN Binding Requests must be sent by the CPE for the purpose of maintaining the binding in the Gateway. |
|
||||
| `client_port` | integer | The client source port of the STUN UDP binding. |
|
||||
| `log_level` | integer | The log type to use, by default it is set to **'INFO'**. The possible types are **'EMERG', 'ALERT', 'CRITIC' ,'ERROR', 'WARNING', 'NOTICE', 'INFO' and 'DEBUG'**. |
|
||||
|
||||
## Dependencies ##
|
||||
|
||||
To successfully build stund, the following libraries are needed:
|
||||
|
||||
| Dependency | Link | License |
|
||||
| --------------- | ------------------------------------------- | -------------- |
|
||||
| libuci | https://git.openwrt.org/project/uci.git | LGPL 2.1 |
|
||||
| libubox | https://git.openwrt.org/project/libubox.git | BSD |
|
||||
| libubus | https://git.openwrt.org/project/ubus.git | LGPL 2.1 |
|
||||
| libjson-c | https://s3.amazonaws.com/json-c_releases | MIT |
|
||||
| libopenssl | http://ftp.fi.muni.cz/pub/openssl/source/ | OpenSSL |
|
||||
|
||||
108
stun/src/ubus.c
Normal file
108
stun/src/ubus.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* ubus.c -- This file conatains functions that allow to make ubus calls
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2020 iopsys Software Solutions AB. All rights reserved.
|
||||
*
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <json-c/json.h>
|
||||
#include <libubox/blobmsg_json.h>
|
||||
#include <libubus.h>
|
||||
|
||||
#include "ubus.h"
|
||||
|
||||
static struct ubus_context *ubus_ctx = NULL;
|
||||
static struct blob_buf b;
|
||||
|
||||
int subus_init(void)
|
||||
{
|
||||
ubus_ctx = ubus_connect(NULL);
|
||||
if (!ubus_ctx) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int subus_fini(void)
|
||||
{
|
||||
if (ubus_ctx) {
|
||||
ubus_free(ubus_ctx);
|
||||
}
|
||||
ubus_ctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sadd_json_obj(json_object *json_obj_out, char *object, char *string)
|
||||
{
|
||||
json_object *json_obj_tmp = json_object_new_string(string);
|
||||
json_object_object_add(json_obj_out, object, json_obj_tmp);
|
||||
}
|
||||
|
||||
static int subus_call_req(char *path, char *method, int argc, struct sarg sarg[])
|
||||
{
|
||||
uint32_t id;
|
||||
int i, r = 1;
|
||||
char *arg;
|
||||
|
||||
json_object *json_obj_out = json_object_new_object();
|
||||
if (json_obj_out == NULL)
|
||||
return r;
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
if (argc) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
sadd_json_obj(json_obj_out, sarg[i].key, sarg[i].val);
|
||||
}
|
||||
arg = (char *)json_object_to_json_string(json_obj_out);
|
||||
|
||||
if (!blobmsg_add_json_from_string(&b, arg)) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (ubus_lookup_id(ubus_ctx, path, &id))
|
||||
goto end;
|
||||
|
||||
r = ubus_invoke(ubus_ctx, id, method, b.head, NULL, NULL, 1);
|
||||
|
||||
end:
|
||||
json_object_put(json_obj_out);
|
||||
blob_buf_free(&b);
|
||||
return r;
|
||||
}
|
||||
|
||||
int subus_call(char *path, char *method, int argc, struct sarg dmarg[])
|
||||
{
|
||||
int r = -1;
|
||||
subus_init();
|
||||
if (ubus_ctx) {
|
||||
r = subus_call_req(path, method, argc, dmarg);
|
||||
if (r > 0) r = -1;
|
||||
}
|
||||
subus_fini();
|
||||
return r;
|
||||
}
|
||||
22
stun/src/ubus.h
Normal file
22
stun/src/ubus.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* TR-069 STUN client software
|
||||
* Copyright (C) 2020 PIVA SOFTWARE <www.pivasoftware.com> - All Rights Reserved
|
||||
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
|
||||
*/
|
||||
|
||||
#ifndef __SUBUS_H
|
||||
#define __SUBUS_H
|
||||
|
||||
#include <libubox/blobmsg_json.h>
|
||||
#include <json-c/json.h>
|
||||
#include <libubus.h>
|
||||
|
||||
struct sarg {
|
||||
char *key;
|
||||
char *val;
|
||||
};
|
||||
|
||||
#define UBUS_ARGS (struct sarg[])
|
||||
|
||||
int subus_call(char *path, char *method, int argc, struct sarg sarg[]);
|
||||
|
||||
#endif //__SUBUS_H
|
||||
@@ -6,10 +6,10 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=swmodd
|
||||
PKG_VERSION:=1.0.2
|
||||
PKG_VERSION:=1.1.0
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=3bfc97cd6f8e22f561601c47b79203b17fdb0fbe
|
||||
PKG_SOURCE_VERSION:=c8cc4a3b332ea931dbf2fe7e6b94bebf5c4bcc33
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/swmodd.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
|
||||
@@ -21,7 +21,7 @@ define Package/swmodd
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=SWMOD - software modules ubus backend
|
||||
DEPENDS:=+libuci +libubox +ubus +libuuid
|
||||
DEPENDS:=+libuci +libubox +ubus +libuuid +PACKAGE_liblxc:liblxc
|
||||
endef
|
||||
|
||||
define Package/swmodd/description
|
||||
@@ -32,6 +32,11 @@ TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include \
|
||||
-D_GNU_SOURCE
|
||||
|
||||
ifeq ($(CONFIG_PACKAGE_liblxc),y)
|
||||
MAKE_FLAGS += \
|
||||
SWMOD_LXC="yes"
|
||||
endif
|
||||
|
||||
define Package/swmodd/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/swmodd.init $(1)/etc/init.d/swmodd
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user