RIC-125: Expose discovered gNBs and their status via O1 28/2528/2
authorMohamed Abukar <abukar.mohamed@nokia.com>
Sat, 15 Feb 2020 06:03:57 +0000 (08:03 +0200)
committerMohamed Abukar <abukar.mohamed@nokia.com>
Mon, 17 Feb 2020 14:19:21 +0000 (16:19 +0200)
Change-Id: Ibaef18ba33ab6a889b9623a36bd7dcb7404bb014
Signed-off-by: Mohamed Abukar <abukar.mohamed@nokia.com>
16 files changed:
.gitignore [new file with mode: 0644]
Dockerfile
agent/build_o1agent.sh [new file with mode: 0755]
agent/cli/o1-cli.go
agent/cmd/o1agent.go
agent/config/config-file.json
agent/go.mod
agent/go.sum
agent/pkg/nbi/helper.c
agent/pkg/nbi/helper.h
agent/pkg/nbi/nbi.go
agent/pkg/nbi/nbi_test.go
agent/pkg/nbi/types.go
agent/pkg/sbi/sbi.go
agent/yang/o-ran-sc-ric-gnb-status-v1.yang [new file with mode: 0755]
container-tag.yaml

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..2493dd2
--- /dev/null
@@ -0,0 +1,2 @@
+agent/build
+agent/Makefile
index 7cb06df..6be155a 100755 (executable)
@@ -14,7 +14,7 @@
 #   limitations under the License.
 
 #----------------------------------------------------------
-FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:4-u18.04-nng AS o2mediator-build
+FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:4-u18.04-nng AS o1mediator-build
 
 RUN apt-get update -y && apt-get install -y jq \
       git \
@@ -70,7 +70,7 @@ RUN \
       cd /opt/dev && \
       git clone https://github.com/sysrepo/sysrepo.git && \
       cd sysrepo && mkdir build && cd build && \
-      cmake -DCMAKE_BUILD_TYPE:String="Release" -DSR_RPC_CB_TIMEOUT=30000 -DENABLE_TESTS=OFF -DREPOSITORY_LOC:PATH=/etc/sysrepo .. && \
+      cmake -DCMAKE_BUILD_TYPE:String="Release" -DENABLE_TESTS=OFF -DREPOSITORY_LOC:PATH=/etc/sysrepo .. && \
       make -j2 && \
       make install && make sr_clean && \
       ldconfig
@@ -90,7 +90,7 @@ RUN \
       cd /opt/dev && \
       git clone https://github.com/CESNET/Netopeer2.git && \
       cd Netopeer2/server && mkdir build && cd build && \
-      cmake -DCMAKE_BUILD_TYPE:String="Release" .. && \
+      cmake -DCMAKE_BUILD_TYPE:String="Release" -DNP2SRV_DATA_CHANGE_TIMEOUT=30000 -DNP2SRV_DATA_CHANGE_WAIT=ON .. && \
       make -j2 && \
       make install && \
       cd ../../cli && mkdir build && cd build && \
@@ -101,7 +101,7 @@ RUN \
 # ======================================================================
 
 # RMR
-ARG RMRVERSION=1.11.0
+ARG RMRVERSION=3.1.0
 ARG RMRLIBURL=https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_${RMRVERSION}_amd64.deb/download.deb
 ARG RMRDEVURL=https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_${RMRVERSION}_amd64.deb/download.deb
 
@@ -118,31 +118,30 @@ RUN cd /go/bin \
     && chmod +x swagger
 
 RUN mkdir -p /go/src/ws
+COPY . /go/src/ws
 WORKDIR "/go/src/ws/agent"
 
 # Module prepare (if go.mod/go.sum updated)
-COPY agent /go/src/ws
 RUN GO111MODULE=on go mod download
 
+# Fetch xApp Manager REST API spec
 RUN mkdir -p api \
     && mkdir -p pkg \
     && git clone "https://gerrit.o-ran-sc.org/r/ric-plt/appmgr" \
     && cp appmgr/api/appmgr_rest_api.yaml api/ \
     && rm -rf appmgr
     
-# build and test
-COPY . /go/src/ws
-
 # generate swagger client
 RUN /go/bin/swagger generate client -f api/appmgr_rest_api.yaml -t pkg/ -m appmgrmodel -c appmgrclient
-# build the o1agent
-RUN GO111MODULE=on GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o o1agent cmd/o1agent.go
+# build and test o1agent
+#RUN GO111MODULE=on GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o o1agent cmd/o1agent.go
 
-COPY . /go/src/ws
+RUN ./build_o1agent.sh
 
 # make the data model based on the ric yang model
 RUN /usr/local/bin/sysrepoctl -i /go/src/ws/agent/yang/o-ran-sc-ric-xapp-desc-v1.yang
 RUN /usr/local/bin/sysrepoctl -i /go/src/ws/agent/yang/o-ran-sc-ric-ueec-config-v1.yang
+RUN /usr/local/bin/sysrepoctl -i /go/src/ws/agent/yang/o-ran-sc-ric-gnb-status-v1.yang
 
 CMD ["/bin/bash"]
 
@@ -192,19 +191,19 @@ RUN mkdir -p ${CONFIGDIR}
 COPY config/supervisord.conf ${CONFIGDIR}/supervisord.conf
     
 # libraries and binaries & config
-COPY --from=o2mediator-build /usr/local/share/ /usr/local/share/
-COPY --from=o2mediator-build /usr/local/etc/ /usr/local/etc/
-COPY --from=o2mediator-build /usr/local/bin/ /usr/local/bin/
-COPY --from=o2mediator-build /usr/local/lib/ /usr/local/lib/
+COPY --from=o1mediator-build /usr/local/share/ /usr/local/share/
+COPY --from=o1mediator-build /usr/local/etc/ /usr/local/etc/
+COPY --from=o1mediator-build /usr/local/bin/ /usr/local/bin/
+COPY --from=o1mediator-build /usr/local/lib/ /usr/local/lib/
 RUN ldconfig
 
 # copy yang models with data
-COPY --from=o2mediator-build /etc/sysrepo /etc/sysrepo
+COPY --from=o1mediator-build /etc/sysrepo /etc/sysrepo
 
-COPY --from=o2mediator-build /go/src/ws/agent/o1agent /usr/local/bin
-COPY --from=o2mediator-build /go/src/ws/manager/src/process-state.py /usr/local/bin
+COPY --from=o1mediator-build /go/src/ws/agent/o1agent /usr/local/bin
+COPY --from=o1mediator-build /go/src/ws/manager/src/process-state.py /usr/local/bin
 RUN mkdir -p /etc/o1agent
-COPY --from=o2mediator-build /go/src/ws/agent/config/* /etc/o1agent/
+COPY --from=o1mediator-build /go/src/ws/agent/config/* /etc/o1agent/
 
 # ports available outside 8080 for mediator and 9001 supervise http control interrface
 # port 830 for netconf client ssh session
diff --git a/agent/build_o1agent.sh b/agent/build_o1agent.sh
new file mode 100755 (executable)
index 0000000..5b20e41
--- /dev/null
@@ -0,0 +1,38 @@
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+#   This source code is part of the near-RT RIC (RAN Intelligent Controller)
+#   platform project (RICP).
+#
+
+
+set -e
+set -x
+
+# setup version tag
+if [ -f ../container-tag.yaml ]
+then
+    tag=$(grep "tag:" ../container-tag.yaml | awk '{print $2}')
+else
+    tag="-"
+fi
+
+hash=$(git rev-parse --short HEAD || true)
+
+export GOPATH=$HOME/go
+export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
+export CFG_FILE=config/config-file.json
+export RMR_SEED_RT=config/uta_rtg_ut.rt
+GO111MODULE=on GO_ENABLED=0 GOOS=linux
+
+# Build o1mediator
+go build -a -installsuffix cgo -ldflags "-X main.Version=$tag -X main.Hash=$hash" -o o1agent ./cmd/o1agent.go
+
+# Run o1agent UT
+go test -v -p 1 -cover -coverprofile cover.out ./pkg/nbi/ -c -o ./nbi_test && ./nbi_test
index eb5062e..14daf3a 100755 (executable)
@@ -1,17 +1,18 @@
 package main
 
 import (
+       "log"
+       "strings"
+       "time"
+       "os"
        "bytes"
-       "encoding/json"
        "flag"
        "fmt"
+       "encoding/json"
+       "io/ioutil"
        "github.com/Juniper/go-netconf/netconf"
        xj "github.com/basgys/goxml2json"
        "golang.org/x/crypto/ssh"
-       "io/ioutil"
-       "log"
-       "strings"
-       "time"
 )
 
 var (
@@ -25,11 +26,19 @@ var (
        action   = flag.String("action", "get", "Netconf command: get or edit")
        timeout  = flag.Int("timeout", 30, "Timeout")
 
+       getStateXml   = "<get><filter type=\"subtree\"><ric xmlns=\"urn:o-ran:ric:gnb-status:1.0\"></ric></filter></get>"
        getConfigXml  = "<get-config><source><%s/></source><filter type=\"subtree\"><%s/></filter></get-config>"
        editConfigXml = "<edit-config><target><%s/></target><config>%s</config></edit-config>"
 )
 
 func main() {
+       defer func() { // catch or finally
+        if err := recover(); err != nil { //catch
+            fmt.Fprintf(os.Stderr, "Something went wrong: %v\n", err)
+            os.Exit(1)
+        }
+       }()
+
        if flag.Parse(); flag.Parsed() == false {
                log.Fatal("Syntax error!")
                return
@@ -37,20 +46,22 @@ func main() {
 
        switch *action {
        case "get":
-               getConfig()
+               getConfig(getStateXml)
+       case "get-config":
+               getConfig(getConfigXml)
        case "edit":
                editConfig()
        }
 }
 
-func getConfig() {
+func getConfig(cmdXml string) {
        session := startSSHSession()
        if session == nil {
                return
        }
        defer session.Close()
 
-       cmd := netconf.RawMethod(fmt.Sprintf(getConfigXml, *source, *subtree))
+       cmd := netconf.RawMethod(fmt.Sprintf(cmdXml, *source, *subtree))
        reply, err := session.Exec(cmd)
        if err != nil {
                log.Fatal(err)
index 76d19b6..17a2685 100755 (executable)
@@ -21,19 +21,23 @@ package main
 
 import (
        "os"
-    "os/signal"
-    "syscall"
+       "os/signal"
+       "syscall"
+       "fmt"
 
-       "github.com/spf13/viper"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
-       "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/sbi"
        "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/nbi"
+       "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/sbi"
+       "github.com/spf13/viper"
 )
 
+var Version string
+var Hash string
+
 type O1Agent struct {
-       rmrReady        bool
-       nbiClient       *nbi.Nbi
-       sigChan         chan os.Signal
+       rmrReady  bool
+       nbiClient *nbi.Nbi
+       sigChan   chan os.Signal
 }
 
 func (o O1Agent) Consume(rp *xapp.RMRParams) (err error) {
@@ -53,7 +57,7 @@ func (o *O1Agent) StatusCB() bool {
 }
 
 func (o *O1Agent) Run() {
-       xapp.Logger.SetMdc("o1agent", "0.3.1")
+       xapp.Logger.SetMdc("o1agent", fmt.Sprintf("%s:%s", Version, Hash))
        xapp.SetReadyCB(func(d interface{}) { o.rmrReady = true }, true)
        xapp.AddConfigChangeListener(o.ConfigChangeHandler)
        xapp.Resource.InjectStatusCb(o.StatusCB)
@@ -67,7 +71,7 @@ func (o *O1Agent) Run() {
 func (o *O1Agent) Sighandler() {
        xapp.Logger.Info("Signal handler installed!")
 
-       <- o.sigChan
+       <-o.sigChan
        o.nbiClient.Stop()
        os.Exit(1)
 }
@@ -81,9 +85,9 @@ func NewO1Agent() *O1Agent {
        sbiClient := sbi.NewSBIClient(host, baseUrl, []string{prot}, timeout)
 
        return &O1Agent{
-               rmrReady: false,
+               rmrReady:  false,
                nbiClient: nbi.NewNbi(sbiClient),
-               sigChan: make(chan os.Signal, 1),
+               sigChan:   make(chan os.Signal, 1),
        }
 }
 
@@ -94,6 +98,6 @@ func main() {
                xapp.Logger.Error("NBI initialization failed!")
                return
        }
-       
+
        o1Agent.Run()
 }
index 7bada6d..12d2bbb 100755 (executable)
@@ -5,6 +5,11 @@
     "logger": {
         "level": 4
     },
+    "db": {
+        "host": "localhost",
+        "port": 6379,
+        "namespaces": ["sdl", "rnib"]
+    },
     "rmr": {
         "protPort": "tcp:4560",
         "maxSize": 65536,
index f322edb..81595a5 100644 (file)
@@ -2,7 +2,7 @@ module gerrit.oran-osc.org/r/ric-plt/o1mediator
 
 go 1.12
 
-replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.21
+replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.26
 
 replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.0
 
@@ -12,15 +12,16 @@ require (
        gerrit.o-ran-sc.org/r/com/golog v0.0.1
        gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.0-00010101000000-000000000000
        github.com/Juniper/go-netconf v0.1.1 // indirect
+       github.com/basgys/goxml2json v1.1.0 // indirect
        github.com/coreos/go-etcd v2.0.0+incompatible // indirect
        github.com/fsnotify/fsnotify v1.4.7
-       github.com/go-openapi/errors v0.19.2
+       github.com/go-openapi/errors v0.19.3
        github.com/go-openapi/loads v0.19.4
        github.com/go-openapi/runtime v0.19.7
        github.com/go-openapi/spec v0.19.4
-       github.com/go-openapi/strfmt v0.19.3
-       github.com/go-openapi/swag v0.19.5
-       github.com/go-openapi/validate v0.19.4
+       github.com/go-openapi/strfmt v0.19.4
+       github.com/go-openapi/swag v0.19.7
+       github.com/go-openapi/validate v0.19.6
        github.com/gorilla/mux v1.7.1
        github.com/jessevdk/go-flags v1.4.0
        github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75
index 7daaca4..8fee757 100644 (file)
@@ -13,6 +13,8 @@ gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.0/go.mod h1:y2WhrCvdLkAKdH+ySdHSOSe
 gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.19/go.mod h1:c7zYW0EOxX1wQ4p1yigO2t+RjtwYSVdEXxSA+IqFxIk=
 gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.21 h1:Ur+OXnHXlRQG9mp5B05SfS/0ZmuORwC8+SQJKuIjQNw=
 gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.21/go.mod h1:WHzMFLWFYnKZzAT76Lu8wXqcM9MQ9hHM0sxlV45icSw=
+gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.26 h1:zFsExCZVAX9vTcLEHNsYgxnKDsGREKoVaz/jwRfTTOI=
+gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.26/go.mod h1:lW3UYpVXwPiOR39t6JgNCE4kdmMSdPVelMPC/Pp9fQM=
 gerrit.oran-osc.org/r/ric-plt/sdlgo.git v0.0.1 h1:l2dl31r++3xhgCumTzwvuo0/F415eqU4aFk/uDQ4WnM=
 gerrit.oran-osc.org/r/ric-plt/sdlgo.git v0.0.1/go.mod h1:LVhkNS82IofJTBK/VYPKiYed9MG/3OFwvWC6MGSDw1w=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
@@ -25,12 +27,16 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
 github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
 github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
 github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
 github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw=
+github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -69,6 +75,8 @@ github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQH
 github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
 github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY=
 github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
+github.com/go-openapi/errors v0.19.3 h1:7MGZI1ibQDLasvAz8HuhvYk9eNJbJkCOXWsSjjMS+Zc=
+github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
 github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
 github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
 github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
@@ -78,6 +86,8 @@ github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3Hfo
 github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
 github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
 github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
+github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
 github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
 github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
 github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
@@ -102,16 +112,22 @@ github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+Z
 github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
 github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA=
 github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
+github.com/go-openapi/strfmt v0.19.4 h1:eRvaqAhpL0IL6Trh5fDsGnGhiXndzHFuA05w6sXH6/g=
+github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
 github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
 github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
 github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.7 h1:VRuXN2EnMSsZdauzdss6JBC29YotDqG59BZ+tdlIL1s=
+github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
 github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
 github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
 github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
 github.com/go-openapi/validate v0.19.4 h1:LGjO87VyXY3bIKjlYpXSFuLRG2mTeuYlZyeNwFFWpyM=
 github.com/go-openapi/validate v0.19.4/go.mod h1:BkJ0ZmXui7yB0bJXWSXgLPNTmbLVeX/3D1xn/N9mMUM=
+github.com/go-openapi/validate v0.19.6 h1:WsKw9J1WzYBVxWRYwLqEk3325RL6G0SSWksuamkk6q0=
+github.com/go-openapi/validate v0.19.6/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
 github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
 github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
 github.com/go-redis/redis v6.15.3+incompatible h1:NZ0O90AhLSvSrvLZ/S9h7D4kl1mW2PrKyxL7MyBKO2g=
@@ -162,6 +178,8 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
+github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
@@ -198,6 +216,7 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/segmentio/ksuid v1.0.2 h1:9yBfKyw4ECGTdALaF09Snw3sLJmYIX6AbPJrAy6MrDc=
 github.com/segmentio/ksuid v1.0.2/go.mod h1:BXuJDr2byAiHuQaQtSKoXh1J0YmUDurywOXgB2w+OSU=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@@ -229,6 +248,7 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE=
 github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o=
+github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
@@ -243,6 +263,8 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
 go.mongodb.org/mongo-driver v1.1.1 h1:Sq1fR+0c58RME5EoqKdjkiQAmPjmfHlZOoRI6fTUOcs=
 go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
+go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@@ -295,6 +317,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
index 9fc912e..b06e732 100755 (executable)
@@ -92,4 +92,18 @@ char * get_data_json(sr_session_ctx_t *session, const char *module_name) {
 
 sr_val_t *get_val(sr_val_t *val, size_t i) {
        return &val[i];
+}
+
+int gnb_status_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *req_xpath, uint32_t req_id, struct lyd_node **parent, void *private_data) {
+    return nbiGnbStateCB(session, (char *)module_name, (char *)xpath, (char *)req_xpath, req_id, (char **)parent);
+}
+
+void create_new_path(sr_session_ctx_t *session, char **parent, char *key, char *value) {
+    struct lyd_node **p = (struct lyd_node **)parent;
+
+    if (*parent == NULL) {
+        *p = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), key, value, 0, 0);
+    } else {
+        lyd_new_path(*p, sr_get_context(sr_session_get_connection(session)), key, value, 0, 0);
+    }
 }
\ No newline at end of file
index 514fb8a..46ee4bc 100755 (executable)
@@ -30,4 +30,8 @@ char * yang_data_sr2json(sr_session_ctx_t *session, const char *module_name, sr_
 
 char * get_data_json(sr_session_ctx_t *session, const char *module_name);
 
+int gnb_status_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *req_xpath, uint32_t req_id, struct lyd_node **parent, void *private_data);
+
+void create_new_path(sr_session_ctx_t *session, char **parent, char *key, char *value);
+
 #endif
index c148ce9..b1304ee 100755 (executable)
 
 package nbi
 
-import (       
-       "time"
+import (
+       "encoding/json"
        "errors"
        "fmt"
-       "strings"
-       "unsafe"
-       "encoding/json"
        "github.com/spf13/viper"
        "github.com/valyala/fastjson"
+       "strings"
+       "time"
+       "unsafe"
 
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
        "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/sbi"
@@ -52,7 +52,7 @@ func NewNbi(s sbi.SBIClientInterface) *Nbi {
        sbiClient = s
 
        nbiClient = &Nbi{
-               schemas:  viper.GetStringSlice("nbi.schemas"),
+               schemas:     viper.GetStringSlice("nbi.schemas"),
                cleanupChan: make(chan bool),
        }
        return nbiClient
@@ -68,7 +68,7 @@ func (n *Nbi) Start() bool {
        return true
 }
 
-func (n *Nbi) Stop() { 
+func (n *Nbi) Stop() {
        C.sr_unsubscribe(n.subscription)
        C.sr_session_stop(n.session)
        C.sr_disconnect(n.connection)
@@ -108,7 +108,7 @@ func (n *Nbi) DoSubscription(schemas []string) bool {
                        return false
                }
        }
-       return true
+       return n.SubscribeStatusData()
 }
 
 func (n *Nbi) SubscribeModule(module *C.char) bool {
@@ -120,6 +120,20 @@ func (n *Nbi) SubscribeModule(module *C.char) bool {
        return true
 }
 
+func (n *Nbi) SubscribeStatusData() bool {
+       mod := C.CString("o-ran-sc-ric-gnb-status-v1")
+       path := C.CString("/o-ran-sc-ric-gnb-status-v1:ric/nodes")
+       defer C.free(unsafe.Pointer(mod))
+       defer C.free(unsafe.Pointer(path))
+
+       rc := C.sr_oper_get_items_subscribe(n.session, mod, path, C.sr_oper_get_items_cb(C.gnb_status_cb), nil, 0, &n.subscription)
+       if C.SR_ERR_OK != rc {
+               log.Error("NBI: sr_oper_get_items_subscribe failed: %s", C.GoString(C.sr_strerror(rc)))
+               return false
+       }
+       return true
+}
+
 //export nbiModuleChangeCB
 func nbiModuleChangeCB(session *C.sr_session_ctx_t, module *C.char, xpath *C.char, event C.sr_event_t, reqId C.int) C.int {
        changedModule := C.GoString(module)
@@ -167,12 +181,12 @@ func (n *Nbi) ManageXapps(module, configJson string, oper int) error {
 
                desc := sbiClient.BuildXappDescriptor(xappName, namespace, relName, version)
                switch oper {
-                       case C.SR_OP_CREATED:
-                               return sbiClient.DeployXapp(desc)
-                       case C.SR_OP_DELETED:
-                               return sbiClient.UndeployXapp(desc)
-                       default:
-                               return errors.New(fmt.Sprintf("Operation '%d' not supported!", oper))
+               case C.SR_OP_CREATED:
+                       return sbiClient.DeployXapp(desc)
+               case C.SR_OP_DELETED:
+                       return sbiClient.UndeployXapp(desc)
+               default:
+                       return errors.New(fmt.Sprintf("Operation '%d' not supported!", oper))
                }
        }
        return nil
@@ -180,7 +194,7 @@ func (n *Nbi) ManageXapps(module, configJson string, oper int) error {
 
 func (n *Nbi) ManageConfigmaps(module, configJson string, oper int) error {
        log.Info("ManageConfig: module=%s configJson=%s", module, configJson)
-       
+
        if configJson == "" || module != "o-ran-sc-ric-ueec-config-v1" {
                return nil
        }
@@ -226,3 +240,95 @@ func (n *Nbi) ParseJsonArray(dsContent, model, top, elem string) ([]*fastjson.Va
        }
        return v.GetArray(model, top, elem), nil
 }
+
+//export nbiGnbStateCB
+func nbiGnbStateCB(session *C.sr_session_ctx_t, module *C.char, xpath *C.char, req_xpath *C.char, reqid C.uint32_t, parent **C.char) C.int {
+       log.Info("NBI: Module state data for module='%s' path='%s' rpath='%s' requested [id=%d]", C.GoString(module), C.GoString(xpath), C.GoString(req_xpath), reqid)
+
+       gnbs, err := xapp.Rnib.GetListGnbIds()
+       if err != nil || len(gnbs) == 0 {
+               log.Info("Rnib.GetListGnbIds() returned elementCount=%d err:%v", len(gnbs), err)
+               return C.SR_ERR_OK
+       }
+
+       for _, gnb := range gnbs {
+               ranName := gnb.GetInventoryName()
+               info, err := xapp.Rnib.GetNodeb(ranName)
+               if err != nil {
+                       log.Error("GetNodeb() failed for ranName=%s: %v", ranName, err)
+                       continue
+               }
+
+               prot := nbiClient.E2APProt2Str(int(info.E2ApplicationProtocol))
+               connStat := nbiClient.ConnStatus2Str(int(info.ConnectionStatus))
+               ntype := nbiClient.NodeType2Str(int(info.NodeType))
+
+               log.Info("gNB info: %s -> %s %s %s -> %s %s", ranName, prot, connStat, ntype, gnb.GetGlobalNbId().GetPlmnId(), gnb.GetGlobalNbId().GetNbId())
+
+               nbiClient.CreateNewElement(session, parent, ranName, "ran-name", ranName)
+               nbiClient.CreateNewElement(session, parent, ranName, "ip", info.Ip)
+               nbiClient.CreateNewElement(session, parent, ranName, "port", fmt.Sprintf("%d", info.Port))
+               nbiClient.CreateNewElement(session, parent, ranName, "plmn-id", gnb.GetGlobalNbId().GetPlmnId())
+               nbiClient.CreateNewElement(session, parent, ranName, "nb-id", gnb.GetGlobalNbId().GetNbId())
+               nbiClient.CreateNewElement(session, parent, ranName, "e2ap-protocol", prot)
+               nbiClient.CreateNewElement(session, parent, ranName, "connection-status", connStat)
+               nbiClient.CreateNewElement(session, parent, ranName, "node", ntype)
+       }
+       return C.SR_ERR_OK
+}
+
+func (n *Nbi) CreateNewElement(session *C.sr_session_ctx_t, parent **C.char, key, name, value string) {
+       basePath := fmt.Sprintf("/o-ran-sc-ric-gnb-status-v1:ric/nodes/node[ran-name='%s']/%s", key, name)
+       log.Info("%s -> %s", basePath, value)
+
+       cPath := C.CString(basePath)
+       defer C.free(unsafe.Pointer(cPath))
+       cValue := C.CString(value)
+       defer C.free(unsafe.Pointer(cValue))
+
+       C.create_new_path(session, parent, cPath, cValue)
+}
+
+func (n *Nbi) ConnStatus2Str(connStatus int) string {
+       switch connStatus {
+       case 0:
+               return "not-specified"
+       case 1:
+               return "connected"
+       case 2:
+               return "disconnected"
+       case 3:
+               return "setup-failed"
+       case 4:
+               return "connecting"
+       case 5:
+               return "shutting-down"
+       case 6:
+               return "shutdown"
+       }
+       return "not-specified"
+}
+
+func (n *Nbi) E2APProt2Str(prot int) string {
+       switch prot {
+       case 0:
+               return "not-specified"
+       case 1:
+               return "x2-setup-request"
+       case 2:
+               return "endc-x2-setup-request"
+       }
+       return "not-specified"
+}
+
+func (n *Nbi) NodeType2Str(ntype int) string {
+       switch ntype {
+       case 0:
+               return "not-specified"
+       case 1:
+               return "enb"
+       case 2:
+               return "gnb"
+       }
+       return "not-specified"
+}
index 8a1acd2..3812fd6 100755 (executable)
@@ -156,6 +156,31 @@ func TestErrorCases(t *testing.T) {
        assert.Equal(t, true, err != nil)
 }
 
+func TestConnStatus2Str(t *testing.T) {
+       assert.Equal(t, n.ConnStatus2Str(0), "not-specified")
+       assert.Equal(t, n.ConnStatus2Str(1), "connected")
+       assert.Equal(t, n.ConnStatus2Str(2), "disconnected")
+       assert.Equal(t, n.ConnStatus2Str(3), "setup-failed")
+       assert.Equal(t, n.ConnStatus2Str(4), "connecting")
+       assert.Equal(t, n.ConnStatus2Str(5), "shutting-down")
+       assert.Equal(t, n.ConnStatus2Str(6), "shutdown")
+       assert.Equal(t, n.ConnStatus2Str(1234), "not-specified")
+}
+
+func TestE2APProt2Str(t *testing.T) {
+       assert.Equal(t, n.E2APProt2Str(0), "not-specified")
+       assert.Equal(t, n.E2APProt2Str(1), "x2-setup-request")
+       assert.Equal(t, n.E2APProt2Str(2), "endc-x2-setup-request")
+       assert.Equal(t, n.E2APProt2Str(1111), "not-specified")
+}
+
+func TestNodeType2Str(t *testing.T) {
+       assert.Equal(t, n.NodeType2Str(0), "not-specified")
+       assert.Equal(t, n.NodeType2Str(1), "enb")
+       assert.Equal(t, n.NodeType2Str(2), "gnb")
+       assert.Equal(t, n.NodeType2Str(1111), "not-specified")
+}
+
 func TestTeardown(t *testing.T) {
        n.Stop()
 }
index 7525436..a955d54 100755 (executable)
@@ -31,7 +31,7 @@ type Nbi struct {
        schemas      []string
        connection   *C.sr_conn_ctx_t
        session      *C.sr_session_ctx_t
-  subscription *C.sr_subscription_ctx_t
-  oper          C.sr_change_oper_t
+       subscription *C.sr_subscription_ctx_t
+       oper         C.sr_change_oper_t
        cleanupChan  chan bool
 }
index 4306601..09dae0e 100755 (executable)
 package sbi
 
 import (
-       "time"
        httptransport "github.com/go-openapi/runtime/client"
        "github.com/go-openapi/strfmt"
-       
+       "time"
+
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
        apiclient "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/appmgrclient"
        apixapp "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/appmgrclient/xapp"
@@ -93,13 +93,13 @@ func (s *SBIClient) GetDeployedXapps() error {
 
 func (s *SBIClient) BuildXappConfig(name, namespace string, configData interface{}) *apimodel.XAppConfig {
        metadata := &apimodel.ConfigMetadata{
-               XappName:    &name,
+               XappName:  &name,
                Namespace: &namespace,
        }
 
        return &apimodel.XAppConfig{
                Metadata: metadata,
-               Config: configData,
+               Config:   configData,
        }
 }
 
diff --git a/agent/yang/o-ran-sc-ric-gnb-status-v1.yang b/agent/yang/o-ran-sc-ric-gnb-status-v1.yang
new file mode 100755 (executable)
index 0000000..967ed6b
--- /dev/null
@@ -0,0 +1,163 @@
+module o-ran-sc-ric-gnb-status-v1 {
+    yang-version 1;
+    namespace "urn:o-ran:ric:gnb-status:1.0";
+    prefix rxad;
+
+    organization
+        "O-RAN Software Community";
+    contact
+        "www.o-ran.org";
+    description
+        "This module defines the gNB status and other information visible to operators
+
+        Copyright 2020 the O-RAN Alliance.
+
+        Licensed under the Apache License, Version 2.0 (the 'License');
+        you may not use this file except in compliance with the License.
+        You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing, software
+        distributed under the License is distributed on an 'AS IS' BASIS,
+        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        See the License for the specific language governing permissions and
+        limitations under the License.";
+
+    revision 2020-01-29 {
+        description
+            "initial revision";
+        reference
+            "O-RAN-OAM-Interface-Specification (O1)";
+    }
+    
+    typedef e2ap-protocol-type {
+        type enumeration {
+            enum not-specified {
+                description
+                    "None";
+            }
+            enum x2-setup-request {
+                description
+                    "X2 setup request";
+            }
+            enum endc-x2-setup-request {
+                description
+                    "ENDC X2 setup request";
+            }
+        }
+        description
+            "The E2AP protocol setup types";
+    }
+
+    typedef connection-status-type {
+        type enumeration {
+            enum not-specified {
+                description
+                    "None";
+            }
+            enum connected {
+                description
+                    "Connected";
+            }
+            enum connecting {
+                description
+                    "Connecting";
+            }
+            enum disconnected {
+                description
+                    "Disconnected";
+            }
+            enum setup-failed {
+                description
+                    "Setup failed";
+            }
+            enum shutting-down {
+                description
+                    "Shutting down";
+            }
+            enum shutdown {
+                description
+                    "Shutdown";
+            }
+        }
+        description
+            "The connection status of gNB";
+    }
+
+    typedef node-type {
+        type enumeration {
+            enum not-specified {
+                description
+                    "None";
+            }
+            enum enb {
+                description
+                    "eNB";
+            }
+            enum gnb {
+                description
+                    "gNB";
+            }
+        }
+        description
+            "The connection status of gNB";
+    }
+
+    grouping nodeb-info {
+        leaf ran-name {
+            type string;
+            description
+                "The unique RAN name";
+        }
+        leaf ip {
+            type string;
+            description
+                "The IP address of the node";
+        }
+        leaf port {
+            type uint32;
+            description
+                "The port of the node";
+        }
+        leaf e2ap-protocol {
+            type e2ap-protocol-type;
+            description
+                "Specifies the protocol type of the connection";
+        }
+        leaf connection-status {
+            type connection-status-type;
+            description
+                "Specifies the connection type of the node";
+        }
+        leaf plmn-id {
+            type string;
+            description
+                "PLMN id";
+        }
+        leaf nb-id {
+            type string;
+            description
+                "eNB id";
+        }
+        leaf node {
+            type node-type;
+            description
+                "The type of the node: eNB or gNB";
+        }
+    }
+    
+    container ric {
+        container nodes {
+            config false;
+            list node {
+                key "ran-name";
+                uses nodeb-info;
+                description
+                    "The list of the gNBs currently discovered by RIC";
+            }
+            description
+                "State data container of the nodes";
+        }
+    }
+}
index b9299ce..db88a6c 100644 (file)
@@ -2,4 +2,4 @@
 # By default this file is in the docker build directory,
 # but the location can configured in the JJB template.
 ---
-tag: 0.3.1
+tag: 0.3.2