freecwmp
[Top] [All Lists]

[PATCH] Add GetParameterName feature. communication from external script

Subject: [PATCH] Add GetParameterName feature. communication from external script to core via ubus. Update GetParameterValue in order to support many parameter names and in order to support parameter type. and modify GetParameterNames related scripts Contributed by Inteno Broadband Technology AB
From: Mohamed <mohamed.kallel@pivasoftware.com>
Date: Fri, 16 Nov 2012 18:08:02 +0100
---
 bin/Makefile.am                                 |    3 +-
 configure.ac                                    |    3 +
 ext/openwrt/config/freecwmp                     |    6 +
 ext/openwrt/scripts/freecwmp.sh                 |   98 +++++++-
 ext/openwrt/scripts/functions/common            |   27 ++
 ext/openwrt/scripts/functions/device_hosts      |   23 +-
 ext/openwrt/scripts/functions/device_info       |  216 ++++++++++++++-
 ext/openwrt/scripts/functions/device_routing    |   33 ++--
 ext/openwrt/scripts/functions/device_users      |   13 +-
 ext/openwrt/scripts/functions/lan_device        |  108 ++++++++-
 ext/openwrt/scripts/functions/management_server |  318 +++++++++++++++++++++--
 ext/openwrt/scripts/functions/misc              |    8 +-
 ext/openwrt/scripts/functions/wan_device        |  217 +++++++++++++++-
 src/external.c                                  |  173 ++++++++++--
 src/external.h                                  |   16 ++
 src/freecwmp.c                                  |   19 ++
 src/freecwmp.h                                  |    1 +
 src/ubus.c                                      |  127 +++++++++
 src/xml.c                                       |  211 ++++++++++++----
 src/xml.h                                       |    4 +
 20 files changed, 1457 insertions(+), 167 deletions(-)

diff --git a/bin/Makefile.am b/bin/Makefile.am
index 78cb111..ac96905 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -48,5 +48,6 @@ freecwmpd_LDADD =             \
        $(LIBUBUS_LIBS)         \
        $(MICROXML_LIBS)        \
        $(LIBCURL_LIBS)         \
-       $(LIBZSTREAM_LIBS)
+       $(LIBZSTREAM_LIBS)      \
+       $(LIBPTHREAD_LIBS)
 
diff --git a/configure.ac b/configure.ac
index c646c3a..38d3df4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -80,6 +80,9 @@ AC_SUBST([LIBUBUS_LDFLAGS])
 LIBUBUS_LIBS='-lubus'
 AC_SUBST([LIBUBUS_LIBS])
 
+LIBPTHREAD_LIBS='-lpthread'
+AC_SUBST([LIBPTHREAD_LIBS])
+
 AM_COND_IF([HTTP_CURL], [
  AC_DEFINE(HTTP_CURL)
  PKG_CHECK_MODULES(LIBCURL, [libcurl])
diff --git a/ext/openwrt/config/freecwmp b/ext/openwrt/config/freecwmp
index c5b4ed4..88dca66 100644
--- a/ext/openwrt/config/freecwmp
+++ b/ext/openwrt/config/freecwmp
@@ -29,19 +29,25 @@ config scripts
        # freecwmp specific functions
        list location /usr/share/freecwmp/functions/device_info
        list get_value_function get_device_info
+       list get_name_function get_device_info_name
        list set_value_function set_device_info
        list get_value_function get_device_info_generic
+       list get_name_function get_device_info_generic_name
        list set_value_function set_device_info_generic
        list location /usr/share/freecwmp/functions/lan_device
        list get_value_function get_lan_device
+       list get_name_function get_lan_device_name
        list set_value_function set_lan_device
        list location /usr/share/freecwmp/functions/management_server
        list get_value_function get_management_server
+       list get_name_function get_management_server_name
        list set_value_function set_management_server
        list get_value_function get_management_server_generic
+       list get_name_function get_management_server_generic_name
        list set_value_function set_management_server_generic
        list location /usr/share/freecwmp/functions/wan_device
        list get_value_function get_wan_device
+       list get_name_function get_wan_device_name
        list set_value_function set_wan_device
        list location /usr/share/freecwmp/functions/misc
        list get_value_function get_misc
diff --git a/ext/openwrt/scripts/freecwmp.sh b/ext/openwrt/scripts/freecwmp.sh
index 3fbee27..60c29b0 100644
--- a/ext/openwrt/scripts/freecwmp.sh
+++ b/ext/openwrt/scripts/freecwmp.sh
@@ -67,6 +67,10 @@ case "$1" in
                elif [ "$2" = "value" ]; then
                        __arg1="$3"
                        action="get_value"
+               elif [ "$2" = "name" ]; then
+                       __arg1="$3"
+                       __arg2=`echo $4| tr '[A-Z]' '[a-z]'`
+                       action="get_name"
                elif [ "$2" = "all" ]; then
                        __arg1="$3"
                        action="get_all"
@@ -106,27 +110,103 @@ handle_scripts() {
        config_get prefix "$section" "prefix"
        config_list_foreach "$section" 'location' load_script
        config_get get_value_functions "$section" "get_value_function"
+       config_get get_name_functions "$section" "get_name_function"
        config_get set_value_functions "$section" "set_value_function"
 }
 
 config_load freecwmp
 config_foreach handle_scripts "scripts"
 
+# Fault code
+
+FAULT_CPE_NO_FAULT="0"
+FAULT_CPE_REQUEST_DENIED="1"
+FAULT_CPE_INTERNAL_ERROR="2"
+FAULT_CPE_INVALID_ARGUMENTS="3"
+FAULT_CPE_RESOURCES_EXCEEDED="4"
+FAULT_CPE_INVALID_PARAMETER_NAME="5"
+FAULT_CPE_INVALID_PARAMETER_TYPE="6"
+FAULT_CPE_INVALID_PARAMETER_VALUE="7"
+FAULT_CPE_NON_WRITABLE_PARAMETER="8"
+FAULT_CPE_NOTIFICATION_REJECTED="9"
+FAULT_CPE_DOWNLOAD_FAILURE="10"
+FAULT_CPE_UPLOAD_FAILURE="11"
+FAULT_CPE_FILE_TRANSFER_AUTHENTICATION_FAILURE="12"
+FAULT_CPE_FILE_TRANSFER_UNSUPPORTED_PROTOCOL="13"
+FAULT_CPE_DOWNLOAD_FAIL_MULTICAST_GROUP="14"
+FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER="15"
+FAULT_CPE_DOWNLOAD_FAIL_ACCESS_FILE="16"
+FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD="17"
+FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED="18"
+FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION="19"
+
 if [ "$action" = "get_value" -o "$action" = "get_all" ]; then
-       if [ ${FLAGS_force} -eq ${FLAGS_FALSE} ]; then
-               __tmp_arg="Device."
-               # TODO: don't check only string length ; but this is only used
-               #       for getting correct prefix of CWMP parameter anyway
-               if [  ${#__arg1} -lt ${#__tmp_arg} ]; then
-                       echo "CWMP parameters usualy begin with 
'InternetGatewayDevice.' or 'Device.'     "
-                       echo "if you want to force script execution with 
provided parameter use '-f' flag."
-                       exit -1
-               fi
+       no_fault="0"
+       freecwmp_check_fault "$__arg1"
+       fault_code="$?"
+       if [ "$fault_code" = "0" ]; then
+               if [ \( "$__arg1" = "InternetGatewayDevice." \) -o \( "$__arg1" 
= "" \) ]; then
+                       __arg1="InternetGatewayDevice."
        fi
        for function_name in $get_value_functions
        do
                $function_name "$__arg1"
+                       fault_code="$?"
+                       if [ "$fault_code" = "0" ]; then
+                               no_fault="1"
+                       fi
+                       if [ "$fault_code" = "$FAULT_CPE_INVALID_ARGUMENTS" ]; 
then
+                               break
+                       fi
+               done
+               if [ "$no_fault" = "1" ]; then fault_code="0"; fi
+       fi
+       if [ "$fault_code" != "0" ]; then
+               let fault_code=$fault_code+9000
+               ubus_freecwmp_output "$__arg1" "" "" "$fault_code"
+       fi
+fi
+
+if [ "$action" = "get_name" -o "$action" = "get_all" ]; then
+       no_fault="0"
+       freecwmp_check_fault "$__arg1"
+       fault_code="$?"
+       if [ "$fault_code" = "0" ]; then
+               if [ \( "$__arg2" != "0" \) -a \( "$__arg2" != "1" \) -a \( 
"$__arg2" != "true" \) -a \( "$__arg2" != "false" \) ]; then
+                       fault_code="$FAULT_CPE_INVALID_ARGUMENTS"
+               else
+                       if [ "$__arg2" = "true" ]; then
+                               __arg2="1"
+                       elif [ "$__arg2" = "false" ]; then
+                               __arg2="0"
+                       fi
+               fi
+               if [ "$fault_code" = "0" ]; then
+                       if [ \( "$__arg1" = "InternetGatewayDevice." \) -o \( 
"$__arg1" = "" \) ]; then
+                               ubus_freecwmp_output "InternetGatewayDevice." 
"0"
+                               if [ \( "$__arg1" = "" \) -a \( "$__arg2" = "1" 
\) ]; then
+                                       exit 0
+                               fi
+                               __arg1="InternetGatewayDevice."
+                       fi
+                       for function_name in $get_name_functions
+                       do
+                               $function_name "$__arg1" "$__arg2"
+                               fault_code="$?"
+                               if [ "$fault_code" = "0" ]; then
+                                       no_fault="1"
+                               fi
+                               if [ "$fault_code" = 
"$FAULT_CPE_INVALID_ARGUMENTS" ]; then
+                                       break
+                               fi
        done
+                       if [ "$no_fault" = "1" ]; then fault_code="0"; fi
+               fi
+       fi
+       if [ "$fault_code" != "0" ]; then
+               let fault_code=$fault_code+9000
+               ubus_freecwmp_output "$__arg1" "" "" "$fault_code"
+       fi
 fi
 
 if [ "$action" = "set_value" ]; then
diff --git a/ext/openwrt/scripts/functions/common 
b/ext/openwrt/scripts/functions/common
index 7e3000a..7e26acf 100644
--- a/ext/openwrt/scripts/functions/common
+++ b/ext/openwrt/scripts/functions/common
@@ -34,6 +34,26 @@ if [ -n "$value" -o ${FLAGS_empty} -eq ${FLAGS_TRUE} ]; then
 fi
 }
 
+ubus_freecwmp_output() {
+local parameter="$1"
+local value="$2"
+local type="$3"
+local fault_code="$4"
+
+if [ "$type" = "" ]; then
+       type="xsd:string"
+fi
+
+case "$action" in
+       get_value)
+       ubus call tr069 GetParameterValues '{"parameter": "'$parameter'", 
"value": "'$value'", "type": "'$type'", "fault_code":"'$fault_code'"}'
+       ;;
+       get_name)
+       ubus call tr069 GetParameterNames '{"parameter": "'$parameter'", 
"writable": "'$value'", "fault_code":"'$fault_code'"}'
+       ;;
+esac
+}
+
 freecwmp_value_output() {
        freecwmp_output "$1" "$2" "V"
 }
@@ -249,3 +269,10 @@ EOF
        sh "$lock" &
 fi
 }
+
+freecwmp_check_fault() {
+if [ "$1" = "." ]; then
+       return $FAULT_CPE_INVALID_PARAMETER_NAME
+fi
+return $FAULT_CPE_NO_FAULT
+}
diff --git a/ext/openwrt/scripts/functions/device_hosts 
b/ext/openwrt/scripts/functions/device_hosts
index 4c3fcd4..1e80f32 100644
--- a/ext/openwrt/scripts/functions/device_hosts
+++ b/ext/openwrt/scripts/functions/device_hosts
@@ -44,7 +44,7 @@ local parameter=`echo -n $1 | sed 
"s/InternetGatewayDevice\.LANDevice\.1\./Devic
 case "$parameter" in
        Device.Hosts.HostNumberOfEntries)
        let local val=$num_static_leases+$num_dynamic_leases
-       freecwmp_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
        ;;
 esac
@@ -66,7 +66,7 @@ if [ $rc -eq 0 ]; then
                local sed_cmd=`echo -n \'$num; echo p\'`
                val=`eval sed -n $sed_cmd $leases_file | awk '{ print $2 }'`
        fi
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -74,7 +74,7 @@ freecwmp_parse_formated_parameter "$parameter" 
"Device.Hosts.Host.{i}.IPAddress"
 if [ $rc -eq 0 ]; then
        local val
        get_device_hosts_ip_address "$leases_file" "$num" "$num_static_leases" 
"$num_dynamic_leases" "val"
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -88,7 +88,7 @@ if [ $rc -eq 0 ]; then
        if [ $num -gt 0 -a $num -le $num_dynamic_leases ]; then
                val="DHCP"
        fi
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -107,7 +107,7 @@ if [ $rc -eq 0 ]; then
                local t2=`date +%s`
                let val=$t1-$t2
        fi
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -131,7 +131,7 @@ if [ $rc -eq 0 ]; then
                val=`eval sed -n $sed_cmd $leases_file | awk '{ print $4 }'`
                if [ "x$val" == "x*" ]; then val=""; fi
        fi
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -144,7 +144,7 @@ if [ $rc -eq 0 ]; then
        get_device_hosts_ip_address "$leases_file" "$num" "$num_static_leases" 
"$num_dynamic_leases" "ip"
        val=`ping -c 1 $ip 2>&1 > /dev/null ; echo $?`
        let val=!$val
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -156,7 +156,7 @@ if [ $rc -eq 0 ]; then
        if [ $num -le $n ]; then
                val=1
        fi
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -168,7 +168,7 @@ if [ $rc -eq 0 ]; then
        if [ $num -le $n ]; then
                val=0
        fi
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -182,10 +182,11 @@ if [ $rc -eq 0 ]; then
        if [ $num2 -eq 1 ]; then
                get_device_hosts_ip_address "$leases_file" "$num1" 
"$num_static_leases" "$num_dynamic_leases" "val"
        fi
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
 # TODO: Device.Hosts.Host.{i}.IPv6Address.{i}.IPAddress (no IPv6 support yet)
-
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
+
diff --git a/ext/openwrt/scripts/functions/device_info 
b/ext/openwrt/scripts/functions/device_info
index 4423b8b..a4f0552 100644
--- a/ext/openwrt/scripts/functions/device_info
+++ b/ext/openwrt/scripts/functions/device_info
@@ -2,8 +2,16 @@
 # Copyright (C) 2011-2012 Luka Perkov <freecwmp@lukaperkov.net>
 
 get_device_info_manufacturer() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].manufacturer 2> /dev/null`
-freecwmp_output "InternetGatewayDevice.DeviceInfo.Manufacturer" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].manufacturer 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo.Manufacturer" "$val"
 }
 
 set_device_info_manufacturer() {
@@ -11,8 +19,16 @@ set_device_info_manufacturer() {
 }
 
 get_device_info_oui() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].oui 2> /dev/null`
-freecwmp_output "InternetGatewayDevice.DeviceInfo.ManufacturerOUI" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].oui 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo.ManufacturerOUI" "$val"
 }
 
 set_device_info_oui() {
@@ -20,8 +36,16 @@ set_device_info_oui() {
 }
 
 get_device_info_product_class() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].product_class 2> /dev/null`
-freecwmp_output "InternetGatewayDevice.DeviceInfo.ProductClass" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].product_class 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo.ProductClass" "$val"    
 }
 
 set_device_info_product_class() {
@@ -29,8 +53,16 @@ set_device_info_product_class() {
 }
 
 get_device_info_serial_number() {
+local val=""
+case "$action" in
+       get_value)
 local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].serial_number 2> /dev/null`
-freecwmp_output "InternetGatewayDevice.DeviceInfo.SerialNumber" "$val"
+       ;;
+       get_name)
+       local val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo.SerialNumber" "$val"
 }
 
 set_device_info_serial_number() {
@@ -38,8 +70,16 @@ set_device_info_serial_number() {
 }
 
 get_device_info_hardware_version() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].hardware_version 2> /dev/null`
-freecwmp_output "InternetGatewayDevice.DeviceInfo.HardwareVersion" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].hardware_version 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo.HardwareVersion" "$val"
 }
 
 set_device_info_hardware_version() {
@@ -47,8 +87,16 @@ set_device_info_hardware_version() {
 }
 
 get_device_info_software_version() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].software_version 2> /dev/null`
-freecwmp_output "InternetGatewayDevice.DeviceInfo.SoftwareVersion" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@device[0].software_version 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo.SoftwareVersion" "$val"
 }
 
 set_device_info_software_version() {
@@ -56,18 +104,33 @@ set_device_info_software_version() {
 }
 
 get_device_info_uptime() {
-local val=`cat /proc/uptime | awk -F "." '{ print $1 }'`
-freecwmp_output "InternetGatewayDevice.DeviceInfo.UpTime" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`cat /proc/uptime | awk -F "." '{ print $1 }'`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo.UpTime" "$val"
 }
 
 get_device_info_device_log() {
 local val=""
+case "$action" in
+       get_value)
 if [ ${FLAGS_last} -eq ${FLAGS_TRUE} ]; then
        val=`dmesg | tail -n1`
 else
        val=`dmesg | tail -n10`
 fi
-freecwmp_output "InternetGatewayDevice.DeviceInfo.DeviceLog" "$val"
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo.DeviceLog" "$val"
 }
 
 get_device_info() {
@@ -81,6 +144,7 @@ case "$1" in
        get_device_info_software_version
        get_device_info_uptime
        get_device_info_device_log
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.)
        get_device_info_manufacturer
@@ -91,32 +155,130 @@ case "$1" in
        get_device_info_software_version
        get_device_info_uptime
        get_device_info_device_log
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.Manufacturer)
        get_device_info_manufacturer
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.ManufacturerOUI)
        get_device_info_oui
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.ProductClass)
        get_device_info_product_class
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.SerialNumber)
        get_device_info_serial_number
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.HardwareVersion)
        get_device_info_hardware_version
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.SoftwareVersion)
        get_device_info_software_version
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.UpTime)
        get_device_info_uptime
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.DeviceInfo.DeviceLog)
        get_device_info_device_log
+       return $FAULT_CPE_NO_FAULT
        ;;
 esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
+}
+
+get_device_info_name() {
+case "$1" in
+       InternetGatewayDevice.)
+       ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo." "0"
+       if [ "$2" = "0" ]; then
+               get_device_info_manufacturer
+               get_device_info_oui
+               get_device_info_product_class
+               get_device_info_serial_number
+               get_device_info_hardware_version
+               get_device_info_software_version
+               get_device_info_uptime
+               get_device_info_device_log
+       fi
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.)
+       ubus_freecwmp_output "InternetGatewayDevice.DeviceInfo." "0"
+       get_device_info_manufacturer
+       get_device_info_oui
+       get_device_info_product_class
+       get_device_info_serial_number
+       get_device_info_hardware_version
+       get_device_info_software_version
+       get_device_info_uptime
+       get_device_info_device_log
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.Manufacturer)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_device_info_manufacturer
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.ManufacturerOUI)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_device_info_oui
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.ProductClass)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_device_info_product_class
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.SerialNumber)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_device_info_serial_number
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.HardwareVersion)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_device_info_hardware_version
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.SoftwareVersion)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_device_info_software_version
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.UpTime)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_device_info_uptime
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.DeviceLog)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_device_info_device_log
+       return $FAULT_CPE_NO_FAULT
+       ;;
+esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
 
 set_device_info() {
@@ -164,7 +326,31 @@ get_device_info_generic() {
        check_parameter_device_info_generic "$1" ; _tmp=$? ; if [ "$_tmp" -eq 1 
]; then return 0; fi
 
        freecwmp_get_parameter_value "val" "$1"
-       freecwmp_value_output "$1" "$val"
+       ubus_freecwmp_output "$1" "$val"
+}
+
+get_device_info_generic_name() {
+       local val=""
+       case "$1" in
+       InternetGatewayDevice.DeviceInfo.ModelName|\
+       InternetGatewayDevice.DeviceInfo.Description|\
+       InternetGatewayDevice.DeviceInfo.ModemFirmwareVersion|\
+       InternetGatewayDevice.DeviceInfo.EnabledOptions|\
+       InternetGatewayDevice.DeviceInfo.AdditionalHardwareVersion|\
+       InternetGatewayDevice.DeviceInfo.AdditionalSoftwareVersion|\
+       InternetGatewayDevice.DeviceInfo.SpecVersion|\
+       InternetGatewayDevice.DeviceInfo.FirstUseDate)
+       val="0"
+       ubus_freecwmp_output "$1" "$val"
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.DeviceInfo.ProvisioningCode)
+       val="1"
+       ubus_freecwmp_output "$1" "$val"
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
 
 set_device_info_generic() {
diff --git a/ext/openwrt/scripts/functions/device_routing 
b/ext/openwrt/scripts/functions/device_routing
index 3dfa418..ca6dab1 100644
--- a/ext/openwrt/scripts/functions/device_routing
+++ b/ext/openwrt/scripts/functions/device_routing
@@ -85,7 +85,7 @@ local parameter=$1
 
 case "$parameter" in
        Device.Routing.RouterNumberOfEntries)
-       freecwmp_output "$parameter" "1"
+       ubus_freecwmp_output "$parameter" "1"
        return
        ;;
 esac
@@ -101,7 +101,7 @@ if [ $rc -eq 0 ]; then
        else
                val="0"
        fi
-       freecwmp_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -113,7 +113,7 @@ if [ $rc -eq 0 ]; then
        else
                val="Disabled"
        fi
-       freecwmp_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -134,7 +134,7 @@ if [ $rc -eq 0 ]; then
        else
                return
        fi
-       freecwmp_output "$parameter" "$total"
+       ubus_freecwmp_output "$parameter" "$total"
        return
 fi
 
@@ -146,7 +146,7 @@ if [ $rc -eq 0 ]; then
        else
                return
        fi
-       freecwmp_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -166,15 +166,15 @@ if [ $rc -eq 0 ]; then
                        return
                fi
                if [ $num2 -gt $static ]; then
-                       freecwmp_output "$parameter" "Enabled"
+                       ubus_freecwmp_output "$parameter" "Enabled"
                        return
                fi
                if [ $num2 -le $inactive ]; then
-                       freecwmp_output "$parameter" "Error: not active but 
enabled"
+                       ubus_freecwmp_output "$parameter" "Error: not active 
but enabled"
                        return
                fi
                if [ $num2 -le $static ]; then
-                       freecwmp_output "$parameter" "Enabled"
+                       ubus_freecwmp_output "$parameter" "Enabled"
                        return
                fi
        else
@@ -197,11 +197,11 @@ if [ $rc -eq 0 ]; then
                        return
                fi
                if [ $num2 -gt $static ]; then
-                       freecwmp_output "$parameter" "0"
+                       ubus_freecwmp_output "$parameter" "0"
                        return
                fi
                if [ $num2 -le $static ]; then
-                       freecwmp_output "$parameter" "1"
+                       ubus_freecwmp_output "$parameter" "1"
                        return
                fi
        else
@@ -230,7 +230,7 @@ if [ $rc -eq 0 ]; then
                        let local i=$static-$num2
                        target=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} 
get network.@route[$i].target 2> /dev/null`
                fi
-               freecwmp_output "$parameter" "$target"
+               ubus_freecwmp_output "$parameter" "$target"
                return
        else
                return
@@ -258,7 +258,7 @@ if [ $rc -eq 0 ]; then
                        let local i=$static-$num2
                        netmask=`/sbin/uci ${UCI_CONFIG_DIR:+-c 
$UCI_CONFIG_DIR} get network.@route[$i].netmask 2> /dev/null`
                fi
-               freecwmp_output "$parameter" "$netmask"
+               ubus_freecwmp_output "$parameter" "$netmask"
                return
        else
                return
@@ -288,7 +288,7 @@ if [ $rc -eq 0 ]; then
                        let local i=$static-$num2
                        gateway=`/sbin/uci ${UCI_CONFIG_DIR:+-c 
$UCI_CONFIG_DIR} get network.@route[$i].gateway 2> /dev/null`
                fi
-               freecwmp_output "$parameter" "$gateway"
+               ubus_freecwmp_output "$parameter" "$gateway"
                return
        else
                return
@@ -315,7 +315,7 @@ if [ $rc -eq 0 ]; then
                elif [ $num2 -le $static ]; then
                        val="Static"
                fi
-               freecwmp_output "$parameter" "$val"
+               ubus_freecwmp_output "$parameter" "$val"
                return
        else
                return
@@ -343,11 +343,12 @@ if [ $rc -eq 0 ]; then
                        let local i=$static-$num2
                        metric=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} 
get network.@route[$i].metric 2> /dev/null`
                fi
-               freecwmp_output "$parameter" "$metric"
+               ubus_freecwmp_output "$parameter" "$metric"
                return
        else
                return
        fi
 fi
-
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
+
diff --git a/ext/openwrt/scripts/functions/device_users 
b/ext/openwrt/scripts/functions/device_users
index 0d377f7..d8dba61 100644
--- a/ext/openwrt/scripts/functions/device_users
+++ b/ext/openwrt/scripts/functions/device_users
@@ -6,7 +6,7 @@ local parameter="$1"
 case "$parameter" in
        Device.Users.UserNumberOfEntries)
        local val=`wc -l /etc/passwd | awk '{ print $1 }'`
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
        ;;
 esac
@@ -21,7 +21,7 @@ if [ $rc -eq 0 ]; then
        # TODO: this is very system dependent, for now just look at users shell
        local sed_cmd=`echo -n \'$num; echo p\'`
        local val=`eval sed -n $sed_cmd /etc/passwd | grep -v '/bin/false' | wc 
-l`
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -30,7 +30,7 @@ if [ $rc -eq 0 ]; then
        # TODO: this is very system dependent, for now just look at users shell
        local sed_cmd=`echo -n \'$num; echo p\'`
        local val=`eval sed -n $sed_cmd /etc/passwd | grep -v '/bin/false' | wc 
-l`
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -38,7 +38,7 @@ freecwmp_parse_formated_parameter "$parameter" 
"Device.Users.User.{i}.Username"
 if [ $rc -eq 0 ]; then
        local sed_cmd=`echo -n \'$num; echo p\'`
        local val=`eval sed -n $sed_cmd /etc/passwd | awk -F ':' '{ print $1 }'`
-       freecwmp_value_output "$parameter" "$val"
+       ubus_freecwmp_output "$parameter" "$val"
        return
 fi
 
@@ -48,15 +48,16 @@ if [ $rc -eq 0 ]; then
        #   local sed_cmd=`echo -n \'$num; echo p\'`
        #   local val=`eval sed -n $sed_cmd /etc/shadow | awk -F ':' '{ print 
$2 }'`
        #   freecwmp_value_output "$parameter" "$val"
-       freecwmp_value_output "$parameter" ""
+       ubus_freecwmp_output "$parameter" ""
        return
 fi
 
 freecwmp_parse_formated_parameter "$parameter" 
"Device.Users.User.{i}.Language" "rc" "num"
 if [ $rc -eq 0 ]; then
-       freecwmp_value_output "$parameter" ""
+       ubus_freecwmp_output "$parameter" ""
        return
 fi
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
 
 set_device_users() {
diff --git a/ext/openwrt/scripts/functions/lan_device 
b/ext/openwrt/scripts/functions/lan_device
index 5ba513c..b29f07a 100644
--- a/ext/openwrt/scripts/functions/lan_device
+++ b/ext/openwrt/scripts/functions/lan_device
@@ -3,14 +3,26 @@
 
 get_wlan_enable() {
 local num="$1"
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
wireless.@wifi-device[$num].disabled 2> /dev/null`
+local type="xsd:boolean"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
wireless.@wifi-device[$num].disabled 2> /dev/null`
 let num=$num+1
 if [ "$val" = "1" ]; then
        val="0"
 else
        val="1"
 fi
-freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.$num.Enable" "$val"
+       ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.$num.Enable" "$val" "$type"
+       ;;
+       get_name)
+       val="1"
+       let num=$num+1
+       ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.$num.Enable" "$val"
+       ;;
+esac
+
 }
 
 set_wlan_enable() {
@@ -27,9 +39,20 @@ delay_command "wifi" "wifi" "45"
 
 get_wlan_ssid() {
 local num="$1"
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
wireless.@wifi-iface[$num].ssid 2> /dev/null`
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
wireless.@wifi-iface[$num].ssid 2> /dev/null`
 let num=$num+1
-freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.$num.SSID" "$val"
+       ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.$num.SSID" "$val"
+       ;;
+       get_name)
+       val="1"
+       let num=$num+1
+       ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.$num.SSID" "$val"
+       ;;
+esac
+
 }
 
 set_wlan_ssid() {
@@ -44,30 +67,107 @@ case "$1" in
        InternetGatewayDevice.)
        get_wlan_enable 0
        get_wlan_ssid 0
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.LANDevice.)
        get_wlan_enable 0
        get_wlan_ssid 0
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.LANDevice.1.)
+       get_wlan_enable 0
+       get_wlan_ssid 0
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.LANDevice.1.WLANConfiguration.)
+       get_wlan_enable 0
+       get_wlan_ssid 0
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.)
+       get_wlan_enable 0
+       get_wlan_ssid 0
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.Enable)
+       get_wlan_enable 0
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.SSID)
+       get_wlan_ssid 0
+       return $FAULT_CPE_NO_FAULT
+       ;;
+esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
+}
+
+get_lan_device_name() {
+case "$1" in
+       InternetGatewayDevice.)
+       ubus_freecwmp_output "InternetGatewayDevice.LANDevice." "1"
+       if [ "$2" = "0" ]; then
+               ubus_freecwmp_output "InternetGatewayDevice.LANDevice.1." "1"
+               ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration." "1"
+               ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.1." "1"
+               get_wlan_enable 0
+               get_wlan_ssid 0
+       fi
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.LANDevice.)
+       ubus_freecwmp_output "InternetGatewayDevice.LANDevice." "1"
+       ubus_freecwmp_output "InternetGatewayDevice.LANDevice.1." "1"
+       if [ "$2" = "0" ]; then
+               ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration." "1"
+               ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.1." "1"
+               get_wlan_enable 0
+               get_wlan_ssid 0
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.LANDevice.1.)
+       ubus_freecwmp_output "InternetGatewayDevice.LANDevice.1." "1"
+       ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration." "1"
+       if [ "$2" = "0" ]; then
+               ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.1." "1"
        get_wlan_enable 0
        get_wlan_ssid 0
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.LANDevice.1.WLANConfiguration.)
+       ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration." "1"
+       ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.1." "1"
+       if [ "$2" = "0" ]; then
        get_wlan_enable 0
        get_wlan_ssid 0
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.)
+       ubus_freecwmp_output 
"InternetGatewayDevice.LANDevice.1.WLANConfiguration.1." "1"
+       if [ "$2" = "0" ]; then
        get_wlan_enable 0
        get_wlan_ssid 0
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.Enable)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
        get_wlan_enable 0
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.SSID)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
        get_wlan_ssid 0
+       return $FAULT_CPE_NO_FAULT
        ;;
 esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
 
 set_lan_device() {
diff --git a/ext/openwrt/scripts/functions/management_server 
b/ext/openwrt/scripts/functions/management_server
index 9d1447e..2979863 100644
--- a/ext/openwrt/scripts/functions/management_server
+++ b/ext/openwrt/scripts/functions/management_server
@@ -9,8 +9,16 @@ local 
hostname=`get_management_server_x_freecwmp_org__acs_hostname`
 local port=`get_management_server_x_freecwmp_org__acs_port`
 local path=`get_management_server_x_freecwmp_org__acs_path`
 FLAGS_value=$tmp
-local val=`echo $scheme://$hostname:$port$path`
-freecwmp_output "InternetGatewayDevice.ManagementServer.URL" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`echo $scheme://$hostname:$port$path`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.ManagementServer.URL" "$val"
 }
 
 set_management_server_url() {
@@ -45,8 +53,16 @@ ubus ${UBUS_SOCKET:+-s $UBUS_SOCKET} call tr069 inform '{ 
"event": "value_change
 }
 
 get_management_server_username() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].username 2> /dev/null`
-freecwmp_output "InternetGatewayDevice.ManagementServer.Username" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].username 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.ManagementServer.Username" "$val"
 }
 
 set_management_server_username() {
@@ -54,8 +70,16 @@ set_management_server_username() {
 }
 
 get_management_server_password() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].password 2> /dev/null`
-freecwmp_output "InternetGatewayDevice.ManagementServer.Password" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].password 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output "InternetGatewayDevice.ManagementServer.Password" "$val"
 }
 
 set_management_server_password() {
@@ -63,9 +87,17 @@ set_management_server_password() {
 }
 
 get_management_server_periodic_inform_enable() {
+local val=""
 local parm="InternetGatewayDevice.ManagementServer.PeriodicInformEnable"
+case "$action" in
+       get_value)
 freecwmp_get_parameter_value "val" "$parm"
-freecwmp_output "$parm" "$val"
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+ubus_freecwmp_output "$parm" "$val"
 }
 
 set_management_server_periodic_inform_enable() {
@@ -74,9 +106,17 @@ freecwmp_set_parameter_value "$parm" "$1"
 }
 
 get_management_server_periodic_inform_interval() {
+local val=""
 local parm="InternetGatewayDevice.ManagementServer.PeriodicInformInterval"
+case "$action" in
+       get_value)
 freecwmp_get_parameter_value "val" "$parm"
-freecwmp_output "$parm" "$val"
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+ubus_freecwmp_output "$parm" "$val"
 }
 
 set_management_server_periodic_inform_interval() {
@@ -86,6 +126,8 @@ freecwmp_set_parameter_value "$parm" "$1"
 
 get_management_server_connection_request_url() {
 local val
+case "$action" in
+       get_value)
 if [ -z "$default_management_server_connection_request_url" ]; then
        local tmp=${FLAGS_value}
        FLAGS_value=${FLAGS_TRUE}
@@ -99,13 +141,25 @@ if [ -z 
"$default_management_server_connection_request_url" ]; then
 else
        val=$default_management_server_connection_request_url
 fi
-
-freecwmp_output "InternetGatewayDevice.ManagementServer.ConnectionRequestURL" 
"$val"
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output 
"InternetGatewayDevice.ManagementServer.ConnectionRequestURL" "$val"
 }
 
 get_management_server_connection_request_username() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@local[0].username 2> /dev/null`
-freecwmp_value_output 
"InternetGatewayDevice.ManagementServer.ConnectionRequestUsername" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@local[0].username 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output 
"InternetGatewayDevice.ManagementServer.ConnectionRequestUsername" "$val"
 }
 
 set_management_server_connection_request_username() {
@@ -113,8 +167,16 @@ set_management_server_connection_request_username() {
 }
 
 get_management_server_connection_request_password() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@local[0].password 2> /dev/null`
-freecwmp_value_output 
"InternetGatewayDevice.ManagementServer.ConnectionRequestPassword" "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@local[0].password 2> /dev/null`
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output 
"InternetGatewayDevice.ManagementServer.ConnectionRequestPassword" "$val"
 }
 
 set_management_server_connection_request_password() {
@@ -124,8 +186,20 @@ set_management_server_connection_request_password() {
 # TODO: InternetGatewayDevice.ManagementServer.PeriodicInformTime
 
 get_management_server_x_freecwmp_org__acs_scheme() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].scheme 2> /dev/null`
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].scheme 2> /dev/null`
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+if [ "$FLAGS_value" != "${FLAGS_TRUE}" ]; then
+       ubus_freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Scheme" "$val"
+else
 freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Scheme" "$val"
+fi
 }
 
 set_management_server_x_freecwmp_org__acs_scheme() {
@@ -133,8 +207,20 @@ set_management_server_x_freecwmp_org__acs_scheme() {
 }
 
 get_management_server_x_freecwmp_org__acs_hostname() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].hostname 2> /dev/null`
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].hostname 2> /dev/null`
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+if [ "$FLAGS_value" != "${FLAGS_TRUE}" ]; then
+       ubus_freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Hostname" "$val"
+else
 freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Hostname" "$val"
+fi
 }
 
 set_management_server_x_freecwmp_org__acs_hostname() {
@@ -146,8 +232,20 @@ fi
 }
 
 get_management_server_x_freecwmp_org__acs_port() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].port 2> /dev/null`
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].port 2> /dev/null`
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+if [ "$FLAGS_value" != "${FLAGS_TRUE}" ]; then
+       ubus_freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Port" "$val"
+else
 freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Port" "$val"
+fi
 }
 
 set_management_server_x_freecwmp_org__acs_port() {
@@ -155,8 +253,20 @@ set_management_server_x_freecwmp_org__acs_port() {
 }
 
 get_management_server_x_freecwmp_org__acs_path() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].path 2> /dev/null`
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@acs[0].path 2> /dev/null`
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+if [ "$FLAGS_value" != "${FLAGS_TRUE}" ]; then
+       ubus_freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Path" "$val"
+else
 freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Path" "$val"
+fi
 }
 
 set_management_server_x_freecwmp_org__acs_path() {
@@ -164,8 +274,20 @@ set_management_server_x_freecwmp_org__acs_path() {
 }
 
 get_management_server_x_freecwmp_org__connection_request_port() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@local[0].port 2> /dev/null`
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
freecwmp.@local[0].port 2> /dev/null`
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+if [ "$FLAGS_value" != "${FLAGS_TRUE}" ]; then
+       ubus_freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__Connection_Request_Port"
 "$val"
+else
 freecwmp_output 
"InternetGatewayDevice.ManagementServer.X_freecwmp_org__Connection_Request_Port"
 "$val"
+fi
 }
 
 set_management_server_x_freecwmp_org__connection_request_port() {
@@ -188,6 +310,7 @@ case "$1" in
        get_management_server_x_freecwmp_org__acs_port
        get_management_server_x_freecwmp_org__acs_path
        get_management_server_x_freecwmp_org__connection_request_port
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.)
        get_management_server_url
@@ -203,47 +326,195 @@ case "$1" in
        get_management_server_x_freecwmp_org__acs_port
        get_management_server_x_freecwmp_org__acs_path
        get_management_server_x_freecwmp_org__connection_request_port
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.URL)
        get_management_server_url
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.Username)
        get_management_server_username
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.Password)
        get_management_server_password
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.PeriodicInformEnable)
        get_management_server_periodic_inform_enable
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.PeriodicInformInterval)
        get_management_server_periodic_inform_interval
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.ConnectionRequestURL)
        get_management_server_connection_request_url
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.ConnectionRequestUsername)
        get_management_server_connection_request_username
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.ConnectionRequestPassword)
        get_management_server_connection_request_password
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Scheme)
        get_management_server_x_freecwmp_org__acs_scheme
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Hostname)
        get_management_server_x_freecwmp_org__acs_hostname
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Port)
        get_management_server_x_freecwmp_org__acs_port
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Path)
        get_management_server_x_freecwmp_org__acs_path
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.ManagementServer.X_freecwmp_org__Connection_Request_Port)
        get_management_server_x_freecwmp_org__connection_request_port
+       return $FAULT_CPE_NO_FAULT
        ;;
 esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
+}
+
+get_management_server_name() {
+case "$1" in
+       InternetGatewayDevice.)
+       ubus_freecwmp_output "InternetGatewayDevice.ManagementServer." "0"
+       if [ "$2" = "0" ]; then
+               get_management_server_url
+               get_management_server_username
+               get_management_server_password
+               get_management_server_periodic_inform_enable
+               get_management_server_periodic_inform_interval
+               get_management_server_connection_request_url
+               get_management_server_connection_request_username
+               get_management_server_connection_request_password
+               get_management_server_x_freecwmp_org__acs_scheme
+               get_management_server_x_freecwmp_org__acs_hostname
+               get_management_server_x_freecwmp_org__acs_port
+               get_management_server_x_freecwmp_org__acs_path
+               get_management_server_x_freecwmp_org__connection_request_port
+       fi
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.)
+       ubus_freecwmp_output "InternetGatewayDevice.ManagementServer." "0"
+       get_management_server_url
+       get_management_server_username
+       get_management_server_password
+       get_management_server_periodic_inform_enable
+       get_management_server_periodic_inform_interval
+       get_management_server_connection_request_url
+       get_management_server_connection_request_username
+       get_management_server_connection_request_password
+       get_management_server_x_freecwmp_org__acs_scheme
+       get_management_server_x_freecwmp_org__acs_hostname
+       get_management_server_x_freecwmp_org__acs_port
+       get_management_server_x_freecwmp_org__acs_path
+       get_management_server_x_freecwmp_org__connection_request_port
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.URL)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_url
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.Username)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_username
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.Password)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_password
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.PeriodicInformEnable)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_periodic_inform_enable
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.PeriodicInformInterval)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_periodic_inform_interval
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.ConnectionRequestURL)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_connection_request_url
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.ConnectionRequestUsername)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_connection_request_username
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.ConnectionRequestPassword)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_connection_request_password
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Scheme)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_x_freecwmp_org__acs_scheme
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Hostname)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_x_freecwmp_org__acs_hostname
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Port)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_x_freecwmp_org__acs_port
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.ManagementServer.X_freecwmp_org__ACS_Path)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_x_freecwmp_org__acs_path
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.ManagementServer.X_freecwmp_org__Connection_Request_Port)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
+       get_management_server_x_freecwmp_org__connection_request_port
+       return $FAULT_CPE_NO_FAULT
+       ;;
+esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
 
 set_management_server() {
@@ -304,7 +575,14 @@ get_management_server_generic() {
        check_parameter_management_server_generic "$1" ; _tmp=$? ; if [ "$_tmp" 
-eq 1 ]; then return 0; fi
 
        freecwmp_get_parameter_value "val" "$1"
-       freecwmp_value_output "$1" "$val"
+       ubus_freecwmp_output "$1" "$val"
+}
+
+get_management_server_generic_name() {
+       check_parameter_management_server_generic "$1" ; _tmp=$? ; if [ "$_tmp" 
-eq 1 ]; then return $FAULT_CPE_INVALID_PARAMETER_NAME; fi
+
+       local val="1"
+       ubus_freecwmp_output "$1" "$val"
 }
 
 set_management_server_generic() {
diff --git a/ext/openwrt/scripts/functions/misc 
b/ext/openwrt/scripts/functions/misc
index 2e0210c..13f2142 100644
--- a/ext/openwrt/scripts/functions/misc
+++ b/ext/openwrt/scripts/functions/misc
@@ -3,21 +3,25 @@
 
 get_misc_cpu_usage() {
 local val=`uptime | awk -F'average: ' '{ print $2 }' | awk -F',' '{ print $1 
}' | awk -F'.' '{ print $2 }'`
-freecwmp_value_output "Device.DeviceInfo.ProcessStatus.CPUUsage" "$val"
+ubus_freecwmp_output "Device.DeviceInfo.ProcessStatus.CPUUsage" "$val"
 }
 
 get_misc_process_number() {
 local val=`ps | grep -v COMMAND | wc -l`
-freecwmp_value_output "Device.DeviceInfo.ProcessStatus.ProcessNumberOfEntries" 
"$val"
+local type="xsd:unsignedInt"
+ubus_freecwmp_output "Device.DeviceInfo.ProcessStatus.ProcessNumberOfEntries" 
"$val" "$type"
 }
 
 get_misc() {
 case "$1" in
        Device.DeviceInfo.ProcessStatus.CPUUsage)
        get_misc_cpu_usage
+       return $FAULT_CPE_NO_FAULT
        ;;
        Device.DeviceInfo.ProcessStatus.ProcessNumberOfEntries)
        get_misc_process_number
+       return $FAULT_CPE_NO_FAULT
        ;;
 esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
diff --git a/ext/openwrt/scripts/functions/wan_device 
b/ext/openwrt/scripts/functions/wan_device
index 77cb63f..5c128e7 100644
--- a/ext/openwrt/scripts/functions/wan_device
+++ b/ext/openwrt/scripts/functions/wan_device
@@ -3,35 +3,76 @@
 
 get_wan_device_mng_status() {
 # TODO: Unconfigured ; Connecting ; Connected ; PendingDisconnect ; 
Disconneting ; Disconnected 
-local val="Connected"
-freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ConnectionStatus"
 "$val"
+local val=""
+local type="xsd:boolean"
+case "$action" in
+       get_value)
+       val="Connected"
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ConnectionStatus"
 "$val"
 }
 
 get_wan_device_mng_interface_ip() {
-local val
+local val=""
+case "$action" in
+       get_value)
 if [ -z "$default_wan_device_mng_interface_ip" ]; then
        val=`network_get_ipaddr val mng`
 else
        val=$default_wan_device_mng_interface_ip
 fi
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+if [ "$FLAGS_value" != "${FLAGS_TRUE}" ]; then
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress"
 "$val"
+else
 freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress"
 "$val"
+fi
 }
 
 get_wan_device_mng_interface_mac() {
+local val=""
+case "$action" in
+       get_value)
 if [ -z "$default_wan_device_mng_interface_mac" ]; then
        val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
network.mng.macaddr`
 else
        val=$default_wan_device_mng_interface_mac
 fi
+       ;;
+       get_name)
+       val="0"
+       ;;
+esac
+if [ "$FLAGS_value" != "${FLAGS_TRUE}" ]; then
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress"
 "$val"
+else
 freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress"
 "$val"
+fi
 }
 
 get_wan_device_wan_ppp_enable() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
network.wan.auto 2> /dev/null`
+local val=""
+local type="xsd:boolean"
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
network.wan.auto 2> /dev/null`
 if [ -z $val ]; then
        val="1"
 fi
-freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Enable"
 "$val"
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Enable"
 "$val" "$type"
 }
 
 set_wan_device_wan_ppp_enable() {
@@ -46,8 +87,16 @@ fi
 }
 
 get_wan_device_wan_ppp_username() {
-local val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
network.wan.username 2> /dev/null`
-freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Username"
 "$val"
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
network.wan.username 2> /dev/null`
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Username"
 "$val"
 }
 
 set_wan_device_wan_ppp_username() {
@@ -55,7 +104,16 @@ set_wan_device_wan_ppp_username() {
 }
 
 get_wan_device_wan_ppp_password() {
-freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Password"
 ""
+local val=""
+case "$action" in
+       get_value)
+       val=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} get 
network.wan.password 2> /dev/null`
+       ;;
+       get_name)
+       val="1"
+       ;;
+esac
+ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Password"
 "$val"
 }
 
 set_wan_device_wan_ppp_password() {
@@ -71,68 +129,211 @@ case "$1" in
        get_wan_device_wan_ppp_enable
        get_wan_device_wan_ppp_username
        get_wan_device_wan_ppp_password
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.WANDevice.)
+       get_wan_device_mng_status
+       get_wan_device_mng_interface_ip
+       get_wan_device_mng_interface_mac
+       get_wan_device_wan_ppp_enable
+       get_wan_device_wan_ppp_username
+       get_wan_device_wan_ppp_password
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.WANDevice.1.)
+       get_wan_device_mng_status
+       get_wan_device_mng_interface_ip
+       get_wan_device_mng_interface_mac
+       get_wan_device_wan_ppp_enable
+       get_wan_device_wan_ppp_username
+       get_wan_device_wan_ppp_password
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.WANDevice.1.WANConnectionDevice.)
+       get_wan_device_mng_status
+       get_wan_device_mng_interface_ip
+       get_wan_device_mng_interface_mac
+       get_wan_device_wan_ppp_enable
+       get_wan_device_wan_ppp_username
+       get_wan_device_wan_ppp_password
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.)
+       get_wan_device_mng_status
+       get_wan_device_mng_interface_ip
+       get_wan_device_mng_interface_mac
+       get_wan_device_wan_ppp_enable
+       get_wan_device_wan_ppp_username
+       get_wan_device_wan_ppp_password
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.)
+       get_wan_device_mng_status
+       get_wan_device_mng_interface_ip
+       get_wan_device_mng_interface_mac
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.)
+       get_wan_device_mng_status
+       get_wan_device_mng_interface_ip
+       get_wan_device_mng_interface_mac
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ConnectionStatus)
+       get_wan_device_mng_status
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress)
+       get_wan_device_mng_interface_ip
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress)
+       get_wan_device_mng_interface_mac
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Enable)
+       get_wan_device_wan_ppp_enable
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Username)
+       get_wan_device_wan_ppp_username
+       return $FAULT_CPE_NO_FAULT
+       ;;
+       
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Password)
+       get_wan_device_wan_ppp_password
+       return $FAULT_CPE_NO_FAULT
+       ;;
+esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
+}
+
+get_wan_device_name() {
+case "$1" in
+       InternetGatewayDevice.)
+       ubus_freecwmp_output "InternetGatewayDevice.WANDevice." "1"
+       if [ "$2" = "0" ]; then
+               get_wan_device_mng_status
+               get_wan_device_mng_interface_ip
+               get_wan_device_mng_interface_mac
+               get_wan_device_wan_ppp_enable
+               get_wan_device_wan_ppp_username
+               get_wan_device_wan_ppp_password
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.WANDevice.)
+       ubus_freecwmp_output "InternetGatewayDevice.WANDevice." "1"
+       ubus_freecwmp_output "InternetGatewayDevice.WANDevice.1." "1"
+       if [ "$2" = "0" ]; then
        get_wan_device_mng_status
        get_wan_device_mng_interface_ip
        get_wan_device_mng_interface_mac
        get_wan_device_wan_ppp_enable
        get_wan_device_wan_ppp_username
        get_wan_device_wan_ppp_password
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.WANDevice.1.)
+       ubus_freecwmp_output "InternetGatewayDevice.WANDevice.1." "1"
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice." "1"
+       if [ "$2" = "0" ]; then
        get_wan_device_mng_status
        get_wan_device_mng_interface_ip
        get_wan_device_mng_interface_mac
        get_wan_device_wan_ppp_enable
        get_wan_device_wan_ppp_username
        get_wan_device_wan_ppp_password
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.WANDevice.1.WANConnectionDevice.)
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice." "1"
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1." "1"
+       if [ "$2" = "0" ]; then
        get_wan_device_mng_status
        get_wan_device_mng_interface_ip
        get_wan_device_mng_interface_mac
        get_wan_device_wan_ppp_enable
        get_wan_device_wan_ppp_username
        get_wan_device_wan_ppp_password
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.)
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1." "1"
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection." "1"
+       if [ "$2" = "0" ]; then
        get_wan_device_mng_status
        get_wan_device_mng_interface_ip
        get_wan_device_mng_interface_mac
        get_wan_device_wan_ppp_enable
        get_wan_device_wan_ppp_username
        get_wan_device_wan_ppp_password
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.)
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection." "1"
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1." "1"
+       if [ "$2" = "0" ]; then
        get_wan_device_mng_status
        get_wan_device_mng_interface_ip
        get_wan_device_mng_interface_mac
+       fi
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.)
+       ubus_freecwmp_output 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1." "1"
        get_wan_device_mng_status
        get_wan_device_mng_interface_ip
        get_wan_device_mng_interface_mac
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ConnectionStatus)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
        get_wan_device_mng_status
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
        get_wan_device_mng_interface_ip
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.MACAddress)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
        get_wan_device_mng_interface_mac
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Enable)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
        get_wan_device_wan_ppp_enable
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Username)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
        get_wan_device_wan_ppp_username
+       return $FAULT_CPE_NO_FAULT
        ;;
        
InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANPPPConnection.1.Password)
+       if [ "$2" = "1" ]; then
+               return $FAULT_CPE_INVALID_ARGUMENTS
+       fi
        get_wan_device_wan_ppp_password
+       return $FAULT_CPE_NO_FAULT
        ;;
 esac
+return $FAULT_CPE_INVALID_PARAMETER_NAME
 }
 
 set_wan_device() {
diff --git a/src/external.c b/src/external.c
index fa802af..e62b14d 100644
--- a/src/external.c
+++ b/src/external.c
@@ -25,15 +25,81 @@
 #include "freecwmp.h"
 
 static struct uloop_process uproc;
+pthread_t ubus_thread;
+LIST_HEAD(external_list_parameter);
+
+void *thread_uloop_run (void *v)
+{
+       uloop_run();
+       return NULL;
+}
+
+void external_add_list_paramameter(char *param_name, char *param_data, char 
*param_type, char *fault_code)
+{
+       struct external_parameter *external_parameter;
+       struct list_head *ilist; int i =0;
+       external_parameter = calloc(1, sizeof(struct external_parameter));
+       list_add_tail(&external_parameter->list,&external_list_parameter);
+       if (param_name) external_parameter->name = strdup(param_name);
+       if (param_data) external_parameter->data = strdup(param_data);
+       if (param_type) external_parameter->type = strdup(param_type);
+       if (fault_code) external_parameter->fault_code = strdup(fault_code);
+}
+
+void external_free_list_parameter()
+{
+       struct external_parameter *external_parameter;
+       while (external_list_parameter.next!=&external_list_parameter) {
+               external_parameter = list_entry(external_list_parameter.next, 
struct external_parameter, list);
+               list_del(&external_parameter->list);
+               CFREE(external_parameter->name);
+               CFREE(external_parameter->data);
+               CFREE(external_parameter->type);
+               CFREE(external_parameter->fault_code);
+               CFREE(external_parameter);
+       }
+}
+
+void external_get_head_parameter_data(char *data_buffer)
+{
+       struct external_parameter *external_parameter;
+       if (external_list_parameter.next!=&external_list_parameter) {
+               external_parameter = list_entry(external_list_parameter.next, 
struct external_parameter, list);
+               if (external_parameter->data) strcpy(data_buffer, 
external_parameter->data);
+               list_del(&external_parameter->list);
+               CFREE(external_parameter->name);
+               CFREE(external_parameter->data);
+               CFREE(external_parameter->type);
+               CFREE(external_parameter->fault_code);
+               CFREE(external_parameter);
+       }
+}
 
 int external_get_action(char *action, char *name, char **value)
 {
+       struct external_parameter *external_parameter;
+       external_get_action_common(action, name, NULL);
+       if (external_list_parameter.next!=&external_list_parameter) {
+               external_parameter = list_entry(external_list_parameter.next, 
struct external_parameter, list);
+               if (external_parameter->data)
+                       *value = external_parameter->data;
+               list_del(&external_parameter->list);
+               CFREE(external_parameter->name);
+               CFREE(external_parameter->data);
+               CFREE(external_parameter->type);
+               CFREE(external_parameter->fault_code);
+               CFREE(external_parameter);
+       }
+       external_free_list_parameter();
+}
+
+int external_get_action_common(char *action, char *name, char *arg /* arg is 
added for GetParameterNames NextLevel argument*/)
+{
        freecwmp_log_message(NAME, L_NOTICE,
                             "executing get %s '%s'\n", action, name);
 
-       int pfds[2];
-       if (pipe(pfds) < 0)
-               return -1;
+
+       pthread_create(&ubus_thread, NULL, &thread_uloop_run, NULL);
 
        if ((uproc.pid = fork()) == -1)
                goto error;
@@ -45,57 +111,106 @@ int external_get_action(char *action, char *name, char 
**value)
                int i = 0;
                argv[i++] = "/bin/sh";
                argv[i++] = fc_script;
-               argv[i++] = "--newline";
-               argv[i++] = "--value";
                argv[i++] = "get";
                argv[i++] = action;
                argv[i++] = name;
+               if(arg) argv[i++] = arg;
                argv[i++] = NULL;
 
-               close(pfds[0]);
-               dup2(pfds[1], 1);
-               close(pfds[1]);
-
                execvp(argv[0], (char **) argv);
                exit(ESRCH);
 
        } else if (uproc.pid < 0)
                goto error;
 
-       /* parent */
-       close(pfds[1]);
-
        int status;
        while (wait(&status) != uproc.pid) {
                DD("waiting for child to exit");
        }
+       pthread_cancel(ubus_thread);
+       pthread_join(ubus_thread,NULL);
 
-       char buffer[2];
-       ssize_t rxed;
+       return 0;
+
+error:
+       return -1;
 
-       *value = (char *) calloc(1, sizeof(char));
-       while ((rxed = read(pfds[0], buffer, sizeof(buffer))) > 0) {
-               *value = (char *) realloc(*value, (strlen(*value) + rxed + 1) * 
sizeof(char));
-               if (!(*value)) goto error;
-               bzero(*value + strlen(*value), rxed + 1);
-               memcpy(*value + strlen(*value), buffer, rxed);
        }
 
-       if (!strlen(*value)) {
-               FREE(*value);
-               goto done;
+int external_get_action_write(char *action, char *name, char *arg)
+{
+       freecwmp_log_message(NAME, L_NOTICE,
+               "adding to get %s script '%s'\n", action, name);
+
+       FILE *fp;
+
+       if (access(fc_script_get_actions, R_OK | W_OK | X_OK) != -1) {
+               fp = fopen(fc_script_get_actions, "a");
+               if (!fp) return -1;
+       } else {
+               fp = fopen(fc_script_get_actions, "w");
+               if (!fp) return -1;
+
+               fprintf(fp, "#!/bin/sh\n");
+
+               if (chmod(fc_script_get_actions,
+                       strtol("0700", 0, 8)) < 0) {
+                       return -1;
+               }
        }
 
-       if (rxed < 0)
-               goto error;
+#ifdef DUMMY_MODE
+       fprintf(fp, "/bin/sh `pwd`/%s get %s %s %s\n", fc_script, action, name, 
arg?arg:"");
+#else
+       fprintf(fp, "/bin/sh %s get %s %s %s\n", fc_script, action, name, 
arg?arg:"");
+#endif
+
+       fclose(fp);
 
-done:
-       close(pfds[0]);
        return 0;
+}
 
-error:
-       close(pfds[0]);
+int external_get_action_execute()
+{
+       freecwmp_log_message(NAME, L_NOTICE, "executing get script\n");
+
+       pthread_create(&ubus_thread, NULL, &thread_uloop_run, NULL);
+
+       if ((uproc.pid = fork()) == -1) {
+               return -1;
+       }
+
+       if (uproc.pid == 0) {
+               /* child */
+
+               const char *argv[3];
+               int i = 0;
+               argv[i++] = "/bin/sh";
+               argv[i++] = fc_script_get_actions;
+               argv[i++] = NULL;
+
+               execvp(argv[0], (char **) argv);
+               exit(ESRCH);
+
+       } else if (uproc.pid < 0)
+               return -1;
+
+       /* parent */
+       int status;
+       while (wait(&status) != uproc.pid) {
+               DD("waiting for child to exit");
+       }
+
+       pthread_cancel(ubus_thread);
+       pthread_join(ubus_thread,NULL);
+
+
+       // TODO: add some kind of checks
+
+       if (remove(fc_script_get_actions) != 0)
        return -1;
+
+       return 0;
 }
 
 int external_set_action_write(char *action, char *name, char *value)
diff --git a/src/external.h b/src/external.h
index 8606266..fcf9819 100644
--- a/src/external.h
+++ b/src/external.h
@@ -9,6 +9,7 @@
 
 #ifndef _FREECWMP_EXTERNAL_H__
 #define _FREECWMP_EXTERNAL_H__
+#include <libubox/list.h>
 
 #ifdef DUMMY_MODE
 static char *fc_script = "./ext/openwrt/scripts/freecwmp.sh";
@@ -16,12 +17,27 @@ static char *fc_script = 
"./ext/openwrt/scripts/freecwmp.sh";
 static char *fc_script = "/usr/sbin/freecwmp";
 #endif
 static char *fc_script_set_actions = "/tmp/freecwmp_set_action_values.sh";
+static char *fc_script_get_actions = "/tmp/freecwmp_get_action_values.sh";
+
+struct external_parameter {
+       struct list_head list;
+       char *name;
+       char *data; /* notification for GetParameterAttribute; writable for 
GetParameterNames; value for GetParameterValues*/
+       char *type;
+       char *fault_code;
+};
+
 
 int external_get_action(char *action, char *name, char **value);
+int external_get_action_common(char *action, char *name, char *arg);
+int external_get_action_write(char *action, char *name, char *arg);
+int external_get_action_execute();
 int external_set_action_write(char *action, char *name, char *value);
 int external_set_action_execute();
 int external_simple(char *arg);
 int external_download(char *url, char *size);
+void external_add_list_paramameter(char *param_name, char *param_data, char 
*param_type, char *fault_code);
+void external_free_list_parameter();
 
 #endif
 
diff --git a/src/freecwmp.c b/src/freecwmp.c
index 7d6a672..e6742a4 100644
--- a/src/freecwmp.c
+++ b/src/freecwmp.c
@@ -18,6 +18,9 @@
 #include <arpa/inet.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <signal.h>
+
+
 
 #include <libfreecwmp.h>
 #include <libubox/uloop.h>
@@ -194,11 +197,27 @@ netlink_init(void)
        return 0;
 }
 
+void signal_kill_all_handler(int sig)
+{
+     pthread_exit(NULL);
+}
+
+
+
 int main (int argc, char **argv)
 {
        freecwmp_log_message(NAME, L_NOTICE, "daemon started\n");
 
        bool foreground = false;
+       struct sigaction sigint_action;
+
+       sigint_action.sa_handler = &signal_kill_all_handler;
+       sigemptyset (&sigint_action.sa_mask);
+       /* reset handler in case when pthread_cancel didn't stop
+          threads for some reason */
+       sigint_action.sa_flags = SA_RESETHAND;
+       sigaction(SIGTERM, &sigint_action, NULL);
+
 
        setlocale(LC_CTYPE, "");
        umask(0037);
diff --git a/src/freecwmp.h b/src/freecwmp.h
index c5304c8..3777181 100644
--- a/src/freecwmp.h
+++ b/src/freecwmp.h
@@ -13,6 +13,7 @@
 #define NAME   "freecwmpd"
 
 #define FREE(x) free(x); x = NULL;
+#define CFREE(x) if (x) free(x);
 
 #ifdef DEBUG
 #define D(format, ...) fprintf(stderr, "%s(%d): " format, __func__, __LINE__, 
## __VA_ARGS__)
diff --git a/src/ubus.c b/src/ubus.c
index ce25e07..db9d5d3 100644
--- a/src/ubus.c
+++ b/src/ubus.c
@@ -16,6 +16,7 @@
 #include "config.h"
 #include "cwmp.h"
 #include "freecwmp.h"
+#include "external.h"
 
 static struct ubus_context *ctx = NULL;
 
@@ -98,9 +99,135 @@ freecwmpd_handle_reload(struct ubus_context *ctx, struct 
ubus_object *obj,
        return 0;
 }
 
+static enum getParamValues {
+       GETPARAMVALUES_PARAM,
+       GETPARAMVALUES_VALUE,
+       GETPARAMVALUES_TYPE,
+       GETPARAMVALUES_FAULT,
+       __GETPARAMVALUES_MAX
+};
+
+static const struct blobmsg_policy getParamValues_policy[] = {
+       [GETPARAMVALUES_PARAM] = { .name = "parameter", .type = 
BLOBMSG_TYPE_STRING },
+       [GETPARAMVALUES_VALUE] = { .name = "value", .type = BLOBMSG_TYPE_STRING 
},
+       [GETPARAMVALUES_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING },
+       [GETPARAMVALUES_FAULT] = { .name = "fault_code", .type = 
BLOBMSG_TYPE_STRING },
+};
+
+static int
+freecwmpd_handle_getParamValues(struct ubus_context *ctx, struct ubus_object 
*obj,
+                       struct ubus_request_data *req, const char *method,
+                       struct blob_attr *msg)
+{
+       struct blob_attr *tb[__GETPARAMVALUES_MAX];
+
+       blobmsg_parse(getParamValues_policy, ARRAY_SIZE(getParamValues_policy), 
tb,
+                     blob_data(msg), blob_len(msg));
+
+       if (!tb[GETPARAMVALUES_PARAM])
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
+
+       freecwmp_log_message(NAME, L_NOTICE,
+                            "triggered ubus GetParameterValues parameter %s\n",
+                            blobmsg_data(tb[GETPARAMVALUES_PARAM]));
+
+
+       external_add_list_paramameter(blobmsg_data(tb[GETPARAMVALUES_PARAM]),
+                       tb[GETPARAMVALUES_VALUE]? 
blobmsg_data(tb[GETPARAMVALUES_VALUE]) : NULL,
+                       tb[GETPARAMVALUES_TYPE]? 
blobmsg_data(tb[GETPARAMVALUES_TYPE]) : "xsd:string",
+                       tb[GETPARAMVALUES_FAULT]? 
blobmsg_data(tb[GETPARAMVALUES_FAULT]) : NULL);
+
+       return 0;
+}
+
+static enum getParamNames {
+       GETPARAMNAMES_PARAM,
+       GETPARAMNAMES_WRITABLE,
+       GETPARAMNAMES_FAULT,
+       __GETPARAMNAMES_MAX
+};
+
+static const struct blobmsg_policy getParamNames_policy[] = {
+       [GETPARAMNAMES_PARAM] = { .name = "parameter", .type = 
BLOBMSG_TYPE_STRING },
+       [GETPARAMNAMES_WRITABLE] = { .name = "writable", .type = 
BLOBMSG_TYPE_STRING },
+       [GETPARAMNAMES_FAULT] = { .name = "fault_code", .type = 
BLOBMSG_TYPE_STRING },
+};
+
+static int
+freecwmpd_handle_getParamNames(struct ubus_context *ctx, struct ubus_object 
*obj,
+                       struct ubus_request_data *req, const char *method,
+                       struct blob_attr *msg)
+{
+       struct blob_attr *tb[__GETPARAMNAMES_MAX];
+
+       blobmsg_parse(getParamNames_policy, ARRAY_SIZE(getParamNames_policy), 
tb,
+                     blob_data(msg), blob_len(msg));
+
+       if (!tb[GETPARAMNAMES_PARAM])
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
+
+       freecwmp_log_message(NAME, L_NOTICE,
+                            "triggered ubus GetParameterNames parameter %s\n",
+                            blobmsg_data(tb[GETPARAMNAMES_PARAM]));
+
+
+       external_add_list_paramameter(blobmsg_data(tb[GETPARAMNAMES_PARAM]),
+                       tb[GETPARAMNAMES_WRITABLE]? 
blobmsg_data(tb[GETPARAMNAMES_WRITABLE]) : NULL,
+                       NULL,
+                       tb[GETPARAMNAMES_FAULT]? 
blobmsg_data(tb[GETPARAMNAMES_FAULT]) : NULL);
+
+       return 0;
+}
+
+static enum getParamAttributes {
+       GETPARAMATTRIBUTES_PARAM,
+       GETPARAMATTRIBUTES_NOTIF,
+       GETPARAMATTRIBUTES_FAULT,
+       __GETPARAMATTRIBUTES_MAX
+};
+
+static const struct blobmsg_policy getParamAttributes_policy[] = {
+       [GETPARAMATTRIBUTES_PARAM] = { .name = "parameter", .type = 
BLOBMSG_TYPE_STRING },
+       [GETPARAMATTRIBUTES_NOTIF] = { .name = "notification", .type = 
BLOBMSG_TYPE_STRING },
+       [GETPARAMATTRIBUTES_FAULT] = { .name = "fault_code", .type = 
BLOBMSG_TYPE_STRING },
+};
+
+static int
+freecwmpd_handle_getParamAttributes(struct ubus_context *ctx, struct 
ubus_object *obj,
+                       struct ubus_request_data *req, const char *method,
+                       struct blob_attr *msg)
+{
+       struct blob_attr *tb[__GETPARAMATTRIBUTES_MAX];
+
+       blobmsg_parse(getParamAttributes_policy, 
ARRAY_SIZE(getParamAttributes_policy), tb,
+                     blob_data(msg), blob_len(msg));
+
+       if (!tb[GETPARAMATTRIBUTES_PARAM])
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
+       if (!tb[GETPARAMATTRIBUTES_NOTIF])
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
+       freecwmp_log_message(NAME, L_NOTICE,
+                            "triggered ubus GetParameterAttributes parameter 
%s\n",
+                            blobmsg_data(tb[GETPARAMATTRIBUTES_PARAM]));
+
+       
external_add_list_paramameter(blobmsg_data(tb[GETPARAMATTRIBUTES_PARAM]),
+                                     
blobmsg_data(tb[GETPARAMATTRIBUTES_NOTIF]),
+                                     NULL,
+                                     
blobmsg_data(tb[GETPARAMATTRIBUTES_FAULT]));
+
+       return 0;
+}
+
 static const struct ubus_method freecwmp_methods[] = {
        UBUS_METHOD("notify", freecwmpd_handle_notify, notify_policy),
        UBUS_METHOD("inform", freecwmpd_handle_inform, inform_policy),
+       UBUS_METHOD("GetParameterValues", freecwmpd_handle_getParamValues, 
getParamValues_policy),
+       UBUS_METHOD("GetParameterNames", freecwmpd_handle_getParamNames, 
getParamNames_policy),
+       UBUS_METHOD("GetParameterAttributes", 
freecwmpd_handle_getParamAttributes, getParamAttributes_policy),
        { .name = "reload", .handler = freecwmpd_handle_reload },
 };
 
diff --git a/src/xml.c b/src/xml.c
index 22cfbcd..000f216 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -21,6 +21,8 @@
 #include "messages.h"
 #include "time.h"
 
+extern struct list_head external_list_parameter;
+
 struct rpc_method {
        const char *name;
        int (*handler)(mxml_node_t *body_in, mxml_node_t *tree_in,
@@ -49,6 +51,7 @@ static struct cwmp_namespaces
 const struct rpc_method rpc_methods[] = {
        { "SetParameterValues", xml_handle_set_parameter_values },
        { "GetParameterValues", xml_handle_get_parameter_values },
+       { "GetParameterNames", xml_handle_get_parameter_names },
        { "SetParameterAttributes", xml_handle_set_parameter_attributes },
        { "Download", xml_handle_download },
        { "FactoryReset", xml_handle_factory_reset },
@@ -217,6 +220,7 @@ int xml_prepare_inform_message(char **msg_out)
 {
        mxml_node_t *tree, *b;
        char *c, *tmp;
+       struct external_parameter *external_parameter;
 
 #ifdef DUMMY_MODE
        FILE *fp;
@@ -335,37 +339,33 @@ int xml_prepare_inform_message(char **msg_out)
        if (mxmlGetType(b) != MXML_ELEMENT)
                goto error;
 
-       tmp = 
"InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress";
-       b = mxmlFindElementText(tree, tree, tmp, MXML_DESCEND);
-       if (!b) goto error;
-
-       b = b->parent->next->next;
-       if (mxmlGetType(b) != MXML_ELEMENT)
+       
external_get_action_write("value","InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.ExternalIPAddress",
 NULL);
+       
external_get_action_write("value","InternetGatewayDevice.ManagementServer.ConnectionRequestURL",
 NULL);
+       if (external_get_action_execute())
                goto error;
 
-       c = NULL;
-       if (external_get_action("value", tmp, &c)) goto error;
-       if (c) {
-               b = mxmlNewText(b, 0, c);
-               FREE(c);
-               if (!b) goto error;
-       }
-
-       tmp = "InternetGatewayDevice.ManagementServer.ConnectionRequestURL";
-       b = mxmlFindElementText(tree, tree, tmp, MXML_DESCEND);
-       if (!b) goto error;
+       while (external_list_parameter.next!=&external_list_parameter)
+       {
+               external_parameter = list_entry(external_list_parameter.next, 
struct external_parameter, list);
+               b = mxmlFindElementText(tree, tree, external_parameter->name, 
MXML_DESCEND);
+               if (!b) continue;
 
        b = b->parent->next->next;
        if (mxmlGetType(b) != MXML_ELEMENT)
                goto error;
 
-       c = NULL;
-       if (external_get_action("value", tmp, &c)) goto error;
-       if (c) {
-               b = mxmlNewText(b, 0, c);
-               FREE(c);
+               if (external_parameter->data) {
+                       b = mxmlNewText(b, 0, external_parameter->data);
                if (!b) goto error;
        }
+               list_del(&external_parameter->list);
+               CFREE(external_parameter->name);
+               CFREE(external_parameter->data);
+               CFREE(external_parameter->type);
+               CFREE(external_parameter->fault_code);
+               CFREE(external_parameter);
+       }
+
 
        if (xml_prepare_notifications_inform(tree))
                goto error;
@@ -376,6 +376,7 @@ int xml_prepare_inform_message(char **msg_out)
        return 0;
 
 error:
+       external_free_list_parameter();
        mxmlDelete(tree);
        return -1;
 }
@@ -628,10 +629,11 @@ int xml_handle_get_parameter_values(mxml_node_t *body_in,
                                    mxml_node_t *tree_in,
                                    mxml_node_t *tree_out)
 {
-       mxml_node_t *n, *b = body_in;
+       mxml_node_t *n, *ParameterList, *b = body_in;
+       struct external_parameter *external_parameter;
        char *parameter_name = NULL;
        char *parameter_value = NULL;
-       char *c;
+       char *c = NULL;
        int counter = 0;
 
        n = mxmlFindElement(tree_out, tree_out, "soap_env:Body",
@@ -655,29 +657,44 @@ int xml_handle_get_parameter_values(mxml_node_t *body_in,
                    !strcmp(b->parent->value.element.name, "string")) {
                        parameter_name = b->value.text.string;
                }
-
+               if (b && b->type == MXML_ELEMENT && /* added in order to 
support GetParameterValues with empty string*/
+                       !strcmp(b->value.element.name, "string") &&
+                       !b->child) {
+                       parameter_name = "";
+               }
                if (parameter_name) {
                        if (!config_get_cwmp(parameter_name, &parameter_value)) 
{
+                               
external_add_list_paramameter(parameter_name,parameter_value,"xsd:string",NULL);
+                               FREE(parameter_value);
                                // got the parameter value using libuci
-                       } else if (!external_get_action("value",
-                                       parameter_name, &parameter_value)) {
+                       } else if 
(!external_get_action_write("value",parameter_name, NULL)) {
                                // got the parameter value via external script
                        } else {
                                // error occurred when getting parameter value
                                goto out;
                        }
-                       counter++;
+               }
+               b = mxmlWalkNext(b, body_in, MXML_DESCEND);
+               parameter_name = NULL;
+       }
 
-                       n = mxmlFindElement(tree_out, tree_out, 
"ParameterList", NULL, NULL, MXML_DESCEND);
-                       if (!n) goto out;
+       if (external_get_action_execute())
+               goto out;
 
-                       n = mxmlNewElement(n, "ParameterValueStruct");
+       ParameterList = mxmlFindElement(tree_out, tree_out, "ParameterList", 
NULL, NULL, MXML_DESCEND);
+       if (!ParameterList) goto out;
+
+       while (external_list_parameter.next!=&external_list_parameter) {
+
+               external_parameter = list_entry(external_list_parameter.next, 
struct external_parameter, list);
+
+               n = mxmlNewElement(ParameterList, "ParameterValueStruct");
                        if (!n) goto out;
 
                        n = mxmlNewElement(n, "Name");
                        if (!n) goto out;
 
-                       n = mxmlNewText(n, 0, parameter_name);
+               n = mxmlNewText(n, 0, external_parameter->name);
                        if (!n) goto out;
 
                        n = n->parent->parent;
@@ -685,42 +702,144 @@ int xml_handle_get_parameter_values(mxml_node_t *body_in,
                        if (!n) goto out;
 
 #ifdef ACS_MULTI
-                       mxmlElementSetAttr(n, "xsi:type", "xsd:string");
+               mxmlElementSetAttr(n, "xsi:type", external_parameter->type);
 #endif
-                       n = mxmlNewText(n, 0, parameter_value ? parameter_value 
: "");
+               n = mxmlNewText(n, 0, external_parameter->data? 
external_parameter->data : "");
                        if (!n) goto out;
 
-                       /*
-                        * three day's work to finally find memory leak if we
-                        * free parameter_name;
-                        * it points to: b->value.text.string
-                        *
-                        * also, parameter_value can be NULL so we don't do 
checks
-                        */
-                       parameter_name = NULL;
+               counter++;
+               
+               list_del(&external_parameter->list);
+               CFREE(external_parameter->name);
+               CFREE(external_parameter->data);
+               CFREE(external_parameter->type);
+               CFREE(external_parameter->fault_code);
+               CFREE(external_parameter);
+       }
+#ifdef ACS_MULTI
+       b = mxmlFindElement(tree_out, tree_out, "ParameterList", 
+                           NULL, NULL, MXML_DESCEND);
+       if (!b) goto out;
+
+       if (asprintf(&c, "cwmp:ParameterValueStruct[%d]", counter) == -1)
+               goto out;
+
+       mxmlElementSetAttr(b, "soap_enc:arrayType", c);
+       FREE(c);
+#endif
+
+       return 0;
+
+out:
+       external_free_list_parameter();
+       return -1;
                }
                
-               FREE(parameter_value);
+int xml_handle_get_parameter_names(mxml_node_t *body_in,
+                                   mxml_node_t *tree_in,
+                                   mxml_node_t *tree_out)
+{
+       mxml_node_t *n, *ParameterList, *b = body_in;
+       struct external_parameter *external_parameter;
+       char *parameter_name = NULL;
+       char *NextLevel = NULL;
+       char *c;
+       int counter = 0;
+
+       n = mxmlFindElement(tree_out, tree_out, "soap_env:Body",
+                           NULL, NULL, MXML_DESCEND);
+       if (!n) return -1;
+
+       n = mxmlNewElement(n, "cwmp:GetParameterNamesResponse");
+       if (!n) return -1;
+
+       n = mxmlNewElement(n, "ParameterList");
+       if (!n) return -1;
+
+#ifdef ACS_MULTI
+       mxmlElementSetAttr(n, "xsi:type", "soap_enc:Array");
+#endif
+
+       while (b) {
+               if (b && b->type == MXML_TEXT &&
+                       b->value.text.string &&
+                       b->parent->type == MXML_ELEMENT &&
+                       !strcmp(b->parent->value.element.name, 
"ParameterPath")) {
+                       parameter_name = b->value.text.string;
+               }
+               if (b && b->type == MXML_ELEMENT && /* added in order to 
support GetParameterNames with empty ParameterPath*/
+                       !strcmp(b->value.element.name, "ParameterPath") &&
+                       !b->child) {
+                       parameter_name = "";
+               }
+               if (b && b->type == MXML_TEXT &&
+                       b->value.text.string &&
+                       b->parent->type == MXML_ELEMENT &&
+                       !strcmp(b->parent->value.element.name, "NextLevel")) {
+                       NextLevel = b->value.text.string;
+               }
                b = mxmlWalkNext(b, body_in, MXML_DESCEND);
        }
+       if (parameter_name && NextLevel) {
+               if (!external_get_action_common("name", parameter_name, 
NextLevel)) {
+                       // got the parameter value via external script
+               } else {
+                       // error occurred when getting parameter value
+                       goto out;
+               }
+       }
+
+
+       ParameterList = mxmlFindElement(tree_out, tree_out, "ParameterList", 
NULL, NULL, MXML_DESCEND);
+       if (!ParameterList) goto out;
+
+       while (external_list_parameter.next!=&external_list_parameter) {
+
+               external_parameter = list_entry(external_list_parameter.next, 
struct external_parameter, list);
+
+
+               n = mxmlNewElement(ParameterList, "ParameterInfoStruct");
+               if (!n) goto out;
+
+               n = mxmlNewElement(n, "Name");
+               if (!n) goto out;
+
+               n = mxmlNewText(n, 0, external_parameter->name);
+               if (!n) goto out;
+
+               n = n->parent->parent;
+               n = mxmlNewElement(n, "Writable");
+               if (!n) goto out;
+
+               n = mxmlNewText(n, 0, external_parameter->data);
+               if (!n) goto out;
+
+               counter++;
+
+               list_del(&external_parameter->list);
+               CFREE(external_parameter->name);
+               CFREE(external_parameter->data);
+               CFREE(external_parameter->type);
+               CFREE(external_parameter->fault_code);
+               CFREE(external_parameter);
+       }
 
 #ifdef ACS_MULTI
        b = mxmlFindElement(tree_out, tree_out, "ParameterList", 
                            NULL, NULL, MXML_DESCEND);
        if (!b) goto out;
 
-       if (asprintf(&c, "cwmp:ParameterValueStruct[%d]", counter) == -1)
+       if (asprintf(&c, "cwmp:ParameterInfoStruct[%d]", counter) == -1)
                goto out;
 
        mxmlElementSetAttr(b, "soap_enc:arrayType", c);
        FREE(c);
 #endif
 
-       FREE(parameter_value);
        return 0;
 
 out:
-       FREE(parameter_value);
+       external_free_list_parameter();
        return -1;
 }
 
diff --git a/src/xml.h b/src/xml.h
index 8f63192..a9191eb 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -26,6 +26,10 @@ static int xml_handle_get_parameter_values(mxml_node_t 
*body_in,
                                           mxml_node_t *tree_in,
                                           mxml_node_t *tree_out);
 
+static int xml_handle_get_parameter_names(mxml_node_t *body_in,
+                                          mxml_node_t *tree_in,
+                                          mxml_node_t *tree_out);
+
 static int xml_handle_set_parameter_attributes(mxml_node_t *body_in,
                                               mxml_node_t *tree_in,
                                               mxml_node_t *tree_out);
-- 
1.7.4.1


--------------000002090002030008060608--

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH] Add GetParameterName feature. communication from external script to core via ubus. Update GetParameterValue in order to support many parameter names and in order to support parameter type. and modify GetParameterNames related scripts Contributed by Inteno Broadband Technology AB, Mohamed <=