| /////////////////////////////////////////////////////////////////////////////// |
| // Copyright (c) 2000-2018 Ericsson Telecom AB |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v2.0 |
| // which accompanies this distribution, and is available at |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // File: SGsAP_SCTP_Daemon.ttcn |
| // Description: SGsAP SDD behavior |
| // Rev: <RnXnn> |
| // Prodnr: CNL 113 630 |
| // Updated: 2010-10-20 |
| // Contact: http://ttcn.ericsson.se |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| module SGsAP_SCTP_Daemon |
| |
| { |
| |
| //========================================================================= |
| // Import Part |
| //========================================================================= |
| |
| import from SGsAP_SCTP_Daemon_Types all; |
| import from SGsAP_Types all; |
| import from SCTP_Daemon_Dynamic all; |
| import from SCTP_Daemon_Dynamic_Types all; |
| import from EPTF_CLL_HashMapStr2Int_Functions all; |
| import from EPTF_CLL_HashMapInt2Int_Functions all; |
| import from EPTF_CLL_FBQ_Definitions all; |
| import from EPTF_CLL_FBQ_Functions all; |
| |
| |
| modulepar |
| { |
| boolean tsp_SGsAP_enableDebug := false; |
| } |
| |
| const charstring c_SGsAP_HashMap_Imsi2ConnDbIdx := "SGsAP_hashmap_imsi_connDbIdx"; |
| const charstring c_SGsAP_HashMap_ConnDbIdx2ConnId := "SGsAP_hashmap_connDbIdx_connId" |
| |
| //========================================================================= |
| // Functions |
| //========================================================================= |
| |
| function f_getIMSI_fromSGSAP(in octetstring pl_data, out charstring vl_imsi) |
| return boolean |
| { |
| f_SGsAP_debugLog(log2str(%definitionId, " enter")); |
| |
| var PDU_SGsAP vl_PDU_SGsAP:=dec_PDU_SGsAP(pl_data); |
| var boolean vl_ret := true; |
| |
| if (ischosen(vl_PDU_SGsAP.sGsAP_ALERT_ACK)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_ALERT_ACK.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_ALERT_REJECT)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_ALERT_REJECT.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_ALERT_REQUEST)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_ALERT_REQUEST.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_DOWNLINK_UNITDATA)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_DOWNLINK_UNITDATA.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_EPS_DETACH_ACK)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_EPS_DETACH_ACK.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_EPS_DETACH_INDICATION)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_EPS_DETACH_INDICATION.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_IMSI_DETACH_ACK)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_IMSI_DETACH_ACK.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_IMSI_DETACH_INDICATION)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_IMSI_DETACH_INDICATION.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_ACCEPT)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_ACCEPT.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_REJECT)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_REJECT.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_REQUEST)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_LOCATION_UPDATE_REQUEST.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_MM_INFORMATION_REQUEST)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_MM_INFORMATION_REQUEST.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_PAGING_REJECT)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_PAGING_REJECT.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_PAGING_REQUEST)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_PAGING_REQUEST.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_SERVICE_REQUEST)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_SERVICE_REQUEST.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_STATUS)) |
| { |
| if (ispresent(vl_PDU_SGsAP.sGsAP_STATUS.iMSI)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_STATUS.iMSI.iMSI.digits) } |
| else |
| { vl_ret := false; } |
| } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_TMSI_REALLOCATION_COMPLETE)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_TMSI_REALLOCATION_COMPLETE.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_UE_ACTIVITY_INDICATION)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_UE_ACTIVITY_INDICATION.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_UE_UNREACHABLE)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_UE_UNREACHABLE.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_UPLINK_UNITDATA)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_UPLINK_UNITDATA.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_RELEASE_REQUEST)) |
| { vl_imsi := hex2str(vl_PDU_SGsAP.sGsAP_RELEASE_REQUEST.iMSI.iMSI.digits) } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_RESET_ACK)) |
| { vl_ret := false } |
| else if (ischosen(vl_PDU_SGsAP.sGsAP_RESET_INDICATION)) |
| { vl_ret := false } |
| else |
| { |
| vl_ret := false; |
| log(%definitionId, " WARNING: Cannot fetch IMSI from SGsAP PDU: ", vl_PDU_SGsAP); |
| } |
| |
| f_SGsAP_debugLog(log2str(%definitionId, " returns: ", vl_ret)); |
| |
| return vl_ret; |
| } |
| |
| function f_SGsAP_SDD_getAllConnIds() |
| runs on SGsAP_SDD_CT |
| return TCP_connections_List |
| { |
| f_SGsAP_debugLog(log2str(%definitionId, " enter")); |
| |
| var TCP_connections_List vl_list := {}; |
| var integer vl_idx := -1; |
| |
| if (f_EPTF_FBQ_getBusyHeadIdx(vl_idx, v_connDB.queue)) |
| { |
| vl_list[sizeof(vl_list)] := v_connDB.data[vl_idx].connId; |
| while(f_EPTF_FBQ_getFwdBusyItemIdx(vl_idx, v_connDB.queue)) |
| { |
| vl_list[sizeof(vl_list)] := v_connDB.data[vl_idx].connId; |
| } |
| } |
| |
| f_SGsAP_debugLog(log2str(%definitionId, " finished: ", vl_list)); |
| |
| return vl_list; |
| } |
| |
| function f_SGsAP_SDD_Insert(octetstring pl_data, integer pl_id) runs on SGsAP_SDD_CT |
| { |
| f_SGsAP_debugLog(log2str(%definitionId, " enter")); |
| |
| var charstring vl_imsi := ""; |
| var integer vl_connDbIdx := -1; |
| var integer vl_lookedUpConnDbIdx := -1; |
| |
| if (f_getIMSI_fromSGSAP(pl_data, vl_imsi)) |
| { |
| if (not f_EPTF_int2int_HashMap_Find(v_connDB.hashRef, pl_id, vl_connDbIdx)) |
| { |
| vl_connDbIdx := f_EPTF_FBQ_getOrCreateFreeSlot(v_connDB.queue); |
| v_connDB.data[vl_connDbIdx] := ConnectionEntry_empty; |
| v_connDB.data[vl_connDbIdx].connId := pl_id; |
| |
| f_EPTF_int2int_HashMap_Insert(v_connDB.hashRef, pl_id, vl_connDbIdx); |
| |
| f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_connDB.queue); |
| } |
| |
| if (not f_EPTF_str2int_HashMap_Find(v_imsi2connDbIdx, vl_imsi, vl_lookedUpConnDbIdx) or vl_connDbIdx != vl_lookedUpConnDbIdx) |
| { |
| v_connDB.data[vl_connDbIdx].imsiList[sizeof(v_connDB.data[vl_connDbIdx].imsiList)] := vl_imsi; |
| f_EPTF_str2int_HashMap_Insert(v_imsi2connDbIdx, vl_imsi, vl_connDbIdx); |
| } |
| } |
| |
| f_SGsAP_debugLog(log2str(%definitionId, " finished")); |
| } |
| |
| function f_SGsAP_SDD_Lookup(octetstring pl_data) runs on SGsAP_SDD_CT |
| return TCP_connections_List |
| { |
| f_SGsAP_debugLog(log2str(%definitionId, " enter")); |
| |
| var TCP_connections_List vl_list := {}; |
| var charstring vl_imsi := ""; |
| var integer vl_connDbIdx := -1; |
| |
| if (f_getIMSI_fromSGSAP(pl_data, vl_imsi)) |
| { |
| if (f_EPTF_str2int_HashMap_Find(v_imsi2connDbIdx, vl_imsi, vl_connDbIdx)) |
| { |
| vl_list := { v_connDB.data[vl_connDbIdx].connId } |
| } |
| else { log(%definitionId, "IMSI: ",vl_imsi," wasn't found in the SGsAP routing table: Dropping!"); } |
| } |
| else |
| { |
| vl_list := f_SGsAP_SDD_getAllConnIds(); |
| } |
| |
| f_SGsAP_debugLog(log2str(%definitionId, " returns: ", vl_list)); |
| |
| return vl_list; |
| } |
| |
| function f_SGsAP_SDD_Delete(integer pl_id) runs on SGsAP_SDD_CT |
| { |
| f_SGsAP_debugLog(log2str(%definitionId, " enter")); |
| |
| var integer vl_connDbIdx := -1; |
| |
| if (f_EPTF_int2int_HashMap_Find(v_connDB.hashRef, pl_id, vl_connDbIdx)) |
| { |
| // Removing IMSI->ConnDbIdx mappings |
| for (var integer i:=0; i<sizeof(v_connDB.data[vl_connDbIdx].imsiList); i:=i+1) |
| { |
| var integer vl_imsiConn := -1; |
| if (f_EPTF_str2int_HashMap_Find(v_imsi2connDbIdx, v_connDB.data[vl_connDbIdx].imsiList[i], vl_imsiConn)) |
| { |
| if (vl_imsiConn == vl_connDbIdx) { f_EPTF_str2int_HashMap_Erase(v_imsi2connDbIdx, v_connDB.data[vl_connDbIdx].imsiList[i]); } |
| else |
| { |
| // IMSI is already on an other connection |
| } |
| } |
| } |
| |
| f_EPTF_int2int_HashMap_Erase(v_connDB.hashRef, pl_id); |
| |
| if (f_EPTF_FBQ_itemIsBusy(vl_connDbIdx, v_connDB.queue)) |
| { |
| f_EPTF_FBQ_moveFromBusyToFreeTail(vl_connDbIdx, v_connDB.queue); |
| } |
| } |
| |
| f_SGsAP_debugLog(log2str(%definitionId, " finished")); |
| } |
| |
| function f_SGsAP_SDD_init() runs on SGsAP_SDD_CT |
| { |
| f_SGsAP_debugLog(log2str(%definitionId, " enter")); |
| |
| f_EPTF_str2int_HashMap_Init(); |
| f_EPTF_int2int_HashMap_Init(); |
| |
| v_imsi2connDbIdx := f_EPTF_str2int_HashMap_New(c_SGsAP_HashMap_Imsi2ConnDbIdx); |
| |
| v_connDB.hashRef := f_EPTF_int2int_HashMap_New(c_SGsAP_HashMap_ConnDbIdx2ConnId); |
| v_connDB.data := {}; |
| v_connDB.queue := c_EPTF_emptyFreeBusyQueue; |
| |
| f_EPTF_FBQ_initFreeBusyQueue(v_connDB.queue); |
| |
| v_Connection_Insert:=refers(f_SGsAP_SDD_Insert); |
| v_Connection_Lookup:=refers(f_SGsAP_SDD_Lookup); |
| v_Connection_Delete:=refers(f_SGsAP_SDD_Delete); |
| |
| f_SGsAP_debugLog(log2str(%definitionId, " finished")); |
| } |
| |
| function f_SGsAP_SDD_cleanUp() runs on SGsAP_SDD_CT |
| { |
| f_SGsAP_debugLog(log2str(%definitionId, " enter")); |
| |
| f_EPTF_str2int_HashMap_Delete(c_SGsAP_HashMap_Imsi2ConnDbIdx); |
| f_EPTF_int2int_HashMap_Delete(c_SGsAP_HashMap_ConnDbIdx2ConnId); |
| |
| f_SGsAP_debugLog(log2str(%definitionId, " finished")); |
| } |
| |
| function f_SGsAP_debugLog(in charstring p_log) |
| { |
| if (tsp_SGsAP_enableDebug) { log(p_log); } |
| } |
| |
| testcase tc_SGsAP_SDD() runs on SGsAP_SDD_CT |
| { |
| f_SGsAP_SDD_init(); |
| |
| f_SDD(); |
| |
| f_SGsAP_SDD_cleanUp(); |
| } |
| |
| //========================================================================= |
| // Control |
| //========================================================================= |
| |
| control |
| { |
| execute(tc_SGsAP_SDD()); |
| } |
| |
| } // end of module |