First release
[sim/ns3-o-ran-e2.git] / model / ric-control-message.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2022 Northeastern University
4  * Copyright (c) 2022 Sapienza, University of Rome
5  * Copyright (c) 2022 University of Padova
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation;
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Author: Andrea Lacava <thecave003@gmail.com>
21  *                 Tommaso Zugno <tommasozugno@gmail.com>
22  *                 Michele Polese <michele.polese@gmail.com>
23  */
24  
25 #include <ns3/ric-control-message.h>
26 #include <ns3/asn1c-types.h>
27 #include <ns3/log.h>
28 #include <bitset>
29 namespace ns3 {
30
31 NS_LOG_COMPONENT_DEFINE ("RicControlMessage");
32
33
34 RicControlMessage::RicControlMessage (E2AP_PDU_t* pdu)
35 {
36   DecodeRicControlMessage (pdu);
37   NS_LOG_INFO ("End of RicControlMessage::RicControlMessage()");
38 }
39
40 RicControlMessage::~RicControlMessage ()
41 {
42
43 }
44
45 void  
46 RicControlMessage::DecodeRicControlMessage(E2AP_PDU_t* pdu)
47 {
48     InitiatingMessage_t* mess = pdu->choice.initiatingMessage;
49     auto *request = (RICcontrolRequest_t *) &mess->value.choice.RICcontrolRequest;
50     NS_LOG_INFO (xer_fprint(stderr, &asn_DEF_RICcontrolRequest, request));
51
52     size_t count = request->protocolIEs.list.count; 
53     if (count <= 0) {
54         NS_LOG_ERROR("[E2SM] received empty list");
55         return;
56     }
57
58     for (size_t i = 0; i < count; i++) 
59     {
60         RICcontrolRequest_IEs_t *ie = request->protocolIEs.list.array [i];
61         switch (ie->value.present) {
62             case RICcontrolRequest_IEs__value_PR_RICrequestID: {
63                 NS_LOG_DEBUG("[E2SM] RICcontrolRequest_IEs__value_PR_RICrequestID");
64                 m_ricRequestId = ie->value.choice.RICrequestID;
65                 switch (m_ricRequestId.ricRequestorID) {
66                     case 1001: {
67                         NS_LOG_DEBUG("TS xApp message");
68                         m_requestType = ControlMessageRequestIdType::TS;
69                         break;
70                     }
71                     case 1002: {
72                         NS_LOG_DEBUG("QoS xApp message");
73                         m_requestType = ControlMessageRequestIdType::QoS;
74                         break;
75                     }
76                 }
77                 break;
78             }
79             case RICcontrolRequest_IEs__value_PR_RANfunctionID: {
80                 m_ranFunctionId = ie->value.choice.RANfunctionID;
81
82                 NS_LOG_DEBUG("[E2SM] RICcontrolRequest_IEs__value_PR_RANfunctionID");
83                 break;
84             }
85             case RICcontrolRequest_IEs__value_PR_RICcallProcessID: {
86                 m_ricCallProcessId = ie->value.choice.RICcallProcessID;
87                 NS_LOG_DEBUG("[E2SM] RICcontrolRequest_IEs__value_PR_RICcallProcessID");
88                 break;
89             }
90             case RICcontrolRequest_IEs__value_PR_RICcontrolHeader: {
91                 NS_LOG_DEBUG("[E2SM] RICcontrolRequest_IEs__value_PR_RICcontrolHeader");
92                 // xer_fprint(stderr, &asn_DEF_RICcontrolHeader, &ie->value.choice.RICcontrolHeader);
93
94                 auto *e2smControlHeader = (E2SM_RC_ControlHeader_t *) calloc(1,
95                                                                              sizeof(E2SM_RC_ControlHeader_t));
96                 ASN_STRUCT_RESET(asn_DEF_E2SM_RC_ControlHeader, e2smControlHeader);
97                 asn_decode (nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_RC_ControlHeader,
98                             (void **) &e2smControlHeader, ie->value.choice.RICcontrolHeader.buf,
99                             ie->value.choice.RICcontrolHeader.size);
100
101                 NS_LOG_INFO (xer_fprint (stderr, &asn_DEF_E2SM_RC_ControlHeader, e2smControlHeader));
102                 if (e2smControlHeader->present == E2SM_RC_ControlHeader_PR_controlHeader_Format1) {
103                     m_e2SmRcControlHeaderFormat1 = e2smControlHeader->choice.controlHeader_Format1;
104                     //m_e2SmRcControlHeaderFormat1->ric_ControlAction_ID;
105                     //m_e2SmRcControlHeaderFormat1->ric_ControlStyle_Type;
106                     //m_e2SmRcControlHeaderFormat1->ueId;
107                 } else {
108                     NS_LOG_DEBUG("[E2SM] Error in checking format of E2SM Control Header");
109                 }
110                 break;
111             }
112             case RICcontrolRequest_IEs__value_PR_RICcontrolMessage: {
113                 NS_LOG_DEBUG("[E2SM] RICcontrolRequest_IEs__value_PR_RICcontrolMessage");
114                 // xer_fprint(stderr, &asn_DEF_RICcontrolMessage, &ie->value.choice.RICcontrolMessage);
115
116                 auto *e2SmControlMessage = (E2SM_RC_ControlMessage_t *) calloc(1,
117                                                                                sizeof(E2SM_RC_ControlMessage_t));
118                 ASN_STRUCT_RESET(asn_DEF_E2SM_RC_ControlMessage, e2SmControlMessage);
119
120                 asn_decode (nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2SM_RC_ControlMessage,
121                             (void **) &e2SmControlMessage, ie->value.choice.RICcontrolMessage.buf,
122                             ie->value.choice.RICcontrolMessage.size);
123
124                 NS_LOG_INFO (xer_fprint(stderr, &asn_DEF_E2SM_RC_ControlMessage, e2SmControlMessage));
125
126                 if (e2SmControlMessage->present == E2SM_RC_ControlMessage_PR_controlMessage_Format1)
127                   {
128                     NS_LOG_DEBUG ("[E2SM] E2SM_RC_ControlMessage_PR_controlMessage_Format1");
129                     E2SM_RC_ControlMessage_Format1_t *e2SmRcControlMessageFormat1 =
130                         e2SmControlMessage->choice.controlMessage_Format1;
131                     m_valuesExtracted =
132                         ExtractRANParametersFromControlMessage (e2SmRcControlMessageFormat1);
133                     if (m_requestType == ControlMessageRequestIdType::TS)
134                       {
135                         // Get and parse the secondaty cell id according to 3GPP TS 38.473, Section 9.2.2.1
136                         for (RANParameterItem item : m_valuesExtracted)
137                           {
138                             if (item.m_valueType == RANParameterItem::ValueType::OctectString)
139                               {
140                                 // First 3 digits are the PLMNID (always 111), last digit is CellId
141                                 std::string cgi = item.m_valueStr->DecodeContent ();
142                                  NS_LOG_INFO ("Decoded CGI value is: " << cgi);
143                                 m_secondaryCellId = cgi.back();
144                               }
145                           }         
146                       }
147                   }
148                 else
149                   {
150                     NS_LOG_DEBUG("[E2SM] Error in checking format of E2SM Control Message");
151                   }
152                 break;
153             }
154             case RICcontrolRequest_IEs__value_PR_RICcontrolAckRequest: {
155                 NS_LOG_DEBUG("[E2SM] RICcontrolRequest_IEs__value_PR_RICcontrolAckRequest");
156
157                 switch (ie->value.choice.RICcontrolAckRequest) {
158                     case RICcontrolAckRequest_noAck: {
159                         NS_LOG_DEBUG("[E2SM] RIC Control ack value: NO ACK");
160                         break;
161                     }
162                     case RICcontrolAckRequest_ack: {
163                         NS_LOG_DEBUG("[E2SM] RIC Control ack value: ACK");
164                         break;
165                     }
166                     case RICcontrolAckRequest_nAck: {
167                         NS_LOG_DEBUG("[E2SM] RIC Control ack value: NACK");
168                         break;
169                     }
170                     default: {
171                         NS_LOG_DEBUG("[E2SM] RIC Control ack value unknown");
172                         break;
173                     }
174                 }
175                 break;
176             }
177             case RICcontrolRequest_IEs__value_PR_NOTHING: {
178                 NS_LOG_DEBUG("[E2SM] RICcontrolRequest_IEs__value_PR_NOTHING");
179                 NS_LOG_DEBUG("[E2SM] Nothing");
180                 break;
181             }
182             default: {
183                 NS_LOG_DEBUG("[E2SM] RIC Control value unknown");
184                 break;
185             }
186         }
187     }
188
189     NS_LOG_INFO ("End of DecodeRicControlMessage");
190 }
191
192 std::string
193 RicControlMessage::GetSecondaryCellIdHO ()
194 {
195   return m_secondaryCellId;
196 }
197
198 std::vector<RANParameterItem>
199 RicControlMessage::ExtractRANParametersFromControlMessage (
200     E2SM_RC_ControlMessage_Format1_t *e2SmRcControlMessageFormat1)
201 {
202   std::vector<RANParameterItem> ranParameterList;
203   int count = e2SmRcControlMessageFormat1->ranParameters_List->list.count;
204   for (int i = 0; i < count; i++)
205     {
206       RANParameter_Item_t *ranParameterItem =
207           e2SmRcControlMessageFormat1->ranParameters_List->list.array[i];
208       for (RANParameterItem extractedParameter :
209            RANParameterItem::ExtractRANParametersFromRANParameter (ranParameterItem))
210         {
211           ranParameterList.push_back (extractedParameter);
212         }
213     }
214
215   return ranParameterList;
216 }
217
218 } // namespace ns3