blob: dc8c5e0493c0adb708a6d76411c1d386223cf24a [file] [log] [blame]
kalnagy45114752019-06-18 14:40:39 +02001/*
2==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17==================================================================================
18*/
19
20package control
21
kalnagy45114752019-06-18 14:40:39 +020022import "C"
23
kalnagy45114752019-06-18 14:40:39 +020024import (
Peter Szilagyifbc56f92019-07-23 19:29:46 +000025 "errors"
kalnagy93cc3e22019-09-19 11:29:29 +020026 rtmgrclient "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client"
27 rtmgrhandle "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client/handle"
kalnagy1455c852019-10-21 13:06:23 +020028 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
29 httptransport "github.com/go-openapi/runtime/client"
30 "github.com/go-openapi/strfmt"
31 "github.com/spf13/viper"
Peter Szilagyifbc56f92019-07-23 19:29:46 +000032 "math/rand"
33 "strconv"
34 "time"
kalnagy45114752019-06-18 14:40:39 +020035)
36
37type Control struct {
kalnagy93cc3e22019-09-19 11:29:29 +020038 e2ap *E2ap
39 registry *Registry
40 rtmgrClient *RtmgrClient
41 tracker *Tracker
kalnagy1455c852019-10-21 13:06:23 +020042 rcChan chan *xapp.RMRParams
kalnagy93cc3e22019-09-19 11:29:29 +020043}
44
45type RMRMeid struct {
46 PlmnID string
47 EnbID string
48}
49
kalnagy1455c852019-10-21 13:06:23 +020050var seedSN uint16
51var SubscriptionReqChan = make(chan SubRouteInfo, 10)
kalnagy93cc3e22019-09-19 11:29:29 +020052
53const (
54 CREATE Action = 0
kalnagy1455c852019-10-21 13:06:23 +020055 MERGE Action = 1
kalnagy93cc3e22019-09-19 11:29:29 +020056 DELETE Action = 3
57)
Peter Szilagyifbc56f92019-07-23 19:29:46 +000058
59func init() {
60 viper.AutomaticEnv()
61 viper.SetEnvPrefix("submgr")
62 viper.AllowEmptyEnv(true)
kalnagy1455c852019-10-21 13:06:23 +020063 seedSN = uint16(viper.GetInt("seed_sn"))
64 if seedSN == 0 {
Peter Szilagyifbc56f92019-07-23 19:29:46 +000065 rand.Seed(time.Now().UnixNano())
kalnagy1455c852019-10-21 13:06:23 +020066 seedSN = uint16(rand.Intn(65535))
Peter Szilagyifbc56f92019-07-23 19:29:46 +000067 }
kalnagy1455c852019-10-21 13:06:23 +020068 if seedSN > 65535 {
69 seedSN = 0
Peter Szilagyifbc56f92019-07-23 19:29:46 +000070 }
kalnagy1455c852019-10-21 13:06:23 +020071 xapp.Logger.Info("SUBMGR: Initial Sequence Number: %v", seedSN)
kalnagy45114752019-06-18 14:40:39 +020072}
73
74func NewControl() Control {
Peter Szilagyifbc56f92019-07-23 19:29:46 +000075 registry := new(Registry)
kalnagy1455c852019-10-21 13:06:23 +020076 registry.Initialize(seedSN)
kalnagy93cc3e22019-09-19 11:29:29 +020077
Balint Uvegese9608cd2019-09-20 18:00:32 +000078 tracker := new(Tracker)
79 tracker.Init()
80
kalnagy1455c852019-10-21 13:06:23 +020081 transport := httptransport.New(viper.GetString("rtmgr.HostAddr")+":"+viper.GetString("rtmgr.port"), viper.GetString("rtmgr.baseUrl"), []string{"http"})
kalnagy93cc3e22019-09-19 11:29:29 +020082 client := rtmgrclient.New(transport, strfmt.Default)
83 handle := rtmgrhandle.NewProvideXappSubscriptionHandleParamsWithTimeout(10 * time.Second)
kalnagy1455c852019-10-21 13:06:23 +020084 deleteHandle := rtmgrhandle.NewDeleteXappSubscriptionHandleParamsWithTimeout(10 * time.Second)
85 rtmgrClient := RtmgrClient{client, handle, deleteHandle}
kalnagy93cc3e22019-09-19 11:29:29 +020086
Balint Uvegescd3881b2019-10-02 15:01:43 +000087 return Control{new(E2ap), registry, &rtmgrClient, tracker, make(chan *xapp.RMRParams)}
kalnagy45114752019-06-18 14:40:39 +020088}
89
90func (c *Control) Run() {
Balint Uvegescd3881b2019-10-02 15:01:43 +000091 go c.controlLoop()
Peter Szilagyifbc56f92019-07-23 19:29:46 +000092 xapp.Run(c)
kalnagy45114752019-06-18 14:40:39 +020093}
94
kalnagy93cc3e22019-09-19 11:29:29 +020095func (c *Control) Consume(rp *xapp.RMRParams) (err error) {
kalnagy1455c852019-10-21 13:06:23 +020096 c.rcChan <- rp
Peter Szilagyifbc56f92019-07-23 19:29:46 +000097 return
kalnagy45114752019-06-18 14:40:39 +020098}
99
kalnagy93cc3e22019-09-19 11:29:29 +0200100func (c *Control) rmrSend(params *xapp.RMRParams) (err error) {
101 if !xapp.Rmr.Send(params, false) {
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000102 err = errors.New("rmr.Send() failed")
103 }
104 return
kalnagy45114752019-06-18 14:40:39 +0200105}
106
kalnagye0018682019-09-26 16:28:25 +0200107func (c *Control) rmrReplyToSender(params *xapp.RMRParams) (err error) {
108 if !xapp.Rmr.Send(params, true) {
109 err = errors.New("rmr.Send() failed")
110 }
111 return
112}
113
Balint Uvegescd3881b2019-10-02 15:01:43 +0000114func (c *Control) controlLoop() {
115 for {
kalnagy1455c852019-10-21 13:06:23 +0200116 msg := <-c.rcChan
Balint Uvegescd3881b2019-10-02 15:01:43 +0000117 switch msg.Mtype {
kalnagy1455c852019-10-21 13:06:23 +0200118 case xapp.RICMessageTypes["RIC_SUB_REQ"]:
119 c.handleSubscriptionRequest(msg)
120 case xapp.RICMessageTypes["RIC_SUB_RESP"]:
121 c.handleSubscriptionResponse(msg)
122 case xapp.RICMessageTypes["RIC_SUB_DEL_REQ"]:
123 c.handleSubscriptionDeleteRequest(msg)
124 case xapp.RICMessageTypes["RIC_SUB_DEL_RESP"]:
125 c.handleSubscriptionDeleteResponse(msg)
126 default:
127 err := errors.New("Message Type " + strconv.Itoa(msg.Mtype) + " is discarded")
128 xapp.Logger.Error("Unknown message type: %v", err)
Balint Uvegescd3881b2019-10-02 15:01:43 +0000129 }
130 }
131}
132
kalnagy93cc3e22019-09-19 11:29:29 +0200133func (c *Control) handleSubscriptionRequest(params *xapp.RMRParams) (err error) {
kalnagy1455c852019-10-21 13:06:23 +0200134 payloadSeqNum, err := c.e2ap.GetSubscriptionRequestSequenceNumber(params.Payload)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000135 if err != nil {
136 err = errors.New("Unable to get Subscription Sequence Number from Payload due to: " + err.Error())
137 return
138 }
kalnagy1455c852019-10-21 13:06:23 +0200139 xapp.Logger.Info("Subscription Request Received. RMR SUBSCRIPTION_ID: %v | PAYLOAD SEQUENCE_NUMBER: %v", params.SubId, payloadSeqNum)
kalnagy93cc3e22019-09-19 11:29:29 +0200140
141 /* Reserve a sequence number and set it in the payload */
kalnagy1455c852019-10-21 13:06:23 +0200142 newSubId := c.registry.ReserveSequenceNumber()
kalnagy93cc3e22019-09-19 11:29:29 +0200143
kalnagy1455c852019-10-21 13:06:23 +0200144 _, err = c.e2ap.SetSubscriptionRequestSequenceNumber(params.Payload, newSubId)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000145 if err != nil {
146 err = errors.New("Unable to set Subscription Sequence Number in Payload due to: " + err.Error())
147 return
148 }
kalnagy93cc3e22019-09-19 11:29:29 +0200149
kalnagy1455c852019-10-21 13:06:23 +0200150 srcAddr, srcPort, err := c.rtmgrClient.SplitSource(params.Src)
kalnagy93cc3e22019-09-19 11:29:29 +0200151 if err != nil {
152 xapp.Logger.Error("Failed to update routing-manager about the subscription request with reason: %s", err)
153 return
154 }
155
156 /* Create transatcion records for every subscription request */
kalnagy1455c852019-10-21 13:06:23 +0200157 xactKey := TransactionKey{newSubId, CREATE}
158 xactValue := Transaction{*srcAddr, *srcPort, params}
159 err = c.tracker.TrackTransaction(xactKey, xactValue)
kalnagy93cc3e22019-09-19 11:29:29 +0200160 if err != nil {
kalnagy1455c852019-10-21 13:06:23 +0200161 xapp.Logger.Error("Failed to create a Subscription Request transaction record due to %v", err)
kalnagy93cc3e22019-09-19 11:29:29 +0200162 return
163 }
164
165 /* Update routing manager about the new subscription*/
kalnagy1455c852019-10-21 13:06:23 +0200166 subRouteAction := SubRouteInfo{CREATE, *srcAddr, *srcPort, newSubId}
kalnagy93cc3e22019-09-19 11:29:29 +0200167 go c.rtmgrClient.SubscriptionRequestUpdate()
kalnagy1455c852019-10-21 13:06:23 +0200168 SubscriptionReqChan <- subRouteAction
kalnagy93cc3e22019-09-19 11:29:29 +0200169
170 // Setting new subscription ID in the RMR header
kalnagy1455c852019-10-21 13:06:23 +0200171 params.SubId = int(newSubId)
kalnagy93cc3e22019-09-19 11:29:29 +0200172
kalnagy1455c852019-10-21 13:06:23 +0200173 xapp.Logger.Info("Generated ID: %v. Forwarding to E2 Termination...", int(newSubId))
kalnagy93cc3e22019-09-19 11:29:29 +0200174 c.rmrSend(params)
kalnagy1455c852019-10-21 13:06:23 +0200175 xapp.Logger.Debug("--- Debugging transaction table = %v", c.tracker.transactionTable)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000176 return
kalnagy45114752019-06-18 14:40:39 +0200177}
178
kalnagy93cc3e22019-09-19 11:29:29 +0200179func (c *Control) handleSubscriptionResponse(params *xapp.RMRParams) (err error) {
kalnagy1455c852019-10-21 13:06:23 +0200180 payloadSeqNum, err := c.e2ap.GetSubscriptionResponseSequenceNumber(params.Payload)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000181 if err != nil {
182 err = errors.New("Unable to get Subscription Sequence Number from Payload due to: " + err.Error())
183 return
184 }
kalnagy1455c852019-10-21 13:06:23 +0200185 xapp.Logger.Info("Subscription Response Received. RMR SUBSCRIPTION_ID: %v | PAYLOAD SEQUENCE_NUMBER: %v", params.SubId, payloadSeqNum)
186 if !c.registry.IsValidSequenceNumber(payloadSeqNum) {
187 err = errors.New("Unknown Subscription ID: " + strconv.Itoa(int(payloadSeqNum)) + " in Subscritpion Response. Message discarded.")
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000188 return
189 }
kalnagy1455c852019-10-21 13:06:23 +0200190 c.registry.setSubscriptionToConfirmed(payloadSeqNum)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000191 xapp.Logger.Info("Subscription Response Registered. Forwarding to Requestor...")
kalnagy1455c852019-10-21 13:06:23 +0200192 transaction, err := c.tracker.completeTransaction(payloadSeqNum, CREATE)
kalnagye0018682019-09-26 16:28:25 +0200193 if err != nil {
kalnagy1455c852019-10-21 13:06:23 +0200194 xapp.Logger.Error("Failed to delete a Subscription Request transaction record due to %v", err)
kalnagye0018682019-09-26 16:28:25 +0200195 return
196 }
kalnagy1455c852019-10-21 13:06:23 +0200197 xapp.Logger.Info("Subscription ID: %v, from address: %v:%v. Forwarding to E2 Termination...", int(payloadSeqNum), transaction.XappInstanceAddress, transaction.XappPort)
198 params.Mbuf = transaction.OrigParams.Mbuf
kalnagye0018682019-09-26 16:28:25 +0200199 c.rmrReplyToSender(params)
kalnagy93cc3e22019-09-19 11:29:29 +0200200 return
201}
202
203func (act Action) String() string {
204 actions := [...]string{
205 "CREATE",
206 "MERGE",
207 "DELETE",
208 }
209
210 if act < CREATE || act > DELETE {
211 return "Unknown"
212 }
213 return actions[act]
214}
215
216func (act Action) valid() bool {
217 switch act {
218 case CREATE, MERGE, DELETE:
219 return true
220 default:
221 return false
222 }
223}
224
225func (c *Control) handleSubscriptionDeleteRequest(params *xapp.RMRParams) (err error) {
kalnagy1455c852019-10-21 13:06:23 +0200226 payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteRequestSequenceNumber(params.Payload)
kalnagy93cc3e22019-09-19 11:29:29 +0200227 if err != nil {
228 err = errors.New("Unable to get Subscription Sequence Number from Payload due to: " + err.Error())
229 return
230 }
kalnagy1455c852019-10-21 13:06:23 +0200231 xapp.Logger.Info("Subscription Delete Request Received. RMR SUBSCRIPTION_ID: %v | PAYLOAD SEQUENCE_NUMBER: %v", params.SubId, payloadSeqNum)
232 if c.registry.IsValidSequenceNumber(payloadSeqNum) {
233 c.registry.deleteSubscription(payloadSeqNum)
234 trackErr := c.trackDeleteTransaction(params, payloadSeqNum)
kalnagye0018682019-09-26 16:28:25 +0200235 if trackErr != nil {
kalnagy1455c852019-10-21 13:06:23 +0200236 xapp.Logger.Error("Failed to create a Subscription Delete Request transaction record due to %v", trackErr)
kalnagye0018682019-09-26 16:28:25 +0200237 return trackErr
238 }
kalnagy93cc3e22019-09-19 11:29:29 +0200239 }
kalnagy1455c852019-10-21 13:06:23 +0200240 xapp.Logger.Info("Subscription ID: %v. Forwarding to E2 Termination...", int(payloadSeqNum))
kalnagy93cc3e22019-09-19 11:29:29 +0200241 c.rmrSend(params)
Peter Szilagyifbc56f92019-07-23 19:29:46 +0000242 return
243}
kalnagye0018682019-09-26 16:28:25 +0200244
kalnagy1455c852019-10-21 13:06:23 +0200245func (c *Control) trackDeleteTransaction(params *xapp.RMRParams, payloadSeqNum uint16) (err error) {
246 srcAddr, srcPort, err := c.rtmgrClient.SplitSource(params.Src)
247 if err != nil {
248 xapp.Logger.Error("Failed to update routing-manager about the subscription delete request with reason: %s", err)
249 }
250 xactKey := TransactionKey{payloadSeqNum, DELETE}
251 xactValue := Transaction{*srcAddr, *srcPort, params}
252 err = c.tracker.TrackTransaction(xactKey, xactValue)
kalnagye0018682019-09-26 16:28:25 +0200253 return
254}
255
256func (c *Control) handleSubscriptionDeleteResponse(params *xapp.RMRParams) (err error) {
kalnagy1455c852019-10-21 13:06:23 +0200257 payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteResponseSequenceNumber(params.Payload)
kalnagye0018682019-09-26 16:28:25 +0200258 if err != nil {
259 err = errors.New("Unable to get Subscription Sequence Number from Payload due to: " + err.Error())
260 return
261 }
kalnagy1455c852019-10-21 13:06:23 +0200262 var transaction, _ = c.tracker.RetriveTransaction(payloadSeqNum, DELETE)
263 subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, payloadSeqNum}
kalnagye0018682019-09-26 16:28:25 +0200264 go c.rtmgrClient.SubscriptionRequestUpdate()
kalnagy1455c852019-10-21 13:06:23 +0200265 SubscriptionReqChan <- subRouteAction
kalnagye0018682019-09-26 16:28:25 +0200266
kalnagy1455c852019-10-21 13:06:23 +0200267 xapp.Logger.Info("Subscription Delete Response Received. RMR SUBSCRIPTION_ID: %v | PAYLOAD SEQUENCE_NUMBER: %v", params.SubId, payloadSeqNum)
268 if c.registry.releaseSequenceNumber(payloadSeqNum) {
269 transaction, err = c.tracker.completeTransaction(payloadSeqNum, DELETE)
kalnagye0018682019-09-26 16:28:25 +0200270 if err != nil {
kalnagy1455c852019-10-21 13:06:23 +0200271 xapp.Logger.Error("Failed to delete a Subscription Delete Request transaction record due to %v", err)
kalnagye0018682019-09-26 16:28:25 +0200272 return
273 }
kalnagy1455c852019-10-21 13:06:23 +0200274 xapp.Logger.Info("Subscription ID: %v, from address: %v:%v. Forwarding to E2 Termination...", int(payloadSeqNum), transaction.XappInstanceAddress, transaction.XappPort)
kalnagye0018682019-09-26 16:28:25 +0200275 //params.Src = xAddress + ":" + strconv.Itoa(int(xPort))
kalnagy1455c852019-10-21 13:06:23 +0200276 params.Mbuf = transaction.OrigParams.Mbuf
kalnagye0018682019-09-26 16:28:25 +0200277 c.rmrReplyToSender(params)
278 }
279 return
280}