mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
362 lines
8.2 KiB
Bash
362 lines
8.2 KiB
Bash
#!/bin/sh
|
|
|
|
. /lib/functions.sh
|
|
. /usr/share/libubox/jshn.sh
|
|
|
|
CLASS=""
|
|
OUI=""
|
|
SERIAL=""
|
|
GW_DISCOVERED=0
|
|
_json_no_warning=1
|
|
|
|
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}
|
|
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 ))
|
|
|
|
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 '')
|
|
GW_DISCOVERED=1
|
|
;;
|
|
"5")
|
|
SERIAL=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
|
|
GW_DISCOVERED=1
|
|
;;
|
|
"6")
|
|
CLASS=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
|
|
GW_DISCOVERED=1
|
|
;;
|
|
esac
|
|
|
|
# add 2 bytes for sub_opt id and sub_opt len field
|
|
sub_opt_end=$(( sub_opt_len + 4 ))
|
|
|
|
# update the remaining sub option hex string length
|
|
sub_data_len=$((sub_data_len - sub_opt_end))
|
|
|
|
# fetch next sub option hex string
|
|
sub_data=${sub_data:"${sub_opt_end}":"${sub_data_len}"}
|
|
done
|
|
|
|
# move ahead data to next enterprise id
|
|
data=${data:"${data_len}":"${rem_len}"}
|
|
rem_len=$(( rem_len - data_len ))
|
|
done
|
|
}
|
|
|
|
send_host_query() {
|
|
intf="${1}"
|
|
resp=1
|
|
loop=3
|
|
usp_serv_found=0
|
|
sent_host=" "
|
|
|
|
ubus call umdns update
|
|
while [ "${loop}" -ne 0 ]; do
|
|
sleep 5
|
|
|
|
json_load "$(ubus call umdns browse)"
|
|
if ! json_select discovered_services; then
|
|
json_cleanup
|
|
loop=$(( loop - 1 ))
|
|
continue
|
|
fi
|
|
|
|
if ! json_select _usp-agt-mqtt._tcp; then
|
|
json_cleanup
|
|
loop=$(( loop - 1 ))
|
|
continue
|
|
fi
|
|
|
|
usp_serv_found=1
|
|
break
|
|
done
|
|
|
|
if [ "${usp_serv_found}" -eq 0 ]; then
|
|
echo "${resp}"
|
|
return 0
|
|
fi
|
|
|
|
json_get_keys keys
|
|
for key in $keys; do
|
|
json_select "${key}"
|
|
json_get_var _host host ""
|
|
|
|
if [ -z "${_host}" ] || [[ "${sent_host}" =~ " ${_host}" ]]; then
|
|
json_select ..
|
|
continue
|
|
fi
|
|
|
|
sent_host="${sent_host} ${_host}"
|
|
cmd="ubus call umdns query '{\"question\":\"$_host\",\"interface\":\"$intf\"}'"
|
|
sh -c "${cmd}"
|
|
resp=0
|
|
json_select ..
|
|
sleep 2 # umdns query sometime takes time to resolve so adding some sleep
|
|
done
|
|
|
|
json_cleanup
|
|
echo "${resp}"
|
|
}
|
|
|
|
get_usp_agent_id() {
|
|
dhcp_ip="${1}"
|
|
family="ipv4"
|
|
ID=""
|
|
|
|
if [[ "${dhcp_ip}" =~ ":" ]]; then
|
|
family="ipv6"
|
|
fi
|
|
|
|
json_load "$(ubus call umdns browse)"
|
|
if ! json_select discovered_services; then
|
|
json_cleanup
|
|
echo "${ID}"
|
|
return 0
|
|
fi
|
|
|
|
if ! json_select _usp-agt-mqtt._tcp; then
|
|
json_cleanup
|
|
echo "${ID}"
|
|
return 0
|
|
fi
|
|
|
|
json_get_keys keys
|
|
for key in $keys; do
|
|
json_select "${key}"
|
|
if ! json_select "${family}"; then
|
|
json_select ..
|
|
continue
|
|
fi
|
|
|
|
json_get_keys ips
|
|
for ip in $ips; do
|
|
json_get_var ip_val "${ip}"
|
|
if [ "${ip_val}" != "${dhcp_ip}" ]; then
|
|
continue
|
|
fi
|
|
|
|
json_select ..
|
|
json_select txt
|
|
json_get_keys txts
|
|
for _txt in $txts; do
|
|
json_get_var text_val "${_txt}"
|
|
if [[ "${text_val:0:3}" = "ID=" ]]; then
|
|
ID="${text_val:3}"
|
|
break
|
|
fi
|
|
done
|
|
|
|
break
|
|
done
|
|
|
|
json_select ..
|
|
json_select ..
|
|
|
|
if [ -n "${ID}" ]; then
|
|
break
|
|
fi
|
|
done
|
|
|
|
json_cleanup
|
|
echo "${ID}"
|
|
}
|
|
|
|
get_mac_address() {
|
|
ip="${1}"
|
|
device="${2}"
|
|
|
|
mac=$(grep "${ip}" /proc/net/arp | awk '{print $4}')
|
|
if [ -z "${mac}" ]; then
|
|
arp_resp=$(arping -b -f -c 5 -I "${device}" "${ip}" | grep 'Unicast reply from' | awk '{print $5}')
|
|
if [ -n "${arp_resp}" ]; then
|
|
mac=${arp_resp:1:-1}
|
|
fi
|
|
fi
|
|
|
|
echo "${mac}"
|
|
}
|
|
|
|
send_unknown_gw_event() {
|
|
mac="${1}"
|
|
|
|
cmd="ubus -t 5 send gateway-info.gateway.unknown '{\"hwaddr\":\"$mac\"}'"
|
|
sh -c "${cmd}"
|
|
}
|
|
|
|
send_cwmp_gw_event() {
|
|
oui="${1}"
|
|
class="${2}"
|
|
serial="${3}"
|
|
|
|
cmd="ubus -t 5 send gateway-info.gateway.cwmp '{\"oui\":\"$oui\",\"class\":\"$class\",\"serial\":\"$serial\"}'"
|
|
sh -c "${cmd}"
|
|
}
|
|
|
|
send_usp_gw_event() {
|
|
endpoint="${1}"
|
|
|
|
cmd="ubus -t 5 send gateway-info.gateway.usp '{\"endpoint\":\"$endpoint\"}'"
|
|
sh -c "${cmd}"
|
|
}
|
|
|
|
config_load gateway
|
|
config_get_bool enable global enable '1'
|
|
config_get wan_intf global wan_interface "wan"
|
|
|
|
if [ "${enable}" -eq 0 ]; then
|
|
return 0
|
|
fi
|
|
|
|
if [ "${wan_intf}" = "${INTERFACE}" ]; then
|
|
if [ "${1}" = "deconfig" ]; then
|
|
rm -rf /var/state/gwinfo
|
|
return 0
|
|
fi
|
|
|
|
json_load "$(ifstatus "${INTERFACE}")"
|
|
json_get_var dev_name device ""
|
|
json_select data
|
|
json_get_var dhcp_ip dhcpserver ""
|
|
json_cleanup
|
|
|
|
if [ -z "${dhcp_ip}" ] || [ -z "${dev_name}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
MAC=$(get_mac_address "${dhcp_ip}" "${dev_name}")
|
|
|
|
mkdir -p /var/state
|
|
touch /var/state/gwinfo
|
|
sec=$(uci -q -c /var/state get gwinfo.gatewayinfo)
|
|
if [ -z "${sec}" ]; then
|
|
sec=$(uci -q -c /var/state add gwinfo gatewayinfo)
|
|
uci -q -c /var/state rename gwinfo."${sec}"="gatewayinfo"
|
|
fi
|
|
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.hwaddr="$MAC"
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.endpoint=""
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.class=""
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.oui=""
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.serial=""
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.proto=""
|
|
uci -q -c /var/state commit gwinfo
|
|
|
|
if [ -z "$opt125" ]; then
|
|
send_unknown_gw_event "${MAC}"
|
|
return 0
|
|
fi
|
|
|
|
len=$(echo -n "${opt125}" | wc -c)
|
|
get_vivsoi "${opt125}" "${len}"
|
|
|
|
if [ "${GW_DISCOVERED}" -eq 0 ]; then
|
|
send_unknown_gw_event "${MAC}"
|
|
return 0
|
|
fi
|
|
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.class="$CLASS"
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.oui="$OUI"
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.serial="$SERIAL"
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.proto="CWMP"
|
|
uci -q -c /var/state commit gwinfo
|
|
|
|
# Check for USP parameters
|
|
if ! ubus -t 15 wait_for umdns; then
|
|
send_cwmp_gw_event "${OUI}" "${CLASS}" "${SERIAL}"
|
|
return 0
|
|
fi
|
|
|
|
resp=$(send_host_query "${dev_name}")
|
|
if [ "${resp}" -ne 0 ]; then
|
|
send_cwmp_gw_event "${OUI}" "${CLASS}" "${SERIAL}"
|
|
return 0
|
|
fi
|
|
|
|
ID=$(get_usp_agent_id "${dhcp_ip}")
|
|
if [ -z "${ID}" ]; then
|
|
send_cwmp_gw_event "${OUI}" "${CLASS}" "${SERIAL}"
|
|
return 0
|
|
fi
|
|
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.endpoint="$ID"
|
|
uci -q -c /var/state set gwinfo.gatewayinfo.proto="USP"
|
|
uci -q -c /var/state commit gwinfo
|
|
|
|
send_usp_gw_event "${ID}"
|
|
fi
|