| |
| /* |
| * Copyright 2019-present Infosys Limited |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /****************************************************************************** |
| * |
| * This file has both generated and manual code. |
| * |
| * File template used for code generation: |
| * <TOP-DIR/scripts/SMCodeGen/templates/stateMachineTmpls/actionHandlers.cpp.tt> |
| * |
| ******************************************************************************/ |
| |
| #include <typeinfo> |
| #include "actionHandlers/actionHandlers.h" |
| #include "controlBlock.h" |
| #include "msgType.h" |
| #include "contextManager/subsDataGroupManager.h" |
| #include "contextManager/dataBlocks.h" |
| #include "procedureStats.h" |
| #include "log.h" |
| #include "secUtils.h" |
| #include "state.h" |
| #include <string.h> |
| #include <sstream> |
| #include <smTypes.h> |
| #include "common_proc_info.h" |
| #include <ipcTypes.h> |
| #include <tipcTypes.h> |
| #include <msgBuffer.h> |
| #include <interfaces/mmeIpcInterface.h> |
| #include <event.h> |
| #include <stateMachineEngine.h> |
| #include <utils/mmeContextManagerUtils.h> |
| |
| using namespace mme; |
| using namespace SM; |
| using namespace cmn::utils; |
| |
| extern MmeIpcInterface* mmeIpcIf_g; |
| |
| /*************************************** |
| * Action handler :send_paging_req_to_ue |
| ***************************************/ |
| ActStatus ActionHandlers::send_paging_req_to_ue(ControlBlock& cb) |
| { |
| log_msg(LOG_INFO,"Inside send_paging_req\n"); |
| |
| UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock()); |
| |
| if (ue_ctxt == NULL) |
| { |
| log_msg(LOG_DEBUG, "send_paging_req: ue context is NULL\n"); |
| return ActStatus::HALT; |
| } |
| |
| struct paging_req_Q_msg pag_req; |
| pag_req.msg_type = paging_request; |
| pag_req.ue_idx = ue_ctxt->getContextID(); |
| pag_req.enb_s1ap_ue_id = ue_ctxt->getS1apEnbUeId(); |
| pag_req.enb_fd = ue_ctxt->getEnbFd(); |
| pag_req.cn_domain = CN_DOMAIN_PS; |
| |
| const DigitRegister15& ueImsi = ue_ctxt->getImsi(); |
| ueImsi.convertToBcdArray( pag_req.IMSI ); |
| memcpy(&pag_req.tai, &(ue_ctxt->getTai().tai_m), sizeof(struct TAI)); |
| |
| cmn::ipc::IpcAddress destAddr; |
| destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c; |
| mmeIpcIf_g->dispatchIpcMsg((char *) &pag_req, sizeof(pag_req), destAddr); |
| |
| ProcedureStats::num_of_ddn_received++; |
| |
| log_msg(LOG_INFO,"Leaving send_paging_req\n"); |
| |
| return ActStatus::PROCEED; |
| } |
| |
| /*************************************** |
| * Action handler : process_service_request |
| ***************************************/ |
| ActStatus ActionHandlers::process_service_request(ControlBlock& cb) |
| { |
| log_msg(LOG_DEBUG, "Inside process_service_request \n"); |
| |
| UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock()); |
| |
| if (ue_ctxt == NULL ) |
| { |
| log_msg(LOG_DEBUG, "process_service_request: ue ctxt is NULL \n"); |
| return ActStatus::HALT; |
| } |
| |
| log_msg(LOG_DEBUG, "Leaving process_service_request \n"); |
| |
| ProcedureStats::num_of_service_request_received ++; |
| |
| return ActStatus::PROCEED; |
| } |
| |
| /*************************************** |
| * Action handler : send_ddn_ack_to_sgw |
| ***************************************/ |
| ActStatus ActionHandlers::send_ddn_ack_to_sgw(ControlBlock& cb) |
| { |
| log_msg(LOG_DEBUG, "Inside send_ddn_ack_to_sgw \n"); |
| |
| UEContext *ue_ctxt = static_cast<UEContext*>(cb.getPermDataBlock()); |
| MmeSvcReqProcedureCtxt* srPrcdCtxt_p = dynamic_cast<MmeSvcReqProcedureCtxt*>(cb.getTempDataBlock()); |
| |
| if (ue_ctxt == NULL || srPrcdCtxt_p == NULL) |
| { |
| log_msg(LOG_DEBUG, "send_ddn_ack_to_sgw: ue ctxt or MmeSvcReqProcedureCtxt is NULL \n"); |
| return ActStatus::HALT; |
| } |
| |
| DDN_ACK_Q_msg ddn_ack; |
| ddn_ack.msg_type = ddn_acknowledgement; |
| ddn_ack.ue_idx= ue_ctxt->getContextID(); |
| ddn_ack.seq_no= srPrcdCtxt_p->getDdnSeqNo(); |
| ddn_ack.cause = 16; |
| |
| cmn::ipc::IpcAddress destAddr; |
| destAddr.u32 = TipcServiceInstance::s11AppInstanceNum_c; |
| |
| mmeIpcIf_g->dispatchIpcMsg((char *) &ddn_ack, sizeof(ddn_ack), destAddr); |
| |
| log_msg(LOG_DEBUG, "Leaving send_ddn_ack_to_sgw \n"); |
| |
| ProcedureStats::num_of_ddn_ack_sent ++; |
| |
| return ActStatus::PROCEED; |
| } |
| |
| /*************************************** |
| * Action handler : perform_auth_and_sec_check |
| ***************************************/ |
| ActStatus ActionHandlers::perform_auth_and_sec_check(ControlBlock& cb) |
| { |
| log_msg(LOG_DEBUG, "Inside auth_and_sec_check \n"); |
| SM::ControlBlock* controlBlk_p = SubsDataGroupManager::Instance()->findControlBlock(cb.getCBIndex()); |
| UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock()); |
| |
| if (ue_ctxt == NULL) |
| { |
| log_msg(LOG_DEBUG, "auth_and_sec_check: ue context is NULL\n"); |
| return ActStatus::HALT; |
| } |
| |
| log_msg(LOG_DEBUG, "Leaving auth_and_sec_check \n"); |
| |
| |
| SM::Event evt(Event_e::AUTH_AND_SEC_CHECK_COMPLETE, NULL); |
| |
| controlBlk_p->addEventToProcQ(evt); |
| |
| |
| return ActStatus::PROCEED; |
| } |
| /*************************************************** |
| * Action handler : send_init_ctxt_req_to_ue_svc_req |
| ****************************************************/ |
| ActStatus ActionHandlers::send_init_ctxt_req_to_ue_svc_req(ControlBlock& cb) |
| { |
| log_msg(LOG_DEBUG, "Inside send_init_ctxt_req_to_ue_svc_req \n"); |
| |
| UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock()); |
| if (ue_ctxt == NULL ) |
| { |
| log_msg(LOG_DEBUG, "send_init_ctxt_req_to_ue_svc_req : ue context is NULL \n"); |
| return ActStatus::HALT; |
| } |
| |
| SessionContext* sessionCtxt = ue_ctxt->getSessionContext(); |
| if (sessionCtxt == NULL) |
| { |
| log_msg(LOG_DEBUG, "send_init_ctxt_req_to_ue_svc_req : session ctxt is NULL \n"); |
| return ActStatus::HALT; |
| } |
| |
| unsigned int nas_count = 0; |
| E_UTRAN_sec_vector* secVect = const_cast<E_UTRAN_sec_vector*>(ue_ctxt->getAiaSecInfo().AiaSecInfo_mp); |
| secinfo& secInfo = const_cast<secinfo&>(ue_ctxt->getUeSecInfo().secinfo_m); |
| |
| SecUtils::create_kenb_key(secVect->kasme.val, secInfo.kenb_key, nas_count); |
| |
| ics_req_paging_Q_msg icr_msg; |
| icr_msg.msg_type = ics_req_paging; |
| icr_msg.ue_idx = ue_ctxt->getContextID(); |
| icr_msg.enb_fd = ue_ctxt->getEnbFd(); |
| icr_msg.enb_s1ap_ue_id = ue_ctxt->getS1apEnbUeId(); |
| |
| icr_msg.ueag_max_ul_bitrate = (ue_ctxt->getAmbr().ambr_m).max_requested_bw_dl; |
| icr_msg.ueag_max_dl_bitrate = (ue_ctxt->getAmbr().ambr_m).max_requested_bw_ul; |
| BearerContext* bearerCtxt = sessionCtxt->getBearerContext(); |
| icr_msg.bearer_id = bearerCtxt->getBearerId(); |
| |
| |
| memcpy(&(icr_msg.gtp_teid), &(bearerCtxt->getS1uSgwUserFteid().fteid_m), sizeof(struct fteid)); |
| memcpy(&(icr_msg.sec_key), &((ue_ctxt->getUeSecInfo().secinfo_m).kenb_key), |
| KENB_SIZE); |
| |
| //ue_ctxt->setdwnLnkSeqNo(icr_msg.dl_seq_no+1); |
| |
| cmn::ipc::IpcAddress destAddr; |
| destAddr.u32 = TipcServiceInstance::s1apAppInstanceNum_c; |
| |
| mmeIpcIf_g->dispatchIpcMsg((char *) &icr_msg, sizeof(icr_msg), destAddr); |
| |
| ProcedureStats::num_of_init_ctxt_req_to_ue_sent ++; |
| log_msg(LOG_DEBUG, "Leaving send_init_ctxt_req_to_ue_svc_req_ \n"); |
| |
| return ActStatus::PROCEED; |
| } |
| |
| /*************************************** |
| * Action handler : process_init_ctxt_resp_svc_req |
| ***************************************/ |
| ActStatus ActionHandlers::process_init_ctxt_resp_svc_req(ControlBlock& cb) |
| { |
| log_msg(LOG_DEBUG, "Inside process_init_ctxt_resp_svc_req \n"); |
| |
| UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock()); |
| MmeProcedureCtxt *procCtxt = dynamic_cast<MmeProcedureCtxt*>(cb.getTempDataBlock()); |
| |
| if (ue_ctxt == NULL || procCtxt == NULL) |
| { |
| log_msg(LOG_DEBUG, "process_init_ctxt_resp_svc_req: ue context or procedure ctxt is NULL \n"); |
| return ActStatus::HALT; |
| } |
| |
| SessionContext* sessionCtxt = ue_ctxt->getSessionContext(); |
| if (sessionCtxt == NULL) |
| { |
| log_msg(LOG_DEBUG, "process_init_ctxt_resp_svc_req: session ctxt is NULL \n"); |
| return ActStatus::HALT; |
| } |
| |
| MsgBuffer* msgBuf = static_cast<MsgBuffer*>(cb.getMsgData()); |
| |
| if (msgBuf == NULL) |
| return ActStatus::HALT; |
| |
| const s1_incoming_msg_data_t* s1_msg_data = static_cast<const s1_incoming_msg_data_t*>(msgBuf->getDataPointer()); |
| const struct initctx_resp_Q_msg &ics_res =s1_msg_data->msg_data.initctx_resp_Q_msg_m; |
| |
| fteid S1uEnbUserFteid; |
| S1uEnbUserFteid.header.iface_type = 0; |
| S1uEnbUserFteid.header.v4 = 1; |
| S1uEnbUserFteid.header.teid_gre = ics_res.gtp_teid; |
| S1uEnbUserFteid.ip.ipv4 = *(struct in_addr*)&ics_res.transp_layer_addr; |
| |
| BearerContext* bearerCtxt = sessionCtxt->getBearerContext(); |
| if (bearerCtxt) |
| bearerCtxt->setS1uEnbUserFteid(Fteid(S1uEnbUserFteid)); |
| |
| ProcedureStats::num_of_processed_init_ctxt_resp ++; |
| log_msg(LOG_DEBUG, "Leaving process_init_ctxt_resp_svc_req \n"); |
| |
| return ActStatus::PROCEED; |
| } |
| |
| |
| /*************************************** |
| * Action handler : send_mb_req_to_sgw_svc_req |
| ***************************************/ |
| ActStatus ActionHandlers::send_mb_req_to_sgw_svc_req(ControlBlock& cb) |
| { |
| log_msg(LOG_DEBUG, "Inside send_mb_req_to_sgw_svc_req \n"); |
| |
| UEContext *ue_ctxt = dynamic_cast<UEContext*>(cb.getPermDataBlock()); |
| MmeProcedureCtxt *procCtxt = dynamic_cast<MmeProcedureCtxt*>(cb.getTempDataBlock()); |
| |
| if (ue_ctxt == NULL || procCtxt == NULL) |
| { |
| log_msg(LOG_DEBUG, "send_mb_req_to_sgw_svc_req: ue context or procedure ctxt is NULL \n"); |
| return ActStatus::HALT; |
| } |
| |
| SessionContext* sessionCtxt = ue_ctxt->getSessionContext(); |
| if (sessionCtxt == NULL) |
| { |
| log_msg(LOG_DEBUG, "send_mb_req_to_sgw_svc_req: session ctxt is NULL \n"); |
| return ActStatus::HALT; |
| } |
| |
| struct MB_Q_msg mb_msg; |
| mb_msg.msg_type = modify_bearer_request; |
| mb_msg.ue_idx = ue_ctxt->getContextID(); |
| |
| memset(mb_msg.indication, 0, S11_MB_INDICATION_FLAG_SIZE); /*TODO : future*/ |
| BearerContext* bearerCtxt = sessionCtxt->getBearerContext(); |
| mb_msg.bearer_id = bearerCtxt->getBearerId(); |
| |
| memcpy(&(mb_msg.s11_sgw_c_fteid), &(sessionCtxt->getS11SgwCtrlFteid().fteid_m), |
| sizeof(struct fteid)); |
| |
| memcpy(&(mb_msg.s1u_enb_fteid), &(bearerCtxt->getS1uEnbUserFteid().fteid_m), |
| sizeof(struct fteid)); |
| |
| |
| cmn::ipc::IpcAddress destAddr; |
| destAddr.u32 = TipcServiceInstance::s11AppInstanceNum_c; |
| |
| mmeIpcIf_g->dispatchIpcMsg((char *) &mb_msg, sizeof(mb_msg), destAddr); |
| |
| ProcedureStats::num_of_mb_req_to_sgw_sent ++; |
| log_msg(LOG_DEBUG, "Leaving send_mb_req_to_sgw_svc_req \n"); |
| |
| return ActStatus::PROCEED; |
| } |
| |
| /*************************************** |
| * Action handler : process_mb_resp_svc_req |
| ***************************************/ |
| ActStatus ActionHandlers::process_mb_resp_svc_req(ControlBlock& cb) |
| { |
| log_msg(LOG_DEBUG, "Inside process_mb_resp_svc_req \n"); |
| |
| ProcedureStats::num_of_processed_mb_resp ++; |
| |
| MmeContextManagerUtils::deallocateProcedureCtxt(cb, serviceRequest_c); |
| |
| return ActStatus::PROCEED; |
| } |