#!/bin/sh
######################################
# HISTORY
######################################
# crqms00151045: mingju lai
#               2015/03/25 : avoid POODLE attack: prevent using SSLv2 and SSLv3
# crms00257177 : tcremel
# 		2010/09/09 : use clisettings to get the ethernetlink 
# crms00257156
# crms00257169 
# crms00257288 : tcremel
#		2010/09/09 : change the XML structure.
#
# CRMS00257117 : tcremel 
# 		2010/09/08 : phone model modification to show 8082 rather than VHE
#
# Tue Mar 26 2013 - Ziming Xu <Ziming.b.Xu@alcatel-lucent.com>
#                 * Fix crms00415078: Devices inventory file for VHE - Bluetooth_handset entry empty
#
######################################

## DEBUG
#########
DEBUGFLAG=.debug.send_inventory
cr=$'\n'
esc=$'\x1b'
tab=$'\t'
attr="$esc[43;30m" default="$esc[0m"
PS4="+ (SEND_INVENTORY) $$:"


if [[ -f /tmp/${DEBUGFLAG#.} ]] || [[ -f /$DEBUGFLAG ]] || [[ "${-//x}" != "$x" ]]; then
    DEBUG=1
fi

## READ CONFIG
###############
: "${attr}READ CONFIG${default}"
. /etc/functions
readCurrentConfig

## CONFIGURATION VARS
######################
## number of retry to send the xml file
NBRETRY=3
## delay between retry
RETRYDELAY=10
## time to wait before creating & sending the inventory file
TIME=120
## model number
case "$PHONE_MODEL" in
    VHE) : "${attr}Phone model: $PHONE_MODEL${default}"
        MODEL=8082
    ;;
    HE) : "${attr}Phone model: $PHONE_MODEL${default}"
        MODEL=8072
    ;;
    MR) : "${attr}Phone model: $PHONE_MODEL${default}"
        MODEL=8042
    ;;
    LE) : "${attr}Phone model: $PHONE_MODEL${default}"
        MODEL=8022
    ;;
esac
## inventory file
INVENTORYDIR=/tmp
INVENTORY_FILENAME=OT$MODEL.${ENETCFG_MACADDR//:}.xml
INVENTORY_FILE=$INVENTORYDIR/$INVENTORY_FILENAME
## files use for the inventory
RELEASE_FILE=$NVFAB_ROOT/Release
HWVERSION_FILE=$NVFAB_ROOT/HardwareVersion
SWVERSION_FILE=$VERSIONFILE
DEFENCE_FILE=/log/Defence.log
# crms00415078 zimingxu+
# BlueTooth device type definition
readonly BT_HANDSET=0
readonly BT_HEADSET=1
# crms00415078 zimingxu-

## inventory file contents
###########################
## This is the xml template. Inside the template a shell variable or a function can be use to fill the content.
## by using '%<$varname>%' or '%<function_name>%'.
## For setting variables, the default source is current. To get a different source use a function to do so.
## For example:
##    '%$ENETCFG_MACADDR%' will result in 'aa:bb:cc:dd:ee:ff'
##    '%getContent%' will be replaced with the stdout of getContent()
## crms00257117 modify PHONE MODEL to MODEL
## crms00415078 Devices inventory file for VHE - Bluetooth_handset entry empty
CONTENT='<?xml version="1.0" encoding="utf-8" ?>
<inventory_file>
    <inventory type="Hardware">
        <model_name>
            %$MODEL%
        </model_name>
        <mac_address>
            %$ENETCFG_MACADDR%
        </mac_address>
        <serial_number>
            %get_from_file $RELEASE_FILE SerialNumber%
        </serial_number>
        <hardware_version>
            %get_from_file $RELEASE_FILE PCMS%
        </hardware_version>
        <USB_Device_ID>
        </USB_Device_ID>
        <Bluetooth_handset>
            %get_bt_device $BT_HANDSET%
        </Bluetooth_handset>
        <AddOn_Hardware_version>
        </AddOn_Hardware_version>
        <flash>
            <type>
                %get_from_file $HWVERSION_FILE FlashType%
            </type>
            <size>
                %get_from_file $HWVERSION_FILE FlashSize%
            </size>
            <free>
                %get_free flash%
            </free>
        </flash>
        <ram>
            <type>
                %get_from_file $HWVERSION_FILE DDRType%
            </type>
            <size>
                %get_from_file $HWVERSION_FILE DDRSize%
            </size>
            <free>
                %get_free ram%
            </free>
        </ram>
    </inventory>
    <inventory type="Software">
        <software>
            <version>
                %get_from_file $SWVERSION_FILE VersionSoft%
            </version>
            <date>
                %get_from_file $SWVERSION_FILE VersionDate%
            </date>
            <installed_external_webapp>
                %get_webapp_list%
            </installed_external_webapp>
        </software>
    </inventory>
    <inventory type="Link">
        <pc_port>
            <state>
                %get_port_state PC%
            </state>
            <speed>
                %get_port_speed PC%
            </speed>
            <duplex>
                %get_port_duplex PC%
            </duplex>
            <configured_speed>
                %get_port_configured_speed PC%
            </configured_speed>
            <configured_duplex>
                %get_port_configured_duplex PC%
            </configured_duplex>
        </pc_port>
        <lan_port>
            <state>
                %get_port_state LAN%
            </state>
            <speed>
                %get_port_speed LAN%
            </speed>
            <duplex>
                %get_port_duplex LAN%
            </duplex>
            <configured_speed>
                %get_port_configured_speed LAN%
            </configured_speed>
            <configured_duplex>
                %get_port_configured_duplex LAN%
            </configured_duplex>
        </lan_port>
    </inventory>
    <inventory type="Network">
        <interface>
            %$ENETCFG_INTERFACE%
        </interface>
        <dhcp>
            <mode>
                %$ENETCFG_DHCP_MODE%
            </mode>
            <survivability>
                %$ENETCFG_DHCP_SURVIVABILITY_MODE%
            </survivability>
        </dhcp>
        <ip_configuration>
            <addr>
                %$ENETCFG_IPADDR%
            </addr>
            <vlan>
                %$ENETCFG_VLAN%
            </vlan>
            <subnet>
                %$ENETCFG_SUBNET%
            </subnet>
            <router>
                %$ENETCFG_ROUTER%
            </router>
            <domain>
                %$ENETCFG_DOMAIN%
            </domain>
            <dns>
                <server1>
                    %$ENETCFG_DNS1%
                </server1>
                <server2>
                    %$ENETCFG_DNS2%
                </server2>
                <server3>
                    %$ENETCFG_DNS3%
                </server3>
            </dns>
        </ip_configuration>
        <dm>
            <survivability>
                %$ENETCFG_DM_SURVIVABILITY_MODE%
            </survivability>
            <main>
                %get_main_dm%
            </main>
            <backup>
                %get_backup_dm%
            </backup>
            <proxy>
                %$ENETCFG_DM_PROXY%
            </proxy>
            <proxy_backup>
                %$ENETCFG_DM_PROXY_BACKUP%
            </proxy_backup>
        </dm>
        <wpa_802_1x>
            <configuration>
                %$WPA8021XCFG_MODE%
            </configuration>
            <authenticated>
                %$WPA8021XCFG_AUTHENTICATED%
            </authenticated>
        </wpa_802_1x>
        <coordinate_based_location>
            <LaRes>
                %get_coordinate_based_location LaRes%
            </LaRes>
            <Latitude>
                %get_coordinate_based_location Latitude%
            </Latitude>
            <LoRes>
                %get_coordinate_based_location LoRes%
            </LoRes>
            <Longitude>
                %get_coordinate_based_location Longitude%
            </Longitude>
            <AltType>
                %get_coordinate_based_location AlType%
            </AltType>
            <AltRes>
                %get_coordinate_based_location AlRes%
            </AltRes>
            <Altitude>
                %get_coordinate_based_location Altitude%
            </Altitude>
            <Datum>
                %get_coordinate_based_location Datum%
            </Datum>
        </coordinate_based_location>
        <civic_address_lci>
            <What>
                %get_civic_address_lci What%
            </What>
            <CountryCode>
                %get_civic_address_lci "Country Code"%
            </CountryCode>
            %get_ca_list%
        </civic_address_lci>
        <ecs_elin>
            %$LLDPCFG_ECS_ELIN%
        </ecs_elin>
    </inventory>
    <inventory type="diagnostic">
        <reset_cause>
            %get_reset_cause%
        </reset_cause>
        <core_file>
            %get_core_files%
        </core_file>
    </inventory>
</inventory_file>'

## CHECK URL
#############
case "$ADMCFG_INVENTORY_URL" in
    http*) : "${attr}Url defined ($ADMCFG_INVENTORY_URL).${default}"
        ADMCFG_INVENTORY_URL="${ADMCFG_INVENTORY_URL%%/}"
    ;;
    *) : "${attr}No Url in \$ADMCFG_INVENTORY_URL($ADMCFG_INVENTORY_URL).${default}"
        exit 0
    ;;
esac

## HELPER FUNCTIONS
####################
## CF "$CONTENT"
get_free()
{
    local - FUNCTION=get_from_file
    ENTER_FUNCTION
    local type="$1" data

#crms00257169
    case "$type" in
        ram)
            data=$(free |awk '{ if (NR>1) {print "<zone>";
print "    <name>"$1"</name>";
print "    <total unit=\"1k\">"$2"</total>";
print "    <used unit=\"1k\">"$3"</used>";
print "    <available unit=\"1k\">"$4"</available>";
print "</zone>"}}')
        ;;
#crms00257169 END
#crms00257156
        flash)
            data=$(df -k | grep ubi0 | awk '{print "<filesystem>";
print "    <name>"$1"</name>";
print "    <total unit=\"1k\">"$2"</total>";
print "    <used unit=\"1k\">"$3"</used>";
print "    <available unit=\"1k\">"$4"</available>";
print "    <percent_used>"$5"</percent_used>";
print "    <mount_point>"$6"</mount_point>";
print "</filesystem>"}')
        ;;
    esac
    [[ ${#data} -ne 0 ]] && echo "$data"
    RETURN 0
}

get_from_file()
{
    local - FUNCTION=get_from_file
    ENTER_FUNCTION
    local file="$1" var=$2 IFS

    if [[ $# -ne 2 ]]; then
        IFS='|'
        echo "ERROR: Wrong number of arguments: [""$@""]" >&2
        RETURN 1
    fi
    if [[ ! -f $file ]]; then
        echo "ERROR: $file not found." >&2
        RETURN 1
    fi

    eval '(
    . '"$file"'
    echo "$'"$var"'"
    )'
    RETURN 0
}

# crms00415078 zimingxu+
get_bt_device()
{
    local - FUNCTION=get_bt_device
    ENTER_FUNCTION
    local reply device=$1

    if [[ -z "$1" ]]; then
        echo "ERROR: argument \"device\" is required." >&2 
        RETURN 1
    fi

    reply=$(dbus-send --type=method_call --print-reply --dest=com.alcatel.ICTouch.ictbtmgrService \
                /ictbtmgr com.alcatel.ICTouch.ICTInterface.BthPresence int32:$device 2>/dev/null)

    if [[ $? != 0 ]]; then
        echo "Error: dbus-send failed for BthPresence". >&2
        echo "$reply" >&2
        RETURN 1
    else
        echo "${reply##?*boolean }"
    fi

    RETURN 0
}
# crms00415078 zimingxu-

get_backup_dm()
{
    local - FUNCTION=get_port_state
    ENTER_FUNCTION
    local server

    case "$ENETCFG_DHCP_MODE" in
        [Ss]tatic ) : "${attr}Static mode${default}"
            server="$(CLISettings get LOCAL ENETCFG_DM_BACKUP_URL --nodefault 2>/dev/null)"
            server=${server#http*://}
            server=${server%/*}
            server=${server%:*}
        ;;
        *) : "${attr}Dynamic mode${default}"
            server=$ENETCFG_DM_BACKUP
        ;;
    esac
    [[ -n "$server" ]] && echo "$server"
    RETURN 0
}

get_main_dm()
{
    local - FUNCTION=get_port_state
    ENTER_FUNCTION
    local server

    case "$ENETCFG_DHCP_MODE" in
        [Ss]tatic ) : "${attr}Static mode${default}"
            server="$(CLISettings get LOCAL ENETCFG_DM_URL --nodefault 2>/dev/null)"
            server=${server#http*://}
            server=${server%/*}
            server=${server%:*}
        ;;
        *) : "${attr}Dynamic mode${default}"
            server=$ENETCFG_DM
        ;;
    esac
    [[ -n "$server" ]] && echo "$server"
    RETURN 0
}

get_port_state()
{
    local - FUNCTION=get_port_state
    ENTER_FUNCTION
    local IF=$1 state 

    eval '
    : "${attr}ETHLCFG_'"$IF"': ${ETHLCFG_'"$IF"'}${default}"
    state="$(eth link $ETHLCFG_'"$IF"' '?')"
    '
    if [[ "${state//up}" == "$state" ]]; then
        echo "idle"
    else
        echo "up"
    fi
    RETURN 0
}

get_port_configured_duplex()
{
    local - FUNCTION=get_port_configured_duplex
    ENTER_FUNCTION
    local IF=$1 value

    eval '
    value="$(set +x; readConfig; echo "$ETHLCFG_'"$IF"'_DUPLEX")"
    value="$(set +x; readConfig; [[ "$ETHLCFG_'"$IF"'_AUTO" == "true" ]] && echo "auto" || echo "$ETHLCFG_'"$IF"'_DUPLEX")"
    '
    : "${attr}$IF=$value${default}"
    echo "$value"
    RETURN 0
}

get_port_configured_speed()
{
    local - FUNCTION=get_port_configured_speed
    ENTER_FUNCTION
    local IF=$1 value

    eval '
    value="$(set +x; readConfig; [[ "$ETHLCFG_'"$IF"'_AUTO" == "true" ]] && echo "auto" || echo "$ETHLCFG_'"$IF"'_SPEED")"
    '
    : "${attr}$IF=$value${default}"
    echo "$value"
    RETURN 0
}

get_port_duplex()
{
    local - FUNCTION=get_port_duplex
    ENTER_FUNCTION
    local IF=$1 idle
    
    idle=$(get_port_state $IF)
    if [[ "$idle" == "idle" ]]; then
        echo "idle"
    else
#crms00257177 
	CLISettings get CURRENT ETHLCFG_${IF}_DUPLEX
#crms00257177 END 
    fi
    RETURN 0
}

get_port_speed()
{
    local - FUNCTION=get_port_speed
    ENTER_FUNCTION
    local IF=$1 idle
    
    idle=$(get_port_state $IF)
    if [[ "$idle" == "idle" ]]; then
        echo "idle"
    else
#crms00257177 
	CLISettings get CURRENT ETHLCFG_${IF}_SPEED
#crms00257177 END 
    fi
    RETURN 0
}

get_webapp_list()
{
    local - FUNCTION=get_webapp_list
    ENTER_FUNCTION

    rpm -qa --qf "%{GROUP} %{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm\n" | awk '/^E:/{print $NF}' | sort
    RETURN 0
}

get_ca_list()
{
    local - FUNCTION=get_ca_list
    ENTER_FUNCTION
    local type value line

    [[ -z "$LLDPCFG_CIVIC_ADDRESS_LCI" ]] && { RETURN 0; }
    echo "$LLDPCFG_CIVIC_ADDRESS_LCI" | while IFS=$'\n' read line; do
        : "${attr}line=[$line]${default}"
        case "$line" in
            *Country*Code*|*What*) : "${attr}skipping${default}"
                continue
            ;;
            *) : "${attr}parsing${default}"
                set -- $line
                type=${1%:}
                shift
                value="$*"
                if [[ ${#type} -ne 0 ]] || [[ ${#value} -ne 0 ]]; then
                    echo "<CAtype>$cr$tab$type$cr</CAtype>$cr<CAvalue>$cr$tab$value$cr</CAvalue>"
                fi
            ;;
        esac
    done
    RETURN 0
}

get_civic_address_lci()
{
    local - FUNCTION=get_civic_address_lci
    ENTER_FUNCTION
    local var="$1" value

    exec 2>/dev/console
    [[ "${LLDPCFG_CIVIC_ADDRESS_LCI//$var}" == "$LLDPCFG_CIVIC_ADDRESS_LCI" ]] && { RETURN 0; }
    ## the following line is to replace all '\n' by ' '
    value=$(echo $(echo $LLDPCFG_CIVIC_ADDRESS_LCI))
    value="${value#*$var:}"
    ## remove leading blanks
    value="${value##[[:blank:]]}"
    ## remove trailing parameters
    value="${value%%[\\n[:blank:]]*}"
    echo "$value"
    RETURN 0
}

get_coordinate_based_location()
{
    local - FUNCTION=get_coordinate_based_location
    ENTER_FUNCTION
    local var=$1 value

    [[ "${LLDPCFG_COORDINATE_BASED_LOCATION//$var}" == "$LLDPCFG_COORDINATE_BASED_LOCATION" ]] && { RETURN 0; }
    value="${LLDPCFG_COORDINATE_BASED_LOCATION#*$var:}"
    value="${value##[[:blank:]]}"
    value="${value%% *}"
    echo "$value"
    RETURN 0
}

get_reset_cause()
{
    local - FUNCTION=get_reset_cause
    ENTER_FUNCTION
    
# crms00257288
    grep -h "reset__" `ls -tr ${DEFENCE_FILE}*` | tail -3 | awk '{print "<cause>";
	print "    <date>"$1" "$2" "$3"</date>";
	$1="";$2=""; $3=""; print "    <message>"$0"</message>"
	print "</cause>" }'
# crms00257288 END
    RETURN 0
}

get_core_files()
{
    local - FUNCTION=get_core_files
    ENTER_FUNCTION
    
    ls -alrt /data/core/* |awk '{
# if (NR>1)
  {
	print "<core>";
	print "  <rights> " $1 " </rights>";
	print "  <owner> " $3 " </owner>";
	print "  <group> " $4 " </group>";
	print "  <size> " $5 " </size>";
	print "  <date> " $6, $7, $8" </date>";
	print "  <name> " $9 " </name>";
	print "</core>"}
	}'
    
    RETURN 0
}

## SENDING THREAD
##################
do_send()
{
    local - FUNCTION=do_send
    ENTER_FUNCTION

    local text="" prefix pre line file type text ret

    : "${attr}${tab}Ignoring SIGHUP${default}"
    trap "" HUP

    : "${attr}${tab}Sleeping for $TIME second(s)${default}"
    sleep $TIME

    : "${attr}${tab}Read settings${default}"
    readCurrentConfig

    : "${attr}${tab}Create XML content${default}"
    exec 3>$INVENTORY_FILE
    echo "$CONTENT" | while IFS=$'\n' read line; do
        : "${attr}line=[$line]${default}"
        crneeded=0
        case "$line" in
            *%*%*) : "${attr}${tab}${tab}dynamic field(s) detected${default}"
                while [[ "${line//%}" != "$line" ]]; do
                    : "${attr}${tab}${tab}${tab}line: [$line] ${default}"
                    pre="${line%%%*}"
                    line="${line#$pre%}"
                    prefix="${pre//[^[:space:]]}"
                    pre=${pre#$prefix}
                    field="${line%%%*}"
                    line="${line#$field%}"
                    : "${attr}${tab}${tab}${tab}line: [$prefix|$pre|$field|$line]${default}"
                    set -- $field
                    text=
                    type="$(type $1 2>/dev/null)"
                    if [[ "${type//function}" != "$type" ]]; then
                        : "${attr}${tab}${tab}${tab}function${default}"
                        eval "set -- $field"
                        text=$("$@" 2>/dev/console)
                    elif [[ "${1#$}" != "$1" ]] && [[ $# -eq 1 ]]; then
                        : "${attr}${tab}${tab}${tab}shell variable${default}"
                        text=$(eval "printf $field")
                    else
                        : "${attr}${tab}${tab}${tab}$esc[41;30m[$field] is neither a variable nor a function call !!!${default}"
                    fi
                    if [[ ${#text} -ne 0 ]]; then
                        text="${text//$cr/$cr$prefix}"
                        printf "$prefix$pre%s" "${text}" >&3
                        crneeded=1
                    fi
                done
                [[ -n "$line" ]] && printf "$line" >&3
            ;;
            *)
                printf "$line" >&3
                crneeded=1
            ;;
        esac
        [[ $crneeded -eq 1 ]] && echo "" >&3
    done
    exec 3>&-

    : "${attr}${tab}Sending loop${default}"
    ca=$(getICTinfo PKI CA DM 2>/dev/null)
    cert=$(getICTinfo PKI CERT DM 2>/dev/null)
    key=$(getICTinfo PKI CERT_PKEY DM)

    curl_args="-f"
    #crms00274855 ++
    case "$ADMCFG_INVENTORY_URL" in
        http://*) : "${attr}http server${default}"
        ;;
        https://*) : "${attr}https server${default}"
        # crqms00151045
            curl_args="$curl_args --cert $cert --key $key --cacert $ca --disable-ssl-cn-check --tlsv1"
        # crqms00151045 END
    #crms00274855 --
        ;;
    esac

    while [[ $NBRETRY -gt 0 ]]; do
        : "${attr}${tab}Sending XML file${default}"
        curl $curl_args -T "$INVENTORY_FILE" "$ADMCFG_INVENTORY_URL/$INVENTORY_FILENAME" >/dev/null 2>&1
        ret=$?
        if [[ $ret -ne 0 ]] && [[ $NBRETRY -gt 1 ]]; then
            [[ $DEBUG -ne 0 ]] && display "Retrying..." >/dev/console
            sleep $RETRYDELAY
            NBRETRY=$((NBRETRY-1))
        else
            if [[ $ret -ne 0 ]]; then
                [[ $DEBUG -ne 0 ]] && display "Failed to send the inventory..." >/dev/console
                CLISettings set CURRENT ADMCFG_INVENTORY_STATUS "ERROR: $ret(cURL)" 2>/dev/null
            else
                [[ $DEBUG -ne 0 ]] && display "Inventory successfully sent" >/dev/console
                CLISettings set CURRENT ADMCFG_INVENTORY_STATUS "Successfully sent" 2>/dev/null
            fi
            NBRETRY=0
        fi
    done
    [[ -n "$pidfile" ]] && rm $pidfile
    RETURN 0
}

## COMMAND LINE PROCESSING
###########################
pidfile=
while [[ $# -ne 0 ]]; do
    case "$1" in
        -p|--pidfile) : "${attr}pid${default}"
            shift
            pidfile=$1
        ;;
    esac
    shift
done

## FORK TO SEND THE INVENTORY FILE
###################################
if [[ "${-//x}" != "$-" ]]; then
    TIME=0
    NBRETRY=1
    do_send
else
    {
    	do_send <&- >&- 2>&- &
    	if [[ -n "$pidfile" ]]; then
    		echo "$!" > $pidfile
    	fi
    } &
fi
exit 0
