From ce7bdb1a54c10071a9aa0310a8e42411dcab9226 Mon Sep 17 00:00:00 2001 From: rh362j Date: Wed, 28 Aug 2019 15:13:48 +0300 Subject: [PATCH] [RICPLT-1852] Supports E2T Initialize + ExecuteSetup + prepare setup request on init Change-Id: I5baf070b78f1ed38a92b188b6b8a789d5cb151dd Signed-off-by: rh362j --- E2Manager/asn1codec/src/x2setup_request_wrapper.c | 2 +- E2Manager/container-tag.yaml | 2 +- .../endc_x2_setup_request_test.go} | 37 ++-- .../x2_setup_request_test.go} | 24 +-- E2Manager/e2pdus/x2_setup_requests.go | 80 ++++++++ .../handlers/e2_term_init_notification_handler.go | 66 +++++++ E2Manager/handlers/endc_setup_request_handler.go | 20 +- .../endc_setup_response_notification_handler.go | 1 + .../handlers/endc_x2apSetupRequest_asn1_packer.go | 54 ------ E2Manager/handlers/setup_request_handler.go | 41 ++-- E2Manager/handlers/setup_request_handler_test.go | 9 +- E2Manager/handlers/x2_reset_request_handler.go | 4 +- .../handlers/x2_reset_request_handler_test.go | 2 +- E2Manager/handlers/x2apSetupRequest_asn1_packer.go | 54 ------ .../x2apSetup_response_notification_handler.go | 1 + E2Manager/managers/ran_reconnection_manager.go | 2 +- E2Manager/managers/ran_setup_manager.go | 81 +++++++- E2Manager/managers/ran_setup_manager_test.go | 213 +++++++++++++++++++++ .../notification_handler_provider.go | 1 + .../notification_handler_provider_test.go | 1 + E2Manager/rmrCgo/rmrCgoTypes.go | 1 + E2Manager/rnibBuilders/node_info_builder.go | 3 +- E2Manager/rnibBuilders/node_info_builder_test.go | 3 +- router.txt | 2 +- 24 files changed, 518 insertions(+), 186 deletions(-) rename E2Manager/{handlers/endc_x2apSetupRequest_asn1_packer_test.go => e2pdus/endc_x2_setup_request_test.go} (64%) rename E2Manager/{handlers/x2apSetupRequest_asn1_packer_test.go => e2pdus/x2_setup_request_test.go} (77%) create mode 100644 E2Manager/e2pdus/x2_setup_requests.go create mode 100644 E2Manager/handlers/e2_term_init_notification_handler.go delete mode 100644 E2Manager/handlers/endc_x2apSetupRequest_asn1_packer.go delete mode 100644 E2Manager/handlers/x2apSetupRequest_asn1_packer.go create mode 100644 E2Manager/managers/ran_setup_manager_test.go diff --git a/E2Manager/asn1codec/src/x2setup_request_wrapper.c b/E2Manager/asn1codec/src/x2setup_request_wrapper.c index a159f98..2eebbb1 100644 --- a/E2Manager/asn1codec/src/x2setup_request_wrapper.c +++ b/E2Manager/asn1codec/src/x2setup_request_wrapper.c @@ -211,7 +211,7 @@ static void assignServedCell_Information( assert(broadcastPLMN_Identity != 0); ASN_SEQUENCE_ADD(&servedCell_Information->broadcastPLMNs, broadcastPLMN_Identity); - assignPLMN_Identity(broadcastPLMN_Identity,ric_flag); + assignPLMN_Identity(broadcastPLMN_Identity, pLMN_Identity); //ric_flag: disabled because a real eNB rejects the message servedCell_Information->eUTRA_Mode_Info.present= EUTRA_Mode_Info_PR_fDD; servedCell_Information->eUTRA_Mode_Info.choice.fDD = calloc(1, sizeof(FDD_Info_t)); diff --git a/E2Manager/container-tag.yaml b/E2Manager/container-tag.yaml index daa3e14..4add8c7 100644 --- a/E2Manager/container-tag.yaml +++ b/E2Manager/container-tag.yaml @@ -1,4 +1,4 @@ # The Jenkins job requires a tag to build the Docker image. # Global-JJB script assumes this file is in the repo root. --- -tag: 1.0.4 +tag: 2.0.4 diff --git a/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer_test.go b/E2Manager/e2pdus/endc_x2_setup_request_test.go similarity index 64% rename from E2Manager/handlers/endc_x2apSetupRequest_asn1_packer_test.go rename to E2Manager/e2pdus/endc_x2_setup_request_test.go index 5c88773..e288c18 100644 --- a/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer_test.go +++ b/E2Manager/e2pdus/endc_x2_setup_request_test.go @@ -15,10 +15,9 @@ * limitations under the License. * *******************************************************************************/ -package handlers +package e2pdus import ( - "e2mgr/logger" "fmt" "strings" "testing" @@ -29,8 +28,8 @@ import ( * Verify the packed representation matches the want value. */ func TestPackEndcX2apSetupRequest(t *testing.T) { - logger, _ := logger.InitLogger(logger.InfoLevel) pLMNId := []byte{0xbb, 0xbc, 0xcc} + ricFlag := []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/ var testCases = []struct { eNBId []byte @@ -38,26 +37,26 @@ func TestPackEndcX2apSetupRequest(t *testing.T) { packedPdu string }{ { - eNBId :[]byte{0xab, 0xcd, 0x2}, /*00000010 -> 10000000*/ - eNBIdBitqty: shortMacro_eNB_ID, - packedPdu: "0024003200000100f4002b0000020015000900bbbccc8003abcd8000fa0017000001f700bbbcccabcd80000000bbbccc000000000001", + eNBId : []byte{0xab, 0xcd, 0x2}, /*00000010 -> 10000000*/ + eNBIdBitqty: ShortMacro_eNB_ID, + packedPdu: "0024003200000100f4002b0000020015000900bbbccc8003abcd8000fa0017000001f700bbbcccabcd80000000bbbccc000000000001", }, { - eNBId :[]byte{0xab, 0xcd, 0xe}, - eNBIdBitqty: macro_eNB_ID, - packedPdu: "0024003100000100f4002a0000020015000800bbbccc00abcde000fa0017000001f700bbbcccabcde0000000bbbccc000000000001", + eNBId : []byte{0xab, 0xcd, 0xe}, + eNBIdBitqty: Macro_eNB_ID, + packedPdu: "0024003100000100f4002a0000020015000800bbbccc00abcde000fa0017000001f700bbbcccabcde0000000bbbccc000000000001", }, { - eNBId :[]byte{0xab, 0xcd, 0x7}, /*00000111 -> 00111000*/ - eNBIdBitqty: longMacro_eNB_ID, + eNBId : []byte{0xab, 0xcd, 0x7}, /*00000111 -> 00111000*/ + eNBIdBitqty: LongMacro_eNB_ID, //packedPdu: "0024003200000100f4002b0000020015000900bbbccc8103abcd3800fa0017000001f700bbbcccabcd38000000bbbccc000000000001", packedPdu: "0024003200000100f4002b0000020015000900bbbcccc003abcd3800fa0017000001f700bbbcccabcd38000000bbbccc000000000001", }, { - eNBId :[]byte{0xab, 0xcd, 0xef, 0x8}, - eNBIdBitqty: home_eNB_ID, - packedPdu: "0024003200000100f4002b0000020015000900bbbccc40abcdef8000fa0017000001f700bbbcccabcdef800000bbbccc000000000001", + eNBId : []byte{0xab, 0xcd, 0xef, 0x8}, + eNBIdBitqty: Home_eNB_ID, + packedPdu: "0024003200000100f4002b0000020015000900bbbccc40abcdef8000fa0017000001f700bbbcccabcdef800000bbbccc000000000001", }, @@ -66,7 +65,7 @@ func TestPackEndcX2apSetupRequest(t *testing.T) { for _, tc := range testCases { t.Run(tc.packedPdu, func(t *testing.T) { - payload, err := packEndcX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId[:], tc.eNBId[:], tc.eNBIdBitqty) + payload, _, err := PreparePackedEndcX2SetupRequest(MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, tc.eNBId, tc.eNBIdBitqty, ricFlag) if err != nil { t.Errorf("want: success, got: pack failed. Error: %v\n", err) } else { @@ -87,11 +86,13 @@ func TestPackEndcX2apSetupRequest(t *testing.T) { /*Packing error*/ func TestPackEndcX2apSetupRequestPackError(t *testing.T) { - logger, _ := logger.InitLogger(logger.InfoLevel) - + pLMNId := []byte{0xbb, 0xbc, 0xcc} + ricFlag := []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/ + eNBId := []byte{0xab, 0xcd, 0x2} + eNBIdBitqty := uint(Macro_eNB_ID) wantError := "packing error: #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big:53" - _, err := packEndcX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, 40 /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId[:], eNBId[:],eNBIdBitqty) + _, _, err :=PreparePackedEndcX2SetupRequest(40 /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, eNBId, eNBIdBitqty, ricFlag) if err != nil { if 0 != strings.Compare(fmt.Sprintf("%s", err), wantError) { t.Errorf("want failure: %s, got: %s", wantError, err) diff --git a/E2Manager/handlers/x2apSetupRequest_asn1_packer_test.go b/E2Manager/e2pdus/x2_setup_request_test.go similarity index 77% rename from E2Manager/handlers/x2apSetupRequest_asn1_packer_test.go rename to E2Manager/e2pdus/x2_setup_request_test.go index 30967ad..42fcff8 100644 --- a/E2Manager/handlers/x2apSetupRequest_asn1_packer_test.go +++ b/E2Manager/e2pdus/x2_setup_request_test.go @@ -15,10 +15,9 @@ * limitations under the License. * *******************************************************************************/ -package handlers +package e2pdus import ( - "e2mgr/logger" "fmt" "strings" "testing" @@ -29,8 +28,9 @@ import ( * Verify the packed representation matches the want value. */ func TestPackX2apSetupRequest(t *testing.T) { - logger, _ := logger.InitLogger(logger.InfoLevel) pLMNId := []byte{0xbb, 0xbc, 0xcc} + ricFlag := []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/ + var testCases = []struct { eNBId []byte eNBIdBitqty uint @@ -38,24 +38,24 @@ func TestPackX2apSetupRequest(t *testing.T) { }{ { eNBId: []byte{0xab, 0xcd, 0x2}, /*00000010 -> 10000000*/ - eNBIdBitqty: shortMacro_eNB_ID, + eNBIdBitqty: ShortMacro_eNB_ID, packedPdu: "0006002b0000020015000900bbbccc8003abcd8000140017000001f700bbbcccabcd80000000bbbccc000000000001", }, { eNBId: []byte{0xab, 0xcd, 0xe}, - eNBIdBitqty: macro_eNB_ID, - packedPdu: "0006002a0000020015000800bbbccc00abcde000140017000001f700bbbcccabcde0000000bbbccc000000000001", + eNBIdBitqty: Macro_eNB_ID, + packedPdu: "0006002a0000020015000800bbbccc00abcde000140017000001f700bbbcccabcde0000000bbbccc000000000001", }, { eNBId: []byte{0xab, 0xcd, 0x7}, /*00000111 -> 00111000*/ - eNBIdBitqty: longMacro_eNB_ID, + eNBIdBitqty: LongMacro_eNB_ID, //packedPdu: "0006002b0000020015000900bbbccc8103abcd3800140017000001f700bbbcccabcd38000000bbbccc000000000001", packedPdu: "0006002b0000020015000900bbbcccc003abcd3800140017000001f700bbbcccabcd38000000bbbccc000000000001", }, { eNBId: []byte{0xab, 0xcd, 0xef, 0x8}, - eNBIdBitqty: home_eNB_ID, + eNBIdBitqty: Home_eNB_ID, packedPdu: "0006002b0000020015000900bbbccc40abcdef8000140017000001f700bbbcccabcdef800000bbbccc000000000001", }, } @@ -65,7 +65,7 @@ func TestPackX2apSetupRequest(t *testing.T) { for _, tc := range testCases { t.Run(tc.packedPdu, func(t *testing.T) { - payload, err := packX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, tc.eNBId, tc.eNBIdBitqty) + payload, _, err :=PreparePackedX2SetupRequest(MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, tc.eNBId, tc.eNBIdBitqty,ricFlag) if err != nil { t.Errorf("want: success, got: pack failed. Error: %v\n", err) } else { @@ -86,13 +86,13 @@ func TestPackX2apSetupRequest(t *testing.T) { /*Packing error*/ func TestPackX2apSetupRequestPackError(t *testing.T) { - logger, _ := logger.InitLogger(logger.InfoLevel) wantError := "packing error: #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big:46" pLMNId := []byte{0xbb, 0xbc, 0xcc} + ricFlag := []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/ eNBId := []byte{0xab, 0xcd, 0xe} - eNBIdBitqty := uint(macro_eNB_ID) - _, err := packX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, 40 /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId[:], eNBId[:], eNBIdBitqty) + eNBIdBitqty := uint(Macro_eNB_ID) + _, _, err := PreparePackedX2SetupRequest(40 /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, eNBId, eNBIdBitqty, ricFlag) if err != nil { if 0 != strings.Compare(fmt.Sprintf("%s", err), wantError) { t.Errorf("want failure: %s, got: %s", wantError, err) diff --git a/E2Manager/e2pdus/x2_setup_requests.go b/E2Manager/e2pdus/x2_setup_requests.go new file mode 100644 index 0000000..9f3d3f8 --- /dev/null +++ b/E2Manager/e2pdus/x2_setup_requests.go @@ -0,0 +1,80 @@ +package e2pdus + +// #cgo CFLAGS: -I../asn1codec/inc/ -I../asn1codec/e2ap_engine/ +// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec +// #include +// #include +import "C" +import ( + "fmt" + "github.com/pkg/errors" + "unsafe" +) + +const ( + ShortMacro_eNB_ID = 18 + Macro_eNB_ID = 20 + LongMacro_eNB_ID = 21 + Home_eNB_ID = 28 +) + +var PackedEndcX2setupRequest []byte +var PackedX2setupRequest []byte +var PackedEndcX2setupRequestAsString string +var PackedX2setupRequestAsString string + +func PreparePackedEndcX2SetupRequest(maxAsn1PackedBufferSize int, maxAsn1CodecMessageBufferSize int,pLMNId []byte, eNB_Id []byte /*18, 20, 21, 28 bits length*/, bitqty uint, ricFlag []byte) ([]byte, string, error) { + packedBuf := make([]byte, maxAsn1PackedBufferSize) + errBuf := make([]C.char, maxAsn1CodecMessageBufferSize) + packedBufSize := C.ulong(len(packedBuf)) + pduAsString := "" + + if !C.build_pack_endc_x2setup_request( + (*C.uchar)(unsafe.Pointer(&pLMNId[0])) /*pLMN_Identity*/, + (*C.uchar)(unsafe.Pointer(&eNB_Id[0])), + C.uint(bitqty), + (*C.uchar)(unsafe.Pointer(&ricFlag[0])) /*pLMN_Identity*/, + &packedBufSize, + (*C.uchar)(unsafe.Pointer(&packedBuf[0])), + C.ulong(len(errBuf)), + &errBuf[0]) { + return nil, "", errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errBuf[0]))) + } + + pdu:= C.new_pdu(C.size_t(1)) //TODO: change signature + defer C.delete_pdu(pdu) + if C.per_unpack_pdu(pdu, packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])),C.size_t(len(errBuf)), &errBuf[0]){ + C.asn1_pdu_printer(pdu, C.size_t(len(errBuf)), &errBuf[0]) + pduAsString = C.GoString(&errBuf[0]) + } + + return packedBuf[:packedBufSize], pduAsString, nil +} + +func PreparePackedX2SetupRequest(maxAsn1PackedBufferSize int, maxAsn1CodecMessageBufferSize int,pLMNId []byte, eNB_Id []byte /*18, 20, 21, 28 bits length*/, bitqty uint, ricFlag []byte) ([]byte, string, error) { + packedBuf := make([]byte, maxAsn1PackedBufferSize) + errBuf := make([]C.char, maxAsn1CodecMessageBufferSize) + packedBufSize := C.ulong(len(packedBuf)) + pduAsString := "" + + if !C.build_pack_x2setup_request( + (*C.uchar)(unsafe.Pointer(&pLMNId[0])) /*pLMN_Identity*/, + (*C.uchar)(unsafe.Pointer(&eNB_Id[0])), + C.uint(bitqty), + (*C.uchar)(unsafe.Pointer(&ricFlag[0])) /*pLMN_Identity*/, + &packedBufSize, + (*C.uchar)(unsafe.Pointer(&packedBuf[0])), + C.ulong(len(errBuf)), + &errBuf[0]) { + return nil, "", errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errBuf[0]))) + } + + pdu:= C.new_pdu(C.size_t(1)) //TODO: change signature + defer C.delete_pdu(pdu) + if C.per_unpack_pdu(pdu, packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])),C.size_t(len(errBuf)), &errBuf[0]){ + C.asn1_pdu_printer(pdu, C.size_t(len(errBuf)), &errBuf[0]) + pduAsString = C.GoString(&errBuf[0]) + } + return packedBuf[:packedBufSize], pduAsString, nil +} + diff --git a/E2Manager/handlers/e2_term_init_notification_handler.go b/E2Manager/handlers/e2_term_init_notification_handler.go new file mode 100644 index 0000000..6e28d14 --- /dev/null +++ b/E2Manager/handlers/e2_term_init_notification_handler.go @@ -0,0 +1,66 @@ +// +// Copyright 2019 AT&T Intellectual Property +// Copyright 2019 Nokia +// +// 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. +// + +package handlers + +import ( + "e2mgr/logger" + "e2mgr/managers" + "e2mgr/models" + "e2mgr/sessions" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader" +) + +type E2TermInitNotificationHandler struct { + rnibReaderProvider func() reader.RNibReader + ranReconnectionManager *managers.RanReconnectionManager +} + +func NewE2TermInitNotificationHandler(ranReconnectionManager *managers.RanReconnectionManager, rnibReaderProvider func() reader.RNibReader) E2TermInitNotificationHandler { + return E2TermInitNotificationHandler{ + rnibReaderProvider: rnibReaderProvider, + ranReconnectionManager: ranReconnectionManager, + } +} + + +func (handler E2TermInitNotificationHandler) Handle(logger *logger.Logger, e2Sessions sessions.E2Sessions, + request *models.NotificationRequest, messageChannel chan<- *models.NotificationResponse) { + logger.Infof("#e2_term_init_notification_handler.Handle - Received E2_TERM_INIT") + return //TODO: enable + + nbIdentityList, err := handler.rnibReaderProvider().GetListNodebIds() + + if err != nil { + logger.Errorf("#e2_term_init_notification_handler.Handle - Failed to get nodes list from RNIB. Error: %s", err.Error()) + return + } + + if len(nbIdentityList) == 0 { + logger.Warnf("#e2_term_init_notification_handler.Handle - The Nodes list in RNIB is empty") + return + } + + for _,nbIdentity := range nbIdentityList{ + + if err := handler.ranReconnectionManager.ReconnectRan(nbIdentity.InventoryName); err != nil { + logger.Errorf("#e2_term_init_notification_handler.Handle - connection attempt failure, ran name: %s. Error: %s", + (*nbIdentity).GetInventoryName(), err.Error()) + break + } + } +} diff --git a/E2Manager/handlers/endc_setup_request_handler.go b/E2Manager/handlers/endc_setup_request_handler.go index ad3ae8f..6954149 100644 --- a/E2Manager/handlers/endc_setup_request_handler.go +++ b/E2Manager/handlers/endc_setup_request_handler.go @@ -18,9 +18,11 @@ package handlers import ( + "e2mgr/e2pdus" "e2mgr/logger" "e2mgr/rNibWriter" "e2mgr/rnibBuilders" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" "sync" "time" @@ -40,7 +42,7 @@ func NewEndcSetupRequestHandler(rnibWriterProvider func() rNibWriter.RNibWriter) } func (handler EndcSetupRequestHandler) PreHandle(logger *logger.Logger, details *models.RequestDetails) error { - nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details) + nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details,entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST) rNibErr := handler.rnibWriterProvider().SaveNodeb(nodebIdentity, nodebInfo) if rNibErr != nil { @@ -56,17 +58,13 @@ func (EndcSetupRequestHandler) CreateMessage(logger *logger.Logger, requestDetai wg.Add(1) - payload, err := packEndcX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId[:], eNBId[:], eNBIdBitqty) - if err != nil { - logger.Errorf("#endc_setup_request_handler.CreateMessage - pack was failed. Error: %v", err) - } else { - transactionId := requestDetails.RanName - e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails} - setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, payload) + transactionId := requestDetails.RanName + e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails} + setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, e2pdus.PackedEndcX2setupRequest) - logger.Debugf("#endc_setup_request_handler.CreateMessage - setupRequestMessage was created successfuly. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage) - messageChannel <- setupRequestMessage - } + logger.Debugf("#endc_setup_request_handler.CreateMessage - PDU: %s", e2pdus.PackedEndcX2setupRequestAsString) + logger.Debugf("#endc_setup_request_handler.CreateMessage - setupRequestMessage was created successfuly. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage) + messageChannel <- setupRequestMessage wg.Done() } diff --git a/E2Manager/handlers/endc_setup_response_notification_handler.go b/E2Manager/handlers/endc_setup_response_notification_handler.go index e706039..2e64f3e 100644 --- a/E2Manager/handlers/endc_setup_response_notification_handler.go +++ b/E2Manager/handlers/endc_setup_response_notification_handler.go @@ -53,6 +53,7 @@ func (src EndcX2SetupResponseNotificationHandler) Handle(logger *logger.Logger, nb.GlobalNbId = nbIdentity.GlobalNbId nb.RanName = e2session.Request.RanName nb.ConnectionStatus = entities.ConnectionStatus_CONNECTED + nb.E2ApplicationProtocol = entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST nb.Ip = e2session.Request.RanIp nb.Port = uint32(e2session.Request.RanPort) nb.NodeType = entities.Node_GNB diff --git a/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer.go b/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer.go deleted file mode 100644 index 879e01d..0000000 --- a/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer.go +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2019 AT&T Intellectual Property -// Copyright 2019 Nokia -// -// 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. -// - -package handlers - -// #cgo CFLAGS: -I../asn1codec/inc/ -I../asn1codec/e2ap_engine/ -// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec -// #include -// #include -import "C" -import ( - "e2mgr/logger" - "fmt" - "github.com/pkg/errors" - "unsafe" -) - -func packEndcX2apSetupRequest(logger *logger.Logger, allocationBufferSize int, maxPackedBufferSize int, maxMessageBufferSize int, pLMNId []byte, eNB_Id []byte /*18, 20, 21, 28 bits length*/, bitqty uint) ([]byte, error) { - packedBuf := make([]byte, maxPackedBufferSize) - errBuf := make([]C.char, maxMessageBufferSize) - packedBufSize := C.ulong(len(packedBuf)) - - if !C.build_pack_endc_x2setup_request((*C.uchar)(unsafe.Pointer(&pLMNId[0])) /*pLMN_Identity*/, - (*C.uchar)(unsafe.Pointer(&eNB_Id[0])), C.uint(bitqty),(*C.uchar)(unsafe.Pointer(&ricFlag[0])) /*pLMN_Identity*/, - &packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])), C.ulong(len(errBuf)), &errBuf[0]) { - return nil, errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errBuf[0]))) - } - - if logger.DebugEnabled() { - pdu:= C.new_pdu(C.size_t(allocationBufferSize)) - defer C.delete_pdu(pdu) - if C.per_unpack_pdu(pdu, packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])),C.size_t(len(errBuf)), &errBuf[0]){ - C.asn1_pdu_printer(pdu, C.size_t(len(errBuf)), &errBuf[0]) - logger.Debugf("endc_x2apSetupRequest_asn1_packer.packEndcX2apSetupRequest - PDU:%s\n\npacked (%d):%x", C.GoString(&errBuf[0]), packedBufSize, packedBuf[:packedBufSize]) - } - } - - return packedBuf[:packedBufSize], nil - -} diff --git a/E2Manager/handlers/setup_request_handler.go b/E2Manager/handlers/setup_request_handler.go index f9c031b..4c49b1d 100644 --- a/E2Manager/handlers/setup_request_handler.go +++ b/E2Manager/handlers/setup_request_handler.go @@ -18,10 +18,12 @@ package handlers import ( + "e2mgr/e2pdus" "e2mgr/logger" "e2mgr/rNibWriter" "e2mgr/rnibBuilders" "fmt" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" "os" "sync" "time" @@ -38,18 +40,12 @@ const ( MaxAsn1CodecMessageBufferSize = 4096 ) -const ( - shortMacro_eNB_ID = 18 - macro_eNB_ID = 20 - longMacro_eNB_ID = 21 - home_eNB_ID = 28 -) /*The Ric Id is the combination of pLMNId and ENBId*/ var pLMNId []byte var eNBId []byte var eNBIdBitqty uint -var ricFlag = [3]byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/ +var ricFlag = []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/ type SetupRequestHandler struct { rnibWriterProvider func() rNibWriter.RNibWriter @@ -62,7 +58,7 @@ func NewSetupRequestHandler(rnibWriterProvider func() rNibWriter.RNibWriter) *Se } func (handler SetupRequestHandler) PreHandle(logger *logger.Logger, details *models.RequestDetails) error { - nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details) + nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details, entities.E2ApplicationProtocol_X2_SETUP_REQUEST) rNibErr := handler.rnibWriterProvider().SaveNodeb(nodebIdentity, nodebInfo) if rNibErr != nil { @@ -78,17 +74,13 @@ func (SetupRequestHandler) CreateMessage(logger *logger.Logger, requestDetails * wg.Add(1) - payload, err := packX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, eNBId, eNBIdBitqty) - if err != nil { - logger.Errorf("#setup_request_handler.CreateMessage - pack was failed. Error: %v", err) - } else { - transactionId := requestDetails.RanName - e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails} - setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, payload) + transactionId := requestDetails.RanName + e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails} + setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, e2pdus.PackedX2setupRequest) - logger.Debugf("#setup_request_handler.CreateMessage - setupRequestMessage was created successfully. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage) - messageChannel <- setupRequestMessage - } + logger.Debugf("#setup_request_handler.CreateMessage - PDU: %s", e2pdus.PackedX2setupRequestAsString) + logger.Debugf("#setup_request_handler.CreateMessage - setupRequestMessage was created successfully. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage) + messageChannel <- setupRequestMessage wg.Done() } @@ -110,7 +102,7 @@ func parseRicID(ricId string) error { return fmt.Errorf("invalid value for %s, len(eNBId:%v) != 3 or 4", ENV_RIC_ID, eNBId) } - if eNBIdBitqty != shortMacro_eNB_ID && eNBIdBitqty != macro_eNB_ID && eNBIdBitqty != longMacro_eNB_ID && eNBIdBitqty != home_eNB_ID { + if eNBIdBitqty != e2pdus.ShortMacro_eNB_ID && eNBIdBitqty != e2pdus.Macro_eNB_ID && eNBIdBitqty != e2pdus.LongMacro_eNB_ID && eNBIdBitqty != e2pdus.Home_eNB_ID { return fmt.Errorf("invalid value for %s, eNBIdBitqty: %d", ENV_RIC_ID, eNBIdBitqty) } @@ -123,11 +115,20 @@ func (SetupRequestHandler) GetMessageType() int { } func init() { + var err error ricId := os.Getenv(ENV_RIC_ID) //ricId="bbbccc-ffff0e/20" //ricId="bbbccc-abcd0e/20" - if err := parseRicID(ricId); err != nil { + if err = parseRicID(ricId); err != nil { panic(err) } + e2pdus.PackedEndcX2setupRequest,e2pdus.PackedEndcX2setupRequestAsString, err = e2pdus.PreparePackedEndcX2SetupRequest(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize,pLMNId, eNBId, eNBIdBitqty, ricFlag ) + if err != nil{ + panic(err) + } + e2pdus.PackedX2setupRequest,e2pdus.PackedX2setupRequestAsString, err = e2pdus.PreparePackedX2SetupRequest(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize,pLMNId, eNBId, eNBIdBitqty, ricFlag ) + if err != nil{ + panic(err) + } } diff --git a/E2Manager/handlers/setup_request_handler_test.go b/E2Manager/handlers/setup_request_handler_test.go index f0de7c4..afd093d 100644 --- a/E2Manager/handlers/setup_request_handler_test.go +++ b/E2Manager/handlers/setup_request_handler_test.go @@ -19,6 +19,7 @@ package handlers import ( "bytes" + "e2mgr/e2pdus" "e2mgr/logger" "e2mgr/mocks" "e2mgr/models" @@ -64,25 +65,25 @@ func TestParseRicId(t *testing.T) { ricId: "bbbccc-abcd02/18", pLMNId: []byte{0xbb, 0xbc, 0xcc}, eNBId: []byte{0xab, 0xcd, 0x2}, /*00000010 -> 10000000*/ - eNBIdBitqty: shortMacro_eNB_ID, + eNBIdBitqty: e2pdus.ShortMacro_eNB_ID, }, { ricId: "bbbccc-abcd0e/20", pLMNId: []byte{0xbb, 0xbc, 0xcc}, eNBId: []byte{0xab, 0xcd, 0xe}, - eNBIdBitqty: macro_eNB_ID, + eNBIdBitqty: e2pdus.Macro_eNB_ID, }, { ricId: "bbbccc-abcd07/21", pLMNId: []byte{0xbb, 0xbc, 0xcc}, eNBId: []byte{0xab, 0xcd, 0x7}, /*00000111 -> 00111000*/ - eNBIdBitqty: longMacro_eNB_ID, + eNBIdBitqty: e2pdus.LongMacro_eNB_ID, }, { ricId: "bbbccc-abcdef08/28", pLMNId: []byte{0xbb, 0xbc, 0xcc}, eNBId: []byte{0xab, 0xcd, 0xef, 0x8}, - eNBIdBitqty: home_eNB_ID, + eNBIdBitqty: e2pdus.Home_eNB_ID, }, { ricId: "", diff --git a/E2Manager/handlers/x2_reset_request_handler.go b/E2Manager/handlers/x2_reset_request_handler.go index eafd0cc..5964c67 100644 --- a/E2Manager/handlers/x2_reset_request_handler.go +++ b/E2Manager/handlers/x2_reset_request_handler.go @@ -32,7 +32,7 @@ import ( ) const ( - X2_RESET_ACTIVITIY_NAME = "X2_RESET" + X2_RESET_ACTIVITY_NAME = "X2_RESET" ) type X2ResetRequestHandler struct { readerProvider func() reader.RNibReader @@ -75,7 +75,7 @@ func (handler *X2ResetRequestHandler) Handle(logger *logger.Logger, request mode if nodeb.ConnectionStatus != entities.ConnectionStatus_CONNECTED { logger.Errorf("#reset_request_handler.Handle - RAN: %s in wrong state (%s)", resetRequest.RanName, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)]) - return e2managererrors.NewWrongStateError(X2_RESET_ACTIVITIY_NAME,entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)]) + return e2managererrors.NewWrongStateError(X2_RESET_ACTIVITY_NAME,entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)]) } response := models.NotificationResponse{MgsType: rmrCgo.RIC_X2_RESET, RanName: resetRequest.RanName, Payload: payload} diff --git a/E2Manager/handlers/x2_reset_request_handler_test.go b/E2Manager/handlers/x2_reset_request_handler_test.go index 7027ec4..79dc93e 100644 --- a/E2Manager/handlers/x2_reset_request_handler_test.go +++ b/E2Manager/handlers/x2_reset_request_handler_test.go @@ -140,7 +140,7 @@ func TestHandleFailureWrongState(t *testing.T){ actual := handler.Handle(log, models.ResetRequest{RanName: ranName }) - assert.IsType(t, e2managererrors.NewWrongStateError(X2_RESET_ACTIVITIY_NAME, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)]), actual) + assert.IsType(t, e2managererrors.NewWrongStateError(X2_RESET_ACTIVITY_NAME, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)]), actual) } diff --git a/E2Manager/handlers/x2apSetupRequest_asn1_packer.go b/E2Manager/handlers/x2apSetupRequest_asn1_packer.go deleted file mode 100644 index 9c548b0..0000000 --- a/E2Manager/handlers/x2apSetupRequest_asn1_packer.go +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2019 AT&T Intellectual Property -// Copyright 2019 Nokia -// -// 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. -// - -package handlers - -// #cgo CFLAGS: -I../asn1codec/inc/ -I../asn1codec/e2ap_engine/ -// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec -// #include -// #include -import "C" -import ( - "e2mgr/logger" - "fmt" - "github.com/pkg/errors" - "unsafe" -) - -func packX2apSetupRequest(logger *logger.Logger, allocationBufferSize int, maxPackedBufferSize int, maxMessageBufferSize int, pLMNId []byte, eNB_Id []byte /*18, 20, 21, 28 bits length*/, bitqty uint) ([]byte, error) { - packedBuf := make([]byte, maxPackedBufferSize) - errBuf := make([]C.char, maxMessageBufferSize) - packedBufSize := C.ulong(len(packedBuf)) - - if !C.build_pack_x2setup_request((*C.uchar)(unsafe.Pointer(&pLMNId[0])) /*pLMN_Identity*/, - (*C.uchar)(unsafe.Pointer(&eNB_Id[0])), C.uint(bitqty),(*C.uchar)(unsafe.Pointer(&ricFlag[0])) /*pLMN_Identity*/, - &packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])), C.ulong(len(errBuf)), &errBuf[0]) { - return nil, errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errBuf[0]))) - } - - if logger.DebugEnabled() { - pdu:= C.new_pdu(C.size_t(allocationBufferSize)) - defer C.delete_pdu(pdu) - if C.per_unpack_pdu(pdu, packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])),C.size_t(len(errBuf)), &errBuf[0]){ - C.asn1_pdu_printer(pdu, C.size_t(len(errBuf)), &errBuf[0]) - logger.Debugf("#x2apSetupRequest_asn1_packer.packX2apSetupRequest - PDU:%s\n\npacked (%d):%x", C.GoString(&errBuf[0]), packedBufSize, packedBuf[:packedBufSize]) - } - } - return packedBuf[:packedBufSize], nil - -} - diff --git a/E2Manager/handlers/x2apSetup_response_notification_handler.go b/E2Manager/handlers/x2apSetup_response_notification_handler.go index 5e9f674..b69cf58 100644 --- a/E2Manager/handlers/x2apSetup_response_notification_handler.go +++ b/E2Manager/handlers/x2apSetup_response_notification_handler.go @@ -51,6 +51,7 @@ func (src X2SetupResponseNotificationHandler) Handle(logger *logger.Logger, e2Se nb.GlobalNbId = nbIdentity.GlobalNbId nb.RanName = e2session.Request.RanName nb.ConnectionStatus = entities.ConnectionStatus_CONNECTED + nb.E2ApplicationProtocol = entities.E2ApplicationProtocol_X2_SETUP_REQUEST nb.Ip = e2session.Request.RanIp nb.Port = uint32(e2session.Request.RanPort) nb.NodeType = entities.Node_ENB diff --git a/E2Manager/managers/ran_reconnection_manager.go b/E2Manager/managers/ran_reconnection_manager.go index 328018b..df3467a 100644 --- a/E2Manager/managers/ran_reconnection_manager.go +++ b/E2Manager/managers/ran_reconnection_manager.go @@ -45,7 +45,7 @@ func NewRanReconnectionManager(logger *logger.Logger, config *configuration.Conf config: config, rnibReaderProvider: rnibReaderProvider, rnibWriterProvider: rnibWriterProvider, - ranSetupManager: NewRanSetupManager(logger,rmrService,rnibReaderProvider,rnibWriterProvider), + ranSetupManager: NewRanSetupManager(logger,rmrService,rnibWriterProvider), } } diff --git a/E2Manager/managers/ran_setup_manager.go b/E2Manager/managers/ran_setup_manager.go index ce84468..cb24472 100644 --- a/E2Manager/managers/ran_setup_manager.go +++ b/E2Manager/managers/ran_setup_manager.go @@ -18,28 +18,101 @@ package managers import ( + "e2mgr/e2managererrors" + "e2mgr/e2pdus" "e2mgr/logger" + "e2mgr/models" "e2mgr/rNibWriter" + "e2mgr/rmrCgo" "e2mgr/services" "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" - "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader" ) type RanSetupManager struct { logger *logger.Logger - rnibReaderProvider func() reader.RNibReader rnibWriterProvider func() rNibWriter.RNibWriter rmrService *services.RmrService } -func NewRanSetupManager(logger *logger.Logger, rmrService *services.RmrService, rnibReaderProvider func() reader.RNibReader, rnibWriterProvider func() rNibWriter.RNibWriter) *RanSetupManager { +func NewRanSetupManager(logger *logger.Logger, rmrService *services.RmrService, rnibWriterProvider func() rNibWriter.RNibWriter) *RanSetupManager { return &RanSetupManager{ logger: logger, - rnibReaderProvider: rnibReaderProvider, rnibWriterProvider: rnibWriterProvider, + rmrService : rmrService, } } + +// Update retries and connection status (connecting) +func (m *RanSetupManager) updateConnectionStatusConnecting(nodebInfo *entities.NodebInfo) error { + // Update retries and connection status (connecting) + nodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTING + nodebInfo.ConnectionAttempts++ + err:= m.rnibWriterProvider().UpdateNodebInfo(nodebInfo) + if err != nil { + m.logger.Errorf("#ran_setup_manager.updateConnectionStatusConnecting - failed to update RAN's connection status to CONNECTING: %s", err) + } else { + m.logger.Infof("#ran_setup_manager.updateConnectionStatusConnecting - successfully updated RAN's connection status to CONNECTING: %s", err) + } + return err +} + +// Decrement retries and connection status (disconnected) +func (m *RanSetupManager) updateConnectionStatusDisconnected(nodebInfo *entities.NodebInfo) error { + // Update retries and connection status (connecting) + nodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED + nodebInfo.ConnectionAttempts-- + err := m.rnibWriterProvider().UpdateNodebInfo(nodebInfo) + if err != nil { + m.logger.Errorf("#ran_setup_manager.updateConnectionStatusDisconnected - failed to update RAN's connection status to DISCONNECTED : %s", err) + } else { + m.logger.Errorf("#ran_setup_manager.updateConnectionStatusDisconnected - successfully updated RAN's connection status to DISCONNECTED : %s", err) + } + return err +} + +func (m *RanSetupManager) prepareSetupRequest(nodebInfo *entities.NodebInfo) (int, *models.E2RequestMessage, error) { + // Build the endc/x2 setup request + switch nodebInfo.E2ApplicationProtocol { + case entities.E2ApplicationProtocol_X2_SETUP_REQUEST: + rmrMsgType := rmrCgo.RIC_X2_SETUP_REQ + request := models.NewE2RequestMessage(nodebInfo.RanName /*tid*/, nodebInfo.Ip, uint16(nodebInfo.Port), nodebInfo.RanName, e2pdus.PackedX2setupRequest) + return rmrMsgType, request, nil + case entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST: + rmrMsgType := rmrCgo.RIC_ENDC_X2_SETUP_REQ + request:= models.NewE2RequestMessage(nodebInfo.RanName /*tid*/, nodebInfo.Ip, uint16(nodebInfo.Port), nodebInfo.RanName, e2pdus.PackedEndcX2setupRequest) + return rmrMsgType, request, nil + } + + m.logger.Errorf("#ran_setup_manager.ExecuteSetup - unsupported nodebInfo.E2ApplicationProtocol %d ", nodebInfo.E2ApplicationProtocol) + return 0, nil, e2managererrors.NewInternalError() +} + +// ExecuteSetup updates the connection status and number of attempts in the nodebInfo and send an endc/x2 setup request to establish a connection with the RAN func (m *RanSetupManager) ExecuteSetup(nodebInfo *entities.NodebInfo) error { + + // Update retries and connection status (connecting) + if err := m.updateConnectionStatusConnecting(nodebInfo); err != nil { + return e2managererrors.NewRnibDbError() + } + + // Build the endc/x2 setup request + rmrMsgType,request, err := m.prepareSetupRequest(nodebInfo) + if err != nil { + return err + } + + // Send the endc/x2 setup request + response := &models.NotificationResponse{MgsType: rmrMsgType, RanName: nodebInfo.RanName, Payload: request.GetMessageAsBytes(m.logger)} + if err := m.rmrService.SendRmrMessage(response); err != nil { + m.logger.Errorf("#ran_setup_manager.ExecuteSetup - failed to send setup request to RMR: %s", err) + + // Decrement retries and connection status (disconnected) + if err := m.updateConnectionStatusDisconnected(nodebInfo); err != nil { + return e2managererrors.NewRnibDbError() + } + + return e2managererrors.NewRmrError() + } return nil } diff --git a/E2Manager/managers/ran_setup_manager_test.go b/E2Manager/managers/ran_setup_manager_test.go new file mode 100644 index 0000000..2b1906b --- /dev/null +++ b/E2Manager/managers/ran_setup_manager_test.go @@ -0,0 +1,213 @@ +// +// Copyright 2019 AT&T Intellectual Property +// Copyright 2019 Nokia +// +// 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. +// + +package managers + +import ( + "e2mgr/e2managererrors" + "e2mgr/e2pdus" + "e2mgr/logger" + "e2mgr/mocks" + "e2mgr/rNibWriter" + "e2mgr/rmrCgo" + "fmt" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "testing" +) + +func TestExecuteSetupConnectingX2Setup(t *testing.T) { + log := initLog(t) + + ranName := "test1" + + + writerMock := &mocks.RnibWriterMock{} + writerProvider := func() rNibWriter.RNibWriter { + return writerMock + } + + var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST} + var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1 } + var rnibErr common.IRNibError + writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr) + + payload:= e2pdus.PackedX2setupRequest + xaction := []byte(ranName) + msg:= rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction) + rmrMessengerMock := &mocks.RmrMessengerMock{} + rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,nil) + rmrService:= getRmrService(rmrMessengerMock, log) + + mgr := NewRanSetupManager(log, rmrService, writerProvider) + if err:= mgr.ExecuteSetup(initialNodeb); err != nil { + t.Errorf("want: success, got: error: %s", err) + } + + writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1) + rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1) +} + + +func TestExecuteSetupConnectingEndcX2Setup(t *testing.T) { + log := initLog(t) + + ranName := "test1" + + + writerMock := &mocks.RnibWriterMock{} + writerProvider := func() rNibWriter.RNibWriter { + return writerMock + } + + var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST} + var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 1 } + var rnibErr common.IRNibError + writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr) + + payload:= e2pdus.PackedEndcX2setupRequest + xaction := []byte(ranName) + msg:= rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction) + rmrMessengerMock := &mocks.RmrMessengerMock{} + rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,nil) + rmrService:= getRmrService(rmrMessengerMock, log) + + mgr := NewRanSetupManager(log, rmrService, writerProvider) + if err:= mgr.ExecuteSetup(initialNodeb); err != nil { + t.Errorf("want: success, got: error: %s", err) + } + + writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1) + rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1) +} + +func TestExecuteSetupDisconnected(t *testing.T) { + log := initLog(t) + + ranName := "test1" + + writerMock := &mocks.RnibWriterMock{} + writerProvider := func() rNibWriter.RNibWriter { + return writerMock + } + + var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST} + var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1 } + var argNodebDisconnected = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 0 } + var rnibErr common.IRNibError + writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr) + writerMock.On("UpdateNodebInfo",argNodebDisconnected).Return(rnibErr) + + payload:= []byte {0} + xaction := []byte(ranName) + msg:= rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction) + rmrMessengerMock := &mocks.RmrMessengerMock{} + rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,fmt.Errorf("send failure")) + rmrService:= getRmrService(rmrMessengerMock, log) + + mgr := NewRanSetupManager(log, rmrService, writerProvider) + if err:= mgr.ExecuteSetup(initialNodeb); err == nil { + t.Errorf("want: failure, got: success") + } + + writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2) + rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1) +} + +func TestExecuteSetupConnectingRnibError(t *testing.T) { + log := initLog(t) + + ranName := "test1" + + writerMock := &mocks.RnibWriterMock{} + writerProvider := func() rNibWriter.RNibWriter { + return writerMock + } + + var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST} + var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1 } + var argNodebDisconnected = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 0 } + var rnibErr = common.NewInternalError(fmt.Errorf("DB error")) + writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr) + writerMock.On("UpdateNodebInfo",argNodebDisconnected).Return(rnibErr) + + payload:= []byte {0} + xaction := []byte(ranName) + msg:= rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction) + rmrMessengerMock := &mocks.RmrMessengerMock{} + rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,fmt.Errorf("send failure")) + rmrService:= getRmrService(rmrMessengerMock, log) + + mgr := NewRanSetupManager(log, rmrService, writerProvider) + if err:= mgr.ExecuteSetup(initialNodeb); err == nil { + t.Errorf("want: failure, got: success") + } else { + assert.IsType(t, e2managererrors.NewRnibDbError(), err) + } + + + writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1) + rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0) +} + +func TestExecuteSetupDisconnectedRnibError(t *testing.T) { + log := initLog(t) + + ranName := "test1" + + writerMock := &mocks.RnibWriterMock{} + writerProvider := func() rNibWriter.RNibWriter { + return writerMock + } + + var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST} + var argNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1 } + var argNodebDisconnected = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 0 } + var rnibErr common.IRNibError + writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr) + writerMock.On("UpdateNodebInfo",argNodebDisconnected).Return(common.NewInternalError(fmt.Errorf("DB error"))) + + payload:= []byte {0} + xaction := []byte(ranName) + msg:= rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction) + rmrMessengerMock := &mocks.RmrMessengerMock{} + rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,fmt.Errorf("send failure")) + rmrService:= getRmrService(rmrMessengerMock, log) + + mgr := NewRanSetupManager(log, rmrService, writerProvider) + if err:= mgr.ExecuteSetup(initialNodeb); err == nil { + t.Errorf("want: failure, got: success") + } else { + assert.IsType(t, e2managererrors.NewRnibDbError(), err) + } + + writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2) + rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1) +} + + +func initLog(t *testing.T) *logger.Logger { + log, err := logger.InitLogger(logger.InfoLevel) + if err != nil { + t.Errorf("#initLog test - failed to initialize logger, error: %s", err) + } + return log +} + + diff --git a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go index f65dee3..159c44d 100644 --- a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go +++ b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go @@ -49,6 +49,7 @@ func initNotificationHandlersMap(rnibReaderProvider func() reader.RNibReader, rn rmrCgo.RIC_ENDC_CONF_UPDATE: handlers.EndcConfigurationUpdateHandler{}, rmrCgo.RIC_X2_RESET_RESP: handlers.NewX2ResetResponseHandler(rnibReaderProvider), rmrCgo.RIC_X2_RESET: handlers.NewX2ResetRequestNotificationHandler(rnibReaderProvider), + rmrCgo.RIC_E2_TERM_INIT: handlers.NewE2TermInitNotificationHandler(ranReconnectionManager, rnibReaderProvider ), } } diff --git a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go index a2a814d..66f2e36 100644 --- a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go +++ b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go @@ -68,6 +68,7 @@ func TestGetNotificationHandlerSuccess(t *testing.T) { {rmrCgo.RIC_ENB_LOAD_INFORMATION, handlers.NewEnbLoadInformationNotificationHandler(rnibWriterProvider)}, {rmrCgo.RIC_ENB_CONF_UPDATE, handlers.X2EnbConfigurationUpdateHandler{}}, {rmrCgo.RIC_ENDC_CONF_UPDATE, handlers.EndcConfigurationUpdateHandler{}}, + {rmrCgo.RIC_E2_TERM_INIT, handlers.NewE2TermInitNotificationHandler(ranReconnectionManager, rnibReaderProvider)}, } for _, tc := range testCases { diff --git a/E2Manager/rmrCgo/rmrCgoTypes.go b/E2Manager/rmrCgo/rmrCgoTypes.go index e37b97b..441ed9f 100644 --- a/E2Manager/rmrCgo/rmrCgoTypes.go +++ b/E2Manager/rmrCgo/rmrCgoTypes.go @@ -67,6 +67,7 @@ const ( RIC_SCTP_CLEAR_ALL = C.RIC_SCTP_CLEAR_ALL RIC_X2_RESET_RESP = C.RIC_X2_RESET_RESP RIC_X2_RESET = C.RIC_X2_RESET + RIC_E2_TERM_INIT = C.E2_TERM_INIT ) const ( diff --git a/E2Manager/rnibBuilders/node_info_builder.go b/E2Manager/rnibBuilders/node_info_builder.go index 53c3411..3595d79 100644 --- a/E2Manager/rnibBuilders/node_info_builder.go +++ b/E2Manager/rnibBuilders/node_info_builder.go @@ -22,11 +22,12 @@ import ( "e2mgr/models" ) -func CreateInitialNodeInfo(requestDetails *models.RequestDetails) (*entities.NodebInfo, *entities.NbIdentity) { +func CreateInitialNodeInfo(requestDetails *models.RequestDetails, protocol entities.E2ApplicationProtocol) (*entities.NodebInfo, *entities.NbIdentity) { nodebInfo := &entities.NodebInfo{} nodebInfo.Ip = requestDetails.RanIp nodebInfo.Port = uint32(requestDetails.RanPort) nodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTING + nodebInfo.E2ApplicationProtocol = protocol nodebInfo.RanName = requestDetails.RanName nodebIdentity := &entities.NbIdentity{} diff --git a/E2Manager/rnibBuilders/node_info_builder_test.go b/E2Manager/rnibBuilders/node_info_builder_test.go index 40c0d1b..e95f12d 100644 --- a/E2Manager/rnibBuilders/node_info_builder_test.go +++ b/E2Manager/rnibBuilders/node_info_builder_test.go @@ -34,9 +34,10 @@ func TestCreateInitialNodeInfo(t *testing.T) { RanPort:ranPort, RanIp:ranIP, } - nodebInfo, identity := CreateInitialNodeInfo(requestDetails) + nodebInfo, identity := CreateInitialNodeInfo(requestDetails, entities.E2ApplicationProtocol_X2_SETUP_REQUEST) assert.Equal(t, identity.InventoryName, ranName) assert.Equal(t, nodebInfo.Ip, ranIP) assert.Equal(t, nodebInfo.ConnectionStatus, entities.ConnectionStatus_CONNECTING) + assert.Equal(t, nodebInfo.E2ApplicationProtocol, entities.E2ApplicationProtocol_X2_SETUP_REQUEST) assert.Equal(t, nodebInfo.Port, uint32(ranPort)) } \ No newline at end of file diff --git a/router.txt b/router.txt index 0a643f9..b80e438 100644 --- a/router.txt +++ b/router.txt @@ -13,5 +13,5 @@ rte|10372|10.0.2.15:38000 rte|10080|10.0.2.15:3801 rte|10081|10.0.2.15:38000 rte|10082|10.0.2.15:38000 - +rte|1100|10.0.2.15:3801 newrt|end -- 2.16.6