blob: b0ebc1f2e2781b4b8c28e2ebb271500af955f46e [file] [log] [blame]
Elia Battistonac8d23f2022-03-14 17:54:56 +01001/*
2* Copyright 2022-present Open Networking Foundation
3
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7
8* http://www.apache.org/licenses/LICENSE-2.0
9
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15 */
16
17package sysrepo
18
19//#cgo CFLAGS: -I/usr/include
20//#cgo LDFLAGS: -lsysrepo -Wl,--allow-multiple-definition
21//#include "plugin.c"
22import "C"
23import (
24 "context"
25 "fmt"
26
27 "github.com/opencord/voltha-lib-go/v7/pkg/log"
28)
29
30const (
31 BASE_YANG_MODEL = "bbf-device-aggregation"
32 DEVICES_YANG_MODEL = "/" + BASE_YANG_MODEL + ":devices"
33)
34
35type SysrepoPlugin struct {
36 connection *C.sr_conn_ctx_t
37 session *C.sr_session_ctx_t
38 subscription *C.sr_subscription_ctx_t
39}
40
41func errorMsg(code C.int) string {
42 return C.GoString(C.sr_strerror(code))
43}
44
45//createPluginState populates a SysrepoPlugin struct by establishing
46//a connection and a session
47func (p *SysrepoPlugin) createSession(ctx context.Context) error {
48
49 var errCode C.int
50
51 //Populates connection
52 errCode = C.sr_connect(C.SR_CONN_DEFAULT, &p.connection)
53 if errCode != C.SR_ERR_OK {
54 err := fmt.Errorf("sysrepo-connect-error")
55 logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
56 return err
57 }
58
59 //Populates session
60 errCode = C.sr_session_start(p.connection, C.SR_DS_RUNNING, &p.session)
61 if errCode != C.SR_ERR_OK {
62 err := fmt.Errorf("sysrepo-session-error")
63 logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
64
65 _ = p.Stop(ctx)
66
67 return err
68 }
69
70 return nil
71}
72
73//export get_data_cb
74func get_data_cb() {
75 //This function is a callback for the retrieval of data from sysrepo
76 //The "export" comment instructs CGO to create a C function for it
77
78 //As a placeholder, it just reports that a request to get data
79 //has been received from the netconf server
80
81 //TODO: get actual information
82 ctx := context.Background()
83 logger.Info(ctx, ">>>>>>>RECEIVED REQUEST FROM SYSREPO<<<<<<<")
84}
85
86func StartNewPlugin(ctx context.Context) (*SysrepoPlugin, error) {
87 plugin := &SysrepoPlugin{}
88
89 //Open a session to sysrepo
90 err := plugin.createSession(ctx)
91 if err != nil {
92 return nil, err
93 }
94
95 //TODO: could be useful to set it according to the adapter log level
96 C.sr_log_stderr(C.SR_LL_WRN)
97
98 //Set callbacks for events
99
100 //Subscribe with a callback to the request of data on a certain path
101 errCode := C.sr_oper_get_items_subscribe(
102 plugin.session,
103 C.CString(BASE_YANG_MODEL),
104 C.CString(DEVICES_YANG_MODEL+"/*"),
105 C.function(C.get_data_cb_wrapper),
106 C.NULL,
107 C.SR_SUBSCR_CTX_REUSE,
108 &plugin.subscription,
109 )
110 if errCode != C.SR_ERR_OK {
111 err := fmt.Errorf("sysrepo-failed-subscription-to-get-events")
112 logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
113 return nil, err
114 }
115
116 logger.Debug(ctx, "sysrepo-plugin-started")
117
118 return plugin, nil
119}
120
121func (p *SysrepoPlugin) Stop(ctx context.Context) error {
122 var errCode C.int
123
124 //Frees subscription
125 if p.subscription != nil {
126 errCode = C.sr_unsubscribe(p.subscription)
127 if errCode != C.SR_ERR_OK {
128 err := fmt.Errorf("failed-to-close-sysrepo-subscription")
129 logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
130 return err
131 }
132 p.subscription = nil
133 }
134
135 //Frees session
136 if p.session != nil {
137 errCode = C.sr_session_stop(p.session)
138 if errCode != C.SR_ERR_OK {
139 err := fmt.Errorf("failed-to-close-sysrepo-session")
140 logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
141 return err
142 }
143 p.session = nil
144 }
145
146 //Frees connection
147 if p.connection != nil {
148 errCode = C.sr_disconnect(p.connection)
149 if errCode != C.SR_ERR_OK {
150 err := fmt.Errorf("failed-to-close-sysrepo-connection")
151 logger.Errorw(ctx, err.Error(), log.Fields{"errCode": errCode, "errMsg": errorMsg(errCode)})
152 return err
153 }
154 p.connection = nil
155 }
156
157 logger.Debug(ctx, "sysrepo-plugin-stopped")
158
159 return nil
160}