blob: 3cbe8596f85135fe833eb00bcaa5d1bd06f68b97 [file] [log] [blame]
anjana_sreekumar@infosys.com991c2062020-01-08 11:42:57 +05301
2/*
3 * Copyright 2019-present Infosys Limited
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8/******************************************************************************
9 *
10 * This file has both generated and manual code.
11 *
12 * File template used for code generation:
13 * <TOP-DIR/scripts/SMCodeGen/templates/stateMachineTmpls/actionHandlers.cpp.tt>
14 *
15 ******************************************************************************/
16
17#include <typeinfo>
18#include "actionHandlers/actionHandlers.h"
19#include "controlBlock.h"
20#include "msgType.h"
21#include "contextManager/subsDataGroupManager.h"
22#include "contextManager/dataBlocks.h"
23#include "procedureStats.h"
24#include "log.h"
25#include "secUtils.h"
26#include "state.h"
27#include <string.h>
28#include <sstream>
29#include <smTypes.h>
30#include "common_proc_info.h"
31#include <ipcTypes.h>
32#include <tipcTypes.h>
33#include <msgBuffer.h>
34#include <interfaces/mmeIpcInterface.h>
35#include <event.h>
36#include <stateMachineEngine.h>
37#include <utils/mmeContextManagerUtils.h>
38
39using namespace mme;
40using namespace SM;
41using namespace cmn::utils;
42
43extern MmeIpcInterface* mmeIpcIf_g;
44
45/***************************************
46* Action handler :send_paging_req_to_ue
47***************************************/
48ActStatus ActionHandlers::send_paging_req_to_ue(ControlBlock& cb)
49{
50 log_msg(LOG_INFO,"Inside send_paging_req\n");
51
52 UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
53
54 if (ue_ctxt == NULL)
55 {
56 log_msg(LOG_DEBUG, "send_paging_req: ue context is NULL\n");
57 return ActStatus::HALT;
58 }
59
60 struct paging_req_Q_msg pag_req;
61 pag_req.msg_type = paging_request;
62 pag_req.ue_idx = ue_ctxt->getContextID();
63 pag_req.enb_s1ap_ue_id = ue_ctxt->getS1apEnbUeId();
64 pag_req.enb_fd = ue_ctxt->getEnbFd();
65 pag_req.cn_domain = CN_DOMAIN_PS;
66
67 const DigitRegister15& ueImsi = ue_ctxt->getImsi();
68 ueImsi.convertToBcdArray( pag_req.IMSI );
69 memcpy(&pag_req.tai, &(ue_ctxt->getTai().tai_m), sizeof(struct TAI));
70
71 cmn::ipc::IpcAddress destAddr;
72 destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c;
73 mmeIpcIf_g->dispatchIpcMsg((char *) &pag_req, sizeof(pag_req), destAddr);
74
75 ProcedureStats::num_of_ddn_received++;
76
77 log_msg(LOG_INFO,"Leaving send_paging_req\n");
78
79 return ActStatus::PROCEED;
80}
81
82/***************************************
83* Action handler : process_service_request
84***************************************/
85ActStatus ActionHandlers::process_service_request(ControlBlock& cb)
86{
87 log_msg(LOG_DEBUG, "Inside process_service_request \n");
88
89 UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
90
91 if (ue_ctxt == NULL )
92 {
93 log_msg(LOG_DEBUG, "process_service_request: ue ctxt is NULL \n");
94 return ActStatus::HALT;
95 }
96
97 log_msg(LOG_DEBUG, "Leaving process_service_request \n");
98
99 ProcedureStats::num_of_service_request_received ++;
100
101 return ActStatus::PROCEED;
102}
103
104/***************************************
105* Action handler : send_ddn_ack_to_sgw
106***************************************/
107ActStatus ActionHandlers::send_ddn_ack_to_sgw(ControlBlock& cb)
108{
109 log_msg(LOG_DEBUG, "Inside send_ddn_ack_to_sgw \n");
110
111 UEContext *ue_ctxt = static_cast<UEContext*>(cb.getPermDataBlock());
112 MmeSvcReqProcedureCtxt* srPrcdCtxt_p = dynamic_cast<MmeSvcReqProcedureCtxt*>(cb.getTempDataBlock());
113
114 if (ue_ctxt == NULL || srPrcdCtxt_p == NULL)
115 {
116 log_msg(LOG_DEBUG, "send_ddn_ack_to_sgw: ue ctxt or MmeSvcReqProcedureCtxt is NULL \n");
117 return ActStatus::HALT;
118 }
119
120 DDN_ACK_Q_msg ddn_ack;
121 ddn_ack.msg_type = ddn_acknowledgement;
122 ddn_ack.ue_idx= ue_ctxt->getContextID();
123 ddn_ack.seq_no= srPrcdCtxt_p->getDdnSeqNo();
124 ddn_ack.cause = 16;
125
126 cmn::ipc::IpcAddress destAddr;
127 destAddr.u32 = TipcServiceInstance::s11AppInstanceNum_c;
128
129 mmeIpcIf_g->dispatchIpcMsg((char *) &ddn_ack, sizeof(ddn_ack), destAddr);
130
131 log_msg(LOG_DEBUG, "Leaving send_ddn_ack_to_sgw \n");
132
133 ProcedureStats::num_of_ddn_ack_sent ++;
134
135 return ActStatus::PROCEED;
136}
137
138/***************************************
139* Action handler : perform_auth_and_sec_check
140***************************************/
141ActStatus ActionHandlers::perform_auth_and_sec_check(ControlBlock& cb)
142{
143 log_msg(LOG_DEBUG, "Inside auth_and_sec_check \n");
144 SM::ControlBlock* controlBlk_p = SubsDataGroupManager::Instance()->findControlBlock(cb.getCBIndex());
145 UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
146
147 if (ue_ctxt == NULL)
148 {
149 log_msg(LOG_DEBUG, "auth_and_sec_check: ue context is NULL\n");
150 return ActStatus::HALT;
151 }
152
153 log_msg(LOG_DEBUG, "Leaving auth_and_sec_check \n");
154
155
156 SM::Event evt(Event_e::AUTH_AND_SEC_CHECK_COMPLETE, NULL);
157
158 controlBlk_p->addEventToProcQ(evt);
159
160
161 return ActStatus::PROCEED;
162}
163/***************************************************
164* Action handler : send_init_ctxt_req_to_ue_svc_req
165****************************************************/
166ActStatus ActionHandlers::send_init_ctxt_req_to_ue_svc_req(ControlBlock& cb)
167{
168 log_msg(LOG_DEBUG, "Inside send_init_ctxt_req_to_ue_svc_req \n");
169
170 UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
171 if (ue_ctxt == NULL )
172 {
173 log_msg(LOG_DEBUG, "send_init_ctxt_req_to_ue_svc_req : ue context is NULL \n");
174 return ActStatus::HALT;
175 }
176
177 SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
178 if (sessionCtxt == NULL)
179 {
180 log_msg(LOG_DEBUG, "send_init_ctxt_req_to_ue_svc_req : session ctxt is NULL \n");
181 return ActStatus::HALT;
182 }
183
184 unsigned int nas_count = 0;
185 E_UTRAN_sec_vector* secVect = const_cast<E_UTRAN_sec_vector*>(ue_ctxt->getAiaSecInfo().AiaSecInfo_mp);
186 secinfo& secInfo = const_cast<secinfo&>(ue_ctxt->getUeSecInfo().secinfo_m);
187
188 SecUtils::create_kenb_key(secVect->kasme.val, secInfo.kenb_key, nas_count);
189
190 ics_req_paging_Q_msg icr_msg;
191 icr_msg.msg_type = ics_req_paging;
192 icr_msg.ue_idx = ue_ctxt->getContextID();
193 icr_msg.enb_fd = ue_ctxt->getEnbFd();
194 icr_msg.enb_s1ap_ue_id = ue_ctxt->getS1apEnbUeId();
195
196 icr_msg.ueag_max_ul_bitrate = (ue_ctxt->getAmbr().ambr_m).max_requested_bw_dl;
197 icr_msg.ueag_max_dl_bitrate = (ue_ctxt->getAmbr().ambr_m).max_requested_bw_ul;
198 BearerContext* bearerCtxt = sessionCtxt->getBearerContext();
199 icr_msg.bearer_id = bearerCtxt->getBearerId();
200
201
202 memcpy(&(icr_msg.gtp_teid), &(bearerCtxt->getS1uSgwUserFteid().fteid_m), sizeof(struct fteid));
203 memcpy(&(icr_msg.sec_key), &((ue_ctxt->getUeSecInfo().secinfo_m).kenb_key),
204 KENB_SIZE);
205
206 //ue_ctxt->setdwnLnkSeqNo(icr_msg.dl_seq_no+1);
207
208 cmn::ipc::IpcAddress destAddr;
209 destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c;
210
211 mmeIpcIf_g->dispatchIpcMsg((char *) &icr_msg, sizeof(icr_msg), destAddr);
212
213 ProcedureStats::num_of_init_ctxt_req_to_ue_sent ++;
214 log_msg(LOG_DEBUG, "Leaving send_init_ctxt_req_to_ue_svc_req_ \n");
215
216 return ActStatus::PROCEED;
217}
218
219/***************************************
220* Action handler : process_init_ctxt_resp_svc_req
221***************************************/
222ActStatus ActionHandlers::process_init_ctxt_resp_svc_req(ControlBlock& cb)
223{
224 log_msg(LOG_DEBUG, "Inside process_init_ctxt_resp_svc_req \n");
225
226 UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
227 MmeProcedureCtxt *procCtxt = dynamic_cast<MmeProcedureCtxt*>(cb.getTempDataBlock());
228
229 if (ue_ctxt == NULL || procCtxt == NULL)
230 {
231 log_msg(LOG_DEBUG, "process_init_ctxt_resp_svc_req: ue context or procedure ctxt is NULL \n");
232 return ActStatus::HALT;
233 }
234
235 SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
236 if (sessionCtxt == NULL)
237 {
238 log_msg(LOG_DEBUG, "process_init_ctxt_resp_svc_req: session ctxt is NULL \n");
239 return ActStatus::HALT;
240 }
241
242 MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData());
243
244 if (msgBuf == NULL)
245 return ActStatus::HALT;
246
247 const s1_incoming_msg_data_t* s1_msg_data = static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer());
248 const struct initctx_resp_Q_msg &ics_res =s1_msg_data->msg_data.initctx_resp_Q_msg_m;
249
250 fteid S1uEnbUserFteid;
251 S1uEnbUserFteid.header.iface_type = 0;
252 S1uEnbUserFteid.header.v4 = 1;
253 S1uEnbUserFteid.header.teid_gre = ics_res.gtp_teid;
254 S1uEnbUserFteid.ip.ipv4 = *(struct in_addr*)&ics_res.transp_layer_addr;
255
256 BearerContext* bearerCtxt = sessionCtxt->getBearerContext();
257 if (bearerCtxt)
258 bearerCtxt->setS1uEnbUserFteid(Fteid(S1uEnbUserFteid));
259
260 ProcedureStats::num_of_processed_init_ctxt_resp ++;
261 log_msg(LOG_DEBUG, "Leaving process_init_ctxt_resp_svc_req \n");
262
263 return ActStatus::PROCEED;
264}
265
266
267/***************************************
268* Action handler : send_mb_req_to_sgw_svc_req
269***************************************/
270ActStatus ActionHandlers::send_mb_req_to_sgw_svc_req(ControlBlock& cb)
271{
272 log_msg(LOG_DEBUG, "Inside send_mb_req_to_sgw_svc_req \n");
273
274 UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock());
275 MmeProcedureCtxt *procCtxt = dynamic_cast<MmeProcedureCtxt*>(cb.getTempDataBlock());
276
277 if (ue_ctxt == NULL || procCtxt == NULL)
278 {
279 log_msg(LOG_DEBUG, "send_mb_req_to_sgw_svc_req: ue context or procedure ctxt is NULL \n");
280 return ActStatus::HALT;
281 }
282
283 SessionContext* sessionCtxt = ue_ctxt->getSessionContext();
284 if (sessionCtxt == NULL)
285 {
286 log_msg(LOG_DEBUG, "send_mb_req_to_sgw_svc_req: session ctxt is NULL \n");
287 return ActStatus::HALT;
288 }
289
290 struct MB_Q_msg mb_msg;
291 mb_msg.msg_type = modify_bearer_request;
292 mb_msg.ue_idx = ue_ctxt->getContextID();
293
294 memset(mb_msg.indication, 0, S11_MB_INDICATION_FLAG_SIZE); /*TODO : future*/
295 BearerContext* bearerCtxt = sessionCtxt->getBearerContext();
296 mb_msg.bearer_id = bearerCtxt->getBearerId();
297
298 memcpy(&(mb_msg.s11_sgw_c_fteid), &(sessionCtxt->getS11SgwCtrlFteid().fteid_m),
299 sizeof(struct fteid));
300
301 memcpy(&(mb_msg.s1u_enb_fteid), &(bearerCtxt->getS1uEnbUserFteid().fteid_m),
302 sizeof(struct fteid));
303
304
305 cmn::ipc::IpcAddress destAddr;
306 destAddr.u32 = TipcServiceInstance::s11AppInstanceNum_c;
307
308 mmeIpcIf_g->dispatchIpcMsg((char *) &mb_msg, sizeof(mb_msg), destAddr);
309
310 ProcedureStats::num_of_mb_req_to_sgw_sent ++;
311 log_msg(LOG_DEBUG, "Leaving send_mb_req_to_sgw_svc_req \n");
312
313 return ActStatus::PROCEED;
314}
315
316/***************************************
317* Action handler : process_mb_resp_svc_req
318***************************************/
319ActStatus ActionHandlers::process_mb_resp_svc_req(ControlBlock& cb)
320{
321 log_msg(LOG_DEBUG, "Inside process_mb_resp_svc_req \n");
322
323 ProcedureStats::num_of_processed_mb_resp ++;
324
325 MmeContextManagerUtils::deallocateProcedureCtxt(cb, serviceRequest_c);
326
327 return ActStatus::PROCEED;
328}