blob: 269b7fc128f5275dd04f2fd8f7b8c852d491cb68 [file] [log] [blame]
anjana_sreekumar@infosys.com991c2062020-01-08 11:42:57 +05301/*
2 * Copyright 2019-present Infosys Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7/******************************************************************************
8 *
9 * This file has both generated and manual code.
10 *
11 * File template used for code generation:
12 * <TOP-DIR/scripts/SMCodeGen/templates/stateMachineTmpls/actionHandlers.cpp.tt>
13 *
14 ******************************************************************************/
15
16#include <actionHandlers/actionHandlers.h>
17#include <contextManager/dataBlocks.h>
18#include <contextManager/subsDataGroupManager.h>
19#include <controlBlock.h>
20#include <event.h>
21#include <mmeStates/attachStart.h>
22#include <mmeStates/detachStart.h>
23#include <mmeStates/niDetachStart.h>
24#include <mmeStates/pagingStart.h>
25#include <mmeStates/s1ReleaseStart.h>
26#include <mmeStates/serviceRequestStart.h>
27#include "mmeStates/tauStart.h"
28#include <msgBuffer.h>
29#include <msgType.h>
30#include <log.h>
31#include <procedureStats.h>
32#include <s1ap_structs.h>
33#include <state.h>
34#include <string.h>
35#include <sstream>
36#include <smTypes.h>
37#include <typeinfo>
38#include <utils/mmeProcedureTypes.h>
39#include <utils/mmeCommonUtils.h>
40#include <utils/mmeContextManagerUtils.h>
41
42using namespace mme;
43using namespace SM;
44
45/***************************************
46* Action handler : default_attach_req_handler
47***************************************/
48ActStatus ActionHandlers::default_attach_req_handler(ControlBlock& cb)
49{
50 log_msg(LOG_ERROR, "default_attach_req_handler \n");
51
52 UEContext* ueCtxt_p = NULL;
53 MmContext* mmctxt = NULL;
54
55 ueCtxt_p = static_cast <UEContext *>(cb.getPermDataBlock());
56 if (ueCtxt_p != NULL)
57 mmctxt = ueCtxt_p->getMmContext();
58
59 MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
60 if (msgBuf == NULL)
61 {
62 log_msg(LOG_ERROR, "Failed to retrieve message buffer \n");
63 return ActStatus::HALT;
64 }
65
66 const s1_incoming_msg_data_t* msgData_p =
67 static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
68 if (msgData_p == NULL)
69 {
70 log_msg(LOG_ERROR, "Failed to retrieve data buffer \n");
71 return ActStatus::HALT;
72 }
73
74 const struct ue_attach_info &ue_info = (msgData_p->msg_data.ue_attach_info_m);
75
76 AttachType attachType = MmeCommonUtils::getAttachType(ueCtxt_p, ue_info);
77 if (attachType == maxAttachType_c)
78 {
79 log_msg(LOG_ERROR, "Failed to identify attach type \n");
80 return ActStatus::HALT;
81 }
82
83 if (ueCtxt_p == NULL)
84 {
85 ueCtxt_p = SubsDataGroupManager::Instance()->getUEContext();
86 if (ueCtxt_p == NULL)
87 {
88 log_msg(LOG_ERROR, "Failed to allocate UE context \n");
89
90 return ActStatus::HALT;
91 }
92
93 mmctxt = SubsDataGroupManager::Instance()->getMmContext();
94 if( mmctxt == NULL )
95 {
96 log_msg(LOG_ERROR, "Failed to allocate MM Context \n");
97
98 SubsDataGroupManager::Instance()->deleteUEContext( ueCtxt_p );
99 return ActStatus::HALT;
100 }
101
102 ueCtxt_p->setContextID(cb.getCBIndex());
103 ueCtxt_p->setMmContext( mmctxt );
104
105 cb.setPermDataBlock(ueCtxt_p);
106 cb.setFastAccessBlock(ueCtxt_p, 1);
107 }
108
109 MmeProcedureCtxt* prcdCtxt_p = SubsDataGroupManager::Instance()->getMmeProcedureCtxt();
110 if( prcdCtxt_p == NULL )
111 {
112 log_msg(LOG_ERROR, "Failed to allocate Procedure Context \n");
113
114 return ActStatus::HALT;
115 }
116
117 prcdCtxt_p->setCtxtType( ProcedureType::attach_c );
118 prcdCtxt_p->setNextState(AttachStart::Instance());
119
120 cb.setCurrentTempDataBlock(prcdCtxt_p);
121
122 // Copy attach request message data into UE Context
123
124 ueCtxt_p->setS1apEnbUeId(ue_info.s1ap_enb_ue_id);
125 ueCtxt_p->setEnbFd(ue_info.enb_fd);
126 ueCtxt_p->setTai(Tai(ue_info.tai));
127 ueCtxt_p->setUtranCgi(Cgi(ue_info.utran_cgi));
128 ueCtxt_p->setUeNetCapab(Ue_net_capab(ue_info.ue_net_capab));
129 ueCtxt_p->setMsNetCapab(Ms_net_capab(ue_info.ms_net_capab));
130 prcdCtxt_p->setPti(ue_info.pti);
131 prcdCtxt_p->setPcoOptions(ue_info.pco_options);
132 prcdCtxt_p->setEsmInfoTxRequired(ue_info.esm_info_tx_required);
133 prcdCtxt_p->setAttachType(attachType);
134
135 switch(attachType)
136 {
137 case imsiAttach_c:
138 {
139 uint8_t imsi[BINARY_IMSI_LEN] = {0};
140 memcpy( imsi, ue_info.IMSI, BINARY_IMSI_LEN );
141
142 // Only upper nibble of first octect in imsi need to be considered
143 // Changing the lower nibble to 0x0f for handling
144 uint8_t first = imsi[0] >> 4;
145 imsi[0] = (uint8_t)(( first << 4 ) | 0x0f );
146
147 DigitRegister15 IMSIInfo;
148 IMSIInfo.convertFromBcdArray(imsi);
149 ueCtxt_p->setImsi(IMSIInfo);
150
151 SubsDataGroupManager::Instance()->addimsikey(ueCtxt_p->getImsi(), ueCtxt_p->getContextID());
152
153 SM::Event evt(Event_e::VALIDATE_IMSI, NULL);
154 cb.addEventToProcQ(evt);
155
156 break;
157 }
158 case knownGutiAttach_c:
159 {
160 // copy seq num?
161
162 SM::Event evt(Event_e::VALIDATE_IMSI, NULL);
163 cb.addEventToProcQ(evt);
164
165 break;
166 }
167 case unknownGutiAttach_c:
168 {
169 SM::Event evt(Event_e::VALIDATE_IMSI, NULL);
170 cb.addEventToProcQ(evt);
171
172 break;
173 }
174 default:
175 {
176 log_msg(LOG_ERROR, "Unhandled attach type %s", attachType);
177 }
178 }
179
180 return ActStatus::PROCEED;
181}
182
183/***************************************
184* Action handler : default_detach_req_handler
185***************************************/
186ActStatus ActionHandlers::default_detach_req_handler(ControlBlock& cb)
187{
188 MmeDetachProcedureCtxt* prcdCtxt_p = SubsDataGroupManager::Instance()->getMmeDetachProcedureCtxt();
189 if( prcdCtxt_p == NULL )
190 {
191 log_msg(LOG_ERROR, "Failed to allocate procedure context for detach cbIndex %d\n", cb.getCBIndex());
192
193 return ActStatus::HALT;
194 }
195
196 prcdCtxt_p->setCtxtType( ProcedureType::detach_c );
197 prcdCtxt_p->setDetachType( DetachType::ueInitDetach_c );
198 prcdCtxt_p->setNextState(DetachStart::Instance());
199 cb.setCurrentTempDataBlock(prcdCtxt_p);
200
201 SM::Event evt(Event_e::DETACH_REQ_FROM_UE, NULL);
202 cb.addEventToProcQ(evt);
203
204 return ActStatus::PROCEED;
205}
206
207/***************************************
208* Action handler : default_ddn_handler
209***************************************/
210ActStatus ActionHandlers::default_ddn_handler(ControlBlock& cb)
211{
212 MmeSvcReqProcedureCtxt* svcReqProc_p = SubsDataGroupManager::Instance()->getMmeSvcReqProcedureCtxt();
213 if (svcReqProc_p == NULL)
214 {
215 log_msg(LOG_ERROR, "Failed to allocate procedure context"
216 " for DDN handling cbIndex %d\n", cb.getCBIndex());
217
218 return ActStatus::HALT;
219 }
220
221 MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
222
223 if (msgBuf == NULL)
224 {
225 log_msg(LOG_DEBUG,"process_ddn: msgBuf is NULL \n");
226 return ActStatus::HALT;
227 }
228
229 const gtp_incoming_msg_data_t* gtp_msg_data= static_cast<const gtp_incoming_msg_data_t*>(msgBuf->getDataPointer());
230 const struct ddn_Q_msg& ddn_info = gtp_msg_data->msg_data.ddn_Q_msg_m;
231
232 svcReqProc_p->setCtxtType(ProcedureType::serviceRequest_c);
233 svcReqProc_p->setNextState(PagingStart::Instance());
234 svcReqProc_p->setPagingTrigger(ddnInit_c);
235 svcReqProc_p->setDdnSeqNo(ddn_info.seq_no);
236 svcReqProc_p->setArp(Arp(ddn_info.arp));
237 svcReqProc_p->setEpsBearerId(ddn_info.eps_bearer_id);
238
239 cb.setCurrentTempDataBlock(svcReqProc_p);
240
241 SM::Event evt(Event_e::DDN_FROM_SGW, NULL);
242 cb.addEventToProcQ(evt);
243 return ActStatus::PROCEED;
244}
245
246/***************************************
247* Action handler : default_service_req_handler
248***************************************/
249ActStatus ActionHandlers::default_service_req_handler(ControlBlock& cb)
250{
251 MmeSvcReqProcedureCtxt* svcReqProc_p = SubsDataGroupManager::Instance()->getMmeSvcReqProcedureCtxt();
252 if (svcReqProc_p == NULL)
253 {
254 log_msg(LOG_ERROR, "Failed to allocate procedure context"
255 " for service request cbIndex %d\n", cb.getCBIndex());
256
257 return ActStatus::HALT;
258 }
259
260 svcReqProc_p->setCtxtType(ProcedureType::serviceRequest_c);
261 svcReqProc_p->setNextState(ServiceRequestStart::Instance());
262 cb.setCurrentTempDataBlock(svcReqProc_p);
263
264 SM::Event evt(Event_e::SERVICE_REQUEST_FROM_UE, NULL);
265 cb.addEventToProcQ(evt);
266
267 return ActStatus::PROCEED;
268}
269
270/***************************************
271* Action handler : default_cancel_loc_req_handler
272***************************************/
273ActStatus ActionHandlers::default_cancel_loc_req_handler(ControlBlock& cb)
274{
275 UEContext *ueCtxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
276 if (ueCtxt == NULL)
277 {
278 log_msg(LOG_DEBUG, "ue context is NULL \n");
279 return ActStatus::HALT;
280 }
281
282 MmContext* mmCtxt = ueCtxt->getMmContext();
283 if (mmCtxt == NULL)
284 {
285 log_msg(LOG_DEBUG, "mm context is NULL \n");
286 return ActStatus::HALT;
287 }
288
289 if (mmCtxt->getMmState() == EpsDetached)
290 {
291 log_msg(LOG_INFO, "Subscriber is already detached. "
292 "Cleaning up the contexts. UE IDx %d\n", cb.getCBIndex());
293
294 MmeContextManagerUtils::deleteUEContext(cb.getCBIndex());
295
296 return ActStatus::PROCEED;
297 }
298
299 MmeDetachProcedureCtxt* prcdCtxt_p = SubsDataGroupManager::Instance()->getMmeDetachProcedureCtxt();
300 if(prcdCtxt_p == NULL)
301 {
302 log_msg(LOG_ERROR, "Failed to allocate Procedure Ctxt\n");
303 return ActStatus::HALT;
304 }
305 prcdCtxt_p->setCtxtType( ProcedureType::detach_c );
306 prcdCtxt_p->setDetachType(DetachType::hssInitDetach_c);
307 prcdCtxt_p->setNextState(NiDetachStart::Instance());
308 prcdCtxt_p->setCancellationType(SUBSCRIPTION_WITHDRAWAL);
309 cb.setCurrentTempDataBlock(prcdCtxt_p);
310
311 SM::Event evt(Event_e::CLR_FROM_HSS, NULL);
312 cb.addEventToProcQ(evt);
313
314 return ActStatus::PROCEED;
315}
316
317/***************************************
318* Action handler : default_s1_release_req_handler
319***************************************/
320ActStatus ActionHandlers::default_s1_release_req_handler(ControlBlock& cb)
321{
322 MmeProcedureCtxt* prcdCtxt_p = SubsDataGroupManager::Instance()->getMmeProcedureCtxt();
323 if( prcdCtxt_p == NULL )
324 {
325 log_msg(LOG_ERROR, "Failed to allocate procedure Ctxt \n");
326 return ActStatus::HALT;
327 }
328
329 prcdCtxt_p->setCtxtType( ProcedureType::s1Release_c );
330 prcdCtxt_p->setNextState(S1ReleaseStart::Instance());
331 cb.setCurrentTempDataBlock(prcdCtxt_p);
332
333 ProcedureStats::num_of_s1_rel_req_received ++;
334
335 SM::Event evt(Event_e::S1_REL_REQ_FROM_UE, NULL);
336 cb.addEventToProcQ(evt);
337
338 return ActStatus::PROCEED;
339}
340
341/***************************************
342* Action handler : default_tau_req_handler
343***************************************/
344ActStatus ActionHandlers::default_tau_req_handler(ControlBlock& cb)
345{
346 MmeTauProcedureCtxt* tauReqProc_p = SubsDataGroupManager::Instance()->getMmeTauProcedureCtxt();
347 if (tauReqProc_p == NULL)
348 {
349 log_msg(LOG_ERROR, "Failed to allocate procedure context"
350 " for tau request cbIndex %d\n", cb.getCBIndex());
351
352 return ActStatus::HALT;
353 }
354
355 MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
356 if (msgBuf == NULL)
357 {
358 log_msg(LOG_DEBUG,"process_tau_req: msgBuf is NULL \n");
359 return ActStatus::HALT;
360 }
361
362 const s1_incoming_msg_data_t* msgData_p =
363 static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
364 if (msgData_p == NULL)
365 {
366 log_msg(LOG_ERROR, "Failed to retrieve data buffer \n");
367 return ActStatus::HALT;
368 }
369
370 const struct tauReq_Q_msg &tauReq = (msgData_p->msg_data.tauReq_Q_msg_m);
371
372 tauReqProc_p->setCtxtType(ProcedureType::tau_c);
373 tauReqProc_p->setNextState(TauStart::Instance());
374 tauReqProc_p->setS1apEnbUeId(msgData_p->s1ap_enb_ue_id);
375 tauReqProc_p->setEnbFd(tauReq.enb_fd);
376 cb.setCurrentTempDataBlock(tauReqProc_p);
377
378 SM::Event evt(Event_e::TAU_REQUEST_FROM_UE, NULL);
379 cb.addEventToProcQ(evt);
380 return ActStatus::PROCEED;
381}
382