diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..fe33922
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,134 @@
+image: "docker:stable"
+
+services:
+ - docker:dind
+
+variables:
+ GIT_STRATEGY: "clone"
+ IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+
+stages:
+ - build
+ - fvt
+ - package
+ - release
+
+.build_before_script:
+ before_script:
+ - mkdir -p /tmp/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/$CI_PROJECT_NAMESPACE/
+ - ln -s $CI_PROJECT_DIR /tmp/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/$CI_PROJECT_PATH
+ - cd /tmp/padding_for_CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX/$CI_PROJECT_PATH
+
+.build_ntc_radius_plug:
+ extends: .build_before_script
+ image: git.mesalab.cn:7443/mesa_platform/radius:master
+ script:
+ - source /etc/profile.d/MESA.sh
+ - mkdir -p build
+ - cd build
+ - cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+ - make
+ - make package
+
+.fvt:
+ script:
+ - source /etc/profile.d/MESA.sh
+ - rpm -ivh ./build/*.rpm
+ - sed -i 's/LOG_LEVEL=30/LOG_LEVEL=10/g' /home/mesasoft/sapp_run/conf/radius/radius.conf
+ - sed -i 's/.\/plug\/business\/gtest_sapp\/gtest_sapp.inf/#.\/plug\/business\/gtest_sapp\/gtest_sapp.inf/g' /home/mesasoft/sapp_run/plug/conflist.inf
+ - sed -i 's/.\/plug\/business\/test_app\/test_app.inf/#.\/plug\/business\/test_app\/test_app.inf/g' /home/mesasoft/sapp_run/plug/conflist.inf
+ - cd /home/mesasoft/
+ - git clone https://$USER_NAME:$CI_TOKEN@git.mesalab.cn/tango/fvt.git
+ - cd fvt/
+ - sh +x fvt_verify.sh /home/mesasoft/sapp_run/ /home/mesasoft/sapp_run/conf/radius/radius_maat.json /home/mesasoft/sapp_run/log/ntc_radius_plug/ntc_radius_plug /home/mesasoft/fvt/radius/
+
+.package_ntc_radius_plug:
+ extends: .build_before_script
+ image: git.mesalab.cn:7443/mesa_platform/radius:master
+ script:
+ - source /etc/profile.d/MESA.sh
+ - mkdir -p build
+ - cd build
+ - cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+ - make package
+
+build:
+ stage: build
+ extends: .build_ntc_radius_plug
+ tags:
+ - share
+ variables:
+ BUILD_TYPE: "Release"
+ artifacts:
+ name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA"
+ paths:
+ - ./build/*.rpm
+ except:
+ - tags
+
+fvt:
+ stage: fvt
+ image: git.mesalab.cn:7443/mesa_platform/radius:master
+ extends: .fvt
+ tags:
+ - share
+ except:
+ - tags
+
+ntc_radius_plug-release-package:
+ stage: package
+ extends: .package_ntc_radius_plug
+ tags:
+ - share
+ variables:
+ BUILD_TYPE: "Release"
+ artifacts:
+ name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
+ paths:
+ - ./build/*.rpm
+ expire_in: "2 years"
+ only:
+ - tags
+
+ntc_radius_plug-debug-package:
+ stage: package
+ extends: .package_ntc_radius_plug
+ tags:
+ - share
+ variables:
+ BUILD_TYPE: "Debug"
+ artifacts:
+ name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
+ paths:
+ - ./build/*.rpm
+ expire_in: "2 years"
+ only:
+ - tags
+
+release-ntc_radius_plug-release:
+ stage: release
+ image: git.mesalab.cn:7443/mesa_platform/radius:master
+ tags:
+ - share
+ only:
+ - tags
+ variables:
+ ARTIFACTS_JOB: "ntc_radius_plug-release-package"
+ PROJECT_NAME: "ntc_radius_plug"
+ USER_DEFINE: "release"
+ script:
+ - /bin/bash -x ./autorelease.sh $CI_API_V4_URL $CI_PROJECT_URL $CI_PROJECT_ID $CI_TOKEN $CI_COMMIT_TAG $ARTIFACTS_JOB $CI_PROJECT_NAME $USER_DEFINE
+
+release-ntc_radius_plug-debug:
+ stage: release
+ image: git.mesalab.cn:7443/mesa_platform/radius:master
+ tags:
+ - share
+ only:
+ - tags
+ variables:
+ ARTIFACTS_JOB: "ntc_radius_plug-debug-package"
+ PROJECT_NAME: "ntc_radius_plug"
+ USER_DEFINE: "debug"
+ script:
+ - /bin/bash -x ./autorelease.sh $CI_API_V4_URL $CI_PROJECT_URL $CI_PROJECT_ID $CI_TOKEN $CI_COMMIT_TAG $ARTIFACTS_JOB $CI_PROJECT_NAME $USER_DEFINE
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..5745582
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required (VERSION 2.8)
+
+project(ntc_radius_plug)
+
+set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
+include(Version)
+
+set(CMAKE_MACOSX_RPATH 0)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
+
+include_directories(/opt/MESA/include/)
+
+option(ENABLE_WARNING_ALL "Enable all optional warnings which are desirable for normal code" TRUE)
+option(ENABLE_SANITIZE_ADDRESS "Enable AddressSanitizer" FALSE)
+option(ENABLE_SANITIZE_THREAD "Enable ThreadSanitizer" FALSE)
+
+if(ENABLE_SANITIZE_ADDRESS)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan")
+elseif(ENABLE_SANITIZE_THREAD)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread -fno-omit-frame-pointer")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -fno-omit-frame-pointer")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan")
+endif()
+
+set(CMAKE_INSTALL_PREFIX /home/mesasoft/sapp_run)
+
+add_subdirectory (src)
+
+SET(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/preinstall/install.sh")
+SET(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${PROJECT_SOURCE_DIR}/preinstall/uninstall.sh")
+
+include(Package)
diff --git a/autorelease.sh b/autorelease.sh
new file mode 100644
index 0000000..34eaefb
--- /dev/null
+++ b/autorelease.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+if [ $# -lt 8 ] ; then
+ echo "USAGE: ./autorelease.sh [API_V4_URL] [PROJECT_URL]
+ [PROJECT_ID] [TOKEN]
+ [COMMIT_TAG] [JOB] [PROJECT_NAME] [USER_DEFINE]"
+ echo "$1; $2; $3; $4; $5; $6; $7; $8"
+exit 1;
+fi
+
+CI_API_V4_URL=$1
+CI_PROJECT_URL=$2
+CI_PROJECT_ID=$3
+CI_TOKEN=$4
+CI_COMMIT_TAG=$5
+ARTIFACTS_JOB=$6
+CI_PROJECT_NAME=$7
+USER_DEFINE=$8
+
+res=`echo -e "curl --header \"PRIVATE-TOKEN: $CI_TOKEN\" $CI_API_V4_URL/projects/$CI_PROJECT_ID/releases/$CI_COMMIT_TAG -o /dev/null -s -w %{http_code}"| /bin/bash`
+
+if [[ $res == "200" ]]; then
+ eval $(echo -e "curl --request POST --header \"PRIVATE-TOKEN: $CI_TOKEN\" \
+ --data name=\"$CI_PROJECT_NAME-$USER_DEFINE-$CI_COMMIT_TAG.zip\" \
+ --data url=\"$CI_PROJECT_URL/-/jobs/artifacts/$CI_COMMIT_TAG/download?job=$ARTIFACTS_JOB\"\
+ $CI_API_V4_URL/projects/$CI_PROJECT_ID/releases/$CI_COMMIT_TAG/assets/links")
+else
+ eval $(echo -e "curl --header 'Content-Type: application/json' --header \
+ \"PRIVATE-TOKEN: $CI_TOKEN\" --data '{ \"name\": \"$CI_COMMIT_TAG\", \
+ \"tag_name\": \"$CI_COMMIT_TAG\", \"description\": \"auto_release\",\
+ \"assets\": { \"links\": [{ \"name\": \
+ \"$CI_PROJECT_NAME-$USER_DEFINE-$CI_COMMIT_TAG.zip\", \"url\": \
+ \"$CI_PROJECT_URL/-/jobs/artifacts/$CI_COMMIT_TAG/download?job=$ARTIFACTS_JOB\"\
+ }] } }' --request POST $CI_API_V4_URL/projects/$CI_PROJECT_ID/releases/")
+fi
\ No newline at end of file
diff --git a/autorevision.sh b/autorevision.sh
new file mode 100644
index 0000000..3baa179
--- /dev/null
+++ b/autorevision.sh
@@ -0,0 +1,1268 @@
+#!/bin/sh
+
+# Copyright (c) 2012 - 2016 dak180 and contributors. See
+# https://opensource.org/licenses/mit-license.php or the included
+# COPYING.md for licence terms.
+#
+# autorevision - extracts metadata about the head version from your
+# repository.
+
+# Usage message.
+arUsage() {
+ cat > "/dev/stderr" << EOF
+usage: autorevision {-t output-type | -s symbol} [-o cache-file [-f] ] [-V]
+ Options include:
+ -t output-type = specify output type
+ -s symbol = specify symbol output
+ -o cache-file = specify cache file location
+ -f = force the use of cache data
+ -U = check for untracked files in svn
+ -V = emit version and exit
+ -? = help message
+
+The following are valid output types:
+ clojure = clojure file
+ c = C/C++ file
+ h = Header for use with c/c++
+ hpp = Alternate C++ header strings with namespace
+ ini = INI file
+ java = Java file
+ javaprop = Java properties file
+ js = javascript file
+ json = JSON file
+ lua = Lua file
+ m4 = m4 file
+ matlab = matlab file
+ octave = octave file
+ php = PHP file
+ pl = Perl file
+ py = Python file
+ rpm = rpm file
+ scheme = scheme file
+ sh = Bash sytax
+ swift = Swift file
+ tex = (La)TeX file
+ xcode = Header useful for populating info.plist files
+ cmake = CMake file
+
+
+The following are valid symbols:
+ VCS_TYPE
+ VCS_BASENAME
+ VCS_UUID
+ VCS_NUM
+ VCS_DATE
+ VCS_BRANCH
+ VCS_TAG
+ VCS_TICK
+ VCS_EXTRA
+ VCS_FULL_HASH
+ VCS_SHORT_HASH
+ VCS_WC_MODIFIED
+ VCS_ACTION_STAMP
+EOF
+ exit 1
+}
+
+# Config
+ARVERSION="&&ARVERSION&&"
+TARGETFILE="/dev/stdout"
+while getopts ":t:o:s:VfU" OPTION; do
+ case "${OPTION}" in
+ t)
+ AFILETYPE="${OPTARG}"
+ ;;
+ o)
+ CACHEFILE="${OPTARG}"
+ ;;
+ f)
+ CACHEFORCE="1"
+ ;;
+ s)
+ VAROUT="${OPTARG}"
+ ;;
+ U)
+ UNTRACKEDFILES="1"
+ ;;
+ V)
+ echo "autorevision ${ARVERSION}"
+ exit 0
+ ;;
+ ?)
+ # If an unknown flag is used (or -?):
+ arUsage
+ ;;
+ esac
+done
+
+if [ ! -z "${VAROUT}" ] && [ ! -z "${AFILETYPE}" ]; then
+ # If both -s and -t are specified:
+ echo "error: Improper argument combination." 1>&2
+ exit 1
+elif [ -z "${VAROUT}" ] && [ -z "${AFILETYPE}" ]; then
+ # If neither -s or -t are specified:
+ arUsage
+elif [ -z "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then
+ # If -f is specified without -o:
+ arUsage
+elif [ ! -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then
+ # If we are forced to use the cache but it does not exist.
+ echo "error: Cache forced but no cache found." 1>&2
+ exit 1
+fi
+
+# Make sure that the path we are given is one we can source
+# (dash, we are looking at you).
+if [ ! -z "${CACHEFILE}" ] && ! echo "${CACHEFILE}" | grep -q '^\.*/'; then
+ CACHEFILE="./${CACHEFILE}"
+fi
+
+GENERATED_HEADER="Generated by autorevision - do not hand-hack!"
+
+# Functions to extract data from different repo types.
+# For git repos
+# shellcheck disable=SC2039,SC2164,SC2155
+gitRepo() {
+ local oldPath="${PWD}"
+
+ cd "$(git rev-parse --show-toplevel)"
+
+ VCS_TYPE="git"
+
+ VCS_BASENAME="$(basename "${PWD}")"
+
+ VCS_UUID="$(git rev-list --max-parents=0 --date-order --reverse HEAD 2>/dev/null | sed -n 1p)"
+ if [ -z "${VCS_UUID}" ]; then
+ VCS_UUID="$(git rev-list --topo-order HEAD | tail -n 1)"
+ fi
+
+ # Is the working copy clean?
+ test -z "$(git status --untracked-files=normal --porcelain)"
+ VCS_WC_MODIFIED="${?}"
+
+ # Enumeration of changesets
+ VCS_NUM="$(git rev-list --count HEAD 2>/dev/null)"
+ if [ -z "${VCS_NUM}" ]; then
+ echo "warning: Counting the number of revisions may be slower due to an outdated git version less than 1.7.2.3. If something breaks, please update it." 1>&2
+ VCS_NUM="$(git rev-list HEAD | wc -l)"
+ fi
+
+ # This may be a git-svn remote. If so, report the Subversion revision.
+ if [ -z "$(git config svn-remote.svn.url 2>/dev/null)" ]; then
+ # The full revision hash
+ VCS_FULL_HASH="$(git rev-parse HEAD)"
+
+ # The short hash
+ VCS_SHORT_HASH="$(echo "${VCS_FULL_HASH}" | cut -b 1-7)"
+ else
+ # The git-svn revision number
+ VCS_FULL_HASH="$(git svn find-rev HEAD)"
+ VCS_SHORT_HASH="${VCS_FULL_HASH}"
+ fi
+
+ # Current branch
+ VCS_BRANCH="$(git rev-parse --symbolic-full-name --verify "$(git name-rev --name-only --no-undefined HEAD 2>/dev/null)" 2>/dev/null | sed -e 's:refs/heads/::' | sed -e 's:refs/::')"
+
+ # Cache the description
+ local DESCRIPTION="$(git describe --long --tags 2>/dev/null)"
+
+ # Current or last tag ancestor (empty if no tags)
+ VCS_TAG="$(echo "${DESCRIPTION}" | sed -e "s:-g${VCS_SHORT_HASH}\$::" -e 's:-[0-9]*$::')"
+
+ # Distance to last tag or an alias of VCS_NUM if there is no tag
+ if [ ! -z "${DESCRIPTION}" ]; then
+ VCS_TICK="$(echo "${DESCRIPTION}" | sed -e "s:${VCS_TAG}-::" -e "s:-g${VCS_SHORT_HASH}::")"
+ else
+ VCS_TICK="${VCS_NUM}"
+ fi
+
+ # Date of the current commit
+ VCS_DATE="$(TZ=UTC git show -s --date=iso-strict-local --pretty=format:%ad | sed -e 's|+00:00|Z|')"
+ if [ -z "${VCS_DATE}" ]; then
+ echo "warning: Action stamps require git version 2.7+." 1>&2
+ VCS_DATE="$(git log -1 --pretty=format:%ci | sed -e 's: :T:' -e 's: ::' -e 's|+00:00|Z|')"
+ local ASdis="1"
+ fi
+
+ # Action Stamp
+ if [ -z "${ASdis}" ]; then
+ VCS_ACTION_STAMP="${VCS_DATE}!$(git show -s --pretty=format:%cE)"
+ else
+ VCS_ACTION_STAMP=""
+ fi
+
+ cd "${oldPath}"
+}
+
+# For hg repos
+# shellcheck disable=SC2039,SC2164
+hgRepo() {
+ local oldPath="${PWD}"
+
+ cd "$(hg root)"
+
+ VCS_TYPE="hg"
+
+ VCS_BASENAME="$(basename "${PWD}")"
+
+ VCS_UUID="$(hg log -r "0" -l 1 --template '{node}\n')"
+
+ # Is the working copy clean?
+ test -z "$(hg status -duram)"
+ VCS_WC_MODIFIED="${?}"
+
+ # Enumeration of changesets
+ VCS_NUM="$(hg id -n | tr -d '+')"
+
+ # The full revision hash
+ VCS_FULL_HASH="$(hg log -r "${VCS_NUM}" -l 1 --template '{node}\n')"
+
+ # The short hash
+ VCS_SHORT_HASH="$(hg id -i | tr -d '+')"
+
+ # Current bookmark (bookmarks are roughly equivalent to git's branches)
+ # or branch if no bookmark
+ VCS_BRANCH="$(hg id -B | cut -d ' ' -f 1)"
+ # Fall back to the branch if there are no bookmarks
+ if [ -z "${VCS_BRANCH}" ]; then
+ VCS_BRANCH="$(hg id -b)"
+ fi
+
+ # Current or last tag ancestor (excluding auto tags, empty if no tags)
+ VCS_TAG="$(hg log -r "${VCS_NUM}" -l 1 --template '{latesttag}\n' 2>/dev/null | sed -e 's:qtip::' -e 's:tip::' -e 's:qbase::' -e 's:qparent::' -e "s:$(hg --config 'extensions.color=' --config 'extensions.mq=' --color never qtop 2>/dev/null)::" | cut -d ' ' -f 1)"
+
+ # Distance to last tag or an alias of VCS_NUM if there is no tag
+ if [ ! -z "${VCS_TAG}" ]; then
+ VCS_TICK="$(hg log -r "${VCS_NUM}" -l 1 --template '{latesttagdistance}\n' 2>/dev/null)"
+ else
+ VCS_TICK="${VCS_NUM}"
+ fi
+
+ # Date of the current commit
+ VCS_DATE="$(hg log -r "${VCS_NUM}" -l 1 --template '{date|isodatesec}\n' 2>/dev/null | sed -e 's: :T:' -e 's: ::' -e 's|+00:00|Z|')"
+
+ # Action Stamp
+ VCS_ACTION_STAMP="$(TZ=UTC hg log -r "${VCS_NUM}" -l 1 --template '{date|localdate|rfc3339date}\n' 2>/dev/null | sed -e 's|+00:00|Z|')!$(hg log -r "${VCS_NUM}" -l 1 --template '{author|email}\n' 2>/dev/null)"
+
+ cd "${oldPath}"
+}
+
+# For bzr repos
+# shellcheck disable=SC2039,SC2164
+bzrRepo() {
+ local oldPath="${PWD}"
+
+ cd "$(bzr root)"
+
+ VCS_TYPE="bzr"
+
+ VCS_BASENAME="$(basename "${PWD}")"
+
+ # Currently unimplemented because more investigation is needed.
+ VCS_UUID=""
+
+ # Is the working copy clean?
+ bzr version-info --custom --template='{clean}\n' | grep -q '1'
+ VCS_WC_MODIFIED="${?}"
+
+ # Enumeration of changesets
+ VCS_NUM="$(bzr revno)"
+
+ # The full revision hash
+ VCS_FULL_HASH="$(bzr version-info --custom --template='{revision_id}\n')"
+
+ # The short hash
+ VCS_SHORT_HASH="${VCS_NUM}"
+
+ # Nick of the current branch
+ VCS_BRANCH="$(bzr nick)"
+
+ # Current or last tag ancestor (excluding auto tags, empty if no tags)
+ VCS_TAG="$(bzr tags --sort=time | sed '/?$/d' | tail -n1 | cut -d ' ' -f1)"
+
+ # Distance to last tag or an alias of VCS_NUM if there is no tag
+ if [ ! -z "${VCS_TAG}" ]; then
+ VCS_TICK="$(bzr log --line -r "tag:${VCS_TAG}.." | tail -n +2 | wc -l | sed -e 's:^ *::')"
+ else
+ VCS_TICK="${VCS_NUM}"
+ fi
+
+ # Date of the current commit
+ VCS_DATE="$(bzr version-info --custom --template='{date}\n' | sed -e 's: :T:' -e 's: ::')"
+
+ # Action Stamp
+ # Currently unimplemented because more investigation is needed.
+ VCS_ACTION_STAMP=""
+
+ cd "${oldPath}"
+}
+
+# For svn repos
+# shellcheck disable=SC2039,SC2164,SC2155
+svnRepo() {
+ local oldPath="${PWD}"
+
+ VCS_TYPE="svn"
+
+ case "${PWD}" in
+ /*trunk*|/*branches*|/*tags*)
+ local fn="${PWD}"
+ while [ "$(basename "${fn}")" != 'trunk' ] && [ "$(basename "${fn}")" != 'branches' ] && [ "$(basename "${fn}")" != 'tags' ] && [ "$(basename "${fn}")" != '/' ]; do
+ local fn="$(dirname "${fn}")"
+ done
+ local fn="$(dirname "${fn}")"
+ if [ "${fn}" = '/' ]; then
+ VCS_BASENAME="$(basename "${PWD}")"
+ else
+ VCS_BASENAME="$(basename "${fn}")"
+ fi
+ ;;
+ *) VCS_BASENAME="$(basename "${PWD}")" ;;
+ esac
+
+ VCS_UUID="$(svn info --xml | sed -n -e 's:::' -e 's:::p')"
+
+ # Cache svnversion output
+ local SVNVERSION="$(svnversion)"
+
+ # Is the working copy clean?
+ echo "${SVNVERSION}" | grep -q "M"
+ case "${?}" in
+ 0)
+ VCS_WC_MODIFIED="1"
+ ;;
+ 1)
+ if [ ! -z "${UNTRACKEDFILES}" ]; then
+ # `svnversion` does not detect untracked files and `svn status` is really slow, so only run it if we really have to.
+ if [ -z "$(svn status)" ]; then
+ VCS_WC_MODIFIED="0"
+ else
+ VCS_WC_MODIFIED="1"
+ fi
+ else
+ VCS_WC_MODIFIED="0"
+ fi
+ ;;
+ esac
+
+ # Enumeration of changesets
+ VCS_NUM="$(echo "${SVNVERSION}" | cut -d : -f 1 | sed -e 's:M::' -e 's:S::' -e 's:P::')"
+
+ # The full revision hash
+ VCS_FULL_HASH="${SVNVERSION}"
+
+ # The short hash
+ VCS_SHORT_HASH="${VCS_NUM}"
+
+ # Current branch
+ case "${PWD}" in
+ /*trunk*|/*branches*|/*tags*)
+ local lastbase=""
+ local fn="${PWD}"
+ while :
+ do
+ base="$(basename "${fn}")"
+ if [ "${base}" = 'trunk' ]; then
+ VCS_BRANCH='trunk'
+ break
+ elif [ "${base}" = 'branches' ] || [ "${base}" = 'tags' ]; then
+ VCS_BRANCH="${lastbase}"
+ break
+ elif [ "${base}" = '/' ]; then
+ VCS_BRANCH=""
+ break
+ fi
+ local lastbase="${base}"
+ local fn="$(dirname "${fn}")"
+ done
+ ;;
+ *) VCS_BRANCH="" ;;
+ esac
+
+ # Current or last tag ancestor (empty if no tags). But "current
+ # tag" can't be extracted reliably because Subversion doesn't
+ # have tags the way other VCSes do.
+ VCS_TAG=""
+ VCS_TICK=""
+
+ # Date of the current commit
+ VCS_DATE="$(svn info --xml | sed -n -e 's:::' -e 's:::p')"
+
+ # Action Stamp
+ VCS_ACTION_STAMP="${VCS_DATE}!$(svn log --xml -l 1 -r "${VCS_SHORT_HASH}" | sed -n -e 's:::' -e 's:::p')"
+
+ cd "${oldPath}"
+}
+
+
+# Functions to output data in different formats.
+# For bash output
+shOutput() {
+ cat > "${TARGETFILE}" << EOF
+# ${GENERATED_HEADER}
+
+VCS_TYPE="${VCS_TYPE}"
+VCS_BASENAME="${VCS_BASENAME}"
+VCS_UUID="${VCS_UUID}"
+VCS_NUM="${VCS_NUM}"
+VCS_DATE="${VCS_DATE}"
+VCS_BRANCH="${VCS_BRANCH}"
+VCS_TAG="${VCS_TAG}"
+VCS_TICK="${VCS_TICK}"
+VCS_EXTRA="${VCS_EXTRA}"
+
+VCS_ACTION_STAMP="${VCS_ACTION_STAMP}"
+VCS_FULL_HASH="${VCS_FULL_HASH}"
+VCS_SHORT_HASH="${VCS_SHORT_HASH}"
+
+VCS_WC_MODIFIED="${VCS_WC_MODIFIED}"
+
+# end
+EOF
+}
+
+# For source C output
+cOutput() {
+ cat > "${TARGETFILE}" << EOF
+/* ${GENERATED_HEADER} */
+
+const char *VCS_TYPE = "${VCS_TYPE}";
+const char *VCS_BASENAME = "${VCS_BASENAME}";
+const char *VCS_UUID = "${VCS_UUID}";
+const int VCS_NUM = ${VCS_NUM};
+const char *VCS_DATE = "${VCS_DATE}";
+const char *VCS_BRANCH = "${VCS_BRANCH}";
+const char *VCS_TAG = "${VCS_TAG}";
+const int VCS_TICK = ${VCS_TICK};
+const char *VCS_EXTRA = "${VCS_EXTRA}";
+
+const char *VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}";
+const char *VCS_FULL_HASH = "${VCS_FULL_HASH}";
+const char *VCS_SHORT_HASH = "${VCS_SHORT_HASH}";
+
+const int VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
+
+/* end */
+EOF
+}
+
+# For header output
+hOutput() {
+ cat > "${TARGETFILE}" << EOF
+/* ${GENERATED_HEADER} */
+#ifndef AUTOREVISION_H
+#define AUTOREVISION_H
+
+#define VCS_TYPE "${VCS_TYPE}"
+#define VCS_BASENAME "${VCS_BASENAME}"
+#define VCS_UUID "${VCS_UUID}"
+#define VCS_NUM ${VCS_NUM}
+#define VCS_DATE "${VCS_DATE}"
+#define VCS_BRANCH "${VCS_BRANCH}"
+#define VCS_TAG "${VCS_TAG}"
+#define VCS_TICK ${VCS_TICK}
+#define VCS_EXTRA "${VCS_EXTRA}"
+
+#define VCS_ACTION_STAMP "${VCS_ACTION_STAMP}"
+#define VCS_FULL_HASH "${VCS_FULL_HASH}"
+#define VCS_SHORT_HASH "${VCS_SHORT_HASH}"
+
+#define VCS_WC_MODIFIED ${VCS_WC_MODIFIED}
+
+#endif
+
+/* end */
+EOF
+}
+
+# A header output for use with xcode to populate info.plist strings
+xcodeOutput() {
+ cat > "${TARGETFILE}" << EOF
+/* ${GENERATED_HEADER} */
+#ifndef AUTOREVISION_H
+#define AUTOREVISION_H
+
+#define VCS_TYPE ${VCS_TYPE}
+#define VCS_BASENAME ${VCS_BASENAME}
+#define VCS_UUID ${VCS_UUID}
+#define VCS_NUM ${VCS_NUM}
+#define VCS_DATE ${VCS_DATE}
+#define VCS_BRANCH ${VCS_BRANCH}
+#define VCS_TAG ${VCS_TAG}
+#define VCS_TICK ${VCS_TICK}
+#define VCS_EXTRA ${VCS_EXTRA}
+
+#define VCS_ACTION_STAMP ${VCS_ACTION_STAMP}
+#define VCS_FULL_HASH ${VCS_FULL_HASH}
+#define VCS_SHORT_HASH ${VCS_SHORT_HASH}
+
+#define VCS_WC_MODIFIED ${VCS_WC_MODIFIED}
+
+#endif
+
+/* end */
+EOF
+}
+
+# For Swift output
+swiftOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="false" ;;
+ 1) VCS_WC_MODIFIED="true" ;;
+ esac
+ # For values that may not exist depending on the type of repo we
+ # have read from, set them to `nil` when they are empty.
+ if [ -z "${VCS_UUID}" ]; then
+ VCS_UUID="nil"
+ else
+ VCS_UUID="\"${VCS_UUID}\""
+ fi
+ if [ -z "${VCS_TAG}" ]; then
+ VCS_TAG="nil"
+ else
+ VCS_TAG="\"${VCS_TAG}\""
+ fi
+ : "${VCS_TICK:="nil"}"
+ if [ -z "${VCS_EXTRA}" ]; then
+ VCS_EXTRA="nil"
+ else
+ VCS_EXTRA="\"${VCS_EXTRA}\""
+ fi
+ if [ -z "${VCS_ACTION_STAMP}" ]; then
+ VCS_ACTION_STAMP="nil"
+ else
+ VCS_ACTION_STAMP="\"${VCS_ACTION_STAMP}\""
+ fi
+ cat > "${TARGETFILE}" << EOF
+/* ${GENERATED_HEADER} */
+
+let VCS_TYPE = "${VCS_TYPE}"
+let VCS_BASENAME = "${VCS_BASENAME}"
+let VCS_UUID: String? = ${VCS_UUID}
+let VCS_NUM: Int = ${VCS_NUM}
+let VCS_DATE = "${VCS_DATE}"
+let VCS_BRANCH: String = "${VCS_BRANCH}"
+let VCS_TAG: String? = ${VCS_TAG}
+let VCS_TICK: Int? = ${VCS_TICK}
+let VCS_EXTRA: String? = ${VCS_EXTRA}
+
+let VCS_ACTION_STAMP: String? = ${VCS_ACTION_STAMP}
+let VCS_FULL_HASH: String = "${VCS_FULL_HASH}"
+let VCS_SHORT_HASH: String = "${VCS_SHORT_HASH}"
+
+let VCS_WC_MODIFIED: Bool = ${VCS_WC_MODIFIED}
+
+/* end */
+EOF
+}
+
+# For Python output
+pyOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="False" ;;
+ 1) VCS_WC_MODIFIED="True" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+# ${GENERATED_HEADER}
+
+VCS_TYPE = "${VCS_TYPE}"
+VCS_BASENAME = "${VCS_BASENAME}"
+VCS_UUID = "${VCS_UUID}"
+VCS_NUM = ${VCS_NUM}
+VCS_DATE = "${VCS_DATE}"
+VCS_BRANCH = "${VCS_BRANCH}"
+VCS_TAG = "${VCS_TAG}"
+VCS_TICK = ${VCS_TICK}
+VCS_EXTRA = "${VCS_EXTRA}"
+
+VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"
+VCS_FULL_HASH = "${VCS_FULL_HASH}"
+VCS_SHORT_HASH = "${VCS_SHORT_HASH}"
+
+VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}
+
+# end
+EOF
+}
+
+# For Perl output
+plOutput() {
+ cat << EOF
+# ${GENERATED_HEADER}
+
+\$VCS_TYPE = '${VCS_TYPE}';
+\$VCS_BASENAME = '${VCS_BASENAME}';
+\$VCS_UUID = '${VCS_UUID}';
+\$VCS_NUM = ${VCS_NUM};
+\$VCS_DATE = '${VCS_DATE}';
+\$VCS_BRANCH = '${VCS_BRANCH}';
+\$VCS_TAG = '${VCS_TAG}';
+\$VCS_TICK = ${VCS_TICK};
+\$VCS_EXTRA = '${VCS_EXTRA}';
+
+\$VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}';
+\$VCS_FULL_HASH = '${VCS_FULL_HASH}';
+\$VCS_SHORT_HASH = '${VCS_SHORT_HASH}';
+
+\$VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
+
+# end
+1;
+EOF
+}
+
+# For lua output
+luaOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="false" ;;
+ 1) VCS_WC_MODIFIED="true" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+-- ${GENERATED_HEADER}
+
+VCS_TYPE = "${VCS_TYPE}"
+VCS_BASENAME = "${VCS_BASENAME}"
+VCS_UUID = "${VCS_UUID}"
+VCS_NUM = ${VCS_NUM}
+VCS_DATE = "${VCS_DATE}"
+VCS_BRANCH = "${VCS_BRANCH}"
+VCS_TAG = "${VCS_TAG}"
+VCS_TICK = ${VCS_TICK}
+VCS_EXTRA = "${VCS_EXTRA}"
+
+VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"
+VCS_FULL_HASH = "${VCS_FULL_HASH}"
+VCS_SHORT_HASH = "${VCS_SHORT_HASH}"
+
+VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}
+
+-- end
+EOF
+}
+
+# For php output
+phpOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="false" ;;
+ 1) VCS_WC_MODIFIED="true" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+ "${VCS_TYPE}",
+ "VCS_BASENAME" => "${VCS_BASENAME}",
+ "VCS_UUID" => "${VCS_UUID}",
+ "VCS_NUM" => ${VCS_NUM},
+ "VCS_DATE" => "${VCS_DATE}",
+ "VCS_BRANCH" => "${VCS_BRANCH}",
+ "VCS_TAG" => "${VCS_TAG}",
+ "VCS_TICK" => ${VCS_TICK},
+ "VCS_EXTRA" => "${VCS_EXTRA}",
+ "VCS_ACTION_STAMP" => "${VCS_ACTION_STAMP}",
+ "VCS_FULL_HASH" => "${VCS_FULL_HASH}",
+ "VCS_SHORT_HASH" => "${VCS_SHORT_HASH}",
+ "VCS_WC_MODIFIED" => ${VCS_WC_MODIFIED}
+);
+
+# end
+?>
+EOF
+}
+
+# For ini output
+iniOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="false" ;;
+ 1) VCS_WC_MODIFIED="true" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+; ${GENERATED_HEADER}
+[VCS]
+VCS_TYPE = "${VCS_TYPE}"
+VCS_BASENAME = "${VCS_BASENAME}"
+VCS_UUID = "${VCS_UUID}"
+VCS_NUM = ${VCS_NUM}
+VCS_DATE = "${VCS_DATE}"
+VCS_BRANCH = "${VCS_BRANCH}"
+VCS_TAG = "${VCS_TAG}"
+VCS_TICK = ${VCS_TICK}
+VCS_EXTRA = "${VCS_EXTRA}"
+VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}"
+VCS_FULL_HASH = "${VCS_FULL_HASH}"
+VCS_SHORT_HASH = "${VCS_SHORT_HASH}"
+VCS_WC_MODIFIED = ${VCS_WC_MODIFIED}
+; end
+EOF
+}
+
+# For javascript output
+jsOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 1) VCS_WC_MODIFIED="true" ;;
+ 0) VCS_WC_MODIFIED="false" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+/** ${GENERATED_HEADER} */
+
+var autorevision = {
+ VCS_TYPE: "${VCS_TYPE}",
+ VCS_BASENAME: "${VCS_BASENAME}",
+ VCS_UUID: "${VCS_UUID}",
+ VCS_NUM: ${VCS_NUM},
+ VCS_DATE: "${VCS_DATE}",
+ VCS_BRANCH: "${VCS_BRANCH}",
+ VCS_TAG: "${VCS_TAG}",
+ VCS_TICK: ${VCS_TICK},
+ VCS_EXTRA: "${VCS_EXTRA}",
+
+ VCS_ACTION_STAMP: "${VCS_ACTION_STAMP}",
+ VCS_FULL_HASH: "${VCS_FULL_HASH}",
+ VCS_SHORT_HASH: "${VCS_SHORT_HASH}",
+
+ VCS_WC_MODIFIED: ${VCS_WC_MODIFIED}
+};
+
+/** Node.js compatibility */
+if (typeof module !== 'undefined') {
+ module.exports = autorevision;
+}
+
+/** end */
+EOF
+}
+
+# For JSON output
+jsonOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 1) VCS_WC_MODIFIED="true" ;;
+ 0) VCS_WC_MODIFIED="false" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+{
+ "_comment": "${GENERATED_HEADER}",
+ "VCS_TYPE": "${VCS_TYPE}",
+ "VCS_BASENAME": "${VCS_BASENAME}",
+ "VCS_UUID": "${VCS_UUID}",
+ "VCS_NUM": ${VCS_NUM},
+ "VCS_DATE": "${VCS_DATE}",
+ "VCS_BRANCH":"${VCS_BRANCH}",
+ "VCS_TAG": "${VCS_TAG}",
+ "VCS_TICK": ${VCS_TICK},
+ "VCS_EXTRA": "${VCS_EXTRA}",
+
+ "VCS_ACTION_STAMP": "${VCS_ACTION_STAMP}",
+ "VCS_FULL_HASH": "${VCS_FULL_HASH}",
+ "VCS_SHORT_HASH": "${VCS_SHORT_HASH}",
+
+ "VCS_WC_MODIFIED": ${VCS_WC_MODIFIED}
+}
+EOF
+}
+
+# For Java output
+javaOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 1) VCS_WC_MODIFIED="true" ;;
+ 0) VCS_WC_MODIFIED="false" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+/* ${GENERATED_HEADER} */
+
+public class autorevision {
+ public static final String VCS_TYPE = "${VCS_TYPE}";
+ public static final String VCS_BASENAME = "${VCS_BASENAME}";
+ public static final String VCS_UUID = "${VCS_UUID}";
+ public static final long VCS_NUM = ${VCS_NUM};
+ public static final String VCS_DATE = "${VCS_DATE}";
+ public static final String VCS_BRANCH = "${VCS_BRANCH}";
+ public static final String VCS_TAG = "${VCS_TAG}";
+ public static final long VCS_TICK = ${VCS_TICK};
+ public static final String VCS_EXTRA = "${VCS_EXTRA}";
+
+ public static final String VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}";
+ public static final String VCS_FULL_HASH = "${VCS_FULL_HASH}";
+ public static final String VCS_SHORT_HASH = "${VCS_SHORT_HASH}";
+
+ public static final boolean VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
+}
+EOF
+}
+
+# For Java properties output
+javapropOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 1) VCS_WC_MODIFIED="true" ;;
+ 0) VCS_WC_MODIFIED="false" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+# ${GENERATED_HEADER}
+
+VCS_TYPE=${VCS_TYPE}
+VCS_BASENAME=${VCS_BASENAME}
+VCS_UUID=${VCS_UUID}
+VCS_NUM=${VCS_NUM}
+VCS_DATE=${VCS_DATE}
+VCS_BRANCH=${VCS_BRANCH}
+VCS_TAG=${VCS_TAG}
+VCS_TICK=${VCS_TICK}
+VCS_EXTRA=${VCS_EXTRA}
+
+VCS_ACTION_STAMP=${VCS_ACTION_STAMP}
+VCS_FULL_HASH=${VCS_FULL_HASH}
+VCS_SHORT_HASH=${VCS_SHORT_HASH}
+
+VCS_WC_MODIFIED=${VCS_WC_MODIFIED}
+EOF
+}
+
+# For m4 output
+m4Output() {
+ cat > "${TARGETFILE}" << EOF
+dnl ${GENERATED_HEADER}
+define(\`VCS_TYPE', \`${VCS_TYPE}')dnl
+define(\`VCS_BASENAME', \`${VCS_BASENAME}')dnl
+define(\`VCS_UUID', \`${VCS_UUID}')dnl
+define(\`VCS_NUM', \`${VCS_NUM}')dnl
+define(\`VCS_DATE', \`${VCS_DATE}')dnl
+define(\`VCS_BRANCH', \`${VCS_BRANCH}')dnl
+define(\`VCS_TAG', \`${VCS_TAG}')dnl
+define(\`VCS_TICK', \`${VCS_TICK}')dnl
+define(\`VCS_EXTRA', \`${VCS_EXTRA}')dnl
+define(\`VCS_ACTIONSTAMP', \`${VCS_ACTION_STAMP}')dnl
+define(\`VCS_FULLHASH', \`${VCS_FULL_HASH}')dnl
+define(\`VCS_SHORTHASH', \`${VCS_SHORT_HASH}')dnl
+define(\`VCS_WC_MODIFIED', \`${VCS_WC_MODIFIED}')dnl
+EOF
+}
+
+# For (La)TeX output
+texOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="false" ;;
+ 1) VCS_WC_MODIFIED="true" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+% ${GENERATED_HEADER}
+\def \vcsType {${VCS_TYPE}}
+\def \vcsBasename {${VCS_BASENAME}}
+\def \vcsUUID {${VCS_UUID}}
+\def \vcsNum {${VCS_NUM}}
+\def \vcsDate {${VCS_DATE}}
+\def \vcsBranch {${VCS_BRANCH}}
+\def \vcsTag {${VCS_TAG}}
+\def \vcsTick {${VCS_TICK}}
+\def \vcsExtra {${VCS_EXTRA}}
+\def \vcsACTIONSTAMP {${VCS_ACTION_STAMP}}
+\def \vcsFullHash {${VCS_FULL_HASH}}
+\def \vcsShortHash {${VCS_SHORT_HASH}}
+\def \vcsWCModified {${VCS_WC_MODIFIED}}
+\endinput
+EOF
+}
+
+# For scheme output
+schemeOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="#f" ;;
+ 1) VCS_WC_MODIFIED="#t" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+;; ${GENERATED_HEADER}
+(define VCS_TYPE "${VCS_TYPE}")
+(define VCS_BASENAME "${VCS_BASENAME}")
+(define VCS_UUID "${VCS_UUID}")
+(define VCS_NUM ${VCS_NUM})
+(define VCS_DATE "${VCS_DATE}")
+(define VCS_BRANCH "${VCS_BRANCH}")
+(define VCS_TAG "${VCS_TAG}")
+(define VCS_TICK ${VCS_TICK})
+(define VCS_EXTRA "${VCS_EXTRA}")
+
+(define VCS_ACTION_STAMP "${VCS_ACTION_STAMP}")
+(define VCS_FULL_HASH "${VCS_FULL_HASH}")
+(define VCS_SHORT_HASH "${VCS_SHORT_HASH}")
+
+(define VCS_WC_MODIFIED ${VCS_WC_MODIFIED})
+;; end
+EOF
+}
+
+# For clojure output
+clojureOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="false" ;;
+ 1) VCS_WC_MODIFIED="true" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+;; ${GENERATED_HEADER}
+(def VCS_TYPE "${VCS_TYPE}")
+(def VCS_BASENAME "${VCS_BASENAME}")
+(def VCS_UUID "${VCS_UUID}")
+(def VCS_NUM ${VCS_NUM})
+(def VCS_DATE "${VCS_DATE}")
+(def VCS_BRANCH "${VCS_BRANCH}")
+(def VCS_TAG "${VCS_TAG}")
+(def VCS_TICK ${VCS_TICK})
+(def VCS_EXTRA "${VCS_EXTRA}")
+
+(def VCS_ACTION_STAMP "${VCS_ACTION_STAMP}")
+(def VCS_FULL_HASH "${VCS_FULL_HASH}")
+(def VCS_SHORT_HASH "${VCS_SHORT_HASH}")
+
+(def VCS_WC_MODIFIED ${VCS_WC_MODIFIED})
+;; end
+EOF
+}
+
+# For rpm spec file output
+rpmOutput() {
+ cat > "${TARGETFILE}" << EOF
+# ${GENERATED_HEADER}
+$([ "${VCS_TYPE}" ] && echo "%define vcs_type ${VCS_TYPE}")
+$([ "${VCS_BASENAME}" ] && echo "%define vcs_basename ${VCS_BASENAME}")
+$([ "${VCS_UUID}" ] && echo "%define vcs_uuid ${VCS_UUID}")
+$([ "${VCS_NUM}" ] && echo "%define vcs_num ${VCS_NUM}")
+$([ "${VCS_DATE}" ] && echo "%define vcs_date ${VCS_DATE}")
+$([ "${VCS_BRANCH}" ] && echo "%define vcs_branch ${VCS_BRANCH}")
+$([ "${VCS_TAG}" ] && echo "%define vcs_tag ${VCS_TAG}")
+$([ "${VCS_TICK}" ] && echo "%define vcs_tick ${VCS_TICK}")
+$([ "${VCS_EXTRA}" ] && echo "%define vcs_extra ${VCS_EXTRA}")
+
+$([ "${VCS_ACTION_STAMP}" ] && echo "%define vcs_action_stamp ${VCS_ACTION_STAMP}")
+$([ "${VCS_FULL_HASH}" ] && echo "%define vcs_full_hash ${VCS_FULL_HASH}")
+$([ "${VCS_SHORT_HASH}" ] && echo "%define vcs_short_hash ${VCS_SHORT_HASH}")
+
+$([ "${VCS_WC_MODIFIED}" ] && echo "%define vcs_wc_modified ${VCS_WC_MODIFIED}")
+# end
+EOF
+}
+
+# shellcheck disable=SC2155,SC2039
+hppOutput() {
+ local NAMESPACE="$(echo "${VCS_BASENAME}" | sed -e 's:_::g' | tr '[:lower:]' '[:upper:]')"
+ cat > "${TARGETFILE}" << EOF
+/* ${GENERATED_HEADER} */
+
+#ifndef ${NAMESPACE}_AUTOREVISION_H
+#define ${NAMESPACE}_AUTOREVISION_H
+
+#include
+
+namespace $(echo "${NAMESPACE}" | tr '[:upper:]' '[:lower:]')
+{
+ const std::string VCS_TYPE = "${VCS_TYPE}";
+ const std::string VCS_BASENAME = "${VCS_BASENAME}";
+ const std::string VCS_UUID = "${VCS_UUID}";
+ const int VCS_NUM = ${VCS_NUM};
+ const std::string VCS_DATE = "${VCS_DATE}";
+ const std::string VCS_BRANCH = "${VCS_BRANCH}";
+ const std::string VCS_TAG = "${VCS_TAG}";
+ const int VCS_TICK = ${VCS_TICK};
+ const std::string VCS_EXTRA = "${VCS_EXTRA}";
+
+ const std::string VCS_ACTION_STAMP = "${VCS_ACTION_STAMP}";
+ const std::string VCS_FULL_HASH = "${VCS_FULL_HASH}";
+ const std::string VCS_SHORT_HASH = "${VCS_SHORT_HASH}";
+
+ const int VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
+}
+
+#endif
+
+/* end */
+EOF
+}
+
+matlabOutput() {
+ case "${VCS_WC_MODIFIED}" in
+ 0) VCS_WC_MODIFIED="FALSE" ;;
+ 1) VCS_WC_MODIFIED="TRUE" ;;
+ esac
+ cat > "${TARGETFILE}" << EOF
+% ${GENERATED_HEADER}
+
+VCS_TYPE = '${VCS_TYPE}';
+VCS_BASENAME = '${VCS_BASENAME}';
+VCS_UUID = '${VCS_UUID}';
+VCS_NUM = ${VCS_NUM};
+VCS_DATE = '${VCS_DATE}';
+VCS_BRANCH = '${VCS_BRANCH}';
+VCS_TAG = '${VCS_TAG}';
+VCS_TICK = ${VCS_TICK};
+VCS_EXTRA = '${VCS_EXTRA}';
+
+VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}';
+VCS_FULL_HASH = '${VCS_FULL_HASH}';
+VCS_SHORT_HASH = '${VCS_SHORT_HASH}';
+
+VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
+
+% end
+EOF
+}
+
+octaveOutput() {
+ cat > "${TARGETFILE}" << EOF
+% ${GENERATED_HEADER}
+
+VCS_TYPE = '${VCS_TYPE}';
+VCS_BASENAME = '${VCS_BASENAME}';
+VCS_UUID = '${VCS_UUID}';
+VCS_NUM = ${VCS_NUM};
+VCS_DATE = '${VCS_DATE}';
+VCS_BRANCH = '${VCS_BRANCH}';
+VCS_TAG = '${VCS_TAG}';
+VCS_TICK = ${VCS_TICK};
+VCS_EXTRA = '${VCS_EXTRA}';
+
+VCS_ACTION_STAMP = '${VCS_ACTION_STAMP}';
+VCS_FULL_HASH = '${VCS_FULL_HASH}';
+VCS_SHORT_HASH = '${VCS_SHORT_HASH}';
+
+VCS_WC_MODIFIED = ${VCS_WC_MODIFIED};
+
+% end
+EOF
+}
+
+cmakeOutput() {
+ cat > "${TARGETFILE}" << EOF
+# ${GENERATED_HEADER}
+
+set(VCS_TYPE ${VCS_TYPE})
+set(VCS_BASENAME ${VCS_BASENAME})
+set(VCS_UUID ${VCS_UUID})
+set(VCS_NUM ${VCS_NUM})
+set(VCS_DATE ${VCS_DATE})
+set(VCS_BRANCH ${VCS_BRANCH})
+set(VCS_TAG ${VCS_TAG})
+set(VCS_TICK ${VCS_TICK})
+set(VCS_EXTRA ${VCS_EXTRA})
+
+set(VCS_ACTION_STAMP ${VCS_ACTION_STAMP})
+set(VCS_FULL_HASH ${VCS_FULL_HASH})
+set(VCS_SHORT_HASH ${VCS_SHORT_HASH})
+
+set(VCS_WC_MODIFIED ${VCS_WC_MODIFIED})
+
+# end
+EOF
+}
+
+
+# Helper functions
+# Count path segments
+# shellcheck disable=SC2039
+pathSegment() {
+ local pathz="${1}"
+ local depth="0"
+
+ if [ ! -z "${pathz}" ]; then
+ # Continue until we are at / or there are no path separators left.
+ while [ ! "${pathz}" = "/" ] && [ ! "${pathz}" = "$(echo "${pathz}" | sed -e 's:/::')" ]; do
+ pathz="$(dirname "${pathz}")"
+ depth="$((depth+1))"
+ done
+ fi
+ echo "${depth}"
+}
+
+# Largest of four numbers
+# shellcheck disable=SC2039
+multiCompare() {
+ local larger="${1}"
+ local numA="${2}"
+ local numB="${3}"
+ local numC="${4}"
+
+ [ "${numA}" -gt "${larger}" ] && larger="${numA}"
+ [ "${numB}" -gt "${larger}" ] && larger="${numB}"
+ [ "${numC}" -gt "${larger}" ] && larger="${numC}"
+ echo "${larger}"
+}
+
+# Test for repositories
+# shellcheck disable=SC2155,SC2039
+repoTest() {
+ REPONUM="0"
+ if [ ! -z "$(git rev-parse HEAD 2>/dev/null)" ]; then
+ local gitPath="$(git rev-parse --show-toplevel)"
+ local gitDepth="$(pathSegment "${gitPath}")"
+ REPONUM="$((REPONUM+1))"
+ else
+ local gitDepth="0"
+ fi
+ if [ ! -z "$(hg root 2>/dev/null)" ]; then
+ local hgPath="$(hg root 2>/dev/null)"
+ local hgDepth="$(pathSegment "${hgPath}")"
+ REPONUM="$((REPONUM+1))"
+ else
+ local hgDepth="0"
+ fi
+ if [ ! -z "$(bzr root 2>/dev/null)" ]; then
+ local bzrPath="$(bzr root 2>/dev/null)"
+ local bzrDepth="$(pathSegment "${bzrPath}")"
+ REPONUM="$((REPONUM+1))"
+ else
+ local bzrDepth="0"
+ fi
+ if [ ! -z "$(svn info 2>/dev/null)" ]; then
+ local stringz=""
+ local stringx=""
+ local svnPath="$(svn info --xml | sed -n -e "s:${stringz}::" -e "s:${stringx}::p")"
+ # An old enough svn will not be able give us a path; default
+ # to 1 for that case.
+ if [ -z "${svnPath}" ]; then
+ local svnDepth="1"
+ else
+ local svnDepth="$(pathSegment "${svnPath}")"
+ fi
+ REPONUM="$((REPONUM+1))"
+ else
+ local svnDepth="0"
+ fi
+
+ # Do not do more work then we have to.
+ if [ "${REPONUM}" = "0" ]; then
+ return
+ fi
+
+ # Figure out which repo is the deepest and use it.
+ local wonRepo="$(multiCompare "${gitDepth}" "${hgDepth}" "${bzrDepth}" "${svnDepth}")"
+ if [ "${wonRepo}" = "${gitDepth}" ]; then
+ gitRepo
+ elif [ "${wonRepo}" = "${hgDepth}" ]; then
+ hgRepo
+ elif [ "${wonRepo}" = "${bzrDepth}" ]; then
+ bzrRepo
+ elif [ "${wonRepo}" = "${svnDepth}" ]; then
+ svnRepo
+ fi
+}
+
+
+
+# Detect which repos we are in and gather data.
+# shellcheck source=/dev/null
+if [ -f "${CACHEFILE}" ] && [ "${CACHEFORCE}" = "1" ]; then
+ # When requested only read from the cache to populate our symbols.
+ . "${CACHEFILE}"
+else
+ # If a value is not set through the environment set VCS_EXTRA to nothing.
+ : "${VCS_EXTRA:=""}"
+ repoTest
+
+ if [ -f "${CACHEFILE}" ] && [ "${REPONUM}" = "0" ]; then
+ # We are not in a repo; try to use a previously generated cache to populate our symbols.
+ . "${CACHEFILE}"
+ # Do not overwrite the cache if we know we are not going to write anything new.
+ CACHEFORCE="1"
+ elif [ "${REPONUM}" = "0" ]; then
+ echo "error: No repo or cache detected." 1>&2
+ exit 1
+ fi
+fi
+
+
+# -s output is handled here.
+if [ ! -z "${VAROUT}" ]; then
+ if [ "${VAROUT}" = "VCS_TYPE" ]; then
+ echo "${VCS_TYPE}"
+ elif [ "${VAROUT}" = "VCS_BASENAME" ]; then
+ echo "${VCS_BASENAME}"
+ elif [ "${VAROUT}" = "VCS_NUM" ]; then
+ echo "${VCS_NUM}"
+ elif [ "${VAROUT}" = "VCS_DATE" ]; then
+ echo "${VCS_DATE}"
+ elif [ "${VAROUT}" = "VCS_BRANCH" ]; then
+ echo "${VCS_BRANCH}"
+ elif [ "${VAROUT}" = "VCS_TAG" ]; then
+ echo "${VCS_TAG}"
+ elif [ "${VAROUT}" = "VCS_TICK" ]; then
+ echo "${VCS_TICK}"
+ elif [ "${VAROUT}" = "VCS_FULL_HASH" ]; then
+ echo "${VCS_FULL_HASH}"
+ elif [ "${VAROUT}" = "VCS_SHORT_HASH" ]; then
+ echo "${VCS_SHORT_HASH}"
+ elif [ "${VAROUT}" = "VCS_WC_MODIFIED" ]; then
+ echo "${VCS_WC_MODIFIED}"
+ elif [ "${VAROUT}" = "VCS_ACTION_STAMP" ]; then
+ echo "${VCS_ACTION_STAMP}"
+ else
+ echo "error: Not a valid output symbol." 1>&2
+ exit 1
+ fi
+fi
+
+
+# Detect requested output type and use it.
+if [ ! -z "${AFILETYPE}" ]; then
+ if [ "${AFILETYPE}" = "c" ]; then
+ cOutput
+ elif [ "${AFILETYPE}" = "h" ]; then
+ hOutput
+ elif [ "${AFILETYPE}" = "xcode" ]; then
+ xcodeOutput
+ elif [ "${AFILETYPE}" = "swift" ]; then
+ swiftOutput
+ elif [ "${AFILETYPE}" = "sh" ]; then
+ shOutput
+ elif [ "${AFILETYPE}" = "py" ] || [ "${AFILETYPE}" = "python" ]; then
+ pyOutput
+ elif [ "${AFILETYPE}" = "pl" ] || [ "${AFILETYPE}" = "perl" ]; then
+ plOutput
+ elif [ "${AFILETYPE}" = "lua" ]; then
+ luaOutput
+ elif [ "${AFILETYPE}" = "php" ]; then
+ phpOutput
+ elif [ "${AFILETYPE}" = "ini" ]; then
+ iniOutput
+ elif [ "${AFILETYPE}" = "js" ]; then
+ jsOutput
+ elif [ "${AFILETYPE}" = "json" ]; then
+ jsonOutput
+ elif [ "${AFILETYPE}" = "java" ]; then
+ javaOutput
+ elif [ "${AFILETYPE}" = "javaprop" ]; then
+ javapropOutput
+ elif [ "${AFILETYPE}" = "tex" ]; then
+ texOutput
+ elif [ "${AFILETYPE}" = "m4" ]; then
+ m4Output
+ elif [ "${AFILETYPE}" = "scheme" ]; then
+ schemeOutput
+ elif [ "${AFILETYPE}" = "clojure" ]; then
+ clojureOutput
+ elif [ "${AFILETYPE}" = "rpm" ]; then
+ rpmOutput
+ elif [ "${AFILETYPE}" = "hpp" ]; then
+ hppOutput
+ elif [ "${AFILETYPE}" = "matlab" ]; then
+ matlabOutput
+ elif [ "${AFILETYPE}" = "octave" ]; then
+ octaveOutput
+ elif [ "${AFILETYPE}" = "cmake" ]; then
+ cmakeOutput
+ else
+ echo "error: Not a valid output type." 1>&2
+ exit 1
+ fi
+fi
+
+
+# If requested, make a cache file.
+if [ ! -z "${CACHEFILE}" ] && [ ! "${CACHEFORCE}" = "1" ]; then
+ TARGETFILE="${CACHEFILE}.tmp"
+ shOutput
+
+ # Check to see if there have been any actual changes.
+ if [ ! -f "${CACHEFILE}" ]; then
+ mv -f "${CACHEFILE}.tmp" "${CACHEFILE}"
+ elif cmp -s "${CACHEFILE}.tmp" "${CACHEFILE}"; then
+ rm -f "${CACHEFILE}.tmp"
+ else
+ mv -f "${CACHEFILE}.tmp" "${CACHEFILE}"
+ fi
+fi
diff --git a/bin/ntc_radius_plug.inf b/bin/ntc_radius_plug.inf
index f883cb0..0e74f6c 100644
--- a/bin/ntc_radius_plug.inf
+++ b/bin/ntc_radius_plug.inf
@@ -1,12 +1,9 @@
[PLUGINFO]
-PLUGNAME=RADIUS
-SO_PATH=./plug/business/radius/radius.so
-INIT_FUNC=RADIUS_INIT
-DESTROY_FUNC=RADIUS_DESTROY
-FLAGCHANGE_FUNC=FLAG_CHANGE
-FLAGSTATE_FUNC=PROT_FUNSTAT
-GETPLUGID_FUNC=GET_PLUGID
+PLUGNAME=NTC_RADIUS_PLUG
+SO_PATH=./plug/business/ntc_radius_plug/ntc_radius_plug.so
+INIT_FUNC=NTC_RADIUS_PLUG_INIT
+DESTROY_FUNC=NTC_RADIUS_PLUG_DESTROY
-[UDP]
+[RADIUS]
FUNC_FLAG=ALL
-FUNC_NAME=RADIUS_ENTRY
+FUNC_NAME=NTC_RADIUS_PLUG_ENTRY
diff --git a/cmake/Package.cmake b/cmake/Package.cmake
new file mode 100644
index 0000000..69bc509
--- /dev/null
+++ b/cmake/Package.cmake
@@ -0,0 +1,41 @@
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(CPACK_PACKAGE_NAME "${PROJECT_NAME}-debug")
+else()
+ set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
+endif()
+
+message(STATUS "Package: ${CPACK_PACKAGE_NAME}")
+
+set(CPACK_PACKAGE_VECDOR "MESA")
+set(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}")
+set(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}")
+set(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}.${VERSION_BUILD}")
+set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
+
+set(CPACK_COMPONENTS_ALL devel)
+set(CPACK_RPM_PACKAGE_DEBUG 1)
+set(CPACK_RPM_COMPONENT_INSTALL OFF)
+set(CPACK_RPM_DEVEL_FILE_NAME "${PROJECT_NAME}-devel.rpm")
+set(CPACK_RPM_DEVEL_DEBUGINFO_FILE_NAME "${PROJECT_NAME}-devel-debuginfo.rpm")
+
+# RPM Build
+set(CPACK_GENERATOR "RPM")
+set(CPACK_RPM_AUTO_GENERATED_FILE_NAME ON)
+set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
+set(CPACK_RPM_PACKAGE_VENDOR "MESA")
+set(CPACK_RPM_PACKAGE_AUTOREQPROV "no")
+set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
+set(CPACK_RPM_DEBUGINFO_PACKAGE ON)
+
+
+set(CPACK_BUILD_SOURCE_DIRS "${CMAKE_SOURCE_DIR}")
+
+# Must uninstall the debug package before install release package
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(CPACK_RPM_PACKAGE_CONFLICTS "${PROJECT_NAME}-debug")
+else()
+ set(CPACK_RPM_PACKAGE_CONFLICTS ${PROJECT_NAME})
+ # set(CPACK_STRIP_FILES TRUE)
+endif()
+
+include(CPack)
diff --git a/cmake/Version.cmake b/cmake/Version.cmake
new file mode 100644
index 0000000..752f20f
--- /dev/null
+++ b/cmake/Version.cmake
@@ -0,0 +1,53 @@
+
+# Using autorevision.sh to generate version information
+
+set(__SOURCE_AUTORESIVISION ${CMAKE_SOURCE_DIR}/autorevision.sh)
+set(__AUTORESIVISION ${CMAKE_BINARY_DIR}/autorevision.sh)
+set(__VERSION_CACHE ${CMAKE_SOURCE_DIR}/version.txt)
+set(__VERSION_CONFIG ${CMAKE_BINARY_DIR}/version.cmake)
+
+file(COPY ${__SOURCE_AUTORESIVISION} DESTINATION ${CMAKE_BINARY_DIR}
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE)
+
+# execute autorevision.sh to generate version information
+execute_process(COMMAND ${__AUTORESIVISION} -t cmake -o ${__VERSION_CACHE}
+ OUTPUT_FILE ${__VERSION_CONFIG} ERROR_QUIET)
+include(${__VERSION_CONFIG})
+
+# extract major, minor, patch version from git tag
+string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VCS_TAG}")
+string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VCS_TAG}")
+string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VCS_TAG}")
+
+if(NOT VERSION_MAJOR)
+ set(VERSION_MAJOR 1)
+endif()
+
+if(NOT VERSION_MINOR)
+ set(VERSION_MINOR 0)
+endif()
+
+if(NOT VERSION_PATCH)
+ set(VERSION_PATCH 0)
+endif()
+
+set(VERSION "${VERSION_MAJOR}_${VERSION_MINOR}_${VERSION_PATCH}")
+set(VERSION_BUILD "${VCS_SHORT_HASH}")
+
+# print information
+message(STATUS "Version: ${VERSION}-${VERSION_BUILD}")
+
+if(NOT DEFINE_GIT_VERSION)
+ option(DEFINE_GIT_VERSION "Set DEFINE_GIT_VERSION to OFF" OFF)
+
+set(GIT_VERSION
+ "${VERSION}-${CMAKE_BUILD_TYPE}-${VERSION_BUILD}-${VCS_BRANCH}-${VCS_TAG}-${VCS_DATE}")
+string(REGEX REPLACE "[-:+/\\.]" "_" GIT_VERSION ${GIT_VERSION})
+
+if(DEFINE_GIT_VERSION)
+ add_definitions(-DGIT_VERSION=${GIT_VERSION})
+ option(DEFINE_GIT_VERSION "Set DEFINE_GIT_VERSION to OFF" ON)
+endif()
+
+endif()
diff --git a/preinstall/install.sh b/preinstall/install.sh
new file mode 100644
index 0000000..397e134
--- /dev/null
+++ b/preinstall/install.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+CONFILE=conf/radius/radius.conf
+DST=${RPM_INSTALL_PREFIX}
+mkdir -p ${DST}/plug/business/
+touch ${DST}/plug/conflist.inf
+mkdir -p ${DST}/conf/
+touch ${DST}/${CONFILE}
+
+if [[ -z `grep -rn '\[business\]' ${DST}/plug/conflist.inf` ]];then
+ echo '[business]' >> ${DST}/plug/conflist.inf
+fi
+
+if [[ -z `grep -rn 'ntc_radius_plug.inf' ${DST}/plug/conflist.inf` ]];then
+ sed -i '/\[business\]/a\./plug/business/ntc_radius_plug/ntc_radius_plug.inf' ${DST}/plug/conflist.inf
+fi
+
+if [[ -z `grep -rn '\[RADIUS_PLUG\]' ${DST}/${CONFILE}` ]];then
+ sed -i '1i\\[RADIUS_PLUG\]' ${DST}/${CONFILE}
+ sed -i '/\[RADIUS_PLUG\]/a\LOG_LEVEL=30' ${DST}/${CONFILE}
+ sed -i '/\[RADIUS_PLUG\]/a\LOG_PATH=./log/ntc_radius_plug/ntc_radius_plug' ${DST}/${CONFILE}
+ sed -i '/\[RADIUS_PLUG\]/a\NIC_NAME=lo' ${DST}/${CONFILE}
+ sed -i '/\[RADIUS_PLUG\]/a\SERVICE_ID=162' ${DST}/${CONFILE}
+ sed -i '/\[RADIUS_PLUG\]/a\COLLECT_TOPIC=RADIUS-RECORD-LOG' ${DST}/${CONFILE}
+ sed -i '/\[RADIUS_PLUG\]/a\BROKERLIST=127.0.0.1:9092' ${DST}/${CONFILE}
+ sed -i '/\[RADIUS_PLUG\]/a\DEVICE_ID=0' ${DST}/${CONFILE}
+fi
diff --git a/preinstall/uninstall.sh b/preinstall/uninstall.sh
new file mode 100644
index 0000000..18703b0
--- /dev/null
+++ b/preinstall/uninstall.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+CONFILE=conf/radius/radius.conf
+DST=${RPM_INSTALL_PREFIX}
+mkdir -p ${DST}/plug/business/
+touch ${DST}/plug/conflist.inf
+touch ${DST}/${CONFILE}
+sed -i '/fw_mail_plug.inf/d' ${DST}/plug/conflist.inf
+sed -i '/\[RADIUS_PLUG\]/,+7d' ${DST}/${CONFILE}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..54efa98
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 2.8)
+
+add_definitions(-fPIC)
+
+set(SRC ntc_radius_plug.cpp)
+
+include_directories(${CMAKE_SOURCE_DIR}/src)
+include_directories(/opt/MESA/include/)
+
+set(DEPEND_DYN_LIB MESA_handle_logger MESA_prof_load cjson rdkafka)
+
+add_library(ntc_radius_plug SHARED ${SRC})
+target_link_libraries(ntc_radius_plug ${DEPEND_DYN_LIB})
+set_target_properties(ntc_radius_plug PROPERTIES PREFIX "")
+
+install(TARGETS ntc_radius_plug DESTINATION ${CMAKE_INSTALL_PREFIX}/plug/business/ntc_radius_plug)
+install(FILES ../bin/ntc_radius_plug.inf DESTINATION ${CMAKE_INSTALL_PREFIX}/plug/business/ntc_radius_plug)
diff --git a/src/ntc_radius_plug.cpp b/src/ntc_radius_plug.cpp
index 28f1c51..4b9598c 100644
--- a/src/ntc_radius_plug.cpp
+++ b/src/ntc_radius_plug.cpp
@@ -25,8 +25,30 @@
#include "ntc_radius_plug.h"
-static int NTC_RADIUS_PLUG_VERSION_20191022=0;
-const char *config_file="t1conf/main.conf";
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define GIT_VERSION_CATTER(v) __attribute__((__used__)) const char * GIT_VERSION_##v = NULL
+#define GIT_VERSION_EXPEND(v) GIT_VERSION_CATTER(v)
+
+/* VERSION TAG */
+#ifdef GIT_VERSION
+GIT_VERSION_EXPEND(GIT_VERSION);
+#else
+static __attribute__((__used__)) const char * GIT_VERSION_UNKNOWN = NULL;
+#endif
+#undef GIT_VERSION_CATTER
+#undef GIT_VERSION_EXPEND
+
+#ifdef __cplusplus
+}
+#endif
+
+
+static int NTC_RADIUS_PLUG_VERSION_20191211=0;
+const char *config_file="conf/radius/radius.conf";
g_ntc_radius_plug_t g_ntc_radius_plug;
@@ -65,88 +87,157 @@ error:
}
-int get_radius_object_element(cJSON *radius_info_object, radius_header_t *radius_header, radius_body_t *radius_body)
+int get_radius_object_element(cJSON *radius_info_object, cJSON *radius_debug, radius_header_t *radius_header, radius_body_t *radius_body, int *account_index)
{
int i=0;
- cJSON *radius_json_obj = radius_info_object;
- cJSON_AddNumberToObject(radius_json_obj, "CODE", radius_header->code);
+ cJSON_AddNumberToObject(radius_debug, "radius_packet_type", radius_header->code);
+ cJSON_AddNumberToObject(radius_info_object, "radius_packet_type", radius_header->code);
for(i=0; iattribute_num; i++)
{
switch(radius_body->attribute[i].type)
{
- case RADIUS_USER_NAME:
- cJSON_AddStringToObject(radius_json_obj, "user_name", (char *)(radius_body->attribute[i].value));
- break;
- case CALLBACK_NUMBER:
- cJSON_AddStringToObject(radius_json_obj, "CALLBACK_NUMBER", (char *)(radius_body->attribute[i].value));
- break;
- case CALLBACK_ID:
- cJSON_AddStringToObject(radius_json_obj, "CALLBACK_ID", (char *)(radius_body->attribute[i].value));
- break;
- case CALLED_STATION_ID:
- cJSON_AddStringToObject(radius_json_obj, "CALLED_STATION_ID", (char *)(radius_body->attribute[i].value));
- break;
- case CALLING_STATION_ID:
- cJSON_AddStringToObject(radius_json_obj, "CALLING_STATION_ID", (char *)(radius_body->attribute[i].value));
- break;
- case ACCT_SESSION_ID:
- cJSON_AddStringToObject(radius_json_obj, "ACCT_SESSION_ID", (char *)(radius_body->attribute[i].value));
- break;
- case ACCT_MULTI_SESSION_ID:
- cJSON_AddStringToObject(radius_json_obj, "ACCT_MULTI_SESSION_ID", (char *)(radius_body->attribute[i].value));
+ case USER_NAME:
+ cJSON_AddStringToObject(radius_debug, "radius_account", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_account", (char *)(radius_body->attribute[i].value));
+ *account_index=i;
break;
case NAS_IP_ADDRESS:
- cJSON_AddStringToObject(radius_json_obj, "NAS_IP_ADDRESS", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_debug, "radius_nas_ip", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_nas_ip", (char *)(radius_body->attribute[i].value));
break;
- case FRAMED_IP_ADDRESS:
- cJSON_AddStringToObject(radius_json_obj, "FRAMED_IP_ADDRESS", (char *)(radius_body->attribute[i].value));
- break;
- case FRAMED_IP_NETMASK:
- cJSON_AddStringToObject(radius_json_obj, "FRAMED_IP_NETMASK", (char *)(radius_body->attribute[i].value));
+ case NAS_PORT:
+ cJSON_AddNumberToObject(radius_debug, "radius_nas_port", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_nas_port", *(unsigned int *)(radius_body->attribute[i].value));
break;
case SERVICE_TYPE:
- cJSON_AddNumberToObject(radius_json_obj, "SERVICE_TYPE", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_service_type", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_service_type", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case FRAMED_PROTOCOL:
+ cJSON_AddNumberToObject(radius_debug, "radius_framed_protocol", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_framed_protocol", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case FRAMED_IP_ADDRESS:
+ cJSON_AddStringToObject(radius_debug, "radius_framed_ip", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_framed_ip", (char *)(radius_body->attribute[i].value));
+ break;
+ case FRAMED_IP_NETMASK:
+ cJSON_AddStringToObject(radius_debug, "radius_framed_ip_netmask", (char *)(radius_body->attribute[i].value));
+ break;
+ case FRAMED_ROUTING:
+ cJSON_AddNumberToObject(radius_debug, "radius_framed_routing", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case FILTER_ID:
+ cJSON_AddStringToObject(radius_debug, "radius_filter_id", (char *)(radius_body->attribute[i].value));
break;
case FRAMED_MTU:
- cJSON_AddNumberToObject(radius_json_obj, "FRAMED_MTU", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_framed_mtu", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case FRAMED_COMPRESSION:
+ cJSON_AddNumberToObject(radius_debug, "radius_framed_compression", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case CALLBACK_NUMBER:
+ cJSON_AddStringToObject(radius_debug, "radius_callback_number", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_callback_number", (char *)(radius_body->attribute[i].value));
break;
+ case CALLBACK_ID:
+ cJSON_AddStringToObject(radius_debug, "radius_callback_id", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_callback_id", (char *)(radius_body->attribute[i].value));
+ break;
+ case CLASS:
+ cJSON_AddStringToObject(radius_debug, "radius_class", (char *)(radius_body->attribute[i].value));
+ break;
case SESSION_TIMEOUT:
- cJSON_AddNumberToObject(radius_json_obj, "SESSION_TIMEOUT", *(unsigned int *)(radius_body->attribute[i].value));
- break;
+ cJSON_AddNumberToObject(radius_debug, "radius_session_timeout", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_session_timeout", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
case IDLE_TIMEOUT:
- cJSON_AddNumberToObject(radius_json_obj, "IDLE_TIMEOUT", *(unsigned int *)(radius_body->attribute[i].value));
- break;
+ cJSON_AddNumberToObject(radius_debug, "radius_idle_timeout", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_idle_timeout", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
case TERMINATION_ACTION:
- cJSON_AddNumberToObject(radius_json_obj, "TERMINATION_ACTION", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_termination_action", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_termination_action", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case CALLED_STATION_ID:
+ cJSON_AddStringToObject(radius_debug, "radius_called_station_id", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_called_station_id", (char *)(radius_body->attribute[i].value));
+ break;
+ case CALLING_STATION_ID:
+ cJSON_AddStringToObject(radius_debug, "radius_calling_station_id", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_calling_station_id", (char *)(radius_body->attribute[i].value));
+ break;
+ case NAS_IDENTIFIER:
+ cJSON_AddStringToObject(radius_debug, "radius_nas_indentifies", (char *)(radius_body->attribute[i].value));
break;
case PROXY_STATE:
- cJSON_AddNumberToObject(radius_json_obj, "PROXY_STATE", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_proxy_state", *(unsigned int *)(radius_body->attribute[i].value));
break;
case ACCT_STATUS_TYPE:
- cJSON_AddNumberToObject(radius_json_obj, "ACCT_STATUS_TYPE", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_status_type", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_status_type", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case ACCT_DELAY_TIME:
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_delay_time", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_delay_time", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case ACCT_SESSION_ID:
+ cJSON_AddStringToObject(radius_debug, "radius_acct_session_id", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_acct_session_id", (char *)(radius_body->attribute[i].value));
+ break;
+ case ACCT_MULTI_SESSION_ID:
+ cJSON_AddStringToObject(radius_debug, "radius_acct_multi_session_id", (char *)(radius_body->attribute[i].value));
+ cJSON_AddStringToObject(radius_info_object, "radius_acct_multi_session_id", (char *)(radius_body->attribute[i].value));
break;
case ACCT_INPUT_OCTETS:
- cJSON_AddNumberToObject(radius_json_obj, "ACCT_INPUT_OCTETS", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_input_octets", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_input_octets", *(unsigned int *)(radius_body->attribute[i].value));
break;
case ACCT_OUTPUT_OCTETS:
- cJSON_AddNumberToObject(radius_json_obj, "ACCT_OUTPUT_OCTETS", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_output_octets", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_output_octets", *(unsigned int *)(radius_body->attribute[i].value));
break;
case ACCT_INPUT_PACKETS:
- cJSON_AddNumberToObject(radius_json_obj, "ACCT_INPUT_PACKETS", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_input_packets", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_input_packets", *(unsigned int *)(radius_body->attribute[i].value));
break;
case ACCT_OUTPUT_PACKETS:
- cJSON_AddNumberToObject(radius_json_obj, "ACCT_OUTPUT_PACKETS", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_output_packets", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_output_packets", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case ACCT_SESSION_TIME:
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_session_time", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_session_time", *(unsigned int *)(radius_body->attribute[i].value));
break;
case ACCT_TERMINATE_CAUSE:
- cJSON_AddNumberToObject(radius_json_obj, "ACCT_TERMINATE_CAUSE", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_terminate_cause", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_terminate_cause", *(unsigned int *)(radius_body->attribute[i].value));
break;
case ACCT_LINK_COUNT:
- cJSON_AddNumberToObject(radius_json_obj, "ACCT_LINK_COUNT", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_link_count", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_link_count", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case ACCT_INPUT_GIGAWORDS:
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_input_gigawords", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case ACCT_OUTPUT_GIGAWORDS:
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_output_gigawords", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case ACCT_EVENT_TIMESTAMP:
+ cJSON_AddNumberToObject(radius_debug, "radius_event_timestamp", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_event_timestamp", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case NAS_PORT_TYPE:
+ cJSON_AddNumberToObject(radius_debug, "radius_nas_port_type", *(unsigned int *)(radius_body->attribute[i].value));
break;
case ACCT_INTERIM_INTERVAL:
- cJSON_AddNumberToObject(radius_json_obj, "ACCT_INTERIM_INTERVAL", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_debug, "radius_acct_interim_interval", *(unsigned int *)(radius_body->attribute[i].value));
+ cJSON_AddNumberToObject(radius_info_object, "radius_acct_interim_interval", *(unsigned int *)(radius_body->attribute[i].value));
+ break;
+ case NAS_PORT_ID:
+ cJSON_AddStringToObject(radius_debug, "radius_nas_port_id", (char *)(radius_body->attribute[i].value));
break;
default:
continue;
@@ -158,7 +249,8 @@ int get_radius_object_element(cJSON *radius_info_object, radius_header_t *radius
static int streamInfo2jsonObject(cJSON *json_obj, const struct streaminfo *a_stream)
{
- int ret = 0;
+ time_t cur_time;
+ int ret=0,con_duration_ms=0;
const char *addr_proto = NULL;
unsigned short tunnel_type=0;
char nest_addr_buf[1024];
@@ -166,37 +258,64 @@ static int streamInfo2jsonObject(cJSON *json_obj, const struct streaminfo *a_str
const struct layer_addr *addr=NULL;
char src_ip_str[128] = {0}, dst_ip_str[128] = {0};
- cJSON_AddNumberToObject(json_obj, "stream_dir", a_stream->dir);
+ cJSON_AddNumberToObject(json_obj, "common_stream_dir", a_stream->dir);
addr=&(a_stream->addr);
switch(addr->addrtype)
{
case ADDR_TYPE_IPV4:
case __ADDR_TYPE_IP_PAIR_V4:
- cJSON_AddNumberToObject(json_obj, "addr_type", 4);
+ cJSON_AddNumberToObject(json_obj, "common_address_type", 4);
inet_ntop(AF_INET, &addr->ipv4->saddr, src_ip_str, sizeof(src_ip_str));
inet_ntop(AF_INET, &addr->ipv4->daddr, dst_ip_str, sizeof(dst_ip_str));
- cJSON_AddStringToObject(json_obj, "s_ip", src_ip_str);
- cJSON_AddStringToObject(json_obj, "d_ip", dst_ip_str);
- cJSON_AddNumberToObject(json_obj, "s_port", ntohs(addr->ipv4->source));
- cJSON_AddNumberToObject(json_obj, "d_port", ntohs(addr->ipv4->dest));
+ cJSON_AddStringToObject(json_obj, "common_client_ip", src_ip_str);
+ cJSON_AddStringToObject(json_obj, "common_server_ip", dst_ip_str);
+ cJSON_AddNumberToObject(json_obj, "common_client_port", ntohs(addr->ipv4->source));
+ cJSON_AddNumberToObject(json_obj, "common_server_port", ntohs(addr->ipv4->dest));
break;
case ADDR_TYPE_IPV6:
case __ADDR_TYPE_IP_PAIR_V6:
- cJSON_AddNumberToObject(json_obj, "addr_type", 6);
+ cJSON_AddNumberToObject(json_obj, "common_address_type", 6);
inet_ntop(AF_INET6, addr->ipv6->saddr, src_ip_str, sizeof(src_ip_str));
inet_ntop(AF_INET6, addr->ipv6->daddr, dst_ip_str, sizeof(dst_ip_str));
- cJSON_AddStringToObject(json_obj, "s_ip", src_ip_str);
- cJSON_AddStringToObject(json_obj, "d_ip", dst_ip_str);
- cJSON_AddNumberToObject(json_obj, "s_port", ntohs(addr->ipv6->source));
- cJSON_AddNumberToObject(json_obj, "d_port", ntohs(addr->ipv6->dest));
+ cJSON_AddStringToObject(json_obj, "common_client_ip", src_ip_str);
+ cJSON_AddStringToObject(json_obj, "common_server_ip", dst_ip_str);
+ cJSON_AddNumberToObject(json_obj, "common_client_port", ntohs(addr->ipv6->source));
+ cJSON_AddNumberToObject(json_obj, "common_server_port", ntohs(addr->ipv6->dest));
break;
default:
break;
}
+ cJSON_AddNumberToObject(json_obj, "common_c2s_pkt_num", a_stream->ptcpdetail->serverpktnum);
+ cJSON_AddNumberToObject(json_obj, "common_s2c_pkt_num", a_stream->ptcpdetail->clientpktnum);
+ cJSON_AddNumberToObject(json_obj, "common_c2s_byte_num", a_stream->ptcpdetail->serverbytes);
+ cJSON_AddNumberToObject(json_obj, "common_s2c_byte_num", a_stream->ptcpdetail->clientbytes);
+
+ cur_time = time(NULL);
+ if(a_stream!=NULL && a_stream->ptcpdetail!=NULL)
+ {
+ cJSON_AddNumberToObject(json_obj, "common_start_time", a_stream->ptcpdetail->createtime);
+ cJSON_AddNumberToObject(json_obj, "common_end_time", a_stream->ptcpdetail->lastmtime);
+
+ con_duration_ms=(a_stream->ptcpdetail->lastmtime-a_stream->ptcpdetail->createtime)*1000;
+ cJSON_AddNumberToObject(json_obj, "common_con_duration_ms", con_duration_ms);
+ }
+ else
+ {
+ con_duration_ms=0;
+ cJSON_AddNumberToObject(json_obj, "common_start_time", cur_time);
+ cJSON_AddNumberToObject(json_obj, "common_end_time", cur_time);
+ cJSON_AddNumberToObject(json_obj, "common_con_duration_ms", con_duration_ms);
+ }
+
+ int device_id_size=sizeof(unsigned long long);
+ unsigned long long device_id=(unsigned long long)g_ntc_radius_plug.device_id;
+ MESA_get_stream_opt(a_stream, MSO_GLOBAL_STREAM_ID, (void *)&device_id, &device_id_size);
+ cJSON_AddNumberToObject(json_obj, "common_stream_trace_id", device_id);
+
addr_proto = layer_addr_prefix_ntop(a_stream);
- cJSON_AddStringToObject(json_obj, "trans_proto", addr_proto);
+ cJSON_AddStringToObject(json_obj, "common_l4_protocol", addr_proto);
ret=MESA_get_stream_opt(a_stream, MSO_STREAM_TUNNEL_TYPE, &tunnel_type, &tunnel_type_size);
assert(ret==0);
@@ -209,7 +328,7 @@ static int streamInfo2jsonObject(cJSON *json_obj, const struct streaminfo *a_str
stream_addr_list_ntop(a_stream,nest_addr_buf, sizeof(nest_addr_buf));
}
- cJSON_AddStringToObject(json_obj, "addr_list", nest_addr_buf);
+ cJSON_AddStringToObject(json_obj, "common_address_list", nest_addr_buf);
return 0;
}
@@ -217,72 +336,50 @@ static int streamInfo2jsonObject(cJSON *json_obj, const struct streaminfo *a_str
char NTC_RADIUS_PLUG_ENTRY(stSessionInfo *session_info, void **pme, int thread_seq, struct streaminfo *stream, void *a_packet)
{
- int ret=0,status=0;
+ int status=0;
int config_id=0;
- int payload_len=0;
- time_t cur_time;
+ int payload_len=0,index=0;
char *payload=NULL;
- struct vxlan_info vinfo;
- int opt_val_len = sizeof(vinfo);
radius_info_t *radius_info=(radius_info_t *)session_info->app_info;
cJSON *radius_info_object=cJSON_CreateObject();
streamInfo2jsonObject(radius_info_object, stream);
- get_radius_object_element(radius_info_object, &radius_info->header, &radius_info->body);
- cJSON_AddNumberToObject(radius_info_object, "cfg_id", config_id);
- cJSON_AddNumberToObject(radius_info_object, "service", g_ntc_radius_plug.service_id);
+ cJSON_AddNumberToObject(radius_info_object, "common_policy_id", config_id);
+ cJSON_AddNumberToObject(radius_info_object, "common_service", g_ntc_radius_plug.service_id);
+
+ cJSON_AddStringToObject(radius_info_object, "common_sled_ip", g_ntc_radius_plug.local_ip);
+ cJSON_AddStringToObject(radius_info_object, "common_schema_type", "RADIUS");
+
+ cJSON *radius_debug=cJSON_Duplicate(radius_info_object, 1);
- cur_time = time(NULL);
- if(stream!=NULL && stream->ptcpdetail!=NULL)
- {
- cJSON_AddNumberToObject(radius_info_object, "recv_time", stream->ptcpdetail->createtime);
- }
- else
- {
- cJSON_AddNumberToObject(radius_info_object, "recv_time", cur_time);
- }
- cJSON_AddNumberToObject(radius_info_object, "found_time", cur_time);
-
- ret = MESA_get_stream_opt(stream, MSO_STREAM_VXLAN_INFO, &vinfo, &opt_val_len);
- if(ret < 0)
- {
- MESA_handle_runtime_log(g_ntc_radius_plug.logger, RLOG_LV_FATAL, "DNS_COLLECT_LOG", "soq log: get vxlan info error, tuple4: %s", printaddr(&stream->addr, thread_seq));
- }
- else
- {
- cJSON_AddNumberToObject(radius_info_object, "entrance_id", vinfo.entrance_id);
- cJSON_AddNumberToObject(radius_info_object, "direction", vinfo.link_dir);
- cJSON_AddNumberToObject(radius_info_object, "device_id", vinfo.dev_id);
- cJSON_AddNumberToObject(radius_info_object, "encap_type", vinfo.encap_type);
- cJSON_AddNumberToObject(radius_info_object, "link_id", vinfo.link_id);
-
- cJSON_AddStringToObject(radius_info_object, "inner_smac", (char *)vinfo.inner_smac);
- cJSON_AddStringToObject(radius_info_object, "inner_dmac", (char *)vinfo.inner_dmac);
- }
-
- cJSON_AddStringToObject(radius_info_object, "cap_ip", g_ntc_radius_plug.local_ip);
-
+ get_radius_object_element(radius_info_object, radius_debug, &radius_info->header, &radius_info->body, &index);
payload = cJSON_PrintUnformatted(radius_info_object);
payload_len = strlen(payload);
-
- status = rd_kafka_produce(g_ntc_radius_plug.topic_rkt, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_COPY, payload, payload_len, NULL, 0, NULL);
+ status = rd_kafka_produce(g_ntc_radius_plug.topic_rkt, RD_KAFKA_PARTITION_UA, RD_KAFKA_MSG_F_COPY, payload, payload_len,
+ radius_info->body.attribute[index].value, radius_info->body.attribute[index].len, NULL);
if(status < 0)
{
- MESA_handle_runtime_log(g_ntc_radius_plug.logger,RLOG_LV_INFO,"sendlog", "sendlog to kafka is error, status: %d, topic: %s payload: %s", status, g_ntc_radius_plug.topic_name, payload);
+ MESA_handle_runtime_log(g_ntc_radius_plug.logger,RLOG_LV_INFO,"SEND_LOG", "sendlog to kafka is error, status: %d, topic: %s payload: %s", status, g_ntc_radius_plug.topic_name, payload);
}
else
{
- MESA_handle_runtime_log(g_ntc_radius_plug.logger,RLOG_LV_INFO,"sendlog", "topic: %s %s", g_ntc_radius_plug.topic_name, payload);
+ MESA_handle_runtime_log(g_ntc_radius_plug.logger,RLOG_LV_INFO,"SEND_LOG", "topic: %s %s", g_ntc_radius_plug.topic_name, payload);
}
free(payload);
cJSON_Delete(radius_info_object);
radius_info_object = NULL;
+
+ payload = cJSON_PrintUnformatted(radius_debug);
+ MESA_handle_runtime_log(g_ntc_radius_plug.logger,RLOG_LV_INFO, "RADIUS_DEBUG", "payload: %s", payload);
+ free(payload);
+ cJSON_Delete(radius_debug);
+ radius_debug = NULL;
return APP_STATE_GIVEME;
}
@@ -297,12 +394,13 @@ int NTC_RADIUS_PLUG_INIT(void)
rd_kafka_topic_conf_t *topic_conf;
memset(&g_ntc_radius_plug,0,sizeof(g_ntc_radius_plug_t));
- MESA_load_profile_string_def(config_file, "SYSTEM", "NIC_NAME", nic_name, sizeof(nic_name), "eth0");
- MESA_load_profile_string_def(config_file, "RADIUS","LOG_PATH",g_ntc_radius_plug.pathname, sizeof(g_ntc_radius_plug.pathname), "./t1log/ntc_radius_plug/ntc_radius_plug");
- MESA_load_profile_int_def(config_file, "RADIUS", "SERVICE_ID", &g_ntc_radius_plug.service_id, 0xA2);
- MESA_load_profile_int_def(config_file, "RADIUS","LEVEL", &g_ntc_radius_plug.level, RLOG_LV_FATAL);
- MESA_load_profile_string_def(config_file, "RADIUS", "COLLECT_TOPIC", g_ntc_radius_plug.topic_name, sizeof(g_ntc_radius_plug.topic_name), "eth0");
- MESA_load_profile_string_def(config_file, "RADIUS", "BROKERLIST", g_ntc_radius_plug.brokerlist, sizeof(g_ntc_radius_plug.brokerlist), "127.0.0.1:9092");
+ MESA_load_profile_string_def(config_file, "RADIUS_PLUG", "NIC_NAME", nic_name, sizeof(nic_name), "lo");
+ MESA_load_profile_string_def(config_file, "RADIUS_PLUG","LOG_PATH",g_ntc_radius_plug.pathname, sizeof(g_ntc_radius_plug.pathname), "./log/ntc_radius_plug/ntc_radius_plug");
+ MESA_load_profile_int_def(config_file, "RADIUS_PLUG", "SERVICE_ID", &g_ntc_radius_plug.service_id, 0xA2);
+ MESA_load_profile_int_def(config_file, "RADIUS_PLUG","LOG_LEVEL", &g_ntc_radius_plug.level, RLOG_LV_FATAL);
+ MESA_load_profile_string_def(config_file, "RADIUS_PLUG", "COLLECT_TOPIC", g_ntc_radius_plug.topic_name, sizeof(g_ntc_radius_plug.topic_name), "RADIUS-RECORD-LOG");
+ MESA_load_profile_string_def(config_file, "RADIUS_PLUG", "BROKERLIST", g_ntc_radius_plug.brokerlist, sizeof(g_ntc_radius_plug.brokerlist), "127.0.0.1:9092");
+ MESA_load_profile_int_def(config_file, "RADIUS_PLUG", "DEVICE_ID", &g_ntc_radius_plug.device_id, 0);
g_ntc_radius_plug.logger = MESA_create_runtime_log_handle(g_ntc_radius_plug.pathname, g_ntc_radius_plug.level);
if(g_ntc_radius_plug.logger == NULL)
@@ -345,7 +443,7 @@ int NTC_RADIUS_PLUG_INIT(void)
return -1;
}
- printf("INIT NTC_RADIUS_PLUG SUCCESS, VERSION: %d\n", NTC_RADIUS_PLUG_VERSION_20191022);
+ printf("INIT NTC_RADIUS_PLUG SUCCESS, VERSION: %d\n", NTC_RADIUS_PLUG_VERSION_20191211);
return 0;
}
diff --git a/src/ntc_radius_plug.h b/src/ntc_radius_plug.h
index 905056e..30257ef 100644
--- a/src/ntc_radius_plug.h
+++ b/src/ntc_radius_plug.h
@@ -11,6 +11,7 @@ typedef struct _ntc_radius_plug
{
int level;
int service_id;
+ int device_id;
void *logger;
char pathname[128];
char topic_name[128];