#!/bin/sh # Copyright (C) 2011-2012 Luka Perkov # Copyright (C) 2013 Inteno Broadband Technology AB # Author Ahmed Zribi # Author Mohamed Kallel # TODO: merge this one somewhere in OpenWrt uci_remove_list_element() { local option="$1" local value="$2" local list="$(/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q get $option)" local elem /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q delete $option for elem in $list; do if [ "$elem" != "$value" ]; then /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q add_list $option=$elem fi done } freecwmp_output() { local MSG="" local parameter="$1" local value="$2" local permissions="$3" local notification="$4" local type="$5" local fault_code="$6" local status="$7" local instance="$8" local success="$9" case "$action" in get_value|inform) json_init json_add_string "parameter" "$parameter" json_add_string "value" "$value" json_add_string "fault_code" "$fault_code" if [ "$type" != "" ]; then json_add_string "type" "$type"; fi json_close_object MSG=`json_dump` ;; get_name) json_init json_add_string "parameter" "$parameter" json_add_string "writable" "$permissions" json_add_string "fault_code" "$fault_code" json_close_object MSG=`json_dump` ;; get_notification) json_init json_add_string "parameter" "$parameter" if [ "$notification" != "" ]; then json_add_string "notification" "$notification"; fi json_add_string "fault_code" "$fault_code" json_close_object MSG=`json_dump` ;; add_object) json_init json_add_string "instance" "$instance" json_add_string "status" "$status" json_add_string "fault_code" "$fault_code" json_close_object MSG=`json_dump` ;; delete_object) json_init json_add_string "status" "$status" json_add_string "fault_code" "$fault_code" json_close_object MSG=`json_dump` ;; apply_value) json_init json_add_string "status" "$status" json_close_object MSG=`json_dump` ;; apply_notification) json_init json_add_string "success" "$success" json_add_string "fault_code" "$fault_code" json_close_object MSG=`json_dump` ;; esac echo "$MSG" } freecwmp_cache_output() { local MSG="" local parameter="$1" local value="$2" local permission="$3" local notification="$4" local type="$5" local set_cmd="$6" local get_cmd="$7" local notif_permission="$8" local forced_inform="$9" local secret_value="$10" json_init json_add_string "parameter" "$parameter" json_add_string "writable" "$permission" if [ "$type" != "" ]; then json_add_string "type" "$type"; fi if [ "$get_cmd" != "" ]; then json_add_string "get_cmd" "$get_cmd"; fi if [ "$set_cmd" != "" ]; then json_add_string "set_cmd" "$set_cmd"; fi if [ "$notif_permission" != "" ]; then json_add_string "notif_permission" "$notif_permission"; fi if [ "$notification" != "" ]; then json_add_string "notification" "$notification" json_add_string "value" "$value" fi if [ "$forced_inform" != "" ]; then json_add_string "forced_inform" "$forced_inform"; fi if [ "$secret_value" != "" ]; then json_add_string "secret_value" "$secret_value"; fi json_close_object MSG=`json_dump` echo "$MSG" } freecwmp_fault_output() { local MSG="" local parameter="$1" local fault_code="$2" local success="$3" case "$action" in apply_value) json_init json_add_string "parameter" "$parameter" json_add_string "fault_code" "$fault_code" json_close_object MSG=`json_dump` ;; apply_notification) json_init json_add_string "success" "$success" json_add_string "fault_code" "$fault_code" json_close_object MSG=`json_dump` ;; *download) json_init json_add_string "fault_code" "$fault_code" json_close_object MSG=`json_dump` ;; esac echo "$MSG" } freecwmp_parse_formated_parameter() { local parameter="$1" local pattern="$2" local p="" q="" local _values="" n="" local i local j=0 while [ true ]; do if [ "_" = "_$parameter" -o "_" = "_$pattern" ]; then if [ "_$parameter" != "_$pattern" ]; then eval "export -- \"$3=-1\"" return else break fi fi split_param=${parameter%%.*} split_pattr=${pattern%%.*} p="$parameter"; q="$pattern" parameter=${parameter#*.} pattern=${pattern#*.} if [ "$p" = "$parameter" -o "$q" = "$pattern" ]; then if [ "$parameter" != "$pattern" -a "_$pattern" != "_{i}" ]; then eval "export -- \"$3=-1\"" return else break fi fi if [ "_$split_pattr" = "_{i}" ]; then let n=$split_param-1 if [ $n -lt 0 ]; then eval "export -- \"$3=-1\"" return fi if [ "_$_values" == "_" ]; then _values="$split_param" else _values="$_values $split_param" fi elif [ "_$split_param" != "_$split_pattr" ]; then eval "export -- \"$3=-1\"" return fi done eval "export -- \"$3=0\"" eval "export -- \"$4=\"\"$_values\"\"\"" } freecwmp_config_cwmp() { config_get __parameter "$1" "parameter" config_get __value "$1" "value" config_get __tags "$1" "tag" if [ "$__parameter" = "$4" ]; then if [ "get" = "$2" ]; then if [ "value" = "$3" ]; then eval "export -- \"$5=\"\"$__value\"\"\"" fi if [ "tags" = "$3" ]; then eval "export -- \"$5=\"\"$__tags\"\"\"" fi elif [ "set" = "$2" ]; then if [ "value" = "$3" ]; then /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q set cwmp.$1.value=$5 2> /dev/null fi elif [ "check" = "$2" ]; then if [ "parameter" = "$3" ]; then eval "export -- \"$5=\"$1\"\"" fi fi fi } freecwmp_config_notifications() { config_get __active "$1" "active" config_get __passive "$1" "passive" config_get __disabled "$1" "disabled" local length="0" for item in $__disabled do if [ "$item" = "$3" ]; then eval "export -- \"$4=0\"" return 0 elif [ "`echo $3|grep $item`" = "$3" -a "`echo $item|grep '\.$'`" != "" ]; then if [ $length -lt ${#item} ]; then eval "export -- \"$4=0\"" length="${#item}" fi fi done for item in $__active do if [ "$item" = "$3" ]; then eval "export -- \"$4=2\"" return 0 elif [ "`echo $3|grep $item`" = "$3" -a "`echo $item|grep '\.$'`" != "" ]; then if [ $length -lt ${#item} ]; then eval "export -- \"$4=2\"" length="${#item}" fi fi done for item in $__passive do if [ "$item" = "$3" ]; then eval "export -- \"$4=1\"" return 0 elif [ "`echo $3|grep $item`" = "$3" -a "`echo $item|grep '\.$'`" != "" ]; then if [ $length -lt ${#item} ]; then eval "export -- \"$4=1\"" length="${#item}" fi fi done return 0 } freecwmp_get_parameter_value() { local _dest="$1" local _parm="$2" local _val config_foreach freecwmp_config_cwmp "cwmp" "get" "value" "$_parm" "_val" echo "$_val" } freecwmp_set_parameter_value() { local _parm="$1" local _val="$2" config_foreach freecwmp_config_cwmp "cwmp" "check" "parameter" "$_parm" "_section" if [ ! "$_section" = "" ]; then /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q set cwmp.$_section.value=$_val 2> /dev/null else /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q batch << EOF 2>&1 >/dev/null add cwmp cwmp set cwmp.@cwmp[-1].parameter="$_parm" set cwmp.@cwmp[-1].value="$_val" EOF fi } freecwmp_get_parameter_notification() { local _dest="$1" local _parm="$2" local _val local _parent config_foreach freecwmp_config_notifications "notifications" "get" "$_parm" "_val" if [ "$_val" = "" ]; then if [ "`echo $_parm|grep '\.$'`" = "" ]; then _parent="${_parm%.*}." config_foreach freecwmp_config_notifications "notifications" "get" "$_parent" "_val" else _parent="${_parm%.*.}." config_foreach freecwmp_config_notifications "notifications" "get" "$_parent" "_val" fi fi if [ "$_val" = "" ];then _val="0" ;fi eval "export -- \"$_dest=$_val\"" } freecwmp_notify() { local parm="$1" local val="$2" local attribute="$3" local type="$4" local param_check="$parm" if [ "_$attribute" = "_" ]; then json_msg=`get_param_notification_generic "$parm" | head -1` json_init json_load "$json_msg" json_get_var attribute notification json_get_var param_check parameter json_get_var type type fi if [ "$param_check" = "$parm" -a "_$attribute" != "_0" ]; then ubus ${UBUS_SOCKET:+-s $UBUS_SOCKET} call tr069 notify '{ "parameter": "'$parm'", "value": "'$val'", "attribute": "'$attribute'", "type": "'$type'" }' & fi } freecwmp_update_notification() { local list="$1" local __parm="$2" for i in $(/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q get cwmp.@notifications[0].$list);do if [ "`echo $i|grep $__parm`" != "" ];then uci_remove_list_element "cwmp.@notifications[0].$list" "$i" 2>/dev/null fi done } freecwmp_set_parameter_notification() { local _parm="$1" local _val="$2" local tmp=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q get cwmp.@notifications[0] 2>/dev/null` if [ "$tmp" = "" ]; then /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q add cwmp notifications 2>&1 >/dev/null else uci_remove_list_element "cwmp.@notifications[0].passive" "$_parm" 2>/dev/null uci_remove_list_element "cwmp.@notifications[0].active" "$_parm" 2>/dev/null uci_remove_list_element "cwmp.@notifications[0].disabled" "$_parm" 2>/dev/null freecwmp_update_notification "passive" "$_parm" 2>/dev/null freecwmp_update_notification "active" "$_parm" 2>/dev/null freecwmp_update_notification "disabled" "$_parm" 2>/dev/null fi if [ "`echo $_parm|grep '\.$'`" = "" ]; then _parent="${_parm%.*}." config_foreach freecwmp_config_notifications "notifications" "get" "$_parent" "_val_p" else _parent="${_parm%.*.}." config_foreach freecwmp_config_notifications "notifications" "get" "$_parent" "_val_p" fi if [ "$_val" -eq "1" ]; then /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q add_list cwmp.@notifications[0].passive="$_parm" 2>&1 >/dev/null elif [ "$_val" -eq "2" ]; then /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q add_list cwmp.@notifications[0].active="$_parm" 2>&1 >/dev/null elif [ "$_val" -eq "0" -a "$_val_p" != "" -a "$_val_p" != "0" ]; then /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q add_list cwmp.@notifications[0].disabled="$_parm" 2>&1 >/dev/null fi } delay_service() { local action="$1" local service="$2" local delay="$3" if [ ! -f /tmp/end_session.sh ];then ubus ${UBUS_SOCKET:+-s $UBUS_SOCKET} call tr069 command '{ "command": "action_end_session" }' &> /dev/null & echo '#!/bin/sh' > /tmp/end_session.sh chmod +x /tmp/end_session.sh else check="`cat /tmp/end_session.sh|grep /etc/init.d/$service`" if [ "$check" != "" ];then return 0 fi fi if [ "$action" = "restart" ]; then cat << EOF >> /tmp/end_session.sh /etc/init.d/$service stop &> /dev/null sleep $delay /etc/init.d/$service start &> /dev/null EOF fi if [ "$action" = "reload" ]; then cat << EOF >> /tmp/end_session.sh sleep $delay /etc/init.d/$service reload &> /dev/null EOF fi } freecwmp_set_parameter_fault() { local _parm="-$1" local _fault="$2" /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q -P /var/state batch << EOF 2>&1 >/dev/null add cwmp fault set cwmp.@fault[-1].parameter="$_parm" set cwmp.@fault[-1].fault_code="$_fault" EOF } freecwmp_check_image() { . /etc/functions.sh; include /lib/upgrade; platform_check_image /tmp/firmware_upgrade_image return $? } freecwmp_check_flash_size() { local size=0 if [ -f /proc/mtd ];then for line in `cat /proc/mtd` do if [ "`echo $line|grep "^([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+\"([^[:space:]]+)\""`" != "" ] then b=`cat $line|cut -f1 -d " "` n=`cat $line|cut -f3 -d " "` if [ "$n" = "\"linux\"" -o "$n" = "\"firmware\"" ];then size=`echo $(($s))` break; fi fi done elif [ -f /proc/partitions ] then for line in `cat /proc/partitions` do if [ "`echo $line|grep "[[:space:]]*([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)"`" != "" ] then b=`cat $line|cut -f2 -d " "` n=`cat $line|cut -f3 -d " "` if [ checkline "([^[:space:]]+)" $n ];then size=`let $b*1024`; break; fi fi done fi echo "$size" } freecwmp_apply_firmware() { local fault_code="9000" sync killall dropbear uhttpd; sleep 1; /sbin/sysupgrade /tmp/firmware_upgrade_image_last_valid if [ "$?" != "0" ];then let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED freecwmp_fault_output "" "$fault_code" else freecwmp_fault_output "" "$FAULT_CPE_NO_FAULT" fi } freecwmp_apply_web_content() { local fault_code="9000" /bin/opkg install /tmp/web_content.ipk if [ "$?" != "0" ];then rm /tmp/web_content.ipk 2> /dev/null let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED freecwmp_fault_output "" "$fault_code" else freecwmp_fault_output "" "$FAULT_CPE_NO_FAULT" fi } freecwmp_apply_vendor_configuration() { local fault_code="9000" /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q import < /tmp/vendor_configuration_file.cfg if [ "$?" = "0" ];then /sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q commit if [ "$?" != "0" ];then let fault_code=$fault_code+$FAULT_CPE_INTERNAL_ERROR freecwmp_fault_output "" "$fault_code" else freecwmp_fault_output "" "$FAULT_CPE_NO_FAULT" sync reboot fi else rm /tmp/vendor_configuration_file.cfg 2> /dev/null let fault_code=$fault_code+$FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED freecwmp_fault_output "" "$fault_code" fi } get_param_cache_generic() { local param="$1" local permission="$2" local val_cmd="$3" local set_cmd="$4" local get_cmd="$5" local type="$6" local notif_permission="$7" local forced_inform="$8" local forced_notify="$9" local secret_value="$10" local val="" local notification="0" if [ "$val_cmd" != "" ]; then val=`eval "$val_cmd"` fi if [ "_$forced_notify" = "_" ]; then freecwmp_get_parameter_notification "notification" $param else notification="$forced_notify" fi freecwmp_cache_output "$param" "$val" "$permission" "$notification" "$type" "$set_cmd" "$get_cmd" "$notif_permission" "$forced_inform" "$secret_value" } get_object_cache_generic() { local param=$1 local permission=$2 local notif_permission=$3 freecwmp_cache_output "$param" "" "$permission" "" "" "" "" "$notif_permission" } get_generic_dynamic() { local found_prefix="$1" local param="$2" local prefix="" get_func="" for prefix in $prefix_list; do case "$prefix" in "$found_prefix"*) get_func=${prefix%.} get_func=${get_func//./_} get_func="get_dynamic_""$get_func" $get_func "$param" >"$cache_path/$prefix""_dynamic" esac done } cat_cache_filter_param() { cat "$1"* | grep "$2" } get_param_prefix() { local parameter="$1" local max_len=0 local found="" prefix="" len=0 if [ "$parameter" != "" ]; then for prefix in $prefix_list; do case "$parameter" in "$prefix"*) if [ "$parameter" = "$prefix"]; then found="$prefix" break fi len=${#prefix} if [ $len -gt $max_len ]; then max_len=$len found="$prefix" fi esac done if [ "$found" = "" ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME fi fi eval "export -- $2='$found'" return $FAULT_CPE_NO_FAULT } get_generic_cmd() { local parameter="$1" local found="$2" local msgs="" command="" if [ "$parameter" != "" -a "$parameter" != "$found" ]; then msgs=`cat "$cache_path/$found"* | grep "\"$parameter\""` if [ "$msgs" = "" ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME fi l=${#parameter} let l-- if [ "${parameter:$l:1}" != "." ]; then command="echo $msgs" else command="cat_cache_filter_param $cache_path/$found $parameter" fi else command="cat $cache_path/$found*" fi eval "export -- $3='$command'" return $FAULT_CPE_NO_FAULT } get_param_value_generic() { local parameter=$1 local param="" val="" type="" found_prefix="" cmd="" get_param_prefix "$parameter" "found_prefix" local ret="$?" if [ "$ret" != $FAULT_CPE_NO_FAULT ]; then return "$ret" fi rm -f "$cache_path/"*"_dynamic" get_generic_dynamic "$found_prefix" "$parameter" get_generic_cmd "$parameter" "$found_prefix" "cmd" ret="$?" if [ "$ret" = $FAULT_CPE_NO_FAULT ]; then eval '$cmd' | grep "\"value\"" | grep -v "\"get_cmd\"" eval '$cmd' | grep "\"get_cmd\"" | while read line; do json_init json_load "$line" json_get_var exec_get_cmd get_cmd json_get_var param parameter json_get_var type type val=`eval "$exec_get_cmd"` freecwmp_output "$param" "$val" "" "$type" done fi rm -f "$cache_path/"*"_dynamic" return "$ret" } get_param_name_generic() { local parameter=$1 local next_level=$2 local found_prefix="" cmd="" get_param_prefix "$parameter" "found_prefix" local ret="$?" if [ "$ret" != $FAULT_CPE_NO_FAULT ]; then return "$ret" fi rm -f "$cache_path/"*"_dynamic" get_generic_dynamic "$found_prefix" "$parameter" get_generic_cmd "$parameter" "$found_prefix" "cmd" ret="$?" if [ "$ret" = "$FAULT_CPE_NO_FAULT" ]; then if [ "$next_level" = "0" ]; then eval '$cmd' else if [ "$parameter" != "" ]; then local len=${#parameter} let len-- if [ "${parameter:$len:1}" != "." ]; then return $FAULT_CPE_INVALID_ARGUMENTS fi eval '$cmd' | grep -v "$parameter[A-Za-z_0-9]\+\.[A-Za-z_0-9]" | grep -v "\"$parameter\"" else eval '$cmd' | grep -v "$parameter[A-Za-z_0-9]\+\.[A-Za-z_0-9]" fi fi fi rm -f "$cache_path/"*"_dynamic" return $ret } get_param_notification_generic() { local parameter=$1 local found_prefix="" cmd="" get_param_prefix "$parameter" "found_prefix" local ret="$?" if [ "$ret" != $FAULT_CPE_NO_FAULT ]; then return "$ret" fi rm -f "$cache_path/"*"_dynamic" get_generic_dynamic "$found_prefix" "$parameter" get_generic_cmd "$parameter" "$found_prefix" "cmd" ret="$?" if [ "$ret" = "$FAULT_CPE_NO_FAULT" ]; then eval '$cmd' | grep "\"notification\"" fi rm -f "$cache_path/"*"_dynamic" return $ret } set_param_value_generic() { local param="$1" local val="$2" local max_len=0 local found_prefix="" msgs="" prefix="" len="" permission="" set_cmd="" if [ "$param" = "" ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME fi for prefix in $prefix_list; do case "$param" in "$prefix"*) if [ "$param" = "$prefix" ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME fi len=${#prefix} if [ $len -gt $max_len ]; then max_len=$len found_prefix="$prefix" fi esac done if [ "$found_prefix" = "" ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME fi rm -f "$cache_path/"*"_dynamic" get_generic_dynamic "$found_prefix" "$param" msgs=`cat "$cache_path/$found_prefix"* | grep "\"$param\"" | grep "\"value\"" | head -1` rm -f "$cache_path/"*"_dynamic" if [ "$msgs" = "" ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME fi json_init json_load "$msgs" json_get_var writable writable if [ "$writable" != "1" ];then return $FAULT_CPE_NON_WRITABLE_PARAMETER fi json_get_var set_cmd set_cmd if [ "$set_cmd" = "" ];then return $FAULT_CPE_NON_WRITABLE_PARAMETER fi eval "$set_cmd" json_get_var secret_value secret_value if [ "$secret_value" != "1" ]; then json_add_string "value" "$val" json_close_object echo "`json_dump`" >> $set_tmp_file fi return $FAULT_CPE_NO_FAULT } set_param_notification_generic() { local param="$1" local notification="$2" local max_len=0 local same="0" local found_prefix="" msgs="" cmd="" prefix="" len="" line="" notif_permission="" if [ "$param" != "" ]; then for prefix in $prefix_list; do case "$param" in "$prefix"*) if [ "$param" = "$prefix"]; then same="1" found_prefix="$prefix" break fi len=${#prefix} if [ $len -gt $max_len ]; then max_len=$len found_prefix="$prefix" fi esac done if [ "$found_prefix" = "" ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME fi rm -f "$cache_path/"*"_dynamic" get_generic_dynamic "$found_prefix" "$param" msgs=`cat "$cache_path/$found_prefix"* | grep "\"$param\""` rm -f "$cache_path/"*"_dynamic" if [ "$msgs" = "" ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME fi else rm -f "$cache_path/"*"_dynamic" get_generic_dynamic "$found_prefix" "$param" msgs=`cat "$cache_path/"* | grep "\"[A-Za-z_0-9]\+\.\""` rm -f "$cache_path/"*"_dynamic" fi echo "$msgs" | while read line; do json_init json_load "$line" json_get_var notif_permission notif_permission if [ "$notif_permission" = "0" ]; then return $FAULT_CPE_NOTIFICATION_REJECTED fi json_get_var param parameter freecwmp_set_parameter_notification "$param" "$notification" json_add_string "notification" "$notification" json_close_object echo "`json_dump`" >> $set_tmp_file done return $? } object_fn_generic() { local object="$1" local prefix="" local found="" local max_len=0 local len=0 for prefix in $prefix_list; do case "$object" in "$prefix"*) len=${#prefix} if [ $len -gt $max_len ]; then max_len=$len found="$prefix" fi esac done if [ "$found" = "" ];then return $FAULT_CPE_INVALID_PARAMETER_NAME fi local fn=${found%.} fn=${fn//./_} local f="$action"_"$fn" $f "$1" "$found" return $? }