diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index 758ee97981e26c960be3ee4d81b3c49001e7a2cb..4ac46e84b548978b282016cf70b2f3641c9cdf8e 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -48,6 +48,9 @@ #include "hashtable.h" #include "asn_compare.h" +#define ET_XPATH_EXPRESSION_MAX_LENGTH 400 + + // powers of 2 #define ET_BIT_MASK_MATCH_SCTP_STREAM 1 #define ET_BIT_MASK_MATCH_SCTP_SSN 2 @@ -252,7 +255,7 @@ typedef struct et_s1ap_s { uint16_t binary_stream_allocated_size; uint8_t *binary_stream; s1ap_message message; // decoded message: information elements - xmlNodePtr xml_node; // XML representation of the S1AP PDU + xmlDocPtr doc; // XML representation of the S1AP PDU } et_s1ap_t; diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 35ed5c860367275c513b6cf4bb02d692fe916a89..b9d24f366c0d2237cc7a42efaaf1932c357ca08f 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -70,9 +70,12 @@ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * co unsigned int go_deeper_in_tree = 1; if ((NULL != s1ap_node) && (NULL != s1ap)) { - // seee http://www.xmlsoft.org/html/libxml-tree.html#xmlCopyNode - s1ap->xml_node = xmlCopyNode(s1ap_node, 1); - AssertFatal(NULL != s1ap->xml_node, "xmlCopyNode Failed"); + // see http://www.xmlsoft.org/html/libxml-tree.html#xmlCopyNode + cur_node = xmlCopyNode(s1ap_node, 1); + AssertFatal(NULL != cur_node, "xmlCopyNode Failed"); + s1ap->doc = xmlNewDoc(BAD_CAST "1.0"); + xmlDocSetRootElement(s1ap->doc, cur_node); + for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) { go_deeper_in_tree = 1; if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c index 3533ee086e272568e63e69beb45cc816d9dabdfd..87ffe29e322b1758b69828de72e3a9f5dee78e69 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -40,6 +40,10 @@ #include <stdint.h> #include <unistd.h> #include <crypt.h> +#include <libxml/tree.h> +#include <libxml/parser.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> #include "tree.h" #include "queue.h" @@ -452,353 +456,146 @@ asn_comp_rval_t * et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_messag return ret; } -//------------------------------------------------------------------------------ -int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_S1AP_ID_t old_id, const S1ap_MME_UE_S1AP_ID_t new_id) -{ - S1ap_MME_UE_S1AP_ID_t mme_ue_s1ap_id = 0; - S1AP_PDU_PR present; - ssize_t encoded; - - present = packet->sctp_hdr.u.data_hdr.payload.pdu.present; - - S1AP_DEBUG("Updating mme_ue_s1ap_id of packet num %d...\n", packet->packet_number); - - switch (packet->sctp_hdr.u.data_hdr.payload.message.procedureCode) { - case S1ap_ProcedureCode_id_HandoverPreparation: - if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs.mme_ue_s1ap_id; - if (old_id == mme_ue_s1ap_id) { - packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs.mme_ue_s1ap_id = new_id; - // re-encode - S1ap_HandoverRequired_t msg; - S1ap_HandoverRequired_t *msg_p = &msg; - memset((void *)msg_p, 0, sizeof(msg)); - - if (s1ap_encode_s1ap_handoverrequiredies( - msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs) < 0) { - AssertFatal(0, "Re-encoding handoverrequiredies failed"); - } - - ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, - &asn_DEF_S1ap_HandoverRequired, - &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs); - - packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequiredIEs; - encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, - (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); - AssertFatal(encoded < 0, "Re-encoding PDU failed"); - } - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverCommandIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_HandoverResourceAllocation: - if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_successfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverRequestAcknowledgeIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverFailureIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_HandoverNotification: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverNotifyIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_PathSwitchRequest: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_PathSwitchRequestIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_PathSwitchRequestIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_HandoverCancel: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_HandoverCancelIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_E_RABSetup: - if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABSetupRequestIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABSetupResponseIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_E_RABModify: - if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABModifyRequestIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABModifyResponseIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_E_RABRelease: - if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseCommandIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseResponseIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_E_RABReleaseIndication: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_E_RABReleaseIndicationIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_InitialContextSetup: - if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupRequestIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialContextSetupResponseIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_Paging: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_PagingIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_PagingIEs.mme_ue_s1ap_id; - break; - case S1ap_ProcedureCode_id_downlinkNASTransport: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs.mme_ue_s1ap_id; - if (old_id == mme_ue_s1ap_id) { - packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs.mme_ue_s1ap_id = new_id; - // re-encode - S1ap_DownlinkNASTransport_t msg; - S1ap_DownlinkNASTransport_t *msg_p = &msg; - memset((void *)msg_p, 0, sizeof(msg)); - - if (s1ap_encode_s1ap_downlinknastransporties( - msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs) < 0) { - AssertFatal(0, "Re-encoding downlinknastransporties failed"); +static void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, xmlChar *new_id_hex, xmlChar *new_id_dec, xmlChar *showname) +{ + xmlNode *cur_node = NULL; + xmlAttrPtr attr = NULL; + xmlChar *xml_char = NULL; + int size = 0; + int pos = 0; + int go_deeper_in_tree = 1; + // modify + for (cur_node = (xmlNode *)node; cur_node; cur_node = cur_node->next) { + go_deeper_in_tree = 1; + if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) { + // do not get hidden fields + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide"); + if (NULL != xml_char) { + if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) { + go_deeper_in_tree = 0; } - - ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, - &asn_DEF_S1ap_DownlinkNASTransport, - &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNASTransportIEs); - - encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, - (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); - AssertFatal(encoded < 0, "Re-encoding PDU failed"); + xmlFree(xml_char); } - break; - - case S1ap_ProcedureCode_id_initialUEMessage: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialUEMessageIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_InitialUEMessageIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_uplinkNASTransport: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs.mme_ue_s1ap_id; - if (old_id == mme_ue_s1ap_id) { - packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs.mme_ue_s1ap_id = new_id; - // re-encode - S1ap_UplinkNASTransport_t msg; - S1ap_UplinkNASTransport_t *msg_p = &msg; - memset((void *)msg_p, 0, sizeof(msg)); - - if (s1ap_encode_s1ap_uplinknastransporties( - msg_p, &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs) < 0) { - AssertFatal(0, "Re-encoding uplinknastransporties failed"); + if (0 < go_deeper_in_tree) { + // first get size + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"pos"); + if (NULL != xml_char) { + pos = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); + xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size"); + if (NULL != xml_char) { + size = strtoul((const char *)xml_char, NULL, 0); + xmlFree(xml_char); + // second: try to set value (always hex) + attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"value", new_id_hex); + attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"show", new_id_dec); + attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"showname", showname); + //TODO update s1ap->binary_stream @pos with new_id_hex, size + } } - - ANY_fromType_aper(&packet->sctp_hdr.u.data_hdr.payload.pdu.choice.initiatingMessage.value, - &asn_DEF_S1ap_DownlinkNASTransport, - &packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNASTransportIEs); - - encoded = aper_encode_to_new_buffer(&asn_DEF_S1AP_PDU, 0, &packet->sctp_hdr.u.data_hdr.payload.pdu, - (void **)&packet->sctp_hdr.u.data_hdr.payload.binary_stream); - AssertFatal(encoded < 0, "Re-encoding PDU failed"); - } - break; - - case S1ap_ProcedureCode_id_Reset: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ResetIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ResetIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_ErrorIndication: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ErrorIndicationIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_NASNonDeliveryIndication: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_NASNonDeliveryIndication_IEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_S1Setup: - /*if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupRequestIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupRequestIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_successfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupResponseIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupResponseIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupFailureIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_S1SetupFailureIEs.mme_ue_s1ap_id; - }*/ - break; - - case S1ap_ProcedureCode_id_UEContextReleaseRequest: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseRequestIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_DownlinkS1cdma2000tunneling: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkS1cdma2000tunnelingIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_UplinkS1cdma2000tunneling: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkS1cdma2000tunnelingIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_UEContextModification: - if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationRequestIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_successfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationResponseIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_unsuccessfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextModificationFailureIEs.mme_ue_s1ap_id; - } - break; - - case S1ap_ProcedureCode_id_UECapabilityInfoIndication: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UECapabilityInfoIndicationIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_UEContextRelease: - if (present == S1AP_PDU_PR_initiatingMessage) { - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCommandIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UEContextReleaseCompleteIEs.mme_ue_s1ap_id; } - break; - - case S1ap_ProcedureCode_id_eNBStatusTransfer: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBStatusTransferIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_MMEStatusTransfer: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEStatusTransferIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_DeactivateTrace: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DeactivateTraceIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_TraceStart: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_TraceStartIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_TraceFailureIndication: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_TraceFailureIndicationIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_ENBConfigurationUpdate: - /*if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_successfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateAcknowledgeIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateAcknowledgeIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateFailureIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBConfigurationUpdateFailureIEs.mme_ue_s1ap_id; - }*/ - break; - - case S1ap_ProcedureCode_id_MMEConfigurationUpdate: - /*if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateIEs.mme_ue_s1ap_id; - } else if (present == S1AP_PDU_PR_successfulOutcome) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateAcknowledgeIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateAcknowledgeIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateFailureIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEConfigurationUpdateFailureIEs.mme_ue_s1ap_id; - }*/ - break; - - case S1ap_ProcedureCode_id_LocationReportingControl: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingControlIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_LocationReportingFailureIndication: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportingFailureIndicationIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_LocationReport: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_LocationReportIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_OverloadStart: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_OverloadStartIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_OverloadStartIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_OverloadStop: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_OverloadStopIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_OverloadStopIEs.mme_ue_s1ap_id; - break; - - case S1ap_ProcedureCode_id_WriteReplaceWarning: - /*if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_WriteReplaceWarningRequestIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_WriteReplaceWarningRequestIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_WriteReplaceWarningResponseIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_WriteReplaceWarningResponseIEs.mme_ue_s1ap_id; - }*/ - break; + } + if (0 < go_deeper_in_tree) { + update_xpath_node_mme_ue_s1ap_id(s1ap, cur_node->children, new_id_hex, new_id_dec, showname); + } + } +} - case S1ap_ProcedureCode_id_eNBDirectInformationTransfer: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBDirectInformationTransferIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_ENBDirectInformationTransferIEs.mme_ue_s1ap_id; - break; +/** + * update_xpath_nodes: + * @nodes: the nodes set. + * @value: the new value for the node(s) + * + * Prints the @nodes content to @output. + * From http://www.xmlsoft.org/examples/#xpath2.c + */ +static void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xmlNodeSetPtr nodes, const S1ap_MME_UE_S1AP_ID_t new_id) +{ + int size = 0; + int i = 0; + int ret = 0; + const xmlChar value_d[32]; + const xmlChar value_h[20]; + const xmlChar showname[64]; + xmlNode *s1ap_node = NULL; + + size = (nodes) ? nodes->nodeNr : 0; + + ret = snprintf((char *)value_d, 32, "%ld", new_id); + AssertFatal((ret < 0) || (ret > 32), "Could not convert int to dec str"); + ret = snprintf((char *)value_h, 20, "C0%X", new_id); + AssertFatal((ret < 0) || (ret > 20), "Could not convert int to hex str"); + ret = snprintf((char *)showname, 64, "MME-UE-S1AP-ID: %d", new_id); + AssertFatal((ret < 0) || (ret > 64), "Could not convert int to dec str"); + /* + * NOTE: the nodes are processed in reverse order, i.e. reverse document + * order because xmlNodeSetContent can actually free up descendant + * of the node and such nodes may have been selected too ! Handling + * in reverse order ensure that descendant are accessed first, before + * they get removed. Mixing XPath and modifications on a tree must be + * done carefully ! + */ + for(i = size - 1; i >= 0; i--) { + s1ap_node = nodes->nodeTab[i]; + AssertFatal(NULL != s1ap_node, "One element of resultset of XPATH expression is NULL\n"); + update_xpath_node_mme_ue_s1ap_id(s1ap_payload, s1ap_node, value_d, value_h, showname); + /* + * All the elements returned by an XPath query are pointers to + * elements from the tree *except* namespace nodes where the XPath + * semantic is different from the implementation in libxml2 tree. + * As a result when a returned node set is freed when + * xmlXPathFreeObject() is called, that routine must check the + * element type. But node from the returned set may have been removed + * by xmlNodeSetContent() resulting in access to freed data. + * This can be exercised by running valgrind + * There is 2 ways around it: + * - make a copy of the pointers to the nodes from the result set + * then call xmlXPathFreeObject() and then modify the nodes + * or + * - remove the reference to the modified nodes from the node set + * as they are processed, if they are not namespace nodes. + */ + if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL) { + nodes->nodeTab[i] = NULL; + } + } +} +//------------------------------------------------------------------------------ +int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_S1AP_ID_t old_id, const S1ap_MME_UE_S1AP_ID_t new_id) +{ - case S1ap_ProcedureCode_id_MMEDirectInformationTransfer: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEDirectInformationTransferIEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_MMEDirectInformationTransferIEs.mme_ue_s1ap_id; - break; - case S1ap_ProcedureCode_id_PrivateMessage: - case S1ap_ProcedureCode_id_eNBConfigurationTransfer: - case S1ap_ProcedureCode_id_MMEConfigurationTransfer: - AssertFatal(0, "TODO"); - break; + xmlNode *cur_node = NULL; + xmlChar xpath_expression[ET_XPATH_EXPRESSION_MAX_LENGTH]; + int ret = 0; + xmlDocPtr doc = NULL; + xmlXPathContextPtr xpath_ctx = NULL; + xmlXPathObjectPtr xpath_obj = NULL; - case S1ap_ProcedureCode_id_CellTrafficTrace: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_CellTrafficTraceIEs.mme_ue_s1ap_id; - break; + ret = snprintf(xpath_expression, ET_XPATH_EXPRESSION_MAX_LENGTH, "//field[@name=\"s1ap.MME_UE_S1AP_ID\"][@show=\"%d\"]", old_id); + AssertFatal((ret < 0) || (ret > ET_XPATH_EXPRESSION_MAX_LENGTH), "Could not build XPATH expression"); - case S1ap_ProcedureCode_id_Kill: - /*if (present == S1AP_PDU_PR_initiatingMessage) { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_KillRequestIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_KillRequestIEs.mme_ue_s1ap_id; - } else { - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_KillResponseIEs.mme_ue_s1ap_id; - scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_KillResponseIEs.mme_ue_s1ap_id; - }*/ - break; + doc = packet->sctp_hdr.u.data_hdr.payload.doc; - case S1ap_ProcedureCode_id_downlinkUEAssociatedLPPaTransport: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; - break; + // Create xpath evaluation context + xpath_ctx = xmlXPathNewContext(doc); + if(xpath_ctx == NULL) { + fprintf(stderr,"Error: unable to create new XPath context\n"); + xmlFreeDoc(doc); + return(-1); + } - case S1ap_ProcedureCode_id_uplinkUEAssociatedLPPaTransport: - mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; - break; + // Evaluate xpath expression + xpath_obj = xmlXPathEvalExpression(xpath_expression, xpath_ctx); + AssertFatal(xpath_obj != NULL, "Unable to evaluate XPATH expression \"%s\"\n", xpath_expression); - case S1ap_ProcedureCode_id_downlinkNonUEAssociatedLPPaTransport: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNonUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_DownlinkNonUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; - break; + // update selected nodes + update_xpath_nodes_mme_ue_s1ap_id(&packet->sctp_hdr.u.data_hdr.payload, xpath_obj->nodesetval, new_id); - case S1ap_ProcedureCode_id_uplinkNonUEAssociatedLPPaTransport: - //mme_ue_s1ap_id = packet->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNonUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; - //scenario_mme_ue_s1ap_id = spacket->sctp_hdr.u.data_hdr.payload.message.msg.s1ap_UplinkNonUEAssociatedLPPaTransport_IEs.mme_ue_s1ap_id; - break; + // Cleanup of XPath data + xmlXPathFreeObject(xpath_obj); + xmlXPathFreeContext(xpath_ctx); - default: - AssertFatal(0, "Unknown procedure code %ld", packet->sctp_hdr.u.data_hdr.payload.message.procedureCode); - } return 0; }