mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-31 00:29:54 +08:00
Compare commits
6 Commits
notificati
...
layer3ts
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fefbcdf9b3 | ||
|
|
d2ac9d5684 | ||
|
|
8d4293b22d | ||
|
|
2c05fcc08a | ||
|
|
14344b452c | ||
|
|
c3ac2d0b04 |
@@ -5,11 +5,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libbbfdm
|
||||
PKG_VERSION:=6.8.9.30
|
||||
PKG_VERSION:=6.8.9.25
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/bbf.git
|
||||
PKG_SOURCE_VERSION:=3d59cceff21f8e7ab43f4ff3e24def4d81ae0638
|
||||
PKG_SOURCE_VERSION:=e87b25b08294c608aef1e73d1268b35073097592
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dectmngr
|
||||
PKG_RELEASE:=3
|
||||
PKG_VERSION:=3.5.6
|
||||
PKG_VERSION:=3.5.5
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/dectmngr.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=81450033d98fcdb68911e2148f48d190492090a6
|
||||
PKG_SOURCE_VERSION:=cf4e91ffe0a1d83140fef5b41d16e581e5341cec
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=easy-soc-libs
|
||||
PKG_VERSION:=6.4.53
|
||||
PKG_VERSION:=6.4.52
|
||||
PKG_RELEASE:=1
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=7f2340c41e2fdf22419ee649a8661ef4cf5d2602
|
||||
PKG_SOURCE_VERSION:=822e9a50790970d14db254ffe3d7464709bcd3ca
|
||||
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
|
||||
|
||||
@@ -13,7 +13,7 @@ LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/endptmngr.git
|
||||
PKG_SOURCE_VERSION:=fb85081443c19b5062bede49c80b1802c0f05d34
|
||||
PKG_SOURCE_VERSION:=dc12712af8c4088f7873502ca845e51c68a1ada9
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=icwmp
|
||||
PKG_VERSION:=8.4.25.12
|
||||
PKG_VERSION:=8.4.25.10
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/icwmp.git
|
||||
PKG_SOURCE_VERSION:=71fb2cb9c579db5f12b502f7098aafb160e45590
|
||||
PKG_SOURCE_VERSION:=cb601366e6a91db532ba7d577f653a2b86c4a479
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
@@ -88,7 +88,6 @@ define Package/icwmp/default/install
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
|
||||
$(INSTALL_DIR) $(1)/etc/bbfdm/json/
|
||||
$(INSTALL_DIR) $(1)/etc/udhcpc.user.d
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/icwmpd $(1)/usr/sbin/icwmpd
|
||||
$(INSTALL_DATA) ./files/etc/config/cwmp $(1)/etc/config/cwmp
|
||||
$(INSTALL_BIN) ./files/etc/firewall.cwmp $(1)/etc/firewall.cwmp
|
||||
@@ -98,8 +97,6 @@ define Package/icwmp/default/install
|
||||
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/icwmp $(1)/lib/upgrade/keep.d/icwmp
|
||||
$(INSTALL_BIN) ./files/etc/icwmpd/update.sh $(1)/etc/icwmpd/update.sh
|
||||
$(INSTALL_DATA) ./files/etc/bbfdm/json/CWMPManagementServer.json $(1)/etc/bbfdm/json/
|
||||
$(INSTALL_BIN) ./files/etc/udhcpc.user.d/udhcpc_icwmp.user $(1)/etc/udhcpc.user.d/udhcpc_icwmp.user
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/files/etc/udhcpc.user.d/udhcpc_icwmp_opt43.user $(1)/etc/udhcpc.user.d/udhcpc_icwmp_opt43.user
|
||||
endef
|
||||
|
||||
Package/icwmp-openssl/install = $(Package/icwmp/default/install)
|
||||
|
||||
@@ -288,6 +288,12 @@ wait_for_resolvfile() {
|
||||
copy_cwmp_etc_files_to_varstate() {
|
||||
mkdir -p /var/run/icwmpd
|
||||
|
||||
if [ -f /etc/icwmpd/cwmp ]; then
|
||||
uci -q -c /etc/icwmpd delete cwmp.acs
|
||||
uci -q -c /etc/icwmpd commit cwmp
|
||||
cp -f /etc/icwmpd/cwmp /var/state/cwmp
|
||||
fi
|
||||
|
||||
if [ -f /etc/icwmpd/icwmpd_backup_session.xml ]; then
|
||||
cp -f /etc/icwmpd/icwmpd_backup_session.xml /var/run/icwmpd/ 2>/dev/null
|
||||
fi
|
||||
@@ -306,6 +312,12 @@ copy_cwmp_varstate_files_to_etc() {
|
||||
cp -f /var/run/icwmpd/dm_enabled_notify /etc/icwmpd/ 2>/dev/null
|
||||
fi
|
||||
|
||||
if [ -f /var/state/cwmp ]; then
|
||||
uci -q -c /var/state delete cwmp.sess_status
|
||||
uci -q -c /var/state commit cwmp
|
||||
cp -f /var/state/cwmp /etc/icwmpd/
|
||||
fi
|
||||
|
||||
# move the successful custom notify import marker to persistent storage
|
||||
if [ -f /var/run/icwmpd/icwmpd_notify_import_marker ]; then
|
||||
cp -f /var/run/icwmpd/icwmpd_notify_import_marker /etc/icwmpd/
|
||||
@@ -409,12 +421,6 @@ boot() {
|
||||
regenerate_ssl_link "${ssl_capath}"
|
||||
fi
|
||||
|
||||
# Copy backup data so that if it restart latter on it gets the info
|
||||
copy_cwmp_etc_files_to_varstate
|
||||
touch /etc/icwmpd/cwmp_notification
|
||||
mkdir -p /var/run/icwmpd/
|
||||
touch /var/run/icwmpd/cwmp
|
||||
|
||||
start
|
||||
}
|
||||
|
||||
@@ -437,6 +443,9 @@ start_service() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Copy backup data so that if it restart latter on it gets the info
|
||||
copy_cwmp_etc_files_to_varstate
|
||||
|
||||
procd_open_instance icwmp
|
||||
procd_set_param command "$PROG"
|
||||
procd_append_param command -b
|
||||
@@ -448,6 +457,11 @@ start_service() {
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_stopped()
|
||||
{
|
||||
copy_cwmp_varstate_files_to_etc
|
||||
}
|
||||
|
||||
stop_service()
|
||||
{
|
||||
copy_cwmp_varstate_files_to_etc
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
CLASS=""
|
||||
OUI=""
|
||||
SERIAL=""
|
||||
|
||||
get_vivsoi() {
|
||||
# opt125 environment variable has data in below format
|
||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
# | enterprise-number1 |
|
||||
# | |
|
||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
# | data-len1 | |
|
||||
# +-+-+-+-+-+-+-+-+ option-data1 |
|
||||
# / /
|
||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -----
|
||||
# | enterprise-number2 | ^
|
||||
# | | |
|
||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
||||
# | data-len2 | | optional
|
||||
# +-+-+-+-+-+-+-+-+ option-data2 | |
|
||||
# / / |
|
||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
||||
# ~ ... ~ V
|
||||
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -----
|
||||
|
||||
# Enterprise Id Len Sub Op SLen Data Sub Op SLen Data Sub Op SLen Data
|
||||
# +-------------+-----+------+------+----+------+-----+----+-----+------+-----+----+
|
||||
# | id | n | 1 | n1 | D1 | 2 | n2 | D2 | ... | 6 | n6 | D6 |
|
||||
# +-------------+-----+------+------+----+------+-----+----+-----+------+-----+----+
|
||||
|
||||
local opt125="$1"
|
||||
local len="$2"
|
||||
local ent_id
|
||||
|
||||
#hex-string 2 character=1 Byte
|
||||
# length in hex string will be twice of actual Byte length
|
||||
[ "$len" -gt "8" ] || return
|
||||
|
||||
data="${opt125}"
|
||||
rem_len="${len}"
|
||||
while [ $rem_len -gt 0 ]; do
|
||||
ent_id=${data:0:8}
|
||||
ent_id=$(printf "%d\n" "0x$ent_id")
|
||||
|
||||
if [ $ent_id -ne 3561 ]; then
|
||||
len_val=${data:8:2}
|
||||
data_len=$(printf "%d\n" "0x$len_val")
|
||||
# add 4 byte for ent_id and 1 byte for len
|
||||
data_len=$(( data_len * 2 + 10 ))
|
||||
# move ahead data to next enterprise id
|
||||
data=${data:"${data_len}":"${rem_len}"}
|
||||
rem_len=$(( rem_len - $data_len ))
|
||||
continue
|
||||
fi
|
||||
|
||||
# read the length of enterprise data
|
||||
len_val=${data:8:2}
|
||||
opt_len=$(printf "%d\n" "0x$len_val")
|
||||
[ $opt_len -eq 0 ] && return
|
||||
|
||||
# populate the option data of enterprise id
|
||||
sub_data_len=$(( opt_len * 2))
|
||||
# starting 10 means ahead of length field
|
||||
sub_data=${data:10:"${sub_data_len}"}
|
||||
|
||||
# parsing of suboption of option 125
|
||||
while [ $sub_data_len -gt 0 ]; do
|
||||
# get the suboption id
|
||||
sub_opt_id=${sub_data:0:2}
|
||||
sub_opt_id=$(printf "%d\n" "0x$sub_opt_id")
|
||||
|
||||
# get the length of suboption
|
||||
sub_opt_len=${sub_data:2:2}
|
||||
sub_opt_len=$(printf "%d\n" "0x$sub_opt_len")
|
||||
sub_opt_len=$(( sub_opt_len * 2 ))
|
||||
|
||||
# get the value of sub option starting 4 means starting after length
|
||||
sub_opt_val=${sub_data:4:${sub_opt_len}}
|
||||
|
||||
# assign the value found in sub option
|
||||
case "${sub_opt_id}" in
|
||||
"4") OUI=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
|
||||
;;
|
||||
"5") SERIAL=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
|
||||
;;
|
||||
"6") CLASS=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
|
||||
;;
|
||||
esac
|
||||
|
||||
# add 2 bytes for sub_opt id and sub_opt len field
|
||||
sub_opt_end=$(( sub_opt_len + 4 ))
|
||||
|
||||
# fetch next sub option hex string
|
||||
sub_data=${sub_data:${sub_opt_end}:${sub_data_len}}
|
||||
|
||||
# update the remaining sub option hex string length
|
||||
sub_data_len=$((sub_data_len - sub_opt_end))
|
||||
done
|
||||
|
||||
break
|
||||
done
|
||||
}
|
||||
|
||||
config_load cwmp
|
||||
config_get_bool enable_cwmp cpe enable 1
|
||||
config_get wan_intf cpe default_wan_interface "wan"
|
||||
|
||||
if [ "$enable_cwmp" = "0" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "${wan_intf}" == "${INTERFACE}" ]; then
|
||||
if [ -n "$opt125" ]; then
|
||||
len=$(printf "$opt125"|wc -c)
|
||||
get_vivsoi "$opt125" "$len"
|
||||
fi
|
||||
|
||||
mkdir -p /var/state
|
||||
touch /var/state/cwmp
|
||||
sec=$(uci -q -c /var/state get cwmp.gatewayinfo)
|
||||
if [ -z "${sec}" ]; then
|
||||
sec=$(uci -q -c /var/state add cwmp gatewayinfo)
|
||||
uci -q -c /var/state rename cwmp."${sec}"="gatewayinfo"
|
||||
fi
|
||||
|
||||
uci -q -c /var/state set cwmp.gatewayinfo.class="$CLASS"
|
||||
uci -q -c /var/state set cwmp.gatewayinfo.oui="$OUI"
|
||||
uci -q -c /var/state set cwmp.gatewayinfo.serial="$SERIAL"
|
||||
uci -q -c /var/state commit cwmp
|
||||
fi
|
||||
@@ -1,2 +1,2 @@
|
||||
/var/run/icwmpd/icwmpd_backup_session.xml
|
||||
/etc/icwmpd/cwmp_notifications
|
||||
/etc/icwmpd/cwmp
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ieee1905
|
||||
PKG_VERSION:=4.10.31
|
||||
PKG_VERSION:=4.10.28
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=3b932c967e9a54aa277521202d92411825b4fc91
|
||||
PKG_SOURCE_VERSION:=e10385f117bc20a8d16f1b57ad4f86d4a98552c0
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/ieee1905.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
@@ -44,8 +44,7 @@ validate_ap_section() {
|
||||
uci_validate_section ieee1905 $section "${1}" \
|
||||
'band:or("2", "5", "60")' \
|
||||
'ssid:string' \
|
||||
'encryption:or("psk2", "sae-mixed", "sae",
|
||||
"psk", "psk-mixed", "none", string)' \
|
||||
'encryption:or("psk2", "sae-mixed", "sae", string)' \
|
||||
'key:string' \
|
||||
'uuid:string' \
|
||||
'manufacturer:string' \
|
||||
|
||||
@@ -254,22 +254,11 @@ function genconfig {
|
||||
setup_dirs()
|
||||
{
|
||||
git remote -v | grep -q http || {
|
||||
CUSTBRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
||||
if git ls-remote $CUSTREPO -q 2>/dev/null; then
|
||||
if [ ! -d "$CUSTPATH" ]; then
|
||||
echo "Cloning $CUSTBRANCH branch of $CUSTREPO"
|
||||
git clone -b "$CUSTBRANCH" "$CUSTREPO" "$CUSTPATH" 2>/dev/null || {
|
||||
DEFBRANCH="$(git remote show $CUSTREPO | grep 'HEAD branch' | cut -d' ' -f5)"
|
||||
echo "$CUSTBRANCH branch is not found, cloning $DEFBRANCH branch of $CUSTREPO"
|
||||
git clone "$CUSTREPO" "$CUSTPATH"
|
||||
}
|
||||
git clone "$CUSTREPO" "$CUSTPATH"
|
||||
elif [ $IMPORT -eq 1 ]; then
|
||||
cd $CUSTPATH
|
||||
echo "Checking out $CUSTBRANCH branch in $CUSTPATH"
|
||||
git checkout "$CUSTBRANCH" 2>/dev/null || {
|
||||
DEFBRANCH="$(git symbolic-ref refs/remotes/origin/HEAD | cut -d '/' -f4)"
|
||||
echo "Checking out $CUSTBRANCH branch has failed, using $DEFBRANCH branch in $CUSTPATH"
|
||||
}
|
||||
v "git pull"
|
||||
git pull
|
||||
cd - >/dev/null #go back
|
||||
|
||||
@@ -170,6 +170,12 @@ function genconfig_min {
|
||||
|
||||
git remote -v | grep -qE '(git@|ssh://)' && {
|
||||
DEVELOPER=1
|
||||
|
||||
bcmAllowed=0
|
||||
endptAllowed=0
|
||||
|
||||
git ls-remote git@dev.iopsys.eu:broadcom/bcmcreator.git -q 2>/dev/null && bcmAllowed=1
|
||||
git ls-remote git@dev.iopsys.eu:iopsys/endptmngr.git -q 2>/dev/null && endptAllowed=1
|
||||
}
|
||||
|
||||
v() {
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=map-agent
|
||||
PKG_VERSION:=2.10.2.6
|
||||
PKG_VERSION:=2.10.2.2
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=4b86476466e63a42db2fcf89a064bde7d9a6dc2a
|
||||
PKG_SOURCE_VERSION:=4ed3f9bf0743086a85e1b7cf49c47eb49ab05015
|
||||
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
|
||||
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
|
||||
@@ -103,11 +103,7 @@ validate_radio_section() {
|
||||
'include_sta_metric:bool:false' \
|
||||
'rcpi_hysteresis_margin:range(0,255)' \
|
||||
'report_util_threshold:range(0,255)' \
|
||||
'encryption:or("sae", "sae+aes", "psk2",
|
||||
"psk2+aes", "sae-mixed", "sae-mixed+aes",
|
||||
"none", "psk-mixed", "psk-mixed+aes",
|
||||
"wpa", "wpa+aes", "wpa2", "wpa2+aes",
|
||||
"psk", "psk+aes")' \
|
||||
'encryption:or("sae", "psk2", "sae-mixed")'
|
||||
|
||||
[ "$?" -ne 0 ] && {
|
||||
logger -s -t "mapagent" "Validation of radio section failed"
|
||||
|
||||
@@ -23,51 +23,146 @@ EOF
|
||||
}
|
||||
|
||||
ts_create() {
|
||||
_net_setup() {
|
||||
net_check_for_vlan() {
|
||||
_dhcp_setup() {
|
||||
local name=$1
|
||||
|
||||
[ -n "$(uci -q get dhcp.${name})" ] && return
|
||||
|
||||
uci -q set dhcp.${name}=dhcp
|
||||
uci -q set dhcp.${name}.interface="${name}"
|
||||
uci -q set dhcp.${name}.start="100"
|
||||
uci -q set dhcp.${name}.limit="150"
|
||||
uci -q set dhcp.${name}.leasetime="1h"
|
||||
uci -q set dhcp.${name}.dhcpv4="server"
|
||||
uci -q set dhcp.${name}.dhcpv6="server"
|
||||
uci -q set dhcp.${name}.ra="server"
|
||||
uci -q set dhcp.${name}.ra_slaac="1"
|
||||
uci -q add_list dhcp.${name}.ra_flags="managed-config"
|
||||
uci -q add_list dhcp.${name}.ra_flags="other-config"
|
||||
|
||||
uci -q commit dhcp
|
||||
}
|
||||
|
||||
_firewall_setup() {
|
||||
local name=$1
|
||||
local network=$1
|
||||
local vid=$2
|
||||
local zone_exist=0
|
||||
|
||||
config_load firewall
|
||||
|
||||
_process_zone() {
|
||||
local section=$1
|
||||
local vid=$2
|
||||
local new_name=$2
|
||||
local name
|
||||
|
||||
config_get vlan "$section" vlan
|
||||
config_get name $section name
|
||||
|
||||
[ "$vid" = "$vlan" ] && {
|
||||
echo "1"
|
||||
break
|
||||
}
|
||||
[ "$name" == "$new_name" ] && zone_exist=1
|
||||
}
|
||||
|
||||
config_foreach _process_zone zone $name
|
||||
|
||||
[ "$zone_exist" != "0" ] && return
|
||||
|
||||
uci -q add firewall zone
|
||||
uci -q set firewall.@zone[-1].name="$name"
|
||||
uci -q add_list firewall.@zone[-1].network="$network"
|
||||
uci -q set firewall.@zone[-1].input='ACCEPT'
|
||||
uci -q set firewall.@zone[-1].output='ACCEPT'
|
||||
uci -q set firewall.@zone[-1].forward='ACCEPT'
|
||||
|
||||
uci -q add firewall forwarding
|
||||
uci -q set firewall.@forwarding[-1].src="$name"
|
||||
uci -q set firewall.@forwarding[-1].dest="wan"
|
||||
|
||||
uci -q commit firewall
|
||||
}
|
||||
|
||||
_guest_net_setup() {
|
||||
local vid=$1
|
||||
local name="guest${vid}"
|
||||
local dev="guest_dev${vid}"
|
||||
local br_guest="br-guest${vid}"
|
||||
local peer="guest_peer${vid}"
|
||||
local ip_addr="192.168.${vid}.1"
|
||||
local br_dev="${AL_BRIDGE/-/_}"
|
||||
|
||||
[ "${vid}" = "${PRIMARY_VID}" ] && return
|
||||
|
||||
ip link show $dev 2> /dev/null || {
|
||||
ip link add $dev type veth peer name $peer
|
||||
}
|
||||
|
||||
ip link set $dev up
|
||||
ip link set $port_dev up
|
||||
|
||||
[ -z "$(uci -q get network.${name})" ] || return
|
||||
|
||||
uci -q set network.${name}="interface"
|
||||
uci -q set network.${name}.device="${br_guest}"
|
||||
uci -q set network.${name}.is_lan="1"
|
||||
uci -q set network.${name}.proto="static"
|
||||
uci -q set network.${name}.ipaddr="${ip_addr}"
|
||||
uci -q set network.${name}.netmask="255.255.255.0"
|
||||
uci -q set network.${name}.ip6assign '60'
|
||||
|
||||
uci -q set network.br_${name}="device"
|
||||
uci -q set network.br_${name}.name="${br_guest}"
|
||||
uci -q set network.br_${name}.type="bridge"
|
||||
|
||||
if [ -z $(uci -q get network.${br_dev}.ports | grep -w ${dev}) ]; then
|
||||
uci -q add_list network.${br_dev}.ports="${dev}"
|
||||
fi
|
||||
|
||||
if [ -z $(uci -q get network.br_${name}.ports | grep -w ${peer}) ]; then
|
||||
uci -q add_list network.br_${name}.ports="${peer}"
|
||||
fi
|
||||
|
||||
if [ -z $(uci -q get network.vlan${vid}.ports | grep -w ${dev}) ]; then
|
||||
uci -q add_list network.vlan${vid}.ports="${dev}:*"
|
||||
fi
|
||||
|
||||
uci -q commit network
|
||||
}
|
||||
|
||||
_net_setup() {
|
||||
local vid=$1
|
||||
local layer3=$2
|
||||
local name="vlan${vid}"
|
||||
local br_dev="${AL_BRIDGE/-/_}"
|
||||
local tag=":t"
|
||||
local self_flags="untagged"
|
||||
local brvid_local="1"
|
||||
|
||||
config_load network
|
||||
|
||||
exists=$(config_foreach net_check_for_vlan bridge-vlan $vid)
|
||||
|
||||
[ -z "$exists" ] || return
|
||||
[ -z "$(uci -q get network.${name})" ] || return
|
||||
|
||||
uci -q set network.${name}="bridge-vlan"
|
||||
uci -q set network.${name}.name="${name}"
|
||||
uci -q set network.${name}.device="$AL_BRIDGE"
|
||||
uci -q set network.${name}.vlan="$vid"
|
||||
|
||||
[ "${vid}" = "${PRIMARY_VID}" ] && {
|
||||
if [ "${vid}" = "${PRIMARY_VID}" ]; then
|
||||
self_flags="untagged pvid"
|
||||
tag=":*"
|
||||
}
|
||||
elif [ -x "/usr/sbin/mapcontroller" -a "$layer3" = "1" ]; then
|
||||
brvid_local="0"
|
||||
fi
|
||||
|
||||
uci -q set network.${name}.flags="${self_flags}"
|
||||
uci -q set network.${name}.local='1'
|
||||
uci -q set network.${name}.local="${brvid_local}"
|
||||
|
||||
for port in $(uci -q get network.${br_dev}.ports) ; do
|
||||
if [ -x "/usr/sbin/mapcontroller" -a "$layer3" = "1" ]; then
|
||||
echo $port | grep "guest" && continue
|
||||
fi
|
||||
uci -q get network.${name}.ports | grep -q "${port}${tag}" && continue
|
||||
uci -q add_list network.${name}.ports="${port}${tag}"
|
||||
done
|
||||
|
||||
uci -q commit network
|
||||
}
|
||||
local layer3=$(uci -q get mapagent.agent.layer3_ts)
|
||||
|
||||
vid=$1
|
||||
|
||||
@@ -78,8 +173,15 @@ EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
_net_setup ${vid} ${layer3}
|
||||
|
||||
logger -t vlan "setup ts vid $vid"
|
||||
_net_setup ${vid}
|
||||
[ -x "/usr/sbin/mapcontroller" -a "$layer3" = "1" ] && {
|
||||
_dhcp_setup guest${vid}
|
||||
_firewall_setup guest${vid} ${vid}
|
||||
_guest_net_setup ${vid}
|
||||
|
||||
}
|
||||
|
||||
# Disable pktfwd here and flush FlowCache rules
|
||||
echo 0 > /proc/pktfwd_dhd/enable
|
||||
@@ -138,15 +240,32 @@ EOF
|
||||
# maintain VIDs passed as args in network config, remove rest
|
||||
ts_keep() {
|
||||
local al_bridge=$(uci -q get mapagent.agent.al_bridge)
|
||||
local layer3="$(uci -q get mapagent.agent.layer3_ts)"
|
||||
restart=""
|
||||
|
||||
[ "$al_bridge" = "" ] && al_bridge="br-lan"
|
||||
|
||||
|
||||
guest_teardown() {
|
||||
local section=$1
|
||||
local config=$2
|
||||
local bridge=$3
|
||||
local option=$4
|
||||
|
||||
config_get name "$section" "$option"
|
||||
|
||||
[ "$bridge" != "$name" ] && continue
|
||||
|
||||
uci -q delete ${config}.${section}
|
||||
}
|
||||
|
||||
bridge_vlan_teardown() {
|
||||
local section=$1
|
||||
shift
|
||||
local bridge=$1
|
||||
shift
|
||||
local layer3=$1
|
||||
shift
|
||||
local keep="$@"
|
||||
|
||||
config_get device "$section" device
|
||||
@@ -161,15 +280,39 @@ EOF
|
||||
fi
|
||||
done
|
||||
|
||||
#if layer3ts enabled
|
||||
if [ -x "/usr/sbin/mapcontroller" -a "$layer3" = "1" ]; then
|
||||
local br_guest="br-guest${vlan}"
|
||||
|
||||
config_load network
|
||||
config_foreach guest_teardown device "network" $br_guest "name" $@ # could easier be replaced by uci ubus api and using match field
|
||||
config_foreach guest_teardown interface "network" $br_guest "device" $@ # could easier be replaced by uci ubus api and using match field
|
||||
|
||||
config_load dhcp
|
||||
[ -n "$(uci -q get dhcp.guest${vlan})" ] && {
|
||||
uci -q delete dhcp.guest${vlan}
|
||||
restart="1"
|
||||
}
|
||||
config_load firewall
|
||||
config_foreach guest_teardown zone "firewall" guest${vlan} "name" $@ #delete firewall section with name = guest${vlan}
|
||||
config_foreach guest_teardown forwarding "firewall" guest${vlan} "src" $@ #delete firewall section with name = guest${vlan}
|
||||
fi
|
||||
|
||||
|
||||
#endif
|
||||
uci -q delete network.$section
|
||||
restart="1"
|
||||
}
|
||||
|
||||
config_load network
|
||||
config_foreach bridge_vlan_teardown bridge-vlan $al_bridge $@
|
||||
(config_foreach bridge_vlan_teardown bridge-vlan $al_bridge $layer3 $@)
|
||||
|
||||
if [ "$restart" = "1" ]; then
|
||||
uci commit network
|
||||
if [ -x "/usr/sbin/mapcontroller" -a "$layer3" = "1" ]; then
|
||||
uci commit firewall
|
||||
uci commit dhcp
|
||||
fi
|
||||
dbg "trigger network restart"
|
||||
/etc/init.d/network restart
|
||||
fi
|
||||
@@ -177,6 +320,7 @@ EOF
|
||||
|
||||
ts_cleanup() {
|
||||
local al_bridge=$(uci -q get mapagent.agent.al_bridge)
|
||||
local layer3="$(uci -q get mapagent.agent.layer3_ts)"
|
||||
restart=""
|
||||
|
||||
[ "$al_bridge" = "" ] && al_bridge="br-lan"
|
||||
@@ -184,19 +328,86 @@ EOF
|
||||
bridge_device_teardown() {
|
||||
local section=$1
|
||||
local bridge=$2
|
||||
local layer3=$3
|
||||
local br_dev="${AL_BRIDGE/-/_}"
|
||||
local dev
|
||||
local br_guest
|
||||
local peer
|
||||
|
||||
config_get device "$section" device
|
||||
config_get vlan "$section" vlan
|
||||
|
||||
dev="guest_dev${vlan}"
|
||||
|
||||
[ "$bridge" != "$device" ] && continue
|
||||
|
||||
uci -q delete network.$section
|
||||
restart="1"
|
||||
|
||||
echo "restart"
|
||||
|
||||
[ -x "/usr/sbin/mapcontroller" -a "$layer3" = "1" ] || continue
|
||||
|
||||
####
|
||||
# layer3 specific teardown
|
||||
####
|
||||
|
||||
guest_teardown() {
|
||||
local section=$1
|
||||
local config=$2
|
||||
local bridge=$3
|
||||
local option=$4
|
||||
|
||||
config_get name "$section" "$option"
|
||||
|
||||
[ "$bridge" != "$name" ] && continue
|
||||
|
||||
echo "$bridge=$name" > /dev/console
|
||||
|
||||
uci -q delete ${config}.${section}
|
||||
echo "uci -q delete ${config}.${section}" > /dev/console
|
||||
}
|
||||
|
||||
br_guest="br-guest${vlan}"
|
||||
|
||||
# network config guest teardown
|
||||
config_load network
|
||||
config_foreach guest_teardown device "network" $br_guest "name"
|
||||
config_foreach guest_teardown interface "network" $br_guest "device"
|
||||
|
||||
if [ -n "$(uci -q get network.${br_dev}.ports | grep -w ${dev})" ]; then
|
||||
uci -q del_list network.${br_dev}.ports="${dev}"
|
||||
fi
|
||||
|
||||
peer="guest_peer${vlan}"
|
||||
|
||||
ip link show $dev 2> /dev/null && {
|
||||
ip link del $dev
|
||||
}
|
||||
|
||||
ip link show $peer 2> /dev/null && {
|
||||
ip link del $peer
|
||||
}
|
||||
|
||||
# dhcp config guest teardown
|
||||
[ -n "$(uci -q get dhcp.guest${vlan})" ] && {
|
||||
uci -q delete dhcp.guest${vlan}
|
||||
}
|
||||
|
||||
# firewall config guest teardown
|
||||
config_load firewall
|
||||
config_foreach guest_teardown zone "firewall" guest${vlan} "name"
|
||||
config_foreach guest_teardown forwarding "firewall" guest${vlan} "src"
|
||||
}
|
||||
|
||||
config_load network
|
||||
config_foreach bridge_device_teardown bridge-vlan $al_bridge
|
||||
restart="$(config_foreach bridge_device_teardown bridge-vlan $al_bridge $layer3)"
|
||||
|
||||
if [ "$restart" = "1" ]; then
|
||||
if [ -n "$restart" ]; then
|
||||
uci commit network
|
||||
if [ -x "/usr/sbin/mapcontroller" -a "$layer3" = "1" ]; then
|
||||
uci commit firewall
|
||||
uci commit dhcp
|
||||
fi
|
||||
dbg "trigger network restart"
|
||||
/etc/init.d/network restart
|
||||
fi
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=map-controller
|
||||
PKG_VERSION:=2.8.0.17
|
||||
PKG_VERSION:=2.8.0.15
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=bd6faf13bf57e9b78a6dba29bf6e8f8e531fed91
|
||||
PKG_SOURCE_VERSION:=e71a5f4f7f947f4c7819b4caf238fd1bec9b4fe8
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
|
||||
@@ -26,11 +26,7 @@ validate_controller_section() {
|
||||
'use_usta_metrics:bool:false' \
|
||||
'allow_bgdfs:range(0,2629744)' \
|
||||
'channel_plan:range(0,2629744)' \
|
||||
'enable_ts:bool:false' \
|
||||
'rcpi_threshold_2g:range(0,220)' \
|
||||
'rcpi_threshold_5g:range(0,220)' \
|
||||
'report_rcpi_threshold_2g:range(0,220)' \
|
||||
'report_rcpi_threshold_5g:range(0,220)'
|
||||
'enable_ts:bool:false'
|
||||
|
||||
[ "$?" -ne 0 ] && {
|
||||
logger -s -t "mapcontroller" "Validation of controller section failed"
|
||||
@@ -47,10 +43,7 @@ validate_ap_section() {
|
||||
'band:or("2", "5")' \
|
||||
'ssid:string' \
|
||||
'encryption:or("sae", "sae+aes", "psk2",
|
||||
"psk2+aes", "sae-mixed", "sae-mixed+aes",
|
||||
"none", "psk-mixed", "psk-mixed+aes",
|
||||
"wpa", "wpa+aes", "wpa2", "wpa2+aes",
|
||||
"psk", "psk+aes")' \
|
||||
"psk2+aes", "sae-mixed", "sae-mixed+aes")' \
|
||||
'key:string' \
|
||||
'vid:range(1,65535):1' \
|
||||
'type:or("backhaul", "fronthaul", "combined")' \
|
||||
|
||||
@@ -6,11 +6,11 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=map-topology
|
||||
PKG_VERSION:=2.5.0.14
|
||||
PKG_VERSION:=2.5.0.13
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_VERSION:=b7985e2d564754acf00def2e98f8594f85219258
|
||||
PKG_SOURCE_VERSION:=413330b08fc4608ea2f5f740cf829f62d5a8bba0
|
||||
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
|
||||
|
||||
@@ -72,9 +72,6 @@ start_service() {
|
||||
config_load "hosts"
|
||||
validate_hosts_config || return 1;
|
||||
|
||||
if [ -f "/proc/sys/net/netfilter/nf_conntrack_timestamp" ]; then
|
||||
echo 1 >/proc/sys/net/netfilter/nf_conntrack_timestamp
|
||||
fi
|
||||
procd_open_instance
|
||||
procd_set_param command "/usr/sbin/topologyd"
|
||||
procd_set_param respawn
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=obuspa
|
||||
PKG_VERSION:=5.0.0.16.6
|
||||
PKG_VERSION:=5.0.0.16.5
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=6477337ec0d5dd6fa5586b42ba6423a892643106
|
||||
PKG_SOURCE_VERSION:=b0626e54ba4a0e8d1d261948a7114c6dc35e2dbc
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/fork/obuspa.git
|
||||
PKG_MAINTAINER:=Vivek Dutta <vivek.dutta@iopsys.eu>
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2022 OpenWrt.org
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ssdpd
|
||||
PKG_VERSION:=1.0.4
|
||||
|
||||
LOCAL_DEV:=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/miniupnp/miniupnp.git
|
||||
PKG_SOURCE_VERSION:=207cf440a22c075cb55fb067a850be4f9c204e6e
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
endif
|
||||
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ssdpd
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+libnfnetlink +libpthread +libubox +libubus +libblobmsg-json +libcurl +mxml
|
||||
TITLE:=MiniSSDPd - SSDP daemon
|
||||
URL:=https://miniupnp.tuxfamily.org/minissdpd.html
|
||||
endef
|
||||
|
||||
MAKE_PATH:=minissdpd
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-D_GNU_SOURCE \
|
||||
-Wall -Wextra -Werror
|
||||
|
||||
TARGET_LDFLAGS += \
|
||||
-lpthread -lubox -lubus -lblobmsg_json -lcurl -lmxml
|
||||
|
||||
ifeq ($(LOCAL_DEV),1)
|
||||
define Build/Prepare
|
||||
$(CP) -rf ~/git/sspd/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
endif
|
||||
|
||||
define Package/ssdpd/install
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_CONF) ./files/etc/config/ssdpd $(1)/etc/config/ssdpd
|
||||
$(INSTALL_BIN) ./files/etc/init.d/ssdpd $(1)/etc/init.d/ssdpd
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/minissdpd/minissdpd $(1)/usr/sbin/ssdpd
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ssdpd))
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
config ssdpd 'ssdp'
|
||||
option enabled '1'
|
||||
option ipv6_enabled '0'
|
||||
option socket_path '/var/run/minissdpd.sock'
|
||||
option ttl '2'
|
||||
option interface 'br-lan'
|
||||
option debug '0'
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
STOP=02
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/usr/sbin/ssdpd
|
||||
|
||||
log() {
|
||||
echo "${@}"|logger -t ssdpd.init -p info
|
||||
}
|
||||
|
||||
validate_ssdpd_ssdp_section()
|
||||
{
|
||||
uci_validate_section ssdpd ssdpd "ssdp" \
|
||||
'enabled:bool:true' \
|
||||
'debug:bool:false' \
|
||||
'ipv6_enabled:bool:false' \
|
||||
'socket_path:string' \
|
||||
'ttl:uinteger' \
|
||||
'interface:string'
|
||||
}
|
||||
|
||||
configure_ssdp()
|
||||
{
|
||||
local enabled ipv6_enabled socket_path ttl interface
|
||||
|
||||
config_load ssdpd
|
||||
|
||||
validate_ssdpd_ssdp_section || {
|
||||
log "Validation of ssdp section failed"
|
||||
return 1;
|
||||
}
|
||||
|
||||
[ ${enabled} -eq 0 ] && return 0
|
||||
|
||||
mkdir -p /tmp/ssdp/description/
|
||||
|
||||
procd_set_param command ${PROG}
|
||||
|
||||
if [ ${ipv6_enabled} -eq 1 ]; then
|
||||
procd_append_param command -6
|
||||
fi
|
||||
|
||||
if [ ${debug} -eq 1 ]; then
|
||||
procd_append_param command -d
|
||||
fi
|
||||
|
||||
if [ -n "${socket_path}" ]; then
|
||||
procd_append_param command -s ${socket_path}
|
||||
fi
|
||||
|
||||
if [ -n "${ttl}" ]; then
|
||||
procd_append_param command -t ${ttl}
|
||||
fi
|
||||
|
||||
# If no interface is given defaults for br-lan
|
||||
procd_append_param command -i ${interface:-br-lan}
|
||||
}
|
||||
|
||||
start_service() {
|
||||
procd_open_instance ssdp
|
||||
configure_ssdp
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "ssdpd"
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
--- a/minissdpd/openssdpsocket.c
|
||||
+++ b/minissdpd/openssdpsocket.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
+#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
--- a/minissdpd/ifacewatch.c
|
||||
+++ b/minissdpd/ifacewatch.c
|
||||
@@ -130,6 +130,7 @@ ProcessInterfaceWatch(int s, int s_ssdp,
|
||||
/* case RTM_DELLINK: */
|
||||
case RTM_DELADDR:
|
||||
is_del = 1;
|
||||
+ // fall through
|
||||
case RTM_NEWADDR:
|
||||
/* http://linux-hacks.blogspot.fr/2009/01/sample-code-to-learn-netlink.html */
|
||||
ifa = (struct ifaddrmsg *)NLMSG_DATA(nlhdr);
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/minissdpd/Makefile
|
||||
+++ b/minissdpd/Makefile
|
||||
@@ -41,7 +41,7 @@ endif
|
||||
EXECUTABLES = minissdpd testminissdpd testcodelength \
|
||||
showminissdpdnotif
|
||||
MINISSDPDOBJS = minissdpd.o openssdpsocket.o daemonize.o upnputils.o \
|
||||
- ifacewatch.o getroute.o getifaddr.o asyncsendto.o
|
||||
+ ifacewatch.o getroute.o getifaddr.o asyncsendto.o ssdpd.o
|
||||
TESTMINISSDPDOBJS = testminissdpd.o printresponse.o
|
||||
SHOWMINISSDPDNOTIFOBJS = showminissdpdnotif.o printresponse.o
|
||||
|
||||
@@ -1,629 +0,0 @@
|
||||
--- /dev/null
|
||||
+++ b/minissdpd/ssdpd.c
|
||||
@@ -0,0 +1,626 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2022 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 Romdhane <amin.benromdhane@iopsys.eu>
|
||||
+ */
|
||||
+
|
||||
+#include <unistd.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <sys/un.h>
|
||||
+#include <net/if.h>
|
||||
+#include <syslog.h>
|
||||
+
|
||||
+#include <curl/curl.h>
|
||||
+#include <libubox/uloop.h>
|
||||
+#include <libubox/blobmsg_json.h>
|
||||
+#include <libubox/list.h>
|
||||
+#include <libubus.h>
|
||||
+#include <mxml.h>
|
||||
+
|
||||
+#include "codelength.h"
|
||||
+
|
||||
+struct UPNPDev {
|
||||
+ struct list_head list;
|
||||
+ char *descURL;
|
||||
+ char *st;
|
||||
+ char *usn;
|
||||
+};
|
||||
+
|
||||
+struct desc_list_elt {
|
||||
+ struct list_head list;
|
||||
+ char *url;
|
||||
+ char *desc_path;
|
||||
+ bool is_device_desc;
|
||||
+};
|
||||
+
|
||||
+#define UPNP_DESC_PATH "/etc/upnp/description"
|
||||
+#define UPNP_DISCOVER_TIMEOUT (30 * 1000)
|
||||
+
|
||||
+#ifndef MIN
|
||||
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
+#endif /* MIN */
|
||||
+
|
||||
+/* macros used to read from unix socket */
|
||||
+#define READ_BYTE_BUFFER(c) \
|
||||
+ if ((int)bufferindex >= n) { \
|
||||
+ n = read(s, buffer, sizeof(buffer)); \
|
||||
+ if (n <= 0) break; \
|
||||
+ bufferindex = 0; \
|
||||
+ } \
|
||||
+ c = buffer[bufferindex++];
|
||||
+
|
||||
+#define READ_COPY_BUFFER(dst, len) \
|
||||
+ for (l = len, p = (unsigned char *)dst; l > 0; ) { \
|
||||
+ unsigned int lcopy; \
|
||||
+ if ((int)bufferindex >= n) { \
|
||||
+ n = read(s, buffer, sizeof(buffer)); \
|
||||
+ if ( n<= 0) break; \
|
||||
+ bufferindex = 0; \
|
||||
+ } \
|
||||
+ lcopy = MIN(l, (n - bufferindex)); \
|
||||
+ memcpy(p, buffer + bufferindex, lcopy); \
|
||||
+ l -= lcopy; \
|
||||
+ p += lcopy; \
|
||||
+ bufferindex += lcopy; \
|
||||
+ }
|
||||
+
|
||||
+LIST_HEAD(dev_list);
|
||||
+LIST_HEAD(desc_list);
|
||||
+
|
||||
+char *ssdp_sockpath = NULL;
|
||||
+
|
||||
+static void upnp_discover_devices(struct uloop_timeout *timeout);
|
||||
+static struct uloop_timeout upnpdiscover_timer = { .cb = upnp_discover_devices };
|
||||
+
|
||||
+static void add_dev_to_dev_list(char *descURL, char *st, char *usn)
|
||||
+{
|
||||
+ struct UPNPDev *dev = NULL;
|
||||
+
|
||||
+ dev = calloc(1, sizeof(struct UPNPDev));
|
||||
+ list_add_tail(&dev->list, &dev_list);
|
||||
+
|
||||
+ dev->descURL = descURL;
|
||||
+ dev->st = st;
|
||||
+ dev->usn = usn;
|
||||
+}
|
||||
+
|
||||
+void free_all_dev_list(void)
|
||||
+{
|
||||
+ struct UPNPDev *dev = NULL;
|
||||
+
|
||||
+ while (dev_list.next != &dev_list) {
|
||||
+ dev = list_entry(dev_list.next, struct UPNPDev, list);
|
||||
+ free(dev->descURL);
|
||||
+ free(dev->st);
|
||||
+ free(dev->usn);
|
||||
+ free(dev);
|
||||
+ list_del(&dev->list);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int connectToMiniSSDPD(void)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ struct sockaddr_un addr;
|
||||
+
|
||||
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ if(s < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ char *ssdp_s = ssdp_sockpath ? ssdp_sockpath : "/var/run/minissdpd.sock";
|
||||
+
|
||||
+ memset(&addr, 0, sizeof(addr));
|
||||
+ addr.sun_family = AF_UNIX;
|
||||
+
|
||||
+ strncpy(addr.sun_path, ssdp_s, sizeof(addr.sun_path));
|
||||
+
|
||||
+ if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
|
||||
+ close(s);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return s;
|
||||
+}
|
||||
+
|
||||
+static int disconnectFromMiniSSDPD(int s)
|
||||
+{
|
||||
+ if (close(s) < 0)
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int requestDevicesFromMiniSSDPD(int s)
|
||||
+{
|
||||
+ unsigned char buffer[256];
|
||||
+ unsigned char *p = NULL;
|
||||
+ unsigned int stsize = 0, l = 0;
|
||||
+ char *devtype = "ssdp:all";
|
||||
+
|
||||
+ buffer[0] = 3; /* request type 3 : everything */
|
||||
+ stsize = strlen(devtype);
|
||||
+
|
||||
+ p = buffer + 1;
|
||||
+ l = stsize; CODELENGTH(l, p);
|
||||
+ if (p + stsize > buffer + sizeof(buffer))
|
||||
+ return -1;
|
||||
+
|
||||
+ memcpy(p, devtype, stsize);
|
||||
+ p += stsize;
|
||||
+ if (write(s, buffer, p - buffer) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int receiveDevicesFromMiniSSDPD(int s)
|
||||
+{
|
||||
+ unsigned char buffer[256];
|
||||
+ ssize_t n;
|
||||
+ unsigned char *p;
|
||||
+ unsigned int bufferindex;
|
||||
+ unsigned int i, ndev;
|
||||
+ unsigned int urlsize, stsize, usnsize, l;
|
||||
+ char *url, *st, *usn;
|
||||
+
|
||||
+ n = read(s, buffer, sizeof(buffer));
|
||||
+ if (n <= 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ ndev = buffer[0];
|
||||
+ bufferindex = 1;
|
||||
+ for (i = 0; i < ndev; i++) {
|
||||
+ DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER);
|
||||
+ if (n <= 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ url = (char *)malloc(urlsize);
|
||||
+ if (url == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ READ_COPY_BUFFER(url, urlsize);
|
||||
+ if (n <= 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ DECODELENGTH_READ(stsize, READ_BYTE_BUFFER);
|
||||
+ if (n <= 0)
|
||||
+ goto free_url_and_return;
|
||||
+
|
||||
+ st = (char *)malloc(stsize);
|
||||
+ if (st == NULL)
|
||||
+ goto free_url_and_return;
|
||||
+
|
||||
+ READ_COPY_BUFFER(st, stsize);
|
||||
+ if (n <= 0)
|
||||
+ goto free_url_and_st_and_return;
|
||||
+
|
||||
+ DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER);
|
||||
+ if (n <= 0)
|
||||
+ goto free_url_and_st_and_return;
|
||||
+
|
||||
+ usn = (char *)malloc(usnsize);
|
||||
+ if (usn == NULL)
|
||||
+ goto free_url_and_st_and_return;
|
||||
+
|
||||
+ READ_COPY_BUFFER(usn, usnsize);
|
||||
+ if (n <= 0)
|
||||
+ goto free_url_and_st_and_usn_and_return;
|
||||
+
|
||||
+ add_dev_to_dev_list(url, st, usn);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+free_url_and_st_and_usn_and_return:
|
||||
+ free(usn);
|
||||
+free_url_and_st_and_return:
|
||||
+ free(st);
|
||||
+free_url_and_return:
|
||||
+ free(url);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static int getDevicesFromMiniSSDPD(void)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ int res = 0;
|
||||
+
|
||||
+ s = connectToMiniSSDPD();
|
||||
+ if (s < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ res = requestDevicesFromMiniSSDPD(s);
|
||||
+ if (res < 0)
|
||||
+ goto close_socket_and_return;
|
||||
+
|
||||
+ res = receiveDevicesFromMiniSSDPD(s);
|
||||
+
|
||||
+close_socket_and_return:
|
||||
+ disconnectFromMiniSSDPD(s);
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+static void download_file(char *file_path, const char *url)
|
||||
+{
|
||||
+ CURL *curl = curl_easy_init();
|
||||
+ if (curl) {
|
||||
+ curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, 500);
|
||||
+
|
||||
+ FILE *fp = fopen(file_path, "wb");
|
||||
+ if (fp) {
|
||||
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
+ curl_easy_perform(curl);
|
||||
+ fclose(fp);
|
||||
+ }
|
||||
+
|
||||
+ curl_easy_cleanup(curl);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static bool is_desc_exist(const char *desc_url)
|
||||
+{
|
||||
+ struct desc_list_elt *desc_elt = NULL;
|
||||
+
|
||||
+ if (!desc_url)
|
||||
+ return false;
|
||||
+
|
||||
+ list_for_each_entry(desc_elt, &desc_list, list) {
|
||||
+ if (strcmp(desc_elt->url, desc_url) == 0)
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static void get_desc_name(const char *desc_url, char *str, size_t len)
|
||||
+{
|
||||
+ if (!desc_url || !str || len == 0)
|
||||
+ return;
|
||||
+
|
||||
+ char *p = strstr(desc_url, "://");
|
||||
+
|
||||
+ snprintf(str, len, "%s", p ? p + 3 : desc_url);
|
||||
+
|
||||
+ for (int i = 0; str[i]; i++) {
|
||||
+ if (str[i] == '/')
|
||||
+ str[i] = '_';
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void add_desc_to_desc_list(const char *desc_path, const char *url, int is_device_desc)
|
||||
+{
|
||||
+ struct desc_list_elt *desc_elt;
|
||||
+
|
||||
+ desc_elt = calloc(1, sizeof(struct desc_list_elt));
|
||||
+ list_add_tail(&desc_elt->list, &desc_list);
|
||||
+
|
||||
+ desc_elt->desc_path = strdup(desc_path);
|
||||
+ desc_elt->url = strdup(url);
|
||||
+ desc_elt->is_device_desc = is_device_desc;
|
||||
+}
|
||||
+
|
||||
+static void free_all_desc_list(void)
|
||||
+{
|
||||
+ struct desc_list_elt *desc_elt = NULL;
|
||||
+
|
||||
+ while (desc_list.next != &desc_list) {
|
||||
+ desc_elt = list_entry(desc_list.next, struct desc_list_elt, list);
|
||||
+ free(desc_elt->desc_path);
|
||||
+ free(desc_elt->url);
|
||||
+ free(desc_elt);
|
||||
+ list_del(&desc_elt->list);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void __upnp_discover_devices(void)
|
||||
+{
|
||||
+ struct UPNPDev *dev = NULL;
|
||||
+ char desc_name[128] = {0};
|
||||
+ char file_path[256] = {0};
|
||||
+ int res = 0, is_device_desc = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Discover devices
|
||||
+ */
|
||||
+ if (!list_empty(&dev_list))
|
||||
+ free_all_dev_list();
|
||||
+
|
||||
+ res = getDevicesFromMiniSSDPD();
|
||||
+ if (res)
|
||||
+ goto end;
|
||||
+
|
||||
+ /*
|
||||
+ * Download description files
|
||||
+ */
|
||||
+ list_for_each_entry_reverse(dev, &dev_list, list) {
|
||||
+
|
||||
+ if (is_desc_exist(dev->descURL))
|
||||
+ continue;
|
||||
+
|
||||
+ get_desc_name(dev->descURL, desc_name, sizeof(desc_name));
|
||||
+ snprintf(file_path, sizeof(file_path), "%s/%s", UPNP_DESC_PATH, desc_name);
|
||||
+ is_device_desc = (dev->usn && strstr(dev->usn, ":service:")) ? 0 : 1;
|
||||
+
|
||||
+ // Download Description
|
||||
+ download_file(file_path, dev->descURL);
|
||||
+
|
||||
+ // Add description to descriptions list
|
||||
+ add_desc_to_desc_list(file_path, dev->descURL, is_device_desc);
|
||||
+ }
|
||||
+
|
||||
+end:
|
||||
+ uloop_timeout_set(&upnpdiscover_timer, UPNP_DISCOVER_TIMEOUT);
|
||||
+}
|
||||
+
|
||||
+static int upnp_discovery_res(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)),
|
||||
+ struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg __attribute__((unused)))
|
||||
+{
|
||||
+ struct blob_buf bb = {0};
|
||||
+ struct UPNPDev *dev = NULL;
|
||||
+
|
||||
+ memset(&bb,0,sizeof(struct blob_buf));
|
||||
+ blob_buf_init(&bb, 0);
|
||||
+
|
||||
+ void *devices_array = blobmsg_open_array(&bb, "devices");
|
||||
+ list_for_each_entry_reverse(dev, &dev_list, list) {
|
||||
+ // Parse Root device and devices
|
||||
+ if ((dev->st && strstr(dev->st, ":rootdevice") != NULL) || (dev->usn && strstr(dev->usn, ":device:") != NULL)) {
|
||||
+ void *device_obj = blobmsg_open_table(&bb, NULL);
|
||||
+ blobmsg_add_string(&bb, "descurl", dev->descURL);
|
||||
+ blobmsg_add_string(&bb, "st", dev->st);
|
||||
+ blobmsg_add_string(&bb, "usn", dev->usn);
|
||||
+ blobmsg_add_string(&bb, "is_root_device", dev->st && strstr(dev->st, ":rootdevice") ? "1" : "0");
|
||||
+ blobmsg_close_table(&bb, device_obj);
|
||||
+ }
|
||||
+ }
|
||||
+ blobmsg_close_array(&bb, devices_array);
|
||||
+
|
||||
+ void *services_array = blobmsg_open_array(&bb, "services");
|
||||
+ list_for_each_entry_reverse(dev, &dev_list, list) {
|
||||
+ // Parse Services
|
||||
+ if (dev->usn && strstr(dev->usn, ":service:") != NULL) {
|
||||
+ void *service_obj = blobmsg_open_table(&bb, NULL);
|
||||
+ blobmsg_add_string(&bb, "descurl", dev->descURL);
|
||||
+ blobmsg_add_string(&bb, "st", dev->st);
|
||||
+ blobmsg_add_string(&bb, "usn", dev->usn);
|
||||
+ blobmsg_close_table(&bb, service_obj);
|
||||
+ }
|
||||
+ }
|
||||
+ blobmsg_close_array(&bb, services_array);
|
||||
+
|
||||
+ ubus_send_reply(ctx, req, bb.head);
|
||||
+ blob_buf_free(&bb);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void fill_device_instances(struct blob_buf *bb, mxml_node_t *device)
|
||||
+{
|
||||
+ void *device_obj = NULL;
|
||||
+ mxml_node_t *b = device;
|
||||
+ char buf[64] = {0};
|
||||
+ bool new_device_discovery = false;
|
||||
+
|
||||
+ while (b) {
|
||||
+
|
||||
+ if (mxmlGetType(b) != MXML_ELEMENT) {
|
||||
+ b = mxmlWalkNext(b, device, MXML_DESCEND);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ const char *elm_name = mxmlGetElement(b);
|
||||
+ const char *elm_val = mxmlGetOpaque(b);
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "device") == 0) {
|
||||
+
|
||||
+ if (new_device_discovery && device_obj)
|
||||
+ blobmsg_close_table(bb, device_obj);
|
||||
+
|
||||
+ device_obj = blobmsg_open_table(bb, NULL);
|
||||
+ blobmsg_add_string(bb, "parent_dev", buf);
|
||||
+ new_device_discovery = true;
|
||||
+ }
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "deviceType") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "deviceType", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "friendlyName") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "friendlyName", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "manufacturer") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "manufacturer", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "manufacturerURL") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "manufacturerURL", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "modelDescription") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "modelDescription", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "modelName") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "modelName", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "modelNumber") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "modelNumber", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "modelURL") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "modelURL", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "serialNumber") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "serialNumber", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "UDN") == 0 && new_device_discovery) {
|
||||
+ snprintf(buf, sizeof(buf), "%s", elm_val ? elm_val : "");
|
||||
+ blobmsg_add_string(bb, "UDN", buf);
|
||||
+ }
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "UPC") == 0 && new_device_discovery)
|
||||
+ blobmsg_add_string(bb, "UPC", elm_val ? elm_val : "");
|
||||
+
|
||||
+ b = mxmlWalkNext(b, device, MXML_DESCEND);
|
||||
+ }
|
||||
+
|
||||
+ if (new_device_discovery && device_obj)
|
||||
+ blobmsg_close_table(bb, device_obj);
|
||||
+}
|
||||
+
|
||||
+static void fill_service_element(struct blob_buf *bb, mxml_node_t *service)
|
||||
+{
|
||||
+ mxml_node_t *b = service;
|
||||
+ void *service_obj = NULL;
|
||||
+ char buf[64] = {0};
|
||||
+ bool new_srv_discovery = false;
|
||||
+
|
||||
+ while (b) {
|
||||
+
|
||||
+ if (mxmlGetType(b) != MXML_ELEMENT) {
|
||||
+ b = mxmlWalkNext(b, service, MXML_DESCEND);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ const char *elm_name = mxmlGetElement(b);
|
||||
+ const char *elm_val = mxmlGetOpaque(b);
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "UDN") == 0)
|
||||
+ snprintf(buf, sizeof(buf), "%s", elm_val ? elm_val : "");
|
||||
+
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "service") == 0) {
|
||||
+
|
||||
+ if (new_srv_discovery && service_obj)
|
||||
+ blobmsg_close_table(bb, service_obj);
|
||||
+
|
||||
+ service_obj = blobmsg_open_table(bb, NULL);
|
||||
+ blobmsg_add_string(bb, "parent_dev", buf);
|
||||
+ new_srv_discovery = true;
|
||||
+ }
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "serviceType") == 0 && new_srv_discovery)
|
||||
+ blobmsg_add_string(bb, "serviceType", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "serviceId") == 0 && new_srv_discovery)
|
||||
+ blobmsg_add_string(bb, "serviceId", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "SCPDURL") == 0 && new_srv_discovery)
|
||||
+ blobmsg_add_string(bb, "SCPDURL", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "controlURL") == 0 && new_srv_discovery)
|
||||
+ blobmsg_add_string(bb, "controlURL", elm_val ? elm_val : "");
|
||||
+
|
||||
+ if (elm_name && strcmp(elm_name, "eventSubURL") == 0 && new_srv_discovery)
|
||||
+ blobmsg_add_string(bb, "eventSubURL", elm_val ? elm_val : "");
|
||||
+
|
||||
+ b = mxmlWalkNext(b, service, MXML_DESCEND);
|
||||
+ }
|
||||
+
|
||||
+ if (new_srv_discovery && service_obj)
|
||||
+ blobmsg_close_table(bb, service_obj);
|
||||
+}
|
||||
+
|
||||
+static int upnp_description_res(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)),
|
||||
+ struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg __attribute__((unused)))
|
||||
+{
|
||||
+ struct desc_list_elt *desc_elt = NULL;
|
||||
+ struct blob_buf bb = {0};
|
||||
+
|
||||
+ memset(&bb,0,sizeof(struct blob_buf));
|
||||
+ blob_buf_init(&bb, 0);
|
||||
+
|
||||
+ void *desc_array = blobmsg_open_array(&bb, "descriptions");
|
||||
+ list_for_each_entry(desc_elt, &desc_list, list) {
|
||||
+ void *device_obj = blobmsg_open_table(&bb, NULL);
|
||||
+ blobmsg_add_string(&bb, "desc_url", desc_elt->url);
|
||||
+ blobmsg_add_u32(&bb, "is_device_desc", desc_elt->is_device_desc);
|
||||
+ blobmsg_close_table(&bb, device_obj);
|
||||
+
|
||||
+ }
|
||||
+ blobmsg_close_array(&bb, desc_array);
|
||||
+
|
||||
+ list_for_each_entry(desc_elt, &desc_list, list) {
|
||||
+
|
||||
+ FILE *fp = fopen(desc_elt->desc_path, "r");
|
||||
+ if (!fp)
|
||||
+ continue;
|
||||
+
|
||||
+ mxml_node_t *tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ if (tree) {
|
||||
+ void *devices_array = blobmsg_open_array(&bb, "devices");
|
||||
+ mxml_node_t *device = mxmlFindElement(tree, tree, "device", NULL, NULL, MXML_DESCEND);
|
||||
+ fill_device_instances(&bb, device);
|
||||
+ blobmsg_close_array(&bb, devices_array);
|
||||
+
|
||||
+ void *services_array = blobmsg_open_array(&bb, "services");
|
||||
+ mxml_node_t *service = mxmlFindElement(tree, tree, "device", NULL, NULL, MXML_DESCEND);
|
||||
+ fill_service_element(&bb, service);
|
||||
+ blobmsg_close_array(&bb, services_array);
|
||||
+
|
||||
+ mxmlDelete(tree);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ubus_send_reply(ctx, req, bb.head);
|
||||
+ blob_buf_free(&bb);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct ubus_method upnp_methods[] = {
|
||||
+ UBUS_METHOD_NOARG("discovery", upnp_discovery_res),
|
||||
+ UBUS_METHOD_NOARG("description", upnp_description_res),
|
||||
+};
|
||||
+
|
||||
+static struct ubus_object_type upnp_type = UBUS_OBJECT_TYPE("upnp", upnp_methods);
|
||||
+
|
||||
+static void upnp_discover_devices(struct uloop_timeout *timeout __attribute__((unused)))
|
||||
+{
|
||||
+ __upnp_discover_devices();
|
||||
+}
|
||||
+
|
||||
+static struct ubus_object upnp_object = {
|
||||
+ .name = "upnp",
|
||||
+ .type = &upnp_type,
|
||||
+ .methods = upnp_methods,
|
||||
+ .n_methods = ARRAY_SIZE(upnp_methods),
|
||||
+};
|
||||
+
|
||||
+void upnp_thread_discover_devices(void)
|
||||
+{
|
||||
+ struct ubus_context *ctx = NULL;
|
||||
+ const char *ubus_socket = NULL;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ uloop_init();
|
||||
+
|
||||
+ ctx = ubus_connect(ubus_socket);
|
||||
+ if (!ctx) {
|
||||
+ syslog(LOG_ERR, "Failed to connect to ubus\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ubus_add_uloop(ctx);
|
||||
+
|
||||
+ __upnp_discover_devices();
|
||||
+
|
||||
+ ret = ubus_add_object(ctx, &upnp_object);
|
||||
+ if (ret) {
|
||||
+ syslog(LOG_ERR, "Failed to add 'upnp' ubus object: %s\n", ubus_strerror(ret));
|
||||
+ goto end;
|
||||
+ }
|
||||
+
|
||||
+ uloop_run();
|
||||
+
|
||||
+end:
|
||||
+ free_all_desc_list();
|
||||
+ free_all_dev_list();
|
||||
+ uloop_done();
|
||||
+ ubus_free(ctx);
|
||||
+}
|
||||
@@ -1,311 +0,0 @@
|
||||
--- a/minissdpd/minissdpd.c
|
||||
+++ b/minissdpd/minissdpd.c
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#endif
|
||||
+/* for uloop thread */
|
||||
+#include <pthread.h>
|
||||
|
||||
/* LOG_PERROR does not exist on Solaris */
|
||||
#ifndef LOG_PERROR
|
||||
@@ -52,6 +54,10 @@
|
||||
#define MIN(x,y) (((x)<(y))?(x):(y))
|
||||
#endif
|
||||
|
||||
+extern char *ssdp_sockpath;
|
||||
+void upnp_thread_discover_devices(void);
|
||||
+void ssdpd_ubus_stop(void);
|
||||
+
|
||||
/* current request management structure */
|
||||
struct reqelem {
|
||||
int socket;
|
||||
@@ -1220,6 +1226,12 @@ static void ssdpDiscover(int s, int ipv6
|
||||
}
|
||||
}
|
||||
|
||||
+static void *thread_discover_devices(void *args __attribute__((unused)))
|
||||
+{
|
||||
+ upnp_thread_discover_devices();
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
/* main(): program entry point */
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
@@ -1264,6 +1276,7 @@ int main(int argc, char * * argv)
|
||||
unsigned char ttl = 2; /* UDA says it should default to 2 */
|
||||
const char * searched_device = NULL; /* if not NULL, search/filter a specific device type */
|
||||
int opt;
|
||||
+ pthread_t upnp_thread;
|
||||
|
||||
LIST_INIT(&reqlisthead);
|
||||
LIST_INIT(&servicelisthead);
|
||||
@@ -1309,6 +1322,7 @@ int main(int argc, char * * argv)
|
||||
break;
|
||||
case 's':
|
||||
sockpath = optarg;
|
||||
+ ssdp_sockpath = optarg;
|
||||
break;
|
||||
#ifndef NO_BACKGROUND_NO_PIDFILE
|
||||
case 'p':
|
||||
@@ -1496,6 +1510,11 @@ int main(int argc, char * * argv)
|
||||
if(s_ssdp6 >= 0)
|
||||
ssdpDiscover(s_ssdp6, 1, searched_device);
|
||||
|
||||
+ int err = pthread_create(&upnp_thread, NULL, &thread_discover_devices, NULL);
|
||||
+ if (err < 0) {
|
||||
+ syslog(LOG_ERR, "Error when creating upnp thread");
|
||||
+ }
|
||||
+
|
||||
/* Main loop */
|
||||
while(!quitting) {
|
||||
/* fill readfds fd_set */
|
||||
@@ -1704,6 +1723,8 @@ quit:
|
||||
if(unlink(pidfilename) < 0)
|
||||
syslog(LOG_ERR, "unlink(%s): %m", pidfilename);
|
||||
#endif
|
||||
+ ssdpd_ubus_stop();
|
||||
+ pthread_join(upnp_thread, NULL);
|
||||
closelog();
|
||||
return ret;
|
||||
}
|
||||
--- a/minissdpd/ssdpd.c
|
||||
+++ b/minissdpd/ssdpd.c
|
||||
@@ -39,10 +39,9 @@ struct desc_list_elt {
|
||||
struct list_head list;
|
||||
char *url;
|
||||
char *desc_path;
|
||||
- bool is_device_desc;
|
||||
};
|
||||
|
||||
-#define UPNP_DESC_PATH "/etc/upnp/description"
|
||||
+#define UPNP_DESC_PATH "/tmp/ssdp/description"
|
||||
#define UPNP_DISCOVER_TIMEOUT (30 * 1000)
|
||||
|
||||
#ifndef MIN
|
||||
@@ -282,6 +281,21 @@ static bool is_desc_exist(const char *de
|
||||
return false;
|
||||
}
|
||||
|
||||
+static bool is_device_exist(const char *dev_url)
|
||||
+{
|
||||
+ struct UPNPDev *dev = NULL;
|
||||
+
|
||||
+ if (!dev_url)
|
||||
+ return false;
|
||||
+
|
||||
+ list_for_each_entry(dev, &dev_list, list) {
|
||||
+ if (strcmp(dev->descURL, dev_url) == 0)
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static void get_desc_name(const char *desc_url, char *str, size_t len)
|
||||
{
|
||||
if (!desc_url || !str || len == 0)
|
||||
@@ -297,7 +311,7 @@ static void get_desc_name(const char *de
|
||||
}
|
||||
}
|
||||
|
||||
-static void add_desc_to_desc_list(const char *desc_path, const char *url, int is_device_desc)
|
||||
+static void add_desc_to_desc_list(const char *desc_path, const char *url)
|
||||
{
|
||||
struct desc_list_elt *desc_elt;
|
||||
|
||||
@@ -306,7 +320,6 @@ static void add_desc_to_desc_list(const
|
||||
|
||||
desc_elt->desc_path = strdup(desc_path);
|
||||
desc_elt->url = strdup(url);
|
||||
- desc_elt->is_device_desc = is_device_desc;
|
||||
}
|
||||
|
||||
static void free_all_desc_list(void)
|
||||
@@ -324,10 +337,12 @@ static void free_all_desc_list(void)
|
||||
|
||||
static void __upnp_discover_devices(void)
|
||||
{
|
||||
+ struct desc_list_elt *desc_elt = NULL;
|
||||
+ struct desc_list_elt *desc_elt_tmp = NULL;
|
||||
struct UPNPDev *dev = NULL;
|
||||
char desc_name[128] = {0};
|
||||
char file_path[256] = {0};
|
||||
- int res = 0, is_device_desc = 0;
|
||||
+ int res = 0;
|
||||
|
||||
/*
|
||||
* Discover devices
|
||||
@@ -349,13 +364,26 @@ static void __upnp_discover_devices(void
|
||||
|
||||
get_desc_name(dev->descURL, desc_name, sizeof(desc_name));
|
||||
snprintf(file_path, sizeof(file_path), "%s/%s", UPNP_DESC_PATH, desc_name);
|
||||
- is_device_desc = (dev->usn && strstr(dev->usn, ":service:")) ? 0 : 1;
|
||||
|
||||
// Download Description
|
||||
download_file(file_path, dev->descURL);
|
||||
|
||||
// Add description to descriptions list
|
||||
- add_desc_to_desc_list(file_path, dev->descURL, is_device_desc);
|
||||
+ add_desc_to_desc_list(file_path, dev->descURL);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Remove unused descriptions
|
||||
+ */
|
||||
+ list_for_each_entry_safe(desc_elt, desc_elt_tmp, &desc_list, list) {
|
||||
+
|
||||
+ if (is_device_exist(desc_elt->url))
|
||||
+ continue;
|
||||
+
|
||||
+ free(desc_elt->desc_path);
|
||||
+ free(desc_elt->url);
|
||||
+ free(desc_elt);
|
||||
+ list_del(&desc_elt->list);
|
||||
}
|
||||
|
||||
end:
|
||||
@@ -371,15 +399,27 @@ static int upnp_discovery_res(struct ubu
|
||||
memset(&bb,0,sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
+ void *root_devices_array = blobmsg_open_array(&bb, "root_devices");
|
||||
+ list_for_each_entry_reverse(dev, &dev_list, list) {
|
||||
+ // Parse root device
|
||||
+ if (dev->st && strstr(dev->st, ":rootdevice") != NULL) {
|
||||
+ void *device_obj = blobmsg_open_table(&bb, NULL);
|
||||
+ blobmsg_add_string(&bb, "descurl", dev->descURL);
|
||||
+ blobmsg_add_string(&bb, "st", dev->st);
|
||||
+ blobmsg_add_string(&bb, "usn", dev->usn);
|
||||
+ blobmsg_close_table(&bb, device_obj);
|
||||
+ }
|
||||
+ }
|
||||
+ blobmsg_close_array(&bb, root_devices_array);
|
||||
+
|
||||
void *devices_array = blobmsg_open_array(&bb, "devices");
|
||||
list_for_each_entry_reverse(dev, &dev_list, list) {
|
||||
- // Parse Root device and devices
|
||||
- if ((dev->st && strstr(dev->st, ":rootdevice") != NULL) || (dev->usn && strstr(dev->usn, ":device:") != NULL)) {
|
||||
+ // Parse devices
|
||||
+ if (dev->usn && strstr(dev->usn, ":device:") != NULL) {
|
||||
void *device_obj = blobmsg_open_table(&bb, NULL);
|
||||
blobmsg_add_string(&bb, "descurl", dev->descURL);
|
||||
blobmsg_add_string(&bb, "st", dev->st);
|
||||
blobmsg_add_string(&bb, "usn", dev->usn);
|
||||
- blobmsg_add_string(&bb, "is_root_device", dev->st && strstr(dev->st, ":rootdevice") ? "1" : "0");
|
||||
blobmsg_close_table(&bb, device_obj);
|
||||
}
|
||||
}
|
||||
@@ -472,7 +512,7 @@ static void fill_device_instances(struct
|
||||
blobmsg_close_table(bb, device_obj);
|
||||
}
|
||||
|
||||
-static void fill_service_element(struct blob_buf *bb, mxml_node_t *service)
|
||||
+static void fill_service_instances(struct blob_buf *bb, mxml_node_t *service)
|
||||
{
|
||||
mxml_node_t *b = service;
|
||||
void *service_obj = NULL;
|
||||
@@ -525,6 +565,32 @@ static void fill_service_element(struct
|
||||
blobmsg_close_table(bb, service_obj);
|
||||
}
|
||||
|
||||
+static void fill_device_service_instances(struct blob_buf *bb, bool is_device)
|
||||
+{
|
||||
+ struct desc_list_elt *desc_elt = NULL;
|
||||
+
|
||||
+ list_for_each_entry(desc_elt, &desc_list, list) {
|
||||
+
|
||||
+ FILE *fp = fopen(desc_elt->desc_path, "r");
|
||||
+ if (!fp)
|
||||
+ continue;
|
||||
+
|
||||
+ mxml_node_t *tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ if (tree) {
|
||||
+ mxml_node_t *node = mxmlFindElement(tree, tree, "device", NULL, NULL, MXML_DESCEND);
|
||||
+
|
||||
+ if (is_device)
|
||||
+ fill_device_instances(bb, node);
|
||||
+ else
|
||||
+ fill_service_instances(bb, node);
|
||||
+
|
||||
+ mxmlDelete(tree);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int upnp_description_res(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)),
|
||||
struct ubus_request_data *req, const char *method __attribute__((unused)), struct blob_attr *msg __attribute__((unused)))
|
||||
{
|
||||
@@ -534,39 +600,25 @@ static int upnp_description_res(struct u
|
||||
memset(&bb,0,sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
+ // Descriptions Array
|
||||
void *desc_array = blobmsg_open_array(&bb, "descriptions");
|
||||
list_for_each_entry(desc_elt, &desc_list, list) {
|
||||
void *device_obj = blobmsg_open_table(&bb, NULL);
|
||||
blobmsg_add_string(&bb, "desc_url", desc_elt->url);
|
||||
- blobmsg_add_u32(&bb, "is_device_desc", desc_elt->is_device_desc);
|
||||
blobmsg_close_table(&bb, device_obj);
|
||||
|
||||
}
|
||||
blobmsg_close_array(&bb, desc_array);
|
||||
|
||||
- list_for_each_entry(desc_elt, &desc_list, list) {
|
||||
-
|
||||
- FILE *fp = fopen(desc_elt->desc_path, "r");
|
||||
- if (!fp)
|
||||
- continue;
|
||||
-
|
||||
- mxml_node_t *tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK);
|
||||
- fclose(fp);
|
||||
-
|
||||
- if (tree) {
|
||||
- void *devices_array = blobmsg_open_array(&bb, "devices");
|
||||
- mxml_node_t *device = mxmlFindElement(tree, tree, "device", NULL, NULL, MXML_DESCEND);
|
||||
- fill_device_instances(&bb, device);
|
||||
- blobmsg_close_array(&bb, devices_array);
|
||||
-
|
||||
- void *services_array = blobmsg_open_array(&bb, "services");
|
||||
- mxml_node_t *service = mxmlFindElement(tree, tree, "device", NULL, NULL, MXML_DESCEND);
|
||||
- fill_service_element(&bb, service);
|
||||
- blobmsg_close_array(&bb, services_array);
|
||||
+ // Devices Array
|
||||
+ void *devices_array = blobmsg_open_array(&bb, "devices");
|
||||
+ fill_device_service_instances(&bb, true);
|
||||
+ blobmsg_close_array(&bb, devices_array);
|
||||
|
||||
- mxmlDelete(tree);
|
||||
- }
|
||||
- }
|
||||
+ // Services Array
|
||||
+ void *services_array = blobmsg_open_array(&bb, "services");
|
||||
+ fill_device_service_instances(&bb, false);
|
||||
+ blobmsg_close_array(&bb, services_array);
|
||||
|
||||
ubus_send_reply(ctx, req, bb.head);
|
||||
blob_buf_free(&bb);
|
||||
@@ -624,3 +676,8 @@ end:
|
||||
uloop_done();
|
||||
ubus_free(ctx);
|
||||
}
|
||||
+
|
||||
+void ssdpd_ubus_stop(void)
|
||||
+{
|
||||
+ uloop_end();
|
||||
+}
|
||||
+
|
||||
--- a/minissdpd/config.h
|
||||
+++ b/minissdpd/config.h
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
/* When NO_BACKGROUND_NO_PIDFILE is defined, minissdpd does not go to
|
||||
* background and does not create any pidfile */
|
||||
-/*#define NO_BACKGROUND_NO_PIDFILE*/
|
||||
+#define NO_BACKGROUND_NO_PIDFILE
|
||||
|
||||
/* define HAVE_IP_MREQN to use struct ip_mreqn instead of struct ip_mreq
|
||||
* for setsockopt(IP_MULTICAST_IF). Available with Linux 2.4+,
|
||||
@@ -5,11 +5,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=sulu
|
||||
PKG_VERSION:=1.3.26
|
||||
PKG_VERSION:=1.3.15
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/websdk/sulu.git
|
||||
PKG_SOURCE_VERSION:=6d6848119bffdbe0ec9b8116caf6375749299dc0
|
||||
PKG_SOURCE_VERSION:=81d4bb268914dc3822293e93519ae6adbd6ddbea
|
||||
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_SOURCE_VERSION)
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wfadatad
|
||||
PKG_VERSION:=2.10.0.8
|
||||
PKG_VERSION:=2.10.0.6
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=0f30582473eed26864f243eae22d21bc54e1faea
|
||||
PKG_SOURCE_VERSION:=70cc85371e2fa8e1eedf3601eaed03fe0bc2fe96
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/wfadatad.git
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wifimngr
|
||||
PKG_VERSION:=14.0.10
|
||||
PKG_VERSION:=14.0.9
|
||||
|
||||
LOCAL_DEV=0
|
||||
ifneq ($(LOCAL_DEV),1)
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=b6481f096228da9805ff159d17ddac4dbce0e1ab
|
||||
PKG_SOURCE_VERSION:=c14a18402bc3abf4098916fefe6dafd0873c4586
|
||||
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/wifimngr.git
|
||||
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
|
||||
|
||||
Reference in New Issue
Block a user