diff --git a/lib/include/srslte/asn1/liblte_s1ap.h b/lib/include/srslte/asn1/liblte_s1ap.h new file mode 100644 index 000000000..077ddac66 --- /dev/null +++ b/lib/include/srslte/asn1/liblte_s1ap.h @@ -0,0 +1,10355 @@ +/******************************************************************************* +/* +/* Copyright 2016 Software Radio Systems Limited +/* +********************************************************************************/ + +#ifndef LIBLTE_S1AP_H +#define LIBLTE_S1AP_H + +/******************************************************************************* +/* Warnings/Todos +********************************************************************************/ +// Extensions are not yet handled correctly +// Dynamic Sequence Of types have max 32 elements to reduce memory footprint +// Container Lists are not yet handled correctly e.g. E-RAB-IE-ContainerList + +/******************************************************************************* +/* INCLUDES +********************************************************************************/ + +#include "liblte_common.h" + +/******************************************************************************* + LOGGING +*******************************************************************************/ + +typedef void (*log_handler_t)(void *ctx, char *str); + +void liblte_log_register_handler(void *ctx, log_handler_t handler); + + +/******************************************************************************* +/* MAX defines +********************************************************************************/ +#define LIBLTE_S1AP_MAXPRIVATEIES 65535 +#define LIBLTE_S1AP_MAXPROTOCOLIES 65535 +#define LIBLTE_S1AP_MAXNOOFE_RABS 256 +#define LIBLTE_S1AP_MAXNOOFTACS 256 +#define LIBLTE_S1AP_MAXNOOFBPLMNS 6 +#define LIBLTE_S1AP_MAXNOOFEPLMNS 15 +#define LIBLTE_S1AP_MAXNOOFFORBLACS 4096 +#define LIBLTE_S1AP_MAXNOOFINDIVIDUALS1CONNECTIONSTORESET 256 +#define LIBLTE_S1AP_MAXNOOFTAIFORWARNING 65535 +#define LIBLTE_S1AP_MAXNOOFEMERGENCYAREAID 65535 +#define LIBLTE_S1AP_MAXNOOFCELLINEAI 65535 +#define LIBLTE_S1AP_MAXNOOFENBX2EXTTLAS 16 +#define LIBLTE_S1AP_MAXNOOFRATS 8 +#define LIBLTE_S1AP_MAXNOOFMMECS 256 +#define LIBLTE_S1AP_MAXNOOFTAFORMDT 8 +#define LIBLTE_S1AP_MAXNOOFCELLSFORRESTART 256 +#define LIBLTE_S1AP_MAXNOOFRESTARTEMERGENCYAREAIDS 256 +#define LIBLTE_S1AP_MAXNOOFCSGS 256 +#define LIBLTE_S1AP_MAXNOOFERRORS 256 +#define LIBLTE_S1AP_MAXNOOFEPLMNSPLUSONE 16 +#define LIBLTE_S1AP_MAXNOOFCELLS 16 +#define LIBLTE_S1AP_MAXNOOFCELLINTAI 65535 +#define LIBLTE_S1AP_MAXNOOFENBX2GTPTLAS 16 +#define LIBLTE_S1AP_MAXNOOFCELLIDFORMDT 32 +#define LIBLTE_S1AP_MAXNOOFRESTARTTAIS 2048 +#define LIBLTE_S1AP_MAXPROTOCOLEXTENSIONS 65535 +#define LIBLTE_S1AP_MAXNOOFPLMNSPERMME 32 +#define LIBLTE_S1AP_MAXNOOFCELLID 65535 +#define LIBLTE_S1AP_MAXNOOFGROUPIDS 65535 +#define LIBLTE_S1AP_MAXNOOFTAIS 256 +#define LIBLTE_S1AP_MAXNOOFENBX2TLAS 2 +#define LIBLTE_S1AP_MAXNOOFMDTPLMNS 16 +#define LIBLTE_S1AP_MAXNOOFFORBTACS 4096 + +/******************************************************************************* +/* Elementary Procedures +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PROC_ID_HANDOVERPREPARATION = 0, + LIBLTE_S1AP_PROC_ID_HANDOVERRESOURCEALLOCATION = 1, + LIBLTE_S1AP_PROC_ID_HANDOVERNOTIFICATION = 2, + LIBLTE_S1AP_PROC_ID_PATHSWITCHREQUEST = 3, + LIBLTE_S1AP_PROC_ID_HANDOVERCANCEL = 4, + LIBLTE_S1AP_PROC_ID_E_RABSETUP = 5, + LIBLTE_S1AP_PROC_ID_E_RABMODIFY = 6, + LIBLTE_S1AP_PROC_ID_E_RABRELEASE = 7, + LIBLTE_S1AP_PROC_ID_E_RABRELEASEINDICATION = 8, + LIBLTE_S1AP_PROC_ID_INITIALCONTEXTSETUP = 9, + LIBLTE_S1AP_PROC_ID_PAGING = 10, + LIBLTE_S1AP_PROC_ID_DOWNLINKNASTRANSPORT = 11, + LIBLTE_S1AP_PROC_ID_INITIALUEMESSAGE = 12, + LIBLTE_S1AP_PROC_ID_UPLINKNASTRANSPORT = 13, + LIBLTE_S1AP_PROC_ID_RESET = 14, + LIBLTE_S1AP_PROC_ID_ERRORINDICATION = 15, + LIBLTE_S1AP_PROC_ID_NASNONDELIVERYINDICATION = 16, + LIBLTE_S1AP_PROC_ID_S1SETUP = 17, + LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASEREQUEST = 18, + LIBLTE_S1AP_PROC_ID_DOWNLINKS1CDMA2000TUNNELING = 19, + LIBLTE_S1AP_PROC_ID_UPLINKS1CDMA2000TUNNELING = 20, + LIBLTE_S1AP_PROC_ID_UECONTEXTMODIFICATION = 21, + LIBLTE_S1AP_PROC_ID_UECAPABILITYINFOINDICATION = 22, + LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASE = 23, + LIBLTE_S1AP_PROC_ID_ENBSTATUSTRANSFER = 24, + LIBLTE_S1AP_PROC_ID_MMESTATUSTRANSFER = 25, + LIBLTE_S1AP_PROC_ID_DEACTIVATETRACE = 26, + LIBLTE_S1AP_PROC_ID_TRACESTART = 27, + LIBLTE_S1AP_PROC_ID_TRACEFAILUREINDICATION = 28, + LIBLTE_S1AP_PROC_ID_ENBCONFIGURATIONUPDATE = 29, + LIBLTE_S1AP_PROC_ID_MMECONFIGURATIONUPDATE = 30, + LIBLTE_S1AP_PROC_ID_LOCATIONREPORTINGCONTROL = 31, + LIBLTE_S1AP_PROC_ID_LOCATIONREPORTINGFAILUREINDICATION = 32, + LIBLTE_S1AP_PROC_ID_LOCATIONREPORT = 33, + LIBLTE_S1AP_PROC_ID_OVERLOADSTART = 34, + LIBLTE_S1AP_PROC_ID_OVERLOADSTOP = 35, + LIBLTE_S1AP_PROC_ID_WRITEREPLACEWARNING = 36, + LIBLTE_S1AP_PROC_ID_ENBDIRECTINFORMATIONTRANSFER = 37, + LIBLTE_S1AP_PROC_ID_MMEDIRECTINFORMATIONTRANSFER = 38, + LIBLTE_S1AP_PROC_ID_PRIVATEMESSAGE = 39, + LIBLTE_S1AP_PROC_ID_ENBCONFIGURATIONTRANSFER = 40, + LIBLTE_S1AP_PROC_ID_MMECONFIGURATIONTRANSFER = 41, + LIBLTE_S1AP_PROC_ID_CELLTRAFFICTRACE = 42, + LIBLTE_S1AP_PROC_ID_KILL = 43, + LIBLTE_S1AP_PROC_ID_DOWNLINKUEASSOCIATEDLPPATRANSPORT = 44, + LIBLTE_S1AP_PROC_ID_UPLINKUEASSOCIATEDLPPATRANSPORT = 45, + LIBLTE_S1AP_PROC_ID_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT = 46, + LIBLTE_S1AP_PROC_ID_UPLINKNONUEASSOCIATEDLPPATRANSPORT = 47, + LIBLTE_S1AP_PROC_ID_UERADIOCAPABILITYMATCH = 48, + LIBLTE_S1AP_PROC_ID_PWSRESTARTINDICATION = 49, + LIBLTE_S1AP_PROC_N_ITEMS, +}LIBLTE_S1AP_PROC_ENUM; +static const char liblte_s1ap_proc_text[LIBLTE_S1AP_PROC_N_ITEMS][64] = { + "id-HandoverPreparation", + "id-HandoverResourceAllocation", + "id-HandoverNotification", + "id-PathSwitchRequest", + "id-HandoverCancel", + "id-E-RABSetup", + "id-E-RABModify", + "id-E-RABRelease", + "id-E-RABReleaseIndication", + "id-InitialContextSetup", + "id-Paging", + "id-downlinkNASTransport", + "id-initialUEMessage", + "id-uplinkNASTransport", + "id-Reset", + "id-ErrorIndication", + "id-NASNonDeliveryIndication", + "id-S1Setup", + "id-UEContextReleaseRequest", + "id-DownlinkS1cdma2000tunneling", + "id-UplinkS1cdma2000tunneling", + "id-UEContextModification", + "id-UECapabilityInfoIndication", + "id-UEContextRelease", + "id-eNBStatusTransfer", + "id-MMEStatusTransfer", + "id-DeactivateTrace", + "id-TraceStart", + "id-TraceFailureIndication", + "id-ENBConfigurationUpdate", + "id-MMEConfigurationUpdate", + "id-LocationReportingControl", + "id-LocationReportingFailureIndication", + "id-LocationReport", + "id-OverloadStart", + "id-OverloadStop", + "id-WriteReplaceWarning", + "id-eNBDirectInformationTransfer", + "id-MMEDirectInformationTransfer", + "id-PrivateMessage", + "id-eNBConfigurationTransfer", + "id-MMEConfigurationTransfer", + "id-CellTrafficTrace", + "id-Kill", + "id-downlinkUEAssociatedLPPaTransport", + "id-uplinkUEAssociatedLPPaTransport", + "id-downlinkNonUEAssociatedLPPaTransport", + "id-uplinkNonUEAssociatedLPPaTransport", + "id-UERadioCapabilityMatch", + "id-PWSRestartIndication", +}; + + + +/******************************************************************************* +/* ProtocolIE Ids +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID = 0, + LIBLTE_S1AP_IE_ID_HANDOVERTYPE = 1, + LIBLTE_S1AP_IE_ID_CAUSE = 2, + LIBLTE_S1AP_IE_ID_SOURCEID = 3, + LIBLTE_S1AP_IE_ID_TARGETID = 4, + LIBLTE_S1AP_IE_ID_SPARE5 = 5, + LIBLTE_S1AP_IE_ID_SPARE6 = 6, + LIBLTE_S1AP_IE_ID_SPARE7 = 7, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID = 8, + LIBLTE_S1AP_IE_ID_SPARE9 = 9, + LIBLTE_S1AP_IE_ID_SPARE10 = 10, + LIBLTE_S1AP_IE_ID_SPARE11 = 11, + LIBLTE_S1AP_IE_ID_E_RABSUBJECTTODATAFORWARDINGLIST = 12, + LIBLTE_S1AP_IE_ID_E_RABTORELEASELISTHOCMD = 13, + LIBLTE_S1AP_IE_ID_E_RABDATAFORWARDINGITEM = 14, + LIBLTE_S1AP_IE_ID_E_RABRELEASEITEMBEARERRELCOMP = 15, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTBEARERSUREQ = 16, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMBEARERSUREQ = 17, + LIBLTE_S1AP_IE_ID_E_RABADMITTEDLIST = 18, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTHOREQACK = 19, + LIBLTE_S1AP_IE_ID_E_RABADMITTEDITEM = 20, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPITEMHOREQACK = 21, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDDLLIST = 22, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDDLITEM = 23, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTCTXTSUREQ = 24, + LIBLTE_S1AP_IE_ID_TRACEACTIVATION = 25, + LIBLTE_S1AP_IE_ID_NAS_PDU = 26, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMHOREQ = 27, + LIBLTE_S1AP_IE_ID_E_RABSETUPLISTBEARERSURES = 28, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTBEARERSURES = 29, + LIBLTE_S1AP_IE_ID_E_RABTOBEMODIFIEDLISTBEARERMODREQ = 30, + LIBLTE_S1AP_IE_ID_E_RABMODIFYLISTBEARERMODRES = 31, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOMODIFYLIST = 32, + LIBLTE_S1AP_IE_ID_E_RABTOBERELEASEDLIST = 33, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTORELEASELIST = 34, + LIBLTE_S1AP_IE_ID_E_RABITEM = 35, + LIBLTE_S1AP_IE_ID_E_RABTOBEMODIFIEDITEMBEARERMODREQ = 36, + LIBLTE_S1AP_IE_ID_E_RABMODIFYITEMBEARERMODRES = 37, + LIBLTE_S1AP_IE_ID_E_RABRELEASEITEM = 38, + LIBLTE_S1AP_IE_ID_E_RABSETUPITEMBEARERSURES = 39, + LIBLTE_S1AP_IE_ID_SECURITYCONTEXT = 40, + LIBLTE_S1AP_IE_ID_HANDOVERRESTRICTIONLIST = 41, + LIBLTE_S1AP_IE_ID_SPARE42 = 42, + LIBLTE_S1AP_IE_ID_UEPAGINGID = 43, + LIBLTE_S1AP_IE_ID_PAGINGDRX = 44, + LIBLTE_S1AP_IE_ID_SPARE45 = 45, + LIBLTE_S1AP_IE_ID_TAILIST = 46, + LIBLTE_S1AP_IE_ID_TAIITEM = 47, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTCTXTSURES = 48, + LIBLTE_S1AP_IE_ID_E_RABRELEASEITEMHOCMD = 49, + LIBLTE_S1AP_IE_ID_E_RABSETUPITEMCTXTSURES = 50, + LIBLTE_S1AP_IE_ID_E_RABSETUPLISTCTXTSURES = 51, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMCTXTSUREQ = 52, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTHOREQ = 53, + LIBLTE_S1AP_IE_ID_SPARE54 = 54, + LIBLTE_S1AP_IE_ID_GERANTOLTEHOINFORMATIONRES = 55, + LIBLTE_S1AP_IE_ID_SPARE56 = 56, + LIBLTE_S1AP_IE_ID_UTRANTOLTEHOINFORMATIONRES = 57, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS = 58, + LIBLTE_S1AP_IE_ID_GLOBAL_ENB_ID = 59, + LIBLTE_S1AP_IE_ID_ENBNAME = 60, + LIBLTE_S1AP_IE_ID_MMENAME = 61, + LIBLTE_S1AP_IE_ID_SPARE62 = 62, + LIBLTE_S1AP_IE_ID_SERVEDPLMNS = 63, + LIBLTE_S1AP_IE_ID_SUPPORTEDTAS = 64, + LIBLTE_S1AP_IE_ID_TIMETOWAIT = 65, + LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE = 66, + LIBLTE_S1AP_IE_ID_TAI = 67, + LIBLTE_S1AP_IE_ID_SPARE68 = 68, + LIBLTE_S1AP_IE_ID_E_RABRELEASELISTBEARERRELCOMP = 69, + LIBLTE_S1AP_IE_ID_CDMA2000PDU = 70, + LIBLTE_S1AP_IE_ID_CDMA2000RATTYPE = 71, + LIBLTE_S1AP_IE_ID_CDMA2000SECTORID = 72, + LIBLTE_S1AP_IE_ID_SECURITYKEY = 73, + LIBLTE_S1AP_IE_ID_UERADIOCAPABILITY = 74, + LIBLTE_S1AP_IE_ID_GUMMEI_ID = 75, + LIBLTE_S1AP_IE_ID_SPARE76 = 76, + LIBLTE_S1AP_IE_ID_SPARE77 = 77, + LIBLTE_S1AP_IE_ID_E_RABINFORMATIONLISTITEM = 78, + LIBLTE_S1AP_IE_ID_DIRECT_FORWARDING_PATH_AVAILABILITY = 79, + LIBLTE_S1AP_IE_ID_UEIDENTITYINDEXVALUE = 80, + LIBLTE_S1AP_IE_ID_SPARE81 = 81, + LIBLTE_S1AP_IE_ID_SPARE82 = 82, + LIBLTE_S1AP_IE_ID_CDMA2000HOSTATUS = 83, + LIBLTE_S1AP_IE_ID_CDMA2000HOREQUIREDINDICATION = 84, + LIBLTE_S1AP_IE_ID_SPARE85 = 85, + LIBLTE_S1AP_IE_ID_E_UTRAN_TRACE_ID = 86, + LIBLTE_S1AP_IE_ID_RELATIVEMMECAPACITY = 87, + LIBLTE_S1AP_IE_ID_SOURCEMME_UE_S1AP_ID = 88, + LIBLTE_S1AP_IE_ID_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM = 89, + LIBLTE_S1AP_IE_ID_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER = 90, + LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM = 91, + LIBLTE_S1AP_IE_ID_RESETTYPE = 92, + LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK = 93, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDULITEM = 94, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDULLIST = 95, + LIBLTE_S1AP_IE_ID_S_TMSI = 96, + LIBLTE_S1AP_IE_ID_CDMA2000ONEXRAND = 97, + LIBLTE_S1AP_IE_ID_REQUESTTYPE = 98, + LIBLTE_S1AP_IE_ID_UE_S1AP_IDS = 99, + LIBLTE_S1AP_IE_ID_EUTRAN_CGI = 100, + LIBLTE_S1AP_IE_ID_OVERLOADRESPONSE = 101, + LIBLTE_S1AP_IE_ID_CDMA2000ONEXSRVCCINFO = 102, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOBERELEASEDLIST = 103, + LIBLTE_S1AP_IE_ID_SOURCE_TOTARGET_TRANSPARENTCONTAINER = 104, + LIBLTE_S1AP_IE_ID_SERVEDGUMMEIS = 105, + LIBLTE_S1AP_IE_ID_SUBSCRIBERPROFILEIDFORRFP = 106, + LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES = 107, + LIBLTE_S1AP_IE_ID_CSFALLBACKINDICATOR = 108, + LIBLTE_S1AP_IE_ID_CNDOMAIN = 109, + LIBLTE_S1AP_IE_ID_E_RABRELEASEDLIST = 110, + LIBLTE_S1AP_IE_ID_MESSAGEIDENTIFIER = 111, + LIBLTE_S1AP_IE_ID_SERIALNUMBER = 112, + LIBLTE_S1AP_IE_ID_WARNINGAREALIST = 113, + LIBLTE_S1AP_IE_ID_REPETITIONPERIOD = 114, + LIBLTE_S1AP_IE_ID_NUMBEROFBROADCASTREQUEST = 115, + LIBLTE_S1AP_IE_ID_WARNINGTYPE = 116, + LIBLTE_S1AP_IE_ID_WARNINGSECURITYINFO = 117, + LIBLTE_S1AP_IE_ID_DATACODINGSCHEME = 118, + LIBLTE_S1AP_IE_ID_WARNINGMESSAGECONTENTS = 119, + LIBLTE_S1AP_IE_ID_BROADCASTCOMPLETEDAREALIST = 120, + LIBLTE_S1AP_IE_ID_INTER_SYSTEMINFORMATIONTRANSFERTYPEEDT = 121, + LIBLTE_S1AP_IE_ID_INTER_SYSTEMINFORMATIONTRANSFERTYPEMDT = 122, + LIBLTE_S1AP_IE_ID_TARGET_TOSOURCE_TRANSPARENTCONTAINER = 123, + LIBLTE_S1AP_IE_ID_SRVCCOPERATIONPOSSIBLE = 124, + LIBLTE_S1AP_IE_ID_SRVCCHOINDICATION = 125, + LIBLTE_S1AP_IE_ID_NAS_DOWNLINKCOUNT = 126, + LIBLTE_S1AP_IE_ID_CSG_ID = 127, + LIBLTE_S1AP_IE_ID_CSG_IDLIST = 128, + LIBLTE_S1AP_IE_ID_SONCONFIGURATIONTRANSFERECT = 129, + LIBLTE_S1AP_IE_ID_SONCONFIGURATIONTRANSFERMCT = 130, + LIBLTE_S1AP_IE_ID_TRACECOLLECTIONENTITYIPADDRESS = 131, + LIBLTE_S1AP_IE_ID_MSCLASSMARK2 = 132, + LIBLTE_S1AP_IE_ID_MSCLASSMARK3 = 133, + LIBLTE_S1AP_IE_ID_RRC_ESTABLISHMENT_CAUSE = 134, + LIBLTE_S1AP_IE_ID_NASSECURITYPARAMETERSFROME_UTRAN = 135, + LIBLTE_S1AP_IE_ID_NASSECURITYPARAMETERSTOE_UTRAN = 136, + LIBLTE_S1AP_IE_ID_DEFAULTPAGINGDRX = 137, + LIBLTE_S1AP_IE_ID_SOURCE_TOTARGET_TRANSPARENTCONTAINER_SECONDARY = 138, + LIBLTE_S1AP_IE_ID_TARGET_TOSOURCE_TRANSPARENTCONTAINER_SECONDARY = 139, + LIBLTE_S1AP_IE_ID_EUTRANROUNDTRIPDELAYESTIMATIONINFO = 140, + LIBLTE_S1AP_IE_ID_BROADCASTCANCELLEDAREALIST = 141, + LIBLTE_S1AP_IE_ID_CONCURRENTWARNINGMESSAGEINDICATOR = 142, + LIBLTE_S1AP_IE_ID_DATA_FORWARDING_NOT_POSSIBLE = 143, + LIBLTE_S1AP_IE_ID_EXTENDEDREPETITIONPERIOD = 144, + LIBLTE_S1AP_IE_ID_CELLACCESSMODE = 145, + LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS = 146, + LIBLTE_S1AP_IE_ID_LPPA_PDU = 147, + LIBLTE_S1AP_IE_ID_ROUTING_ID = 148, + LIBLTE_S1AP_IE_ID_TIME_SYNCHRONIZATION_INFO = 149, + LIBLTE_S1AP_IE_ID_PS_SERVICENOTAVAILABLE = 150, + LIBLTE_S1AP_IE_ID_PAGINGPRIORITY = 151, + LIBLTE_S1AP_IE_ID_X2TNLCONFIGURATIONINFO = 152, + LIBLTE_S1AP_IE_ID_ENBX2EXTENDEDTRANSPORTLAYERADDRESSES = 153, + LIBLTE_S1AP_IE_ID_GUMMEILIST = 154, + LIBLTE_S1AP_IE_ID_GW_TRANSPORTLAYERADDRESS = 155, + LIBLTE_S1AP_IE_ID_CORRELATION_ID = 156, + LIBLTE_S1AP_IE_ID_SOURCEMME_GUMMEI = 157, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID_2 = 158, + LIBLTE_S1AP_IE_ID_REGISTEREDLAI = 159, + LIBLTE_S1AP_IE_ID_RELAYNODE_INDICATOR = 160, + LIBLTE_S1AP_IE_ID_TRAFFICLOADREDUCTIONINDICATION = 161, + LIBLTE_S1AP_IE_ID_MDTCONFIGURATION = 162, + LIBLTE_S1AP_IE_ID_MMERELAYSUPPORTINDICATOR = 163, + LIBLTE_S1AP_IE_ID_GWCONTEXTRELEASEINDICATION = 164, + LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTALLOWED = 165, + LIBLTE_S1AP_IE_ID_PRIVACYINDICATOR = 166, + LIBLTE_S1AP_IE_ID_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY = 167, + LIBLTE_S1AP_IE_ID_HO_CAUSE = 168, + LIBLTE_S1AP_IE_ID_VOICESUPPORTMATCHINDICATOR = 169, + LIBLTE_S1AP_IE_ID_GUMMEITYPE = 170, + LIBLTE_S1AP_IE_ID_M3CONFIGURATION = 171, + LIBLTE_S1AP_IE_ID_M4CONFIGURATION = 172, + LIBLTE_S1AP_IE_ID_M5CONFIGURATION = 173, + LIBLTE_S1AP_IE_ID_MDT_LOCATION_INFO = 174, + LIBLTE_S1AP_IE_ID_MOBILITYINFORMATION = 175, + LIBLTE_S1AP_IE_ID_TUNNEL_INFORMATION_FOR_BBF = 176, + LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTPLMNLIST = 177, + LIBLTE_S1AP_IE_ID_SIGNALLINGBASEDMDTPLMNLIST = 178, + LIBLTE_S1AP_IE_ID_ULCOUNTVALUEEXTENDED = 179, + LIBLTE_S1AP_IE_ID_DLCOUNTVALUEEXTENDED = 180, + LIBLTE_S1AP_IE_ID_RECEIVESTATUSOFULPDCPSDUSEXTENDED = 181, + LIBLTE_S1AP_IE_ID_ECGILISTFORRESTART = 182, + LIBLTE_S1AP_IE_ID_SIPTO_CORRELATION_ID = 183, + LIBLTE_S1AP_IE_ID_SIPTO_L_GW_TRANSPORTLAYERADDRESS = 184, + LIBLTE_S1AP_IE_ID_TRANSPORTINFORMATION = 185, + LIBLTE_S1AP_IE_ID_LHN_ID = 186, + LIBLTE_S1AP_IE_ID_ADDITIONALCSFALLBACKINDICATOR = 187, + LIBLTE_S1AP_IE_ID_TAILISTFORRESTART = 188, + LIBLTE_S1AP_IE_ID_USERLOCATIONINFORMATION = 189, + LIBLTE_S1AP_IE_ID_EMERGENCYAREAIDLISTFORRESTART = 190, + LIBLTE_S1AP_IE_ID_KILLALLWARNINGMESSAGES = 191, + LIBLTE_S1AP_IE_N_ITEMS, +}LIBLTE_S1AP_IE_ENUM; +static const char liblte_s1ap_ie_text[LIBLTE_S1AP_IE_N_ITEMS][64] = { + "id-MME-UE-S1AP-ID", + "id-HandoverType", + "id-Cause", + "id-SourceID", + "id-TargetID", + "id-spare5", + "id-spare6", + "id-spare7", + "id-eNB-UE-S1AP-ID", + "id-spare9", + "id-spare10", + "id-spare11", + "id-E-RABSubjecttoDataForwardingList", + "id-E-RABtoReleaseListHOCmd", + "id-E-RABDataForwardingItem", + "id-E-RABReleaseItemBearerRelComp", + "id-E-RABToBeSetupListBearerSUReq", + "id-E-RABToBeSetupItemBearerSUReq", + "id-E-RABAdmittedList", + "id-E-RABFailedToSetupListHOReqAck", + "id-E-RABAdmittedItem", + "id-E-RABFailedtoSetupItemHOReqAck", + "id-E-RABToBeSwitchedDLList", + "id-E-RABToBeSwitchedDLItem", + "id-E-RABToBeSetupListCtxtSUReq", + "id-TraceActivation", + "id-NAS-PDU", + "id-E-RABToBeSetupItemHOReq", + "id-E-RABSetupListBearerSURes", + "id-E-RABFailedToSetupListBearerSURes", + "id-E-RABToBeModifiedListBearerModReq", + "id-E-RABModifyListBearerModRes", + "id-E-RABFailedToModifyList", + "id-E-RABToBeReleasedList", + "id-E-RABFailedToReleaseList", + "id-E-RABItem", + "id-E-RABToBeModifiedItemBearerModReq", + "id-E-RABModifyItemBearerModRes", + "id-E-RABReleaseItem", + "id-E-RABSetupItemBearerSURes", + "id-SecurityContext", + "id-HandoverRestrictionList", + "id-spare42", + "id-UEPagingID", + "id-pagingDRX", + "id-spare45", + "id-TAIList", + "id-TAIItem", + "id-E-RABFailedToSetupListCtxtSURes", + "id-E-RABReleaseItemHOCmd", + "id-E-RABSetupItemCtxtSURes", + "id-E-RABSetupListCtxtSURes", + "id-E-RABToBeSetupItemCtxtSUReq", + "id-E-RABToBeSetupListHOReq", + "id-spare54", + "id-GERANtoLTEHOInformationRes", + "id-spare56", + "id-UTRANtoLTEHOInformationRes", + "id-CriticalityDiagnostics", + "id-Global-ENB-ID", + "id-eNBname", + "id-MMEname", + "id-spare62", + "id-ServedPLMNs", + "id-SupportedTAs", + "id-TimeToWait", + "id-uEaggregateMaximumBitrate", + "id-TAI", + "id-spare68", + "id-E-RABReleaseListBearerRelComp", + "id-cdma2000PDU", + "id-cdma2000RATType", + "id-cdma2000SectorID", + "id-SecurityKey", + "id-UERadioCapability", + "id-GUMMEI-ID", + "id-spare76", + "id-spare77", + "id-E-RABInformationListItem", + "id-Direct-Forwarding-Path-Availability", + "id-UEIdentityIndexValue", + "id-spare81", + "id-spare82", + "id-cdma2000HOStatus", + "id-cdma2000HORequiredIndication", + "id-spare85", + "id-E-UTRAN-Trace-ID", + "id-RelativeMMECapacity", + "id-SourceMME-UE-S1AP-ID", + "id-Bearers-SubjectToStatusTransfer-Item", + "id-eNB-StatusTransfer-TransparentContainer", + "id-UE-associatedLogicalS1-ConnectionItem", + "id-ResetType", + "id-UE-associatedLogicalS1-ConnectionListResAck", + "id-E-RABToBeSwitchedULItem", + "id-E-RABToBeSwitchedULList", + "id-S-TMSI", + "id-cdma2000OneXRAND", + "id-RequestType", + "id-UE-S1AP-IDs", + "id-EUTRAN-CGI", + "id-OverloadResponse", + "id-cdma2000OneXSRVCCInfo", + "id-E-RABFailedToBeReleasedList", + "id-Source-ToTarget-TransparentContainer", + "id-ServedGUMMEIs", + "id-SubscriberProfileIDforRFP", + "id-UESecurityCapabilities", + "id-CSFallbackIndicator", + "id-CNDomain", + "id-E-RABReleasedList", + "id-MessageIdentifier", + "id-SerialNumber", + "id-WarningAreaList", + "id-RepetitionPeriod", + "id-NumberofBroadcastRequest", + "id-WarningType", + "id-WarningSecurityInfo", + "id-DataCodingScheme", + "id-WarningMessageContents", + "id-BroadcastCompletedAreaList", + "id-Inter-SystemInformationTransferTypeEDT", + "id-Inter-SystemInformationTransferTypeMDT", + "id-Target-ToSource-TransparentContainer", + "id-SRVCCOperationPossible", + "id-SRVCCHOIndication", + "id-NAS-DownlinkCount", + "id-CSG-Id", + "id-CSG-IdList", + "id-SONConfigurationTransferECT", + "id-SONConfigurationTransferMCT", + "id-TraceCollectionEntityIPAddress", + "id-MSClassmark2", + "id-MSClassmark3", + "id-RRC-Establishment-Cause", + "id-NASSecurityParametersfromE-UTRAN", + "id-NASSecurityParameterstoE-UTRAN", + "id-DefaultPagingDRX", + "id-Source-ToTarget-TransparentContainer-Secondary", + "id-Target-ToSource-TransparentContainer-Secondary", + "id-EUTRANRoundTripDelayEstimationInfo", + "id-BroadcastCancelledAreaList", + "id-ConcurrentWarningMessageIndicator", + "id-Data-Forwarding-Not-Possible", + "id-ExtendedRepetitionPeriod", + "id-CellAccessMode", + "id-CSGMembershipStatus", + "id-LPPa-PDU", + "id-Routing-ID", + "id-Time-Synchronization-Info", + "id-PS-ServiceNotAvailable", + "id-PagingPriority", + "id-x2TNLConfigurationInfo", + "id-eNBX2ExtendedTransportLayerAddresses", + "id-GUMMEIList", + "id-GW-TransportLayerAddress", + "id-Correlation-ID", + "id-SourceMME-GUMMEI", + "id-MME-UE-S1AP-ID-2", + "id-RegisteredLAI", + "id-RelayNode-Indicator", + "id-TrafficLoadReductionIndication", + "id-MDTConfiguration", + "id-MMERelaySupportIndicator", + "id-GWContextReleaseIndication", + "id-ManagementBasedMDTAllowed", + "id-PrivacyIndicator", + "id-Time-UE-StayedInCell-EnhancedGranularity", + "id-HO-Cause", + "id-VoiceSupportMatchIndicator", + "id-GUMMEIType", + "id-M3Configuration", + "id-M4Configuration", + "id-M5Configuration", + "id-MDT-Location-Info", + "id-MobilityInformation", + "id-Tunnel-Information-for-BBF", + "id-ManagementBasedMDTPLMNList", + "id-SignallingBasedMDTPLMNList", + "id-ULCOUNTValueExtended", + "id-DLCOUNTValueExtended", + "id-ReceiveStatusOfULPDCPSDUsExtended", + "id-ECGIListForRestart", + "id-SIPTO-Correlation-ID", + "id-SIPTO-L-GW-TransportLayerAddress", + "id-TransportInformation", + "id-LHN-ID", + "id-AdditionalCSFallbackIndicator", + "id-TAIListForRestart", + "id-UserLocationInformation", + "id-EmergencyAreaIDListForRestart", + "id-KillAllWarningMessages", +}; + + +/******************************************************************************* +/* ProtocolIE Criticality ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_NOTIFY, + LIBLTE_S1AP_CRITICALITY_N_ITEMS, +}LIBLTE_S1AP_CRITICALITY_ENUM; +static const char liblte_s1ap_criticality_text[LIBLTE_S1AP_CRITICALITY_N_ITEMS][80] = { + "reject", + "ignore", + "notify", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticality( + LIBLTE_S1AP_CRITICALITY_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticality( + uint8_t **ptr, + LIBLTE_S1AP_CRITICALITY_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE local INTEGER +********************************************************************************/ +typedef struct{ +uint16_t local; +}LIBLTE_S1AP_LOCAL_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_local( + LIBLTE_S1AP_LOCAL_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_local( + uint8_t **ptr, + LIBLTE_S1AP_LOCAL_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE PrivateIE_ID CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_LOCAL, + LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_GLOBAL, + LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_N_ITEMS, +}LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_ENUM; +static const char liblte_s1ap_privateie_id_choice_text[LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_N_ITEMS][50] = { + "local", + "global", +}; + +typedef union{ + LIBLTE_S1AP_LOCAL_STRUCT local; + LIBLTE_ASN1_OID_STRUCT global; +}LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_UNION; + +typedef struct{ + LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_UNION choice; + LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_PRIVATEIE_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privateie_id( + LIBLTE_S1AP_PRIVATEIE_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privateie_id( + uint8_t **ptr, + LIBLTE_S1AP_PRIVATEIE_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolExtensionID INTEGER +********************************************************************************/ +typedef struct{ +uint16_t ProtocolExtensionID; +}LIBLTE_S1AP_PROTOCOLEXTENSIONID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolextensionid( + LIBLTE_S1AP_PROTOCOLEXTENSIONID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolextensionid( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLEXTENSIONID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TriggeringMessage ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_TRIGGERINGMESSAGE_INITIATING_MESSAGE, + LIBLTE_S1AP_TRIGGERINGMESSAGE_SUCCESSFUL_OUTCOME, + LIBLTE_S1AP_TRIGGERINGMESSAGE_UNSUCCESSFULL_OUTCOME, + LIBLTE_S1AP_TRIGGERINGMESSAGE_N_ITEMS, +}LIBLTE_S1AP_TRIGGERINGMESSAGE_ENUM; +static const char liblte_s1ap_triggeringmessage_text[LIBLTE_S1AP_TRIGGERINGMESSAGE_N_ITEMS][80] = { + "initiating-message", + "successful-outcome", + "unsuccessfull-outcome", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_triggeringmessage( + LIBLTE_S1AP_TRIGGERINGMESSAGE_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_triggeringmessage( + uint8_t **ptr, + LIBLTE_S1AP_TRIGGERINGMESSAGE_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE Presence ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PRESENCE_OPTIONAL, + LIBLTE_S1AP_PRESENCE_CONDITIONAL, + LIBLTE_S1AP_PRESENCE_MANDATORY, + LIBLTE_S1AP_PRESENCE_N_ITEMS, +}LIBLTE_S1AP_PRESENCE_ENUM; +static const char liblte_s1ap_presence_text[LIBLTE_S1AP_PRESENCE_N_ITEMS][80] = { + "optional", + "conditional", + "mandatory", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_presence( + LIBLTE_S1AP_PRESENCE_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_presence( + uint8_t **ptr, + LIBLTE_S1AP_PRESENCE_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolIE_ID INTEGER +********************************************************************************/ +typedef struct{ +uint16_t ProtocolIE_ID; +}LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_id( + LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_id( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProcedureCode INTEGER +********************************************************************************/ +typedef struct{ +uint8_t ProcedureCode; +}LIBLTE_S1AP_PROCEDURECODE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_procedurecode( + LIBLTE_S1AP_PROCEDURECODE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_procedurecode( + uint8_t **ptr, + LIBLTE_S1AP_PROCEDURECODE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolIE_Field SEQUENCE +********************************************************************************/ +typedef struct{ + LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT id; + LIBLTE_S1AP_CRITICALITY_ENUM criticality; + LIBLTE_ASN1_OPEN_TYPE_STRUCT value; +}LIBLTE_S1AP_PROTOCOLIE_FIELD_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_field( + LIBLTE_S1AP_PROTOCOLIE_FIELD_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_field( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_FIELD_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolExtensionField SEQUENCE +********************************************************************************/ +typedef struct{ + LIBLTE_S1AP_PROTOCOLEXTENSIONID_STRUCT id; + LIBLTE_S1AP_CRITICALITY_ENUM criticality; + LIBLTE_ASN1_OPEN_TYPE_STRUCT extensionValue; +}LIBLTE_S1AP_PROTOCOLEXTENSIONFIELD_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolextensionfield( + LIBLTE_S1AP_PROTOCOLEXTENSIONFIELD_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolextensionfield( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLEXTENSIONFIELD_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolIE_FieldPair SEQUENCE +********************************************************************************/ +typedef struct{ + LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT id; + LIBLTE_S1AP_CRITICALITY_ENUM firstCriticality; + LIBLTE_ASN1_OPEN_TYPE_STRUCT firstValue; + LIBLTE_S1AP_CRITICALITY_ENUM secondCriticality; + LIBLTE_ASN1_OPEN_TYPE_STRUCT secondValue; +}LIBLTE_S1AP_PROTOCOLIE_FIELDPAIR_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_fieldpair( + LIBLTE_S1AP_PROTOCOLIE_FIELDPAIR_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_fieldpair( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_FIELDPAIR_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolExtensionContainer DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_PROTOCOLEXTENSIONFIELD_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolextensioncontainer( + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolextensioncontainer( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolIE_ContainerPair DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:0, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_PROTOCOLIE_FIELDPAIR_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIR_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_containerpair( + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIR_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_containerpair( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIR_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolIE_ContainerPairList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:None, ub:None +typedef struct{ + uint32_t len; + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIR_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIRLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_containerpairlist( + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIRLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_containerpairlist( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIRLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE PrivateIE_Field SEQUENCE +********************************************************************************/ +typedef struct{ + LIBLTE_S1AP_PRIVATEIE_ID_STRUCT id; + LIBLTE_S1AP_CRITICALITY_ENUM criticality; + LIBLTE_ASN1_OPEN_TYPE_STRUCT value; +}LIBLTE_S1AP_PRIVATEIE_FIELD_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privateie_field( + LIBLTE_S1AP_PRIVATEIE_FIELD_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privateie_field( + uint8_t **ptr, + LIBLTE_S1AP_PRIVATEIE_FIELD_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ProtocolIE_SingleContainer SEQUENCE +********************************************************************************/ +typedef struct{ + LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT id; + LIBLTE_S1AP_CRITICALITY_ENUM criticality; + LIBLTE_ASN1_OPEN_TYPE_STRUCT value; +}LIBLTE_S1AP_PROTOCOLIE_SINGLECONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_singlecontainer( + LIBLTE_S1AP_PROTOCOLIE_SINGLECONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_singlecontainer( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_SINGLECONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE PrivateIE_Container DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_PRIVATEIE_FIELD_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_PRIVATEIE_CONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privateie_container( + LIBLTE_S1AP_PRIVATEIE_CONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privateie_container( + uint8_t **ptr, + LIBLTE_S1AP_PRIVATEIE_CONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE BitRate INTEGER +********************************************************************************/ +typedef struct{ +uint32_t BitRate; +}LIBLTE_S1AP_BITRATE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bitrate( + LIBLTE_S1AP_BITRATE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bitrate( + uint8_t **ptr, + LIBLTE_S1AP_BITRATE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CauseMisc ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CAUSEMISC_CONTROL_PROCESSING_OVERLOAD, + LIBLTE_S1AP_CAUSEMISC_NOT_ENOUGH_USER_PLANE_PROCESSING_RESOURCES, + LIBLTE_S1AP_CAUSEMISC_HARDWARE_FAILURE, + LIBLTE_S1AP_CAUSEMISC_OM_INTERVENTION, + LIBLTE_S1AP_CAUSEMISC_UNSPECIFIED, + LIBLTE_S1AP_CAUSEMISC_UNKNOWN_PLMN, + LIBLTE_S1AP_CAUSEMISC_N_ITEMS, +}LIBLTE_S1AP_CAUSEMISC_ENUM; +static const char liblte_s1ap_causemisc_text[LIBLTE_S1AP_CAUSEMISC_N_ITEMS][80] = { + "control-processing-overload", + "not-enough-user-plane-processing-resources", + "hardware-failure", + "om-intervention", + "unspecified", + "unknown-PLMN", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSEMISC_ENUM e; +}LIBLTE_S1AP_CAUSEMISC_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causemisc( + LIBLTE_S1AP_CAUSEMISC_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causemisc( + uint8_t **ptr, + LIBLTE_S1AP_CAUSEMISC_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE CauseRadioNetwork ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CAUSERADIONETWORK_UNSPECIFIED, + LIBLTE_S1AP_CAUSERADIONETWORK_TX2RELOCOVERALL_EXPIRY, + LIBLTE_S1AP_CAUSERADIONETWORK_SUCCESSFUL_HANDOVER, + LIBLTE_S1AP_CAUSERADIONETWORK_RELEASE_DUE_TO_EUTRAN_GENERATED_REASON, + LIBLTE_S1AP_CAUSERADIONETWORK_HANDOVER_CANCELLED, + LIBLTE_S1AP_CAUSERADIONETWORK_PARTIAL_HANDOVER, + LIBLTE_S1AP_CAUSERADIONETWORK_HO_FAILURE_IN_TARGET_EPC_ENB_OR_TARGET_SYSTEM, + LIBLTE_S1AP_CAUSERADIONETWORK_HO_TARGET_NOT_ALLOWED, + LIBLTE_S1AP_CAUSERADIONETWORK_TS1RELOCOVERALL_EXPIRY, + LIBLTE_S1AP_CAUSERADIONETWORK_TS1RELOCPREP_EXPIRY, + LIBLTE_S1AP_CAUSERADIONETWORK_CELL_NOT_AVAILABLE, + LIBLTE_S1AP_CAUSERADIONETWORK_UNKNOWN_TARGETID, + LIBLTE_S1AP_CAUSERADIONETWORK_NO_RADIO_RESOURCES_AVAILABLE_IN_TARGET_CELL, + LIBLTE_S1AP_CAUSERADIONETWORK_UNKNOWN_MME_UE_S1AP_ID, + LIBLTE_S1AP_CAUSERADIONETWORK_UNKNOWN_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CAUSERADIONETWORK_UNKNOWN_PAIR_UE_S1AP_ID, + LIBLTE_S1AP_CAUSERADIONETWORK_HANDOVER_DESIRABLE_FOR_RADIO_REASON, + LIBLTE_S1AP_CAUSERADIONETWORK_TIME_CRITICAL_HANDOVER, + LIBLTE_S1AP_CAUSERADIONETWORK_RESOURCE_OPTIMISATION_HANDOVER, + LIBLTE_S1AP_CAUSERADIONETWORK_REDUCE_LOAD_IN_SERVING_CELL, + LIBLTE_S1AP_CAUSERADIONETWORK_USER_INACTIVITY, + LIBLTE_S1AP_CAUSERADIONETWORK_RADIO_CONNECTION_WITH_UE_LOST, + LIBLTE_S1AP_CAUSERADIONETWORK_LOAD_BALANCING_TAU_REQUIRED, + LIBLTE_S1AP_CAUSERADIONETWORK_CS_FALLBACK_TRIGGERED, + LIBLTE_S1AP_CAUSERADIONETWORK_UE_NOT_AVAILABLE_FOR_PS_SERVICE, + LIBLTE_S1AP_CAUSERADIONETWORK_RADIO_RESOURCES_NOT_AVAILABLE, + LIBLTE_S1AP_CAUSERADIONETWORK_FAILURE_IN_RADIO_INTERFACE_PROCEDURE, + LIBLTE_S1AP_CAUSERADIONETWORK_INVALID_QOS_COMBINATION, + LIBLTE_S1AP_CAUSERADIONETWORK_INTERRAT_REDIRECTION, + LIBLTE_S1AP_CAUSERADIONETWORK_INTERACTION_WITH_OTHER_PROCEDURE, + LIBLTE_S1AP_CAUSERADIONETWORK_UNKNOWN_E_RAB_ID, + LIBLTE_S1AP_CAUSERADIONETWORK_MULTIPLE_E_RAB_ID_INSTANCES, + LIBLTE_S1AP_CAUSERADIONETWORK_ENCRYPTION_AND_OR_INTEGRITY_PROTECTION_ALGORITHMS_NOT_SUPPORTED, + LIBLTE_S1AP_CAUSERADIONETWORK_S1_INTRA_SYSTEM_HANDOVER_TRIGGERED, + LIBLTE_S1AP_CAUSERADIONETWORK_S1_INTER_SYSTEM_HANDOVER_TRIGGERED, + LIBLTE_S1AP_CAUSERADIONETWORK_X2_HANDOVER_TRIGGERED, + LIBLTE_S1AP_CAUSERADIONETWORK_REDIRECTION_TOWARDS_1XRTT, + LIBLTE_S1AP_CAUSERADIONETWORK_NOT_SUPPORTED_QCI_VALUE, + LIBLTE_S1AP_CAUSERADIONETWORK_INVALID_CSG_ID, + LIBLTE_S1AP_CAUSERADIONETWORK_N_ITEMS, +}LIBLTE_S1AP_CAUSERADIONETWORK_ENUM; +static const char liblte_s1ap_causeradionetwork_text[LIBLTE_S1AP_CAUSERADIONETWORK_N_ITEMS][80] = { + "unspecified", + "tx2relocoverall-expiry", + "successful-handover", + "release-due-to-eutran-generated-reason", + "handover-cancelled", + "partial-handover", + "ho-failure-in-target-EPC-eNB-or-target-system", + "ho-target-not-allowed", + "tS1relocoverall-expiry", + "tS1relocprep-expiry", + "cell-not-available", + "unknown-targetID", + "no-radio-resources-available-in-target-cell", + "unknown-mme-ue-s1ap-id", + "unknown-enb-ue-s1ap-id", + "unknown-pair-ue-s1ap-id", + "handover-desirable-for-radio-reason", + "time-critical-handover", + "resource-optimisation-handover", + "reduce-load-in-serving-cell", + "user-inactivity", + "radio-connection-with-ue-lost", + "load-balancing-tau-required", + "cs-fallback-triggered", + "ue-not-available-for-ps-service", + "radio-resources-not-available", + "failure-in-radio-interface-procedure", + "invalid-qos-combination", + "interrat-redirection", + "interaction-with-other-procedure", + "unknown-E-RAB-ID", + "multiple-E-RAB-ID-instances", + "encryption-and-or-integrity-protection-algorithms-not-supported", + "s1-intra-system-handover-triggered", + "s1-inter-system-handover-triggered", + "x2-handover-triggered", + "redirection-towards-1xRTT", + "not-supported-QCI-value", + "invalid-CSG-Id", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSERADIONETWORK_ENUM e; +}LIBLTE_S1AP_CAUSERADIONETWORK_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causeradionetwork( + LIBLTE_S1AP_CAUSERADIONETWORK_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causeradionetwork( + uint8_t **ptr, + LIBLTE_S1AP_CAUSERADIONETWORK_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE CauseNas ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CAUSENAS_NORMAL_RELEASE, + LIBLTE_S1AP_CAUSENAS_AUTHENTICATION_FAILURE, + LIBLTE_S1AP_CAUSENAS_DETACH, + LIBLTE_S1AP_CAUSENAS_UNSPECIFIED, + LIBLTE_S1AP_CAUSENAS_CSG_SUBSCRIPTION_EXPIRY, + LIBLTE_S1AP_CAUSENAS_N_ITEMS, +}LIBLTE_S1AP_CAUSENAS_ENUM; +static const char liblte_s1ap_causenas_text[LIBLTE_S1AP_CAUSENAS_N_ITEMS][80] = { + "normal-release", + "authentication-failure", + "detach", + "unspecified", + "csg-subscription-expiry", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSENAS_ENUM e; +}LIBLTE_S1AP_CAUSENAS_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causenas( + LIBLTE_S1AP_CAUSENAS_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causenas( + uint8_t **ptr, + LIBLTE_S1AP_CAUSENAS_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE CellIdentity STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_CELLIDENTITY_BIT_STRING_LEN 28 +typedef struct{ + uint8_t buffer[28]; +}LIBLTE_S1AP_CELLIDENTITY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellidentity( + LIBLTE_S1AP_CELLIDENTITY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellidentity( + uint8_t **ptr, + LIBLTE_S1AP_CELLIDENTITY_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000PDU DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_CDMA2000PDU_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000pdu( + LIBLTE_S1AP_CDMA2000PDU_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000pdu( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000PDU_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000SectorID DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_CDMA2000SECTORID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000sectorid( + LIBLTE_S1AP_CDMA2000SECTORID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000sectorid( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000SECTORID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000HORequiredIndication ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_TRUE, + LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_N_ITEMS, +}LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM; +static const char liblte_s1ap_cdma2000horequiredindication_text[LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_N_ITEMS][80] = { + "true", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM e; +}LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000horequiredindication( + LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000horequiredindication( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXMSI DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_CDMA2000ONEXMSI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexmsi( + LIBLTE_S1AP_CDMA2000ONEXMSI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexmsi( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXMSI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXRAND DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_CDMA2000ONEXRAND_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexrand( + LIBLTE_S1AP_CDMA2000ONEXRAND_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexrand( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXRAND_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CNDomain ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CNDOMAIN_PS, + LIBLTE_S1AP_CNDOMAIN_CS, + LIBLTE_S1AP_CNDOMAIN_N_ITEMS, +}LIBLTE_S1AP_CNDOMAIN_ENUM; +static const char liblte_s1ap_cndomain_text[LIBLTE_S1AP_CNDOMAIN_N_ITEMS][80] = { + "ps", + "cs", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cndomain( + LIBLTE_S1AP_CNDOMAIN_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cndomain( + uint8_t **ptr, + LIBLTE_S1AP_CNDOMAIN_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE Correlation_ID STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_CORRELATION_ID_OCTET_STRING_LEN 4 +typedef struct{ + uint8_t buffer[4]; +}LIBLTE_S1AP_CORRELATION_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_correlation_id( + LIBLTE_S1AP_CORRELATION_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_correlation_id( + uint8_t **ptr, + LIBLTE_S1AP_CORRELATION_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE AdditionalCSFallbackIndicator ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_NO_RESTRICTION, + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_RESTRICTION, + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_N_ITEMS, +}LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM; +static const char liblte_s1ap_additionalcsfallbackindicator_text[LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_N_ITEMS][80] = { + "no-restriction", + "restriction", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM e; +}LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_additionalcsfallbackindicator( + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_additionalcsfallbackindicator( + uint8_t **ptr, + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE DL_Forwarding ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_DL_FORWARDING_DL_FORWARDING_PROPOSED, + LIBLTE_S1AP_DL_FORWARDING_N_ITEMS, +}LIBLTE_S1AP_DL_FORWARDING_ENUM; +static const char liblte_s1ap_dl_forwarding_text[LIBLTE_S1AP_DL_FORWARDING_N_ITEMS][80] = { + "dL-Forwarding-proposed", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_DL_FORWARDING_ENUM e; +}LIBLTE_S1AP_DL_FORWARDING_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_dl_forwarding( + LIBLTE_S1AP_DL_FORWARDING_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_dl_forwarding( + uint8_t **ptr, + LIBLTE_S1AP_DL_FORWARDING_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Data_Forwarding_Not_Possible ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_DATA_FORWARDING_NOT_POSSIBLE, + LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_N_ITEMS, +}LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM; +static const char liblte_s1ap_data_forwarding_not_possible_text[LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_N_ITEMS][80] = { + "data-Forwarding-not-Possible", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM e; +}LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_data_forwarding_not_possible( + LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_data_forwarding_not_possible( + uint8_t **ptr, + LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_EMERGENCYAREAID_OCTET_STRING_LEN 3 +typedef struct{ + uint8_t buffer[3]; +}LIBLTE_S1AP_EMERGENCYAREAID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid( + LIBLTE_S1AP_EMERGENCYAREAID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE macroENB_ID STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_MACROENB_ID_BIT_STRING_LEN 20 +typedef struct{ + uint8_t buffer[20]; +}LIBLTE_S1AP_MACROENB_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_macroenb_id( + LIBLTE_S1AP_MACROENB_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_macroenb_id( + uint8_t **ptr, + LIBLTE_S1AP_MACROENB_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE homeENB_ID STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_HOMEENB_ID_BIT_STRING_LEN 28 +typedef struct{ + uint8_t buffer[28]; +}LIBLTE_S1AP_HOMEENB_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_homeenb_id( + LIBLTE_S1AP_HOMEENB_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_homeenb_id( + uint8_t **ptr, + LIBLTE_S1AP_HOMEENB_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ENB_ID CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_ENB_ID_CHOICE_MACROENB_ID, + LIBLTE_S1AP_ENB_ID_CHOICE_HOMEENB_ID, + LIBLTE_S1AP_ENB_ID_CHOICE_N_ITEMS, +}LIBLTE_S1AP_ENB_ID_CHOICE_ENUM; +static const char liblte_s1ap_enb_id_choice_text[LIBLTE_S1AP_ENB_ID_CHOICE_N_ITEMS][50] = { + "macroENB_ID", + "homeENB_ID", +}; + +typedef union{ + LIBLTE_S1AP_MACROENB_ID_STRUCT macroENB_ID; + LIBLTE_S1AP_HOMEENB_ID_STRUCT homeENB_ID; +}LIBLTE_S1AP_ENB_ID_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_ENB_ID_CHOICE_UNION choice; + LIBLTE_S1AP_ENB_ID_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_ENB_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_id( + LIBLTE_S1AP_ENB_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_id( + uint8_t **ptr, + LIBLTE_S1AP_ENB_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ENBname PrintableString +********************************************************************************/ +typedef struct{ + bool ext; + uint32_t n_octets; + uint8_t buffer[150]; +}LIBLTE_S1AP_ENBNAME_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbname( + LIBLTE_S1AP_ENBNAME_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbname( + uint8_t **ptr, + LIBLTE_S1AP_ENBNAME_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EncryptionAlgorithms STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_ENCRYPTIONALGORITHMS_BIT_STRING_LEN 16 +typedef struct{ + bool ext; + uint8_t buffer[16]; +}LIBLTE_S1AP_ENCRYPTIONALGORITHMS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_encryptionalgorithms( + LIBLTE_S1AP_ENCRYPTIONALGORITHMS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_encryptionalgorithms( + uint8_t **ptr, + LIBLTE_S1AP_ENCRYPTIONALGORITHMS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EventType ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_EVENTTYPE_DIRECT, + LIBLTE_S1AP_EVENTTYPE_CHANGE_OF_SERVE_CELL, + LIBLTE_S1AP_EVENTTYPE_STOP_CHANGE_OF_SERVE_CELL, + LIBLTE_S1AP_EVENTTYPE_N_ITEMS, +}LIBLTE_S1AP_EVENTTYPE_ENUM; +static const char liblte_s1ap_eventtype_text[LIBLTE_S1AP_EVENTTYPE_N_ITEMS][80] = { + "direct", + "change-of-serve-cell", + "stop-change-of-serve-cell", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_EVENTTYPE_ENUM e; +}LIBLTE_S1AP_EVENTTYPE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eventtype( + LIBLTE_S1AP_EVENTTYPE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eventtype( + uint8_t **ptr, + LIBLTE_S1AP_EVENTTYPE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE ExtendedRNC_ID INTEGER +********************************************************************************/ +typedef struct{ +uint16_t ExtendedRNC_ID; +}LIBLTE_S1AP_EXTENDEDRNC_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_extendedrnc_id( + LIBLTE_S1AP_EXTENDEDRNC_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_extendedrnc_id( + uint8_t **ptr, + LIBLTE_S1AP_EXTENDEDRNC_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ForbiddenInterRATs ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_FORBIDDENINTERRATS_ALL, + LIBLTE_S1AP_FORBIDDENINTERRATS_GERAN, + LIBLTE_S1AP_FORBIDDENINTERRATS_UTRAN, + LIBLTE_S1AP_FORBIDDENINTERRATS_CDMA2000, + LIBLTE_S1AP_FORBIDDENINTERRATS_GERANANDUTRAN, + LIBLTE_S1AP_FORBIDDENINTERRATS_CDMA2000ANDUTRAN, + LIBLTE_S1AP_FORBIDDENINTERRATS_N_ITEMS, +}LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM; +static const char liblte_s1ap_forbiddeninterrats_text[LIBLTE_S1AP_FORBIDDENINTERRATS_N_ITEMS][80] = { + "all", + "geran", + "utran", + "cdma2000", + "geranandutran", + "cdma2000andutran", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM e; +}LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddeninterrats( + LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddeninterrats( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE GWContextReleaseIndication ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_TRUE, + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_N_ITEMS, +}LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM; +static const char liblte_s1ap_gwcontextreleaseindication_text[LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_N_ITEMS][80] = { + "true", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM e; +}LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gwcontextreleaseindication( + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gwcontextreleaseindication( + uint8_t **ptr, + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE HFN INTEGER +********************************************************************************/ +typedef struct{ +uint32_t HFN; +}LIBLTE_S1AP_HFN_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_hfn( + LIBLTE_S1AP_HFN_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_hfn( + uint8_t **ptr, + LIBLTE_S1AP_HFN_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE IMSI DYNAMIC OCTET STRING +********************************************************************************/ +// lb:3, ub:8 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[8]; +}LIBLTE_S1AP_IMSI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_imsi( + LIBLTE_S1AP_IMSI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_imsi( + uint8_t **ptr, + LIBLTE_S1AP_IMSI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE InterfacesToTrace STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_INTERFACESTOTRACE_BIT_STRING_LEN 8 +typedef struct{ + uint8_t buffer[8]; +}LIBLTE_S1AP_INTERFACESTOTRACE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_interfacestotrace( + LIBLTE_S1AP_INTERFACESTOTRACE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_interfacestotrace( + uint8_t **ptr, + LIBLTE_S1AP_INTERFACESTOTRACE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE LAC STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_LAC_OCTET_STRING_LEN 2 +typedef struct{ + uint8_t buffer[2]; +}LIBLTE_S1AP_LAC_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lac( + LIBLTE_S1AP_LAC_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lac( + uint8_t **ptr, + LIBLTE_S1AP_LAC_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE LastVisitedUTRANCellInformation DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_LASTVISITEDUTRANCELLINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedutrancellinformation( + LIBLTE_S1AP_LASTVISITEDUTRANCELLINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedutrancellinformation( + uint8_t **ptr, + LIBLTE_S1AP_LASTVISITEDUTRANCELLINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE L3_Information DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_L3_INFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_l3_information( + LIBLTE_S1AP_L3_INFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_l3_information( + uint8_t **ptr, + LIBLTE_S1AP_L3_INFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE LHN_ID DYNAMIC OCTET STRING +********************************************************************************/ +// lb:32, ub:256 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[256]; +}LIBLTE_S1AP_LHN_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lhn_id( + LIBLTE_S1AP_LHN_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lhn_id( + uint8_t **ptr, + LIBLTE_S1AP_LHN_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE LoggingDuration ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_LOGGINGDURATION_M10, + LIBLTE_S1AP_LOGGINGDURATION_M20, + LIBLTE_S1AP_LOGGINGDURATION_M40, + LIBLTE_S1AP_LOGGINGDURATION_M60, + LIBLTE_S1AP_LOGGINGDURATION_M90, + LIBLTE_S1AP_LOGGINGDURATION_M120, + LIBLTE_S1AP_LOGGINGDURATION_N_ITEMS, +}LIBLTE_S1AP_LOGGINGDURATION_ENUM; +static const char liblte_s1ap_loggingduration_text[LIBLTE_S1AP_LOGGINGDURATION_N_ITEMS][80] = { + "m10", + "m20", + "m40", + "m60", + "m90", + "m120", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_loggingduration( + LIBLTE_S1AP_LOGGINGDURATION_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_loggingduration( + uint8_t **ptr, + LIBLTE_S1AP_LOGGINGDURATION_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE MDT_Activation ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_MDT_ACTIVATION_IMMEDIATE_MDT_ONLY, + LIBLTE_S1AP_MDT_ACTIVATION_IMMEDIATE_MDT_AND_TRACE, + LIBLTE_S1AP_MDT_ACTIVATION_LOGGED_MDT_ONLY, + LIBLTE_S1AP_MDT_ACTIVATION_N_ITEMS, +}LIBLTE_S1AP_MDT_ACTIVATION_ENUM; +static const char liblte_s1ap_mdt_activation_text[LIBLTE_S1AP_MDT_ACTIVATION_N_ITEMS][80] = { + "immediate-MDT-only", + "immediate-MDT-and-Trace", + "logged-MDT-only", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_MDT_ACTIVATION_ENUM e; +}LIBLTE_S1AP_MDT_ACTIVATION_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdt_activation( + LIBLTE_S1AP_MDT_ACTIVATION_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdt_activation( + uint8_t **ptr, + LIBLTE_S1AP_MDT_ACTIVATION_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE ManagementBasedMDTAllowed ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ALLOWED, + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_N_ITEMS, +}LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM; +static const char liblte_s1ap_managementbasedmdtallowed_text[LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_N_ITEMS][80] = { + "allowed", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM e; +}LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_managementbasedmdtallowed( + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_managementbasedmdtallowed( + uint8_t **ptr, + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE PrivacyIndicator ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PRIVACYINDICATOR_IMMEDIATE_MDT, + LIBLTE_S1AP_PRIVACYINDICATOR_LOGGED_MDT, + LIBLTE_S1AP_PRIVACYINDICATOR_N_ITEMS, +}LIBLTE_S1AP_PRIVACYINDICATOR_ENUM; +static const char liblte_s1ap_privacyindicator_text[LIBLTE_S1AP_PRIVACYINDICATOR_N_ITEMS][80] = { + "immediate-MDT", + "logged-MDT", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_PRIVACYINDICATOR_ENUM e; +}LIBLTE_S1AP_PRIVACYINDICATOR_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privacyindicator( + LIBLTE_S1AP_PRIVACYINDICATOR_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privacyindicator( + uint8_t **ptr, + LIBLTE_S1AP_PRIVACYINDICATOR_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE MeasurementsToActivate STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_MEASUREMENTSTOACTIVATE_BIT_STRING_LEN 8 +typedef struct{ + uint8_t buffer[8]; +}LIBLTE_S1AP_MEASUREMENTSTOACTIVATE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_measurementstoactivate( + LIBLTE_S1AP_MEASUREMENTSTOACTIVATE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_measurementstoactivate( + uint8_t **ptr, + LIBLTE_S1AP_MEASUREMENTSTOACTIVATE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MessageIdentifier STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_MESSAGEIDENTIFIER_BIT_STRING_LEN 16 +typedef struct{ + uint8_t buffer[16]; +}LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_messageidentifier( + LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_messageidentifier( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MMEname PrintableString +********************************************************************************/ +typedef struct{ + bool ext; + uint32_t n_octets; + uint8_t buffer[150]; +}LIBLTE_S1AP_MMENAME_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmename( + LIBLTE_S1AP_MMENAME_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmename( + uint8_t **ptr, + LIBLTE_S1AP_MMENAME_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MME_Group_ID STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_MME_GROUP_ID_OCTET_STRING_LEN 2 +typedef struct{ + uint8_t buffer[2]; +}LIBLTE_S1AP_MME_GROUP_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mme_group_id( + LIBLTE_S1AP_MME_GROUP_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mme_group_id( + uint8_t **ptr, + LIBLTE_S1AP_MME_GROUP_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MME_UE_S1AP_ID INTEGER +********************************************************************************/ +typedef struct{ +uint32_t MME_UE_S1AP_ID; +}LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mme_ue_s1ap_id( + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mme_ue_s1ap_id( + uint8_t **ptr, + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MSClassmark2 DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_MSCLASSMARK2_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_msclassmark2( + LIBLTE_S1AP_MSCLASSMARK2_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_msclassmark2( + uint8_t **ptr, + LIBLTE_S1AP_MSCLASSMARK2_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE NAS_PDU DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_NAS_PDU_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nas_pdu( + LIBLTE_S1AP_NAS_PDU_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nas_pdu( + uint8_t **ptr, + LIBLTE_S1AP_NAS_PDU_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE NASSecurityParameterstoE_UTRAN DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_NASSECURITYPARAMETERSTOE_UTRAN_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nassecurityparameterstoe_utran( + LIBLTE_S1AP_NASSECURITYPARAMETERSTOE_UTRAN_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nassecurityparameterstoe_utran( + uint8_t **ptr, + LIBLTE_S1AP_NASSECURITYPARAMETERSTOE_UTRAN_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE NumberOfBroadcasts INTEGER +********************************************************************************/ +typedef struct{ +uint16_t NumberOfBroadcasts; +}LIBLTE_S1AP_NUMBEROFBROADCASTS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_numberofbroadcasts( + LIBLTE_S1AP_NUMBEROFBROADCASTS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_numberofbroadcasts( + uint8_t **ptr, + LIBLTE_S1AP_NUMBEROFBROADCASTS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE OverloadAction ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_OVERLOADACTION_REJECT_NON_EMERGENCY_MO_DT, + LIBLTE_S1AP_OVERLOADACTION_REJECT_RRC_CR_SIGNALLING, + LIBLTE_S1AP_OVERLOADACTION_PERMIT_EMERGENCY_SESSIONS_AND_MOBILE_TERMINATED_SERVICES_ONLY, + LIBLTE_S1AP_OVERLOADACTION_PERMIT_HIGH_PRIORITY_SESSIONS_AND_MOBILE_TERMINATED_SERVICES_ONLY, + LIBLTE_S1AP_OVERLOADACTION_REJECT_DELAY_TOLERANT_ACCESS, + LIBLTE_S1AP_OVERLOADACTION_N_ITEMS, +}LIBLTE_S1AP_OVERLOADACTION_ENUM; +static const char liblte_s1ap_overloadaction_text[LIBLTE_S1AP_OVERLOADACTION_N_ITEMS][80] = { + "reject-non-emergency-mo-dt", + "reject-rrc-cr-signalling", + "permit-emergency-sessions-and-mobile-terminated-services-only", + "permit-high-priority-sessions-and-mobile-terminated-services-only", + "reject-delay-tolerant-access", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_OVERLOADACTION_ENUM e; +}LIBLTE_S1AP_OVERLOADACTION_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_overloadaction( + LIBLTE_S1AP_OVERLOADACTION_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_overloadaction( + uint8_t **ptr, + LIBLTE_S1AP_OVERLOADACTION_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE PagingDRX ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PAGINGDRX_V32, + LIBLTE_S1AP_PAGINGDRX_V64, + LIBLTE_S1AP_PAGINGDRX_V128, + LIBLTE_S1AP_PAGINGDRX_V256, + LIBLTE_S1AP_PAGINGDRX_N_ITEMS, +}LIBLTE_S1AP_PAGINGDRX_ENUM; +static const char liblte_s1ap_pagingdrx_text[LIBLTE_S1AP_PAGINGDRX_N_ITEMS][80] = { + "v32", + "v64", + "v128", + "v256", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_PAGINGDRX_ENUM e; +}LIBLTE_S1AP_PAGINGDRX_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pagingdrx( + LIBLTE_S1AP_PAGINGDRX_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pagingdrx( + uint8_t **ptr, + LIBLTE_S1AP_PAGINGDRX_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE PDCP_SN INTEGER +********************************************************************************/ +typedef struct{ +uint16_t PDCP_SN; +}LIBLTE_S1AP_PDCP_SN_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pdcp_sn( + LIBLTE_S1AP_PDCP_SN_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pdcp_sn( + uint8_t **ptr, + LIBLTE_S1AP_PDCP_SN_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Port_Number STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_PORT_NUMBER_OCTET_STRING_LEN 2 +typedef struct{ + uint8_t buffer[2]; +}LIBLTE_S1AP_PORT_NUMBER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_port_number( + LIBLTE_S1AP_PORT_NUMBER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_port_number( + uint8_t **ptr, + LIBLTE_S1AP_PORT_NUMBER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Pre_emptionVulnerability ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_NOT_PRE_EMPTABLE, + LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_PRE_EMPTABLE, + LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_N_ITEMS, +}LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM; +static const char liblte_s1ap_pre_emptionvulnerability_text[LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_N_ITEMS][80] = { + "not-pre-emptable", + "pre-emptable", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pre_emptionvulnerability( + LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pre_emptionvulnerability( + uint8_t **ptr, + LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE PS_ServiceNotAvailable ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_PS_SERVICE_NOT_AVAILABLE, + LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_N_ITEMS, +}LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM; +static const char liblte_s1ap_ps_servicenotavailable_text[LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_N_ITEMS][80] = { + "ps-service-not-available", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM e; +}LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ps_servicenotavailable( + LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ps_servicenotavailable( + uint8_t **ptr, + LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE ReceiveStatusofULPDCPSDUs STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUS_BIT_STRING_LEN 4096 +typedef struct{ + uint8_t buffer[4096]; +}LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_receivestatusofulpdcpsdus( + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_receivestatusofulpdcpsdus( + uint8_t **ptr, + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RelativeMMECapacity INTEGER +********************************************************************************/ +typedef struct{ +uint8_t RelativeMMECapacity; +}LIBLTE_S1AP_RELATIVEMMECAPACITY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_relativemmecapacity( + LIBLTE_S1AP_RELATIVEMMECAPACITY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_relativemmecapacity( + uint8_t **ptr, + LIBLTE_S1AP_RELATIVEMMECAPACITY_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RAC STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_RAC_OCTET_STRING_LEN 1 +typedef struct{ + uint8_t buffer[1]; +}LIBLTE_S1AP_RAC_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rac( + LIBLTE_S1AP_RAC_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rac( + uint8_t **ptr, + LIBLTE_S1AP_RAC_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ReportIntervalMDT ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_REPORTINTERVALMDT_MS120, + LIBLTE_S1AP_REPORTINTERVALMDT_MS240, + LIBLTE_S1AP_REPORTINTERVALMDT_MS480, + LIBLTE_S1AP_REPORTINTERVALMDT_MS640, + LIBLTE_S1AP_REPORTINTERVALMDT_MS1024, + LIBLTE_S1AP_REPORTINTERVALMDT_MS2048, + LIBLTE_S1AP_REPORTINTERVALMDT_MS5120, + LIBLTE_S1AP_REPORTINTERVALMDT_MS10240, + LIBLTE_S1AP_REPORTINTERVALMDT_MIN1, + LIBLTE_S1AP_REPORTINTERVALMDT_MIN6, + LIBLTE_S1AP_REPORTINTERVALMDT_MIN12, + LIBLTE_S1AP_REPORTINTERVALMDT_MIN30, + LIBLTE_S1AP_REPORTINTERVALMDT_MIN60, + LIBLTE_S1AP_REPORTINTERVALMDT_N_ITEMS, +}LIBLTE_S1AP_REPORTINTERVALMDT_ENUM; +static const char liblte_s1ap_reportintervalmdt_text[LIBLTE_S1AP_REPORTINTERVALMDT_N_ITEMS][80] = { + "ms120", + "ms240", + "ms480", + "ms640", + "ms1024", + "ms2048", + "ms5120", + "ms10240", + "min1", + "min6", + "min12", + "min30", + "min60", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_reportintervalmdt( + LIBLTE_S1AP_REPORTINTERVALMDT_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_reportintervalmdt( + uint8_t **ptr, + LIBLTE_S1AP_REPORTINTERVALMDT_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE ReportArea ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_REPORTAREA_ECGI, + LIBLTE_S1AP_REPORTAREA_N_ITEMS, +}LIBLTE_S1AP_REPORTAREA_ENUM; +static const char liblte_s1ap_reportarea_text[LIBLTE_S1AP_REPORTAREA_N_ITEMS][80] = { + "ecgi", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_REPORTAREA_ENUM e; +}LIBLTE_S1AP_REPORTAREA_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_reportarea( + LIBLTE_S1AP_REPORTAREA_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_reportarea( + uint8_t **ptr, + LIBLTE_S1AP_REPORTAREA_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE RNC_ID INTEGER +********************************************************************************/ +typedef struct{ +uint16_t RNC_ID; +}LIBLTE_S1AP_RNC_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rnc_id( + LIBLTE_S1AP_RNC_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rnc_id( + uint8_t **ptr, + LIBLTE_S1AP_RNC_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RRC_Establishment_Cause ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_EMERGENCY, + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_HIGHPRIORITYACCESS, + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_MT_ACCESS, + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_MO_SIGNALLING, + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_MO_DATA, + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_DELAY_TOLERANTACCESS, + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_N_ITEMS, +}LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM; +static const char liblte_s1ap_rrc_establishment_cause_text[LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_N_ITEMS][80] = { + "emergency", + "highPriorityAccess", + "mt-Access", + "mo-Signalling", + "mo-Data", + "delay-TolerantAccess", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM e; +}LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rrc_establishment_cause( + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rrc_establishment_cause( + uint8_t **ptr, + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Routing_ID INTEGER +********************************************************************************/ +typedef struct{ +uint8_t Routing_ID; +}LIBLTE_S1AP_ROUTING_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_routing_id( + LIBLTE_S1AP_ROUTING_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_routing_id( + uint8_t **ptr, + LIBLTE_S1AP_ROUTING_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SONInformationRequest ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_SONINFORMATIONREQUEST_X2TNL_CONFIGURATION_INFO, + LIBLTE_S1AP_SONINFORMATIONREQUEST_TIME_SYNCHRONIZATION_INFO, + LIBLTE_S1AP_SONINFORMATIONREQUEST_N_ITEMS, +}LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM; +static const char liblte_s1ap_soninformationrequest_text[LIBLTE_S1AP_SONINFORMATIONREQUEST_N_ITEMS][80] = { + "x2TNL-Configuration-Info", + "time-Synchronization-Info", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM e; +}LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_soninformationrequest( + LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformationrequest( + uint8_t **ptr, + LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Source_ToTarget_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_SOURCE_TOTARGET_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_source_totarget_transparentcontainer( + LIBLTE_S1AP_SOURCE_TOTARGET_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_source_totarget_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_SOURCE_TOTARGET_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SRVCCHOIndication ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_SRVCCHOINDICATION_PSANDCS, + LIBLTE_S1AP_SRVCCHOINDICATION_CSONLY, + LIBLTE_S1AP_SRVCCHOINDICATION_N_ITEMS, +}LIBLTE_S1AP_SRVCCHOINDICATION_ENUM; +static const char liblte_s1ap_srvcchoindication_text[LIBLTE_S1AP_SRVCCHOINDICATION_N_ITEMS][80] = { + "pSandCS", + "cSonly", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_SRVCCHOINDICATION_ENUM e; +}LIBLTE_S1AP_SRVCCHOINDICATION_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_srvcchoindication( + LIBLTE_S1AP_SRVCCHOINDICATION_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_srvcchoindication( + uint8_t **ptr, + LIBLTE_S1AP_SRVCCHOINDICATION_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE SourceRNC_ToTargetRNC_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourcernc_totargetrnc_transparentcontainer( + LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourcernc_totargetrnc_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SubscriberProfileIDforRFP INTEGER +********************************************************************************/ +typedef struct{ +uint8_t SubscriberProfileIDforRFP; +}LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_subscriberprofileidforrfp( + LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_subscriberprofileidforrfp( + uint8_t **ptr, + LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SynchronizationStatus ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_SYNCHRONOUS, + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ASYNCHRONOUS, + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_N_ITEMS, +}LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM; +static const char liblte_s1ap_synchronizationstatus_text[LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_N_ITEMS][80] = { + "synchronous", + "asynchronous", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM e; +}LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_synchronizationstatus( + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_synchronizationstatus( + uint8_t **ptr, + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE TargetRNC_ToSourceRNC_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetrnc_tosourcernc_transparentcontainer( + LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetrnc_tosourcernc_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Threshold_RSRQ INTEGER +********************************************************************************/ +typedef struct{ +uint8_t Threshold_RSRQ; +}LIBLTE_S1AP_THRESHOLD_RSRQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_threshold_rsrq( + LIBLTE_S1AP_THRESHOLD_RSRQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_threshold_rsrq( + uint8_t **ptr, + LIBLTE_S1AP_THRESHOLD_RSRQ_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Time_UE_StayedInCell INTEGER +********************************************************************************/ +typedef struct{ +uint16_t Time_UE_StayedInCell; +}LIBLTE_S1AP_TIME_UE_STAYEDINCELL_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_time_ue_stayedincell( + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_time_ue_stayedincell( + uint8_t **ptr, + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TransportLayerAddress DYNAMIC BIT STRING +********************************************************************************/ +// lb:1, ub:160 +typedef struct{ + bool ext; + uint32_t n_bits; + uint8_t buffer[160]; +}LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_transportlayeraddress( + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_transportlayeraddress( + uint8_t **ptr, + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TraceDepth ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_TRACEDEPTH_MINIMUM, + LIBLTE_S1AP_TRACEDEPTH_MEDIUM, + LIBLTE_S1AP_TRACEDEPTH_MAXIMUM, + LIBLTE_S1AP_TRACEDEPTH_MINIMUMWITHOUTVENDORSPECIFICEXTENSION, + LIBLTE_S1AP_TRACEDEPTH_MEDIUMWITHOUTVENDORSPECIFICEXTENSION, + LIBLTE_S1AP_TRACEDEPTH_MAXIMUMWITHOUTVENDORSPECIFICEXTENSION, + LIBLTE_S1AP_TRACEDEPTH_N_ITEMS, +}LIBLTE_S1AP_TRACEDEPTH_ENUM; +static const char liblte_s1ap_tracedepth_text[LIBLTE_S1AP_TRACEDEPTH_N_ITEMS][80] = { + "minimum", + "medium", + "maximum", + "minimumWithoutVendorSpecificExtension", + "mediumWithoutVendorSpecificExtension", + "maximumWithoutVendorSpecificExtension", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_TRACEDEPTH_ENUM e; +}LIBLTE_S1AP_TRACEDEPTH_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tracedepth( + LIBLTE_S1AP_TRACEDEPTH_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tracedepth( + uint8_t **ptr, + LIBLTE_S1AP_TRACEDEPTH_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE TrafficLoadReductionIndication INTEGER +********************************************************************************/ +typedef struct{ +uint8_t TrafficLoadReductionIndication; +}LIBLTE_S1AP_TRAFFICLOADREDUCTIONINDICATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_trafficloadreductionindication( + LIBLTE_S1AP_TRAFFICLOADREDUCTIONINDICATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_trafficloadreductionindication( + uint8_t **ptr, + LIBLTE_S1AP_TRAFFICLOADREDUCTIONINDICATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE UERadioCapability DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_UERADIOCAPABILITY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueradiocapability( + LIBLTE_S1AP_UERADIOCAPABILITY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueradiocapability( + uint8_t **ptr, + LIBLTE_S1AP_UERADIOCAPABILITY_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE WarningType STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_WARNINGTYPE_OCTET_STRING_LEN 2 +typedef struct{ + uint8_t buffer[2]; +}LIBLTE_S1AP_WARNINGTYPE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_warningtype( + LIBLTE_S1AP_WARNINGTYPE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_warningtype( + uint8_t **ptr, + LIBLTE_S1AP_WARNINGTYPE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE WarningMessageContents DYNAMIC OCTET STRING +********************************************************************************/ +// lb:1, ub:9600 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[9600]; +}LIBLTE_S1AP_WARNINGMESSAGECONTENTS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_warningmessagecontents( + LIBLTE_S1AP_WARNINGMESSAGECONTENTS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_warningmessagecontents( + uint8_t **ptr, + LIBLTE_S1AP_WARNINGMESSAGECONTENTS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CauseProtocol ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CAUSEPROTOCOL_TRANSFER_SYNTAX_ERROR, + LIBLTE_S1AP_CAUSEPROTOCOL_ABSTRACT_SYNTAX_ERROR_REJECT, + LIBLTE_S1AP_CAUSEPROTOCOL_ABSTRACT_SYNTAX_ERROR_IGNORE_AND_NOTIFY, + LIBLTE_S1AP_CAUSEPROTOCOL_MESSAGE_NOT_COMPATIBLE_WITH_RECEIVER_STATE, + LIBLTE_S1AP_CAUSEPROTOCOL_SEMANTIC_ERROR, + LIBLTE_S1AP_CAUSEPROTOCOL_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE, + LIBLTE_S1AP_CAUSEPROTOCOL_UNSPECIFIED, + LIBLTE_S1AP_CAUSEPROTOCOL_N_ITEMS, +}LIBLTE_S1AP_CAUSEPROTOCOL_ENUM; +static const char liblte_s1ap_causeprotocol_text[LIBLTE_S1AP_CAUSEPROTOCOL_N_ITEMS][80] = { + "transfer-syntax-error", + "abstract-syntax-error-reject", + "abstract-syntax-error-ignore-and-notify", + "message-not-compatible-with-receiver-state", + "semantic-error", + "abstract-syntax-error-falsely-constructed-message", + "unspecified", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSEPROTOCOL_ENUM e; +}LIBLTE_S1AP_CAUSEPROTOCOL_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causeprotocol( + LIBLTE_S1AP_CAUSEPROTOCOL_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causeprotocol( + uint8_t **ptr, + LIBLTE_S1AP_CAUSEPROTOCOL_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE CellAccessMode ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CELLACCESSMODE_HYBRID, + LIBLTE_S1AP_CELLACCESSMODE_N_ITEMS, +}LIBLTE_S1AP_CELLACCESSMODE_ENUM; +static const char liblte_s1ap_cellaccessmode_text[LIBLTE_S1AP_CELLACCESSMODE_N_ITEMS][80] = { + "hybrid", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CELLACCESSMODE_ENUM e; +}LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellaccessmode( + LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellaccessmode( + uint8_t **ptr, + LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000RATType ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CDMA2000RATTYPE_HRPD, + LIBLTE_S1AP_CDMA2000RATTYPE_ONEXRTT, + LIBLTE_S1AP_CDMA2000RATTYPE_N_ITEMS, +}LIBLTE_S1AP_CDMA2000RATTYPE_ENUM; +static const char liblte_s1ap_cdma2000rattype_text[LIBLTE_S1AP_CDMA2000RATTYPE_N_ITEMS][80] = { + "hRPD", + "onexRTT", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CDMA2000RATTYPE_ENUM e; +}LIBLTE_S1AP_CDMA2000RATTYPE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000rattype( + LIBLTE_S1AP_CDMA2000RATTYPE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000rattype( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000RATTYPE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXMEID DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_CDMA2000ONEXMEID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexmeid( + LIBLTE_S1AP_CDMA2000ONEXMEID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexmeid( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXMEID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Cell_Size ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CELL_SIZE_VERYSMALL, + LIBLTE_S1AP_CELL_SIZE_SMALL, + LIBLTE_S1AP_CELL_SIZE_MEDIUM, + LIBLTE_S1AP_CELL_SIZE_LARGE, + LIBLTE_S1AP_CELL_SIZE_N_ITEMS, +}LIBLTE_S1AP_CELL_SIZE_ENUM; +static const char liblte_s1ap_cell_size_text[LIBLTE_S1AP_CELL_SIZE_N_ITEMS][80] = { + "verysmall", + "small", + "medium", + "large", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CELL_SIZE_ENUM e; +}LIBLTE_S1AP_CELL_SIZE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cell_size( + LIBLTE_S1AP_CELL_SIZE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cell_size( + uint8_t **ptr, + LIBLTE_S1AP_CELL_SIZE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE CI STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_CI_OCTET_STRING_LEN 2 +typedef struct{ + uint8_t buffer[2]; +}LIBLTE_S1AP_CI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ci( + LIBLTE_S1AP_CI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ci( + uint8_t **ptr, + LIBLTE_S1AP_CI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CSFallbackIndicator ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CSFALLBACKINDICATOR_CS_FALLBACK_REQUIRED, + LIBLTE_S1AP_CSFALLBACKINDICATOR_CS_FALLBACK_HIGH_PRIORITY, + LIBLTE_S1AP_CSFALLBACKINDICATOR_N_ITEMS, +}LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM; +static const char liblte_s1ap_csfallbackindicator_text[LIBLTE_S1AP_CSFALLBACKINDICATOR_N_ITEMS][80] = { + "cs-fallback-required", + "cs-fallback-high-priority", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM e; +}LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csfallbackindicator( + LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csfallbackindicator( + uint8_t **ptr, + LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE CSGMembershipStatus ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_MEMBER, + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_NOT_MEMBER, + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_N_ITEMS, +}LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM; +static const char liblte_s1ap_csgmembershipstatus_text[LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_N_ITEMS][80] = { + "member", + "not-member", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csgmembershipstatus( + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csgmembershipstatus( + uint8_t **ptr, + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE DataCodingScheme STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_DATACODINGSCHEME_BIT_STRING_LEN 8 +typedef struct{ + uint8_t buffer[8]; +}LIBLTE_S1AP_DATACODINGSCHEME_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_datacodingscheme( + LIBLTE_S1AP_DATACODINGSCHEME_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_datacodingscheme( + uint8_t **ptr, + LIBLTE_S1AP_DATACODINGSCHEME_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EmergencyAreaIDList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_EMERGENCYAREAID_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_EMERGENCYAREAIDLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaidlist( + LIBLTE_S1AP_EMERGENCYAREAIDLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaidlist( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAIDLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EmergencyAreaIDListForRestart DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_EMERGENCYAREAID_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_EMERGENCYAREAIDLISTFORRESTART_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaidlistforrestart( + LIBLTE_S1AP_EMERGENCYAREAIDLISTFORRESTART_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaidlistforrestart( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAIDLISTFORRESTART_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ENB_UE_S1AP_ID INTEGER +********************************************************************************/ +typedef struct{ +uint32_t ENB_UE_S1AP_ID; +}LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_ue_s1ap_id( + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_ue_s1ap_id( + uint8_t **ptr, + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RAB_ID INTEGER +********************************************************************************/ +typedef struct{ + bool ext; +uint8_t E_RAB_ID; +}LIBLTE_S1AP_E_RAB_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rab_id( + LIBLTE_S1AP_E_RAB_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rab_id( + uint8_t **ptr, + LIBLTE_S1AP_E_RAB_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABInformationListItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_DL_FORWARDING_ENUM_EXT dL_Forwarding; + bool dL_Forwarding_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABINFORMATIONLISTITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabinformationlistitem( + LIBLTE_S1AP_E_RABINFORMATIONLISTITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlistitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABINFORMATIONLISTITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EUTRANRoundTripDelayEstimationInfo INTEGER +********************************************************************************/ +typedef struct{ +uint16_t EUTRANRoundTripDelayEstimationInfo; +}LIBLTE_S1AP_EUTRANROUNDTRIPDELAYESTIMATIONINFO_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eutranroundtripdelayestimationinfo( + LIBLTE_S1AP_EUTRANROUNDTRIPDELAYESTIMATIONINFO_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eutranroundtripdelayestimationinfo( + uint8_t **ptr, + LIBLTE_S1AP_EUTRANROUNDTRIPDELAYESTIMATIONINFO_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ForbiddenLACs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:4096 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_LAC_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_FORBIDDENLACS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddenlacs( + LIBLTE_S1AP_FORBIDDENLACS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddenlacs( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENLACS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE GTP_TEID STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_GTP_TEID_OCTET_STRING_LEN 4 +typedef struct{ + uint8_t buffer[4]; +}LIBLTE_S1AP_GTP_TEID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gtp_teid( + LIBLTE_S1AP_GTP_TEID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gtp_teid( + uint8_t **ptr, + LIBLTE_S1AP_GTP_TEID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE GUMMEIType ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_GUMMEITYPE_NATIVE, + LIBLTE_S1AP_GUMMEITYPE_MAPPED, + LIBLTE_S1AP_GUMMEITYPE_N_ITEMS, +}LIBLTE_S1AP_GUMMEITYPE_ENUM; +static const char liblte_s1ap_gummeitype_text[LIBLTE_S1AP_GUMMEITYPE_N_ITEMS][80] = { + "native", + "mapped", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_GUMMEITYPE_ENUM e; +}LIBLTE_S1AP_GUMMEITYPE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gummeitype( + LIBLTE_S1AP_GUMMEITYPE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gummeitype( + uint8_t **ptr, + LIBLTE_S1AP_GUMMEITYPE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE HandoverType ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_HANDOVERTYPE_INTRALTE, + LIBLTE_S1AP_HANDOVERTYPE_LTETOUTRAN, + LIBLTE_S1AP_HANDOVERTYPE_LTETOGERAN, + LIBLTE_S1AP_HANDOVERTYPE_UTRANTOLTE, + LIBLTE_S1AP_HANDOVERTYPE_GERANTOLTE, + LIBLTE_S1AP_HANDOVERTYPE_N_ITEMS, +}LIBLTE_S1AP_HANDOVERTYPE_ENUM; +static const char liblte_s1ap_handovertype_text[LIBLTE_S1AP_HANDOVERTYPE_N_ITEMS][80] = { + "intralte", + "ltetoutran", + "ltetogeran", + "utrantolte", + "gerantolte", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_HANDOVERTYPE_ENUM e; +}LIBLTE_S1AP_HANDOVERTYPE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovertype( + LIBLTE_S1AP_HANDOVERTYPE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovertype( + uint8_t **ptr, + LIBLTE_S1AP_HANDOVERTYPE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE IntegrityProtectionAlgorithms STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_INTEGRITYPROTECTIONALGORITHMS_BIT_STRING_LEN 16 +typedef struct{ + bool ext; + uint8_t buffer[16]; +}LIBLTE_S1AP_INTEGRITYPROTECTIONALGORITHMS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_integrityprotectionalgorithms( + LIBLTE_S1AP_INTEGRITYPROTECTIONALGORITHMS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_integrityprotectionalgorithms( + uint8_t **ptr, + LIBLTE_S1AP_INTEGRITYPROTECTIONALGORITHMS_STRUCT *ie); + +//TODO: Type undefined NULL + +/******************************************************************************* +/* ProtocolIE LastVisitedGERANCellInformation CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_UNDEFINED, + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_N_ITEMS, +}LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_ENUM; +static const char liblte_s1ap_lastvisitedgerancellinformation_choice_text[LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_N_ITEMS][50] = { + "undefined", +}; + +typedef union{ + //TODO: NULL undefined; +}LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_UNION choice; + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedgerancellinformation( + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedgerancellinformation( + uint8_t **ptr, + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Links_to_log ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_LINKS_TO_LOG_UPLINK, + LIBLTE_S1AP_LINKS_TO_LOG_DOWNLINK, + LIBLTE_S1AP_LINKS_TO_LOG_BOTH_UPLINK_AND_DOWNLINK, + LIBLTE_S1AP_LINKS_TO_LOG_N_ITEMS, +}LIBLTE_S1AP_LINKS_TO_LOG_ENUM; +static const char liblte_s1ap_links_to_log_text[LIBLTE_S1AP_LINKS_TO_LOG_N_ITEMS][80] = { + "uplink", + "downlink", + "both-uplink-and-downlink", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_LINKS_TO_LOG_ENUM e; +}LIBLTE_S1AP_LINKS_TO_LOG_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_links_to_log( + LIBLTE_S1AP_LINKS_TO_LOG_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_links_to_log( + uint8_t **ptr, + LIBLTE_S1AP_LINKS_TO_LOG_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE LoggingInterval ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_LOGGINGINTERVAL_MS128, + LIBLTE_S1AP_LOGGINGINTERVAL_MS256, + LIBLTE_S1AP_LOGGINGINTERVAL_MS512, + LIBLTE_S1AP_LOGGINGINTERVAL_MS1024, + LIBLTE_S1AP_LOGGINGINTERVAL_MS2048, + LIBLTE_S1AP_LOGGINGINTERVAL_MS3072, + LIBLTE_S1AP_LOGGINGINTERVAL_MS4096, + LIBLTE_S1AP_LOGGINGINTERVAL_MS6144, + LIBLTE_S1AP_LOGGINGINTERVAL_N_ITEMS, +}LIBLTE_S1AP_LOGGINGINTERVAL_ENUM; +static const char liblte_s1ap_logginginterval_text[LIBLTE_S1AP_LOGGINGINTERVAL_N_ITEMS][80] = { + "ms128", + "ms256", + "ms512", + "ms1024", + "ms2048", + "ms3072", + "ms4096", + "ms6144", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_logginginterval( + LIBLTE_S1AP_LOGGINGINTERVAL_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_logginginterval( + uint8_t **ptr, + LIBLTE_S1AP_LOGGINGINTERVAL_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE M3period ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_M3PERIOD_MS100, + LIBLTE_S1AP_M3PERIOD_MS1000, + LIBLTE_S1AP_M3PERIOD_MS10000, + LIBLTE_S1AP_M3PERIOD_N_ITEMS, +}LIBLTE_S1AP_M3PERIOD_ENUM; +static const char liblte_s1ap_m3period_text[LIBLTE_S1AP_M3PERIOD_N_ITEMS][80] = { + "ms100", + "ms1000", + "ms10000", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_M3PERIOD_ENUM e; +}LIBLTE_S1AP_M3PERIOD_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m3period( + LIBLTE_S1AP_M3PERIOD_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m3period( + uint8_t **ptr, + LIBLTE_S1AP_M3PERIOD_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE M4period ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_M4PERIOD_MS1024, + LIBLTE_S1AP_M4PERIOD_MS2048, + LIBLTE_S1AP_M4PERIOD_MS5120, + LIBLTE_S1AP_M4PERIOD_MS10240, + LIBLTE_S1AP_M4PERIOD_MIN1, + LIBLTE_S1AP_M4PERIOD_N_ITEMS, +}LIBLTE_S1AP_M4PERIOD_ENUM; +static const char liblte_s1ap_m4period_text[LIBLTE_S1AP_M4PERIOD_N_ITEMS][80] = { + "ms1024", + "ms2048", + "ms5120", + "ms10240", + "min1", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_M4PERIOD_ENUM e; +}LIBLTE_S1AP_M4PERIOD_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m4period( + LIBLTE_S1AP_M4PERIOD_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m4period( + uint8_t **ptr, + LIBLTE_S1AP_M4PERIOD_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE M5period ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_M5PERIOD_MS1024, + LIBLTE_S1AP_M5PERIOD_MS2048, + LIBLTE_S1AP_M5PERIOD_MS5120, + LIBLTE_S1AP_M5PERIOD_MS10240, + LIBLTE_S1AP_M5PERIOD_MIN1, + LIBLTE_S1AP_M5PERIOD_N_ITEMS, +}LIBLTE_S1AP_M5PERIOD_ENUM; +static const char liblte_s1ap_m5period_text[LIBLTE_S1AP_M5PERIOD_N_ITEMS][80] = { + "ms1024", + "ms2048", + "ms5120", + "ms10240", + "min1", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_M5PERIOD_ENUM e; +}LIBLTE_S1AP_M5PERIOD_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m5period( + LIBLTE_S1AP_M5PERIOD_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m5period( + uint8_t **ptr, + LIBLTE_S1AP_M5PERIOD_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE MobilityInformation STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_MOBILITYINFORMATION_BIT_STRING_LEN 32 +typedef struct{ + uint8_t buffer[32]; +}LIBLTE_S1AP_MOBILITYINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mobilityinformation( + LIBLTE_S1AP_MOBILITYINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mobilityinformation( + uint8_t **ptr, + LIBLTE_S1AP_MOBILITYINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MME_Code STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_MME_CODE_OCTET_STRING_LEN 1 +typedef struct{ + uint8_t buffer[1]; +}LIBLTE_S1AP_MME_CODE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mme_code( + LIBLTE_S1AP_MME_CODE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mme_code( + uint8_t **ptr, + LIBLTE_S1AP_MME_CODE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MSClassmark3 DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_MSCLASSMARK3_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_msclassmark3( + LIBLTE_S1AP_MSCLASSMARK3_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_msclassmark3( + uint8_t **ptr, + LIBLTE_S1AP_MSCLASSMARK3_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE NumberofBroadcastRequest INTEGER +********************************************************************************/ +typedef struct{ +uint16_t NumberofBroadcastRequest; +}LIBLTE_S1AP_NUMBEROFBROADCASTREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_numberofbroadcastrequest( + LIBLTE_S1AP_NUMBEROFBROADCASTREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_numberofbroadcastrequest( + uint8_t **ptr, + LIBLTE_S1AP_NUMBEROFBROADCASTREQUEST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE OverloadResponse CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_OVERLOADACTION, + LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_N_ITEMS, +}LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_ENUM; +static const char liblte_s1ap_overloadresponse_choice_text[LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_N_ITEMS][50] = { + "overloadAction", +}; + +typedef union{ + LIBLTE_S1AP_OVERLOADACTION_ENUM_EXT overloadAction; +}LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_UNION choice; + LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_OVERLOADRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_overloadresponse( + LIBLTE_S1AP_OVERLOADRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_overloadresponse( + uint8_t **ptr, + LIBLTE_S1AP_OVERLOADRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE PDCP_SNExtended INTEGER +********************************************************************************/ +typedef struct{ +uint16_t PDCP_SNExtended; +}LIBLTE_S1AP_PDCP_SNEXTENDED_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pdcp_snextended( + LIBLTE_S1AP_PDCP_SNEXTENDED_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pdcp_snextended( + uint8_t **ptr, + LIBLTE_S1AP_PDCP_SNEXTENDED_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Pre_emptionCapability ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_SHALL_NOT_TRIGGER_PRE_EMPTION, + LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_MAY_TRIGGER_PRE_EMPTION, + LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_N_ITEMS, +}LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM; +static const char liblte_s1ap_pre_emptioncapability_text[LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_N_ITEMS][80] = { + "shall-not-trigger-pre-emption", + "may-trigger-pre-emption", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pre_emptioncapability( + LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pre_emptioncapability( + uint8_t **ptr, + LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE QCI INTEGER +********************************************************************************/ +typedef struct{ +uint8_t QCI; +}LIBLTE_S1AP_QCI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_qci( + LIBLTE_S1AP_QCI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_qci( + uint8_t **ptr, + LIBLTE_S1AP_QCI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RelayNode_Indicator ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_RELAYNODE_INDICATOR_TRUE, + LIBLTE_S1AP_RELAYNODE_INDICATOR_N_ITEMS, +}LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM; +static const char liblte_s1ap_relaynode_indicator_text[LIBLTE_S1AP_RELAYNODE_INDICATOR_N_ITEMS][80] = { + "true", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM e; +}LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_relaynode_indicator( + LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_relaynode_indicator( + uint8_t **ptr, + LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE M1ReportingTrigger ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_M1REPORTINGTRIGGER_PERIODIC, + LIBLTE_S1AP_M1REPORTINGTRIGGER_A2EVENTTRIGGERED, + LIBLTE_S1AP_M1REPORTINGTRIGGER_A2EVENTTRIGGERED_PERIODIC, + LIBLTE_S1AP_M1REPORTINGTRIGGER_N_ITEMS, +}LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM; +static const char liblte_s1ap_m1reportingtrigger_text[LIBLTE_S1AP_M1REPORTINGTRIGGER_N_ITEMS][80] = { + "periodic", + "a2eventtriggered", + "a2eventtriggered-periodic", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM e; +}LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1reportingtrigger( + LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1reportingtrigger( + uint8_t **ptr, + LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE RIMInformation DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_RIMINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_riminformation( + LIBLTE_S1AP_RIMINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_riminformation( + uint8_t **ptr, + LIBLTE_S1AP_RIMINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RepetitionPeriod INTEGER +********************************************************************************/ +typedef struct{ +uint16_t RepetitionPeriod; +}LIBLTE_S1AP_REPETITIONPERIOD_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_repetitionperiod( + LIBLTE_S1AP_REPETITIONPERIOD_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_repetitionperiod( + uint8_t **ptr, + LIBLTE_S1AP_REPETITIONPERIOD_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SecurityKey STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_SECURITYKEY_BIT_STRING_LEN 256 +typedef struct{ + uint8_t buffer[256]; +}LIBLTE_S1AP_SECURITYKEY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_securitykey( + LIBLTE_S1AP_SECURITYKEY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_securitykey( + uint8_t **ptr, + LIBLTE_S1AP_SECURITYKEY_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SerialNumber STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_SERIALNUMBER_BIT_STRING_LEN 16 +typedef struct{ + uint8_t buffer[16]; +}LIBLTE_S1AP_SERIALNUMBER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_serialnumber( + LIBLTE_S1AP_SERIALNUMBER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_serialnumber( + uint8_t **ptr, + LIBLTE_S1AP_SERIALNUMBER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SourceBSS_ToTargetBSS_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourcebss_totargetbss_transparentcontainer( + LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourcebss_totargetbss_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SRVCCOperationPossible ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_POSSIBLE, + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_N_ITEMS, +}LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM; +static const char liblte_s1ap_srvccoperationpossible_text[LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_N_ITEMS][80] = { + "possible", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM e; +}LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_srvccoperationpossible( + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_srvccoperationpossible( + uint8_t **ptr, + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE ServedGroupIDs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_MME_GROUP_ID_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_SERVEDGROUPIDS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedgroupids( + LIBLTE_S1AP_SERVEDGROUPIDS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedgroupids( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDGROUPIDS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE StratumLevel INTEGER +********************************************************************************/ +typedef struct{ + bool ext; +uint8_t StratumLevel; +}LIBLTE_S1AP_STRATUMLEVEL_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_stratumlevel( + LIBLTE_S1AP_STRATUMLEVEL_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_stratumlevel( + uint8_t **ptr, + LIBLTE_S1AP_STRATUMLEVEL_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAC STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_TAC_OCTET_STRING_LEN 2 +typedef struct{ + uint8_t buffer[2]; +}LIBLTE_S1AP_TAC_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tac( + LIBLTE_S1AP_TAC_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tac( + uint8_t **ptr, + LIBLTE_S1AP_TAC_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAListforMDT DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:8 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TAC_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_TALISTFORMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_talistformdt( + LIBLTE_S1AP_TALISTFORMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_talistformdt( + uint8_t **ptr, + LIBLTE_S1AP_TALISTFORMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TBCD_STRING STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_TBCD_STRING_OCTET_STRING_LEN 3 +typedef struct{ + uint8_t buffer[3]; +}LIBLTE_S1AP_TBCD_STRING_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tbcd_string( + LIBLTE_S1AP_TBCD_STRING_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tbcd_string( + uint8_t **ptr, + LIBLTE_S1AP_TBCD_STRING_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Target_ToSource_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_TARGET_TOSOURCE_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_target_tosource_transparentcontainer( + LIBLTE_S1AP_TARGET_TOSOURCE_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_target_tosource_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_TARGET_TOSOURCE_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Threshold_RSRP INTEGER +********************************************************************************/ +typedef struct{ +uint8_t Threshold_RSRP; +}LIBLTE_S1AP_THRESHOLD_RSRP_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_threshold_rsrp( + LIBLTE_S1AP_THRESHOLD_RSRP_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_threshold_rsrp( + uint8_t **ptr, + LIBLTE_S1AP_THRESHOLD_RSRP_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Time_UE_StayedInCell_EnhancedGranularity INTEGER +********************************************************************************/ +typedef struct{ +uint16_t Time_UE_StayedInCell_EnhancedGranularity; +}LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_time_ue_stayedincell_enhancedgranularity( + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_time_ue_stayedincell_enhancedgranularity( + uint8_t **ptr, + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_UTRAN_Trace_ID STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_E_UTRAN_TRACE_ID_OCTET_STRING_LEN 8 +typedef struct{ + uint8_t buffer[8]; +}LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_utran_trace_id( + LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_utran_trace_id( + uint8_t **ptr, + LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TypeOfError ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_TYPEOFERROR_NOT_UNDERSTOOD, + LIBLTE_S1AP_TYPEOFERROR_MISSING, + LIBLTE_S1AP_TYPEOFERROR_N_ITEMS, +}LIBLTE_S1AP_TYPEOFERROR_ENUM; +static const char liblte_s1ap_typeoferror_text[LIBLTE_S1AP_TYPEOFERROR_N_ITEMS][80] = { + "not-understood", + "missing", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_TYPEOFERROR_ENUM e; +}LIBLTE_S1AP_TYPEOFERROR_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_typeoferror( + LIBLTE_S1AP_TYPEOFERROR_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_typeoferror( + uint8_t **ptr, + LIBLTE_S1AP_TYPEOFERROR_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE UEAggregateMaximumBitrate SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_BITRATE_STRUCT uEaggregateMaximumBitRateDL; + LIBLTE_S1AP_BITRATE_STRUCT uEaggregateMaximumBitRateUL; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueaggregatemaximumbitrate( + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueaggregatemaximumbitrate( + uint8_t **ptr, + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE UE_S1AP_ID_pair SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT mME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_UE_S1AP_ID_PAIR_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_s1ap_id_pair( + LIBLTE_S1AP_UE_S1AP_ID_PAIR_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_s1ap_id_pair( + uint8_t **ptr, + LIBLTE_S1AP_UE_S1AP_ID_PAIR_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE UEIdentityIndexValue STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_UEIDENTITYINDEXVALUE_BIT_STRING_LEN 10 +typedef struct{ + uint8_t buffer[10]; +}LIBLTE_S1AP_UEIDENTITYINDEXVALUE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueidentityindexvalue( + LIBLTE_S1AP_UEIDENTITYINDEXVALUE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueidentityindexvalue( + uint8_t **ptr, + LIBLTE_S1AP_UEIDENTITYINDEXVALUE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE UESecurityCapabilities SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ENCRYPTIONALGORITHMS_STRUCT encryptionAlgorithms; + LIBLTE_S1AP_INTEGRITYPROTECTIONALGORITHMS_STRUCT integrityProtectionAlgorithms; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uesecuritycapabilities( + LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uesecuritycapabilities( + uint8_t **ptr, + LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE VoiceSupportMatchIndicator ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_SUPPORTED, + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_NOT_SUPPORTED, + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_N_ITEMS, +}LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM; +static const char liblte_s1ap_voicesupportmatchindicator_text[LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_N_ITEMS][80] = { + "supported", + "not-supported", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM e; +}LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_voicesupportmatchindicator( + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_voicesupportmatchindicator( + uint8_t **ptr, + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE WarningSecurityInfo STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_WARNINGSECURITYINFO_OCTET_STRING_LEN 50 +typedef struct{ + uint8_t buffer[50]; +}LIBLTE_S1AP_WARNINGSECURITYINFO_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_warningsecurityinfo( + LIBLTE_S1AP_WARNINGSECURITYINFO_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_warningsecurityinfo( + uint8_t **ptr, + LIBLTE_S1AP_WARNINGSECURITYINFO_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ENBX2GTPTLAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_ENBX2GTPTLAS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2gtptlas( + LIBLTE_S1AP_ENBX2GTPTLAS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2gtptlas( + uint8_t **ptr, + LIBLTE_S1AP_ENBX2GTPTLAS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CauseTransport ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CAUSETRANSPORT_TRANSPORT_RESOURCE_UNAVAILABLE, + LIBLTE_S1AP_CAUSETRANSPORT_UNSPECIFIED, + LIBLTE_S1AP_CAUSETRANSPORT_N_ITEMS, +}LIBLTE_S1AP_CAUSETRANSPORT_ENUM; +static const char liblte_s1ap_causetransport_text[LIBLTE_S1AP_CAUSETRANSPORT_N_ITEMS][80] = { + "transport-resource-unavailable", + "unspecified", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSETRANSPORT_ENUM e; +}LIBLTE_S1AP_CAUSETRANSPORT_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causetransport( + LIBLTE_S1AP_CAUSETRANSPORT_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causetransport( + uint8_t **ptr, + LIBLTE_S1AP_CAUSETRANSPORT_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000HOStatus ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CDMA2000HOSTATUS_HOSUCCESS, + LIBLTE_S1AP_CDMA2000HOSTATUS_HOFAILURE, + LIBLTE_S1AP_CDMA2000HOSTATUS_N_ITEMS, +}LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM; +static const char liblte_s1ap_cdma2000hostatus_text[LIBLTE_S1AP_CDMA2000HOSTATUS_N_ITEMS][80] = { + "hOSuccess", + "hOFailure", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM e; +}LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000hostatus( + LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000hostatus( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXPilot DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_CDMA2000ONEXPILOT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexpilot( + LIBLTE_S1AP_CDMA2000ONEXPILOT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexpilot( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXPILOT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ConcurrentWarningMessageIndicator ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_TRUE, + LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_N_ITEMS, +}LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_ENUM; +static const char liblte_s1ap_concurrentwarningmessageindicator_text[LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_N_ITEMS][80] = { + "true", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_concurrentwarningmessageindicator( + LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_concurrentwarningmessageindicator( + uint8_t **ptr, + LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE COUNTvalue SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_PDCP_SN_STRUCT pDCP_SN; + LIBLTE_S1AP_HFN_STRUCT hFN; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_COUNTVALUE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_countvalue( + LIBLTE_S1AP_COUNTVALUE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_countvalue( + uint8_t **ptr, + LIBLTE_S1AP_COUNTVALUE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CriticalityDiagnostics_IE_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CRITICALITY_ENUM iECriticality; + LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT iE_ID; + LIBLTE_S1AP_TYPEOFERROR_ENUM_EXT typeOfError; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics_ie_item( + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ie_item( + uint8_t **ptr, + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ENBX2TLAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:2 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_ENBX2TLAS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2tlas( + LIBLTE_S1AP_ENBX2TLAS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2tlas( + uint8_t **ptr, + LIBLTE_S1AP_ENBX2TLAS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ExtendedRepetitionPeriod INTEGER +********************************************************************************/ +typedef struct{ +uint32_t ExtendedRepetitionPeriod; +}LIBLTE_S1AP_EXTENDEDREPETITIONPERIOD_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_extendedrepetitionperiod( + LIBLTE_S1AP_EXTENDEDREPETITIONPERIOD_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_extendedrepetitionperiod( + uint8_t **ptr, + LIBLTE_S1AP_EXTENDEDREPETITIONPERIOD_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ForbiddenTACs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:4096 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TAC_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_FORBIDDENTACS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddentacs( + LIBLTE_S1AP_FORBIDDENTACS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddentacs( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENTACS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE GBR_QosInformation SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_BITRATE_STRUCT e_RAB_MaximumBitrateDL; + LIBLTE_S1AP_BITRATE_STRUCT e_RAB_MaximumBitrateUL; + LIBLTE_S1AP_BITRATE_STRUCT e_RAB_GuaranteedBitrateDL; + LIBLTE_S1AP_BITRATE_STRUCT e_RAB_GuaranteedBitrateUL; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_GBR_QOSINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gbr_qosinformation( + LIBLTE_S1AP_GBR_QOSINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gbr_qosinformation( + uint8_t **ptr, + LIBLTE_S1AP_GBR_QOSINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE HFNModified INTEGER +********************************************************************************/ +typedef struct{ +uint32_t HFNModified; +}LIBLTE_S1AP_HFNMODIFIED_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_hfnmodified( + LIBLTE_S1AP_HFNMODIFIED_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_hfnmodified( + uint8_t **ptr, + LIBLTE_S1AP_HFNMODIFIED_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE KillAllWarningMessages ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_KILLALLWARNINGMESSAGES_TRUE, + LIBLTE_S1AP_KILLALLWARNINGMESSAGES_N_ITEMS, +}LIBLTE_S1AP_KILLALLWARNINGMESSAGES_ENUM; +static const char liblte_s1ap_killallwarningmessages_text[LIBLTE_S1AP_KILLALLWARNINGMESSAGES_N_ITEMS][80] = { + "true", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_killallwarningmessages( + LIBLTE_S1AP_KILLALLWARNINGMESSAGES_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_killallwarningmessages( + uint8_t **ptr, + LIBLTE_S1AP_KILLALLWARNINGMESSAGES_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE LPPa_PDU DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_LPPA_PDU_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lppa_pdu( + LIBLTE_S1AP_LPPA_PDU_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lppa_pdu( + uint8_t **ptr, + LIBLTE_S1AP_LPPA_PDU_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE M3Configuration SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_M3PERIOD_ENUM_EXT m3period; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_M3CONFIGURATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m3configuration( + LIBLTE_S1AP_M3CONFIGURATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m3configuration( + uint8_t **ptr, + LIBLTE_S1AP_M3CONFIGURATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE M5Configuration SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_M5PERIOD_ENUM_EXT m5period; + LIBLTE_S1AP_LINKS_TO_LOG_ENUM_EXT m5_links_to_log; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_M5CONFIGURATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m5configuration( + LIBLTE_S1AP_M5CONFIGURATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m5configuration( + uint8_t **ptr, + LIBLTE_S1AP_M5CONFIGURATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MeasurementThresholdA2 CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_THRESHOLD_RSRP, + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_THRESHOLD_RSRQ, + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_N_ITEMS, +}LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_ENUM; +static const char liblte_s1ap_measurementthresholda2_choice_text[LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_N_ITEMS][50] = { + "threshold_RSRP", + "threshold_RSRQ", +}; + +typedef union{ + LIBLTE_S1AP_THRESHOLD_RSRP_STRUCT threshold_RSRP; + LIBLTE_S1AP_THRESHOLD_RSRQ_STRUCT threshold_RSRQ; +}LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_UNION choice; + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_measurementthresholda2( + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_measurementthresholda2( + uint8_t **ptr, + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE M_TMSI STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_M_TMSI_OCTET_STRING_LEN 4 +typedef struct{ + uint8_t buffer[4]; +}LIBLTE_S1AP_M_TMSI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m_tmsi( + LIBLTE_S1AP_M_TMSI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m_tmsi( + uint8_t **ptr, + LIBLTE_S1AP_M_TMSI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE OldBSS_ToNewBSS_Information DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_OLDBSS_TONEWBSS_INFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_oldbss_tonewbss_information( + LIBLTE_S1AP_OLDBSS_TONEWBSS_INFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_oldbss_tonewbss_information( + uint8_t **ptr, + LIBLTE_S1AP_OLDBSS_TONEWBSS_INFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE PLMNidentity STATIC OCTET STRING +********************************************************************************/ +#define LIBLTE_S1AP_PLMNIDENTITY_OCTET_STRING_LEN 3 +typedef struct{ + uint8_t buffer[3]; +}LIBLTE_S1AP_PLMNIDENTITY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_plmnidentity( + LIBLTE_S1AP_PLMNIDENTITY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_plmnidentity( + uint8_t **ptr, + LIBLTE_S1AP_PLMNIDENTITY_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ReceiveStatusOfULPDCPSDUsExtended DYNAMIC BIT STRING +********************************************************************************/ +// lb:1, ub:16384 +typedef struct{ + uint32_t n_bits; + uint8_t buffer[16384]; +}LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUSEXTENDED_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_receivestatusofulpdcpsdusextended( + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUSEXTENDED_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_receivestatusofulpdcpsdusextended( + uint8_t **ptr, + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUSEXTENDED_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RequestType SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EVENTTYPE_ENUM_EXT eventType; + LIBLTE_S1AP_REPORTAREA_ENUM_EXT reportArea; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_REQUESTTYPE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_requesttype( + LIBLTE_S1AP_REQUESTTYPE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_requesttype( + uint8_t **ptr, + LIBLTE_S1AP_REQUESTTYPE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RRC_Container DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_RRC_CONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rrc_container( + LIBLTE_S1AP_RRC_CONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rrc_container( + uint8_t **ptr, + LIBLTE_S1AP_RRC_CONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE nextHopChainingCount INTEGER +********************************************************************************/ +typedef struct{ +uint8_t nextHopChainingCount; +}LIBLTE_S1AP_NEXTHOPCHAININGCOUNT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nexthopchainingcount( + LIBLTE_S1AP_NEXTHOPCHAININGCOUNT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nexthopchainingcount( + uint8_t **ptr, + LIBLTE_S1AP_NEXTHOPCHAININGCOUNT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SecurityContext SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_NEXTHOPCHAININGCOUNT_STRUCT nextHopChainingCount; + LIBLTE_S1AP_SECURITYKEY_STRUCT nextHopParameter; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_SECURITYCONTEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_securitycontext( + LIBLTE_S1AP_SECURITYCONTEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_securitycontext( + uint8_t **ptr, + LIBLTE_S1AP_SECURITYCONTEXT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ServedMMECs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_MME_CODE_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_SERVEDMMECS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedmmecs( + LIBLTE_S1AP_SERVEDMMECS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedmmecs( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDMMECS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TimeSynchronizationInfo SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_STRATUMLEVEL_STRUCT stratumLevel; + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM_EXT synchronizationStatus; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TIMESYNCHRONIZATIONINFO_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_timesynchronizationinfo( + LIBLTE_S1AP_TIMESYNCHRONIZATIONINFO_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_timesynchronizationinfo( + uint8_t **ptr, + LIBLTE_S1AP_TIMESYNCHRONIZATIONINFO_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAI SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT pLMNidentity; + LIBLTE_S1AP_TAC_STRUCT tAC; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TAI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai( + LIBLTE_S1AP_TAI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai( + uint8_t **ptr, + LIBLTE_S1AP_TAI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TABasedMDT SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TALISTFORMDT_STRUCT tAListforMDT; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TABASEDMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tabasedmdt( + LIBLTE_S1AP_TABASEDMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tabasedmdt( + uint8_t **ptr, + LIBLTE_S1AP_TABASEDMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TargeteNB_ToSourceeNB_TransparentContainer SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_RRC_CONTAINER_STRUCT rRC_Container; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_tosourceenb_transparentcontainer( + LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_tosourceenb_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE M1ThresholdEventA2 SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_STRUCT measurementThreshold; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_M1THRESHOLDEVENTA2_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1thresholdeventa2( + LIBLTE_S1AP_M1THRESHOLDEVENTA2_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1thresholdeventa2( + uint8_t **ptr, + LIBLTE_S1AP_M1THRESHOLDEVENTA2_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TransportInformation SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT uL_GTP_TEID; +}LIBLTE_S1AP_TRANSPORTINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_transportinformation( + LIBLTE_S1AP_TRANSPORTINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_transportinformation( + uint8_t **ptr, + LIBLTE_S1AP_TRANSPORTINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TunnelInformation SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_PORT_NUMBER_STRUCT uDP_Port_Number; + bool uDP_Port_Number_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TUNNELINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tunnelinformation( + LIBLTE_S1AP_TUNNELINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tunnelinformation( + uint8_t **ptr, + LIBLTE_S1AP_TUNNELINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE UE_S1AP_IDs CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UE_S1AP_ID_PAIR, + LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_MME_UE_S1AP_ID, + LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_N_ITEMS, +}LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_ENUM; +static const char liblte_s1ap_ue_s1ap_ids_choice_text[LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_N_ITEMS][50] = { + "uE_S1AP_ID_pair", + "mME_UE_S1AP_ID", +}; + +typedef union{ + LIBLTE_S1AP_UE_S1AP_ID_PAIR_STRUCT uE_S1AP_ID_pair; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT mME_UE_S1AP_ID; +}LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UNION choice; + LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_UE_S1AP_IDS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_s1ap_ids( + LIBLTE_S1AP_UE_S1AP_IDS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_s1ap_ids( + uint8_t **ptr, + LIBLTE_S1AP_UE_S1AP_IDS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ENBX2ExtTLA SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT iPsecTLA; + bool iPsecTLA_present; + LIBLTE_S1AP_ENBX2GTPTLAS_STRUCT gTPTLAa; + bool gTPTLAa_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_ENBX2EXTTLA_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2exttla( + LIBLTE_S1AP_ENBX2EXTTLA_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2exttla( + uint8_t **ptr, + LIBLTE_S1AP_ENBX2EXTTLA_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE BPLMNs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:6 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TBCD_STRING_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_BPLMNS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bplmns( + LIBLTE_S1AP_BPLMNS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bplmns( + uint8_t **ptr, + LIBLTE_S1AP_BPLMNS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Cause CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_CAUSE_CHOICE_RADIONETWORK, + LIBLTE_S1AP_CAUSE_CHOICE_TRANSPORT, + LIBLTE_S1AP_CAUSE_CHOICE_NAS, + LIBLTE_S1AP_CAUSE_CHOICE_PROTOCOL, + LIBLTE_S1AP_CAUSE_CHOICE_MISC, + LIBLTE_S1AP_CAUSE_CHOICE_N_ITEMS, +}LIBLTE_S1AP_CAUSE_CHOICE_ENUM; +static const char liblte_s1ap_cause_choice_text[LIBLTE_S1AP_CAUSE_CHOICE_N_ITEMS][50] = { + "radioNetwork", + "transport", + "nas", + "protocol", + "misc", +}; + +typedef union{ + LIBLTE_S1AP_CAUSERADIONETWORK_ENUM_EXT radioNetwork; + LIBLTE_S1AP_CAUSETRANSPORT_ENUM_EXT transport; + LIBLTE_S1AP_CAUSENAS_ENUM_EXT nas; + LIBLTE_S1AP_CAUSEPROTOCOL_ENUM_EXT protocol; + LIBLTE_S1AP_CAUSEMISC_ENUM_EXT misc; +}LIBLTE_S1AP_CAUSE_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSE_CHOICE_UNION choice; + LIBLTE_S1AP_CAUSE_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_CAUSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cause( + LIBLTE_S1AP_CAUSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cause( + uint8_t **ptr, + LIBLTE_S1AP_CAUSE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXSRVCCInfo SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CDMA2000ONEXMEID_STRUCT cdma2000OneXMEID; + LIBLTE_S1AP_CDMA2000ONEXMSI_STRUCT cdma2000OneXMSI; + LIBLTE_S1AP_CDMA2000ONEXPILOT_STRUCT cdma2000OneXPilot; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CDMA2000ONEXSRVCCINFO_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexsrvccinfo( + LIBLTE_S1AP_CDMA2000ONEXSRVCCINFO_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexsrvccinfo( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXSRVCCINFO_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CGI SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT pLMNidentity; + LIBLTE_S1AP_LAC_STRUCT lAC; + LIBLTE_S1AP_CI_STRUCT cI; + LIBLTE_S1AP_RAC_STRUCT rAC; + bool rAC_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CGI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cgi( + LIBLTE_S1AP_CGI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cgi( + uint8_t **ptr, + LIBLTE_S1AP_CGI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE COUNTValueExtended SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_PDCP_SNEXTENDED_STRUCT pDCP_SNExtended; + LIBLTE_S1AP_HFNMODIFIED_STRUCT hFNModified; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_COUNTVALUEEXTENDED_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_countvalueextended( + LIBLTE_S1AP_COUNTVALUEEXTENDED_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_countvalueextended( + uint8_t **ptr, + LIBLTE_S1AP_COUNTVALUEEXTENDED_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CriticalityDiagnostics_IE_List DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_LIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics_ie_list( + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_LIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ie_list( + uint8_t **ptr, + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_LIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Global_ENB_ID SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT pLMNidentity; + LIBLTE_S1AP_ENB_ID_STRUCT eNB_ID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_global_enb_id( + LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_global_enb_id( + uint8_t **ptr, + LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EPLMNs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:15 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TBCD_STRING_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_EPLMNS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eplmns( + LIBLTE_S1AP_EPLMNS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eplmns( + uint8_t **ptr, + LIBLTE_S1AP_EPLMNS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_CAUSE_STRUCT cause; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabitem( + LIBLTE_S1AP_E_RABITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EUTRAN_CGI SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT pLMNidentity; + LIBLTE_S1AP_CELLIDENTITY_STRUCT cell_ID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_EUTRAN_CGI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eutran_cgi( + LIBLTE_S1AP_EUTRAN_CGI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eutran_cgi( + uint8_t **ptr, + LIBLTE_S1AP_EUTRAN_CGI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ForbiddenTAs_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT pLMN_Identity; + LIBLTE_S1AP_FORBIDDENTACS_STRUCT forbiddenTACs; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_FORBIDDENTAS_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddentas_item( + LIBLTE_S1AP_FORBIDDENTAS_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddentas_item( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENTAS_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ForbiddenLAs_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT pLMN_Identity; + LIBLTE_S1AP_FORBIDDENLACS_STRUCT forbiddenLACs; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_FORBIDDENLAS_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddenlas_item( + LIBLTE_S1AP_FORBIDDENLAS_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddenlas_item( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENLAS_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE LAI SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT pLMNidentity; + LIBLTE_S1AP_LAC_STRUCT lAC; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_LAI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lai( + LIBLTE_S1AP_LAI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lai( + uint8_t **ptr, + LIBLTE_S1AP_LAI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE M4Configuration SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_M4PERIOD_ENUM_EXT m4period; + LIBLTE_S1AP_LINKS_TO_LOG_ENUM_EXT m4_links_to_log; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_M4CONFIGURATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m4configuration( + LIBLTE_S1AP_M4CONFIGURATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m4configuration( + uint8_t **ptr, + LIBLTE_S1AP_M4CONFIGURATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MDTPLMNList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TBCD_STRING_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_MDTPLMNLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdtplmnlist( + LIBLTE_S1AP_MDTPLMNLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdtplmnlist( + uint8_t **ptr, + LIBLTE_S1AP_MDTPLMNLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MMERelaySupportIndicator ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_TRUE, + LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_N_ITEMS, +}LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM; +static const char liblte_s1ap_mmerelaysupportindicator_text[LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_N_ITEMS][80] = { + "true", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM e; +}LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmerelaysupportindicator( + LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmerelaysupportindicator( + uint8_t **ptr, + LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE PagingPriority ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_PAGINGPRIORITY_PRIOLEVEL1, + LIBLTE_S1AP_PAGINGPRIORITY_PRIOLEVEL2, + LIBLTE_S1AP_PAGINGPRIORITY_PRIOLEVEL3, + LIBLTE_S1AP_PAGINGPRIORITY_PRIOLEVEL4, + LIBLTE_S1AP_PAGINGPRIORITY_PRIOLEVEL5, + LIBLTE_S1AP_PAGINGPRIORITY_PRIOLEVEL6, + LIBLTE_S1AP_PAGINGPRIORITY_PRIOLEVEL7, + LIBLTE_S1AP_PAGINGPRIORITY_PRIOLEVEL8, + LIBLTE_S1AP_PAGINGPRIORITY_N_ITEMS, +}LIBLTE_S1AP_PAGINGPRIORITY_ENUM; +static const char liblte_s1ap_pagingpriority_text[LIBLTE_S1AP_PAGINGPRIORITY_N_ITEMS][80] = { + "priolevel1", + "priolevel2", + "priolevel3", + "priolevel4", + "priolevel5", + "priolevel6", + "priolevel7", + "priolevel8", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_PAGINGPRIORITY_ENUM e; +}LIBLTE_S1AP_PAGINGPRIORITY_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pagingpriority( + LIBLTE_S1AP_PAGINGPRIORITY_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pagingpriority( + uint8_t **ptr, + LIBLTE_S1AP_PAGINGPRIORITY_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE PriorityLevel INTEGER +********************************************************************************/ +typedef struct{ +uint8_t PriorityLevel; +}LIBLTE_S1AP_PRIORITYLEVEL_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_prioritylevel( + LIBLTE_S1AP_PRIORITYLEVEL_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_prioritylevel( + uint8_t **ptr, + LIBLTE_S1AP_PRIORITYLEVEL_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ECGIListForRestart DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_ECGILISTFORRESTART_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ecgilistforrestart( + LIBLTE_S1AP_ECGILISTFORRESTART_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ecgilistforrestart( + uint8_t **ptr, + LIBLTE_S1AP_ECGILISTFORRESTART_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SourceeNB_ID SEQUENCE +********************************************************************************/ +typedef struct{ + LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT global_ENB_ID; + LIBLTE_S1AP_TAI_STRUCT selected_TAI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_SOURCEENB_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_id( + LIBLTE_S1AP_SOURCEENB_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_id( + uint8_t **ptr, + LIBLTE_S1AP_SOURCEENB_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ServedPLMNs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:32 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TBCD_STRING_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_SERVEDPLMNS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedplmns( + LIBLTE_S1AP_SERVEDPLMNS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedplmns( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDPLMNS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SupportedTAs_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TAC_STRUCT tAC; + LIBLTE_S1AP_BPLMNS_STRUCT broadcastPLMNs; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_SUPPORTEDTAS_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_supportedtas_item( + LIBLTE_S1AP_SUPPORTEDTAS_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_supportedtas_item( + uint8_t **ptr, + LIBLTE_S1AP_SUPPORTEDTAS_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAIListforMDT DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:8 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TAI_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_TAILISTFORMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tailistformdt( + LIBLTE_S1AP_TAILISTFORMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tailistformdt( + uint8_t **ptr, + LIBLTE_S1AP_TAILISTFORMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CompletedCellinTAI_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT eCGI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_COMPLETEDCELLINTAI_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellintai_item( + LIBLTE_S1AP_COMPLETEDCELLINTAI_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellintai_item( + uint8_t **ptr, + LIBLTE_S1AP_COMPLETEDCELLINTAI_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TargeteNB_ID SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT global_ENB_ID; + LIBLTE_S1AP_TAI_STRUCT selected_TAI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TARGETENB_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_id( + LIBLTE_S1AP_TARGETENB_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_id( + uint8_t **ptr, + LIBLTE_S1AP_TARGETENB_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TargetBSS_ToSourceBSS_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetbss_tosourcebss_transparentcontainer( + LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetbss_tosourcebss_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAIListForRestart DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:2048 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TAI_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_TAILISTFORRESTART_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tailistforrestart( + LIBLTE_S1AP_TAILISTFORRESTART_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tailistforrestart( + uint8_t **ptr, + LIBLTE_S1AP_TAILISTFORRESTART_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE UserLocationInformation SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT eutran_cgi; + LIBLTE_S1AP_TAI_STRUCT tai; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_userlocationinformation( + LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_userlocationinformation( + uint8_t **ptr, + LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ENBX2ExtTLAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_ENBX2EXTTLA_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_ENBX2EXTTLAS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2exttlas( + LIBLTE_S1AP_ENBX2EXTTLAS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2exttlas( + uint8_t **ptr, + LIBLTE_S1AP_ENBX2EXTTLAS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE AllocationAndRetentionPriority SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_PRIORITYLEVEL_STRUCT priorityLevel; + LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM pre_emptionCapability; + LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM pre_emptionVulnerability; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_ALLOCATIONANDRETENTIONPRIORITY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_allocationandretentionpriority( + LIBLTE_S1AP_ALLOCATIONANDRETENTIONPRIORITY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_allocationandretentionpriority( + uint8_t **ptr, + LIBLTE_S1AP_ALLOCATIONANDRETENTIONPRIORITY_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CancelledCellinEAI_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT eCGI; + LIBLTE_S1AP_NUMBEROFBROADCASTS_STRUCT numberOfBroadcasts; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CANCELLEDCELLINEAI_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellineai_item( + LIBLTE_S1AP_CANCELLEDCELLINEAI_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellineai_item( + uint8_t **ptr, + LIBLTE_S1AP_CANCELLEDCELLINEAI_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CancelledCellinTAI_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT eCGI; + LIBLTE_S1AP_NUMBEROFBROADCASTS_STRUCT numberOfBroadcasts; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CANCELLEDCELLINTAI_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellintai_item( + LIBLTE_S1AP_CANCELLEDCELLINTAI_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellintai_item( + uint8_t **ptr, + LIBLTE_S1AP_CANCELLEDCELLINTAI_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CellID_Broadcast_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT eCGI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CELLID_BROADCAST_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_broadcast_item( + LIBLTE_S1AP_CELLID_BROADCAST_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_broadcast_item( + uint8_t **ptr, + LIBLTE_S1AP_CELLID_BROADCAST_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CellID_Cancelled_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT eCGI; + LIBLTE_S1AP_NUMBEROFBROADCASTS_STRUCT numberOfBroadcasts; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CELLID_CANCELLED_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_cancelled_item( + LIBLTE_S1AP_CELLID_CANCELLED_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_cancelled_item( + uint8_t **ptr, + LIBLTE_S1AP_CELLID_CANCELLED_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CellIdListforMDT DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:32 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_CELLIDLISTFORMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellidlistformdt( + LIBLTE_S1AP_CELLIDLISTFORMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellidlistformdt( + uint8_t **ptr, + LIBLTE_S1AP_CELLIDLISTFORMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CSG_Id STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_CSG_ID_BIT_STRING_LEN 27 +typedef struct{ + uint8_t buffer[27]; +}LIBLTE_S1AP_CSG_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csg_id( + LIBLTE_S1AP_CSG_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csg_id( + uint8_t **ptr, + LIBLTE_S1AP_CSG_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CSG_IdList_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CSG_ID_STRUCT cSG_Id; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CSG_IDLIST_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csg_idlist_item( + LIBLTE_S1AP_CSG_IDLIST_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csg_idlist_item( + uint8_t **ptr, + LIBLTE_S1AP_CSG_IDLIST_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Direct_Forwarding_Path_Availability ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_DIRECTPATHAVAILABLE, + LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_N_ITEMS, +}LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM; +static const char liblte_s1ap_direct_forwarding_path_availability_text[LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_N_ITEMS][80] = { + "directPathAvailable", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM e; +}LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_direct_forwarding_path_availability( + LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_direct_forwarding_path_availability( + uint8_t **ptr, + LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE CompletedCellinEAI_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT eCGI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_COMPLETEDCELLINEAI_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellineai_item( + LIBLTE_S1AP_COMPLETEDCELLINEAI_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellineai_item( + uint8_t **ptr, + LIBLTE_S1AP_COMPLETEDCELLINEAI_ITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABInformationList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABINFORMATIONLISTITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABINFORMATIONLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabinformationlist( + LIBLTE_S1AP_E_RABINFORMATIONLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABINFORMATIONLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ForbiddenTAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_FORBIDDENTAS_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_FORBIDDENTAS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddentas( + LIBLTE_S1AP_FORBIDDENTAS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddentas( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENTAS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE GUMMEI SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT pLMN_Identity; + LIBLTE_S1AP_MME_GROUP_ID_STRUCT mME_Group_ID; + LIBLTE_S1AP_MME_CODE_STRUCT mME_Code; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_GUMMEI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gummei( + LIBLTE_S1AP_GUMMEI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gummei( + uint8_t **ptr, + LIBLTE_S1AP_GUMMEI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE LoggedMDT SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_LOGGINGINTERVAL_ENUM loggingInterval; + LIBLTE_S1AP_LOGGINGDURATION_ENUM loggingDuration; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_LOGGEDMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_loggedmdt( + LIBLTE_S1AP_LOGGEDMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_loggedmdt( + uint8_t **ptr, + LIBLTE_S1AP_LOGGEDMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE NASSecurityParametersfromE_UTRAN DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_NASSECURITYPARAMETERSFROME_UTRAN_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nassecurityparametersfrome_utran( + LIBLTE_S1AP_NASSECURITYPARAMETERSFROME_UTRAN_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nassecurityparametersfrome_utran( + uint8_t **ptr, + LIBLTE_S1AP_NASSECURITYPARAMETERSFROME_UTRAN_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ReportAmountMDT ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_REPORTAMOUNTMDT_R1, + LIBLTE_S1AP_REPORTAMOUNTMDT_R2, + LIBLTE_S1AP_REPORTAMOUNTMDT_R4, + LIBLTE_S1AP_REPORTAMOUNTMDT_R8, + LIBLTE_S1AP_REPORTAMOUNTMDT_R16, + LIBLTE_S1AP_REPORTAMOUNTMDT_R32, + LIBLTE_S1AP_REPORTAMOUNTMDT_R64, + LIBLTE_S1AP_REPORTAMOUNTMDT_RINFINITY, + LIBLTE_S1AP_REPORTAMOUNTMDT_N_ITEMS, +}LIBLTE_S1AP_REPORTAMOUNTMDT_ENUM; +static const char liblte_s1ap_reportamountmdt_text[LIBLTE_S1AP_REPORTAMOUNTMDT_N_ITEMS][80] = { + "r1", + "r2", + "r4", + "r8", + "r16", + "r32", + "r64", + "rinfinity", +}; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_reportamountmdt( + LIBLTE_S1AP_REPORTAMOUNTMDT_ENUM *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_reportamountmdt( + uint8_t **ptr, + LIBLTE_S1AP_REPORTAMOUNTMDT_ENUM *ie); + +/******************************************************************************* +/* ProtocolIE ServedGUMMEIsItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_SERVEDPLMNS_STRUCT servedPLMNs; + LIBLTE_S1AP_SERVEDGROUPIDS_STRUCT servedGroupIDs; + LIBLTE_S1AP_SERVEDMMECS_STRUCT servedMMECs; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_SERVEDGUMMEISITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedgummeisitem( + LIBLTE_S1AP_SERVEDGUMMEISITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedgummeisitem( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDGUMMEISITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE S_TMSI SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_CODE_STRUCT mMEC; + LIBLTE_S1AP_M_TMSI_STRUCT m_TMSI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_S_TMSI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s_tmsi( + LIBLTE_S1AP_S_TMSI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s_tmsi( + uint8_t **ptr, + LIBLTE_S1AP_S_TMSI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAIListforWarning DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TAI_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_TAILISTFORWARNING_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tailistforwarning( + LIBLTE_S1AP_TAILISTFORWARNING_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tailistforwarning( + uint8_t **ptr, + LIBLTE_S1AP_TAILISTFORWARNING_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CompletedCellinTAI DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_COMPLETEDCELLINTAI_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_COMPLETEDCELLINTAI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellintai( + LIBLTE_S1AP_COMPLETEDCELLINTAI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellintai( + uint8_t **ptr, + LIBLTE_S1AP_COMPLETEDCELLINTAI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TargetRNC_ID SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_LAI_STRUCT lAI; + LIBLTE_S1AP_RAC_STRUCT rAC; + bool rAC_present; + LIBLTE_S1AP_RNC_ID_STRUCT rNC_ID; + LIBLTE_S1AP_EXTENDEDRNC_ID_STRUCT extendedRNC_ID; + bool extendedRNC_ID_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TARGETRNC_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetrnc_id( + LIBLTE_S1AP_TARGETRNC_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetrnc_id( + uint8_t **ptr, + LIBLTE_S1AP_TARGETRNC_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE UE_associatedLogicalS1_ConnectionItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT mME_UE_S1AP_ID; + bool mME_UE_S1AP_ID_present; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + bool eNB_UE_S1AP_ID_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitem( + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitem( + uint8_t **ptr, + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE UEPagingID CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_UEPAGINGID_CHOICE_S_TMSI, + LIBLTE_S1AP_UEPAGINGID_CHOICE_IMSI, + LIBLTE_S1AP_UEPAGINGID_CHOICE_N_ITEMS, +}LIBLTE_S1AP_UEPAGINGID_CHOICE_ENUM; +static const char liblte_s1ap_uepagingid_choice_text[LIBLTE_S1AP_UEPAGINGID_CHOICE_N_ITEMS][50] = { + "s_TMSI", + "iMSI", +}; + +typedef union{ + LIBLTE_S1AP_S_TMSI_STRUCT s_TMSI; + LIBLTE_S1AP_IMSI_STRUCT iMSI; +}LIBLTE_S1AP_UEPAGINGID_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_UEPAGINGID_CHOICE_UNION choice; + LIBLTE_S1AP_UEPAGINGID_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_UEPAGINGID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uepagingid( + LIBLTE_S1AP_UEPAGINGID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uepagingid( + uint8_t **ptr, + LIBLTE_S1AP_UEPAGINGID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE Bearers_SubjectToStatusTransfer_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_COUNTVALUE_STRUCT uL_COUNTvalue; + LIBLTE_S1AP_COUNTVALUE_STRUCT dL_COUNTvalue; + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUS_STRUCT receiveStatusofULPDCPSDUs; + bool receiveStatusofULPDCPSDUs_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_item( + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransfer_item( + uint8_t **ptr, + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CancelledCellinEAI DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_CANCELLEDCELLINEAI_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_CANCELLEDCELLINEAI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellineai( + LIBLTE_S1AP_CANCELLEDCELLINEAI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellineai( + uint8_t **ptr, + LIBLTE_S1AP_CANCELLEDCELLINEAI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CellID_Broadcast DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_CELLID_BROADCAST_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_CELLID_BROADCAST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_broadcast( + LIBLTE_S1AP_CELLID_BROADCAST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_broadcast( + uint8_t **ptr, + LIBLTE_S1AP_CELLID_BROADCAST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CellBasedMDT SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CELLIDLISTFORMDT_STRUCT cellIdListforMDT; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CELLBASEDMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellbasedmdt( + LIBLTE_S1AP_CELLBASEDMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellbasedmdt( + uint8_t **ptr, + LIBLTE_S1AP_CELLBASEDMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CSG_IdList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_CSG_IDLIST_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_CSG_IDLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csg_idlist( + LIBLTE_S1AP_CSG_IDLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csg_idlist( + uint8_t **ptr, + LIBLTE_S1AP_CSG_IDLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ECGIList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_ECGILIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ecgilist( + LIBLTE_S1AP_ECGILIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ecgilist( + uint8_t **ptr, + LIBLTE_S1AP_ECGILIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID_Cancelled_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EMERGENCYAREAID_STRUCT emergencyAreaID; + LIBLTE_S1AP_CANCELLEDCELLINEAI_STRUCT cancelledCellinEAI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_cancelled_item( + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_cancelled_item( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE GERAN_Cell_ID SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_LAI_STRUCT lAI; + LIBLTE_S1AP_RAC_STRUCT rAC; + LIBLTE_S1AP_CI_STRUCT cI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_GERAN_CELL_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_geran_cell_id( + LIBLTE_S1AP_GERAN_CELL_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_geran_cell_id( + uint8_t **ptr, + LIBLTE_S1AP_GERAN_CELL_ID_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rablist( + LIBLTE_S1AP_E_RABLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rablist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ForbiddenLAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_FORBIDDENLAS_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_FORBIDDENLAS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddenlas( + LIBLTE_S1AP_FORBIDDENLAS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddenlas( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENLAS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MDT_Location_Info STATIC BIT STRING +********************************************************************************/ +#define LIBLTE_S1AP_MDT_LOCATION_INFO_BIT_STRING_LEN 8 +typedef struct{ + uint8_t buffer[8]; +}LIBLTE_S1AP_MDT_LOCATION_INFO_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdt_location_info( + LIBLTE_S1AP_MDT_LOCATION_INFO_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdt_location_info( + uint8_t **ptr, + LIBLTE_S1AP_MDT_LOCATION_INFO_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE M1PeriodicReporting SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_REPORTINTERVALMDT_ENUM reportInterval; + LIBLTE_S1AP_REPORTAMOUNTMDT_ENUM reportAmount; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_M1PERIODICREPORTING_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1periodicreporting( + LIBLTE_S1AP_M1PERIODICREPORTING_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1periodicreporting( + uint8_t **ptr, + LIBLTE_S1AP_M1PERIODICREPORTING_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE eHRPD_Sector_ID DYNAMIC OCTET STRING +********************************************************************************/ +// lb:0, ub:16318 +typedef struct{ + uint32_t n_octets; + uint8_t buffer[16318]; +}LIBLTE_S1AP_EHRPD_SECTOR_ID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ehrpd_sector_id( + LIBLTE_S1AP_EHRPD_SECTOR_ID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ehrpd_sector_id( + uint8_t **ptr, + LIBLTE_S1AP_EHRPD_SECTOR_ID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RIMRoutingAddress CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_GERAN_CELL_ID, + LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_TARGETRNC_ID, + LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_EHRPD_SECTOR_ID, + LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_N_ITEMS, +}LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_ENUM; +static const char liblte_s1ap_rimroutingaddress_choice_text[LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_N_ITEMS][50] = { + "gERAN_Cell_ID", + "targetRNC_ID", + "eHRPD_Sector_ID", +}; + +typedef union{ + LIBLTE_S1AP_GERAN_CELL_ID_STRUCT gERAN_Cell_ID; + LIBLTE_S1AP_TARGETRNC_ID_STRUCT targetRNC_ID; + LIBLTE_S1AP_EHRPD_SECTOR_ID_STRUCT eHRPD_Sector_ID; +}LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_UNION choice; + LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_RIMROUTINGADDRESS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rimroutingaddress( + LIBLTE_S1AP_RIMROUTINGADDRESS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rimroutingaddress( + uint8_t **ptr, + LIBLTE_S1AP_RIMROUTINGADDRESS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ServedGUMMEIs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:8 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_SERVEDGUMMEISITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_SERVEDGUMMEIS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedgummeis( + LIBLTE_S1AP_SERVEDGUMMEIS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedgummeis( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDGUMMEIS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAIBasedMDT SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TAILISTFORMDT_STRUCT tAIListforMDT; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TAIBASEDMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taibasedmdt( + LIBLTE_S1AP_TAIBASEDMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taibasedmdt( + uint8_t **ptr, + LIBLTE_S1AP_TAIBASEDMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAI_Broadcast_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TAI_STRUCT tAI; + LIBLTE_S1AP_COMPLETEDCELLINTAI_STRUCT completedCellinTAI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TAI_BROADCAST_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_broadcast_item( + LIBLTE_S1AP_TAI_BROADCAST_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_broadcast_item( + uint8_t **ptr, + LIBLTE_S1AP_TAI_BROADCAST_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TargetID CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_TARGETID_CHOICE_TARGETENB_ID, + LIBLTE_S1AP_TARGETID_CHOICE_TARGETRNC_ID, + LIBLTE_S1AP_TARGETID_CHOICE_CGI, + LIBLTE_S1AP_TARGETID_CHOICE_N_ITEMS, +}LIBLTE_S1AP_TARGETID_CHOICE_ENUM; +static const char liblte_s1ap_targetid_choice_text[LIBLTE_S1AP_TARGETID_CHOICE_N_ITEMS][50] = { + "targeteNB_ID", + "targetRNC_ID", + "cGI", +}; + +typedef union{ + LIBLTE_S1AP_TARGETENB_ID_STRUCT targeteNB_ID; + LIBLTE_S1AP_TARGETRNC_ID_STRUCT targetRNC_ID; + LIBLTE_S1AP_CGI_STRUCT cGI; +}LIBLTE_S1AP_TARGETID_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_TARGETID_CHOICE_UNION choice; + LIBLTE_S1AP_TARGETID_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_TARGETID_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetid( + LIBLTE_S1AP_TARGETID_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetid( + uint8_t **ptr, + LIBLTE_S1AP_TARGETID_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE WarningAreaList CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_WARNINGAREALIST_CHOICE_CELLIDLIST, + LIBLTE_S1AP_WARNINGAREALIST_CHOICE_TRACKINGAREALISTFORWARNING, + LIBLTE_S1AP_WARNINGAREALIST_CHOICE_EMERGENCYAREAIDLIST, + LIBLTE_S1AP_WARNINGAREALIST_CHOICE_N_ITEMS, +}LIBLTE_S1AP_WARNINGAREALIST_CHOICE_ENUM; +static const char liblte_s1ap_warningarealist_choice_text[LIBLTE_S1AP_WARNINGAREALIST_CHOICE_N_ITEMS][50] = { + "cellIDList", + "trackingAreaListforWarning", + "emergencyAreaIDList", +}; + +typedef union{ + LIBLTE_S1AP_ECGILIST_STRUCT cellIDList; + LIBLTE_S1AP_TAILISTFORWARNING_STRUCT trackingAreaListforWarning; + LIBLTE_S1AP_EMERGENCYAREAIDLIST_STRUCT emergencyAreaIDList; +}LIBLTE_S1AP_WARNINGAREALIST_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_WARNINGAREALIST_CHOICE_UNION choice; + LIBLTE_S1AP_WARNINGAREALIST_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_WARNINGAREALIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_warningarealist( + LIBLTE_S1AP_WARNINGAREALIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_warningarealist( + uint8_t **ptr, + LIBLTE_S1AP_WARNINGAREALIST_STRUCT *ie); + +//TODO: Type pLMNWide NULL + +/******************************************************************************* +/* ProtocolIE AreaScopeOfMDT CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_CELLBASED, + LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_TABASED, + LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_PLMNWIDE, + LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_TAIBASED, + LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_N_ITEMS, +}LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_ENUM; +static const char liblte_s1ap_areascopeofmdt_choice_text[LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_N_ITEMS][50] = { + "cellBased", + "tABased", + "pLMNWide", + "tAIBased", +}; + +typedef union{ + LIBLTE_S1AP_CELLBASEDMDT_STRUCT cellBased; + LIBLTE_S1AP_TABASEDMDT_STRUCT tABased; + //TODO: NULL pLMNWide; + LIBLTE_S1AP_TAIBASEDMDT_STRUCT tAIBased; +}LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_UNION choice; + LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_AREASCOPEOFMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_areascopeofmdt( + LIBLTE_S1AP_AREASCOPEOFMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_areascopeofmdt( + uint8_t **ptr, + LIBLTE_S1AP_AREASCOPEOFMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CancelledCellinTAI DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_CANCELLEDCELLINTAI_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_CANCELLEDCELLINTAI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellintai( + LIBLTE_S1AP_CANCELLEDCELLINTAI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellintai( + uint8_t **ptr, + LIBLTE_S1AP_CANCELLEDCELLINTAI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CellType SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CELL_SIZE_ENUM_EXT cell_Size; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CELLTYPE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_celltype( + LIBLTE_S1AP_CELLTYPE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_celltype( + uint8_t **ptr, + LIBLTE_S1AP_CELLTYPE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID_Cancelled DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_cancelled( + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_cancelled( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE GUMMEIList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_GUMMEI_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_GUMMEILIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gummeilist( + LIBLTE_S1AP_GUMMEILIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gummeilist( + uint8_t **ptr, + LIBLTE_S1AP_GUMMEILIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABLevelQoSParameters SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_QCI_STRUCT qCI; + LIBLTE_S1AP_ALLOCATIONANDRETENTIONPRIORITY_STRUCT allocationRetentionPriority; + LIBLTE_S1AP_GBR_QOSINFORMATION_STRUCT gbrQosInformation; + bool gbrQosInformation_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rablevelqosparameters( + LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rablevelqosparameters( + uint8_t **ptr, + LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE LastVisitedEUTRANCellInformation SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT global_Cell_ID; + LIBLTE_S1AP_CELLTYPE_STRUCT cellType; + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_STRUCT time_UE_StayedInCell; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_LASTVISITEDEUTRANCELLINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedeutrancellinformation( + LIBLTE_S1AP_LASTVISITEDEUTRANCELLINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedeutrancellinformation( + uint8_t **ptr, + LIBLTE_S1AP_LASTVISITEDEUTRANCELLINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE RIMTransfer SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_RIMINFORMATION_STRUCT rIMInformation; + LIBLTE_S1AP_RIMROUTINGADDRESS_STRUCT rIMRoutingAddress; + bool rIMRoutingAddress_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_RIMTRANSFER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rimtransfer( + LIBLTE_S1AP_RIMTRANSFER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rimtransfer( + uint8_t **ptr, + LIBLTE_S1AP_RIMTRANSFER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SupportedTAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_SUPPORTEDTAS_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_SUPPORTEDTAS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_supportedtas( + LIBLTE_S1AP_SUPPORTEDTAS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_supportedtas( + uint8_t **ptr, + LIBLTE_S1AP_SUPPORTEDTAS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAI_Cancelled_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TAI_STRUCT tAI; + LIBLTE_S1AP_CANCELLEDCELLINTAI_STRUCT cancelledCellinTAI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TAI_CANCELLED_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_cancelled_item( + LIBLTE_S1AP_TAI_CANCELLED_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_cancelled_item( + uint8_t **ptr, + LIBLTE_S1AP_TAI_CANCELLED_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE X2TNLConfigurationInfo SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ENBX2TLAS_STRUCT eNBX2TransportLayerAddresses; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_X2TNLCONFIGURATIONINFO_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_x2tnlconfigurationinfo( + LIBLTE_S1AP_X2TNLCONFIGURATIONINFO_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_x2tnlconfigurationinfo( + uint8_t **ptr, + LIBLTE_S1AP_X2TNLCONFIGURATIONINFO_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List Bearers_SubjectToStatusTransferList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFERLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransferlist( + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFERLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransferlist( + uint8_t **ptr, + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFERLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CellID_Cancelled DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_CELLID_CANCELLED_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_CELLID_CANCELLED_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_cancelled( + LIBLTE_S1AP_CELLID_CANCELLED_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_cancelled( + uint8_t **ptr, + LIBLTE_S1AP_CELLID_CANCELLED_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CompletedCellinEAI DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_COMPLETEDCELLINEAI_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_COMPLETEDCELLINEAI_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellineai( + LIBLTE_S1AP_COMPLETEDCELLINEAI_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellineai( + uint8_t **ptr, + LIBLTE_S1AP_COMPLETEDCELLINEAI_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE HandoverRestrictionList SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TBCD_STRING_STRUCT servingPLMN; + LIBLTE_S1AP_EPLMNS_STRUCT equivalentPLMNs; + bool equivalentPLMNs_present; + LIBLTE_S1AP_FORBIDDENTAS_STRUCT forbiddenTAs; + bool forbiddenTAs_present; + LIBLTE_S1AP_FORBIDDENLAS_STRUCT forbiddenLAs; + bool forbiddenLAs_present; + LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM_EXT forbiddenInterRATs; + bool forbiddenInterRATs_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_HANDOVERRESTRICTIONLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrestrictionlist( + LIBLTE_S1AP_HANDOVERRESTRICTIONLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrestrictionlist( + uint8_t **ptr, + LIBLTE_S1AP_HANDOVERRESTRICTIONLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE LastVisitedCell_Item CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_E_UTRAN_CELL, + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_UTRAN_CELL, + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_GERAN_CELL, + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_N_ITEMS, +}LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_ENUM; +static const char liblte_s1ap_lastvisitedcell_item_choice_text[LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_N_ITEMS][50] = { + "e_UTRAN_Cell", + "uTRAN_Cell", + "gERAN_Cell", +}; + +typedef union{ + LIBLTE_S1AP_LASTVISITEDEUTRANCELLINFORMATION_STRUCT e_UTRAN_Cell; + LIBLTE_S1AP_LASTVISITEDUTRANCELLINFORMATION_STRUCT uTRAN_Cell; + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_STRUCT gERAN_Cell; +}LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_UNION choice; + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_LASTVISITEDCELL_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedcell_item( + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedcell_item( + uint8_t **ptr, + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SONInformationReply SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_X2TNLCONFIGURATIONINFO_STRUCT x2TNLConfigurationInfo; + bool x2TNLConfigurationInfo_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_SONINFORMATIONREPLY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_soninformationreply( + LIBLTE_S1AP_SONINFORMATIONREPLY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformationreply( + uint8_t **ptr, + LIBLTE_S1AP_SONINFORMATIONREPLY_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAI_Broadcast DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TAI_BROADCAST_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_TAI_BROADCAST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_broadcast( + LIBLTE_S1AP_TAI_BROADCAST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_broadcast( + uint8_t **ptr, + LIBLTE_S1AP_TAI_BROADCAST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TimeToWait ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_TIMETOWAIT_V1S, + LIBLTE_S1AP_TIMETOWAIT_V2S, + LIBLTE_S1AP_TIMETOWAIT_V5S, + LIBLTE_S1AP_TIMETOWAIT_V10S, + LIBLTE_S1AP_TIMETOWAIT_V20S, + LIBLTE_S1AP_TIMETOWAIT_V60S, + LIBLTE_S1AP_TIMETOWAIT_N_ITEMS, +}LIBLTE_S1AP_TIMETOWAIT_ENUM; +static const char liblte_s1ap_timetowait_text[LIBLTE_S1AP_TIMETOWAIT_N_ITEMS][80] = { + "v1s", + "v2s", + "v5s", + "v10s", + "v20s", + "v60s", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_TIMETOWAIT_ENUM e; +}LIBLTE_S1AP_TIMETOWAIT_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_timetowait( + LIBLTE_S1AP_TIMETOWAIT_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_timetowait( + uint8_t **ptr, + LIBLTE_S1AP_TIMETOWAIT_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE UE_HistoryInformation DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_UE_HISTORYINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_historyinformation( + LIBLTE_S1AP_UE_HISTORYINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_historyinformation( + uint8_t **ptr, + LIBLTE_S1AP_UE_HISTORYINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE CriticalityDiagnostics SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_PROCEDURECODE_STRUCT procedureCode; + bool procedureCode_present; + LIBLTE_S1AP_TRIGGERINGMESSAGE_ENUM triggeringMessage; + bool triggeringMessage_present; + LIBLTE_S1AP_CRITICALITY_ENUM procedureCriticality; + bool procedureCriticality_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_LIST_STRUCT iEsCriticalityDiagnostics; + bool iEsCriticalityDiagnostics_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics( + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics( + uint8_t **ptr, + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID_Broadcast_Item SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_EMERGENCYAREAID_STRUCT emergencyAreaID; + LIBLTE_S1AP_COMPLETEDCELLINEAI_STRUCT completedCellinEAI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_broadcast_item( + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_broadcast_item( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_ITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ImmediateMDT SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MEASUREMENTSTOACTIVATE_STRUCT measurementsToActivate; + LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM_EXT m1reportingTrigger; + LIBLTE_S1AP_M1THRESHOLDEVENTA2_STRUCT m1thresholdeventA2; + bool m1thresholdeventA2_present; + LIBLTE_S1AP_M1PERIODICREPORTING_STRUCT m1periodicReporting; + bool m1periodicReporting_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_IMMEDIATEMDT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_immediatemdt( + LIBLTE_S1AP_IMMEDIATEMDT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_immediatemdt( + uint8_t **ptr, + LIBLTE_S1AP_IMMEDIATEMDT_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MDTMode CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_MDTMODE_CHOICE_IMMEDIATEMDT, + LIBLTE_S1AP_MDTMODE_CHOICE_LOGGEDMDT, + LIBLTE_S1AP_MDTMODE_CHOICE_N_ITEMS, +}LIBLTE_S1AP_MDTMODE_CHOICE_ENUM; +static const char liblte_s1ap_mdtmode_choice_text[LIBLTE_S1AP_MDTMODE_CHOICE_N_ITEMS][50] = { + "immediateMDT", + "loggedMDT", +}; + +typedef union{ + LIBLTE_S1AP_IMMEDIATEMDT_STRUCT immediateMDT; + LIBLTE_S1AP_LOGGEDMDT_STRUCT loggedMDT; +}LIBLTE_S1AP_MDTMODE_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_MDTMODE_CHOICE_UNION choice; + LIBLTE_S1AP_MDTMODE_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_MDTMODE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdtmode( + LIBLTE_S1AP_MDTMODE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdtmode( + uint8_t **ptr, + LIBLTE_S1AP_MDTMODE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SourceeNB_ToTargeteNB_TransparentContainer SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_RRC_CONTAINER_STRUCT rRC_Container; + LIBLTE_S1AP_E_RABINFORMATIONLIST_STRUCT e_RABInformationList; + bool e_RABInformationList_present; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT targetCell_ID; + LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT subscriberProfileIDforRFP; + bool subscriberProfileIDforRFP_present; + LIBLTE_S1AP_UE_HISTORYINFORMATION_STRUCT uE_HistoryInformation; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer( + LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_totargetenb_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID_Broadcast DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_broadcast( + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_broadcast( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE MDT_Configuration SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MDT_ACTIVATION_ENUM_EXT mdt_Activation; + LIBLTE_S1AP_AREASCOPEOFMDT_STRUCT areaScopeOfMDT; + LIBLTE_S1AP_MDTMODE_STRUCT mDTMode; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_MDT_CONFIGURATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdt_configuration( + LIBLTE_S1AP_MDT_CONFIGURATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdt_configuration( + uint8_t **ptr, + LIBLTE_S1AP_MDT_CONFIGURATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAI_Cancelled DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TAI_CANCELLED_ITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_TAI_CANCELLED_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_cancelled( + LIBLTE_S1AP_TAI_CANCELLED_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_cancelled( + uint8_t **ptr, + LIBLTE_S1AP_TAI_CANCELLED_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE BroadcastCancelledAreaList CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_CELLID_CANCELLED, + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_TAI_CANCELLED, + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_EMERGENCYAREAID_CANCELLED, + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_N_ITEMS, +}LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_ENUM; +static const char liblte_s1ap_broadcastcancelledarealist_choice_text[LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_N_ITEMS][50] = { + "cellID_Cancelled", + "tAI_Cancelled", + "emergencyAreaID_Cancelled", +}; + +typedef union{ + LIBLTE_S1AP_CELLID_CANCELLED_STRUCT cellID_Cancelled; + LIBLTE_S1AP_TAI_CANCELLED_STRUCT tAI_Cancelled; + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_STRUCT emergencyAreaID_Cancelled; +}LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_UNION choice; + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_broadcastcancelledarealist( + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_broadcastcancelledarealist( + uint8_t **ptr, + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ENB_StatusTransfer_TransparentContainer SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFERLIST_STRUCT bearers_SubjectToStatusTransferList; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_statustransfer_transparentcontainer( + LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_statustransfer_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TraceActivation SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT e_UTRAN_Trace_ID; + LIBLTE_S1AP_INTERFACESTOTRACE_STRUCT interfacesToTrace; + LIBLTE_S1AP_TRACEDEPTH_ENUM_EXT traceDepth; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT traceCollectionEntityIPAddress; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TRACEACTIVATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_traceactivation( + LIBLTE_S1AP_TRACEACTIVATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_traceactivation( + uint8_t **ptr, + LIBLTE_S1AP_TRACEACTIVATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE BroadcastCompletedAreaList CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_CELLID_BROADCAST, + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_TAI_BROADCAST, + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_EMERGENCYAREAID_BROADCAST, + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_N_ITEMS, +}LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_ENUM; +static const char liblte_s1ap_broadcastcompletedarealist_choice_text[LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_N_ITEMS][50] = { + "cellID_Broadcast", + "tAI_Broadcast", + "emergencyAreaID_Broadcast", +}; + +typedef union{ + LIBLTE_S1AP_CELLID_BROADCAST_STRUCT cellID_Broadcast; + LIBLTE_S1AP_TAI_BROADCAST_STRUCT tAI_Broadcast; + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_STRUCT emergencyAreaID_Broadcast; +}LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_UNION choice; + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_broadcastcompletedarealist( + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_broadcastcompletedarealist( + uint8_t **ptr, + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SONInformation CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_SONINFORMATION_CHOICE_SONINFORMATIONREQUEST, + LIBLTE_S1AP_SONINFORMATION_CHOICE_SONINFORMATIONREPLY, + LIBLTE_S1AP_SONINFORMATION_CHOICE_N_ITEMS, +}LIBLTE_S1AP_SONINFORMATION_CHOICE_ENUM; +static const char liblte_s1ap_soninformation_choice_text[LIBLTE_S1AP_SONINFORMATION_CHOICE_N_ITEMS][50] = { + "sONInformationRequest", + "sONInformationReply", +}; + +typedef union{ + LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM_EXT sONInformationRequest; + LIBLTE_S1AP_SONINFORMATIONREPLY_STRUCT sONInformationReply; +}LIBLTE_S1AP_SONINFORMATION_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_SONINFORMATION_CHOICE_UNION choice; + LIBLTE_S1AP_SONINFORMATION_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_SONINFORMATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_soninformation( + LIBLTE_S1AP_SONINFORMATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformation( + uint8_t **ptr, + LIBLTE_S1AP_SONINFORMATION_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE SONConfigurationTransfer SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TARGETENB_ID_STRUCT targeteNB_ID; + LIBLTE_S1AP_SOURCEENB_ID_STRUCT sourceeNB_ID; + LIBLTE_S1AP_SONINFORMATION_STRUCT sONInformation; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_SONCONFIGURATIONTRANSFER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sonconfigurationtransfer( + LIBLTE_S1AP_SONCONFIGURATIONTRANSFER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sonconfigurationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_SONCONFIGURATIONTRANSFER_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ResetAll ENUMERATED +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_RESETALL_RESET_ALL, + LIBLTE_S1AP_RESETALL_N_ITEMS, +}LIBLTE_S1AP_RESETALL_ENUM; +static const char liblte_s1ap_resetall_text[LIBLTE_S1AP_RESETALL_N_ITEMS][80] = { + "reset-all", +}; + +typedef struct{ + bool ext; + LIBLTE_S1AP_RESETALL_ENUM e; +}LIBLTE_S1AP_RESETALL_ENUM_EXT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_resetall( + LIBLTE_S1AP_RESETALL_ENUM_EXT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_resetall( + uint8_t **ptr, + LIBLTE_S1AP_RESETALL_ENUM_EXT *ie); + +/******************************************************************************* +/* ProtocolIE Inter_SystemInformationTransferType CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_RIMTRANSFER, + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_N_ITEMS, +}LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_ENUM; +static const char liblte_s1ap_inter_systeminformationtransfertype_choice_text[LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_N_ITEMS][50] = { + "rIMTransfer", +}; + +typedef union{ + LIBLTE_S1AP_RIMTRANSFER_STRUCT rIMTransfer; +}LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_UNION choice; + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_inter_systeminformationtransfertype( + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_inter_systeminformationtransfertype( + uint8_t **ptr, + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RAB_IE_ContainerPairList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIR_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RAB_IE_CONTAINERPAIRLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rab_ie_containerpairlist( + LIBLTE_S1AP_E_RAB_IE_CONTAINERPAIRLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rab_ie_containerpairlist( + uint8_t **ptr, + LIBLTE_S1AP_E_RAB_IE_CONTAINERPAIRLIST_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABDataForwardingItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT dL_transportLayerAddress; + bool dL_transportLayerAddress_present; + LIBLTE_S1AP_GTP_TEID_STRUCT dL_gTP_TEID; + bool dL_gTP_TEID_present; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT uL_TransportLayerAddress; + bool uL_TransportLayerAddress_present; + LIBLTE_S1AP_GTP_TEID_STRUCT uL_GTP_TEID; + bool uL_GTP_TEID_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABDATAFORWARDINGITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabdataforwardingitem( + LIBLTE_S1AP_E_RABDATAFORWARDINGITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabdataforwardingitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABDATAFORWARDINGITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABToBeSetupItemHOReq SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; + LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT e_RABlevelQosParameters; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABTOBESETUPITEMHOREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemhoreq( + LIBLTE_S1AP_E_RABTOBESETUPITEMHOREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemhoreq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPITEMHOREQ_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABAdmittedItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT dL_transportLayerAddress; + bool dL_transportLayerAddress_present; + LIBLTE_S1AP_GTP_TEID_STRUCT dL_gTP_TEID; + bool dL_gTP_TEID_present; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT uL_TransportLayerAddress; + bool uL_TransportLayerAddress_present; + LIBLTE_S1AP_GTP_TEID_STRUCT uL_GTP_TEID; + bool uL_GTP_TEID_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABADMITTEDITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabadmitteditem( + LIBLTE_S1AP_E_RABADMITTEDITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabadmitteditem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABADMITTEDITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABFailedToSetupItemHOReqAck SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_CAUSE_STRUCT cause; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabfailedtosetupitemhoreqack( + LIBLTE_S1AP_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabfailedtosetupitemhoreqack( + uint8_t **ptr, + LIBLTE_S1AP_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABToBeSwitchedDLItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABTOBESWITCHEDDLITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitcheddlitem( + LIBLTE_S1AP_E_RABTOBESWITCHEDDLITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitcheddlitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESWITCHEDDLITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABToBeSwitchedULItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABTOBESWITCHEDULITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitchedulitem( + LIBLTE_S1AP_E_RABTOBESWITCHEDULITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitchedulitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESWITCHEDULITEM_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABToBeSetupItemBearerSUReq SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT e_RABlevelQoSParameters; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; + LIBLTE_S1AP_NAS_PDU_STRUCT nAS_PDU; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitembearersureq( + LIBLTE_S1AP_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitembearersureq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABSetupItemBearerSURes SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABSETUPITEMBEARERSURES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitembearersures( + LIBLTE_S1AP_E_RABSETUPITEMBEARERSURES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitembearersures( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSETUPITEMBEARERSURES_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABToBeModifiedItemBearerModReq SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT e_RABLevelQoSParameters; + LIBLTE_S1AP_NAS_PDU_STRUCT nAS_PDU; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobemodifieditembearermodreq( + LIBLTE_S1AP_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifieditembearermodreq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABModifyItemBearerModRes SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABMODIFYITEMBEARERMODRES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyitembearermodres( + LIBLTE_S1AP_E_RABMODIFYITEMBEARERMODRES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyitembearermodres( + uint8_t **ptr, + LIBLTE_S1AP_E_RABMODIFYITEMBEARERMODRES_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABReleaseItemBearerRelComp SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABRELEASEITEMBEARERRELCOMP_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseitembearerrelcomp( + LIBLTE_S1AP_E_RABRELEASEITEMBEARERRELCOMP_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseitembearerrelcomp( + uint8_t **ptr, + LIBLTE_S1AP_E_RABRELEASEITEMBEARERRELCOMP_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABToBeSetupItemCtxtSUReq SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT e_RABlevelQoSParameters; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; + LIBLTE_S1AP_NAS_PDU_STRUCT nAS_PDU; + bool nAS_PDU_present; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemctxtsureq( + LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemctxtsureq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE E_RABSetupItemCtxtSURes SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RAB_ID_STRUCT e_RAB_ID; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT transportLayerAddress; + LIBLTE_S1AP_GTP_TEID_STRUCT gTP_TEID; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitemctxtsures( + LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitemctxtsures( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE TAIItem SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TAI_STRUCT tAI; + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT iE_Extensions; + bool iE_Extensions_present; +}LIBLTE_S1AP_TAIITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taiitem( + LIBLTE_S1AP_TAIITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taiitem( + uint8_t **ptr, + LIBLTE_S1AP_TAIITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List UE_associatedLogicalS1_ConnectionListRes DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionlistres( + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionlistres( + uint8_t **ptr, + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List UE_associatedLogicalS1_ConnectionListResAck DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionlistresack( + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionlistresack( + uint8_t **ptr, + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE PrivateMessage SEQUENCE +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_PRIVATEIE_CONTAINER_STRUCT privateIEs; +}LIBLTE_S1AP_PRIVATEMESSAGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privatemessage( + LIBLTE_S1AP_PRIVATEMESSAGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privatemessage( + uint8_t **ptr, + LIBLTE_S1AP_PRIVATEMESSAGE_STRUCT *ie); + +/******************************************************************************* +/* ProtocolIE ResetType CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_RESETTYPE_CHOICE_S1_INTERFACE, + LIBLTE_S1AP_RESETTYPE_CHOICE_PARTOFS1_INTERFACE, + LIBLTE_S1AP_RESETTYPE_CHOICE_N_ITEMS, +}LIBLTE_S1AP_RESETTYPE_CHOICE_ENUM; +static const char liblte_s1ap_resettype_choice_text[LIBLTE_S1AP_RESETTYPE_CHOICE_N_ITEMS][50] = { + "s1_Interface", + "partOfS1_Interface", +}; + +typedef union{ + LIBLTE_S1AP_RESETALL_ENUM_EXT s1_Interface; + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT partOfS1_Interface; +}LIBLTE_S1AP_RESETTYPE_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_RESETTYPE_CHOICE_UNION choice; + LIBLTE_S1AP_RESETTYPE_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_RESETTYPE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_resettype( + LIBLTE_S1AP_RESETTYPE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_resettype( + uint8_t **ptr, + LIBLTE_S1AP_RESETTYPE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABSubjecttoDataForwardingList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABDATAFORWARDINGITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABSUBJECTTODATAFORWARDINGLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsubjecttodataforwardinglist( + LIBLTE_S1AP_E_RABSUBJECTTODATAFORWARDINGLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsubjecttodataforwardinglist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSUBJECTTODATAFORWARDINGLIST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABToBeSetupListHOReq DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABTOBESETUPITEMHOREQ_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABTOBESETUPLISTHOREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetuplisthoreq( + LIBLTE_S1AP_E_RABTOBESETUPLISTHOREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetuplisthoreq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPLISTHOREQ_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABAdmittedList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABADMITTEDITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABADMITTEDLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabadmittedlist( + LIBLTE_S1AP_E_RABADMITTEDLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabadmittedlist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABADMITTEDLIST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABToBeSwitchedDLList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABTOBESWITCHEDDLITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABTOBESWITCHEDDLLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitcheddllist( + LIBLTE_S1AP_E_RABTOBESWITCHEDDLLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitcheddllist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESWITCHEDDLLIST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABToBeSwitchedULList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABTOBESWITCHEDULITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABTOBESWITCHEDULLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitchedullist( + LIBLTE_S1AP_E_RABTOBESWITCHEDULLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitchedullist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESWITCHEDULLIST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABToBeSetupListBearerSUReq DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetuplistbearersureq( + LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetuplistbearersureq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABSetupListBearerSURes DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABSETUPITEMBEARERSURES_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABSETUPLISTBEARERSURES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetuplistbearersures( + LIBLTE_S1AP_E_RABSETUPLISTBEARERSURES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetuplistbearersures( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSETUPLISTBEARERSURES_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABToBeModifiedListBearerModReq DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABTOBEMODIFIEDLISTBEARERMODREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobemodifiedlistbearermodreq( + LIBLTE_S1AP_E_RABTOBEMODIFIEDLISTBEARERMODREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifiedlistbearermodreq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBEMODIFIEDLISTBEARERMODREQ_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABModifyListBearerModRes DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABMODIFYITEMBEARERMODRES_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABMODIFYLISTBEARERMODRES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifylistbearermodres( + LIBLTE_S1AP_E_RABMODIFYLISTBEARERMODRES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifylistbearermodres( + uint8_t **ptr, + LIBLTE_S1AP_E_RABMODIFYLISTBEARERMODRES_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABReleaseListBearerRelComp DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABRELEASEITEMBEARERRELCOMP_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABRELEASELISTBEARERRELCOMP_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaselistbearerrelcomp( + LIBLTE_S1AP_E_RABRELEASELISTBEARERRELCOMP_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaselistbearerrelcomp( + uint8_t **ptr, + LIBLTE_S1AP_E_RABRELEASELISTBEARERRELCOMP_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABToBeSetupListCtxtSUReq DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABTOBESETUPLISTCTXTSUREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetuplistctxtsureq( + LIBLTE_S1AP_E_RABTOBESETUPLISTCTXTSUREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetuplistctxtsureq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPLISTCTXTSUREQ_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABSetupListCtxtSURes DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABSETUPLISTCTXTSURES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetuplistctxtsures( + LIBLTE_S1AP_E_RABSETUPLISTCTXTSURES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetuplistctxtsures( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSETUPLISTCTXTSURES_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List TAIList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_TAIITEM_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_TAILIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tailist( + LIBLTE_S1AP_TAILIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tailist( + uint8_t **ptr, + LIBLTE_S1AP_TAILIST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Container List E_RABFailedtoSetupListHOReqAck DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +typedef struct{ + uint32_t len; + LIBLTE_S1AP_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT buffer[32]; //WARNING: Artificial limit to reduce memory footprint +}LIBLTE_S1AP_E_RABFAILEDTOSETUPLISTHOREQACK_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabfailedtosetuplisthoreqack( + LIBLTE_S1AP_E_RABFAILEDTOSETUPLISTHOREQACK_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabfailedtosetuplisthoreqack( + uint8_t **ptr, + LIBLTE_S1AP_E_RABFAILEDTOSETUPLISTHOREQACK_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message AllocationAndRetentionPriority_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_ALLOCATIONANDRETENTIONPRIORITY_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_allocationandretentionpriority_ext( + LIBLTE_S1AP_MESSAGE_ALLOCATIONANDRETENTIONPRIORITY_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_allocationandretentionpriority_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ALLOCATIONANDRETENTIONPRIORITY_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CancelledCellinEAI_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINEAI_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellineai_item_ext( + LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINEAI_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellineai_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINEAI_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CancelledCellinTAI_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINTAI_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellintai_item_ext( + LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINTAI_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellintai_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINTAI_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CellID_Broadcast_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CELLID_BROADCAST_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_broadcast_item_ext( + LIBLTE_S1AP_MESSAGE_CELLID_BROADCAST_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_broadcast_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLID_BROADCAST_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CellID_Cancelled_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CELLID_CANCELLED_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_cancelled_item_ext( + LIBLTE_S1AP_MESSAGE_CELLID_CANCELLED_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_cancelled_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLID_CANCELLED_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CellBasedMDT_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CELLBASEDMDT_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellbasedmdt_ext( + LIBLTE_S1AP_MESSAGE_CELLBASEDMDT_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellbasedmdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLBASEDMDT_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message Cdma2000OneXSRVCCInfo_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CDMA2000ONEXSRVCCINFO_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexsrvccinfo_ext( + LIBLTE_S1AP_MESSAGE_CDMA2000ONEXSRVCCINFO_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexsrvccinfo_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CDMA2000ONEXSRVCCINFO_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CellType_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CELLTYPE_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_celltype_ext( + LIBLTE_S1AP_MESSAGE_CELLTYPE_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_celltype_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLTYPE_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CGI_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CGI_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cgi_ext( + LIBLTE_S1AP_MESSAGE_CGI_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cgi_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CGI_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CSG_IdList_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CSG_IDLIST_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csg_idlist_item_ext( + LIBLTE_S1AP_MESSAGE_CSG_IDLIST_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csg_idlist_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CSG_IDLIST_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message COUNTvalue_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_COUNTVALUE_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_countvalue_ext( + LIBLTE_S1AP_MESSAGE_COUNTVALUE_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_countvalue_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_COUNTVALUE_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message COUNTValueExtended_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_COUNTVALUEEXTENDED_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_countvalueextended_ext( + LIBLTE_S1AP_MESSAGE_COUNTVALUEEXTENDED_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_countvalueextended_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_COUNTVALUEEXTENDED_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CriticalityDiagnostics_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics_ext( + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CriticalityDiagnostics_IE_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_IE_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics_ie_item_ext( + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_IE_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ie_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_IE_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message EmergencyAreaID_Broadcast_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_BROADCAST_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_broadcast_item_ext( + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_BROADCAST_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_broadcast_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_BROADCAST_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message EmergencyAreaID_Cancelled_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_CANCELLED_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_cancelled_item_ext( + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_CANCELLED_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_cancelled_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_CANCELLED_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CompletedCellinEAI_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINEAI_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellineai_item_ext( + LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINEAI_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellineai_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINEAI_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message GERAN_Cell_ID_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_GERAN_CELL_ID_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_geran_cell_id_ext( + LIBLTE_S1AP_MESSAGE_GERAN_CELL_ID_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_geran_cell_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_GERAN_CELL_ID_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message GlobalENB_ID_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_GLOBALENB_ID_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_globalenb_id_ext( + LIBLTE_S1AP_MESSAGE_GLOBALENB_ID_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_globalenb_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_GLOBALENB_ID_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ENB_StatusTransfer_TransparentContainer_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_statustransfer_transparentcontainer_ext( + LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_statustransfer_transparentcontainer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABInformationListItem_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLISTITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabinformationlistitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLISTITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlistitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLISTITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABItem_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABQoSParameters_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABQOSPARAMETERS_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabqosparameters_ext( + LIBLTE_S1AP_MESSAGE_E_RABQOSPARAMETERS_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabqosparameters_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABQOSPARAMETERS_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message EUTRAN_CGI_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_EUTRAN_CGI_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eutran_cgi_ext( + LIBLTE_S1AP_MESSAGE_EUTRAN_CGI_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eutran_cgi_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_EUTRAN_CGI_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ForbiddenTAs_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_FORBIDDENTAS_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddentas_item_ext( + LIBLTE_S1AP_MESSAGE_FORBIDDENTAS_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddentas_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_FORBIDDENTAS_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ForbiddenLAs_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_FORBIDDENLAS_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddenlas_item_ext( + LIBLTE_S1AP_MESSAGE_FORBIDDENLAS_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddenlas_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_FORBIDDENLAS_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message GBR_QosInformation_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_GBR_QOSINFORMATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gbr_qosinformation_ext( + LIBLTE_S1AP_MESSAGE_GBR_QOSINFORMATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gbr_qosinformation_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_GBR_QOSINFORMATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message GUMMEI_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_GUMMEI_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gummei_ext( + LIBLTE_S1AP_MESSAGE_GUMMEI_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gummei_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_GUMMEI_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverRestrictionList_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_HANDOVERRESTRICTIONLIST_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrestrictionlist_ext( + LIBLTE_S1AP_MESSAGE_HANDOVERRESTRICTIONLIST_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrestrictionlist_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERRESTRICTIONLIST_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message LAI_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_LAI_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lai_ext( + LIBLTE_S1AP_MESSAGE_LAI_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lai_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LAI_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message LoggedMDT_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_LOGGEDMDT_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_loggedmdt_ext( + LIBLTE_S1AP_MESSAGE_LOGGEDMDT_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_loggedmdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LOGGEDMDT_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message M3Configuration_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_M3CONFIGURATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m3configuration_ext( + LIBLTE_S1AP_MESSAGE_M3CONFIGURATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m3configuration_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M3CONFIGURATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message M4Configuration_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_M4CONFIGURATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m4configuration_ext( + LIBLTE_S1AP_MESSAGE_M4CONFIGURATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m4configuration_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M4CONFIGURATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message M5Configuration_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_M5CONFIGURATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m5configuration_ext( + LIBLTE_S1AP_MESSAGE_M5CONFIGURATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m5configuration_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M5CONFIGURATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message M1PeriodicReporting_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_M1PERIODICREPORTING_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1periodicreporting_ext( + LIBLTE_S1AP_MESSAGE_M1PERIODICREPORTING_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1periodicreporting_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M1PERIODICREPORTING_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message RequestType_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_REQUESTTYPE_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_requesttype_ext( + LIBLTE_S1AP_MESSAGE_REQUESTTYPE_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_requesttype_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_REQUESTTYPE_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message RIMTransfer_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_RIMTRANSFER_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rimtransfer_ext( + LIBLTE_S1AP_MESSAGE_RIMTRANSFER_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rimtransfer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_RIMTRANSFER_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message SecurityContext_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_SECURITYCONTEXT_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_securitycontext_ext( + LIBLTE_S1AP_MESSAGE_SECURITYCONTEXT_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_securitycontext_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SECURITYCONTEXT_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message SourceeNB_ID_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_SOURCEENB_ID_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_id_ext( + LIBLTE_S1AP_MESSAGE_SOURCEENB_ID_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SOURCEENB_ID_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ServedGUMMEIsItem_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_SERVEDGUMMEISITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedgummeisitem_ext( + LIBLTE_S1AP_MESSAGE_SERVEDGUMMEISITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedgummeisitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SERVEDGUMMEISITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message SupportedTAs_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_SUPPORTEDTAS_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_supportedtas_item_ext( + LIBLTE_S1AP_MESSAGE_SUPPORTEDTAS_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_supportedtas_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SUPPORTEDTAS_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TimeSynchronizationInfo_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TIMESYNCHRONIZATIONINFO_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_timesynchronizationinfo_ext( + LIBLTE_S1AP_MESSAGE_TIMESYNCHRONIZATIONINFO_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_timesynchronizationinfo_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TIMESYNCHRONIZATIONINFO_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message S_TMSI_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_S_TMSI_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s_tmsi_ext( + LIBLTE_S1AP_MESSAGE_S_TMSI_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s_tmsi_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_S_TMSI_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TAIBasedMDT_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TAIBASEDMDT_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taibasedmdt_ext( + LIBLTE_S1AP_MESSAGE_TAIBASEDMDT_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taibasedmdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAIBASEDMDT_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TAI_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TAI_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_ext( + LIBLTE_S1AP_MESSAGE_TAI_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAI_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TAI_Broadcast_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TAI_BROADCAST_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_broadcast_item_ext( + LIBLTE_S1AP_MESSAGE_TAI_BROADCAST_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_broadcast_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAI_BROADCAST_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TAI_Cancelled_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TAI_CANCELLED_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_cancelled_item_ext( + LIBLTE_S1AP_MESSAGE_TAI_CANCELLED_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_cancelled_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAI_CANCELLED_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TABasedMDT_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TABASEDMDT_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tabasedmdt_ext( + LIBLTE_S1AP_MESSAGE_TABASEDMDT_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tabasedmdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TABASEDMDT_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CompletedCellinTAI_Item_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINTAI_ITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellintai_item_ext( + LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINTAI_ITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellintai_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINTAI_ITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TargeteNB_ID_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TARGETENB_ID_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_id_ext( + LIBLTE_S1AP_MESSAGE_TARGETENB_ID_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TARGETENB_ID_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TargetRNC_ID_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TARGETRNC_ID_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetrnc_id_ext( + LIBLTE_S1AP_MESSAGE_TARGETRNC_ID_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetrnc_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TARGETRNC_ID_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TargeteNB_ToSourceeNB_TransparentContainer_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_tosourceenb_transparentcontainer_ext( + LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_tosourceenb_transparentcontainer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message M1ThresholdEventA2_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_M1THRESHOLDEVENTA2_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1thresholdeventa2_ext( + LIBLTE_S1AP_MESSAGE_M1THRESHOLDEVENTA2_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1thresholdeventa2_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M1THRESHOLDEVENTA2_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message Tunnel_Information_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TUNNEL_INFORMATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tunnel_information_ext( + LIBLTE_S1AP_MESSAGE_TUNNEL_INFORMATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tunnel_information_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TUNNEL_INFORMATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UEAggregate_MaximumBitrates_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_UEAGGREGATE_MAXIMUMBITRATES_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueaggregate_maximumbitrates_ext( + LIBLTE_S1AP_MESSAGE_UEAGGREGATE_MAXIMUMBITRATES_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueaggregate_maximumbitrates_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UEAGGREGATE_MAXIMUMBITRATES_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UE_S1AP_ID_pair_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_UE_S1AP_ID_PAIR_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_s1ap_id_pair_ext( + LIBLTE_S1AP_MESSAGE_UE_S1AP_ID_PAIR_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_s1ap_id_pair_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UE_S1AP_ID_PAIR_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UE_associatedLogicalS1_ConnectionItemExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitemext( + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitemext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UESecurityCapabilities_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_UESECURITYCAPABILITIES_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uesecuritycapabilities_ext( + LIBLTE_S1AP_MESSAGE_UESECURITYCAPABILITIES_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uesecuritycapabilities_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UESECURITYCAPABILITIES_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UserLocationInformation_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_USERLOCATIONINFORMATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_userlocationinformation_ext( + LIBLTE_S1AP_MESSAGE_USERLOCATIONINFORMATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_userlocationinformation_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_USERLOCATIONINFORMATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ENBX2ExtTLA_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_ENBX2EXTTLA_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2exttla_ext( + LIBLTE_S1AP_MESSAGE_ENBX2EXTTLA_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2exttla_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBX2EXTTLA_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message SourceeNB_ToTargeteNB_TransparentContainer_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MOBILITYINFORMATION_STRUCT MobilityInformation; + bool MobilityInformation_present; +}LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer_ext( + LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_totargetenb_transparentcontainer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABInformationList STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABINFORMATIONLISTITEM_STRUCT E_RABInformationListItem; +}LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLIST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabinformationlist( + LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLIST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlist( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLIST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message LastVisitedEUTRANCellInformation_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT Time_UE_StayedInCell_EnhancedGranularity; + bool Time_UE_StayedInCell_EnhancedGranularity_present; + LIBLTE_S1AP_CAUSE_STRUCT HO_Cause; + bool HO_Cause_present; +}LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedeutrancellinformation_ext( + LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedeutrancellinformation_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message SONInformationReply_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TIMESYNCHRONIZATIONINFO_STRUCT Time_Synchronization_Info; + bool Time_Synchronization_Info_present; +}LIBLTE_S1AP_MESSAGE_SONINFORMATIONREPLY_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_soninformationreply_ext( + LIBLTE_S1AP_MESSAGE_SONINFORMATIONREPLY_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformationreply_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SONINFORMATIONREPLY_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message Bearers_SubjectToStatusTransfer_ItemExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_COUNTVALUEEXTENDED_STRUCT ULCOUNTValueExtended; + bool ULCOUNTValueExtended_present; + LIBLTE_S1AP_COUNTVALUEEXTENDED_STRUCT DLCOUNTValueExtended; + bool DLCOUNTValueExtended_present; + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUSEXTENDED_STRUCT ReceiveStatusOfULPDCPSDUsExtended; + bool ReceiveStatusOfULPDCPSDUsExtended_present; +}LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_itemext( + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransfer_itemext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABItem STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABITEM_STRUCT E_RABItem; +}LIBLTE_S1AP_MESSAGE_E_RABITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabitem( + LIBLTE_S1AP_MESSAGE_E_RABITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message MDT_Configuration_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MDTPLMNLIST_STRUCT SignallingBasedMDTPLMNList; + bool SignallingBasedMDTPLMNList_present; +}LIBLTE_S1AP_MESSAGE_MDT_CONFIGURATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdt_configuration_ext( + LIBLTE_S1AP_MESSAGE_MDT_CONFIGURATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdt_configuration_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MDT_CONFIGURATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message X2TNLConfigurationInfo_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ENBX2EXTTLAS_STRUCT eNBX2ExtendedTransportLayerAddresses; + bool eNBX2ExtendedTransportLayerAddresses_present; +}LIBLTE_S1AP_MESSAGE_X2TNLCONFIGURATIONINFO_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_x2tnlconfigurationinfo_ext( + LIBLTE_S1AP_MESSAGE_X2TNLCONFIGURATIONINFO_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_x2tnlconfigurationinfo_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_X2TNLCONFIGURATIONINFO_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message Bearers_SubjectToStatusTransfer_Item STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT Bearers_SubjectToStatusTransfer_Item; +}LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_item( + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransfer_item( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ImmediateMDT_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_M3CONFIGURATION_STRUCT M3Configuration; + bool M3Configuration_present; + LIBLTE_S1AP_M4CONFIGURATION_STRUCT M4Configuration; + bool M4Configuration_present; + LIBLTE_S1AP_M5CONFIGURATION_STRUCT M5Configuration; + bool M5Configuration_present; + LIBLTE_S1AP_MDT_LOCATION_INFO_STRUCT MDT_Location_Info; + bool MDT_Location_Info_present; +}LIBLTE_S1AP_MESSAGE_IMMEDIATEMDT_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_immediatemdt_ext( + LIBLTE_S1AP_MESSAGE_IMMEDIATEMDT_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_immediatemdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_IMMEDIATEMDT_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message SONConfigurationTransfer_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_X2TNLCONFIGURATIONINFO_STRUCT x2TNLConfigurationInfo; + bool x2TNLConfigurationInfo_present; +}LIBLTE_S1AP_MESSAGE_SONCONFIGURATIONTRANSFER_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sonconfigurationtransfer_ext( + LIBLTE_S1AP_MESSAGE_SONCONFIGURATIONTRANSFER_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sonconfigurationtransfer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SONCONFIGURATIONTRANSFER_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TraceActivation_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MDT_CONFIGURATION_STRUCT MDTConfiguration; + bool MDTConfiguration_present; +}LIBLTE_S1AP_MESSAGE_TRACEACTIVATION_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_traceactivation_ext( + LIBLTE_S1AP_MESSAGE_TRACEACTIVATION_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_traceactivation_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TRACEACTIVATION_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverRequired STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_HANDOVERTYPE_ENUM_EXT HandoverType; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_TARGETID_STRUCT TargetID; + LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM_EXT Direct_Forwarding_Path_Availability; + bool Direct_Forwarding_Path_Availability_present; + LIBLTE_S1AP_SRVCCHOINDICATION_ENUM_EXT SRVCCHOIndication; + bool SRVCCHOIndication_present; + LIBLTE_S1AP_SOURCE_TOTARGET_TRANSPARENTCONTAINER_STRUCT Source_ToTarget_TransparentContainer; + LIBLTE_S1AP_SOURCE_TOTARGET_TRANSPARENTCONTAINER_STRUCT Source_ToTarget_TransparentContainer_Secondary; + bool Source_ToTarget_TransparentContainer_Secondary_present; + LIBLTE_S1AP_MSCLASSMARK2_STRUCT MSClassmark2; + bool MSClassmark2_present; + LIBLTE_S1AP_MSCLASSMARK3_STRUCT MSClassmark3; + bool MSClassmark3_present; + LIBLTE_S1AP_CSG_ID_STRUCT CSG_Id; + bool CSG_Id_present; + LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT CellAccessMode; + bool CellAccessMode_present; + LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM_EXT PS_ServiceNotAvailable; + bool PS_ServiceNotAvailable_present; +}LIBLTE_S1AP_MESSAGE_HANDOVERREQUIRED_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrequired( + LIBLTE_S1AP_MESSAGE_HANDOVERREQUIRED_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrequired( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERREQUIRED_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABDataForwardingItem_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabdataforwardingitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabdataforwardingitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverPreparationFailure STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_HANDOVERPREPARATIONFAILURE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverpreparationfailure( + LIBLTE_S1AP_MESSAGE_HANDOVERPREPARATIONFAILURE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverpreparationfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERPREPARATIONFAILURE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemHOReq_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM_EXT Data_Forwarding_Not_Possible; + bool Data_Forwarding_Not_Possible_present; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemhoreq_ext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemhoreq_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABAdmittedItem_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabadmitteditem_ext( + LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabadmitteditem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABFailedToSetupItemHOReqAckExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACKEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabfailedtosetupitemhoreqackext( + LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACKEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabfailedtosetupitemhoreqackext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACKEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverFailure STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_HANDOVERFAILURE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverfailure( + LIBLTE_S1AP_MESSAGE_HANDOVERFAILURE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERFAILURE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverNotify STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT EUTRAN_CGI; + LIBLTE_S1AP_TAI_STRUCT TAI; + LIBLTE_S1AP_TUNNELINFORMATION_STRUCT Tunnel_Information_for_BBF; + bool Tunnel_Information_for_BBF_present; + LIBLTE_S1AP_LHN_ID_STRUCT LHN_ID; + bool LHN_ID_present; +}LIBLTE_S1AP_MESSAGE_HANDOVERNOTIFY_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovernotify( + LIBLTE_S1AP_MESSAGE_HANDOVERNOTIFY_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovernotify( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERNOTIFY_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSwitchedDLItem_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitcheddlitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitcheddlitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSwitchedULItem_Ext STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_EXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitchedulitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_EXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitchedulitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_EXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message PathSwitchRequestFailure STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTFAILURE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pathswitchrequestfailure( + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTFAILURE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pathswitchrequestfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTFAILURE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverCancel STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; +}LIBLTE_S1AP_MESSAGE_HANDOVERCANCEL_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovercancel( + LIBLTE_S1AP_MESSAGE_HANDOVERCANCEL_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovercancel( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERCANCEL_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverCancelAcknowledge STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_HANDOVERCANCELACKNOWLEDGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovercancelacknowledge( + LIBLTE_S1AP_MESSAGE_HANDOVERCANCELACKNOWLEDGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovercancelacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERCANCELACKNOWLEDGE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemBearerSUReqExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CORRELATION_ID_STRUCT Correlation_ID; + bool Correlation_ID_present; + LIBLTE_S1AP_CORRELATION_ID_STRUCT SIPTO_Correlation_ID; + bool SIPTO_Correlation_ID_present; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitembearersureqext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitembearersureqext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABSetupItemBearerSUResExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURESEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitembearersuresext( + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURESEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitembearersuresext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURESEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeModifyItemBearerModReqExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TRANSPORTINFORMATION_STRUCT TransportInformation; + bool TransportInformation_present; +}LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFYITEMBEARERMODREQEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobemodifyitembearermodreqext( + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFYITEMBEARERMODREQEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifyitembearermodreqext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFYITEMBEARERMODREQEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABModifyItemBearerModResExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRESEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyitembearermodresext( + LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRESEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyitembearermodresext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRESEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABReleaseCommand STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT uEaggregateMaximumBitrate; + bool uEaggregateMaximumBitrate_present; + LIBLTE_S1AP_E_RABLIST_STRUCT E_RABToBeReleasedList; + LIBLTE_S1AP_NAS_PDU_STRUCT NAS_PDU; + bool NAS_PDU_present; +}LIBLTE_S1AP_MESSAGE_E_RABRELEASECOMMAND_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleasecommand( + LIBLTE_S1AP_MESSAGE_E_RABRELEASECOMMAND_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleasecommand( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASECOMMAND_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABReleaseItemBearerRelCompExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMPEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseitembearerrelcompext( + LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMPEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseitembearerrelcompext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMPEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABReleaseIndication STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_RABLIST_STRUCT E_RABReleasedList; + LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT UserLocationInformation; + bool UserLocationInformation_present; +}LIBLTE_S1AP_MESSAGE_E_RABRELEASEINDICATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseindication( + LIBLTE_S1AP_MESSAGE_E_RABRELEASEINDICATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASEINDICATION_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemCtxtSUReqExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CORRELATION_ID_STRUCT Correlation_ID; + bool Correlation_ID_present; + LIBLTE_S1AP_CORRELATION_ID_STRUCT SIPTO_Correlation_ID; + bool SIPTO_Correlation_ID_present; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemctxtsureqext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemctxtsureqext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABSetupItemCtxtSUResExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURESEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitemctxtsuresext( + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURESEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitemctxtsuresext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURESEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message InitialContextSetupFailure STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPFAILURE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initialcontextsetupfailure( + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPFAILURE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initialcontextsetupfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPFAILURE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TAIItemExt STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_TAIITEMEXT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taiitemext( + LIBLTE_S1AP_MESSAGE_TAIITEMEXT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taiitemext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAIITEMEXT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UEContextReleaseRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM_EXT GWContextReleaseIndication; + bool GWContextReleaseIndication_present; +}LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextreleaserequest( + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextreleaserequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UEContextReleaseCommand STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_UE_S1AP_IDS_STRUCT UE_S1AP_IDs; + LIBLTE_S1AP_CAUSE_STRUCT Cause; +}LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextreleasecommand( + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextreleasecommand( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UEContextReleaseComplete STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; + LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT UserLocationInformation; + bool UserLocationInformation_present; +}LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextreleasecomplete( + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextreleasecomplete( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UEContextModificationRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_SECURITYKEY_STRUCT SecurityKey; + bool SecurityKey_present; + LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT SubscriberProfileIDforRFP; + bool SubscriberProfileIDforRFP_present; + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT uEaggregateMaximumBitrate; + bool uEaggregateMaximumBitrate_present; + LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM_EXT CSFallbackIndicator; + bool CSFallbackIndicator_present; + LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT UESecurityCapabilities; + bool UESecurityCapabilities_present; + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM CSGMembershipStatus; + bool CSGMembershipStatus_present; + LIBLTE_S1AP_LAI_STRUCT RegisteredLAI; + bool RegisteredLAI_present; + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM_EXT AdditionalCSFallbackIndicator; + bool AdditionalCSFallbackIndicator_present; +}LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextmodificationrequest( + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextmodificationrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UEContextModificationResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextmodificationresponse( + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextmodificationresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UEContextModificationFailure STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONFAILURE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextmodificationfailure( + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONFAILURE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextmodificationfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONFAILURE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UERadioCapabilityMatchRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_UERADIOCAPABILITY_STRUCT UERadioCapability; + bool UERadioCapability_present; +}LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueradiocapabilitymatchrequest( + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueradiocapabilitymatchrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UERadioCapabilityMatchResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM_EXT VoiceSupportMatchIndicator; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueradiocapabilitymatchresponse( + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueradiocapabilitymatchresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message DownlinkNASTransport STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_NAS_PDU_STRUCT NAS_PDU; + LIBLTE_S1AP_HANDOVERRESTRICTIONLIST_STRUCT HandoverRestrictionList; + bool HandoverRestrictionList_present; + LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT SubscriberProfileIDforRFP; + bool SubscriberProfileIDforRFP_present; +}LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinknastransport( + LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinknastransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message InitialUEMessage STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_NAS_PDU_STRUCT NAS_PDU; + LIBLTE_S1AP_TAI_STRUCT TAI; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT EUTRAN_CGI; + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM_EXT RRC_Establishment_Cause; + LIBLTE_S1AP_S_TMSI_STRUCT S_TMSI; + bool S_TMSI_present; + LIBLTE_S1AP_CSG_ID_STRUCT CSG_Id; + bool CSG_Id_present; + LIBLTE_S1AP_GUMMEI_STRUCT GUMMEI_ID; + bool GUMMEI_ID_present; + LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT CellAccessMode; + bool CellAccessMode_present; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT GW_TransportLayerAddress; + bool GW_TransportLayerAddress_present; + LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM_EXT RelayNode_Indicator; + bool RelayNode_Indicator_present; + LIBLTE_S1AP_GUMMEITYPE_ENUM_EXT GUMMEIType; + bool GUMMEIType_present; + LIBLTE_S1AP_TUNNELINFORMATION_STRUCT Tunnel_Information_for_BBF; + bool Tunnel_Information_for_BBF_present; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT SIPTO_L_GW_TransportLayerAddress; + bool SIPTO_L_GW_TransportLayerAddress_present; + LIBLTE_S1AP_LHN_ID_STRUCT LHN_ID; + bool LHN_ID_present; +}LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initialuemessage( + LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initialuemessage( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UplinkNASTransport STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_NAS_PDU_STRUCT NAS_PDU; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT EUTRAN_CGI; + LIBLTE_S1AP_TAI_STRUCT TAI; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT GW_TransportLayerAddress; + bool GW_TransportLayerAddress_present; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT SIPTO_L_GW_TransportLayerAddress; + bool SIPTO_L_GW_TransportLayerAddress_present; + LIBLTE_S1AP_LHN_ID_STRUCT LHN_ID; + bool LHN_ID_present; +}LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uplinknastransport( + LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinknastransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message NASNonDeliveryIndication STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_NAS_PDU_STRUCT NAS_PDU; + LIBLTE_S1AP_CAUSE_STRUCT Cause; +}LIBLTE_S1AP_MESSAGE_NASNONDELIVERYINDICATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nasnondeliveryindication( + LIBLTE_S1AP_MESSAGE_NASNONDELIVERYINDICATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nasnondeliveryindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_NASNONDELIVERYINDICATION_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UE_associatedLogicalS1_ConnectionItem STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT UE_associatedLogicalS1_ConnectionItem; +}LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitem( + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UE_associatedLogicalS1_ConnectionItemRes STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT UE_associatedLogicalS1_ConnectionItem; +}LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitemres( + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitemres( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ErrorIndication STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + bool MME_UE_S1AP_ID_present; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + bool eNB_UE_S1AP_ID_present; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + bool Cause_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_ERRORINDICATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_errorindication( + LIBLTE_S1AP_MESSAGE_ERRORINDICATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_errorindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ERRORINDICATION_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message S1SetupRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT Global_ENB_ID; + LIBLTE_S1AP_ENBNAME_STRUCT eNBname; + bool eNBname_present; + LIBLTE_S1AP_SUPPORTEDTAS_STRUCT SupportedTAs; + LIBLTE_S1AP_PAGINGDRX_ENUM_EXT DefaultPagingDRX; + LIBLTE_S1AP_CSG_IDLIST_STRUCT CSG_IdList; + bool CSG_IdList_present; +}LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s1setuprequest( + LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s1setuprequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message S1SetupResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MMENAME_STRUCT MMEname; + bool MMEname_present; + LIBLTE_S1AP_SERVEDGUMMEIS_STRUCT ServedGUMMEIs; + LIBLTE_S1AP_RELATIVEMMECAPACITY_STRUCT RelativeMMECapacity; + LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM_EXT MMERelaySupportIndicator; + bool MMERelaySupportIndicator_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_S1SETUPRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s1setupresponse( + LIBLTE_S1AP_MESSAGE_S1SETUPRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s1setupresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_S1SETUPRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message S1SetupFailure STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_TIMETOWAIT_ENUM_EXT TimeToWait; + bool TimeToWait_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s1setupfailure( + LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s1setupfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ENBConfigurationUpdate STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ENBNAME_STRUCT eNBname; + bool eNBname_present; + LIBLTE_S1AP_SUPPORTEDTAS_STRUCT SupportedTAs; + bool SupportedTAs_present; + LIBLTE_S1AP_CSG_IDLIST_STRUCT CSG_IdList; + bool CSG_IdList_present; + LIBLTE_S1AP_PAGINGDRX_ENUM_EXT DefaultPagingDRX; + bool DefaultPagingDRX_present; +}LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbconfigurationupdate( + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbconfigurationupdate( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ENBConfigurationUpdateAcknowledge STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEACKNOWLEDGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbconfigurationupdateacknowledge( + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEACKNOWLEDGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbconfigurationupdateacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEACKNOWLEDGE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ENBConfigurationUpdateFailure STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_TIMETOWAIT_ENUM_EXT TimeToWait; + bool TimeToWait_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEFAILURE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbconfigurationupdatefailure( + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEFAILURE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbconfigurationupdatefailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEFAILURE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message MMEConfigurationUpdate STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MMENAME_STRUCT MMEname; + bool MMEname_present; + LIBLTE_S1AP_SERVEDGUMMEIS_STRUCT ServedGUMMEIs; + bool ServedGUMMEIs_present; + LIBLTE_S1AP_RELATIVEMMECAPACITY_STRUCT RelativeMMECapacity; + bool RelativeMMECapacity_present; +}LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmeconfigurationupdate( + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmeconfigurationupdate( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message MMEConfigurationUpdateAcknowledge STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEACKNOWLEDGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmeconfigurationupdateacknowledge( + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEACKNOWLEDGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmeconfigurationupdateacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEACKNOWLEDGE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message MMEConfigurationUpdateFailure STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_TIMETOWAIT_ENUM_EXT TimeToWait; + bool TimeToWait_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEFAILURE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmeconfigurationupdatefailure( + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEFAILURE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmeconfigurationupdatefailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEFAILURE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UplinkS1cdma2000tunneling STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CDMA2000RATTYPE_ENUM_EXT cdma2000RATType; + LIBLTE_S1AP_CDMA2000SECTORID_STRUCT cdma2000SectorID; + LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM_EXT cdma2000HORequiredIndication; + bool cdma2000HORequiredIndication_present; + LIBLTE_S1AP_CDMA2000ONEXSRVCCINFO_STRUCT cdma2000OneXSRVCCInfo; + bool cdma2000OneXSRVCCInfo_present; + LIBLTE_S1AP_CDMA2000ONEXRAND_STRUCT cdma2000OneXRAND; + bool cdma2000OneXRAND_present; + LIBLTE_S1AP_CDMA2000PDU_STRUCT cdma2000PDU; + LIBLTE_S1AP_EUTRANROUNDTRIPDELAYESTIMATIONINFO_STRUCT EUTRANRoundTripDelayEstimationInfo; + bool EUTRANRoundTripDelayEstimationInfo_present; +}LIBLTE_S1AP_MESSAGE_UPLINKS1CDMA2000TUNNELING_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uplinks1cdma2000tunneling( + LIBLTE_S1AP_MESSAGE_UPLINKS1CDMA2000TUNNELING_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinks1cdma2000tunneling( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UPLINKS1CDMA2000TUNNELING_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UECapabilityInfoIndication STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_UERADIOCAPABILITY_STRUCT UERadioCapability; +}LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecapabilityinfoindication( + LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecapabilityinfoindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ENBStatusTransfer STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT eNB_StatusTransfer_TransparentContainer; +}LIBLTE_S1AP_MESSAGE_ENBSTATUSTRANSFER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbstatustransfer( + LIBLTE_S1AP_MESSAGE_ENBSTATUSTRANSFER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbstatustransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBSTATUSTRANSFER_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message MMEStatusTransfer STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT eNB_StatusTransfer_TransparentContainer; +}LIBLTE_S1AP_MESSAGE_MMESTATUSTRANSFER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmestatustransfer( + LIBLTE_S1AP_MESSAGE_MMESTATUSTRANSFER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmestatustransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMESTATUSTRANSFER_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TraceStart STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_TRACEACTIVATION_STRUCT TraceActivation; +}LIBLTE_S1AP_MESSAGE_TRACESTART_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tracestart( + LIBLTE_S1AP_MESSAGE_TRACESTART_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tracestart( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TRACESTART_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TraceFailureIndication STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT E_UTRAN_Trace_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; +}LIBLTE_S1AP_MESSAGE_TRACEFAILUREINDICATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tracefailureindication( + LIBLTE_S1AP_MESSAGE_TRACEFAILUREINDICATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tracefailureindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TRACEFAILUREINDICATION_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message DeactivateTrace STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT E_UTRAN_Trace_ID; +}LIBLTE_S1AP_MESSAGE_DEACTIVATETRACE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_deactivatetrace( + LIBLTE_S1AP_MESSAGE_DEACTIVATETRACE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_deactivatetrace( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DEACTIVATETRACE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message CellTrafficTrace STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT E_UTRAN_Trace_ID; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT EUTRAN_CGI; + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT TraceCollectionEntityIPAddress; + LIBLTE_S1AP_PRIVACYINDICATOR_ENUM_EXT PrivacyIndicator; + bool PrivacyIndicator_present; +}LIBLTE_S1AP_MESSAGE_CELLTRAFFICTRACE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_celltraffictrace( + LIBLTE_S1AP_MESSAGE_CELLTRAFFICTRACE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_celltraffictrace( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLTRAFFICTRACE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message LocationReportingControl STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_REQUESTTYPE_STRUCT RequestType; +}LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGCONTROL_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_locationreportingcontrol( + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGCONTROL_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_locationreportingcontrol( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGCONTROL_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message LocationReportingFailureIndication STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_CAUSE_STRUCT Cause; +}LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGFAILUREINDICATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_locationreportingfailureindication( + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGFAILUREINDICATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_locationreportingfailureindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGFAILUREINDICATION_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message LocationReport STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT EUTRAN_CGI; + LIBLTE_S1AP_TAI_STRUCT TAI; + LIBLTE_S1AP_REQUESTTYPE_STRUCT RequestType; +}LIBLTE_S1AP_MESSAGE_LOCATIONREPORT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_locationreport( + LIBLTE_S1AP_MESSAGE_LOCATIONREPORT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_locationreport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LOCATIONREPORT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message OverloadStart STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_OVERLOADRESPONSE_STRUCT OverloadResponse; + LIBLTE_S1AP_GUMMEILIST_STRUCT GUMMEIList; + bool GUMMEIList_present; + LIBLTE_S1AP_TRAFFICLOADREDUCTIONINDICATION_STRUCT TrafficLoadReductionIndication; + bool TrafficLoadReductionIndication_present; +}LIBLTE_S1AP_MESSAGE_OVERLOADSTART_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_overloadstart( + LIBLTE_S1AP_MESSAGE_OVERLOADSTART_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_overloadstart( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_OVERLOADSTART_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message OverloadStop STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_GUMMEILIST_STRUCT GUMMEIList; + bool GUMMEIList_present; +}LIBLTE_S1AP_MESSAGE_OVERLOADSTOP_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_overloadstop( + LIBLTE_S1AP_MESSAGE_OVERLOADSTOP_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_overloadstop( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_OVERLOADSTOP_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message WriteReplaceWarningRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT MessageIdentifier; + LIBLTE_S1AP_SERIALNUMBER_STRUCT SerialNumber; + LIBLTE_S1AP_WARNINGAREALIST_STRUCT WarningAreaList; + bool WarningAreaList_present; + LIBLTE_S1AP_REPETITIONPERIOD_STRUCT RepetitionPeriod; + LIBLTE_S1AP_EXTENDEDREPETITIONPERIOD_STRUCT ExtendedRepetitionPeriod; + bool ExtendedRepetitionPeriod_present; + LIBLTE_S1AP_NUMBEROFBROADCASTREQUEST_STRUCT NumberofBroadcastRequest; + LIBLTE_S1AP_WARNINGTYPE_STRUCT WarningType; + bool WarningType_present; + LIBLTE_S1AP_WARNINGSECURITYINFO_STRUCT WarningSecurityInfo; + bool WarningSecurityInfo_present; + LIBLTE_S1AP_DATACODINGSCHEME_STRUCT DataCodingScheme; + bool DataCodingScheme_present; + LIBLTE_S1AP_WARNINGMESSAGECONTENTS_STRUCT WarningMessageContents; + bool WarningMessageContents_present; + LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_ENUM ConcurrentWarningMessageIndicator; + bool ConcurrentWarningMessageIndicator_present; +}LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_writereplacewarningrequest( + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_writereplacewarningrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message WriteReplaceWarningResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT MessageIdentifier; + LIBLTE_S1AP_SERIALNUMBER_STRUCT SerialNumber; + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_STRUCT BroadcastCompletedAreaList; + bool BroadcastCompletedAreaList_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_writereplacewarningresponse( + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_writereplacewarningresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message MMEDirectInformationTransfer STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_STRUCT Inter_SystemInformationTransferTypeMDT; +}LIBLTE_S1AP_MESSAGE_MMEDIRECTINFORMATIONTRANSFER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmedirectinformationtransfer( + LIBLTE_S1AP_MESSAGE_MMEDIRECTINFORMATIONTRANSFER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmedirectinformationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMEDIRECTINFORMATIONTRANSFER_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ENBConfigurationTransfer STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_SONCONFIGURATIONTRANSFER_STRUCT SONConfigurationTransferECT; + bool SONConfigurationTransferECT_present; +}LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONTRANSFER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbconfigurationtransfer( + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONTRANSFER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbconfigurationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONTRANSFER_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message MMEConfigurationTransfer STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_SONCONFIGURATIONTRANSFER_STRUCT SONConfigurationTransferMCT; + bool SONConfigurationTransferMCT_present; +}LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONTRANSFER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmeconfigurationtransfer( + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONTRANSFER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmeconfigurationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONTRANSFER_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message PrivateMessage STRUCT +********************************************************************************/ +typedef struct{ + bool ext; +}LIBLTE_S1AP_MESSAGE_PRIVATEMESSAGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privatemessage( + LIBLTE_S1AP_MESSAGE_PRIVATEMESSAGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privatemessage( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PRIVATEMESSAGE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message KillRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT MessageIdentifier; + LIBLTE_S1AP_SERIALNUMBER_STRUCT SerialNumber; + LIBLTE_S1AP_WARNINGAREALIST_STRUCT WarningAreaList; + bool WarningAreaList_present; + LIBLTE_S1AP_KILLALLWARNINGMESSAGES_ENUM KillAllWarningMessages; + bool KillAllWarningMessages_present; +}LIBLTE_S1AP_MESSAGE_KILLREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_killrequest( + LIBLTE_S1AP_MESSAGE_KILLREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_killrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_KILLREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message KillResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT MessageIdentifier; + LIBLTE_S1AP_SERIALNUMBER_STRUCT SerialNumber; + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_STRUCT BroadcastCancelledAreaList; + bool BroadcastCancelledAreaList_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_KILLRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_killresponse( + LIBLTE_S1AP_MESSAGE_KILLRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_killresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_KILLRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message PWSRestartIndication STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ECGILISTFORRESTART_STRUCT ECGIListForRestart; + LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT Global_ENB_ID; + LIBLTE_S1AP_TAILISTFORRESTART_STRUCT TAIListForRestart; + LIBLTE_S1AP_EMERGENCYAREAIDLISTFORRESTART_STRUCT EmergencyAreaIDListForRestart; + bool EmergencyAreaIDListForRestart_present; +}LIBLTE_S1AP_MESSAGE_PWSRESTARTINDICATION_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pwsrestartindication( + LIBLTE_S1AP_MESSAGE_PWSRESTARTINDICATION_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pwsrestartindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PWSRESTARTINDICATION_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message DownlinkUEAssociatedLPPaTransport STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_ROUTING_ID_STRUCT Routing_ID; + LIBLTE_S1AP_LPPA_PDU_STRUCT LPPa_PDU; +}LIBLTE_S1AP_MESSAGE_DOWNLINKUEASSOCIATEDLPPATRANSPORT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinkueassociatedlppatransport( + LIBLTE_S1AP_MESSAGE_DOWNLINKUEASSOCIATEDLPPATRANSPORT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinkueassociatedlppatransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKUEASSOCIATEDLPPATRANSPORT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UplinkUEAssociatedLPPaTransport STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_ROUTING_ID_STRUCT Routing_ID; + LIBLTE_S1AP_LPPA_PDU_STRUCT LPPa_PDU; +}LIBLTE_S1AP_MESSAGE_UPLINKUEASSOCIATEDLPPATRANSPORT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uplinkueassociatedlppatransport( + LIBLTE_S1AP_MESSAGE_UPLINKUEASSOCIATEDLPPATRANSPORT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinkueassociatedlppatransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UPLINKUEASSOCIATEDLPPATRANSPORT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message DownlinkNonUEAssociatedLPPaTransport STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ROUTING_ID_STRUCT Routing_ID; + LIBLTE_S1AP_LPPA_PDU_STRUCT LPPa_PDU; +}LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinknonueassociatedlppatransport( + LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinknonueassociatedlppatransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message UplinkNonUEAssociatedLPPaTransport STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ROUTING_ID_STRUCT Routing_ID; + LIBLTE_S1AP_LPPA_PDU_STRUCT LPPa_PDU; +}LIBLTE_S1AP_MESSAGE_UPLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uplinknonueassociatedlppatransport( + LIBLTE_S1AP_MESSAGE_UPLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinknonueassociatedlppatransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UPLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ENBDirectInformationTransfer STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_STRUCT Inter_SystemInformationTransferTypeEDT; +}LIBLTE_S1AP_MESSAGE_ENBDIRECTINFORMATIONTRANSFER_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbdirectinformationtransfer( + LIBLTE_S1AP_MESSAGE_ENBDIRECTINFORMATIONTRANSFER_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbdirectinformationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBDIRECTINFORMATIONTRANSFER_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABDataForwardingItem STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABDATAFORWARDINGITEM_STRUCT E_RABDataForwardingItem; +}LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabdataforwardingitem( + LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabdataforwardingitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemHOReq STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABTOBESETUPITEMHOREQ_STRUCT E_RABToBeSetupItemHOReq; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemhoreq( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemhoreq( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABAdmittedItem STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABADMITTEDITEM_STRUCT E_RABAdmittedItem; +}LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabadmitteditem( + LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabadmitteditem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABFailedtoSetupItemHOReqAck STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT E_RABFailedtoSetupItemHOReqAck; +}LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabfailedtosetupitemhoreqack( + LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabfailedtosetupitemhoreqack( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSwitchedDLItem STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABTOBESWITCHEDDLITEM_STRUCT E_RABToBeSwitchedDLItem; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitcheddlitem( + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitcheddlitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSwitchedULItem STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABTOBESWITCHEDULITEM_STRUCT E_RABToBeSwitchedULItem; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitchedulitem( + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitchedulitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemBearerSUReq STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT E_RABToBeSetupItemBearerSUReq; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitembearersureq( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitembearersureq( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABSetupItemBearerSURes STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABSETUPITEMBEARERSURES_STRUCT E_RABSetupItemBearerSURes; +}LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitembearersures( + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitembearersures( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURES_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeModifiedItemBearerModReq STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT E_RABToBeModifiedItemBearerModReq; +}LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobemodifieditembearermodreq( + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifieditembearermodreq( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABModifyItemBearerModRes STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABMODIFYITEMBEARERMODRES_STRUCT E_RABModifyItemBearerModRes; +}LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyitembearermodres( + LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyitembearermodres( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRES_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABReleaseItemBearerRelComp STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABRELEASEITEMBEARERRELCOMP_STRUCT E_RABReleaseItemBearerRelComp; +}LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMP_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseitembearerrelcomp( + LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMP_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseitembearerrelcomp( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMP_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemCtxtSUReq STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT E_RABToBeSetupItemCtxtSUReq; +}LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemctxtsureq( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemctxtsureq( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABSetupItemCtxtSURes STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT E_RABSetupItemCtxtSURes; +}LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURES_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitemctxtsures( + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURES_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitemctxtsures( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURES_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message TAIItem STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_TAIITEM_STRUCT TAIItem; +}LIBLTE_S1AP_MESSAGE_TAIITEM_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taiitem( + LIBLTE_S1AP_MESSAGE_TAIITEM_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taiitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAIITEM_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message ResetAcknowledge STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT UE_associatedLogicalS1_ConnectionListResAck; + bool UE_associatedLogicalS1_ConnectionListResAck_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_RESETACKNOWLEDGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_resetacknowledge( + LIBLTE_S1AP_MESSAGE_RESETACKNOWLEDGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_resetacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_RESETACKNOWLEDGE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message Reset STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_RESETTYPE_STRUCT ResetType; +}LIBLTE_S1AP_MESSAGE_RESET_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_reset( + LIBLTE_S1AP_MESSAGE_RESET_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_reset( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_RESET_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message DownlinkS1cdma2000tunneling STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_RABSUBJECTTODATAFORWARDINGLIST_STRUCT E_RABSubjecttoDataForwardingList; + bool E_RABSubjecttoDataForwardingList_present; + LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM_EXT cdma2000HOStatus; + bool cdma2000HOStatus_present; + LIBLTE_S1AP_CDMA2000RATTYPE_ENUM_EXT cdma2000RATType; + LIBLTE_S1AP_CDMA2000PDU_STRUCT cdma2000PDU; +}LIBLTE_S1AP_MESSAGE_DOWNLINKS1CDMA2000TUNNELING_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinks1cdma2000tunneling( + LIBLTE_S1AP_MESSAGE_DOWNLINKS1CDMA2000TUNNELING_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinks1cdma2000tunneling( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKS1CDMA2000TUNNELING_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverCommand STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_HANDOVERTYPE_ENUM_EXT HandoverType; + LIBLTE_S1AP_NASSECURITYPARAMETERSFROME_UTRAN_STRUCT NASSecurityParametersfromE_UTRAN; + bool NASSecurityParametersfromE_UTRAN_present; + LIBLTE_S1AP_E_RABSUBJECTTODATAFORWARDINGLIST_STRUCT E_RABSubjecttoDataForwardingList; + bool E_RABSubjecttoDataForwardingList_present; + LIBLTE_S1AP_E_RABLIST_STRUCT E_RABtoReleaseListHOCmd; + bool E_RABtoReleaseListHOCmd_present; + LIBLTE_S1AP_TARGET_TOSOURCE_TRANSPARENTCONTAINER_STRUCT Target_ToSource_TransparentContainer; + LIBLTE_S1AP_TARGET_TOSOURCE_TRANSPARENTCONTAINER_STRUCT Target_ToSource_TransparentContainer_Secondary; + bool Target_ToSource_TransparentContainer_Secondary_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_HANDOVERCOMMAND_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovercommand( + LIBLTE_S1AP_MESSAGE_HANDOVERCOMMAND_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovercommand( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERCOMMAND_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_HANDOVERTYPE_ENUM_EXT HandoverType; + LIBLTE_S1AP_CAUSE_STRUCT Cause; + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT uEaggregateMaximumBitrate; + LIBLTE_S1AP_E_RABTOBESETUPLISTHOREQ_STRUCT E_RABToBeSetupListHOReq; + LIBLTE_S1AP_SOURCE_TOTARGET_TRANSPARENTCONTAINER_STRUCT Source_ToTarget_TransparentContainer; + LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT UESecurityCapabilities; + LIBLTE_S1AP_HANDOVERRESTRICTIONLIST_STRUCT HandoverRestrictionList; + bool HandoverRestrictionList_present; + LIBLTE_S1AP_TRACEACTIVATION_STRUCT TraceActivation; + bool TraceActivation_present; + LIBLTE_S1AP_REQUESTTYPE_STRUCT RequestType; + bool RequestType_present; + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM_EXT SRVCCOperationPossible; + bool SRVCCOperationPossible_present; + LIBLTE_S1AP_SECURITYCONTEXT_STRUCT SecurityContext; + LIBLTE_S1AP_NASSECURITYPARAMETERSTOE_UTRAN_STRUCT NASSecurityParameterstoE_UTRAN; + bool NASSecurityParameterstoE_UTRAN_present; + LIBLTE_S1AP_CSG_ID_STRUCT CSG_Id; + bool CSG_Id_present; + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM CSGMembershipStatus; + bool CSGMembershipStatus_present; + LIBLTE_S1AP_GUMMEI_STRUCT GUMMEI_ID; + bool GUMMEI_ID_present; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID_2; + bool MME_UE_S1AP_ID_2_present; + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM_EXT ManagementBasedMDTAllowed; + bool ManagementBasedMDTAllowed_present; + LIBLTE_S1AP_MDTPLMNLIST_STRUCT ManagementBasedMDTPLMNList; + bool ManagementBasedMDTPLMNList_present; +}LIBLTE_S1AP_MESSAGE_HANDOVERREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrequest( + LIBLTE_S1AP_MESSAGE_HANDOVERREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message PathSwitchRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_RABTOBESWITCHEDDLLIST_STRUCT E_RABToBeSwitchedDLList; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT SourceMME_UE_S1AP_ID; + LIBLTE_S1AP_EUTRAN_CGI_STRUCT EUTRAN_CGI; + LIBLTE_S1AP_TAI_STRUCT TAI; + LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT UESecurityCapabilities; + LIBLTE_S1AP_CSG_ID_STRUCT CSG_Id; + bool CSG_Id_present; + LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT CellAccessMode; + bool CellAccessMode_present; + LIBLTE_S1AP_GUMMEI_STRUCT SourceMME_GUMMEI; + bool SourceMME_GUMMEI_present; + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM CSGMembershipStatus; + bool CSGMembershipStatus_present; + LIBLTE_S1AP_TUNNELINFORMATION_STRUCT Tunnel_Information_for_BBF; + bool Tunnel_Information_for_BBF_present; + LIBLTE_S1AP_LHN_ID_STRUCT LHN_ID; + bool LHN_ID_present; +}LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pathswitchrequest( + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pathswitchrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message PathSwitchRequestAcknowledge STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT uEaggregateMaximumBitrate; + bool uEaggregateMaximumBitrate_present; + LIBLTE_S1AP_E_RABTOBESWITCHEDULLIST_STRUCT E_RABToBeSwitchedULList; + bool E_RABToBeSwitchedULList_present; + LIBLTE_S1AP_E_RABLIST_STRUCT E_RABToBeReleasedList; + bool E_RABToBeReleasedList_present; + LIBLTE_S1AP_SECURITYCONTEXT_STRUCT SecurityContext; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID_2; + bool MME_UE_S1AP_ID_2_present; + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM CSGMembershipStatus; + bool CSGMembershipStatus_present; +}LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTACKNOWLEDGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pathswitchrequestacknowledge( + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTACKNOWLEDGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pathswitchrequestacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTACKNOWLEDGE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABSetupRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT uEaggregateMaximumBitrate; + bool uEaggregateMaximumBitrate_present; + LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT E_RABToBeSetupListBearerSUReq; +}LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetuprequest( + LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetuprequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABSetupResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_RABSETUPLISTBEARERSURES_STRUCT E_RABSetupListBearerSURes; + bool E_RABSetupListBearerSURes_present; + LIBLTE_S1AP_E_RABLIST_STRUCT E_RABFailedToSetupListBearerSURes; + bool E_RABFailedToSetupListBearerSURes_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupresponse( + LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABModifyRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT uEaggregateMaximumBitrate; + bool uEaggregateMaximumBitrate_present; + LIBLTE_S1AP_E_RABTOBEMODIFIEDLISTBEARERMODREQ_STRUCT E_RABToBeModifiedListBearerModReq; +}LIBLTE_S1AP_MESSAGE_E_RABMODIFYREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyrequest( + LIBLTE_S1AP_MESSAGE_E_RABMODIFYREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABMODIFYREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABModifyResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_RABMODIFYLISTBEARERMODRES_STRUCT E_RABModifyListBearerModRes; + bool E_RABModifyListBearerModRes_present; + LIBLTE_S1AP_E_RABLIST_STRUCT E_RABFailedToModifyList; + bool E_RABFailedToModifyList_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_E_RABMODIFYRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyresponse( + LIBLTE_S1AP_MESSAGE_E_RABMODIFYRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABMODIFYRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message E_RABReleaseResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_RABRELEASELISTBEARERRELCOMP_STRUCT E_RABReleaseListBearerRelComp; + bool E_RABReleaseListBearerRelComp_present; + LIBLTE_S1AP_E_RABLIST_STRUCT E_RABFailedToReleaseList; + bool E_RABFailedToReleaseList_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; + LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT UserLocationInformation; + bool UserLocationInformation_present; +}LIBLTE_S1AP_MESSAGE_E_RABRELEASERESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseresponse( + LIBLTE_S1AP_MESSAGE_E_RABRELEASERESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASERESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message InitialContextSetupRequest STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT uEaggregateMaximumBitrate; + LIBLTE_S1AP_E_RABTOBESETUPLISTCTXTSUREQ_STRUCT E_RABToBeSetupListCtxtSUReq; + LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT UESecurityCapabilities; + LIBLTE_S1AP_SECURITYKEY_STRUCT SecurityKey; + LIBLTE_S1AP_TRACEACTIVATION_STRUCT TraceActivation; + bool TraceActivation_present; + LIBLTE_S1AP_HANDOVERRESTRICTIONLIST_STRUCT HandoverRestrictionList; + bool HandoverRestrictionList_present; + LIBLTE_S1AP_UERADIOCAPABILITY_STRUCT UERadioCapability; + bool UERadioCapability_present; + LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT SubscriberProfileIDforRFP; + bool SubscriberProfileIDforRFP_present; + LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM_EXT CSFallbackIndicator; + bool CSFallbackIndicator_present; + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM_EXT SRVCCOperationPossible; + bool SRVCCOperationPossible_present; + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM CSGMembershipStatus; + bool CSGMembershipStatus_present; + LIBLTE_S1AP_LAI_STRUCT RegisteredLAI; + bool RegisteredLAI_present; + LIBLTE_S1AP_GUMMEI_STRUCT GUMMEI_ID; + bool GUMMEI_ID_present; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID_2; + bool MME_UE_S1AP_ID_2_present; + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM_EXT ManagementBasedMDTAllowed; + bool ManagementBasedMDTAllowed_present; + LIBLTE_S1AP_MDTPLMNLIST_STRUCT ManagementBasedMDTPLMNList; + bool ManagementBasedMDTPLMNList_present; + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM_EXT AdditionalCSFallbackIndicator; + bool AdditionalCSFallbackIndicator_present; +}LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initialcontextsetuprequest( + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initialcontextsetuprequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message InitialContextSetupResponse STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_RABSETUPLISTCTXTSURES_STRUCT E_RABSetupListCtxtSURes; + LIBLTE_S1AP_E_RABLIST_STRUCT E_RABFailedToSetupListCtxtSURes; + bool E_RABFailedToSetupListCtxtSURes_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; +}LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initialcontextsetupresponse( + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initialcontextsetupresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message Paging STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_UEIDENTITYINDEXVALUE_STRUCT UEIdentityIndexValue; + LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID; + LIBLTE_S1AP_PAGINGDRX_ENUM_EXT pagingDRX; + bool pagingDRX_present; + LIBLTE_S1AP_CNDOMAIN_ENUM CNDomain; + LIBLTE_S1AP_TAILIST_STRUCT TAIList; + LIBLTE_S1AP_CSG_IDLIST_STRUCT CSG_IdList; + bool CSG_IdList_present; + LIBLTE_S1AP_PAGINGPRIORITY_ENUM_EXT PagingPriority; + bool PagingPriority_present; +}LIBLTE_S1AP_MESSAGE_PAGING_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_paging( + LIBLTE_S1AP_MESSAGE_PAGING_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_paging( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PAGING_STRUCT *ie); + +/******************************************************************************* +/* Protocol Message HandoverRequestAcknowledge STRUCT +********************************************************************************/ +typedef struct{ + bool ext; + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT MME_UE_S1AP_ID; + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT eNB_UE_S1AP_ID; + LIBLTE_S1AP_E_RABADMITTEDLIST_STRUCT E_RABAdmittedList; + LIBLTE_S1AP_E_RABFAILEDTOSETUPLISTHOREQACK_STRUCT E_RABFailedToSetupListHOReqAck; + bool E_RABFailedToSetupListHOReqAck_present; + LIBLTE_S1AP_TARGET_TOSOURCE_TRANSPARENTCONTAINER_STRUCT Target_ToSource_TransparentContainer; + LIBLTE_S1AP_CSG_ID_STRUCT CSG_Id; + bool CSG_Id_present; + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT CriticalityDiagnostics; + bool CriticalityDiagnostics_present; + LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT CellAccessMode; + bool CellAccessMode_present; +}LIBLTE_S1AP_MESSAGE_HANDOVERREQUESTACKNOWLEDGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrequestacknowledge( + LIBLTE_S1AP_MESSAGE_HANDOVERREQUESTACKNOWLEDGE_STRUCT *ie, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrequestacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERREQUESTACKNOWLEDGE_STRUCT *ie); + +/******************************************************************************* +/* Procedure code criticality lookups +********************************************************************************/ +static const LIBLTE_S1AP_CRITICALITY_ENUM liblte_s1ap_procedure_criticality[50] = { + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + LIBLTE_S1AP_CRITICALITY_REJECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, +}; + +/******************************************************************************* +/* ProtocolIE-Field +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_header( + uint32_t len, + uint32_t ie_id, + LIBLTE_S1AP_CRITICALITY_ENUM crit, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_header( + uint8_t **ptr, + uint32_t *ie_id, + LIBLTE_S1AP_CRITICALITY_ENUM *crit, + uint32_t *len); + +/******************************************************************************* +/* InitiatingMessage CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORTINGCONTROL, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKS1CDMA2000TUNNELING, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_S1SETUPREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECAPABILITYINFOINDICATION, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORT, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKNONUEASSOCIATEDLPPATRANSPORT, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKS1CDMA2000TUNNELING, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMECONFIGURATIONTRANSFER, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_TRACESTART, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERCANCEL, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UERADIOCAPABILITYMATCHREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKNASTRANSPORT, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALCONTEXTSETUPREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERREQUIRED, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMEDIRECTINFORMATIONTRANSFER, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_TRACEFAILUREINDICATION, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMECONFIGURATIONUPDATE, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_WRITEREPLACEWARNINGREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBDIRECTINFORMATIONTRANSFER, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKUEASSOCIATEDLPPATRANSPORT, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABRELEASECOMMAND, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_NASNONDELIVERYINDICATION, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBCONFIGURATIONUPDATE, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKUEASSOCIATEDLPPATRANSPORT, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALUEMESSAGE, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABMODIFYREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTMODIFICATIONREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABSETUPREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_RESET, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_OVERLOADSTART, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABRELEASEINDICATION, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORTINGFAILUREINDICATION, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DEACTIVATETRACE, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PATHSWITCHREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_OVERLOADSTOP, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PAGING, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERNOTIFY, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PWSRESTARTINDICATION, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASEREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKNASTRANSPORT, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBCONFIGURATIONTRANSFER, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMESTATUSTRANSFER, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_CELLTRAFFICTRACE, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASECOMMAND, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_KILLREQUEST, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PRIVATEMESSAGE, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBSTATUSTRANSFER, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ERRORINDICATION, + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_N_ITEMS, +}LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENUM; +static const char liblte_s1ap_initiatingmessage_choice_text[LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_N_ITEMS][50] = { + "LocationReportingControl", + "DownlinkS1cdma2000tunneling", + "S1SetupRequest", + "UECapabilityInfoIndication", + "LocationReport", + "UplinkNonUEAssociatedLPPaTransport", + "UplinkS1cdma2000tunneling", + "MMEConfigurationTransfer", + "TraceStart", + "HandoverCancel", + "UERadioCapabilityMatchRequest", + "DownlinkNASTransport", + "InitialContextSetupRequest", + "HandoverRequired", + "MMEDirectInformationTransfer", + "TraceFailureIndication", + "MMEConfigurationUpdate", + "WriteReplaceWarningRequest", + "ENBDirectInformationTransfer", + "DownlinkUEAssociatedLPPaTransport", + "E-RABReleaseCommand", + "NASNonDeliveryIndication", + "ENBConfigurationUpdate", + "UplinkUEAssociatedLPPaTransport", + "InitialUEMessage", + "E-RABModifyRequest", + "UEContextModificationRequest", + "E-RABSetupRequest", + "Reset", + "OverloadStart", + "E-RABReleaseIndication", + "LocationReportingFailureIndication", + "DeactivateTrace", + "PathSwitchRequest", + "HandoverRequest", + "DownlinkNonUEAssociatedLPPaTransport", + "OverloadStop", + "Paging", + "HandoverNotify", + "PWSRestartIndication", + "UEContextReleaseRequest", + "UplinkNASTransport", + "ENBConfigurationTransfer", + "MMEStatusTransfer", + "CellTrafficTrace", + "UEContextReleaseCommand", + "KillRequest", + "PrivateMessage", + "ENBStatusTransfer", + "ErrorIndication", +}; + +typedef union{ + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGCONTROL_STRUCT LocationReportingControl; + LIBLTE_S1AP_MESSAGE_DOWNLINKS1CDMA2000TUNNELING_STRUCT DownlinkS1cdma2000tunneling; + LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT S1SetupRequest; + LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT UECapabilityInfoIndication; + LIBLTE_S1AP_MESSAGE_LOCATIONREPORT_STRUCT LocationReport; + LIBLTE_S1AP_MESSAGE_UPLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT UplinkNonUEAssociatedLPPaTransport; + LIBLTE_S1AP_MESSAGE_UPLINKS1CDMA2000TUNNELING_STRUCT UplinkS1cdma2000tunneling; + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONTRANSFER_STRUCT MMEConfigurationTransfer; + LIBLTE_S1AP_MESSAGE_TRACESTART_STRUCT TraceStart; + LIBLTE_S1AP_MESSAGE_HANDOVERCANCEL_STRUCT HandoverCancel; + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHREQUEST_STRUCT UERadioCapabilityMatchRequest; + LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT DownlinkNASTransport; + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT InitialContextSetupRequest; + LIBLTE_S1AP_MESSAGE_HANDOVERREQUIRED_STRUCT HandoverRequired; + LIBLTE_S1AP_MESSAGE_MMEDIRECTINFORMATIONTRANSFER_STRUCT MMEDirectInformationTransfer; + LIBLTE_S1AP_MESSAGE_TRACEFAILUREINDICATION_STRUCT TraceFailureIndication; + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATE_STRUCT MMEConfigurationUpdate; + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGREQUEST_STRUCT WriteReplaceWarningRequest; + LIBLTE_S1AP_MESSAGE_ENBDIRECTINFORMATIONTRANSFER_STRUCT ENBDirectInformationTransfer; + LIBLTE_S1AP_MESSAGE_DOWNLINKUEASSOCIATEDLPPATRANSPORT_STRUCT DownlinkUEAssociatedLPPaTransport; + LIBLTE_S1AP_MESSAGE_E_RABRELEASECOMMAND_STRUCT E_RABReleaseCommand; + LIBLTE_S1AP_MESSAGE_NASNONDELIVERYINDICATION_STRUCT NASNonDeliveryIndication; + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATE_STRUCT ENBConfigurationUpdate; + LIBLTE_S1AP_MESSAGE_UPLINKUEASSOCIATEDLPPATRANSPORT_STRUCT UplinkUEAssociatedLPPaTransport; + LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT InitialUEMessage; + LIBLTE_S1AP_MESSAGE_E_RABMODIFYREQUEST_STRUCT E_RABModifyRequest; + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT UEContextModificationRequest; + LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT E_RABSetupRequest; + LIBLTE_S1AP_MESSAGE_RESET_STRUCT Reset; + LIBLTE_S1AP_MESSAGE_OVERLOADSTART_STRUCT OverloadStart; + LIBLTE_S1AP_MESSAGE_E_RABRELEASEINDICATION_STRUCT E_RABReleaseIndication; + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGFAILUREINDICATION_STRUCT LocationReportingFailureIndication; + LIBLTE_S1AP_MESSAGE_DEACTIVATETRACE_STRUCT DeactivateTrace; + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUEST_STRUCT PathSwitchRequest; + LIBLTE_S1AP_MESSAGE_HANDOVERREQUEST_STRUCT HandoverRequest; + LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT DownlinkNonUEAssociatedLPPaTransport; + LIBLTE_S1AP_MESSAGE_OVERLOADSTOP_STRUCT OverloadStop; + LIBLTE_S1AP_MESSAGE_PAGING_STRUCT Paging; + LIBLTE_S1AP_MESSAGE_HANDOVERNOTIFY_STRUCT HandoverNotify; + LIBLTE_S1AP_MESSAGE_PWSRESTARTINDICATION_STRUCT PWSRestartIndication; + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT UEContextReleaseRequest; + LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT UplinkNASTransport; + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONTRANSFER_STRUCT ENBConfigurationTransfer; + LIBLTE_S1AP_MESSAGE_MMESTATUSTRANSFER_STRUCT MMEStatusTransfer; + LIBLTE_S1AP_MESSAGE_CELLTRAFFICTRACE_STRUCT CellTrafficTrace; + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT UEContextReleaseCommand; + LIBLTE_S1AP_MESSAGE_KILLREQUEST_STRUCT KillRequest; + LIBLTE_S1AP_MESSAGE_PRIVATEMESSAGE_STRUCT PrivateMessage; + LIBLTE_S1AP_MESSAGE_ENBSTATUSTRANSFER_STRUCT ENBStatusTransfer; + LIBLTE_S1AP_MESSAGE_ERRORINDICATION_STRUCT ErrorIndication; +}LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UNION; + +typedef struct{ + uint8_t procedureCode; + LIBLTE_S1AP_CRITICALITY_ENUM criticality; + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UNION choice; + LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initiatingmessage( + LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initiatingmessage( + uint8_t **ptr, + LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg); + +/******************************************************************************* +/* UnsuccessfulOutcome CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_S1SETUPFAILURE, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_PATHSWITCHREQUESTFAILURE, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_UECONTEXTMODIFICATIONFAILURE, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_INITIALCONTEXTSETUPFAILURE, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_ENBCONFIGURATIONUPDATEFAILURE, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_HANDOVERPREPARATIONFAILURE, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_HANDOVERFAILURE, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_MMECONFIGURATIONUPDATEFAILURE, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_N_ITEMS, +}LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_ENUM; +static const char liblte_s1ap_unsuccessfuloutcome_choice_text[LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_N_ITEMS][50] = { + "S1SetupFailure", + "PathSwitchRequestFailure", + "UEContextModificationFailure", + "InitialContextSetupFailure", + "ENBConfigurationUpdateFailure", + "HandoverPreparationFailure", + "HandoverFailure", + "MMEConfigurationUpdateFailure", +}; + +typedef union{ + LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT S1SetupFailure; + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTFAILURE_STRUCT PathSwitchRequestFailure; + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONFAILURE_STRUCT UEContextModificationFailure; + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPFAILURE_STRUCT InitialContextSetupFailure; + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEFAILURE_STRUCT ENBConfigurationUpdateFailure; + LIBLTE_S1AP_MESSAGE_HANDOVERPREPARATIONFAILURE_STRUCT HandoverPreparationFailure; + LIBLTE_S1AP_MESSAGE_HANDOVERFAILURE_STRUCT HandoverFailure; + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEFAILURE_STRUCT MMEConfigurationUpdateFailure; +}LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_UNION; + +typedef struct{ + uint8_t procedureCode; + LIBLTE_S1AP_CRITICALITY_ENUM criticality; + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_UNION choice; + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_unsuccessfuloutcome( + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT *msg, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_unsuccessfuloutcome( + uint8_t **ptr, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT *msg); + +/******************************************************************************* +/* SuccessfulOutcome CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERREQUESTACKNOWLEDGE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UECONTEXTRELEASECOMPLETE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UERADIOCAPABILITYMATCHRESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_INITIALCONTEXTSETUPRESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABSETUPRESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_PATHSWITCHREQUESTACKNOWLEDGE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_MMECONFIGURATIONUPDATEACKNOWLEDGE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_RESETACKNOWLEDGE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_ENBCONFIGURATIONUPDATEACKNOWLEDGE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABMODIFYRESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_WRITEREPLACEWARNINGRESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_S1SETUPRESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_KILLRESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UECONTEXTMODIFICATIONRESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERCOMMAND, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERCANCELACKNOWLEDGE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABRELEASERESPONSE, + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_N_ITEMS, +}LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_ENUM; +static const char liblte_s1ap_successfuloutcome_choice_text[LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_N_ITEMS][50] = { + "HandoverRequestAcknowledge", + "UEContextReleaseComplete", + "UERadioCapabilityMatchResponse", + "InitialContextSetupResponse", + "E-RABSetupResponse", + "PathSwitchRequestAcknowledge", + "MMEConfigurationUpdateAcknowledge", + "ResetAcknowledge", + "ENBConfigurationUpdateAcknowledge", + "E-RABModifyResponse", + "WriteReplaceWarningResponse", + "S1SetupResponse", + "KillResponse", + "UEContextModificationResponse", + "HandoverCommand", + "HandoverCancelAcknowledge", + "E-RABReleaseResponse", +}; + +typedef union{ + LIBLTE_S1AP_MESSAGE_HANDOVERREQUESTACKNOWLEDGE_STRUCT HandoverRequestAcknowledge; + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT UEContextReleaseComplete; + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHRESPONSE_STRUCT UERadioCapabilityMatchResponse; + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT InitialContextSetupResponse; + LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT E_RABSetupResponse; + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTACKNOWLEDGE_STRUCT PathSwitchRequestAcknowledge; + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEACKNOWLEDGE_STRUCT MMEConfigurationUpdateAcknowledge; + LIBLTE_S1AP_MESSAGE_RESETACKNOWLEDGE_STRUCT ResetAcknowledge; + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEACKNOWLEDGE_STRUCT ENBConfigurationUpdateAcknowledge; + LIBLTE_S1AP_MESSAGE_E_RABMODIFYRESPONSE_STRUCT E_RABModifyResponse; + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGRESPONSE_STRUCT WriteReplaceWarningResponse; + LIBLTE_S1AP_MESSAGE_S1SETUPRESPONSE_STRUCT S1SetupResponse; + LIBLTE_S1AP_MESSAGE_KILLRESPONSE_STRUCT KillResponse; + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONRESPONSE_STRUCT UEContextModificationResponse; + LIBLTE_S1AP_MESSAGE_HANDOVERCOMMAND_STRUCT HandoverCommand; + LIBLTE_S1AP_MESSAGE_HANDOVERCANCELACKNOWLEDGE_STRUCT HandoverCancelAcknowledge; + LIBLTE_S1AP_MESSAGE_E_RABRELEASERESPONSE_STRUCT E_RABReleaseResponse; +}LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UNION; + +typedef struct{ + uint8_t procedureCode; + LIBLTE_S1AP_CRITICALITY_ENUM criticality; + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UNION choice; + LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_successfuloutcome( + LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg, + uint8_t **ptr); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_successfuloutcome( + uint8_t **ptr, + LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg); + +/******************************************************************************* +/* S1AP_PDU CHOICE +********************************************************************************/ +typedef enum{ + LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE, + LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME, + LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME, + LIBLTE_S1AP_S1AP_PDU_CHOICE_N_ITEMS, +}LIBLTE_S1AP_S1AP_PDU_CHOICE_ENUM; +static const char liblte_s1ap_s1ap_pdu_choice_text[LIBLTE_S1AP_S1AP_PDU_CHOICE_N_ITEMS][50] = { + "initiatingMessage", + "successfulOutcome", + "unsuccessfulOutcome", +}; + +typedef union{ + LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT initiatingMessage; + LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT successfulOutcome; + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT unsuccessfulOutcome; +}LIBLTE_S1AP_S1AP_PDU_CHOICE_UNION; + +typedef struct{ + bool ext; + LIBLTE_S1AP_S1AP_PDU_CHOICE_UNION choice; + LIBLTE_S1AP_S1AP_PDU_CHOICE_ENUM choice_type; +}LIBLTE_S1AP_S1AP_PDU_STRUCT; + +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s1ap_pdu( + LIBLTE_S1AP_S1AP_PDU_STRUCT *s1ap_pdu, + LIBLTE_BYTE_MSG_STRUCT *msg); +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s1ap_pdu( + LIBLTE_BYTE_MSG_STRUCT *msg, + LIBLTE_S1AP_S1AP_PDU_STRUCT *s1ap_pdu); +#endif // LIBLTE_S1AP_H diff --git a/lib/include/srslte/common/interfaces.h b/lib/include/srslte/common/interfaces.h deleted file mode 100644 index bcdfabbf7..000000000 --- a/lib/include/srslte/common/interfaces.h +++ /dev/null @@ -1,234 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsUE library. - * - * srsUE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsUE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -/****************************************************************************** - * File: interfaces.h - * Description: Abstract base class interfaces provided by layers - * to other layers. - *****************************************************************************/ - -#ifndef INTERFACES_H -#define INTERFACES_H - -#include "srslte/asn1/liblte_rrc.h" -#include "srslte/common/interfaces_common.h" -#include "srslte/common/common.h" -#include "srslte/common/security.h" -#include "mac_interface.h" -#include "phy_interface.h" - -namespace srsue { - -// UE interface -class ue_interface -{ -}; - -// USIM interface for NAS -class usim_interface_nas -{ -public: - virtual void get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0; - virtual void get_imei_vec(uint8_t* imei_, uint32_t n) = 0; - virtual void generate_authentication_response(uint8_t *rand, - uint8_t *autn_enb, - uint16_t mcc, - uint16_t mnc, - bool *net_valid, - uint8_t *res) = 0; - virtual void generate_nas_keys(uint8_t *k_nas_enc, - uint8_t *k_nas_int, - CIPHERING_ALGORITHM_ID_ENUM cipher_algo, - INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0; -}; - -// USIM interface for RRC -class usim_interface_rrc -{ -public: - virtual void generate_as_keys(uint32_t count_ul, - uint8_t *k_rrc_enc, - uint8_t *k_rrc_int, - uint8_t *k_up_enc, - uint8_t *k_up_int, - CIPHERING_ALGORITHM_ID_ENUM cipher_algo, - INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0; -}; - -// GW interface for NAS -class gw_interface_nas -{ -public: - virtual srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str) = 0; -}; - -// GW interface for PDCP -class gw_interface_pdcp -{ -public: - virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; -}; - -// NAS interface for RRC -class nas_interface_rrc -{ -public: - virtual bool is_attached() = 0; - virtual void notify_connection_setup() = 0; - virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; - virtual uint32_t get_ul_count() = 0; - virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0; -}; - -// RRC interface for MAC -class rrc_interface_mac -{ -public: - virtual void release_pucch_srs() = 0; - virtual void ra_problem() = 0; -}; - -// RRC interface for PHY -class rrc_interface_phy -{ -public: - virtual void in_sync() = 0; - virtual void out_of_sync() = 0; -}; - -// RRC interface for NAS -class rrc_interface_nas -{ -public: - virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; - virtual uint16_t get_mcc() = 0; - virtual uint16_t get_mnc() = 0; - virtual void enable_capabilities() = 0; -}; - -// RRC interface for GW -class rrc_interface_gw -{ -public: - virtual bool rrc_connected() = 0; - virtual void rrc_connect() = 0; - virtual bool have_drb() = 0; -}; - -// RRC interface for PDCP -class rrc_interface_pdcp -{ -public: - virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; - virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu) = 0; - virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu) = 0; - virtual void write_pdu_pcch(srslte::byte_buffer_t *pdu) = 0; -}; - -// RRC interface for RLC -class rrc_interface_rlc -{ -public: - virtual void max_retx_attempted() = 0; -}; - -// PDCP interface for GW -class pdcp_interface_gw -{ -public: - virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; -}; - -// PDCP interface for RRC -class pdcp_interface_rrc -{ -public: - virtual void reset() = 0; - virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; - virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0; - virtual void config_security(uint32_t lcid, - uint8_t *k_rrc_enc_, - uint8_t *k_rrc_int_, - CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, - INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; -}; - -// PDCP interface for RLC -class pdcp_interface_rlc -{ -public: - /* RLC calls PDCP to push a PDCP PDU. */ - virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; - virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *sdu) = 0; - virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu) = 0; - virtual void write_pdu_pcch(srslte::byte_buffer_t *sdu) = 0; -}; - -// RLC interface for RRC -class rlc_interface_rrc -{ -public: - virtual void reset() = 0; - virtual void add_bearer(uint32_t lcid) = 0; - virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0; -}; - -// RLC interface for PDCP -class rlc_interface_pdcp -{ -public: - /* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls - * RLC PDUs according to TB size. */ - virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; -}; - -//RLC interface for MAC -class rlc_interface_mac : public srslte::read_pdu_interface -{ -public: - /* MAC calls RLC to get buffer state for a logical channel. - * This function should return quickly. */ - virtual uint32_t get_buffer_state(uint32_t lcid) = 0; - virtual uint32_t get_total_buffer_state(uint32_t lcid) = 0; - - - const static int MAX_PDU_SEGMENTS = 20; - - /* MAC calls RLC to get RLC segment of nof_bytes length. - * Segmentation happens in this function. RLC PDU is stored in payload. */ - virtual int read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; - - /* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. - * PDU gets placed into the buffer and higher layer thread gets notified. */ - virtual void write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; - virtual void write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) = 0; - virtual void write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) = 0; - virtual void write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) = 0; -}; - -} // namespace srsue - -#endif // INTERFACES_H diff --git a/lib/include/srslte/common/mac_interface.h b/lib/include/srslte/common/mac_interface.h deleted file mode 100644 index 3c1c02dc5..000000000 --- a/lib/include/srslte/common/mac_interface.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsUE library. - * - * srsUE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsUE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -/****************************************************************************** - * File: mac_interface.h - * Description: LTE MAC layer interface - * Reference: - *****************************************************************************/ - -#ifndef MAC_INTERFACE_H -#define MAC_INTERFACE_H - -#include -#include -#include "srslte/srslte.h" - -#include "srslte/common/interfaces_common.h" -#include "srslte/common/timers.h" - -#include "srslte/asn1/liblte_rrc.h" - -namespace srsue { - -/* Interface PHY -> MAC */ -class mac_interface_phy -{ -public: - - typedef struct { - uint32_t pid; - uint32_t tti; - uint32_t last_tti; - bool ndi; - bool last_ndi; - uint32_t n_bytes; - int rv; - uint16_t rnti; - bool is_from_rar; - bool is_sps_release; - bool has_cqi_request; - srslte_rnti_type_t rnti_type; - srslte_phy_grant_t phy_grant; - } mac_grant_t; - - typedef struct { - bool decode_enabled; - int rv; - uint16_t rnti; - bool generate_ack; - bool default_ack; - // If non-null, called after tb_decoded_ok to determine if ack needs to be sent - bool (*generate_ack_callback)(void*); - void *generate_ack_callback_arg; - uint8_t *payload_ptr; - srslte_softbuffer_rx_t *softbuffer; - srslte_phy_grant_t phy_grant; - } tb_action_dl_t; - - typedef struct { - bool tx_enabled; - bool expect_ack; - uint32_t rv; - uint16_t rnti; - uint32_t current_tx_nb; - srslte_softbuffer_tx_t *softbuffer; - srslte_phy_grant_t phy_grant; - uint8_t *payload_ptr; - } tb_action_ul_t; - - /* Indicate reception of UL grant. - * payload_ptr points to memory where MAC PDU must be written by MAC layer */ - virtual void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action) = 0; - - /* Indicate reception of UL grant + HARQ information throught PHICH in the same TTI. */ - virtual void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action) = 0; - - /* Indicate reception of HARQ information only through PHICH. */ - virtual void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) = 0; - - /* Indicate reception of DL grant. */ - virtual void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) = 0; - - /* Indicate successfull decoding of PDSCH TB. */ - virtual void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) = 0; - - /* Indicate successfull decoding of BCH TB through PBCH */ - virtual void bch_decoded_ok(uint8_t *payload, uint32_t len) = 0; - - /* Indicate successfull decoding of PCH TB through PDSCH */ - virtual void pch_decoded_ok(uint32_t len) = 0; - - /* Function called every start of a subframe (TTI). Warning, this function is called - * from a high priority thread and should terminate asap - */ - virtual void tti_clock(uint32_t tti) = 0; - -}; - - -/* Interface RRC -> MAC */ -class mac_interface_rrc -{ -public: - - typedef struct { - LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT main; - LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT rach; - LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT sr; - uint32_t prach_config_index; - } mac_cfg_t; - - - // Class to handle UE specific RNTIs between RRC and MAC - typedef struct { - uint16_t crnti; - uint16_t temp_rnti; - uint16_t tpc_rnti; - uint16_t sps_rnti; - uint64_t contention_id; - } ue_rnti_t; - - /* Instructs the MAC to start receiving BCCH */ - virtual void bcch_start_rx() = 0; - virtual void bcch_stop_rx() = 0; - virtual void bcch_start_rx(int si_window_start, int si_window_length) = 0; - - /* Instructs the MAC to start receiving PCCH */ - virtual void pcch_start_rx() = 0; - virtual void pcch_stop_rx() = 0; - - /* RRC configures a logical channel */ - virtual void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD) = 0; - - virtual uint32_t get_current_tti() = 0; - - virtual void set_config(mac_cfg_t *mac_cfg) = 0; - virtual void set_config_main(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *main_cfg) = 0; - virtual void set_config_rach(LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT *rach_cfg, uint32_t prach_config_index) = 0; - virtual void set_config_sr(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT *sr_cfg) = 0; - virtual void get_config(mac_cfg_t *mac_cfg) = 0; - - virtual void get_rntis(ue_rnti_t *rntis) = 0; - virtual void set_contention_id(uint64_t uecri) = 0; - - - virtual void reconfiguration() = 0; - virtual void reset() = 0; -}; - -} - - -#endif - diff --git a/lib/include/srslte/common/pdu_queue.h b/lib/include/srslte/common/pdu_queue.h index c762922aa..2aaa20c07 100644 --- a/lib/include/srslte/common/pdu_queue.h +++ b/lib/include/srslte/common/pdu_queue.h @@ -44,7 +44,7 @@ public: class process_callback { public: - virtual void process_pdu(uint8_t *buff, uint32_t len) = 0; + virtual void process_pdu(uint8_t *buff, uint32_t len, uint32_t tstamp) = 0; }; pdu_queue(uint32_t pool_size = DEFAULT_POOL_SIZE) : pool(pool_size), callback(NULL), log_h(NULL) {} @@ -52,7 +52,7 @@ public: uint8_t* request(uint32_t len); void deallocate(uint8_t* pdu); - void push(uint8_t *ptr, uint32_t len); + void push(uint8_t *ptr, uint32_t len, uint32_t tstamp = 0); bool process_pdus(); @@ -63,6 +63,7 @@ private: typedef struct { uint8_t ptr[MAX_PDU_LEN]; uint32_t len; + uint32_t tstamp; } pdu_t; block_queue pdu_q; diff --git a/lib/include/srslte/common/phy_interface.h b/lib/include/srslte/common/phy_interface.h deleted file mode 100644 index c6c0bf008..000000000 --- a/lib/include/srslte/common/phy_interface.h +++ /dev/null @@ -1,156 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsUE library. - * - * srsUE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsUE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -/****************************************************************************** - * File: phy_interface.h - * Description: PHY layer interfaces provided to other layers - * Reference: - *****************************************************************************/ - -#ifndef PHY_INTERFACE_H -#define PHY_INTERFACE_H - -#include -#include -#include "srslte/srslte.h" - -#include "srslte/asn1/liblte_rrc.h" - -namespace srsue { - - -typedef struct { - bool ul_pwr_ctrl_en; - float prach_gain; - int pdsch_max_its; - bool attach_enable_64qam; - int nof_phy_threads; - - int worker_cpu_mask; - int sync_cpu_affinity; - - uint32_t nof_rx_ant; - std::string equalizer_mode; - int cqi_max; - int cqi_fixed; - float snr_ema_coeff; - std::string snr_estim_alg; - bool cfo_integer_enabled; - float cfo_correct_tol_hz; - int time_correct_period; - bool sfo_correct_disable; - std::string sss_algorithm; - float estimator_fil_w; - bool rssi_sensor_enabled; -} phy_args_t; - -/* Interface MAC -> PHY */ -class phy_interface_mac -{ -public: - /* Configure PRACH using parameters written by RRC */ - virtual void configure_prach_params() = 0; - - /* Start synchronization with strongest cell in the current carrier frequency */ - virtual void sync_start() = 0; - virtual void sync_stop() = 0; - - /* Sets a C-RNTI allowing the PHY to pregenerate signals if necessary */ - virtual void set_crnti(uint16_t rnti) = 0; - - virtual void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm) = 0; - virtual int prach_tx_tti() = 0; - - /* Indicates the transmission of a SR signal in the next opportunity */ - virtual void sr_send() = 0; - virtual int sr_last_tx_tti() = 0; - - /* Time advance commands */ - virtual void set_timeadv_rar(uint32_t ta_cmd) = 0; - virtual void set_timeadv(uint32_t ta_cmd) = 0; - - /* Sets RAR grant payload */ - virtual void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) = 0; - - /* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */ - virtual void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0; - virtual void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0; - virtual void pdcch_ul_search_reset() = 0; - virtual void pdcch_dl_search_reset() = 0; - - virtual uint32_t get_current_tti() = 0; - - virtual float get_phr() = 0; - virtual float get_pathloss_db() = 0; - -}; - -class phy_interface_rrc -{ -public: - - typedef struct { - LIBLTE_RRC_PRACH_CONFIG_SIB_STRUCT prach_cnfg; - LIBLTE_RRC_PDSCH_CONFIG_COMMON_STRUCT pdsch_cnfg; - LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT pusch_cnfg; - LIBLTE_RRC_PHICH_CONFIG_STRUCT phich_cnfg; - LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT pucch_cnfg; - LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT srs_ul_cnfg; - LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT ul_pwr_ctrl; - LIBLTE_RRC_TDD_CONFIG_STRUCT tdd_cnfg; - LIBLTE_RRC_ANTENNA_PORTS_COUNT_ENUM ant_info; - } phy_cfg_common_t; - - typedef struct { - LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT dedicated; - phy_cfg_common_t common; - bool enable_64qam; - } phy_cfg_t; - - virtual void get_current_cell(srslte_cell_t *cell) = 0; - virtual void get_config(phy_cfg_t *phy_cfg) = 0; - virtual void set_config(phy_cfg_t *phy_cfg) = 0; - virtual void set_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated) = 0; - virtual void set_config_common(phy_cfg_common_t *common) = 0; - virtual void set_config_tdd(LIBLTE_RRC_TDD_CONFIG_STRUCT *tdd) = 0; - virtual void set_config_64qam_en(bool enable) = 0; - - /* Is the PHY downlink synchronized? */ - virtual bool status_is_sync() = 0; - - /* Configure UL using parameters written with set_param() */ - virtual void configure_ul_params(bool pregen_disabled = false) = 0; - - virtual void reset() = 0; - - virtual void resync_sfn() = 0; - -}; - -} - -#endif - diff --git a/lib/include/srslte/common/security.h b/lib/include/srslte/common/security.h index f1315401e..080f1848f 100644 --- a/lib/include/srslte/common/security.h +++ b/lib/include/srslte/common/security.h @@ -38,7 +38,7 @@ #define SECURITY_DIRECTION_UPLINK 0 #define SECURITY_DIRECTION_DOWNLINK 1 -namespace srsue{ +namespace srslte { typedef enum{ CIPHERING_ALGORITHM_ID_EEA0 = 0, diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h new file mode 100644 index 000000000..5282db45c --- /dev/null +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -0,0 +1,244 @@ + + +#include "srslte/srslte.h" + +#include "srslte/common/common.h" +#include "srslte/common/security.h" +#include "srslte/interfaces/sched_interface.h" +#include "srslte/asn1/liblte_rrc.h" +#include "srslte/asn1/liblte_s1ap.h" + +#include + +#ifndef ENBINTERFACES_H +#define ENBINTERFACES_H + +namespace srsenb { + +/* Interface PHY -> MAC */ +class mac_interface_phy +{ +public: + const static int MAX_GRANTS = 64; + + typedef struct { + srslte_enb_dl_pdsch_t sched_grants[MAX_GRANTS]; + uint32_t nof_grants; + uint32_t cfi; + } dl_sched_t; + + typedef struct { + srslte_enb_ul_pusch_t sched_grants[MAX_GRANTS]; + srslte_enb_dl_phich_t phich[MAX_GRANTS]; + uint32_t nof_grants; + uint32_t nof_phich; + } ul_sched_t; + + + virtual int sr_detected(uint32_t tti, uint16_t rnti) = 0; + virtual int rach_detected(uint32_t tti, uint32_t preamble_idx, uint32_t time_adv) = 0; + + virtual int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value) = 0; + virtual int snr_info(uint32_t tti, uint16_t rnti, float snr_db) = 0; + virtual int ack_info(uint32_t tti, uint16_t rnti, bool ack) = 0; + virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t nof_bytes, bool crc_res) = 0; + + virtual int get_dl_sched(uint32_t tti, dl_sched_t *dl_sched_res) = 0; + virtual int get_ul_sched(uint32_t tti, ul_sched_t *ul_sched_res) = 0; + + // Radio-Link status + virtual void rl_failure(uint16_t rnti) = 0; + virtual void rl_ok(uint16_t rnti) = 0; + + virtual void tti_clock() = 0; +}; + +/* Interface MAC -> PHY */ +class phy_interface_mac +{ +public: + + /* MAC adds/removes an RNTI to the list of active RNTIs */ + virtual int add_rnti(uint16_t rnti) = 0; + virtual void rem_rnti(uint16_t rnti) = 0; +}; + +/* Interface RRC -> PHY */ +class phy_interface_rrc +{ +public: + virtual void set_config_dedicated(uint16_t rnti, LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT* dedicated) = 0; + +}; + +class mac_interface_rrc +{ +public: + /* Provides cell configuration including SIB periodicity, etc. */ + virtual int cell_cfg(sched_interface::cell_cfg_t *cell_cfg) = 0; + virtual void reset() = 0; + + /* Manages UE configuration context */ + virtual int ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t *cfg) = 0; + virtual int ue_rem(uint16_t rnti) = 0; + + /* Manages UE bearers and associated configuration */ + virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t *cfg) = 0; + virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0; + virtual void phy_config_enabled(uint16_t rnti, bool enabled) = 0; + +}; + +class mac_interface_rlc +{ +public: + virtual int rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) = 0; +}; + +//RLC interface for MAC +class rlc_interface_mac +{ +public: + + /* MAC calls RLC to get RLC segment of nof_bytes length. + * Segmentation happens in this function. RLC PDU is stored in payload. */ + virtual int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; + + virtual void read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t *payload) = 0; + virtual void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) = 0; + + /* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. + * PDU gets placed into the buffer and higher layer thread gets notified. */ + virtual void write_pdu(uint16_t rnti, uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; + +}; + + +// RLC interface for PDCP +class rlc_interface_pdcp +{ +public: + /* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls + * RLC PDUs according to TB size. */ + virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; +}; + +// RLC interface for RRC +class rlc_interface_rrc +{ +public: + virtual void reset(uint16_t rnti) = 0; + virtual void clear_buffer(uint16_t rnti) = 0; + virtual void add_user(uint16_t rnti) = 0; + virtual void rem_user(uint16_t rnti) = 0; + virtual void add_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0; +}; + +// PDCP interface for GTPU +class pdcp_interface_gtpu +{ +public: + virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; +}; + +// PDCP interface for RRC +class pdcp_interface_rrc +{ +public: + virtual void reset(uint16_t rnti) = 0; + virtual void add_user(uint16_t rnti) = 0; + virtual void rem_user(uint16_t rnti) = 0; + virtual void write_sdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; + virtual void add_bearer(uint16_t rnti, uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0; + virtual void config_security(uint16_t rnti, + uint32_t lcid, + uint8_t *k_rrc_enc_, + uint8_t *k_rrc_int_, + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; +}; + +// PDCP interface for RLC +class pdcp_interface_rlc +{ +public: + /* RLC calls PDCP to push a PDCP PDU. */ + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; +}; + +// RRC interface for RLC +class rrc_interface_rlc +{ +public: + virtual void read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t *payload) = 0; + virtual void read_pdu_pcch(uint8_t *payload, uint32_t payload_size) = 0; + virtual void max_retx_attempted(uint16_t rnti) = 0; +}; + +// RRC interface for MAC +class rrc_interface_mac +{ +public: + /* Radio Link failure */ + virtual void rl_failure(uint16_t rnti) = 0; + virtual void add_user(uint16_t rnti) = 0; + virtual void upd_user(uint16_t new_rnti, uint16_t old_rnti) = 0; + virtual void set_activity_user(uint16_t rnti) = 0; + virtual bool is_paging_opportunity(uint32_t tti, uint32_t *payload_len) = 0; +}; + +// RRC interface for PDCP +class rrc_interface_pdcp +{ +public: + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; +}; + +// RRC interface for S1AP +class rrc_interface_s1ap +{ +public: + virtual void write_dl_info(uint16_t rnti, srslte::byte_buffer_t *sdu) = 0; + virtual void release_complete(uint16_t rnti) = 0; + virtual bool setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) = 0; + virtual bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg) = 0; + virtual bool release_erabs(uint32_t rnti) = 0; + virtual void add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID) = 0; +}; + +// GTPU interface for PDCP +class gtpu_interface_pdcp +{ +public: + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; +}; + +// GTPU interface for RRC +class gtpu_interface_rrc +{ +public: + virtual void add_bearer(uint16_t rnti, uint32_t lcid, uint32_t teid_out, uint32_t *teid_in) = 0; + virtual void rem_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual void rem_user(uint16_t rnti) = 0; +}; + +// S1AP interface for RRC +class s1ap_interface_rrc +{ +public: + virtual void initial_ue(uint16_t rnti, srslte::byte_buffer_t *pdu) = 0; + virtual void initial_ue(uint16_t rnti, srslte::byte_buffer_t *pdu, uint32_t m_tmsi, uint8_t mmec) = 0; + virtual void write_pdu(uint16_t rnti, srslte::byte_buffer_t *pdu) = 0; + virtual bool user_exists(uint16_t rnti) = 0; + virtual void user_inactivity(uint16_t rnti) = 0; + virtual void release_eutran(uint16_t rnti) = 0; + virtual bool user_link_lost(uint16_t rnti) = 0; + virtual void ue_ctxt_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *res) = 0; + virtual void ue_erab_setup_complete(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT *res) = 0; + // virtual void ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps) = 0; +}; + +} + +#endif diff --git a/lib/include/srslte/interfaces/enb_metrics_interface.h b/lib/include/srslte/interfaces/enb_metrics_interface.h new file mode 100644 index 000000000..4f0593481 --- /dev/null +++ b/lib/include/srslte/interfaces/enb_metrics_interface.h @@ -0,0 +1,42 @@ + +#ifndef ENB_METRICS_INTERFACE_H +#define ENB_METRICS_INTERFACE_H + +#include + +#include "upper/common_enb.h" +#include "upper/s1ap_metrics.h" +#include "upper/rrc_metrics.h" +#include "srslte/upper/gw_metrics.h" +#include "srslte/upper/rlc_metrics.h" +#include "mac/mac_metrics.h" +#include "phy/phy_metrics.h" + +namespace srsenb { + +typedef struct { + uint32_t rf_o; + uint32_t rf_u; + uint32_t rf_l; + bool rf_error; +}rf_metrics_t; + +typedef struct { + rf_metrics_t rf; + phy_metrics_t phy[ENB_METRICS_MAX_USERS]; + mac_metrics_t mac[ENB_METRICS_MAX_USERS]; + rrc_metrics_t rrc; + s1ap_metrics_t s1ap; + bool running; +}enb_metrics_t; + +// ENB interface +class enb_metrics_interface +{ +public: + virtual bool get_metrics(enb_metrics_t &m) = 0; +}; + +} // namespace srsenb + +#endif // ENB_METRICS_INTERFACE_H diff --git a/lib/include/srslte/interfaces/sched_interface.h b/lib/include/srslte/interfaces/sched_interface.h new file mode 100644 index 000000000..f3041f44c --- /dev/null +++ b/lib/include/srslte/interfaces/sched_interface.h @@ -0,0 +1,222 @@ + +#include "srslte/srslte.h" + +#ifndef SCHED_INTERFACE_H +#define SCHED_INTERFACE_H + +namespace srsenb { + +class sched_interface +{ +public: + + const static int MAX_SIB_PAYLOAD_LEN = 2048; + const static int MAX_SIBS = 16; + const static int MAX_LC = 6; + const static int MAX_DATA_LIST = 32; + const static int MAX_RAR_LIST = 8; + const static int MAX_BC_LIST = 8; + const static int MAX_RLC_PDU_LIST = 8; + const static int MAX_PHICH_LIST = 8; + + typedef struct { + uint32_t len; + uint32_t period_rf; + } cell_cfg_sib_t; + + + typedef struct { + int pdsch_mcs; + int pdsch_max_mcs; + int pusch_mcs; + int pusch_max_mcs; + int nof_ctrl_symbols; + } sched_args_t; + + + typedef struct { + + // Main cell configuration (used to calculate DCI locations in scheduler) + srslte_cell_t cell; + + /* SIB configuration */ + cell_cfg_sib_t sibs[MAX_SIBS]; + uint32_t si_window_ms; + + /* pusch configuration */ + srslte_pusch_hopping_cfg_t pusch_hopping_cfg; + + /* prach configuration */ + uint32_t prach_config; + uint32_t prach_freq_offset; + uint32_t prach_rar_window; + uint32_t prach_contention_resolution_timer; + + uint32_t maxharq_msg3tx; + uint32_t n1pucch_an; + uint32_t delta_pucch_shift; + + uint32_t nrb_cqi; + uint32_t ncs_an; + + uint32_t srs_subframe_config; + uint32_t srs_subframe_offset; + uint32_t srs_bw_config; + + } cell_cfg_t; + + + typedef struct { + int priority; + int bsd; + int pbr; + enum {IDLE = 0, UL, DL, BOTH} direction; + } ue_bearer_cfg_t; + + typedef struct { + + bool continuous_pusch; + + /* ue capabilities, etc */ + + uint32_t maxharq_tx; + uint32_t aperiodic_cqi_period; // if 0 is periodic CQI + uint32_t beta_ack_index; + uint32_t beta_ri_index; + uint32_t beta_cqi_index; + + srslte_pucch_cfg_t pucch_cfg; + uint32_t n_pucch_cqi; + uint32_t sr_I; + uint32_t sr_N_pucch; + bool sr_enabled; + uint32_t cqi_pucch; + uint32_t cqi_idx; + bool cqi_enabled; + + ue_bearer_cfg_t ue_bearers[MAX_LC]; + + } ue_cfg_t; + + typedef struct { + uint32_t lcid; + uint32_t nbytes; + } dl_sched_pdu_t; + + typedef struct { + uint32_t rnti; + srslte_ra_dl_dci_t dci; + srslte_dci_location_t dci_location; + uint32_t tbs; + bool mac_ce_ta; + bool mac_ce_rnti; + uint32_t nof_pdu_elems; + dl_sched_pdu_t pdu[MAX_RLC_PDU_LIST]; + } dl_sched_data_t; + + typedef struct { + uint32_t rnti; + bool needs_pdcch; + uint32_t current_tx_nb; + uint32_t tbs; + srslte_ra_ul_dci_t dci; + srslte_dci_location_t dci_location; + } ul_sched_data_t; + + typedef struct { + uint32_t ra_id; + srslte_dci_rar_grant_t grant; + } dl_sched_rar_grant_t; + + typedef struct { + uint32_t rarnti; + uint32_t tbs; + srslte_ra_dl_dci_t dci; + srslte_dci_location_t dci_location; + uint32_t nof_grants; + dl_sched_rar_grant_t grants[MAX_RAR_LIST]; + } dl_sched_rar_t; + + typedef struct { + srslte_ra_dl_dci_t dci; + srslte_dci_location_t dci_location; + + enum bc_type { + BCCH, PCCH + } type; + + uint32_t index; + + uint32_t tbs; + + } dl_sched_bc_t; + + typedef struct { + uint32_t cfi; + uint32_t nof_data_elems; + uint32_t nof_rar_elems; + uint32_t nof_bc_elems; + dl_sched_data_t data[MAX_DATA_LIST]; + dl_sched_rar_t rar[MAX_RAR_LIST]; + dl_sched_bc_t bc[MAX_BC_LIST]; + } dl_sched_res_t; + + typedef struct { + uint16_t rnti; + enum phich_elem { + ACK, NACK + } phich; + } ul_sched_phich_t; + + typedef struct { + uint32_t nof_dci_elems; + uint32_t nof_phich_elems; + ul_sched_data_t pusch[MAX_DATA_LIST]; + ul_sched_phich_t phich[MAX_PHICH_LIST]; + } ul_sched_res_t; + + /******************* Scheduler Control ****************************/ + + /* Provides cell configuration including SIB periodicity, etc. */ + virtual int cell_cfg(cell_cfg_t *cell_cfg) = 0; + virtual int reset() = 0; + + /* Manages UE scheduling context */ + virtual int ue_cfg(uint16_t rnti, ue_cfg_t *cfg) = 0; + virtual int ue_rem(uint16_t rnti) = 0; + virtual bool ue_exists(uint16_t rnti) = 0; + + /* Manages UE bearers and associated configuration */ + virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, ue_bearer_cfg_t *cfg) = 0; + virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0; + + virtual uint32_t get_ul_buffer(uint16_t rnti) = 0; + virtual uint32_t get_dl_buffer(uint16_t rnti) = 0; + + /******************* Scheduling Interface ***********************/ + /* DL buffer status report */ + virtual int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) = 0; + virtual int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) = 0; + + /* DL information */ + virtual int dl_ack_info(uint32_t tti, uint16_t rnti, bool ack) = 0; + virtual int dl_rach_info(uint32_t tti, uint32_t ra_id, uint16_t rnti, uint32_t estimated_size) = 0; + virtual int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi_value) = 0; + + /* UL information */ + virtual int ul_crc_info(uint32_t tti, uint16_t rnti, bool crc) = 0; + virtual int ul_sr_info(uint32_t tti, uint16_t rnti) = 0; + virtual int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr) = 0; + virtual int ul_recv_len(uint16_t rnti, uint32_t lcid, uint32_t len) = 0; + virtual int ul_phr(uint16_t rnti, int phr) = 0; + virtual int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi, uint32_t ul_ch_code) = 0; + + /* Run Scheduler for this tti */ + virtual int dl_sched(uint32_t tti, dl_sched_res_t *sched_result) = 0; + virtual int ul_sched(uint32_t tti, ul_sched_res_t *sched_result) = 0; + +}; + +} + +#endif diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h new file mode 100644 index 000000000..62b2a7ef7 --- /dev/null +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -0,0 +1,481 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsUE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * File: interfaces.h + * Description: Abstract base class interfaces provided by layers + * to other layers. + *****************************************************************************/ + +#ifndef INTERFACES_H +#define INTERFACES_H + +#include + +#include "srslte/asn1/liblte_rrc.h" +#include "srslte/common/interfaces_common.h" +#include "srslte/common/common.h" +#include "srslte/common/security.h" + +namespace srsue { + +// UE interface +class ue_interface +{ +}; + +// USIM interface for NAS +class usim_interface_nas +{ +public: + virtual void get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0; + virtual void get_imei_vec(uint8_t* imei_, uint32_t n) = 0; + virtual void generate_authentication_response(uint8_t *rand, + uint8_t *autn_enb, + uint16_t mcc, + uint16_t mnc, + bool *net_valid, + uint8_t *res) = 0; + virtual void generate_nas_keys(uint8_t *k_nas_enc, + uint8_t *k_nas_int, + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo, + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0; +}; + +// USIM interface for RRC +class usim_interface_rrc +{ +public: + virtual void generate_as_keys(uint32_t count_ul, + uint8_t *k_rrc_enc, + uint8_t *k_rrc_int, + uint8_t *k_up_enc, + uint8_t *k_up_int, + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo, + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0; +}; + +// GW interface for NAS +class gw_interface_nas +{ +public: + virtual srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str) = 0; +}; + +// GW interface for PDCP +class gw_interface_pdcp +{ +public: + virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; +}; + +// NAS interface for RRC +class nas_interface_rrc +{ +public: + virtual bool is_attached() = 0; + virtual void notify_connection_setup() = 0; + virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; + virtual uint32_t get_ul_count() = 0; + virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0; +}; + +// RRC interface for MAC +class rrc_interface_mac +{ +public: + virtual void release_pucch_srs() = 0; + virtual void ra_problem() = 0; +}; + +// RRC interface for PHY +class rrc_interface_phy +{ +public: + virtual void in_sync() = 0; + virtual void out_of_sync() = 0; +}; + +// RRC interface for NAS +class rrc_interface_nas +{ +public: + virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; + virtual uint16_t get_mcc() = 0; + virtual uint16_t get_mnc() = 0; + virtual void enable_capabilities() = 0; +}; + +// RRC interface for GW +class rrc_interface_gw +{ +public: + virtual bool rrc_connected() = 0; + virtual void rrc_connect() = 0; + virtual bool have_drb() = 0; +}; + +// RRC interface for PDCP +class rrc_interface_pdcp +{ +public: + virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; + virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *pdu) = 0; + virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *pdu) = 0; + virtual void write_pdu_pcch(srslte::byte_buffer_t *pdu) = 0; +}; + +// RRC interface for RLC +class rrc_interface_rlc +{ +public: + virtual void max_retx_attempted() = 0; +}; + +// PDCP interface for GW +class pdcp_interface_gw +{ +public: + virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; +}; + +// PDCP interface for RRC +class pdcp_interface_rrc +{ +public: + virtual void reset() = 0; + virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; + virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg=NULL) = 0; + virtual void config_security(uint32_t lcid, + uint8_t *k_rrc_enc_, + uint8_t *k_rrc_int_, + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; +}; + +// PDCP interface for RLC +class pdcp_interface_rlc +{ +public: + /* RLC calls PDCP to push a PDCP PDU. */ + virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; + virtual void write_pdu_bcch_bch(srslte::byte_buffer_t *sdu) = 0; + virtual void write_pdu_bcch_dlsch(srslte::byte_buffer_t *sdu) = 0; + virtual void write_pdu_pcch(srslte::byte_buffer_t *sdu) = 0; +}; + +// RLC interface for RRC +class rlc_interface_rrc +{ +public: + virtual void reset() = 0; + virtual void add_bearer(uint32_t lcid) = 0; + virtual void add_bearer(uint32_t lcid, LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0; +}; + +// RLC interface for PDCP +class rlc_interface_pdcp +{ +public: + /* PDCP calls RLC to push an RLC SDU. SDU gets placed into the RLC buffer and MAC pulls + * RLC PDUs according to TB size. */ + virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0; +}; + +//RLC interface for MAC +class rlc_interface_mac : public srslte::read_pdu_interface +{ +public: + /* MAC calls RLC to get buffer state for a logical channel. + * This function should return quickly. */ + virtual uint32_t get_buffer_state(uint32_t lcid) = 0; + virtual uint32_t get_total_buffer_state(uint32_t lcid) = 0; + + + const static int MAX_PDU_SEGMENTS = 20; + + /* MAC calls RLC to get RLC segment of nof_bytes length. + * Segmentation happens in this function. RLC PDU is stored in payload. */ + virtual int read_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; + + /* MAC calls RLC to push an RLC PDU. This function is called from an independent MAC thread. + * PDU gets placed into the buffer and higher layer thread gets notified. */ + virtual void write_pdu(uint32_t lcid, uint8_t *payload, uint32_t nof_bytes) = 0; + virtual void write_pdu_bcch_bch(uint8_t *payload, uint32_t nof_bytes) = 0; + virtual void write_pdu_bcch_dlsch(uint8_t *payload, uint32_t nof_bytes) = 0; + virtual void write_pdu_pcch(uint8_t *payload, uint32_t nof_bytes) = 0; +}; + + + +/** MAC interface + * + */ +/* Interface PHY -> MAC */ +class mac_interface_phy +{ +public: + + typedef struct { + uint32_t pid; + uint32_t tti; + uint32_t last_tti; + bool ndi; + bool last_ndi; + uint32_t n_bytes; + int rv; + uint16_t rnti; + bool is_from_rar; + bool is_sps_release; + bool has_cqi_request; + srslte_rnti_type_t rnti_type; + srslte_phy_grant_t phy_grant; + } mac_grant_t; + + typedef struct { + bool decode_enabled; + int rv; + uint16_t rnti; + bool generate_ack; + bool default_ack; + // If non-null, called after tb_decoded_ok to determine if ack needs to be sent + bool (*generate_ack_callback)(void*); + void *generate_ack_callback_arg; + uint8_t *payload_ptr; + srslte_softbuffer_rx_t *softbuffer; + srslte_phy_grant_t phy_grant; + } tb_action_dl_t; + + typedef struct { + bool tx_enabled; + bool expect_ack; + uint32_t rv; + uint16_t rnti; + uint32_t current_tx_nb; + srslte_softbuffer_tx_t *softbuffer; + srslte_phy_grant_t phy_grant; + uint8_t *payload_ptr; + } tb_action_ul_t; + + /* Indicate reception of UL grant. + * payload_ptr points to memory where MAC PDU must be written by MAC layer */ + virtual void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action) = 0; + + /* Indicate reception of UL grant + HARQ information throught PHICH in the same TTI. */ + virtual void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action) = 0; + + /* Indicate reception of HARQ information only through PHICH. */ + virtual void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action) = 0; + + /* Indicate reception of DL grant. */ + virtual void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) = 0; + + /* Indicate successfull decoding of PDSCH TB. */ + virtual void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) = 0; + + /* Indicate successfull decoding of BCH TB through PBCH */ + virtual void bch_decoded_ok(uint8_t *payload, uint32_t len) = 0; + + /* Indicate successfull decoding of PCH TB through PDSCH */ + virtual void pch_decoded_ok(uint32_t len) = 0; + + /* Function called every start of a subframe (TTI). Warning, this function is called + * from a high priority thread and should terminate asap + */ + virtual void tti_clock(uint32_t tti) = 0; + +}; + + +/* Interface RRC -> MAC */ +class mac_interface_rrc +{ +public: + + typedef struct { + LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT main; + LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT rach; + LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT sr; + uint32_t prach_config_index; + } mac_cfg_t; + + + // Class to handle UE specific RNTIs between RRC and MAC + typedef struct { + uint16_t crnti; + uint16_t temp_rnti; + uint16_t tpc_rnti; + uint16_t sps_rnti; + uint64_t contention_id; + } ue_rnti_t; + + /* Instructs the MAC to start receiving BCCH */ + virtual void bcch_start_rx() = 0; + virtual void bcch_stop_rx() = 0; + virtual void bcch_start_rx(int si_window_start, int si_window_length) = 0; + + /* Instructs the MAC to start receiving PCCH */ + virtual void pcch_start_rx() = 0; + virtual void pcch_stop_rx() = 0; + + /* RRC configures a logical channel */ + virtual void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD) = 0; + + virtual uint32_t get_current_tti() = 0; + + virtual void set_config(mac_cfg_t *mac_cfg) = 0; + virtual void set_config_main(LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT *main_cfg) = 0; + virtual void set_config_rach(LIBLTE_RRC_RACH_CONFIG_COMMON_STRUCT *rach_cfg, uint32_t prach_config_index) = 0; + virtual void set_config_sr(LIBLTE_RRC_SCHEDULING_REQUEST_CONFIG_STRUCT *sr_cfg) = 0; + virtual void get_config(mac_cfg_t *mac_cfg) = 0; + + virtual void get_rntis(ue_rnti_t *rntis) = 0; + virtual void set_contention_id(uint64_t uecri) = 0; + + + virtual void reconfiguration() = 0; + virtual void reset() = 0; +}; + + + + +/** PHY interface + * + */ + +typedef struct { + bool ul_pwr_ctrl_en; + float prach_gain; + int pdsch_max_its; + bool attach_enable_64qam; + int nof_phy_threads; + + int worker_cpu_mask; + int sync_cpu_affinity; + + uint32_t nof_rx_ant; + std::string equalizer_mode; + int cqi_max; + int cqi_fixed; + float snr_ema_coeff; + std::string snr_estim_alg; + bool cfo_integer_enabled; + float cfo_correct_tol_hz; + int time_correct_period; + bool sfo_correct_disable; + std::string sss_algorithm; + float estimator_fil_w; + bool rssi_sensor_enabled; +} phy_args_t; + +/* Interface MAC -> PHY */ +class phy_interface_mac +{ +public: + /* Configure PRACH using parameters written by RRC */ + virtual void configure_prach_params() = 0; + + /* Start synchronization with strongest cell in the current carrier frequency */ + virtual void sync_start() = 0; + virtual void sync_stop() = 0; + + /* Sets a C-RNTI allowing the PHY to pregenerate signals if necessary */ + virtual void set_crnti(uint16_t rnti) = 0; + + virtual void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm) = 0; + virtual int prach_tx_tti() = 0; + + /* Indicates the transmission of a SR signal in the next opportunity */ + virtual void sr_send() = 0; + virtual int sr_last_tx_tti() = 0; + + /* Time advance commands */ + virtual void set_timeadv_rar(uint32_t ta_cmd) = 0; + virtual void set_timeadv(uint32_t ta_cmd) = 0; + + /* Sets RAR grant payload */ + virtual void set_rar_grant(uint32_t tti, uint8_t grant_payload[SRSLTE_RAR_GRANT_LEN]) = 0; + + /* Instruct the PHY to decode PDCCH with the CRC scrambled with given RNTI */ + virtual void pdcch_ul_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0; + virtual void pdcch_dl_search(srslte_rnti_type_t rnti_type, uint16_t rnti, int tti_start = -1, int tti_end = -1) = 0; + virtual void pdcch_ul_search_reset() = 0; + virtual void pdcch_dl_search_reset() = 0; + + virtual uint32_t get_current_tti() = 0; + + virtual float get_phr() = 0; + virtual float get_pathloss_db() = 0; + +}; + +class phy_interface_rrc +{ +public: + + typedef struct { + LIBLTE_RRC_PRACH_CONFIG_SIB_STRUCT prach_cnfg; + LIBLTE_RRC_PDSCH_CONFIG_COMMON_STRUCT pdsch_cnfg; + LIBLTE_RRC_PUSCH_CONFIG_COMMON_STRUCT pusch_cnfg; + LIBLTE_RRC_PHICH_CONFIG_STRUCT phich_cnfg; + LIBLTE_RRC_PUCCH_CONFIG_COMMON_STRUCT pucch_cnfg; + LIBLTE_RRC_SRS_UL_CONFIG_COMMON_STRUCT srs_ul_cnfg; + LIBLTE_RRC_UL_POWER_CONTROL_COMMON_STRUCT ul_pwr_ctrl; + LIBLTE_RRC_TDD_CONFIG_STRUCT tdd_cnfg; + LIBLTE_RRC_ANTENNA_PORTS_COUNT_ENUM ant_info; + } phy_cfg_common_t; + + typedef struct { + LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT dedicated; + phy_cfg_common_t common; + bool enable_64qam; + } phy_cfg_t; + + virtual void get_current_cell(srslte_cell_t *cell) = 0; + virtual void get_config(phy_cfg_t *phy_cfg) = 0; + virtual void set_config(phy_cfg_t *phy_cfg) = 0; + virtual void set_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated) = 0; + virtual void set_config_common(phy_cfg_common_t *common) = 0; + virtual void set_config_tdd(LIBLTE_RRC_TDD_CONFIG_STRUCT *tdd) = 0; + virtual void set_config_64qam_en(bool enable) = 0; + + /* Is the PHY downlink synchronized? */ + virtual bool status_is_sync() = 0; + + /* Configure UL using parameters written with set_param() */ + virtual void configure_ul_params(bool pregen_disabled = false) = 0; + + virtual void reset() = 0; + + virtual void resync_sfn() = 0; + +}; + + +} // namespace srslte + +#endif // INTERFACES_H diff --git a/lib/include/srslte/upper/gw.h b/lib/include/srslte/upper/gw.h index b74a8fedd..a01413829 100644 --- a/lib/include/srslte/upper/gw.h +++ b/lib/include/srslte/upper/gw.h @@ -31,41 +31,42 @@ #include "srslte/common/log.h" #include "srslte/common/common.h" #include "srslte/common/msg_queue.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/threads.h" #include "srslte/upper/gw_metrics.h" #include -namespace srsue { +namespace srslte { class gw - :public gw_interface_pdcp - ,public gw_interface_nas + :public srsue::gw_interface_pdcp + ,public srsue::gw_interface_nas ,public thread { public: gw(); - void init(pdcp_interface_gw *pdcp_, rrc_interface_gw *rrc_, ue_interface *ue_, srslte::log *gw_log_); + void init(srsue::pdcp_interface_gw *pdcp_, srsue::rrc_interface_gw *rrc_, srsue::ue_interface *ue_, log *gw_log_); void stop(); void get_metrics(gw_metrics_t &m); // PDCP interface - void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu); + void write_pdu(uint32_t lcid, byte_buffer_t *pdu); // NAS interface - srslte::error_t setup_if_addr(uint32_t ip_addr, char *err_str); + error_t setup_if_addr(uint32_t ip_addr, char *err_str); private: static const int GW_THREAD_PRIO = 7; - srslte::byte_buffer_pool *pool; - srslte::log *gw_log; - pdcp_interface_gw *pdcp; - rrc_interface_gw *rrc; - ue_interface *ue; + srsue::pdcp_interface_gw *pdcp; + srsue::rrc_interface_gw *rrc; + srsue::ue_interface *ue; + + byte_buffer_pool *pool; + log *gw_log; bool running; bool run_enable; int32 tun_fd; @@ -78,7 +79,7 @@ private: struct timeval metrics_time[3]; void run_thread(); - srslte::error_t init_if(char *err_str); + error_t init_if(char *err_str); }; } // namespace srsue diff --git a/lib/include/srslte/upper/gw_metrics.h b/lib/include/srslte/upper/gw_metrics.h index e596046c9..b5d8eaf23 100644 --- a/lib/include/srslte/upper/gw_metrics.h +++ b/lib/include/srslte/upper/gw_metrics.h @@ -28,7 +28,7 @@ #define UE_GW_METRICS_H -namespace srsue { +namespace srslte { struct gw_metrics_t { diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index c5a870acb..e1d7b4639 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -29,24 +29,23 @@ #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/upper/pdcp_entity.h" -using srslte::byte_buffer_t; - -namespace srsue { +namespace srslte { class pdcp - :public pdcp_interface_gw - ,public pdcp_interface_rlc - ,public pdcp_interface_rrc + :public srsue::pdcp_interface_gw + ,public srsue::pdcp_interface_rlc + ,public srsue::pdcp_interface_rrc { public: pdcp(); - void init(rlc_interface_pdcp *rlc_, - rrc_interface_pdcp *rrc_, - gw_interface_pdcp *gw_, - srslte::log *pdcp_log_, + virtual ~pdcp(){} + void init(srsue::rlc_interface_pdcp *rlc_, + srsue::rrc_interface_pdcp *rrc_, + srsue::gw_interface_pdcp *gw_, + log *pdcp_log_, uint8_t direction_); void stop(); @@ -67,12 +66,12 @@ public: void write_pdu_pcch(byte_buffer_t *sdu); private: - srslte::log *pdcp_log; + log *pdcp_log; pdcp_entity pdcp_array[SRSUE_N_RADIO_BEARERS]; - rlc_interface_pdcp *rlc; - rrc_interface_pdcp *rrc; - gw_interface_pdcp *gw; + srsue::rlc_interface_pdcp *rlc; + srsue::rrc_interface_pdcp *rrc; + srsue::gw_interface_pdcp *gw; uint8_t direction; diff --git a/lib/include/srslte/upper/pdcp_entity.h b/lib/include/srslte/upper/pdcp_entity.h index 81be91884..2c1c988a0 100644 --- a/lib/include/srslte/upper/pdcp_entity.h +++ b/lib/include/srslte/upper/pdcp_entity.h @@ -30,13 +30,11 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/security.h" -using srslte::byte_buffer_t; - -namespace srsue { +namespace srslte { /**************************************************************************** * Structs and Defines @@ -64,9 +62,9 @@ class pdcp_entity { public: pdcp_entity(); - void init(rlc_interface_pdcp *rlc_, - rrc_interface_pdcp *rrc_, - gw_interface_pdcp *gw_, + void init(srsue::rlc_interface_pdcp *rlc_, + srsue::rrc_interface_pdcp *rrc_, + srsue::gw_interface_pdcp *gw_, srslte::log *log_, uint32_t lcid_, uint8_t direction_, @@ -87,11 +85,12 @@ public: void write_pdu(byte_buffer_t *pdu); private: - srslte::byte_buffer_pool *pool; - srslte::log *log; - rlc_interface_pdcp *rlc; - rrc_interface_pdcp *rrc; - gw_interface_pdcp *gw; + byte_buffer_pool *pool; + srslte::log *log; + + srsue::rlc_interface_pdcp *rlc; + srsue::rrc_interface_pdcp *rrc; + srsue::gw_interface_pdcp *gw; bool active; uint32_t lcid; diff --git a/lib/include/srslte/upper/rlc.h b/lib/include/srslte/upper/rlc.h index 580ba6c0c..780af9c11 100644 --- a/lib/include/srslte/upper/rlc.h +++ b/lib/include/srslte/upper/rlc.h @@ -30,12 +30,12 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/msg_queue.h" #include "srslte/upper/rlc_entity.h" #include "srslte/upper/rlc_metrics.h" -namespace srsue { +namespace srslte { /**************************************************************************** * RLC Layer @@ -44,17 +44,18 @@ namespace srsue { * each bearer. ***************************************************************************/ class rlc - :public rlc_interface_mac - ,public rlc_interface_pdcp - ,public rlc_interface_rrc + :public srsue::rlc_interface_mac + ,public srsue::rlc_interface_pdcp + ,public srsue::rlc_interface_rrc { public: rlc(); - void init(pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - ue_interface *ue_, - srslte::log *rlc_log_, - srslte::mac_interface_timers *mac_timers_); + virtual ~rlc() {} + void init(srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + srsue::ue_interface *ue_, + log *rlc_log_, + mac_interface_timers *mac_timers_); void stop(); void get_metrics(rlc_metrics_t &m); @@ -79,13 +80,13 @@ public: private: void reset_metrics(); - srslte::byte_buffer_pool *pool; - srslte::log *rlc_log; - pdcp_interface_rlc *pdcp; - rrc_interface_rlc *rrc; + byte_buffer_pool *pool; + srslte::log *rlc_log; + srsue::pdcp_interface_rlc *pdcp; + srsue::rrc_interface_rlc *rrc; srslte::mac_interface_timers *mac_timers; - ue_interface *ue; - rlc_entity rlc_array[SRSUE_N_RADIO_BEARERS]; + srsue::ue_interface *ue; + srslte::rlc_entity rlc_array[SRSUE_N_RADIO_BEARERS]; long ul_tput_bytes[SRSUE_N_RADIO_BEARERS]; long dl_tput_bytes[SRSUE_N_RADIO_BEARERS]; diff --git a/lib/include/srslte/upper/rlc_am.h b/lib/include/srslte/upper/rlc_am.h index 8d35c1701..5fcf31c94 100644 --- a/lib/include/srslte/upper/rlc_am.h +++ b/lib/include/srslte/upper/rlc_am.h @@ -30,7 +30,7 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/msg_queue.h" #include "srslte/common/timeout.h" #include "srslte/upper/rlc_common.h" @@ -38,9 +38,7 @@ #include #include -using srslte::byte_buffer_t; - -namespace srsue { +namespace srslte { @@ -73,11 +71,11 @@ class rlc_am { public: rlc_am(); - void init(srslte::log *rlc_entity_log_, + void init(log *rlc_entity_log_, uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - srslte::mac_interface_timers *mac_timers); + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + mac_interface_timers *mac_timers); void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); void reset(); void empty_queue(); @@ -96,14 +94,14 @@ public: private: - srslte::byte_buffer_pool *pool; - srslte::log *log; - uint32_t lcid; - pdcp_interface_rlc *pdcp; - rrc_interface_rlc *rrc; + byte_buffer_pool *pool; + srslte::log *log; + uint32_t lcid; + srsue::pdcp_interface_rlc *pdcp; + srsue::rrc_interface_rlc *rrc; // TX SDU buffers - srslte::msg_queue tx_sdu_queue; + msg_queue tx_sdu_queue; byte_buffer_t *tx_sdu; // PDU being resegmented @@ -166,9 +164,9 @@ private: * Timers * Ref: 3GPP TS 36.322 v10.0.0 Section 7 ***************************************************************************/ - srslte::timeout poll_retx_timeout; - srslte::timeout reordering_timeout; - srslte::timeout status_prohibit_timeout; + timeout poll_retx_timeout; + timeout reordering_timeout; + timeout status_prohibit_timeout; static const int reordering_timeout_id = 1; diff --git a/lib/include/srslte/upper/rlc_common.h b/lib/include/srslte/upper/rlc_common.h index f43973d41..e45901855 100644 --- a/lib/include/srslte/upper/rlc_common.h +++ b/lib/include/srslte/upper/rlc_common.h @@ -27,7 +27,7 @@ #ifndef RLC_COMMON_H #define RLC_COMMON_H -namespace srsue { +namespace srslte { /**************************************************************************** * Structs and Defines @@ -157,11 +157,11 @@ struct rlc_status_pdu_t{ class rlc_common { public: - virtual void init(srslte::log *rlc_entity_log_, - uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - srslte::mac_interface_timers *mac_timers_) = 0; + virtual void init(srslte::log *rlc_entity_log_, + uint32_t lcid_, + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + srslte::mac_interface_timers *mac_timers_) = 0; virtual void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg) = 0; virtual void reset() = 0; virtual void empty_queue() = 0; @@ -170,7 +170,7 @@ public: virtual uint32_t get_bearer() = 0; // PDCP interface - virtual void write_sdu(srslte::byte_buffer_t *sdu) = 0; + virtual void write_sdu(byte_buffer_t *sdu) = 0; // MAC interface virtual uint32_t get_buffer_state() = 0; diff --git a/lib/include/srslte/upper/rlc_entity.h b/lib/include/srslte/upper/rlc_entity.h index 1f0075a35..cf09c19d2 100644 --- a/lib/include/srslte/upper/rlc_entity.h +++ b/lib/include/srslte/upper/rlc_entity.h @@ -29,13 +29,13 @@ #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/upper/rlc_common.h" #include "srslte/upper/rlc_tm.h" #include "srslte/upper/rlc_um.h" #include "srslte/upper/rlc_am.h" -namespace srsue { +namespace srslte { @@ -48,11 +48,11 @@ class rlc_entity public: rlc_entity(); void init(rlc_mode_t mode, - srslte::log *rlc_entity_log_, + log *rlc_entity_log_, uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - srslte::mac_interface_timers *mac_timers_); + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + mac_interface_timers *mac_timers_); void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); void reset(); diff --git a/lib/include/srslte/upper/rlc_metrics.h b/lib/include/srslte/upper/rlc_metrics.h index da31ec287..0089ab5a6 100644 --- a/lib/include/srslte/upper/rlc_metrics.h +++ b/lib/include/srslte/upper/rlc_metrics.h @@ -28,7 +28,7 @@ #define UE_RLC_METRICS_H -namespace srsue { +namespace srslte { struct rlc_metrics_t { diff --git a/lib/include/srslte/upper/rlc_tm.h b/lib/include/srslte/upper/rlc_tm.h index 475380602..d8034cd38 100644 --- a/lib/include/srslte/upper/rlc_tm.h +++ b/lib/include/srslte/upper/rlc_tm.h @@ -30,22 +30,22 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/msg_queue.h" #include "srslte/upper/rlc_common.h" -namespace srsue { +namespace srslte { class rlc_tm :public rlc_common { public: rlc_tm(); - void init(srslte::log *rlc_entity_log_, + void init(log *rlc_entity_log_, uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - srslte::mac_interface_timers *mac_timers); + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + mac_interface_timers *mac_timers); void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); void reset(); void empty_queue(); @@ -54,7 +54,7 @@ public: uint32_t get_bearer(); // PDCP interface - void write_sdu(srslte::byte_buffer_t *sdu); + void write_sdu(byte_buffer_t *sdu); // MAC interface uint32_t get_buffer_state(); @@ -64,14 +64,14 @@ public: private: - srslte::byte_buffer_pool *pool; - srslte::log *log; - uint32_t lcid; - pdcp_interface_rlc *pdcp; - rrc_interface_rlc *rrc; + byte_buffer_pool *pool; + srslte::log *log; + uint32_t lcid; + srsue::pdcp_interface_rlc *pdcp; + srsue::rrc_interface_rlc *rrc; // Thread-safe queues for MAC messages - srslte::msg_queue ul_queue; + msg_queue ul_queue; }; } // namespace srsue diff --git a/lib/include/srslte/upper/rlc_um.h b/lib/include/srslte/upper/rlc_um.h index d42c4088d..8e95dcb71 100644 --- a/lib/include/srslte/upper/rlc_um.h +++ b/lib/include/srslte/upper/rlc_um.h @@ -30,32 +30,32 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/msg_queue.h" #include "srslte/upper/rlc_common.h" #include #include #include -namespace srsue { +namespace srslte { struct rlc_umd_pdu_t{ rlc_umd_pdu_header_t header; - srslte::byte_buffer_t *buf; + byte_buffer_t *buf; }; class rlc_um - :public srslte::timer_callback + :public timer_callback ,public rlc_common { public: rlc_um(); - void init(srslte::log *rlc_entity_log_, + void init(log *rlc_entity_log_, uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - srslte::mac_interface_timers *mac_timers_); + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + mac_interface_timers *mac_timers_); void configure(LIBLTE_RRC_RLC_CONFIG_STRUCT *cnfg); void reset(); void empty_queue(); @@ -64,7 +64,7 @@ public: uint32_t get_bearer(); // PDCP interface - void write_sdu(srslte::byte_buffer_t *sdu); + void write_sdu(byte_buffer_t *sdu); // MAC interface uint32_t get_buffer_state(); @@ -79,16 +79,16 @@ public: private: - srslte::byte_buffer_pool *pool; - srslte::log *log; - uint32_t lcid; - pdcp_interface_rlc *pdcp; - rrc_interface_rlc *rrc; - srslte::mac_interface_timers *mac_timers; + byte_buffer_pool *pool; + srslte::log *log; + uint32_t lcid; + srsue::pdcp_interface_rlc *pdcp; + srsue::rrc_interface_rlc *rrc; + mac_interface_timers *mac_timers; // TX SDU buffers - srslte::msg_queue tx_sdu_queue; - srslte::byte_buffer_t *tx_sdu; + msg_queue tx_sdu_queue; + byte_buffer_t *tx_sdu; // Rx window std::map rx_window; @@ -97,7 +97,7 @@ private: uint32_t tx_mod; // Tx counter modulus // RX SDU buffers - srslte::byte_buffer_t *rx_sdu; + byte_buffer_t *rx_sdu; uint32_t vr_ur_in_rx_sdu; // Mutexes @@ -144,9 +144,9 @@ private: * Header pack/unpack helper functions * Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1 ***************************************************************************/ -void rlc_um_read_data_pdu_header(srslte::byte_buffer_t *pdu, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t *header); +void rlc_um_read_data_pdu_header(byte_buffer_t *pdu, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t *header); void rlc_um_read_data_pdu_header(uint8_t *payload, uint32_t nof_bytes, rlc_umd_sn_size_t sn_size, rlc_umd_pdu_header_t *header); -void rlc_um_write_data_pdu_header(rlc_umd_pdu_header_t *header, srslte::byte_buffer_t *pdu); +void rlc_um_write_data_pdu_header(rlc_umd_pdu_header_t *header, byte_buffer_t *pdu); uint32_t rlc_um_packed_length(rlc_umd_pdu_header_t *header); bool rlc_um_start_aligned(uint8_t fi); diff --git a/lib/src/asn1/CMakeLists.txt b/lib/src/asn1/CMakeLists.txt index f6ad59a94..aeed84602 100644 --- a/lib/src/asn1/CMakeLists.txt +++ b/lib/src/asn1/CMakeLists.txt @@ -23,5 +23,6 @@ add_library(srslte_asn1 SHARED liblte_common.cc liblte_rrc.cc liblte_mme.cc + liblte_s1ap.cc ) -install(TARGETS srslte_asn1 DESTINATION ${LIBRARY_DIR}) \ No newline at end of file +install(TARGETS srslte_asn1 DESTINATION ${LIBRARY_DIR}) diff --git a/lib/src/asn1/liblte_s1ap.cc b/lib/src/asn1/liblte_s1ap.cc new file mode 100644 index 000000000..31c7391ab --- /dev/null +++ b/lib/src/asn1/liblte_s1ap.cc @@ -0,0 +1,44052 @@ +/******************************************************************************* +/* +/* Copyright 2016 Software Radio Systems Limited +/* +********************************************************************************/ + +#include "srslte/asn1/liblte_s1ap.h" +# include +# include +# include + +/******************************************************************************* + LOGGING +*******************************************************************************/ + +static log_handler_t log_handler; +static void *callback_ctx = NULL; + +void liblte_log_register_handler(void *ctx, log_handler_t handler) { + log_handler = handler; + callback_ctx = ctx; +} + +static void liblte_log_print(const char *format, ...) { + va_list args; + va_start(args, format); + if (log_handler) { + char *args_msg = NULL; + if(vasprintf(&args_msg, format, args) > 0) { + log_handler(callback_ctx, args_msg); + } + if (args_msg) { + free(args_msg); + } + } else { + vprintf(format, args); + } + va_end(args); +} + +/******************************************************************************* +/* ProtocolIE Criticality ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticality( + LIBLTE_S1AP_CRITICALITY_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 2); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticality( + uint8_t **ptr, + LIBLTE_S1AP_CRITICALITY_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* ProtocolIE local INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_local( + LIBLTE_S1AP_LOCAL_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->local + // lb:0, ub:65535 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (2*8)-16); + liblte_value_2_bits(ie->local, ptr, 16); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_local( + uint8_t **ptr, + LIBLTE_S1AP_LOCAL_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->local + // lb:0, ub:65535 + liblte_align_up(ptr, 8); + ie->local = (uint16_t)liblte_bits_2_value(ptr, 2.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* ProtocolIE PrivateIE_ID CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privateie_id( + LIBLTE_S1AP_PRIVATEIE_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_LOCAL) { + if(liblte_s1ap_pack_local(&ie->choice.local, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_GLOBAL) { + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privateie_id( + uint8_t **ptr, + LIBLTE_S1AP_PRIVATEIE_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Choice type + ie->choice_type = (LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_ENUM)liblte_bits_2_value(ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_LOCAL) { + if(liblte_s1ap_unpack_local(ptr, &ie->choice.local) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_PRIVATEIE_ID_CHOICE_GLOBAL) { + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolExtensionID INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolextensionid( + LIBLTE_S1AP_PROTOCOLEXTENSIONID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ProtocolExtensionID + // lb:0, ub:65535 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (2*8)-16); + liblte_value_2_bits(ie->ProtocolExtensionID, ptr, 16); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolextensionid( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLEXTENSIONID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ProtocolExtensionID + // lb:0, ub:65535 + liblte_align_up(ptr, 8); + ie->ProtocolExtensionID = (uint16_t)liblte_bits_2_value(ptr, 2.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TriggeringMessage ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_triggeringmessage( + LIBLTE_S1AP_TRIGGERINGMESSAGE_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 2); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_triggeringmessage( + uint8_t **ptr, + LIBLTE_S1AP_TRIGGERINGMESSAGE_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_TRIGGERINGMESSAGE_ENUM)liblte_bits_2_value(ptr, 2); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Presence ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_presence( + LIBLTE_S1AP_PRESENCE_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 2); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_presence( + uint8_t **ptr, + LIBLTE_S1AP_PRESENCE_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_PRESENCE_ENUM)liblte_bits_2_value(ptr, 2); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolIE_ID INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_id( + LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ProtocolIE_ID + // lb:0, ub:65535 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (2*8)-16); + liblte_value_2_bits(ie->ProtocolIE_ID, ptr, 16); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_id( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ProtocolIE_ID + // lb:0, ub:65535 + liblte_align_up(ptr, 8); + ie->ProtocolIE_ID = (uint16_t)liblte_bits_2_value(ptr, 2.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProcedureCode INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_procedurecode( + LIBLTE_S1AP_PROCEDURECODE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ProcedureCode + // lb:0, ub:255 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-8); + liblte_value_2_bits(ie->ProcedureCode, ptr, 8); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_procedurecode( + uint8_t **ptr, + LIBLTE_S1AP_PROCEDURECODE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ProcedureCode + // lb:0, ub:255 + liblte_align_up(ptr, 8); + ie->ProcedureCode = (uint8_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolIE_Field SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_field( + LIBLTE_S1AP_PROTOCOLIE_FIELD_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_pack_protocolie_id(&ie->id, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum - ie->criticality + liblte_value_2_bits(ie->criticality, ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_field( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_FIELD_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_unpack_protocolie_id(ptr, &ie->id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum - ie->criticality + ie->criticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolExtensionField SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolextensionfield( + LIBLTE_S1AP_PROTOCOLEXTENSIONFIELD_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_pack_protocolextensionid(&ie->id, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum - ie->criticality + liblte_value_2_bits(ie->criticality, ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolextensionfield( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLEXTENSIONFIELD_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_unpack_protocolextensionid(ptr, &ie->id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum - ie->criticality + ie->criticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolIE_FieldPair SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_fieldpair( + LIBLTE_S1AP_PROTOCOLIE_FIELDPAIR_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_pack_protocolie_id(&ie->id, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum - ie->firstCriticality + liblte_value_2_bits(ie->firstCriticality, ptr, 2); + + + // Enum - ie->secondCriticality + liblte_value_2_bits(ie->secondCriticality, ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_fieldpair( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_FIELDPAIR_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_unpack_protocolie_id(ptr, &ie->id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum - ie->firstCriticality + ie->firstCriticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + + + // Enum - ie->secondCriticality + ie->secondCriticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolExtensionContainer DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolextensioncontainer( + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ProtocolExtensionContainer pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_protocolextensionfield(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolextensioncontainer( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLEXTENSIONCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ProtocolExtensionContainer unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolextensionfield(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolIE_ContainerPair DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:0, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_containerpair( + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIR_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ProtocolIE_ContainerPair pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-0, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_protocolie_fieldpair(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_containerpair( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIR_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 0; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ProtocolIE_ContainerPair unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_fieldpair(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolIE_ContainerPairList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:None, ub:None +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_containerpairlist( + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIRLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ProtocolIE_ContainerPairList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + if(ie->len < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->len, ptr, 7); + } else if(ie->len < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->len, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of bits + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_protocolie_containerpair(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_containerpairlist( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_CONTAINERPAIRLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->len = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->len = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of bits + } + } + if(ie->len > 32) { + liblte_log_print("ProtocolIE_ContainerPairList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_containerpair(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PrivateIE_Field SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privateie_field( + LIBLTE_S1AP_PRIVATEIE_FIELD_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_pack_privateie_id(&ie->id, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum - ie->criticality + liblte_value_2_bits(ie->criticality, ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privateie_field( + uint8_t **ptr, + LIBLTE_S1AP_PRIVATEIE_FIELD_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_unpack_privateie_id(ptr, &ie->id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum - ie->criticality + ie->criticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ProtocolIE_SingleContainer SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_singlecontainer( + LIBLTE_S1AP_PROTOCOLIE_SINGLECONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_pack_protocolie_id(&ie->id, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum - ie->criticality + liblte_value_2_bits(ie->criticality, ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_singlecontainer( + uint8_t **ptr, + LIBLTE_S1AP_PROTOCOLIE_SINGLECONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + + if(liblte_s1ap_unpack_protocolie_id(ptr, &ie->id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum - ie->criticality + ie->criticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PrivateIE_Container DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privateie_container( + LIBLTE_S1AP_PRIVATEIE_CONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("PrivateIE_Container pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_privateie_field(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privateie_container( + uint8_t **ptr, + LIBLTE_S1AP_PRIVATEIE_CONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("PrivateIE_Container unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_privateie_field(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE BitRate INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bitrate( + LIBLTE_S1AP_BITRATE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->BitRate + // lb:0, ub:10000000000 + // Range > 65536 - encoded based on value + { + uint32_t n_bits = floor(log2(ie->BitRate-0)+1); + uint32_t n_octets = (n_bits+7)/8; + liblte_value_2_bits(n_octets-1, ptr, 3); + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (n_octets*8)-n_bits); + liblte_value_2_bits(ie->BitRate-0, ptr, n_bits); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bitrate( + uint8_t **ptr, + LIBLTE_S1AP_BITRATE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->BitRate + // lb:0, ub:10000000000 + // Range > 65536 - encoded based on value + { + uint32_t n_octets = liblte_bits_2_value(ptr, 3) + 1; + liblte_align_up(ptr, 8); + ie->BitRate = liblte_bits_2_value(ptr, n_octets*8) + 0; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CauseMisc ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causemisc( + LIBLTE_S1AP_CAUSEMISC_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CauseMisc error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causemisc( + uint8_t **ptr, + LIBLTE_S1AP_CAUSEMISC_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CauseMisc error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CAUSEMISC_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CauseRadioNetwork ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causeradionetwork( + LIBLTE_S1AP_CAUSERADIONETWORK_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CauseRadioNetwork error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 6); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causeradionetwork( + uint8_t **ptr, + LIBLTE_S1AP_CAUSERADIONETWORK_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CauseRadioNetwork error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CAUSERADIONETWORK_ENUM)liblte_bits_2_value(ptr, 6); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CauseNas ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causenas( + LIBLTE_S1AP_CAUSENAS_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CauseNas error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causenas( + uint8_t **ptr, + LIBLTE_S1AP_CAUSENAS_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CauseNas error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CAUSENAS_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellIdentity STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellidentity( + LIBLTE_S1AP_CELLIDENTITY_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - CellIdentity + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellidentity( + uint8_t **ptr, + LIBLTE_S1AP_CELLIDENTITY_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - CellIdentity + liblte_align_up(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000PDU DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000pdu( + LIBLTE_S1AP_CDMA2000PDU_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000PDU + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000pdu( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000PDU_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000PDU + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000SectorID DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000sectorid( + LIBLTE_S1AP_CDMA2000SECTORID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000SectorID + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000sectorid( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000SECTORID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000SectorID + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000HORequiredIndication ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000horequiredindication( + LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Cdma2000HORequiredIndication error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000horequiredindication( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Cdma2000HORequiredIndication error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CDMA2000HOREQUIREDINDICATION_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXMSI DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexmsi( + LIBLTE_S1AP_CDMA2000ONEXMSI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000OneXMSI + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexmsi( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXMSI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000OneXMSI + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXRAND DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexrand( + LIBLTE_S1AP_CDMA2000ONEXRAND_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000OneXRAND + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexrand( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXRAND_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000OneXRAND + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CNDomain ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cndomain( + LIBLTE_S1AP_CNDOMAIN_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 1); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cndomain( + uint8_t **ptr, + LIBLTE_S1AP_CNDOMAIN_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_CNDOMAIN_ENUM)liblte_bits_2_value(ptr, 1); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Correlation_ID STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_correlation_id( + LIBLTE_S1AP_CORRELATION_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - Correlation-ID + if(LIBLTE_S1AP_CORRELATION_ID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_correlation_id( + uint8_t **ptr, + LIBLTE_S1AP_CORRELATION_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - Correlation-ID + if(LIBLTE_S1AP_CORRELATION_ID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE AdditionalCSFallbackIndicator ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_additionalcsfallbackindicator( + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("AdditionalCSFallbackIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_additionalcsfallbackindicator( + uint8_t **ptr, + LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("AdditionalCSFallbackIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_ADDITIONALCSFALLBACKINDICATOR_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE DL_Forwarding ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_dl_forwarding( + LIBLTE_S1AP_DL_FORWARDING_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("DL_Forwarding error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_dl_forwarding( + uint8_t **ptr, + LIBLTE_S1AP_DL_FORWARDING_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("DL_Forwarding error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_DL_FORWARDING_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Data_Forwarding_Not_Possible ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_data_forwarding_not_possible( + LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Data_Forwarding_Not_Possible error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_data_forwarding_not_possible( + uint8_t **ptr, + LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Data_Forwarding_Not_Possible error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_DATA_FORWARDING_NOT_POSSIBLE_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid( + LIBLTE_S1AP_EMERGENCYAREAID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - EmergencyAreaID + if(LIBLTE_S1AP_EMERGENCYAREAID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - EmergencyAreaID + if(LIBLTE_S1AP_EMERGENCYAREAID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* ProtocolIE macroENB_ID STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_macroenb_id( + LIBLTE_S1AP_MACROENB_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - macroENB-ID + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_macroenb_id( + uint8_t **ptr, + LIBLTE_S1AP_MACROENB_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - macroENB-ID + liblte_align_up(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + + + +/******************************************************************************* +/* ProtocolIE homeENB_ID STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_homeenb_id( + LIBLTE_S1AP_HOMEENB_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - homeENB-ID + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_homeenb_id( + uint8_t **ptr, + LIBLTE_S1AP_HOMEENB_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - homeENB-ID + liblte_align_up(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* ProtocolIE ENB_ID CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_id( + LIBLTE_S1AP_ENB_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ENB_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_ENB_ID_CHOICE_MACROENB_ID) { + if(liblte_s1ap_pack_macroenb_id(&ie->choice.macroENB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_ENB_ID_CHOICE_HOMEENB_ID) { + if(liblte_s1ap_pack_homeenb_id(&ie->choice.homeENB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_id( + uint8_t **ptr, + LIBLTE_S1AP_ENB_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ENB_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_ENB_ID_CHOICE_ENUM)liblte_bits_2_value(ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_ENB_ID_CHOICE_MACROENB_ID) { + if(liblte_s1ap_unpack_macroenb_id(ptr, &ie->choice.macroENB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_ENB_ID_CHOICE_HOMEENB_ID) { + if(liblte_s1ap_unpack_homeenb_id(ptr, &ie->choice.homeENB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ENBname PrintableString +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbname( + LIBLTE_S1AP_ENBNAME_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Printable string - ENBname + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ENBname error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Length + liblte_value_2_bits(ie->n_octets-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbname( + uint8_t **ptr, + LIBLTE_S1AP_ENBNAME_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Printable string - ENBname + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ENBname error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Length + ie->n_octets = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EncryptionAlgorithms STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_encryptionalgorithms( + LIBLTE_S1AP_ENCRYPTIONALGORITHMS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - EncryptionAlgorithms + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("EncryptionAlgorithms error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_encryptionalgorithms( + uint8_t **ptr, + LIBLTE_S1AP_ENCRYPTIONALGORITHMS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - EncryptionAlgorithms + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("EncryptionAlgorithms error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EventType ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eventtype( + LIBLTE_S1AP_EVENTTYPE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("EventType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 2); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eventtype( + uint8_t **ptr, + LIBLTE_S1AP_EVENTTYPE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("EventType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_EVENTTYPE_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ExtendedRNC_ID INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_extendedrnc_id( + LIBLTE_S1AP_EXTENDEDRNC_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ExtendedRNC_ID + // lb:4096, ub:65535 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (2*8)-16); + liblte_value_2_bits(ie->ExtendedRNC_ID, ptr, 16); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_extendedrnc_id( + uint8_t **ptr, + LIBLTE_S1AP_EXTENDEDRNC_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ExtendedRNC_ID + // lb:4096, ub:65535 + liblte_align_up(ptr, 8); + ie->ExtendedRNC_ID = (uint16_t)liblte_bits_2_value(ptr, 2.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ForbiddenInterRATs ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddeninterrats( + LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ForbiddenInterRATs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddeninterrats( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ForbiddenInterRATs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_FORBIDDENINTERRATS_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE GWContextReleaseIndication ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gwcontextreleaseindication( + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("GWContextReleaseIndication error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gwcontextreleaseindication( + uint8_t **ptr, + LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("GWContextReleaseIndication error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_GWCONTEXTRELEASEINDICATION_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE HFN INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_hfn( + LIBLTE_S1AP_HFN_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->HFN + // lb:0, ub:1048575 + // Range > 65536 - encoded based on value + { + uint32_t n_bits = floor(log2(ie->HFN-0)+1); + uint32_t n_octets = (n_bits+7)/8; + liblte_value_2_bits(n_octets-1, ptr, 2); + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (n_octets*8)-n_bits); + liblte_value_2_bits(ie->HFN-0, ptr, n_bits); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_hfn( + uint8_t **ptr, + LIBLTE_S1AP_HFN_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->HFN + // lb:0, ub:1048575 + // Range > 65536 - encoded based on value + { + uint32_t n_octets = liblte_bits_2_value(ptr, 2) + 1; + liblte_align_up(ptr, 8); + ie->HFN = liblte_bits_2_value(ptr, n_octets*8) + 0; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE IMSI DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_imsi( + LIBLTE_S1AP_IMSI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - IMSI + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_imsi( + uint8_t **ptr, + LIBLTE_S1AP_IMSI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - IMSI + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE InterfacesToTrace STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_interfacestotrace( + LIBLTE_S1AP_INTERFACESTOTRACE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - InterfacesToTrace + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_interfacestotrace( + uint8_t **ptr, + LIBLTE_S1AP_INTERFACESTOTRACE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - InterfacesToTrace + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LAC STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lac( + LIBLTE_S1AP_LAC_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - LAC + if(LIBLTE_S1AP_LAC_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lac( + uint8_t **ptr, + LIBLTE_S1AP_LAC_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - LAC + if(LIBLTE_S1AP_LAC_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LastVisitedUTRANCellInformation DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedutrancellinformation( + LIBLTE_S1AP_LASTVISITEDUTRANCELLINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - LastVisitedUTRANCellInformation + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedutrancellinformation( + uint8_t **ptr, + LIBLTE_S1AP_LASTVISITEDUTRANCELLINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - LastVisitedUTRANCellInformation + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE L3_Information DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_l3_information( + LIBLTE_S1AP_L3_INFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - L3-Information + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_l3_information( + uint8_t **ptr, + LIBLTE_S1AP_L3_INFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - L3-Information + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LHN_ID DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lhn_id( + LIBLTE_S1AP_LHN_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - LHN-ID + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lhn_id( + uint8_t **ptr, + LIBLTE_S1AP_LHN_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - LHN-ID + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LoggingDuration ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_loggingduration( + LIBLTE_S1AP_LOGGINGDURATION_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 3); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_loggingduration( + uint8_t **ptr, + LIBLTE_S1AP_LOGGINGDURATION_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_LOGGINGDURATION_ENUM)liblte_bits_2_value(ptr, 3); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MDT_Activation ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdt_activation( + LIBLTE_S1AP_MDT_ACTIVATION_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("MDT_Activation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 2); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdt_activation( + uint8_t **ptr, + LIBLTE_S1AP_MDT_ACTIVATION_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("MDT_Activation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_MDT_ACTIVATION_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ManagementBasedMDTAllowed ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_managementbasedmdtallowed( + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ManagementBasedMDTAllowed error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_managementbasedmdtallowed( + uint8_t **ptr, + LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ManagementBasedMDTAllowed error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_MANAGEMENTBASEDMDTALLOWED_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PrivacyIndicator ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privacyindicator( + LIBLTE_S1AP_PRIVACYINDICATOR_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("PrivacyIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privacyindicator( + uint8_t **ptr, + LIBLTE_S1AP_PRIVACYINDICATOR_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("PrivacyIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_PRIVACYINDICATOR_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MeasurementsToActivate STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_measurementstoactivate( + LIBLTE_S1AP_MEASUREMENTSTOACTIVATE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - MeasurementsToActivate + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_measurementstoactivate( + uint8_t **ptr, + LIBLTE_S1AP_MEASUREMENTSTOACTIVATE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - MeasurementsToActivate + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MessageIdentifier STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_messageidentifier( + LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - MessageIdentifier + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_messageidentifier( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGEIDENTIFIER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - MessageIdentifier + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MMEname PrintableString +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmename( + LIBLTE_S1AP_MMENAME_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Printable string - MMEname + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("MMEname error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Length + liblte_value_2_bits(ie->n_octets-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmename( + uint8_t **ptr, + LIBLTE_S1AP_MMENAME_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Printable string - MMEname + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("MMEname error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Length + ie->n_octets = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MME_Group_ID STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mme_group_id( + LIBLTE_S1AP_MME_GROUP_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - MME-Group-ID + if(LIBLTE_S1AP_MME_GROUP_ID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mme_group_id( + uint8_t **ptr, + LIBLTE_S1AP_MME_GROUP_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - MME-Group-ID + if(LIBLTE_S1AP_MME_GROUP_ID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MME_UE_S1AP_ID INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mme_ue_s1ap_id( + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->MME_UE_S1AP_ID + // lb:0, ub:4294967295 + // Range > 65536 - encoded based on value + { + uint32_t n_bits = floor(log2(ie->MME_UE_S1AP_ID-0)+1); + uint32_t n_octets = (n_bits+7)/8; + liblte_value_2_bits(n_octets-1, ptr, 2); + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (n_octets*8)-n_bits); + liblte_value_2_bits(ie->MME_UE_S1AP_ID-0, ptr, n_bits); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mme_ue_s1ap_id( + uint8_t **ptr, + LIBLTE_S1AP_MME_UE_S1AP_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->MME_UE_S1AP_ID + // lb:0, ub:4294967295 + // Range > 65536 - encoded based on value + { + uint32_t n_octets = liblte_bits_2_value(ptr, 2) + 1; + liblte_align_up(ptr, 8); + ie->MME_UE_S1AP_ID = liblte_bits_2_value(ptr, n_octets*8) + 0; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MSClassmark2 DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_msclassmark2( + LIBLTE_S1AP_MSCLASSMARK2_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - MSClassmark2 + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_msclassmark2( + uint8_t **ptr, + LIBLTE_S1AP_MSCLASSMARK2_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - MSClassmark2 + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE NAS_PDU DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nas_pdu( + LIBLTE_S1AP_NAS_PDU_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - NAS-PDU + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nas_pdu( + uint8_t **ptr, + LIBLTE_S1AP_NAS_PDU_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - NAS-PDU + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE NASSecurityParameterstoE_UTRAN DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nassecurityparameterstoe_utran( + LIBLTE_S1AP_NASSECURITYPARAMETERSTOE_UTRAN_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - NASSecurityParameterstoE-UTRAN + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nassecurityparameterstoe_utran( + uint8_t **ptr, + LIBLTE_S1AP_NASSECURITYPARAMETERSTOE_UTRAN_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - NASSecurityParameterstoE-UTRAN + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE NumberOfBroadcasts INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_numberofbroadcasts( + LIBLTE_S1AP_NUMBEROFBROADCASTS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->NumberOfBroadcasts + // lb:0, ub:65535 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (2*8)-16); + liblte_value_2_bits(ie->NumberOfBroadcasts, ptr, 16); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_numberofbroadcasts( + uint8_t **ptr, + LIBLTE_S1AP_NUMBEROFBROADCASTS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->NumberOfBroadcasts + // lb:0, ub:65535 + liblte_align_up(ptr, 8); + ie->NumberOfBroadcasts = (uint16_t)liblte_bits_2_value(ptr, 2.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE OverloadAction ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_overloadaction( + LIBLTE_S1AP_OVERLOADACTION_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("OverloadAction error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_overloadaction( + uint8_t **ptr, + LIBLTE_S1AP_OVERLOADACTION_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("OverloadAction error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_OVERLOADACTION_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PagingDRX ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pagingdrx( + LIBLTE_S1AP_PAGINGDRX_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("PagingDRX error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 2); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pagingdrx( + uint8_t **ptr, + LIBLTE_S1AP_PAGINGDRX_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("PagingDRX error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_PAGINGDRX_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PDCP_SN INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pdcp_sn( + LIBLTE_S1AP_PDCP_SN_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->PDCP_SN + // lb:0, ub:4095 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-12); + liblte_value_2_bits(ie->PDCP_SN, ptr, 12); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pdcp_sn( + uint8_t **ptr, + LIBLTE_S1AP_PDCP_SN_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->PDCP_SN + // lb:0, ub:4095 + liblte_align_up(ptr, 8); + ie->PDCP_SN = (uint16_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Port_Number STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_port_number( + LIBLTE_S1AP_PORT_NUMBER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - Port-Number + if(LIBLTE_S1AP_PORT_NUMBER_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_port_number( + uint8_t **ptr, + LIBLTE_S1AP_PORT_NUMBER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - Port-Number + if(LIBLTE_S1AP_PORT_NUMBER_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Pre_emptionVulnerability ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pre_emptionvulnerability( + LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 1); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pre_emptionvulnerability( + uint8_t **ptr, + LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM)liblte_bits_2_value(ptr, 1); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PS_ServiceNotAvailable ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ps_servicenotavailable( + LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("PS_ServiceNotAvailable error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ps_servicenotavailable( + uint8_t **ptr, + LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("PS_ServiceNotAvailable error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_PS_SERVICENOTAVAILABLE_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ReceiveStatusofULPDCPSDUs STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_receivestatusofulpdcpsdus( + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - ReceiveStatusofULPDCPSDUs + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_receivestatusofulpdcpsdus( + uint8_t **ptr, + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - ReceiveStatusofULPDCPSDUs + liblte_align_up(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RelativeMMECapacity INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_relativemmecapacity( + LIBLTE_S1AP_RELATIVEMMECAPACITY_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->RelativeMMECapacity + // lb:0, ub:255 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-8); + liblte_value_2_bits(ie->RelativeMMECapacity, ptr, 8); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_relativemmecapacity( + uint8_t **ptr, + LIBLTE_S1AP_RELATIVEMMECAPACITY_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->RelativeMMECapacity + // lb:0, ub:255 + liblte_align_up(ptr, 8); + ie->RelativeMMECapacity = (uint8_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RAC STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rac( + LIBLTE_S1AP_RAC_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - RAC + if(LIBLTE_S1AP_RAC_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rac( + uint8_t **ptr, + LIBLTE_S1AP_RAC_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - RAC + if(LIBLTE_S1AP_RAC_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ReportIntervalMDT ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_reportintervalmdt( + LIBLTE_S1AP_REPORTINTERVALMDT_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 4); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_reportintervalmdt( + uint8_t **ptr, + LIBLTE_S1AP_REPORTINTERVALMDT_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_REPORTINTERVALMDT_ENUM)liblte_bits_2_value(ptr, 4); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ReportArea ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_reportarea( + LIBLTE_S1AP_REPORTAREA_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ReportArea error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_reportarea( + uint8_t **ptr, + LIBLTE_S1AP_REPORTAREA_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ReportArea error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_REPORTAREA_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RNC_ID INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rnc_id( + LIBLTE_S1AP_RNC_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->RNC_ID + // lb:0, ub:4095 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-12); + liblte_value_2_bits(ie->RNC_ID, ptr, 12); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rnc_id( + uint8_t **ptr, + LIBLTE_S1AP_RNC_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->RNC_ID + // lb:0, ub:4095 + liblte_align_up(ptr, 8); + ie->RNC_ID = (uint16_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RRC_Establishment_Cause ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rrc_establishment_cause( + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("RRC_Establishment_Cause error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rrc_establishment_cause( + uint8_t **ptr, + LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("RRC_Establishment_Cause error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_RRC_ESTABLISHMENT_CAUSE_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Routing_ID INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_routing_id( + LIBLTE_S1AP_ROUTING_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Routing_ID + // lb:0, ub:255 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-8); + liblte_value_2_bits(ie->Routing_ID, ptr, 8); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_routing_id( + uint8_t **ptr, + LIBLTE_S1AP_ROUTING_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Routing_ID + // lb:0, ub:255 + liblte_align_up(ptr, 8); + ie->Routing_ID = (uint8_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SONInformationRequest ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_soninformationrequest( + LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SONInformationRequest error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformationrequest( + uint8_t **ptr, + LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SONInformationRequest error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_SONINFORMATIONREQUEST_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Source_ToTarget_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_source_totarget_transparentcontainer( + LIBLTE_S1AP_SOURCE_TOTARGET_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Source-ToTarget-TransparentContainer + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_source_totarget_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_SOURCE_TOTARGET_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Source-ToTarget-TransparentContainer + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SRVCCHOIndication ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_srvcchoindication( + LIBLTE_S1AP_SRVCCHOINDICATION_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SRVCCHOIndication error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_srvcchoindication( + uint8_t **ptr, + LIBLTE_S1AP_SRVCCHOINDICATION_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SRVCCHOIndication error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_SRVCCHOINDICATION_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SourceRNC_ToTargetRNC_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourcernc_totargetrnc_transparentcontainer( + LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - SourceRNC-ToTargetRNC-TransparentContainer + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourcernc_totargetrnc_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_SOURCERNC_TOTARGETRNC_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - SourceRNC-ToTargetRNC-TransparentContainer + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SubscriberProfileIDforRFP INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_subscriberprofileidforrfp( + LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->SubscriberProfileIDforRFP + // lb:1, ub:256 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-8); + liblte_value_2_bits(ie->SubscriberProfileIDforRFP, ptr, 8); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_subscriberprofileidforrfp( + uint8_t **ptr, + LIBLTE_S1AP_SUBSCRIBERPROFILEIDFORRFP_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->SubscriberProfileIDforRFP + // lb:1, ub:256 + liblte_align_up(ptr, 8); + ie->SubscriberProfileIDforRFP = (uint8_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SynchronizationStatus ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_synchronizationstatus( + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SynchronizationStatus error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_synchronizationstatus( + uint8_t **ptr, + LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SynchronizationStatus error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_SYNCHRONIZATIONSTATUS_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TargetRNC_ToSourceRNC_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetrnc_tosourcernc_transparentcontainer( + LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - TargetRNC-ToSourceRNC-TransparentContainer + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetrnc_tosourcernc_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_TARGETRNC_TOSOURCERNC_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - TargetRNC-ToSourceRNC-TransparentContainer + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Threshold_RSRQ INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_threshold_rsrq( + LIBLTE_S1AP_THRESHOLD_RSRQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Threshold_RSRQ + // lb:0, ub:34 + liblte_value_2_bits(ie->Threshold_RSRQ, ptr, 6); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_threshold_rsrq( + uint8_t **ptr, + LIBLTE_S1AP_THRESHOLD_RSRQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Threshold_RSRQ + // lb:0, ub:34 + ie->Threshold_RSRQ = (uint8_t)liblte_bits_2_value(ptr, 6); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Time_UE_StayedInCell INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_time_ue_stayedincell( + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Time_UE_StayedInCell + // lb:0, ub:4095 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-12); + liblte_value_2_bits(ie->Time_UE_StayedInCell, ptr, 12); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_time_ue_stayedincell( + uint8_t **ptr, + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Time_UE_StayedInCell + // lb:0, ub:4095 + liblte_align_up(ptr, 8); + ie->Time_UE_StayedInCell = (uint16_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TransportLayerAddress DYNAMIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_transportlayeraddress( + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic bit string - TransportLayerAddress + // lb:1, ub:160 + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TransportLayerAddress error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Length + liblte_value_2_bits(ie->n_bits-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Bits + uint32_t i; + for(i=0;in_bits;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_transportlayeraddress( + uint8_t **ptr, + LIBLTE_S1AP_TRANSPORTLAYERADDRESS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic bit string - TransportLayerAddress + // lb:1, ub:160 + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TransportLayerAddress error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Length + ie->n_bits = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + + // Bits + uint32_t i; + for(i=0;in_bits;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TraceDepth ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tracedepth( + LIBLTE_S1AP_TRACEDEPTH_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TraceDepth error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tracedepth( + uint8_t **ptr, + LIBLTE_S1AP_TRACEDEPTH_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TraceDepth error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_TRACEDEPTH_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TrafficLoadReductionIndication INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_trafficloadreductionindication( + LIBLTE_S1AP_TRAFFICLOADREDUCTIONINDICATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->TrafficLoadReductionIndication + // lb:1, ub:99 + liblte_value_2_bits(ie->TrafficLoadReductionIndication, ptr, 7); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_trafficloadreductionindication( + uint8_t **ptr, + LIBLTE_S1AP_TRAFFICLOADREDUCTIONINDICATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->TrafficLoadReductionIndication + // lb:1, ub:99 + ie->TrafficLoadReductionIndication = (uint8_t)liblte_bits_2_value(ptr, 7); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UERadioCapability DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueradiocapability( + LIBLTE_S1AP_UERADIOCAPABILITY_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - UERadioCapability + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueradiocapability( + uint8_t **ptr, + LIBLTE_S1AP_UERADIOCAPABILITY_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - UERadioCapability + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE WarningType STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_warningtype( + LIBLTE_S1AP_WARNINGTYPE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - WarningType + if(LIBLTE_S1AP_WARNINGTYPE_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_warningtype( + uint8_t **ptr, + LIBLTE_S1AP_WARNINGTYPE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - WarningType + if(LIBLTE_S1AP_WARNINGTYPE_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE WarningMessageContents DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_warningmessagecontents( + LIBLTE_S1AP_WARNINGMESSAGECONTENTS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - WarningMessageContents + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_warningmessagecontents( + uint8_t **ptr, + LIBLTE_S1AP_WARNINGMESSAGECONTENTS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - WarningMessageContents + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CauseProtocol ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causeprotocol( + LIBLTE_S1AP_CAUSEPROTOCOL_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CauseProtocol error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causeprotocol( + uint8_t **ptr, + LIBLTE_S1AP_CAUSEPROTOCOL_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CauseProtocol error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CAUSEPROTOCOL_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellAccessMode ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellaccessmode( + LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CellAccessMode error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellaccessmode( + uint8_t **ptr, + LIBLTE_S1AP_CELLACCESSMODE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CellAccessMode error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CELLACCESSMODE_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000RATType ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000rattype( + LIBLTE_S1AP_CDMA2000RATTYPE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Cdma2000RATType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000rattype( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000RATTYPE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Cdma2000RATType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CDMA2000RATTYPE_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXMEID DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexmeid( + LIBLTE_S1AP_CDMA2000ONEXMEID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000OneXMEID + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexmeid( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXMEID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000OneXMEID + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cell_Size ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cell_size( + LIBLTE_S1AP_CELL_SIZE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Cell_Size error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 2); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cell_size( + uint8_t **ptr, + LIBLTE_S1AP_CELL_SIZE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Cell_Size error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CELL_SIZE_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CI STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ci( + LIBLTE_S1AP_CI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - CI + if(LIBLTE_S1AP_CI_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ci( + uint8_t **ptr, + LIBLTE_S1AP_CI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - CI + if(LIBLTE_S1AP_CI_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CSFallbackIndicator ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csfallbackindicator( + LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CSFallbackIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csfallbackindicator( + uint8_t **ptr, + LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CSFallbackIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CSFALLBACKINDICATOR_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CSGMembershipStatus ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csgmembershipstatus( + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 1); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csgmembershipstatus( + uint8_t **ptr, + LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_CSGMEMBERSHIPSTATUS_ENUM)liblte_bits_2_value(ptr, 1); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE DataCodingScheme STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_datacodingscheme( + LIBLTE_S1AP_DATACODINGSCHEME_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - DataCodingScheme + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_datacodingscheme( + uint8_t **ptr, + LIBLTE_S1AP_DATACODINGSCHEME_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - DataCodingScheme + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EmergencyAreaIDList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaidlist( + LIBLTE_S1AP_EMERGENCYAREAIDLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("EmergencyAreaIDList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_emergencyareaid(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaidlist( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAIDLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("EmergencyAreaIDList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_emergencyareaid(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EmergencyAreaIDListForRestart DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaidlistforrestart( + LIBLTE_S1AP_EMERGENCYAREAIDLISTFORRESTART_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("EmergencyAreaIDListForRestart pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_emergencyareaid(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaidlistforrestart( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAIDLISTFORRESTART_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("EmergencyAreaIDListForRestart unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_emergencyareaid(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ENB_UE_S1AP_ID INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_ue_s1ap_id( + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ENB_UE_S1AP_ID + // lb:0, ub:16777215 + // Range > 65536 - encoded based on value + { + uint32_t n_bits = floor(log2(ie->ENB_UE_S1AP_ID-0)+1); + uint32_t n_octets = (n_bits+7)/8; + liblte_value_2_bits(n_octets-1, ptr, 2); + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (n_octets*8)-n_bits); + liblte_value_2_bits(ie->ENB_UE_S1AP_ID-0, ptr, n_bits); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_ue_s1ap_id( + uint8_t **ptr, + LIBLTE_S1AP_ENB_UE_S1AP_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ENB_UE_S1AP_ID + // lb:0, ub:16777215 + // Range > 65536 - encoded based on value + { + uint32_t n_octets = liblte_bits_2_value(ptr, 2) + 1; + liblte_align_up(ptr, 8); + ie->ENB_UE_S1AP_ID = liblte_bits_2_value(ptr, n_octets*8) + 0; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RAB_ID INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rab_id( + LIBLTE_S1AP_E_RAB_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->E_RAB_ID + // lb:0, ub:15 + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ie->E_RAB_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_value_2_bits(ie->E_RAB_ID, ptr, 4); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rab_id( + uint8_t **ptr, + LIBLTE_S1AP_E_RAB_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->E_RAB_ID + // lb:0, ub:15 + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ie->E_RAB_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + ie->E_RAB_ID = (uint8_t)liblte_bits_2_value(ptr, 4); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABInformationListItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabinformationlistitem( + LIBLTE_S1AP_E_RABINFORMATIONLISTITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABInformationListItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->dL_Forwarding_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->dL_Forwarding_present) { + if(liblte_s1ap_pack_dl_forwarding(&ie->dL_Forwarding, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlistitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABINFORMATIONLISTITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABInformationListItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->dL_Forwarding_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->dL_Forwarding_present) { + if(liblte_s1ap_unpack_dl_forwarding(ptr, &ie->dL_Forwarding) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EUTRANRoundTripDelayEstimationInfo INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eutranroundtripdelayestimationinfo( + LIBLTE_S1AP_EUTRANROUNDTRIPDELAYESTIMATIONINFO_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->EUTRANRoundTripDelayEstimationInfo + // lb:0, ub:2047 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-11); + liblte_value_2_bits(ie->EUTRANRoundTripDelayEstimationInfo, ptr, 11); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eutranroundtripdelayestimationinfo( + uint8_t **ptr, + LIBLTE_S1AP_EUTRANROUNDTRIPDELAYESTIMATIONINFO_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->EUTRANRoundTripDelayEstimationInfo + // lb:0, ub:2047 + liblte_align_up(ptr, 8); + ie->EUTRANRoundTripDelayEstimationInfo = (uint16_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ForbiddenLACs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:4096 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddenlacs( + LIBLTE_S1AP_FORBIDDENLACS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ForbiddenLACs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 12); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_lac(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddenlacs( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENLACS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 12) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ForbiddenLACs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_lac(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE GTP_TEID STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gtp_teid( + LIBLTE_S1AP_GTP_TEID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - GTP-TEID + if(LIBLTE_S1AP_GTP_TEID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gtp_teid( + uint8_t **ptr, + LIBLTE_S1AP_GTP_TEID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - GTP-TEID + if(LIBLTE_S1AP_GTP_TEID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE GUMMEIType ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gummeitype( + LIBLTE_S1AP_GUMMEITYPE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("GUMMEIType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gummeitype( + uint8_t **ptr, + LIBLTE_S1AP_GUMMEITYPE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("GUMMEIType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_GUMMEITYPE_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE HandoverType ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovertype( + LIBLTE_S1AP_HANDOVERTYPE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("HandoverType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovertype( + uint8_t **ptr, + LIBLTE_S1AP_HANDOVERTYPE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("HandoverType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_HANDOVERTYPE_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE IntegrityProtectionAlgorithms STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_integrityprotectionalgorithms( + LIBLTE_S1AP_INTEGRITYPROTECTIONALGORITHMS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - IntegrityProtectionAlgorithms + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("IntegrityProtectionAlgorithms error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_integrityprotectionalgorithms( + uint8_t **ptr, + LIBLTE_S1AP_INTEGRITYPROTECTIONALGORITHMS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - IntegrityProtectionAlgorithms + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("IntegrityProtectionAlgorithms error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LastVisitedGERANCellInformation CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedgerancellinformation( + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("LastVisitedGERANCellInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 0); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_UNDEFINED) { + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedgerancellinformation( + uint8_t **ptr, + LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("LastVisitedGERANCellInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_ENUM)liblte_bits_2_value(ptr, 0); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_LASTVISITEDGERANCELLINFORMATION_CHOICE_UNDEFINED) { + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Links_to_log ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_links_to_log( + LIBLTE_S1AP_LINKS_TO_LOG_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Links_to_log error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 2); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_links_to_log( + uint8_t **ptr, + LIBLTE_S1AP_LINKS_TO_LOG_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Links_to_log error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_LINKS_TO_LOG_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LoggingInterval ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_logginginterval( + LIBLTE_S1AP_LOGGINGINTERVAL_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 3); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_logginginterval( + uint8_t **ptr, + LIBLTE_S1AP_LOGGINGINTERVAL_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_LOGGINGINTERVAL_ENUM)liblte_bits_2_value(ptr, 3); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M3period ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m3period( + LIBLTE_S1AP_M3PERIOD_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M3period error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 2); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m3period( + uint8_t **ptr, + LIBLTE_S1AP_M3PERIOD_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M3period error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_M3PERIOD_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M4period ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m4period( + LIBLTE_S1AP_M4PERIOD_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M4period error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m4period( + uint8_t **ptr, + LIBLTE_S1AP_M4PERIOD_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M4period error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_M4PERIOD_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M5period ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m5period( + LIBLTE_S1AP_M5PERIOD_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M5period error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m5period( + uint8_t **ptr, + LIBLTE_S1AP_M5PERIOD_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M5period error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_M5PERIOD_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MobilityInformation STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mobilityinformation( + LIBLTE_S1AP_MOBILITYINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - MobilityInformation + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mobilityinformation( + uint8_t **ptr, + LIBLTE_S1AP_MOBILITYINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - MobilityInformation + liblte_align_up(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MME_Code STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mme_code( + LIBLTE_S1AP_MME_CODE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - MME-Code + if(LIBLTE_S1AP_MME_CODE_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mme_code( + uint8_t **ptr, + LIBLTE_S1AP_MME_CODE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - MME-Code + if(LIBLTE_S1AP_MME_CODE_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MSClassmark3 DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_msclassmark3( + LIBLTE_S1AP_MSCLASSMARK3_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - MSClassmark3 + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_msclassmark3( + uint8_t **ptr, + LIBLTE_S1AP_MSCLASSMARK3_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - MSClassmark3 + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE NumberofBroadcastRequest INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_numberofbroadcastrequest( + LIBLTE_S1AP_NUMBEROFBROADCASTREQUEST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->NumberofBroadcastRequest + // lb:0, ub:65535 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (2*8)-16); + liblte_value_2_bits(ie->NumberofBroadcastRequest, ptr, 16); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_numberofbroadcastrequest( + uint8_t **ptr, + LIBLTE_S1AP_NUMBEROFBROADCASTREQUEST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->NumberofBroadcastRequest + // lb:0, ub:65535 + liblte_align_up(ptr, 8); + ie->NumberofBroadcastRequest = (uint16_t)liblte_bits_2_value(ptr, 2.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE OverloadResponse CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_overloadresponse( + LIBLTE_S1AP_OVERLOADRESPONSE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("OverloadResponse error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 0); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_OVERLOADACTION) { + if(liblte_s1ap_pack_overloadaction(&ie->choice.overloadAction, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_overloadresponse( + uint8_t **ptr, + LIBLTE_S1AP_OVERLOADRESPONSE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("OverloadResponse error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_ENUM)liblte_bits_2_value(ptr, 0); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_OVERLOADRESPONSE_CHOICE_OVERLOADACTION) { + if(liblte_s1ap_unpack_overloadaction(ptr, &ie->choice.overloadAction) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PDCP_SNExtended INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pdcp_snextended( + LIBLTE_S1AP_PDCP_SNEXTENDED_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->PDCP_SNExtended + // lb:0, ub:32767 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-15); + liblte_value_2_bits(ie->PDCP_SNExtended, ptr, 15); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pdcp_snextended( + uint8_t **ptr, + LIBLTE_S1AP_PDCP_SNEXTENDED_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->PDCP_SNExtended + // lb:0, ub:32767 + liblte_align_up(ptr, 8); + ie->PDCP_SNExtended = (uint16_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Pre_emptionCapability ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pre_emptioncapability( + LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 1); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pre_emptioncapability( + uint8_t **ptr, + LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM)liblte_bits_2_value(ptr, 1); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE QCI INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_qci( + LIBLTE_S1AP_QCI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->QCI + // lb:0, ub:255 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-8); + liblte_value_2_bits(ie->QCI, ptr, 8); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_qci( + uint8_t **ptr, + LIBLTE_S1AP_QCI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->QCI + // lb:0, ub:255 + liblte_align_up(ptr, 8); + ie->QCI = (uint8_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RelayNode_Indicator ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_relaynode_indicator( + LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("RelayNode_Indicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_relaynode_indicator( + uint8_t **ptr, + LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("RelayNode_Indicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_RELAYNODE_INDICATOR_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M1ReportingTrigger ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1reportingtrigger( + LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M1ReportingTrigger error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 2); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1reportingtrigger( + uint8_t **ptr, + LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M1ReportingTrigger error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_M1REPORTINGTRIGGER_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RIMInformation DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_riminformation( + LIBLTE_S1AP_RIMINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - RIMInformation + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_riminformation( + uint8_t **ptr, + LIBLTE_S1AP_RIMINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - RIMInformation + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RepetitionPeriod INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_repetitionperiod( + LIBLTE_S1AP_REPETITIONPERIOD_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->RepetitionPeriod + // lb:0, ub:4095 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (1*8)-12); + liblte_value_2_bits(ie->RepetitionPeriod, ptr, 12); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_repetitionperiod( + uint8_t **ptr, + LIBLTE_S1AP_REPETITIONPERIOD_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->RepetitionPeriod + // lb:0, ub:4095 + liblte_align_up(ptr, 8); + ie->RepetitionPeriod = (uint16_t)liblte_bits_2_value(ptr, 1.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SecurityKey STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_securitykey( + LIBLTE_S1AP_SECURITYKEY_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - SecurityKey + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_securitykey( + uint8_t **ptr, + LIBLTE_S1AP_SECURITYKEY_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - SecurityKey + liblte_align_up(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SerialNumber STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_serialnumber( + LIBLTE_S1AP_SERIALNUMBER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - SerialNumber + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_serialnumber( + uint8_t **ptr, + LIBLTE_S1AP_SERIALNUMBER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - SerialNumber + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SourceBSS_ToTargetBSS_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourcebss_totargetbss_transparentcontainer( + LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - SourceBSS-ToTargetBSS-TransparentContainer + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourcebss_totargetbss_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_SOURCEBSS_TOTARGETBSS_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - SourceBSS-ToTargetBSS-TransparentContainer + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SRVCCOperationPossible ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_srvccoperationpossible( + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SRVCCOperationPossible error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_srvccoperationpossible( + uint8_t **ptr, + LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SRVCCOperationPossible error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_SRVCCOPERATIONPOSSIBLE_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ServedGroupIDs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedgroupids( + LIBLTE_S1AP_SERVEDGROUPIDS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ServedGroupIDs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_mme_group_id(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedgroupids( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDGROUPIDS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ServedGroupIDs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_mme_group_id(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE StratumLevel INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_stratumlevel( + LIBLTE_S1AP_STRATUMLEVEL_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->StratumLevel + // lb:0, ub:3 + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ie->StratumLevel error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_value_2_bits(ie->StratumLevel, ptr, 2); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_stratumlevel( + uint8_t **ptr, + LIBLTE_S1AP_STRATUMLEVEL_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->StratumLevel + // lb:0, ub:3 + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ie->StratumLevel error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + ie->StratumLevel = (uint8_t)liblte_bits_2_value(ptr, 2); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAC STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tac( + LIBLTE_S1AP_TAC_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - TAC + if(LIBLTE_S1AP_TAC_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tac( + uint8_t **ptr, + LIBLTE_S1AP_TAC_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - TAC + if(LIBLTE_S1AP_TAC_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAListforMDT DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:8 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_talistformdt( + LIBLTE_S1AP_TALISTFORMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("TAListforMDT pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 3); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tac(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_talistformdt( + uint8_t **ptr, + LIBLTE_S1AP_TALISTFORMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 3) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("TAListforMDT unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tac(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TBCD_STRING STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tbcd_string( + LIBLTE_S1AP_TBCD_STRING_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - TBCD-STRING + if(LIBLTE_S1AP_TBCD_STRING_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tbcd_string( + uint8_t **ptr, + LIBLTE_S1AP_TBCD_STRING_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - TBCD-STRING + if(LIBLTE_S1AP_TBCD_STRING_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Target_ToSource_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_target_tosource_transparentcontainer( + LIBLTE_S1AP_TARGET_TOSOURCE_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Target-ToSource-TransparentContainer + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_target_tosource_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_TARGET_TOSOURCE_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Target-ToSource-TransparentContainer + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Threshold_RSRP INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_threshold_rsrp( + LIBLTE_S1AP_THRESHOLD_RSRP_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Threshold_RSRP + // lb:0, ub:97 + liblte_value_2_bits(ie->Threshold_RSRP, ptr, 7); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_threshold_rsrp( + uint8_t **ptr, + LIBLTE_S1AP_THRESHOLD_RSRP_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Threshold_RSRP + // lb:0, ub:97 + ie->Threshold_RSRP = (uint8_t)liblte_bits_2_value(ptr, 7); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Time_UE_StayedInCell_EnhancedGranularity INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_time_ue_stayedincell_enhancedgranularity( + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Time_UE_StayedInCell_EnhancedGranularity + // lb:0, ub:40950 + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (2*8)-16); + liblte_value_2_bits(ie->Time_UE_StayedInCell_EnhancedGranularity, ptr, 16); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_time_ue_stayedincell_enhancedgranularity( + uint8_t **ptr, + LIBLTE_S1AP_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->Time_UE_StayedInCell_EnhancedGranularity + // lb:0, ub:40950 + liblte_align_up(ptr, 8); + ie->Time_UE_StayedInCell_EnhancedGranularity = (uint16_t)liblte_bits_2_value(ptr, 2.0*8); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_UTRAN_Trace_ID STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_utran_trace_id( + LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - E-UTRAN-Trace-ID + if(LIBLTE_S1AP_E_UTRAN_TRACE_ID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_utran_trace_id( + uint8_t **ptr, + LIBLTE_S1AP_E_UTRAN_TRACE_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - E-UTRAN-Trace-ID + if(LIBLTE_S1AP_E_UTRAN_TRACE_ID_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TypeOfError ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_typeoferror( + LIBLTE_S1AP_TYPEOFERROR_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TypeOfError error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_typeoferror( + uint8_t **ptr, + LIBLTE_S1AP_TYPEOFERROR_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TypeOfError error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_TYPEOFERROR_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UEAggregateMaximumBitrate SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueaggregatemaximumbitrate( + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("UEAggregateMaximumBitrate error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_bitrate(&ie->uEaggregateMaximumBitRateDL, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_bitrate(&ie->uEaggregateMaximumBitRateUL, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueaggregatemaximumbitrate( + uint8_t **ptr, + LIBLTE_S1AP_UEAGGREGATEMAXIMUMBITRATE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("UEAggregateMaximumBitrate error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_bitrate(ptr, &ie->uEaggregateMaximumBitRateDL) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_bitrate(ptr, &ie->uEaggregateMaximumBitRateUL) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UE_S1AP_ID_pair SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_s1ap_id_pair( + LIBLTE_S1AP_UE_S1AP_ID_PAIR_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("UE_S1AP_ID_pair error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_mme_ue_s1ap_id(&ie->mME_UE_S1AP_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_enb_ue_s1ap_id(&ie->eNB_UE_S1AP_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_s1ap_id_pair( + uint8_t **ptr, + LIBLTE_S1AP_UE_S1AP_ID_PAIR_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("UE_S1AP_ID_pair error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_mme_ue_s1ap_id(ptr, &ie->mME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &ie->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UEIdentityIndexValue STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueidentityindexvalue( + LIBLTE_S1AP_UEIDENTITYINDEXVALUE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - UEIdentityIndexValue + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueidentityindexvalue( + uint8_t **ptr, + LIBLTE_S1AP_UEIDENTITYINDEXVALUE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - UEIdentityIndexValue + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UESecurityCapabilities SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uesecuritycapabilities( + LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("UESecurityCapabilities error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_encryptionalgorithms(&ie->encryptionAlgorithms, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_integrityprotectionalgorithms(&ie->integrityProtectionAlgorithms, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uesecuritycapabilities( + uint8_t **ptr, + LIBLTE_S1AP_UESECURITYCAPABILITIES_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("UESecurityCapabilities error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_encryptionalgorithms(ptr, &ie->encryptionAlgorithms) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_integrityprotectionalgorithms(ptr, &ie->integrityProtectionAlgorithms) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE VoiceSupportMatchIndicator ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_voicesupportmatchindicator( + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("VoiceSupportMatchIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_voicesupportmatchindicator( + uint8_t **ptr, + LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("VoiceSupportMatchIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_VOICESUPPORTMATCHINDICATOR_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE WarningSecurityInfo STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_warningsecurityinfo( + LIBLTE_S1AP_WARNINGSECURITYINFO_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - WarningSecurityInfo + if(LIBLTE_S1AP_WARNINGSECURITYINFO_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_warningsecurityinfo( + uint8_t **ptr, + LIBLTE_S1AP_WARNINGSECURITYINFO_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - WarningSecurityInfo + if(LIBLTE_S1AP_WARNINGSECURITYINFO_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ENBX2GTPTLAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2gtptlas( + LIBLTE_S1AP_ENBX2GTPTLAS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ENBX2GTPTLAs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 4); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_transportlayeraddress(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2gtptlas( + uint8_t **ptr, + LIBLTE_S1AP_ENBX2GTPTLAS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 4) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ENBX2GTPTLAs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CauseTransport ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_causetransport( + LIBLTE_S1AP_CAUSETRANSPORT_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CauseTransport error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_causetransport( + uint8_t **ptr, + LIBLTE_S1AP_CAUSETRANSPORT_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CauseTransport error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CAUSETRANSPORT_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000HOStatus ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000hostatus( + LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Cdma2000HOStatus error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 1); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000hostatus( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Cdma2000HOStatus error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_CDMA2000HOSTATUS_ENUM)liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXPilot DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexpilot( + LIBLTE_S1AP_CDMA2000ONEXPILOT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000OneXPilot + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexpilot( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXPILOT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - Cdma2000OneXPilot + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ConcurrentWarningMessageIndicator ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_concurrentwarningmessageindicator( + LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 0); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_concurrentwarningmessageindicator( + uint8_t **ptr, + LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_CONCURRENTWARNINGMESSAGEINDICATOR_ENUM)liblte_bits_2_value(ptr, 0); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE COUNTvalue SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_countvalue( + LIBLTE_S1AP_COUNTVALUE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("COUNTvalue error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_pdcp_sn(&ie->pDCP_SN, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_hfn(&ie->hFN, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_countvalue( + uint8_t **ptr, + LIBLTE_S1AP_COUNTVALUE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("COUNTvalue error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_pdcp_sn(ptr, &ie->pDCP_SN) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_hfn(ptr, &ie->hFN) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CriticalityDiagnostics_IE_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics_ie_item( + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CriticalityDiagnostics_IE_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + // Enum - ie->iECriticality + liblte_value_2_bits(ie->iECriticality, ptr, 2); + + if(liblte_s1ap_pack_protocolie_id(&ie->iE_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_typeoferror(&ie->typeOfError, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ie_item( + uint8_t **ptr, + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CriticalityDiagnostics_IE_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + // Enum - ie->iECriticality + ie->iECriticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + + if(liblte_s1ap_unpack_protocolie_id(ptr, &ie->iE_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_typeoferror(ptr, &ie->typeOfError) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ENBX2TLAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:2 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2tlas( + LIBLTE_S1AP_ENBX2TLAS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ENBX2TLAs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 0); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_transportlayeraddress(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2tlas( + uint8_t **ptr, + LIBLTE_S1AP_ENBX2TLAS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 0) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ENBX2TLAs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ExtendedRepetitionPeriod INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_extendedrepetitionperiod( + LIBLTE_S1AP_EXTENDEDREPETITIONPERIOD_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ExtendedRepetitionPeriod + // lb:4096, ub:131071 + // Range > 65536 - encoded based on value + { + uint32_t n_bits = floor(log2(ie->ExtendedRepetitionPeriod-4096)+1); + uint32_t n_octets = (n_bits+7)/8; + liblte_value_2_bits(n_octets-1, ptr, 2); + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (n_octets*8)-n_bits); + liblte_value_2_bits(ie->ExtendedRepetitionPeriod-4096, ptr, n_bits); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_extendedrepetitionperiod( + uint8_t **ptr, + LIBLTE_S1AP_EXTENDEDREPETITIONPERIOD_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->ExtendedRepetitionPeriod + // lb:4096, ub:131071 + // Range > 65536 - encoded based on value + { + uint32_t n_octets = liblte_bits_2_value(ptr, 2) + 1; + liblte_align_up(ptr, 8); + ie->ExtendedRepetitionPeriod = liblte_bits_2_value(ptr, n_octets*8) + 4096; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ForbiddenTACs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:4096 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddentacs( + LIBLTE_S1AP_FORBIDDENTACS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ForbiddenTACs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 12); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tac(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddentacs( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENTACS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 12) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ForbiddenTACs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tac(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE GBR_QosInformation SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gbr_qosinformation( + LIBLTE_S1AP_GBR_QOSINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("GBR_QosInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_bitrate(&ie->e_RAB_MaximumBitrateDL, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_bitrate(&ie->e_RAB_MaximumBitrateUL, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_bitrate(&ie->e_RAB_GuaranteedBitrateDL, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_bitrate(&ie->e_RAB_GuaranteedBitrateUL, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gbr_qosinformation( + uint8_t **ptr, + LIBLTE_S1AP_GBR_QOSINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("GBR_QosInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_bitrate(ptr, &ie->e_RAB_MaximumBitrateDL) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_bitrate(ptr, &ie->e_RAB_MaximumBitrateUL) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_bitrate(ptr, &ie->e_RAB_GuaranteedBitrateDL) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_bitrate(ptr, &ie->e_RAB_GuaranteedBitrateUL) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE HFNModified INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_hfnmodified( + LIBLTE_S1AP_HFNMODIFIED_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->HFNModified + // lb:0, ub:131071 + // Range > 65536 - encoded based on value + { + uint32_t n_bits = floor(log2(ie->HFNModified-0)+1); + uint32_t n_octets = (n_bits+7)/8; + liblte_value_2_bits(n_octets-1, ptr, 2); + liblte_align_up_zero(ptr, 8); + liblte_value_2_bits(0, ptr, (n_octets*8)-n_bits); + liblte_value_2_bits(ie->HFNModified-0, ptr, n_bits); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_hfnmodified( + uint8_t **ptr, + LIBLTE_S1AP_HFNMODIFIED_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->HFNModified + // lb:0, ub:131071 + // Range > 65536 - encoded based on value + { + uint32_t n_octets = liblte_bits_2_value(ptr, 2) + 1; + liblte_align_up(ptr, 8); + ie->HFNModified = liblte_bits_2_value(ptr, n_octets*8) + 0; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE KillAllWarningMessages ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_killallwarningmessages( + LIBLTE_S1AP_KILLALLWARNINGMESSAGES_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 0); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_killallwarningmessages( + uint8_t **ptr, + LIBLTE_S1AP_KILLALLWARNINGMESSAGES_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_KILLALLWARNINGMESSAGES_ENUM)liblte_bits_2_value(ptr, 0); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LPPa_PDU DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lppa_pdu( + LIBLTE_S1AP_LPPA_PDU_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - LPPa-PDU + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lppa_pdu( + uint8_t **ptr, + LIBLTE_S1AP_LPPA_PDU_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - LPPa-PDU + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M3Configuration SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m3configuration( + LIBLTE_S1AP_M3CONFIGURATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M3Configuration error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_m3period(&ie->m3period, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m3configuration( + uint8_t **ptr, + LIBLTE_S1AP_M3CONFIGURATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M3Configuration error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_m3period(ptr, &ie->m3period) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M5Configuration SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m5configuration( + LIBLTE_S1AP_M5CONFIGURATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M5Configuration error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_m5period(&ie->m5period, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_links_to_log(&ie->m5_links_to_log, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m5configuration( + uint8_t **ptr, + LIBLTE_S1AP_M5CONFIGURATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M5Configuration error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_m5period(ptr, &ie->m5period) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_links_to_log(ptr, &ie->m5_links_to_log) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MeasurementThresholdA2 CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_measurementthresholda2( + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("MeasurementThresholdA2 error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_THRESHOLD_RSRP) { + if(liblte_s1ap_pack_threshold_rsrp(&ie->choice.threshold_RSRP, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_THRESHOLD_RSRQ) { + if(liblte_s1ap_pack_threshold_rsrq(&ie->choice.threshold_RSRQ, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_measurementthresholda2( + uint8_t **ptr, + LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("MeasurementThresholdA2 error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_ENUM)liblte_bits_2_value(ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_THRESHOLD_RSRP) { + if(liblte_s1ap_unpack_threshold_rsrp(ptr, &ie->choice.threshold_RSRP) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_MEASUREMENTTHRESHOLDA2_CHOICE_THRESHOLD_RSRQ) { + if(liblte_s1ap_unpack_threshold_rsrq(ptr, &ie->choice.threshold_RSRQ) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M_TMSI STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m_tmsi( + LIBLTE_S1AP_M_TMSI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - M-TMSI + if(LIBLTE_S1AP_M_TMSI_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m_tmsi( + uint8_t **ptr, + LIBLTE_S1AP_M_TMSI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - M-TMSI + if(LIBLTE_S1AP_M_TMSI_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE OldBSS_ToNewBSS_Information DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_oldbss_tonewbss_information( + LIBLTE_S1AP_OLDBSS_TONEWBSS_INFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - OldBSS-ToNewBSS-Information + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_oldbss_tonewbss_information( + uint8_t **ptr, + LIBLTE_S1AP_OLDBSS_TONEWBSS_INFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - OldBSS-ToNewBSS-Information + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PLMNidentity STATIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_plmnidentity( + LIBLTE_S1AP_PLMNIDENTITY_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - PLMNidentity + if(LIBLTE_S1AP_PLMNIDENTITY_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up_zero(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_plmnidentity( + uint8_t **ptr, + LIBLTE_S1AP_PLMNIDENTITY_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static octet string - PLMNidentity + if(LIBLTE_S1AP_PLMNIDENTITY_OCTET_STRING_LEN > 2) { // X.691 Sec.16 + liblte_align_up(ptr, 8); + } + // Octets + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ReceiveStatusOfULPDCPSDUsExtended DYNAMIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_receivestatusofulpdcpsdusextended( + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUSEXTENDED_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic bit string - ReceiveStatusOfULPDCPSDUsExtended + // lb:1, ub:16384 + // Length + liblte_value_2_bits(ie->n_bits-1, ptr, 14); + liblte_align_up_zero(ptr, 8); + + // Bits + uint32_t i; + for(i=0;in_bits;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_receivestatusofulpdcpsdusextended( + uint8_t **ptr, + LIBLTE_S1AP_RECEIVESTATUSOFULPDCPSDUSEXTENDED_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic bit string - ReceiveStatusOfULPDCPSDUsExtended + // lb:1, ub:16384 + // Length + ie->n_bits = liblte_bits_2_value(ptr, 14) + 1; + liblte_align_up(ptr, 8); + + // Bits + uint32_t i; + for(i=0;in_bits;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RequestType SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_requesttype( + LIBLTE_S1AP_REQUESTTYPE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("RequestType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eventtype(&ie->eventType, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_reportarea(&ie->reportArea, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_requesttype( + uint8_t **ptr, + LIBLTE_S1AP_REQUESTTYPE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("RequestType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eventtype(ptr, &ie->eventType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_reportarea(ptr, &ie->reportArea) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RRC_Container DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rrc_container( + LIBLTE_S1AP_RRC_CONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - RRC-Container + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rrc_container( + uint8_t **ptr, + LIBLTE_S1AP_RRC_CONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - RRC-Container + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* ProtocolIE nextHopChainingCount INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nexthopchainingcount( + LIBLTE_S1AP_NEXTHOPCHAININGCOUNT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->nextHopChainingCount + // lb:0, ub:7 + liblte_value_2_bits(ie->nextHopChainingCount, ptr, 3); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nexthopchainingcount( + uint8_t **ptr, + LIBLTE_S1AP_NEXTHOPCHAININGCOUNT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->nextHopChainingCount + // lb:0, ub:7 + ie->nextHopChainingCount = (uint8_t)liblte_bits_2_value(ptr, 3); + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* ProtocolIE SecurityContext SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_securitycontext( + LIBLTE_S1AP_SECURITYCONTEXT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SecurityContext error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_nexthopchainingcount(&ie->nextHopChainingCount, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_securitykey(&ie->nextHopParameter, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_securitycontext( + uint8_t **ptr, + LIBLTE_S1AP_SECURITYCONTEXT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SecurityContext error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_nexthopchainingcount(ptr, &ie->nextHopChainingCount) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_securitykey(ptr, &ie->nextHopParameter) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ServedMMECs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedmmecs( + LIBLTE_S1AP_SERVEDMMECS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ServedMMECs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_mme_code(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedmmecs( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDMMECS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ServedMMECs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_mme_code(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TimeSynchronizationInfo SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_timesynchronizationinfo( + LIBLTE_S1AP_TIMESYNCHRONIZATIONINFO_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TimeSynchronizationInfo error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_stratumlevel(&ie->stratumLevel, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_synchronizationstatus(&ie->synchronizationStatus, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_timesynchronizationinfo( + uint8_t **ptr, + LIBLTE_S1AP_TIMESYNCHRONIZATIONINFO_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TimeSynchronizationInfo error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_stratumlevel(ptr, &ie->stratumLevel) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_synchronizationstatus(ptr, &ie->synchronizationStatus) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAI SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai( + LIBLTE_S1AP_TAI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TAI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->pLMNidentity, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_tac(&ie->tAC, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai( + uint8_t **ptr, + LIBLTE_S1AP_TAI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TAI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->pLMNidentity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_tac(ptr, &ie->tAC) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TABasedMDT SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tabasedmdt( + LIBLTE_S1AP_TABASEDMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TABasedMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_talistformdt(&ie->tAListforMDT, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tabasedmdt( + uint8_t **ptr, + LIBLTE_S1AP_TABASEDMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TABasedMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_talistformdt(ptr, &ie->tAListforMDT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TargeteNB_ToSourceeNB_TransparentContainer SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_tosourceenb_transparentcontainer( + LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TargeteNB_ToSourceeNB_TransparentContainer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_rrc_container(&ie->rRC_Container, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_tosourceenb_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TargeteNB_ToSourceeNB_TransparentContainer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_rrc_container(ptr, &ie->rRC_Container) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M1ThresholdEventA2 SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1thresholdeventa2( + LIBLTE_S1AP_M1THRESHOLDEVENTA2_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M1ThresholdEventA2 error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_measurementthresholda2(&ie->measurementThreshold, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1thresholdeventa2( + uint8_t **ptr, + LIBLTE_S1AP_M1THRESHOLDEVENTA2_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M1ThresholdEventA2 error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_measurementthresholda2(ptr, &ie->measurementThreshold) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TransportInformation SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_transportinformation( + LIBLTE_S1AP_TRANSPORTINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TransportInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->uL_GTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_transportinformation( + uint8_t **ptr, + LIBLTE_S1AP_TRANSPORTINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TransportInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->uL_GTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TunnelInformation SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tunnelinformation( + LIBLTE_S1AP_TUNNELINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TunnelInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->uDP_Port_Number_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->uDP_Port_Number_present) { + if(liblte_s1ap_pack_port_number(&ie->uDP_Port_Number, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tunnelinformation( + uint8_t **ptr, + LIBLTE_S1AP_TUNNELINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TunnelInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->uDP_Port_Number_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->uDP_Port_Number_present) { + if(liblte_s1ap_unpack_port_number(ptr, &ie->uDP_Port_Number) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UE_S1AP_IDs CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_s1ap_ids( + LIBLTE_S1AP_UE_S1AP_IDS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("UE_S1AP_IDs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UE_S1AP_ID_PAIR) { + if(liblte_s1ap_pack_ue_s1ap_id_pair(&ie->choice.uE_S1AP_ID_pair, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_MME_UE_S1AP_ID) { + if(liblte_s1ap_pack_mme_ue_s1ap_id(&ie->choice.mME_UE_S1AP_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_s1ap_ids( + uint8_t **ptr, + LIBLTE_S1AP_UE_S1AP_IDS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("UE_S1AP_IDs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_ENUM)liblte_bits_2_value(ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UE_S1AP_ID_PAIR) { + if(liblte_s1ap_unpack_ue_s1ap_id_pair(ptr, &ie->choice.uE_S1AP_ID_pair) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_MME_UE_S1AP_ID) { + if(liblte_s1ap_unpack_mme_ue_s1ap_id(ptr, &ie->choice.mME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ENBX2ExtTLA SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2exttla( + LIBLTE_S1AP_ENBX2EXTTLA_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ENBX2ExtTLA error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iPsecTLA_present?1:0, ptr, 1); + liblte_value_2_bits(ie->gTPTLAa_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(ie->iPsecTLA_present) { + if(liblte_s1ap_pack_transportlayeraddress(&ie->iPsecTLA, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->gTPTLAa_present) { + if(liblte_s1ap_pack_enbx2gtptlas(&ie->gTPTLAa, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2exttla( + uint8_t **ptr, + LIBLTE_S1AP_ENBX2EXTTLA_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ENBX2ExtTLA error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iPsecTLA_present = liblte_bits_2_value(ptr, 1); + ie->gTPTLAa_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(ie->iPsecTLA_present) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->iPsecTLA) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->gTPTLAa_present) { + if(liblte_s1ap_unpack_enbx2gtptlas(ptr, &ie->gTPTLAa) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE BPLMNs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:6 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bplmns( + LIBLTE_S1AP_BPLMNS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("BPLMNs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 3); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tbcd_string(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bplmns( + uint8_t **ptr, + LIBLTE_S1AP_BPLMNS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 3) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("BPLMNs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cause CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cause( + LIBLTE_S1AP_CAUSE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Cause error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 3); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_RADIONETWORK) { + if(liblte_s1ap_pack_causeradionetwork(&ie->choice.radioNetwork, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_TRANSPORT) { + if(liblte_s1ap_pack_causetransport(&ie->choice.transport, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_NAS) { + if(liblte_s1ap_pack_causenas(&ie->choice.nas, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_PROTOCOL) { + if(liblte_s1ap_pack_causeprotocol(&ie->choice.protocol, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_MISC) { + if(liblte_s1ap_pack_causemisc(&ie->choice.misc, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cause( + uint8_t **ptr, + LIBLTE_S1AP_CAUSE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Cause error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_CAUSE_CHOICE_ENUM)liblte_bits_2_value(ptr, 3); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_RADIONETWORK) { + if(liblte_s1ap_unpack_causeradionetwork(ptr, &ie->choice.radioNetwork) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_TRANSPORT) { + if(liblte_s1ap_unpack_causetransport(ptr, &ie->choice.transport) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_NAS) { + if(liblte_s1ap_unpack_causenas(ptr, &ie->choice.nas) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_PROTOCOL) { + if(liblte_s1ap_unpack_causeprotocol(ptr, &ie->choice.protocol) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_CAUSE_CHOICE_MISC) { + if(liblte_s1ap_unpack_causemisc(ptr, &ie->choice.misc) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Cdma2000OneXSRVCCInfo SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexsrvccinfo( + LIBLTE_S1AP_CDMA2000ONEXSRVCCINFO_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Cdma2000OneXSRVCCInfo error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_cdma2000onexmeid(&ie->cdma2000OneXMEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_cdma2000onexmsi(&ie->cdma2000OneXMSI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_cdma2000onexpilot(&ie->cdma2000OneXPilot, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexsrvccinfo( + uint8_t **ptr, + LIBLTE_S1AP_CDMA2000ONEXSRVCCINFO_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Cdma2000OneXSRVCCInfo error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_cdma2000onexmeid(ptr, &ie->cdma2000OneXMEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_cdma2000onexmsi(ptr, &ie->cdma2000OneXMSI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_cdma2000onexpilot(ptr, &ie->cdma2000OneXPilot) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CGI SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cgi( + LIBLTE_S1AP_CGI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CGI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->rAC_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->pLMNidentity, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_lac(&ie->lAC, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_ci(&ie->cI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->rAC_present) { + if(liblte_s1ap_pack_rac(&ie->rAC, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cgi( + uint8_t **ptr, + LIBLTE_S1AP_CGI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CGI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->rAC_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->pLMNidentity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_lac(ptr, &ie->lAC) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_ci(ptr, &ie->cI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->rAC_present) { + if(liblte_s1ap_unpack_rac(ptr, &ie->rAC) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE COUNTValueExtended SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_countvalueextended( + LIBLTE_S1AP_COUNTVALUEEXTENDED_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("COUNTValueExtended error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_pdcp_snextended(&ie->pDCP_SNExtended, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_hfnmodified(&ie->hFNModified, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_countvalueextended( + uint8_t **ptr, + LIBLTE_S1AP_COUNTVALUEEXTENDED_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("COUNTValueExtended error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_pdcp_snextended(ptr, &ie->pDCP_SNExtended) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_hfnmodified(ptr, &ie->hFNModified) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CriticalityDiagnostics_IE_List DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics_ie_list( + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_LIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CriticalityDiagnostics_IE_List pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_criticalitydiagnostics_ie_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ie_list( + uint8_t **ptr, + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_IE_LIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CriticalityDiagnostics_IE_List unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_criticalitydiagnostics_ie_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Global_ENB_ID SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_global_enb_id( + LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Global_ENB_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->pLMNidentity, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_enb_id(&ie->eNB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_global_enb_id( + uint8_t **ptr, + LIBLTE_S1AP_GLOBAL_ENB_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Global_ENB_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->pLMNidentity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_enb_id(ptr, &ie->eNB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EPLMNs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:15 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eplmns( + LIBLTE_S1AP_EPLMNS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("EPLMNs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 4); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tbcd_string(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eplmns( + uint8_t **ptr, + LIBLTE_S1AP_EPLMNS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 4) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("EPLMNs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabitem( + LIBLTE_S1AP_E_RABITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_cause(&ie->cause, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_cause(ptr, &ie->cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EUTRAN_CGI SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eutran_cgi( + LIBLTE_S1AP_EUTRAN_CGI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("EUTRAN_CGI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->pLMNidentity, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_cellidentity(&ie->cell_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eutran_cgi( + uint8_t **ptr, + LIBLTE_S1AP_EUTRAN_CGI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("EUTRAN_CGI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->pLMNidentity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_cellidentity(ptr, &ie->cell_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ForbiddenTAs_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddentas_item( + LIBLTE_S1AP_FORBIDDENTAS_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ForbiddenTAs_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->pLMN_Identity, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_forbiddentacs(&ie->forbiddenTACs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddentas_item( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENTAS_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ForbiddenTAs_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->pLMN_Identity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_forbiddentacs(ptr, &ie->forbiddenTACs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ForbiddenLAs_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddenlas_item( + LIBLTE_S1AP_FORBIDDENLAS_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ForbiddenLAs_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->pLMN_Identity, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_forbiddenlacs(&ie->forbiddenLACs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddenlas_item( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENLAS_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ForbiddenLAs_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->pLMN_Identity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_forbiddenlacs(ptr, &ie->forbiddenLACs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LAI SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lai( + LIBLTE_S1AP_LAI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("LAI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->pLMNidentity, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_lac(&ie->lAC, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lai( + uint8_t **ptr, + LIBLTE_S1AP_LAI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("LAI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->pLMNidentity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_lac(ptr, &ie->lAC) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M4Configuration SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m4configuration( + LIBLTE_S1AP_M4CONFIGURATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M4Configuration error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_m4period(&ie->m4period, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_links_to_log(&ie->m4_links_to_log, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m4configuration( + uint8_t **ptr, + LIBLTE_S1AP_M4CONFIGURATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M4Configuration error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_m4period(ptr, &ie->m4period) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_links_to_log(ptr, &ie->m4_links_to_log) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MDTPLMNList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdtplmnlist( + LIBLTE_S1AP_MDTPLMNLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("MDTPLMNList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 4); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tbcd_string(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdtplmnlist( + uint8_t **ptr, + LIBLTE_S1AP_MDTPLMNLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 4) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("MDTPLMNList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MMERelaySupportIndicator ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmerelaysupportindicator( + LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("MMERelaySupportIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmerelaysupportindicator( + uint8_t **ptr, + LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("MMERelaySupportIndicator error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_MMERELAYSUPPORTINDICATOR_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PagingPriority ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pagingpriority( + LIBLTE_S1AP_PAGINGPRIORITY_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("PagingPriority error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pagingpriority( + uint8_t **ptr, + LIBLTE_S1AP_PAGINGPRIORITY_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("PagingPriority error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_PAGINGPRIORITY_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PriorityLevel INTEGER +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_prioritylevel( + LIBLTE_S1AP_PRIORITYLEVEL_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->PriorityLevel + // lb:0, ub:15 + liblte_value_2_bits(ie->PriorityLevel, ptr, 4); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_prioritylevel( + uint8_t **ptr, + LIBLTE_S1AP_PRIORITYLEVEL_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Integer - ie->PriorityLevel + // lb:0, ub:15 + ie->PriorityLevel = (uint8_t)liblte_bits_2_value(ptr, 4); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ECGIListForRestart DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ecgilistforrestart( + LIBLTE_S1AP_ECGILISTFORRESTART_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ECGIListForRestart pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_eutran_cgi(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ecgilistforrestart( + uint8_t **ptr, + LIBLTE_S1AP_ECGILISTFORRESTART_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ECGIListForRestart unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SourceeNB_ID SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_id( + LIBLTE_S1AP_SOURCEENB_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_global_enb_id(&ie->global_ENB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_tai(&ie->selected_TAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_id( + uint8_t **ptr, + LIBLTE_S1AP_SOURCEENB_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_global_enb_id(ptr, &ie->global_ENB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_tai(ptr, &ie->selected_TAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ServedPLMNs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:32 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedplmns( + LIBLTE_S1AP_SERVEDPLMNS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ServedPLMNs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 5); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tbcd_string(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedplmns( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDPLMNS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 5) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ServedPLMNs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SupportedTAs_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_supportedtas_item( + LIBLTE_S1AP_SUPPORTEDTAS_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SupportedTAs_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tac(&ie->tAC, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_bplmns(&ie->broadcastPLMNs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_supportedtas_item( + uint8_t **ptr, + LIBLTE_S1AP_SUPPORTEDTAS_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SupportedTAs_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tac(ptr, &ie->tAC) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_bplmns(ptr, &ie->broadcastPLMNs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAIListforMDT DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:8 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tailistformdt( + LIBLTE_S1AP_TAILISTFORMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("TAIListforMDT pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 3); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tai(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tailistformdt( + uint8_t **ptr, + LIBLTE_S1AP_TAILISTFORMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 3) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("TAIListforMDT unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tai(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CompletedCellinTAI_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellintai_item( + LIBLTE_S1AP_COMPLETEDCELLINTAI_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CompletedCellinTAI_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eutran_cgi(&ie->eCGI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellintai_item( + uint8_t **ptr, + LIBLTE_S1AP_COMPLETEDCELLINTAI_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CompletedCellinTAI_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->eCGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TargeteNB_ID SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_id( + LIBLTE_S1AP_TARGETENB_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TargeteNB_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_global_enb_id(&ie->global_ENB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_tai(&ie->selected_TAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_id( + uint8_t **ptr, + LIBLTE_S1AP_TARGETENB_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TargeteNB_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_global_enb_id(ptr, &ie->global_ENB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_tai(ptr, &ie->selected_TAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TargetBSS_ToSourceBSS_TransparentContainer DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetbss_tosourcebss_transparentcontainer( + LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - TargetBSS-ToSourceBSS-TransparentContainer + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetbss_tosourcebss_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_TARGETBSS_TOSOURCEBSS_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - TargetBSS-ToSourceBSS-TransparentContainer + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAIListForRestart DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:2048 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tailistforrestart( + LIBLTE_S1AP_TAILISTFORRESTART_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("TAIListForRestart pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 11); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tai(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tailistforrestart( + uint8_t **ptr, + LIBLTE_S1AP_TAILISTFORRESTART_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 11) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("TAIListForRestart unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tai(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UserLocationInformation SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_userlocationinformation( + LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("UserLocationInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eutran_cgi(&ie->eutran_cgi, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_tai(&ie->tai, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_userlocationinformation( + uint8_t **ptr, + LIBLTE_S1AP_USERLOCATIONINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("UserLocationInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->eutran_cgi) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_tai(ptr, &ie->tai) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ENBX2ExtTLAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2exttlas( + LIBLTE_S1AP_ENBX2EXTTLAS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ENBX2ExtTLAs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 4); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_enbx2exttla(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2exttlas( + uint8_t **ptr, + LIBLTE_S1AP_ENBX2EXTTLAS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 4) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ENBX2ExtTLAs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_enbx2exttla(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE AllocationAndRetentionPriority SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_allocationandretentionpriority( + LIBLTE_S1AP_ALLOCATIONANDRETENTIONPRIORITY_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("AllocationAndRetentionPriority error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_prioritylevel(&ie->priorityLevel, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum - ie->pre_emptionCapability + liblte_value_2_bits(ie->pre_emptionCapability, ptr, 1); + + // Enum - ie->pre_emptionVulnerability + liblte_value_2_bits(ie->pre_emptionVulnerability, ptr, 1); + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_allocationandretentionpriority( + uint8_t **ptr, + LIBLTE_S1AP_ALLOCATIONANDRETENTIONPRIORITY_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("AllocationAndRetentionPriority error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_prioritylevel(ptr, &ie->priorityLevel) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum - ie->pre_emptionCapability + ie->pre_emptionCapability = (LIBLTE_S1AP_PRE_EMPTIONCAPABILITY_ENUM)liblte_bits_2_value(ptr, 1); + + // Enum - ie->pre_emptionVulnerability + ie->pre_emptionVulnerability = (LIBLTE_S1AP_PRE_EMPTIONVULNERABILITY_ENUM)liblte_bits_2_value(ptr, 1); + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CancelledCellinEAI_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellineai_item( + LIBLTE_S1AP_CANCELLEDCELLINEAI_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CancelledCellinEAI_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eutran_cgi(&ie->eCGI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_numberofbroadcasts(&ie->numberOfBroadcasts, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellineai_item( + uint8_t **ptr, + LIBLTE_S1AP_CANCELLEDCELLINEAI_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CancelledCellinEAI_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->eCGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_numberofbroadcasts(ptr, &ie->numberOfBroadcasts) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CancelledCellinTAI_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellintai_item( + LIBLTE_S1AP_CANCELLEDCELLINTAI_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CancelledCellinTAI_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eutran_cgi(&ie->eCGI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_numberofbroadcasts(&ie->numberOfBroadcasts, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellintai_item( + uint8_t **ptr, + LIBLTE_S1AP_CANCELLEDCELLINTAI_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CancelledCellinTAI_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->eCGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_numberofbroadcasts(ptr, &ie->numberOfBroadcasts) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellID_Broadcast_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_broadcast_item( + LIBLTE_S1AP_CELLID_BROADCAST_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CellID_Broadcast_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eutran_cgi(&ie->eCGI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_broadcast_item( + uint8_t **ptr, + LIBLTE_S1AP_CELLID_BROADCAST_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CellID_Broadcast_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->eCGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellID_Cancelled_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_cancelled_item( + LIBLTE_S1AP_CELLID_CANCELLED_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CellID_Cancelled_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eutran_cgi(&ie->eCGI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_numberofbroadcasts(&ie->numberOfBroadcasts, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_cancelled_item( + uint8_t **ptr, + LIBLTE_S1AP_CELLID_CANCELLED_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CellID_Cancelled_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->eCGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_numberofbroadcasts(ptr, &ie->numberOfBroadcasts) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellIdListforMDT DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:32 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellidlistformdt( + LIBLTE_S1AP_CELLIDLISTFORMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CellIdListforMDT pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 5); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_eutran_cgi(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellidlistformdt( + uint8_t **ptr, + LIBLTE_S1AP_CELLIDLISTFORMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 5) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CellIdListforMDT unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CSG_Id STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csg_id( + LIBLTE_S1AP_CSG_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - CSG-Id + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csg_id( + uint8_t **ptr, + LIBLTE_S1AP_CSG_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - CSG-Id + liblte_align_up(ptr, 8); + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CSG_IdList_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csg_idlist_item( + LIBLTE_S1AP_CSG_IDLIST_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CSG_IdList_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_csg_id(&ie->cSG_Id, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csg_idlist_item( + uint8_t **ptr, + LIBLTE_S1AP_CSG_IDLIST_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CSG_IdList_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_csg_id(ptr, &ie->cSG_Id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Direct_Forwarding_Path_Availability ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_direct_forwarding_path_availability( + LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Direct_Forwarding_Path_Availability error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_direct_forwarding_path_availability( + uint8_t **ptr, + LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Direct_Forwarding_Path_Availability error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_DIRECT_FORWARDING_PATH_AVAILABILITY_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CompletedCellinEAI_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellineai_item( + LIBLTE_S1AP_COMPLETEDCELLINEAI_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CompletedCellinEAI_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eutran_cgi(&ie->eCGI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellineai_item( + uint8_t **ptr, + LIBLTE_S1AP_COMPLETEDCELLINEAI_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CompletedCellinEAI_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->eCGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABInformationList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabinformationlist( + LIBLTE_S1AP_E_RABINFORMATIONLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABInformationList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabinformationlistitem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABINFORMATIONLISTITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABINFORMATIONLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABInformationList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABINFORMATIONLISTITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabinformationlistitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ForbiddenTAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddentas( + LIBLTE_S1AP_FORBIDDENTAS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ForbiddenTAs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 4); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_forbiddentas_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddentas( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENTAS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 4) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ForbiddenTAs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_forbiddentas_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE GUMMEI SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gummei( + LIBLTE_S1AP_GUMMEI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("GUMMEI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->pLMN_Identity, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_mme_group_id(&ie->mME_Group_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_mme_code(&ie->mME_Code, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gummei( + uint8_t **ptr, + LIBLTE_S1AP_GUMMEI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("GUMMEI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->pLMN_Identity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_mme_group_id(ptr, &ie->mME_Group_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_mme_code(ptr, &ie->mME_Code) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LoggedMDT SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_loggedmdt( + LIBLTE_S1AP_LOGGEDMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("LoggedMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + // Enum - ie->loggingInterval + liblte_value_2_bits(ie->loggingInterval, ptr, 3); + + // Enum - ie->loggingDuration + liblte_value_2_bits(ie->loggingDuration, ptr, 3); + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_loggedmdt( + uint8_t **ptr, + LIBLTE_S1AP_LOGGEDMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("LoggedMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + // Enum - ie->loggingInterval + ie->loggingInterval = (LIBLTE_S1AP_LOGGINGINTERVAL_ENUM)liblte_bits_2_value(ptr, 3); + + // Enum - ie->loggingDuration + ie->loggingDuration = (LIBLTE_S1AP_LOGGINGDURATION_ENUM)liblte_bits_2_value(ptr, 3); + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE NASSecurityParametersfromE_UTRAN DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nassecurityparametersfrome_utran( + LIBLTE_S1AP_NASSECURITYPARAMETERSFROME_UTRAN_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - NASSecurityParametersfromE-UTRAN + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nassecurityparametersfrome_utran( + uint8_t **ptr, + LIBLTE_S1AP_NASSECURITYPARAMETERSFROME_UTRAN_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - NASSecurityParametersfromE-UTRAN + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ReportAmountMDT ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_reportamountmdt( + LIBLTE_S1AP_REPORTAMOUNTMDT_ENUM *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + liblte_value_2_bits(*ie, ptr, 3); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_reportamountmdt( + uint8_t **ptr, + LIBLTE_S1AP_REPORTAMOUNTMDT_ENUM *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Enum - *ie + *ie = (LIBLTE_S1AP_REPORTAMOUNTMDT_ENUM)liblte_bits_2_value(ptr, 3); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ServedGUMMEIsItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedgummeisitem( + LIBLTE_S1AP_SERVEDGUMMEISITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ServedGUMMEIsItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_servedplmns(&ie->servedPLMNs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_servedgroupids(&ie->servedGroupIDs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_servedmmecs(&ie->servedMMECs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedgummeisitem( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDGUMMEISITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ServedGUMMEIsItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_servedplmns(ptr, &ie->servedPLMNs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_servedgroupids(ptr, &ie->servedGroupIDs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_servedmmecs(ptr, &ie->servedMMECs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE S_TMSI SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s_tmsi( + LIBLTE_S1AP_S_TMSI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("S_TMSI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_mme_code(&ie->mMEC, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_m_tmsi(&ie->m_TMSI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s_tmsi( + uint8_t **ptr, + LIBLTE_S1AP_S_TMSI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("S_TMSI error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_mme_code(ptr, &ie->mMEC) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_m_tmsi(ptr, &ie->m_TMSI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAIListforWarning DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tailistforwarning( + LIBLTE_S1AP_TAILISTFORWARNING_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("TAIListforWarning pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tai(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tailistforwarning( + uint8_t **ptr, + LIBLTE_S1AP_TAILISTFORWARNING_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("TAIListforWarning unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tai(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CompletedCellinTAI DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellintai( + LIBLTE_S1AP_COMPLETEDCELLINTAI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CompletedCellinTAI pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_completedcellintai_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellintai( + uint8_t **ptr, + LIBLTE_S1AP_COMPLETEDCELLINTAI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CompletedCellinTAI unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_completedcellintai_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TargetRNC_ID SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetrnc_id( + LIBLTE_S1AP_TARGETRNC_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TargetRNC_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->rAC_present?1:0, ptr, 1); + liblte_value_2_bits(ie->extendedRNC_ID_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_lai(&ie->lAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->rAC_present) { + if(liblte_s1ap_pack_rac(&ie->rAC, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(liblte_s1ap_pack_rnc_id(&ie->rNC_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->extendedRNC_ID_present) { + if(liblte_s1ap_pack_extendedrnc_id(&ie->extendedRNC_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetrnc_id( + uint8_t **ptr, + LIBLTE_S1AP_TARGETRNC_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TargetRNC_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->rAC_present = liblte_bits_2_value(ptr, 1); + ie->extendedRNC_ID_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_lai(ptr, &ie->lAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->rAC_present) { + if(liblte_s1ap_unpack_rac(ptr, &ie->rAC) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(liblte_s1ap_unpack_rnc_id(ptr, &ie->rNC_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->extendedRNC_ID_present) { + if(liblte_s1ap_unpack_extendedrnc_id(ptr, &ie->extendedRNC_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UE_associatedLogicalS1_ConnectionItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitem( + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("UE_associatedLogicalS1_ConnectionItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->mME_UE_S1AP_ID_present?1:0, ptr, 1); + liblte_value_2_bits(ie->eNB_UE_S1AP_ID_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(ie->mME_UE_S1AP_ID_present) { + if(liblte_s1ap_pack_mme_ue_s1ap_id(&ie->mME_UE_S1AP_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->eNB_UE_S1AP_ID_present) { + if(liblte_s1ap_pack_enb_ue_s1ap_id(&ie->eNB_UE_S1AP_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitem( + uint8_t **ptr, + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("UE_associatedLogicalS1_ConnectionItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->mME_UE_S1AP_ID_present = liblte_bits_2_value(ptr, 1); + ie->eNB_UE_S1AP_ID_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(ie->mME_UE_S1AP_ID_present) { + if(liblte_s1ap_unpack_mme_ue_s1ap_id(ptr, &ie->mME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->eNB_UE_S1AP_ID_present) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &ie->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UEPagingID CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uepagingid( + LIBLTE_S1AP_UEPAGINGID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("UEPagingID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_UEPAGINGID_CHOICE_S_TMSI) { + if(liblte_s1ap_pack_s_tmsi(&ie->choice.s_TMSI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_UEPAGINGID_CHOICE_IMSI) { + if(liblte_s1ap_pack_imsi(&ie->choice.iMSI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uepagingid( + uint8_t **ptr, + LIBLTE_S1AP_UEPAGINGID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("UEPagingID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_UEPAGINGID_CHOICE_ENUM)liblte_bits_2_value(ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_UEPAGINGID_CHOICE_S_TMSI) { + if(liblte_s1ap_unpack_s_tmsi(ptr, &ie->choice.s_TMSI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_UEPAGINGID_CHOICE_IMSI) { + if(liblte_s1ap_unpack_imsi(ptr, &ie->choice.iMSI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Bearers_SubjectToStatusTransfer_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_item( + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Bearers_SubjectToStatusTransfer_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->receiveStatusofULPDCPSDUs_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_countvalue(&ie->uL_COUNTvalue, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_countvalue(&ie->dL_COUNTvalue, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->receiveStatusofULPDCPSDUs_present) { + if(liblte_s1ap_pack_receivestatusofulpdcpsdus(&ie->receiveStatusofULPDCPSDUs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransfer_item( + uint8_t **ptr, + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Bearers_SubjectToStatusTransfer_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->receiveStatusofULPDCPSDUs_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_countvalue(ptr, &ie->uL_COUNTvalue) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_countvalue(ptr, &ie->dL_COUNTvalue) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->receiveStatusofULPDCPSDUs_present) { + if(liblte_s1ap_unpack_receivestatusofulpdcpsdus(ptr, &ie->receiveStatusofULPDCPSDUs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CancelledCellinEAI DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellineai( + LIBLTE_S1AP_CANCELLEDCELLINEAI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CancelledCellinEAI pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_cancelledcellineai_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellineai( + uint8_t **ptr, + LIBLTE_S1AP_CANCELLEDCELLINEAI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CancelledCellinEAI unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_cancelledcellineai_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellID_Broadcast DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_broadcast( + LIBLTE_S1AP_CELLID_BROADCAST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CellID_Broadcast pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_cellid_broadcast_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_broadcast( + uint8_t **ptr, + LIBLTE_S1AP_CELLID_BROADCAST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CellID_Broadcast unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_cellid_broadcast_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellBasedMDT SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellbasedmdt( + LIBLTE_S1AP_CELLBASEDMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CellBasedMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_cellidlistformdt(&ie->cellIdListforMDT, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellbasedmdt( + uint8_t **ptr, + LIBLTE_S1AP_CELLBASEDMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CellBasedMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_cellidlistformdt(ptr, &ie->cellIdListforMDT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CSG_IdList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csg_idlist( + LIBLTE_S1AP_CSG_IDLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CSG_IdList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_csg_idlist_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csg_idlist( + uint8_t **ptr, + LIBLTE_S1AP_CSG_IDLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CSG_IdList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_csg_idlist_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ECGIList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ecgilist( + LIBLTE_S1AP_ECGILIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ECGIList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_eutran_cgi(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ecgilist( + uint8_t **ptr, + LIBLTE_S1AP_ECGILIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ECGIList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID_Cancelled_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_cancelled_item( + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("EmergencyAreaID_Cancelled_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_emergencyareaid(&ie->emergencyAreaID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_cancelledcellineai(&ie->cancelledCellinEAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_cancelled_item( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("EmergencyAreaID_Cancelled_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_emergencyareaid(ptr, &ie->emergencyAreaID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_cancelledcellineai(ptr, &ie->cancelledCellinEAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE GERAN_Cell_ID SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_geran_cell_id( + LIBLTE_S1AP_GERAN_CELL_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("GERAN_Cell_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_lai(&ie->lAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_rac(&ie->rAC, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_ci(&ie->cI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_geran_cell_id( + uint8_t **ptr, + LIBLTE_S1AP_GERAN_CELL_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("GERAN_Cell_ID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_lai(ptr, &ie->lAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_rac(ptr, &ie->rAC) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_ci(ptr, &ie->cI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rablist( + LIBLTE_S1AP_E_RABLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabitem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rablist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ForbiddenLAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddenlas( + LIBLTE_S1AP_FORBIDDENLAS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ForbiddenLAs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 4); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_forbiddenlas_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddenlas( + uint8_t **ptr, + LIBLTE_S1AP_FORBIDDENLAS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 4) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ForbiddenLAs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_forbiddenlas_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MDT_Location_Info STATIC BIT STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdt_location_info( + LIBLTE_S1AP_MDT_LOCATION_INFO_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - MDT-Location-Info + uint32_t i; + for(i=0;ibuffer[i], ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdt_location_info( + uint8_t **ptr, + LIBLTE_S1AP_MDT_LOCATION_INFO_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Static bit string - MDT-Location-Info + uint32_t i; + for(i=0;ibuffer[i] = liblte_bits_2_value(ptr, 1); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE M1PeriodicReporting SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1periodicreporting( + LIBLTE_S1AP_M1PERIODICREPORTING_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("M1PeriodicReporting error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + // Enum - ie->reportInterval + liblte_value_2_bits(ie->reportInterval, ptr, 4); + + // Enum - ie->reportAmount + liblte_value_2_bits(ie->reportAmount, ptr, 3); + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1periodicreporting( + uint8_t **ptr, + LIBLTE_S1AP_M1PERIODICREPORTING_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("M1PeriodicReporting error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + // Enum - ie->reportInterval + ie->reportInterval = (LIBLTE_S1AP_REPORTINTERVALMDT_ENUM)liblte_bits_2_value(ptr, 4); + + // Enum - ie->reportAmount + ie->reportAmount = (LIBLTE_S1AP_REPORTAMOUNTMDT_ENUM)liblte_bits_2_value(ptr, 3); + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* ProtocolIE eHRPD_Sector_ID DYNAMIC OCTET STRING +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ehrpd_sector_id( + LIBLTE_S1AP_EHRPD_SECTOR_ID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - eHRPD-Sector-ID + // Length + if(ie->n_octets < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 7); + } else if(ie->n_octets < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(ie->n_octets, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + liblte_value_2_bits(ie->buffer[i], ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ehrpd_sector_id( + uint8_t **ptr, + LIBLTE_S1AP_EHRPD_SECTOR_ID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Dynamic octet string - eHRPD-Sector-ID + // Length + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + ie->n_octets = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Octets + uint32_t i; + for(i=0;in_octets;i++) { + ie->buffer[i] = liblte_bits_2_value(ptr, 8); + } + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* ProtocolIE RIMRoutingAddress CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rimroutingaddress( + LIBLTE_S1AP_RIMROUTINGADDRESS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("RIMRoutingAddress error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_GERAN_CELL_ID) { + if(liblte_s1ap_pack_geran_cell_id(&ie->choice.gERAN_Cell_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_TARGETRNC_ID) { + if(liblte_s1ap_pack_targetrnc_id(&ie->choice.targetRNC_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_EHRPD_SECTOR_ID) { + if(liblte_s1ap_pack_ehrpd_sector_id(&ie->choice.eHRPD_Sector_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rimroutingaddress( + uint8_t **ptr, + LIBLTE_S1AP_RIMROUTINGADDRESS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("RIMRoutingAddress error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_ENUM)liblte_bits_2_value(ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_GERAN_CELL_ID) { + if(liblte_s1ap_unpack_geran_cell_id(ptr, &ie->choice.gERAN_Cell_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_TARGETRNC_ID) { + if(liblte_s1ap_unpack_targetrnc_id(ptr, &ie->choice.targetRNC_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_RIMROUTINGADDRESS_CHOICE_EHRPD_SECTOR_ID) { + if(liblte_s1ap_unpack_ehrpd_sector_id(ptr, &ie->choice.eHRPD_Sector_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ServedGUMMEIs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:8 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedgummeis( + LIBLTE_S1AP_SERVEDGUMMEIS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("ServedGUMMEIs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 3); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_servedgummeisitem(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedgummeis( + uint8_t **ptr, + LIBLTE_S1AP_SERVEDGUMMEIS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 3) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("ServedGUMMEIs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_servedgummeisitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAIBasedMDT SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taibasedmdt( + LIBLTE_S1AP_TAIBASEDMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TAIBasedMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tailistformdt(&ie->tAIListforMDT, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taibasedmdt( + uint8_t **ptr, + LIBLTE_S1AP_TAIBASEDMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TAIBasedMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tailistformdt(ptr, &ie->tAIListforMDT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAI_Broadcast_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_broadcast_item( + LIBLTE_S1AP_TAI_BROADCAST_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TAI_Broadcast_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tai(&ie->tAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_completedcellintai(&ie->completedCellinTAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_broadcast_item( + uint8_t **ptr, + LIBLTE_S1AP_TAI_BROADCAST_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TAI_Broadcast_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tai(ptr, &ie->tAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_completedcellintai(ptr, &ie->completedCellinTAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TargetID CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetid( + LIBLTE_S1AP_TARGETID_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TargetID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_TARGETID_CHOICE_TARGETENB_ID) { + if(liblte_s1ap_pack_targetenb_id(&ie->choice.targeteNB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_TARGETID_CHOICE_TARGETRNC_ID) { + if(liblte_s1ap_pack_targetrnc_id(&ie->choice.targetRNC_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_TARGETID_CHOICE_CGI) { + if(liblte_s1ap_pack_cgi(&ie->choice.cGI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetid( + uint8_t **ptr, + LIBLTE_S1AP_TARGETID_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TargetID error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_TARGETID_CHOICE_ENUM)liblte_bits_2_value(ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_TARGETID_CHOICE_TARGETENB_ID) { + if(liblte_s1ap_unpack_targetenb_id(ptr, &ie->choice.targeteNB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_TARGETID_CHOICE_TARGETRNC_ID) { + if(liblte_s1ap_unpack_targetrnc_id(ptr, &ie->choice.targetRNC_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_TARGETID_CHOICE_CGI) { + if(liblte_s1ap_unpack_cgi(ptr, &ie->choice.cGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE WarningAreaList CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_warningarealist( + LIBLTE_S1AP_WARNINGAREALIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("WarningAreaList error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_WARNINGAREALIST_CHOICE_CELLIDLIST) { + if(liblte_s1ap_pack_ecgilist(&ie->choice.cellIDList, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_WARNINGAREALIST_CHOICE_TRACKINGAREALISTFORWARNING) { + if(liblte_s1ap_pack_tailistforwarning(&ie->choice.trackingAreaListforWarning, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_WARNINGAREALIST_CHOICE_EMERGENCYAREAIDLIST) { + if(liblte_s1ap_pack_emergencyareaidlist(&ie->choice.emergencyAreaIDList, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_warningarealist( + uint8_t **ptr, + LIBLTE_S1AP_WARNINGAREALIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("WarningAreaList error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_WARNINGAREALIST_CHOICE_ENUM)liblte_bits_2_value(ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_WARNINGAREALIST_CHOICE_CELLIDLIST) { + if(liblte_s1ap_unpack_ecgilist(ptr, &ie->choice.cellIDList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_WARNINGAREALIST_CHOICE_TRACKINGAREALISTFORWARNING) { + if(liblte_s1ap_unpack_tailistforwarning(ptr, &ie->choice.trackingAreaListforWarning) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_WARNINGAREALIST_CHOICE_EMERGENCYAREAIDLIST) { + if(liblte_s1ap_unpack_emergencyareaidlist(ptr, &ie->choice.emergencyAreaIDList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE AreaScopeOfMDT CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_areascopeofmdt( + LIBLTE_S1AP_AREASCOPEOFMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("AreaScopeOfMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_CELLBASED) { + if(liblte_s1ap_pack_cellbasedmdt(&ie->choice.cellBased, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_TABASED) { + if(liblte_s1ap_pack_tabasedmdt(&ie->choice.tABased, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_PLMNWIDE) { + } else if(ie->choice_type == LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_TAIBASED) { + if(liblte_s1ap_pack_taibasedmdt(&ie->choice.tAIBased, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_areascopeofmdt( + uint8_t **ptr, + LIBLTE_S1AP_AREASCOPEOFMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("AreaScopeOfMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_ENUM)liblte_bits_2_value(ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_CELLBASED) { + if(liblte_s1ap_unpack_cellbasedmdt(ptr, &ie->choice.cellBased) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_TABASED) { + if(liblte_s1ap_unpack_tabasedmdt(ptr, &ie->choice.tABased) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_PLMNWIDE) { + } else if(ie->choice_type == LIBLTE_S1AP_AREASCOPEOFMDT_CHOICE_TAIBASED) { + if(liblte_s1ap_unpack_taibasedmdt(ptr, &ie->choice.tAIBased) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CancelledCellinTAI DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellintai( + LIBLTE_S1AP_CANCELLEDCELLINTAI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CancelledCellinTAI pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_cancelledcellintai_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellintai( + uint8_t **ptr, + LIBLTE_S1AP_CANCELLEDCELLINTAI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CancelledCellinTAI unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_cancelledcellintai_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellType SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_celltype( + LIBLTE_S1AP_CELLTYPE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CellType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_cell_size(&ie->cell_Size, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_celltype( + uint8_t **ptr, + LIBLTE_S1AP_CELLTYPE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CellType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_cell_size(ptr, &ie->cell_Size) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID_Cancelled DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_cancelled( + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("EmergencyAreaID_Cancelled pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_emergencyareaid_cancelled_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_cancelled( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_CANCELLED_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("EmergencyAreaID_Cancelled unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_emergencyareaid_cancelled_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE GUMMEIList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gummeilist( + LIBLTE_S1AP_GUMMEILIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("GUMMEIList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_gummei(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gummeilist( + uint8_t **ptr, + LIBLTE_S1AP_GUMMEILIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("GUMMEIList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_gummei(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABLevelQoSParameters SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rablevelqosparameters( + LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABLevelQoSParameters error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->gbrQosInformation_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_qci(&ie->qCI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_allocationandretentionpriority(&ie->allocationRetentionPriority, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->gbrQosInformation_present) { + if(liblte_s1ap_pack_gbr_qosinformation(&ie->gbrQosInformation, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rablevelqosparameters( + uint8_t **ptr, + LIBLTE_S1AP_E_RABLEVELQOSPARAMETERS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABLevelQoSParameters error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->gbrQosInformation_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_qci(ptr, &ie->qCI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_allocationandretentionpriority(ptr, &ie->allocationRetentionPriority) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->gbrQosInformation_present) { + if(liblte_s1ap_unpack_gbr_qosinformation(ptr, &ie->gbrQosInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LastVisitedEUTRANCellInformation SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedeutrancellinformation( + LIBLTE_S1AP_LASTVISITEDEUTRANCELLINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("LastVisitedEUTRANCellInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_eutran_cgi(&ie->global_Cell_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_celltype(&ie->cellType, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_time_ue_stayedincell(&ie->time_UE_StayedInCell, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedeutrancellinformation( + uint8_t **ptr, + LIBLTE_S1AP_LASTVISITEDEUTRANCELLINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("LastVisitedEUTRANCellInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->global_Cell_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_celltype(ptr, &ie->cellType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_time_ue_stayedincell(ptr, &ie->time_UE_StayedInCell) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE RIMTransfer SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rimtransfer( + LIBLTE_S1AP_RIMTRANSFER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("RIMTransfer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->rIMRoutingAddress_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_riminformation(&ie->rIMInformation, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->rIMRoutingAddress_present) { + if(liblte_s1ap_pack_rimroutingaddress(&ie->rIMRoutingAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rimtransfer( + uint8_t **ptr, + LIBLTE_S1AP_RIMTRANSFER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("RIMTransfer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->rIMRoutingAddress_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_riminformation(ptr, &ie->rIMInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->rIMRoutingAddress_present) { + if(liblte_s1ap_unpack_rimroutingaddress(ptr, &ie->rIMRoutingAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SupportedTAs DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_supportedtas( + LIBLTE_S1AP_SUPPORTEDTAS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("SupportedTAs pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_supportedtas_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_supportedtas( + uint8_t **ptr, + LIBLTE_S1AP_SUPPORTEDTAS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("SupportedTAs unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_supportedtas_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAI_Cancelled_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_cancelled_item( + LIBLTE_S1AP_TAI_CANCELLED_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TAI_Cancelled_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tai(&ie->tAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_cancelledcellintai(&ie->cancelledCellinTAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_cancelled_item( + uint8_t **ptr, + LIBLTE_S1AP_TAI_CANCELLED_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TAI_Cancelled_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tai(ptr, &ie->tAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_cancelledcellintai(ptr, &ie->cancelledCellinTAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE X2TNLConfigurationInfo SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_x2tnlconfigurationinfo( + LIBLTE_S1AP_X2TNLCONFIGURATIONINFO_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("X2TNLConfigurationInfo error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_enbx2tlas(&ie->eNBX2TransportLayerAddresses, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_x2tnlconfigurationinfo( + uint8_t **ptr, + LIBLTE_S1AP_X2TNLCONFIGURATIONINFO_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("X2TNLConfigurationInfo error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_enbx2tlas(ptr, &ie->eNBX2TransportLayerAddresses) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List Bearers_SubjectToStatusTransferList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransferlist( + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFERLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("Bearers_SubjectToStatusTransferList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_bearers_subjecttostatustransfer_item(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransferlist( + uint8_t **ptr, + LIBLTE_S1AP_BEARERS_SUBJECTTOSTATUSTRANSFERLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("Bearers_SubjectToStatusTransferList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_bearers_subjecttostatustransfer_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CellID_Cancelled DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_cancelled( + LIBLTE_S1AP_CELLID_CANCELLED_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CellID_Cancelled pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_cellid_cancelled_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_cancelled( + uint8_t **ptr, + LIBLTE_S1AP_CELLID_CANCELLED_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CellID_Cancelled unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_cellid_cancelled_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CompletedCellinEAI DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellineai( + LIBLTE_S1AP_COMPLETEDCELLINEAI_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("CompletedCellinEAI pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_completedcellineai_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellineai( + uint8_t **ptr, + LIBLTE_S1AP_COMPLETEDCELLINEAI_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("CompletedCellinEAI unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_completedcellineai_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE HandoverRestrictionList SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrestrictionlist( + LIBLTE_S1AP_HANDOVERRESTRICTIONLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("HandoverRestrictionList error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->equivalentPLMNs_present?1:0, ptr, 1); + liblte_value_2_bits(ie->forbiddenTAs_present?1:0, ptr, 1); + liblte_value_2_bits(ie->forbiddenLAs_present?1:0, ptr, 1); + liblte_value_2_bits(ie->forbiddenInterRATs_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tbcd_string(&ie->servingPLMN, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->equivalentPLMNs_present) { + if(liblte_s1ap_pack_eplmns(&ie->equivalentPLMNs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->forbiddenTAs_present) { + if(liblte_s1ap_pack_forbiddentas(&ie->forbiddenTAs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->forbiddenLAs_present) { + if(liblte_s1ap_pack_forbiddenlas(&ie->forbiddenLAs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->forbiddenInterRATs_present) { + if(liblte_s1ap_pack_forbiddeninterrats(&ie->forbiddenInterRATs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrestrictionlist( + uint8_t **ptr, + LIBLTE_S1AP_HANDOVERRESTRICTIONLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("HandoverRestrictionList error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->equivalentPLMNs_present = liblte_bits_2_value(ptr, 1); + ie->forbiddenTAs_present = liblte_bits_2_value(ptr, 1); + ie->forbiddenLAs_present = liblte_bits_2_value(ptr, 1); + ie->forbiddenInterRATs_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tbcd_string(ptr, &ie->servingPLMN) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->equivalentPLMNs_present) { + if(liblte_s1ap_unpack_eplmns(ptr, &ie->equivalentPLMNs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->forbiddenTAs_present) { + if(liblte_s1ap_unpack_forbiddentas(ptr, &ie->forbiddenTAs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->forbiddenLAs_present) { + if(liblte_s1ap_unpack_forbiddenlas(ptr, &ie->forbiddenLAs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->forbiddenInterRATs_present) { + if(liblte_s1ap_unpack_forbiddeninterrats(ptr, &ie->forbiddenInterRATs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE LastVisitedCell_Item CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedcell_item( + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("LastVisitedCell_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_E_UTRAN_CELL) { + if(liblte_s1ap_pack_lastvisitedeutrancellinformation(&ie->choice.e_UTRAN_Cell, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_UTRAN_CELL) { + if(liblte_s1ap_pack_lastvisitedutrancellinformation(&ie->choice.uTRAN_Cell, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_GERAN_CELL) { + if(liblte_s1ap_pack_lastvisitedgerancellinformation(&ie->choice.gERAN_Cell, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedcell_item( + uint8_t **ptr, + LIBLTE_S1AP_LASTVISITEDCELL_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("LastVisitedCell_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_ENUM)liblte_bits_2_value(ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_E_UTRAN_CELL) { + if(liblte_s1ap_unpack_lastvisitedeutrancellinformation(ptr, &ie->choice.e_UTRAN_Cell) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_UTRAN_CELL) { + if(liblte_s1ap_unpack_lastvisitedutrancellinformation(ptr, &ie->choice.uTRAN_Cell) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_GERAN_CELL) { + if(liblte_s1ap_unpack_lastvisitedgerancellinformation(ptr, &ie->choice.gERAN_Cell) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SONInformationReply SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_soninformationreply( + LIBLTE_S1AP_SONINFORMATIONREPLY_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SONInformationReply error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->x2TNLConfigurationInfo_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(ie->x2TNLConfigurationInfo_present) { + if(liblte_s1ap_pack_x2tnlconfigurationinfo(&ie->x2TNLConfigurationInfo, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformationreply( + uint8_t **ptr, + LIBLTE_S1AP_SONINFORMATIONREPLY_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SONInformationReply error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->x2TNLConfigurationInfo_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(ie->x2TNLConfigurationInfo_present) { + if(liblte_s1ap_unpack_x2tnlconfigurationinfo(ptr, &ie->x2TNLConfigurationInfo) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAI_Broadcast DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_broadcast( + LIBLTE_S1AP_TAI_BROADCAST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("TAI_Broadcast pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tai_broadcast_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_broadcast( + uint8_t **ptr, + LIBLTE_S1AP_TAI_BROADCAST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("TAI_Broadcast unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tai_broadcast_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TimeToWait ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_timetowait( + LIBLTE_S1AP_TIMETOWAIT_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TimeToWait error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 3); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_timetowait( + uint8_t **ptr, + LIBLTE_S1AP_TIMETOWAIT_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TimeToWait error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_TIMETOWAIT_ENUM)liblte_bits_2_value(ptr, 3); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE UE_HistoryInformation DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:16 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_historyinformation( + LIBLTE_S1AP_UE_HISTORYINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("UE_HistoryInformation pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 4); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_lastvisitedcell_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_historyinformation( + uint8_t **ptr, + LIBLTE_S1AP_UE_HISTORYINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 4) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("UE_HistoryInformation unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_lastvisitedcell_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE CriticalityDiagnostics SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics( + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("CriticalityDiagnostics error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->procedureCode_present?1:0, ptr, 1); + liblte_value_2_bits(ie->triggeringMessage_present?1:0, ptr, 1); + liblte_value_2_bits(ie->procedureCriticality_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iEsCriticalityDiagnostics_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(ie->procedureCode_present) { + if(liblte_s1ap_pack_procedurecode(&ie->procedureCode, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->triggeringMessage_present) { + // Enum - ie->triggeringMessage + liblte_value_2_bits(ie->triggeringMessage, ptr, 2); + } + + if(ie->procedureCriticality_present) { + // Enum - ie->procedureCriticality + liblte_value_2_bits(ie->procedureCriticality, ptr, 2); + } + + if(ie->iEsCriticalityDiagnostics_present) { + if(liblte_s1ap_pack_criticalitydiagnostics_ie_list(&ie->iEsCriticalityDiagnostics, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics( + uint8_t **ptr, + LIBLTE_S1AP_CRITICALITYDIAGNOSTICS_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("CriticalityDiagnostics error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->procedureCode_present = liblte_bits_2_value(ptr, 1); + ie->triggeringMessage_present = liblte_bits_2_value(ptr, 1); + ie->procedureCriticality_present = liblte_bits_2_value(ptr, 1); + ie->iEsCriticalityDiagnostics_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(ie->procedureCode_present) { + if(liblte_s1ap_unpack_procedurecode(ptr, &ie->procedureCode) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->triggeringMessage_present) { + // Enum - ie->triggeringMessage + ie->triggeringMessage = (LIBLTE_S1AP_TRIGGERINGMESSAGE_ENUM)liblte_bits_2_value(ptr, 2); + } + + if(ie->procedureCriticality_present) { + // Enum - ie->procedureCriticality + ie->procedureCriticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + } + + if(ie->iEsCriticalityDiagnostics_present) { + if(liblte_s1ap_unpack_criticalitydiagnostics_ie_list(ptr, &ie->iEsCriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID_Broadcast_Item SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_broadcast_item( + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_ITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("EmergencyAreaID_Broadcast_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_emergencyareaid(&ie->emergencyAreaID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_completedcellineai(&ie->completedCellinEAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_broadcast_item( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_ITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("EmergencyAreaID_Broadcast_Item error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_emergencyareaid(ptr, &ie->emergencyAreaID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_completedcellineai(ptr, &ie->completedCellinEAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ImmediateMDT SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_immediatemdt( + LIBLTE_S1AP_IMMEDIATEMDT_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ImmediateMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->m1thresholdeventA2_present?1:0, ptr, 1); + liblte_value_2_bits(ie->m1periodicReporting_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_measurementstoactivate(&ie->measurementsToActivate, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_m1reportingtrigger(&ie->m1reportingTrigger, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->m1thresholdeventA2_present) { + if(liblte_s1ap_pack_m1thresholdeventa2(&ie->m1thresholdeventA2, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->m1periodicReporting_present) { + if(liblte_s1ap_pack_m1periodicreporting(&ie->m1periodicReporting, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_immediatemdt( + uint8_t **ptr, + LIBLTE_S1AP_IMMEDIATEMDT_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ImmediateMDT error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->m1thresholdeventA2_present = liblte_bits_2_value(ptr, 1); + ie->m1periodicReporting_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_measurementstoactivate(ptr, &ie->measurementsToActivate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_m1reportingtrigger(ptr, &ie->m1reportingTrigger) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->m1thresholdeventA2_present) { + if(liblte_s1ap_unpack_m1thresholdeventa2(ptr, &ie->m1thresholdeventA2) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->m1periodicReporting_present) { + if(liblte_s1ap_unpack_m1periodicreporting(ptr, &ie->m1periodicReporting) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MDTMode CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdtmode( + LIBLTE_S1AP_MDTMODE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("MDTMode error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_MDTMODE_CHOICE_IMMEDIATEMDT) { + if(liblte_s1ap_pack_immediatemdt(&ie->choice.immediateMDT, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_MDTMODE_CHOICE_LOGGEDMDT) { + if(liblte_s1ap_pack_loggedmdt(&ie->choice.loggedMDT, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdtmode( + uint8_t **ptr, + LIBLTE_S1AP_MDTMODE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("MDTMode error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_MDTMODE_CHOICE_ENUM)liblte_bits_2_value(ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_MDTMODE_CHOICE_IMMEDIATEMDT) { + if(liblte_s1ap_unpack_immediatemdt(ptr, &ie->choice.immediateMDT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_MDTMODE_CHOICE_LOGGEDMDT) { + if(liblte_s1ap_unpack_loggedmdt(ptr, &ie->choice.loggedMDT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SourceeNB_ToTargeteNB_TransparentContainer SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer( + LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SourceeNB_ToTargeteNB_TransparentContainer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->e_RABInformationList_present?1:0, ptr, 1); + liblte_value_2_bits(ie->subscriberProfileIDforRFP_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_rrc_container(&ie->rRC_Container, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->e_RABInformationList_present) { + if(liblte_s1ap_pack_e_rabinformationlist(&ie->e_RABInformationList, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(liblte_s1ap_pack_eutran_cgi(&ie->targetCell_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->subscriberProfileIDforRFP_present) { + if(liblte_s1ap_pack_subscriberprofileidforrfp(&ie->subscriberProfileIDforRFP, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(liblte_s1ap_pack_ue_historyinformation(&ie->uE_HistoryInformation, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_totargetenb_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SourceeNB_ToTargeteNB_TransparentContainer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->e_RABInformationList_present = liblte_bits_2_value(ptr, 1); + ie->subscriberProfileIDforRFP_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_rrc_container(ptr, &ie->rRC_Container) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->e_RABInformationList_present) { + if(liblte_s1ap_unpack_e_rabinformationlist(ptr, &ie->e_RABInformationList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(liblte_s1ap_unpack_eutran_cgi(ptr, &ie->targetCell_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->subscriberProfileIDforRFP_present) { + if(liblte_s1ap_unpack_subscriberprofileidforrfp(ptr, &ie->subscriberProfileIDforRFP) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(liblte_s1ap_unpack_ue_historyinformation(ptr, &ie->uE_HistoryInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE EmergencyAreaID_Broadcast DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_broadcast( + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("EmergencyAreaID_Broadcast pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_emergencyareaid_broadcast_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_broadcast( + uint8_t **ptr, + LIBLTE_S1AP_EMERGENCYAREAID_BROADCAST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("EmergencyAreaID_Broadcast unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_emergencyareaid_broadcast_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE MDT_Configuration SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdt_configuration( + LIBLTE_S1AP_MDT_CONFIGURATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("MDT_Configuration error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_mdt_activation(&ie->mdt_Activation, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_areascopeofmdt(&ie->areaScopeOfMDT, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_mdtmode(&ie->mDTMode, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdt_configuration( + uint8_t **ptr, + LIBLTE_S1AP_MDT_CONFIGURATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("MDT_Configuration error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_mdt_activation(ptr, &ie->mdt_Activation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_areascopeofmdt(ptr, &ie->areaScopeOfMDT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_mdtmode(ptr, &ie->mDTMode) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAI_Cancelled DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:65535 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_cancelled( + LIBLTE_S1AP_TAI_CANCELLED_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("TAI_Cancelled pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 16); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_tai_cancelled_item(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_cancelled( + uint8_t **ptr, + LIBLTE_S1AP_TAI_CANCELLED_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 16) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("TAI_Cancelled unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_tai_cancelled_item(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE BroadcastCancelledAreaList CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_broadcastcancelledarealist( + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("BroadcastCancelledAreaList error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_CELLID_CANCELLED) { + if(liblte_s1ap_pack_cellid_cancelled(&ie->choice.cellID_Cancelled, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_TAI_CANCELLED) { + if(liblte_s1ap_pack_tai_cancelled(&ie->choice.tAI_Cancelled, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_EMERGENCYAREAID_CANCELLED) { + if(liblte_s1ap_pack_emergencyareaid_cancelled(&ie->choice.emergencyAreaID_Cancelled, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_broadcastcancelledarealist( + uint8_t **ptr, + LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("BroadcastCancelledAreaList error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_ENUM)liblte_bits_2_value(ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_CELLID_CANCELLED) { + if(liblte_s1ap_unpack_cellid_cancelled(ptr, &ie->choice.cellID_Cancelled) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_TAI_CANCELLED) { + if(liblte_s1ap_unpack_tai_cancelled(ptr, &ie->choice.tAI_Cancelled) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_BROADCASTCANCELLEDAREALIST_CHOICE_EMERGENCYAREAID_CANCELLED) { + if(liblte_s1ap_unpack_emergencyareaid_cancelled(ptr, &ie->choice.emergencyAreaID_Cancelled) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ENB_StatusTransfer_TransparentContainer SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_statustransfer_transparentcontainer( + LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ENB_StatusTransfer_TransparentContainer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_bearers_subjecttostatustransferlist(&ie->bearers_SubjectToStatusTransferList, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_statustransfer_transparentcontainer( + uint8_t **ptr, + LIBLTE_S1AP_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ENB_StatusTransfer_TransparentContainer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_bearers_subjecttostatustransferlist(ptr, &ie->bearers_SubjectToStatusTransferList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TraceActivation SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_traceactivation( + LIBLTE_S1AP_TRACEACTIVATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TraceActivation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_utran_trace_id(&ie->e_UTRAN_Trace_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_interfacestotrace(&ie->interfacesToTrace, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_tracedepth(&ie->traceDepth, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->traceCollectionEntityIPAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_traceactivation( + uint8_t **ptr, + LIBLTE_S1AP_TRACEACTIVATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TraceActivation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_utran_trace_id(ptr, &ie->e_UTRAN_Trace_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_interfacestotrace(ptr, &ie->interfacesToTrace) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_tracedepth(ptr, &ie->traceDepth) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->traceCollectionEntityIPAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE BroadcastCompletedAreaList CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_broadcastcompletedarealist( + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("BroadcastCompletedAreaList error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_CELLID_BROADCAST) { + if(liblte_s1ap_pack_cellid_broadcast(&ie->choice.cellID_Broadcast, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_TAI_BROADCAST) { + if(liblte_s1ap_pack_tai_broadcast(&ie->choice.tAI_Broadcast, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_EMERGENCYAREAID_BROADCAST) { + if(liblte_s1ap_pack_emergencyareaid_broadcast(&ie->choice.emergencyAreaID_Broadcast, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_broadcastcompletedarealist( + uint8_t **ptr, + LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("BroadcastCompletedAreaList error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_ENUM)liblte_bits_2_value(ptr, 2); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_CELLID_BROADCAST) { + if(liblte_s1ap_unpack_cellid_broadcast(ptr, &ie->choice.cellID_Broadcast) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_TAI_BROADCAST) { + if(liblte_s1ap_unpack_tai_broadcast(ptr, &ie->choice.tAI_Broadcast) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_BROADCASTCOMPLETEDAREALIST_CHOICE_EMERGENCYAREAID_BROADCAST) { + if(liblte_s1ap_unpack_emergencyareaid_broadcast(ptr, &ie->choice.emergencyAreaID_Broadcast) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SONInformation CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_soninformation( + LIBLTE_S1AP_SONINFORMATION_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SONInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_SONINFORMATION_CHOICE_SONINFORMATIONREQUEST) { + if(liblte_s1ap_pack_soninformationrequest(&ie->choice.sONInformationRequest, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_SONINFORMATION_CHOICE_SONINFORMATIONREPLY) { + if(liblte_s1ap_pack_soninformationreply(&ie->choice.sONInformationReply, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformation( + uint8_t **ptr, + LIBLTE_S1AP_SONINFORMATION_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SONInformation error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_SONINFORMATION_CHOICE_ENUM)liblte_bits_2_value(ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_SONINFORMATION_CHOICE_SONINFORMATIONREQUEST) { + if(liblte_s1ap_unpack_soninformationrequest(ptr, &ie->choice.sONInformationRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_SONINFORMATION_CHOICE_SONINFORMATIONREPLY) { + if(liblte_s1ap_unpack_soninformationreply(ptr, &ie->choice.sONInformationReply) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE SONConfigurationTransfer SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sonconfigurationtransfer( + LIBLTE_S1AP_SONCONFIGURATIONTRANSFER_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("SONConfigurationTransfer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_targetenb_id(&ie->targeteNB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_sourceenb_id(&ie->sourceeNB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_soninformation(&ie->sONInformation, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sonconfigurationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_SONCONFIGURATIONTRANSFER_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("SONConfigurationTransfer error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_targetenb_id(ptr, &ie->targeteNB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_sourceenb_id(ptr, &ie->sourceeNB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_soninformation(ptr, &ie->sONInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ResetAll ENUMERATED +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_resetall( + LIBLTE_S1AP_RESETALL_ENUM_EXT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ResetAll error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Enum + liblte_value_2_bits(ie->e, ptr, 0); + liblte_align_up_zero(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_resetall( + uint8_t **ptr, + LIBLTE_S1AP_RESETALL_ENUM_EXT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ResetAll error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Enum + ie->e = (LIBLTE_S1AP_RESETALL_ENUM)liblte_bits_2_value(ptr, 0); + liblte_align_up(ptr, 8); + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE Inter_SystemInformationTransferType CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_inter_systeminformationtransfertype( + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("Inter_SystemInformationTransferType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 0); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_RIMTRANSFER) { + if(liblte_s1ap_pack_rimtransfer(&ie->choice.rIMTransfer, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_inter_systeminformationtransfertype( + uint8_t **ptr, + LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("Inter_SystemInformationTransferType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_ENUM)liblte_bits_2_value(ptr, 0); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_INTER_SYSTEMINFORMATIONTRANSFERTYPE_CHOICE_RIMTRANSFER) { + if(liblte_s1ap_unpack_rimtransfer(ptr, &ie->choice.rIMTransfer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RAB_IE_ContainerPairList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rab_ie_containerpairlist( + LIBLTE_S1AP_E_RAB_IE_CONTAINERPAIRLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RAB_IE_ContainerPairList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_pack_protocolie_containerpair(&ie->buffer[i], ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rab_ie_containerpairlist( + uint8_t **ptr, + LIBLTE_S1AP_E_RAB_IE_CONTAINERPAIRLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RAB_IE_ContainerPairList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_containerpair(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABDataForwardingItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabdataforwardingitem( + LIBLTE_S1AP_E_RABDATAFORWARDINGITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABDataForwardingItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->dL_transportLayerAddress_present?1:0, ptr, 1); + liblte_value_2_bits(ie->dL_gTP_TEID_present?1:0, ptr, 1); + liblte_value_2_bits(ie->uL_TransportLayerAddress_present?1:0, ptr, 1); + liblte_value_2_bits(ie->uL_GTP_TEID_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->dL_transportLayerAddress_present) { + if(liblte_s1ap_pack_transportlayeraddress(&ie->dL_transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->dL_gTP_TEID_present) { + if(liblte_s1ap_pack_gtp_teid(&ie->dL_gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->uL_TransportLayerAddress_present) { + if(liblte_s1ap_pack_transportlayeraddress(&ie->uL_TransportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->uL_GTP_TEID_present) { + if(liblte_s1ap_pack_gtp_teid(&ie->uL_GTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabdataforwardingitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABDATAFORWARDINGITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABDataForwardingItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->dL_transportLayerAddress_present = liblte_bits_2_value(ptr, 1); + ie->dL_gTP_TEID_present = liblte_bits_2_value(ptr, 1); + ie->uL_TransportLayerAddress_present = liblte_bits_2_value(ptr, 1); + ie->uL_GTP_TEID_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->dL_transportLayerAddress_present) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->dL_transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->dL_gTP_TEID_present) { + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->dL_gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->uL_TransportLayerAddress_present) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->uL_TransportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->uL_GTP_TEID_present) { + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->uL_GTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABToBeSetupItemHOReq SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemhoreq( + LIBLTE_S1AP_E_RABTOBESETUPITEMHOREQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSetupItemHOReq error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_e_rablevelqosparameters(&ie->e_RABlevelQosParameters, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemhoreq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPITEMHOREQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSetupItemHOReq error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_e_rablevelqosparameters(ptr, &ie->e_RABlevelQosParameters) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABAdmittedItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabadmitteditem( + LIBLTE_S1AP_E_RABADMITTEDITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABAdmittedItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->dL_transportLayerAddress_present?1:0, ptr, 1); + liblte_value_2_bits(ie->dL_gTP_TEID_present?1:0, ptr, 1); + liblte_value_2_bits(ie->uL_TransportLayerAddress_present?1:0, ptr, 1); + liblte_value_2_bits(ie->uL_GTP_TEID_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->dL_transportLayerAddress_present) { + if(liblte_s1ap_pack_transportlayeraddress(&ie->dL_transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->dL_gTP_TEID_present) { + if(liblte_s1ap_pack_gtp_teid(&ie->dL_gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->uL_TransportLayerAddress_present) { + if(liblte_s1ap_pack_transportlayeraddress(&ie->uL_TransportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->uL_GTP_TEID_present) { + if(liblte_s1ap_pack_gtp_teid(&ie->uL_GTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabadmitteditem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABADMITTEDITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABAdmittedItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->dL_transportLayerAddress_present = liblte_bits_2_value(ptr, 1); + ie->dL_gTP_TEID_present = liblte_bits_2_value(ptr, 1); + ie->uL_TransportLayerAddress_present = liblte_bits_2_value(ptr, 1); + ie->uL_GTP_TEID_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->dL_transportLayerAddress_present) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->dL_transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->dL_gTP_TEID_present) { + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->dL_gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->uL_TransportLayerAddress_present) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->uL_TransportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->uL_GTP_TEID_present) { + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->uL_GTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABFailedToSetupItemHOReqAck SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabfailedtosetupitemhoreqack( + LIBLTE_S1AP_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABFailedToSetupItemHOReqAck error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_cause(&ie->cause, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabfailedtosetupitemhoreqack( + uint8_t **ptr, + LIBLTE_S1AP_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABFailedToSetupItemHOReqAck error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_cause(ptr, &ie->cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABToBeSwitchedDLItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitcheddlitem( + LIBLTE_S1AP_E_RABTOBESWITCHEDDLITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSwitchedDLItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitcheddlitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESWITCHEDDLITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSwitchedDLItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABToBeSwitchedULItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitchedulitem( + LIBLTE_S1AP_E_RABTOBESWITCHEDULITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSwitchedULItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitchedulitem( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESWITCHEDULITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSwitchedULItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABToBeSetupItemBearerSUReq SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitembearersureq( + LIBLTE_S1AP_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSetupItemBearerSUReq error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_e_rablevelqosparameters(&ie->e_RABlevelQoSParameters, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_nas_pdu(&ie->nAS_PDU, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitembearersureq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSetupItemBearerSUReq error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_e_rablevelqosparameters(ptr, &ie->e_RABlevelQoSParameters) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_nas_pdu(ptr, &ie->nAS_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABSetupItemBearerSURes SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitembearersures( + LIBLTE_S1AP_E_RABSETUPITEMBEARERSURES_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABSetupItemBearerSURes error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitembearersures( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSETUPITEMBEARERSURES_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABSetupItemBearerSURes error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABToBeModifiedItemBearerModReq SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobemodifieditembearermodreq( + LIBLTE_S1AP_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeModifiedItemBearerModReq error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_e_rablevelqosparameters(&ie->e_RABLevelQoSParameters, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_nas_pdu(&ie->nAS_PDU, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifieditembearermodreq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeModifiedItemBearerModReq error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_e_rablevelqosparameters(ptr, &ie->e_RABLevelQoSParameters) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_nas_pdu(ptr, &ie->nAS_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABModifyItemBearerModRes SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyitembearermodres( + LIBLTE_S1AP_E_RABMODIFYITEMBEARERMODRES_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABModifyItemBearerModRes error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyitembearermodres( + uint8_t **ptr, + LIBLTE_S1AP_E_RABMODIFYITEMBEARERMODRES_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABModifyItemBearerModRes error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABReleaseItemBearerRelComp SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseitembearerrelcomp( + LIBLTE_S1AP_E_RABRELEASEITEMBEARERRELCOMP_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABReleaseItemBearerRelComp error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseitembearerrelcomp( + uint8_t **ptr, + LIBLTE_S1AP_E_RABRELEASEITEMBEARERRELCOMP_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABReleaseItemBearerRelComp error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABToBeSetupItemCtxtSUReq SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemctxtsureq( + LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSetupItemCtxtSUReq error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->nAS_PDU_present?1:0, ptr, 1); + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_e_rablevelqosparameters(&ie->e_RABlevelQoSParameters, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->nAS_PDU_present) { + if(liblte_s1ap_pack_nas_pdu(&ie->nAS_PDU, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemctxtsureq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABToBeSetupItemCtxtSUReq error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->nAS_PDU_present = liblte_bits_2_value(ptr, 1); + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_e_rablevelqosparameters(ptr, &ie->e_RABlevelQoSParameters) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->nAS_PDU_present) { + if(liblte_s1ap_unpack_nas_pdu(ptr, &ie->nAS_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE E_RABSetupItemCtxtSURes SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitemctxtsures( + LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABSetupItemCtxtSURes error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_e_rab_id(&ie->e_RAB_ID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_transportlayeraddress(&ie->transportLayerAddress, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(liblte_s1ap_pack_gtp_teid(&ie->gTP_TEID, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitemctxtsures( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSETUPITEMCTXTSURES_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("E_RABSetupItemCtxtSURes error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_e_rab_id(ptr, &ie->e_RAB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &ie->transportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(liblte_s1ap_unpack_gtp_teid(ptr, &ie->gTP_TEID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE TAIItem SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taiitem( + LIBLTE_S1AP_TAIITEM_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("TAIItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + liblte_value_2_bits(ie->iE_Extensions_present?1:0, ptr, 1); + + if(liblte_s1ap_pack_tai(&ie->tAI, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_pack_protocolextensioncontainer(&ie->iE_Extensions, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taiitem( + uint8_t **ptr, + LIBLTE_S1AP_TAIITEM_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("TAIItem error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + ie->iE_Extensions_present = liblte_bits_2_value(ptr, 1); + + if(liblte_s1ap_unpack_tai(ptr, &ie->tAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + + if(ie->iE_Extensions_present) { + if(liblte_s1ap_unpack_protocolextensioncontainer(ptr, &ie->iE_Extensions) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List UE_associatedLogicalS1_ConnectionListRes DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionlistres( + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("UE_associatedLogicalS1_ConnectionListRes pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ue_associatedlogicals1_connectionitem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionlistres( + uint8_t **ptr, + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRES_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("UE_associatedLogicalS1_ConnectionListRes unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_ue_associatedlogicals1_connectionitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List UE_associatedLogicalS1_ConnectionListResAck DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionlistresack( + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("UE_associatedLogicalS1_ConnectionListResAck pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ue_associatedlogicals1_connectionitem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionlistresack( + uint8_t **ptr, + LIBLTE_S1AP_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("UE_associatedLogicalS1_ConnectionListResAck unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_ue_associatedlogicals1_connectionitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE PrivateMessage SEQUENCE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privatemessage( + LIBLTE_S1AP_PRIVATEMESSAGE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("PrivateMessage error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + + if(liblte_s1ap_pack_privateie_container(&ie->privateIEs, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privatemessage( + uint8_t **ptr, + LIBLTE_S1AP_PRIVATEMESSAGE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("PrivateMessage error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + + if(liblte_s1ap_unpack_privateie_container(ptr, &ie->privateIEs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE ResetType CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_resettype( + LIBLTE_S1AP_RESETTYPE_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + liblte_value_2_bits(ie->ext?1:0, ptr, 1); + if(ie->ext) { + liblte_log_print("ResetType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // Choice type + liblte_value_2_bits(ie->choice_type, ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_RESETTYPE_CHOICE_S1_INTERFACE) { + if(liblte_s1ap_pack_resetall(&ie->choice.s1_Interface, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_RESETTYPE_CHOICE_PARTOFS1_INTERFACE) { + if(liblte_s1ap_pack_ue_associatedlogicals1_connectionlistres(&ie->choice.partOfS1_Interface, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_resettype( + uint8_t **ptr, + LIBLTE_S1AP_RESETTYPE_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + // Extension + ie->ext = liblte_bits_2_value(ptr, 1); + if(ie->ext) { + liblte_log_print("ResetType error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // Choice type + ie->choice_type = (LIBLTE_S1AP_RESETTYPE_CHOICE_ENUM)liblte_bits_2_value(ptr, 1); + + // Choice + if(ie->choice_type == LIBLTE_S1AP_RESETTYPE_CHOICE_S1_INTERFACE) { + if(liblte_s1ap_unpack_resetall(ptr, &ie->choice.s1_Interface) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(ie->choice_type == LIBLTE_S1AP_RESETTYPE_CHOICE_PARTOFS1_INTERFACE) { + if(liblte_s1ap_unpack_ue_associatedlogicals1_connectionlistres(ptr, &ie->choice.partOfS1_Interface) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABSubjecttoDataForwardingList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsubjecttodataforwardinglist( + LIBLTE_S1AP_E_RABSUBJECTTODATAFORWARDINGLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABSubjecttoDataForwardingList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabdataforwardingitem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABDATAFORWARDINGITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsubjecttodataforwardinglist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSUBJECTTODATAFORWARDINGLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABSubjecttoDataForwardingList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABDATAFORWARDINGITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabdataforwardingitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABToBeSetupListHOReq DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetuplisthoreq( + LIBLTE_S1AP_E_RABTOBESETUPLISTHOREQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABToBeSetupListHOReq pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetupitemhoreq(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMHOREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetuplisthoreq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPLISTHOREQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABToBeSetupListHOReq unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMHOREQ != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabtobesetupitemhoreq(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABAdmittedList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabadmittedlist( + LIBLTE_S1AP_E_RABADMITTEDLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABAdmittedList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabadmitteditem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABADMITTEDITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabadmittedlist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABADMITTEDLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABAdmittedList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABADMITTEDITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabadmitteditem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABToBeSwitchedDLList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitcheddllist( + LIBLTE_S1AP_E_RABTOBESWITCHEDDLLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABToBeSwitchedDLList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobeswitcheddlitem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDDLITEM, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitcheddllist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESWITCHEDDLLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABToBeSwitchedDLList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDDLITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabtobeswitcheddlitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABToBeSwitchedULList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitchedullist( + LIBLTE_S1AP_E_RABTOBESWITCHEDULLIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABToBeSwitchedULList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobeswitchedulitem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDULITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitchedullist( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESWITCHEDULLIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABToBeSwitchedULList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDULITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabtobeswitchedulitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABToBeSetupListBearerSUReq DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetuplistbearersureq( + LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABToBeSetupListBearerSUReq pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetupitembearersureq(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMBEARERSUREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetuplistbearersureq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABToBeSetupListBearerSUReq unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMBEARERSUREQ != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabtobesetupitembearersureq(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABSetupListBearerSURes DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetuplistbearersures( + LIBLTE_S1AP_E_RABSETUPLISTBEARERSURES_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABSetupListBearerSURes pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabsetupitembearersures(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABSETUPITEMBEARERSURES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetuplistbearersures( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSETUPLISTBEARERSURES_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABSetupListBearerSURes unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABSETUPITEMBEARERSURES != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabsetupitembearersures(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABToBeModifiedListBearerModReq DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobemodifiedlistbearermodreq( + LIBLTE_S1AP_E_RABTOBEMODIFIEDLISTBEARERMODREQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABToBeModifiedListBearerModReq pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobemodifieditembearermodreq(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBEMODIFIEDITEMBEARERMODREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifiedlistbearermodreq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBEMODIFIEDLISTBEARERMODREQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABToBeModifiedListBearerModReq unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABTOBEMODIFIEDITEMBEARERMODREQ != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabtobemodifieditembearermodreq(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABModifyListBearerModRes DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifylistbearermodres( + LIBLTE_S1AP_E_RABMODIFYLISTBEARERMODRES_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABModifyListBearerModRes pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabmodifyitembearermodres(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABMODIFYITEMBEARERMODRES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifylistbearermodres( + uint8_t **ptr, + LIBLTE_S1AP_E_RABMODIFYLISTBEARERMODRES_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABModifyListBearerModRes unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABMODIFYITEMBEARERMODRES != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabmodifyitembearermodres(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABReleaseListBearerRelComp DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaselistbearerrelcomp( + LIBLTE_S1AP_E_RABRELEASELISTBEARERRELCOMP_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABReleaseListBearerRelComp pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabreleaseitembearerrelcomp(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABRELEASEITEMBEARERRELCOMP, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaselistbearerrelcomp( + uint8_t **ptr, + LIBLTE_S1AP_E_RABRELEASELISTBEARERRELCOMP_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABReleaseListBearerRelComp unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABRELEASEITEMBEARERRELCOMP != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabreleaseitembearerrelcomp(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABToBeSetupListCtxtSUReq DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetuplistctxtsureq( + LIBLTE_S1AP_E_RABTOBESETUPLISTCTXTSUREQ_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABToBeSetupListCtxtSUReq pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetupitemctxtsureq(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMCTXTSUREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetuplistctxtsureq( + uint8_t **ptr, + LIBLTE_S1AP_E_RABTOBESETUPLISTCTXTSUREQ_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABToBeSetupListCtxtSUReq unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMCTXTSUREQ != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabtobesetupitemctxtsureq(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABSetupListCtxtSURes DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetuplistctxtsures( + LIBLTE_S1AP_E_RABSETUPLISTCTXTSURES_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABSetupListCtxtSURes pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabsetupitemctxtsures(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABSETUPITEMCTXTSURES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetuplistctxtsures( + uint8_t **ptr, + LIBLTE_S1AP_E_RABSETUPLISTCTXTSURES_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABSetupListCtxtSURes unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABSETUPITEMCTXTSURES != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabsetupitemctxtsures(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List TAIList DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tailist( + LIBLTE_S1AP_TAILIST_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("TAIList pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_taiitem(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAIITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tailist( + uint8_t **ptr, + LIBLTE_S1AP_TAILIST_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("TAIList unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_TAIITEM != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_taiitem(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Container List E_RABFailedtoSetupListHOReqAck DYNAMIC SEQUENCE OF +********************************************************************************/ +// lb:1, ub:256 +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabfailedtosetuplisthoreqack( + LIBLTE_S1AP_E_RABFAILEDTOSETUPLISTHOREQACK_STRUCT *ie, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + if(ie->len > 32) { + liblte_log_print("E_RABFailedtoSetupListHOReqAck pack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_ENCODE_FAIL; + } + // Length + liblte_value_2_bits(ie->len-1, ptr, 8); + liblte_align_up_zero(ptr, 8); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + uint32_t i; + for(i=0;ilen;i++) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabfailedtosetupitemhoreqack(&ie->buffer[i], &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPITEMHOREQACK, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabfailedtosetuplisthoreqack( + uint8_t **ptr, + LIBLTE_S1AP_E_RABFAILEDTOSETUPLISTHOREQACK_STRUCT *ie) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(ie != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + + // Length + ie->len = liblte_bits_2_value(ptr, 8) + 1; + liblte_align_up(ptr, 8); + if(ie->len > 32) { + liblte_log_print("E_RABFailedtoSetupListHOReqAck unpack error - max supported dynamic sequence length = 32, ie->len = %d\n", ie->len); + return LIBLTE_ERROR_DECODE_FAIL; + } + + uint32_t i; + for(i=0;ilen;i++) { + if(liblte_s1ap_unpack_protocolie_header(ptr, &ie_id, &crit, &len) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPITEMHOREQACK != ie_id) { + return LIBLTE_ERROR_DECODE_FAIL; + } + if(liblte_s1ap_unpack_e_rabfailedtosetupitemhoreqack(ptr, &ie->buffer[i]) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message AllocationAndRetentionPriority_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_allocationandretentionpriority_ext( + LIBLTE_S1AP_MESSAGE_ALLOCATIONANDRETENTIONPRIORITY_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("AllocationAndRetentionPriority-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_allocationandretentionpriority_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ALLOCATIONANDRETENTIONPRIORITY_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("AllocationAndRetentionPriority-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CancelledCellinEAI_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellineai_item_ext( + LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINEAI_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CancelledCellinEAI-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellineai_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINEAI_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CancelledCellinEAI-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CancelledCellinTAI_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cancelledcellintai_item_ext( + LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINTAI_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CancelledCellinTAI-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cancelledcellintai_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CANCELLEDCELLINTAI_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CancelledCellinTAI-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CellID_Broadcast_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_broadcast_item_ext( + LIBLTE_S1AP_MESSAGE_CELLID_BROADCAST_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CellID-Broadcast-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_broadcast_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLID_BROADCAST_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CellID-Broadcast-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CellID_Cancelled_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellid_cancelled_item_ext( + LIBLTE_S1AP_MESSAGE_CELLID_CANCELLED_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CellID-Cancelled-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellid_cancelled_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLID_CANCELLED_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CellID-Cancelled-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CellBasedMDT_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cellbasedmdt_ext( + LIBLTE_S1AP_MESSAGE_CELLBASEDMDT_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CellBasedMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cellbasedmdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLBASEDMDT_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CellBasedMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message Cdma2000OneXSRVCCInfo_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cdma2000onexsrvccinfo_ext( + LIBLTE_S1AP_MESSAGE_CDMA2000ONEXSRVCCINFO_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("Cdma2000OneXSRVCCInfo-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cdma2000onexsrvccinfo_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CDMA2000ONEXSRVCCINFO_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("Cdma2000OneXSRVCCInfo-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CellType_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_celltype_ext( + LIBLTE_S1AP_MESSAGE_CELLTYPE_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CellType-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_celltype_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLTYPE_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CellType-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CGI_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_cgi_ext( + LIBLTE_S1AP_MESSAGE_CGI_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CGI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_cgi_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CGI_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CGI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CSG_IdList_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_csg_idlist_item_ext( + LIBLTE_S1AP_MESSAGE_CSG_IDLIST_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CSG-IdList-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_csg_idlist_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CSG_IDLIST_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CSG-IdList-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message COUNTvalue_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_countvalue_ext( + LIBLTE_S1AP_MESSAGE_COUNTVALUE_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("COUNTvalue-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_countvalue_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_COUNTVALUE_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("COUNTvalue-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message COUNTValueExtended_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_countvalueextended_ext( + LIBLTE_S1AP_MESSAGE_COUNTVALUEEXTENDED_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("COUNTValueExtended-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_countvalueextended_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_COUNTVALUEEXTENDED_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("COUNTValueExtended-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CriticalityDiagnostics_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics_ext( + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CriticalityDiagnostics-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CriticalityDiagnostics-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CriticalityDiagnostics_IE_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_criticalitydiagnostics_ie_item_ext( + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_IE_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CriticalityDiagnostics-IE-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_criticalitydiagnostics_ie_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CRITICALITYDIAGNOSTICS_IE_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CriticalityDiagnostics-IE-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message EmergencyAreaID_Broadcast_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_broadcast_item_ext( + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_BROADCAST_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("EmergencyAreaID-Broadcast-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_broadcast_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_BROADCAST_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("EmergencyAreaID-Broadcast-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message EmergencyAreaID_Cancelled_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_emergencyareaid_cancelled_item_ext( + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_CANCELLED_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("EmergencyAreaID-Cancelled-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_emergencyareaid_cancelled_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_EMERGENCYAREAID_CANCELLED_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("EmergencyAreaID-Cancelled-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CompletedCellinEAI_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellineai_item_ext( + LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINEAI_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CompletedCellinEAI-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellineai_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINEAI_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CompletedCellinEAI-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message GERAN_Cell_ID_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_geran_cell_id_ext( + LIBLTE_S1AP_MESSAGE_GERAN_CELL_ID_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("GERAN-Cell-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_geran_cell_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_GERAN_CELL_ID_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("GERAN-Cell-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message GlobalENB_ID_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_globalenb_id_ext( + LIBLTE_S1AP_MESSAGE_GLOBALENB_ID_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("GlobalENB-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_globalenb_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_GLOBALENB_ID_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("GlobalENB-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ENB_StatusTransfer_TransparentContainer_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enb_statustransfer_transparentcontainer_ext( + LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ENB-StatusTransfer-TransparentContainer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enb_statustransfer_transparentcontainer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ENB-StatusTransfer-TransparentContainer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABInformationListItem_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabinformationlistitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLISTITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABInformationListItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlistitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLISTITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABInformationListItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABItem_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABQoSParameters_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabqosparameters_ext( + LIBLTE_S1AP_MESSAGE_E_RABQOSPARAMETERS_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABQoSParameters-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabqosparameters_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABQOSPARAMETERS_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABQoSParameters-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message EUTRAN_CGI_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_eutran_cgi_ext( + LIBLTE_S1AP_MESSAGE_EUTRAN_CGI_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("EUTRAN-CGI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_eutran_cgi_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_EUTRAN_CGI_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("EUTRAN-CGI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ForbiddenTAs_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddentas_item_ext( + LIBLTE_S1AP_MESSAGE_FORBIDDENTAS_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ForbiddenTAs-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddentas_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_FORBIDDENTAS_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ForbiddenTAs-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ForbiddenLAs_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_forbiddenlas_item_ext( + LIBLTE_S1AP_MESSAGE_FORBIDDENLAS_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ForbiddenLAs-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_forbiddenlas_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_FORBIDDENLAS_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ForbiddenLAs-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message GBR_QosInformation_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gbr_qosinformation_ext( + LIBLTE_S1AP_MESSAGE_GBR_QOSINFORMATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("GBR-QosInformation-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gbr_qosinformation_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_GBR_QOSINFORMATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("GBR-QosInformation-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message GUMMEI_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_gummei_ext( + LIBLTE_S1AP_MESSAGE_GUMMEI_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("GUMMEI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_gummei_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_GUMMEI_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("GUMMEI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverRestrictionList_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrestrictionlist_ext( + LIBLTE_S1AP_MESSAGE_HANDOVERRESTRICTIONLIST_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverRestrictionList-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrestrictionlist_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERRESTRICTIONLIST_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverRestrictionList-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message LAI_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lai_ext( + LIBLTE_S1AP_MESSAGE_LAI_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("LAI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lai_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LAI_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("LAI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message LoggedMDT_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_loggedmdt_ext( + LIBLTE_S1AP_MESSAGE_LOGGEDMDT_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("LoggedMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_loggedmdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LOGGEDMDT_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("LoggedMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message M3Configuration_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m3configuration_ext( + LIBLTE_S1AP_MESSAGE_M3CONFIGURATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("M3Configuration-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m3configuration_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M3CONFIGURATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("M3Configuration-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message M4Configuration_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m4configuration_ext( + LIBLTE_S1AP_MESSAGE_M4CONFIGURATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("M4Configuration-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m4configuration_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M4CONFIGURATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("M4Configuration-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message M5Configuration_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m5configuration_ext( + LIBLTE_S1AP_MESSAGE_M5CONFIGURATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("M5Configuration-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m5configuration_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M5CONFIGURATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("M5Configuration-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message M1PeriodicReporting_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1periodicreporting_ext( + LIBLTE_S1AP_MESSAGE_M1PERIODICREPORTING_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("M1PeriodicReporting-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1periodicreporting_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M1PERIODICREPORTING_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("M1PeriodicReporting-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message RequestType_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_requesttype_ext( + LIBLTE_S1AP_MESSAGE_REQUESTTYPE_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("RequestType-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_requesttype_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_REQUESTTYPE_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("RequestType-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message RIMTransfer_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_rimtransfer_ext( + LIBLTE_S1AP_MESSAGE_RIMTRANSFER_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("RIMTransfer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_rimtransfer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_RIMTRANSFER_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("RIMTransfer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message SecurityContext_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_securitycontext_ext( + LIBLTE_S1AP_MESSAGE_SECURITYCONTEXT_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("SecurityContext-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_securitycontext_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SECURITYCONTEXT_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("SecurityContext-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message SourceeNB_ID_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_id_ext( + LIBLTE_S1AP_MESSAGE_SOURCEENB_ID_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("SourceeNB-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SOURCEENB_ID_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("SourceeNB-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ServedGUMMEIsItem_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_servedgummeisitem_ext( + LIBLTE_S1AP_MESSAGE_SERVEDGUMMEISITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ServedGUMMEIsItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_servedgummeisitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SERVEDGUMMEISITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ServedGUMMEIsItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message SupportedTAs_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_supportedtas_item_ext( + LIBLTE_S1AP_MESSAGE_SUPPORTEDTAS_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("SupportedTAs-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_supportedtas_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SUPPORTEDTAS_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("SupportedTAs-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TimeSynchronizationInfo_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_timesynchronizationinfo_ext( + LIBLTE_S1AP_MESSAGE_TIMESYNCHRONIZATIONINFO_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TimeSynchronizationInfo-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_timesynchronizationinfo_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TIMESYNCHRONIZATIONINFO_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TimeSynchronizationInfo-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message S_TMSI_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s_tmsi_ext( + LIBLTE_S1AP_MESSAGE_S_TMSI_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("S-TMSI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s_tmsi_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_S_TMSI_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("S-TMSI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TAIBasedMDT_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taibasedmdt_ext( + LIBLTE_S1AP_MESSAGE_TAIBASEDMDT_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TAIBasedMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taibasedmdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAIBASEDMDT_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TAIBasedMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TAI_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_ext( + LIBLTE_S1AP_MESSAGE_TAI_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TAI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAI_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TAI-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TAI_Broadcast_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_broadcast_item_ext( + LIBLTE_S1AP_MESSAGE_TAI_BROADCAST_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TAI-Broadcast-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_broadcast_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAI_BROADCAST_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TAI-Broadcast-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TAI_Cancelled_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tai_cancelled_item_ext( + LIBLTE_S1AP_MESSAGE_TAI_CANCELLED_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TAI-Cancelled-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tai_cancelled_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAI_CANCELLED_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TAI-Cancelled-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TABasedMDT_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tabasedmdt_ext( + LIBLTE_S1AP_MESSAGE_TABASEDMDT_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TABasedMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tabasedmdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TABASEDMDT_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TABasedMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CompletedCellinTAI_Item_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_completedcellintai_item_ext( + LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINTAI_ITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CompletedCellinTAI-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_completedcellintai_item_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_COMPLETEDCELLINTAI_ITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CompletedCellinTAI-Item-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TargeteNB_ID_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_id_ext( + LIBLTE_S1AP_MESSAGE_TARGETENB_ID_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TargeteNB-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TARGETENB_ID_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TargeteNB-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TargetRNC_ID_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetrnc_id_ext( + LIBLTE_S1AP_MESSAGE_TARGETRNC_ID_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TargetRNC-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetrnc_id_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TARGETRNC_ID_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TargetRNC-ID-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TargeteNB_ToSourceeNB_TransparentContainer_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_targetenb_tosourceenb_transparentcontainer_ext( + LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TargeteNB-ToSourceeNB-TransparentContainer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_targetenb_tosourceenb_transparentcontainer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TARGETENB_TOSOURCEENB_TRANSPARENTCONTAINER_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TargeteNB-ToSourceeNB-TransparentContainer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message M1ThresholdEventA2_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_m1thresholdeventa2_ext( + LIBLTE_S1AP_MESSAGE_M1THRESHOLDEVENTA2_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("M1ThresholdEventA2-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_m1thresholdeventa2_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_M1THRESHOLDEVENTA2_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("M1ThresholdEventA2-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message Tunnel_Information_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tunnel_information_ext( + LIBLTE_S1AP_MESSAGE_TUNNEL_INFORMATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("Tunnel-Information-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tunnel_information_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TUNNEL_INFORMATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("Tunnel-Information-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UEAggregate_MaximumBitrates_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueaggregate_maximumbitrates_ext( + LIBLTE_S1AP_MESSAGE_UEAGGREGATE_MAXIMUMBITRATES_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UEAggregate-MaximumBitrates-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueaggregate_maximumbitrates_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UEAGGREGATE_MAXIMUMBITRATES_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UEAggregate-MaximumBitrates-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UE_S1AP_ID_pair_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_s1ap_id_pair_ext( + LIBLTE_S1AP_MESSAGE_UE_S1AP_ID_PAIR_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UE-S1AP-ID-pair-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_s1ap_id_pair_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UE_S1AP_ID_PAIR_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UE-S1AP-ID-pair-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UE_associatedLogicalS1_ConnectionItemExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitemext( + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UE-associatedLogicalS1-ConnectionItemExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitemext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UE-associatedLogicalS1-ConnectionItemExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UESecurityCapabilities_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uesecuritycapabilities_ext( + LIBLTE_S1AP_MESSAGE_UESECURITYCAPABILITIES_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UESecurityCapabilities-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uesecuritycapabilities_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UESECURITYCAPABILITIES_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UESecurityCapabilities-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UserLocationInformation_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_userlocationinformation_ext( + LIBLTE_S1AP_MESSAGE_USERLOCATIONINFORMATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UserLocationInformation-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_userlocationinformation_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_USERLOCATIONINFORMATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UserLocationInformation-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ENBX2ExtTLA_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbx2exttla_ext( + LIBLTE_S1AP_MESSAGE_ENBX2EXTTLA_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBX2ExtTLA-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbx2exttla_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBX2EXTTLA_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBX2ExtTLA-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message SourceeNB_ToTargeteNB_TransparentContainer_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer_ext( + LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("SourceeNB-ToTargeteNB-TransparentContainer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->MobilityInformation_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MobilityInformation + if(msg->MobilityInformation_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mobilityinformation(&msg->MobilityInformation, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MOBILITYINFORMATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sourceenb_totargetenb_transparentcontainer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->MobilityInformation_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("SourceeNB-ToTargeteNB-TransparentContainer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMobilityInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MobilityInformation_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABInformationList STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabinformationlist( + LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLIST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABInformationListIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABInformationListItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabinformationlistitem(&msg->E_RABInformationListItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABINFORMATIONLISTITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabinformationlist( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABINFORMATIONLIST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABInformationListIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABInformationListItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message LastVisitedEUTRANCellInformation_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_lastvisitedeutrancellinformation_ext( + LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("LastVisitedEUTRANCellInformation-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 2; + if(!msg->Time_UE_StayedInCell_EnhancedGranularity_present) + n_ie--; + if(!msg->HO_Cause_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Time_UE_StayedInCell_EnhancedGranularity + if(msg->Time_UE_StayedInCell_EnhancedGranularity_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_time_ue_stayedincell_enhancedgranularity(&msg->Time_UE_StayedInCell_EnhancedGranularity, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TIME_UE_STAYEDINCELL_ENHANCEDGRANULARITY, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - HO_Cause + if(msg->HO_Cause_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->HO_Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_HO_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_lastvisitedeutrancellinformation_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LASTVISITEDEUTRANCELLINFORMATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->Time_UE_StayedInCell_EnhancedGranularity_present = false; + msg->HO_Cause_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("LastVisitedEUTRANCellInformation-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iTime_UE_StayedInCell_EnhancedGranularity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Time_UE_StayedInCell_EnhancedGranularity_present = true; + } else if(LIBLTE_S1AP_IE_ID_HO_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->HO_Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->HO_Cause_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message SONInformationReply_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_soninformationreply_ext( + LIBLTE_S1AP_MESSAGE_SONINFORMATIONREPLY_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("SONInformationReply-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->Time_Synchronization_Info_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Time_Synchronization_Info + if(msg->Time_Synchronization_Info_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_timesynchronizationinfo(&msg->Time_Synchronization_Info, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TIME_SYNCHRONIZATION_INFO, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_soninformationreply_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SONINFORMATIONREPLY_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->Time_Synchronization_Info_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("SONInformationReply-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iTime_Synchronization_Info) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Time_Synchronization_Info_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message Bearers_SubjectToStatusTransfer_ItemExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_itemext( + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("Bearers-SubjectToStatusTransfer-ItemExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->ULCOUNTValueExtended_present) + n_ie--; + if(!msg->DLCOUNTValueExtended_present) + n_ie--; + if(!msg->ReceiveStatusOfULPDCPSDUsExtended_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - ULCOUNTValueExtended + if(msg->ULCOUNTValueExtended_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_countvalueextended(&msg->ULCOUNTValueExtended, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ULCOUNTVALUEEXTENDED, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - DLCOUNTValueExtended + if(msg->DLCOUNTValueExtended_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_countvalueextended(&msg->DLCOUNTValueExtended, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_DLCOUNTVALUEEXTENDED, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - ReceiveStatusOfULPDCPSDUsExtended + if(msg->ReceiveStatusOfULPDCPSDUsExtended_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_receivestatusofulpdcpsdusextended(&msg->ReceiveStatusOfULPDCPSDUsExtended, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_RECEIVESTATUSOFULPDCPSDUSEXTENDED, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransfer_itemext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEMEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->ULCOUNTValueExtended_present = false; + msg->DLCOUNTValueExtended_present = false; + msg->ReceiveStatusOfULPDCPSDUsExtended_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("Bearers-SubjectToStatusTransfer-ItemExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iULCOUNTValueExtended) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ULCOUNTValueExtended_present = true; + } else if(LIBLTE_S1AP_IE_ID_DLCOUNTVALUEEXTENDED == ie_id) { + if(liblte_s1ap_unpack_countvalueextended(ptr, &msg->DLCOUNTValueExtended) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->DLCOUNTValueExtended_present = true; + } else if(LIBLTE_S1AP_IE_ID_RECEIVESTATUSOFULPDCPSDUSEXTENDED == ie_id) { + if(liblte_s1ap_unpack_receivestatusofulpdcpsdusextended(ptr, &msg->ReceiveStatusOfULPDCPSDUsExtended) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ReceiveStatusOfULPDCPSDUsExtended_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABItem STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabitem( + LIBLTE_S1AP_MESSAGE_E_RABITEM_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabitem(&msg->E_RABItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABITEM_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message MDT_Configuration_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mdt_configuration_ext( + LIBLTE_S1AP_MESSAGE_MDT_CONFIGURATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("MDT-Configuration-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->SignallingBasedMDTPLMNList_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - SignallingBasedMDTPLMNList + if(msg->SignallingBasedMDTPLMNList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mdtplmnlist(&msg->SignallingBasedMDTPLMNList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SIGNALLINGBASEDMDTPLMNLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mdt_configuration_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MDT_CONFIGURATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->SignallingBasedMDTPLMNList_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("MDT-Configuration-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iSignallingBasedMDTPLMNList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SignallingBasedMDTPLMNList_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message X2TNLConfigurationInfo_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_x2tnlconfigurationinfo_ext( + LIBLTE_S1AP_MESSAGE_X2TNLCONFIGURATIONINFO_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("X2TNLConfigurationInfo-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->eNBX2ExtendedTransportLayerAddresses_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - eNBX2ExtendedTransportLayerAddresses + if(msg->eNBX2ExtendedTransportLayerAddresses_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enbx2exttlas(&msg->eNBX2ExtendedTransportLayerAddresses, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENBX2EXTENDEDTRANSPORTLAYERADDRESSES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_x2tnlconfigurationinfo_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_X2TNLCONFIGURATIONINFO_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->eNBX2ExtendedTransportLayerAddresses_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("X2TNLConfigurationInfo-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;ieNBX2ExtendedTransportLayerAddresses) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->eNBX2ExtendedTransportLayerAddresses_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message Bearers_SubjectToStatusTransfer_Item STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_bearers_subjecttostatustransfer_item( + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("Bearers-SubjectToStatusTransfer-ItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Bearers_SubjectToStatusTransfer_Item + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_bearers_subjecttostatustransfer_item(&msg->Bearers_SubjectToStatusTransfer_Item, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_bearers_subjecttostatustransfer_item( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_BEARERS_SUBJECTTOSTATUSTRANSFER_ITEM_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("Bearers-SubjectToStatusTransfer-ItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iBearers_SubjectToStatusTransfer_Item) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ImmediateMDT_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_immediatemdt_ext( + LIBLTE_S1AP_MESSAGE_IMMEDIATEMDT_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ImmediateMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->M3Configuration_present) + n_ie--; + if(!msg->M4Configuration_present) + n_ie--; + if(!msg->M5Configuration_present) + n_ie--; + if(!msg->MDT_Location_Info_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - M3Configuration + if(msg->M3Configuration_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_m3configuration(&msg->M3Configuration, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_M3CONFIGURATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - M4Configuration + if(msg->M4Configuration_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_m4configuration(&msg->M4Configuration, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_M4CONFIGURATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - M5Configuration + if(msg->M5Configuration_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_m5configuration(&msg->M5Configuration, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_M5CONFIGURATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - MDT_Location_Info + if(msg->MDT_Location_Info_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mdt_location_info(&msg->MDT_Location_Info, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MDT_LOCATION_INFO, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_immediatemdt_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_IMMEDIATEMDT_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->M3Configuration_present = false; + msg->M4Configuration_present = false; + msg->M5Configuration_present = false; + msg->MDT_Location_Info_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ImmediateMDT-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iM3Configuration) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_M4CONFIGURATION == ie_id) { + if(liblte_s1ap_unpack_m4configuration(ptr, &msg->M4Configuration) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_M5CONFIGURATION == ie_id) { + if(liblte_s1ap_unpack_m5configuration(ptr, &msg->M5Configuration) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_MDT_LOCATION_INFO == ie_id) { + if(liblte_s1ap_unpack_mdt_location_info(ptr, &msg->MDT_Location_Info) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MDT_Location_Info_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message SONConfigurationTransfer_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_sonconfigurationtransfer_ext( + LIBLTE_S1AP_MESSAGE_SONCONFIGURATIONTRANSFER_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("SONConfigurationTransfer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->x2TNLConfigurationInfo_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - x2TNLConfigurationInfo + if(msg->x2TNLConfigurationInfo_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_x2tnlconfigurationinfo(&msg->x2TNLConfigurationInfo, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_X2TNLCONFIGURATIONINFO, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_sonconfigurationtransfer_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_SONCONFIGURATIONTRANSFER_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->x2TNLConfigurationInfo_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("SONConfigurationTransfer-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;ix2TNLConfigurationInfo) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TraceActivation_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_traceactivation_ext( + LIBLTE_S1AP_MESSAGE_TRACEACTIVATION_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TraceActivation-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->MDTConfiguration_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MDTConfiguration + if(msg->MDTConfiguration_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mdt_configuration(&msg->MDTConfiguration, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MDTCONFIGURATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_traceactivation_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TRACEACTIVATION_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->MDTConfiguration_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TraceActivation-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMDTConfiguration) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MDTConfiguration_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverRequired STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrequired( + LIBLTE_S1AP_MESSAGE_HANDOVERREQUIRED_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverRequiredIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 14; + if(!msg->Direct_Forwarding_Path_Availability_present) + n_ie--; + if(!msg->SRVCCHOIndication_present) + n_ie--; + if(!msg->Source_ToTarget_TransparentContainer_Secondary_present) + n_ie--; + if(!msg->MSClassmark2_present) + n_ie--; + if(!msg->MSClassmark3_present) + n_ie--; + if(!msg->CSG_Id_present) + n_ie--; + if(!msg->CellAccessMode_present) + n_ie--; + if(!msg->PS_ServiceNotAvailable_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - HandoverType + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_handovertype(&msg->HandoverType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_HANDOVERTYPE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TargetID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_targetid(&msg->TargetID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TARGETID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Direct_Forwarding_Path_Availability + if(msg->Direct_Forwarding_Path_Availability_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_direct_forwarding_path_availability(&msg->Direct_Forwarding_Path_Availability, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_DIRECT_FORWARDING_PATH_AVAILABILITY, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SRVCCHOIndication + if(msg->SRVCCHOIndication_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_srvcchoindication(&msg->SRVCCHOIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SRVCCHOINDICATION, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - Source_ToTarget_TransparentContainer + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_source_totarget_transparentcontainer(&msg->Source_ToTarget_TransparentContainer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SOURCE_TOTARGET_TRANSPARENTCONTAINER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Source_ToTarget_TransparentContainer_Secondary + if(msg->Source_ToTarget_TransparentContainer_Secondary_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_source_totarget_transparentcontainer(&msg->Source_ToTarget_TransparentContainer_Secondary, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SOURCE_TOTARGET_TRANSPARENTCONTAINER_SECONDARY, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - MSClassmark2 + if(msg->MSClassmark2_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_msclassmark2(&msg->MSClassmark2, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MSCLASSMARK2, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - MSClassmark3 + if(msg->MSClassmark3_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_msclassmark3(&msg->MSClassmark3, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MSCLASSMARK3, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSG_Id + if(msg->CSG_Id_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csg_id(&msg->CSG_Id, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSG_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CellAccessMode + if(msg->CellAccessMode_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cellaccessmode(&msg->CellAccessMode, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CELLACCESSMODE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - PS_ServiceNotAvailable + if(msg->PS_ServiceNotAvailable_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ps_servicenotavailable(&msg->PS_ServiceNotAvailable, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_PS_SERVICENOTAVAILABLE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrequired( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERREQUIRED_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->Direct_Forwarding_Path_Availability_present = false; + msg->SRVCCHOIndication_present = false; + msg->Source_ToTarget_TransparentContainer_Secondary_present = false; + msg->MSClassmark2_present = false; + msg->MSClassmark3_present = false; + msg->CSG_Id_present = false; + msg->CellAccessMode_present = false; + msg->PS_ServiceNotAvailable_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverRequiredIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_HANDOVERTYPE == ie_id) { + if(liblte_s1ap_unpack_handovertype(ptr, &msg->HandoverType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TARGETID == ie_id) { + if(liblte_s1ap_unpack_targetid(ptr, &msg->TargetID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_DIRECT_FORWARDING_PATH_AVAILABILITY == ie_id) { + if(liblte_s1ap_unpack_direct_forwarding_path_availability(ptr, &msg->Direct_Forwarding_Path_Availability) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Direct_Forwarding_Path_Availability_present = true; + } else if(LIBLTE_S1AP_IE_ID_SRVCCHOINDICATION == ie_id) { + if(liblte_s1ap_unpack_srvcchoindication(ptr, &msg->SRVCCHOIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SRVCCHOIndication_present = true; + } else if(LIBLTE_S1AP_IE_ID_SOURCE_TOTARGET_TRANSPARENTCONTAINER == ie_id) { + if(liblte_s1ap_unpack_source_totarget_transparentcontainer(ptr, &msg->Source_ToTarget_TransparentContainer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SOURCE_TOTARGET_TRANSPARENTCONTAINER_SECONDARY == ie_id) { + if(liblte_s1ap_unpack_source_totarget_transparentcontainer(ptr, &msg->Source_ToTarget_TransparentContainer_Secondary) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Source_ToTarget_TransparentContainer_Secondary_present = true; + } else if(LIBLTE_S1AP_IE_ID_MSCLASSMARK2 == ie_id) { + if(liblte_s1ap_unpack_msclassmark2(ptr, &msg->MSClassmark2) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_MSCLASSMARK3 == ie_id) { + if(liblte_s1ap_unpack_msclassmark3(ptr, &msg->MSClassmark3) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CSG_ID == ie_id) { + if(liblte_s1ap_unpack_csg_id(ptr, &msg->CSG_Id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSG_Id_present = true; + } else if(LIBLTE_S1AP_IE_ID_CELLACCESSMODE == ie_id) { + if(liblte_s1ap_unpack_cellaccessmode(ptr, &msg->CellAccessMode) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CellAccessMode_present = true; + } else if(LIBLTE_S1AP_IE_ID_PS_SERVICENOTAVAILABLE == ie_id) { + if(liblte_s1ap_unpack_ps_servicenotavailable(ptr, &msg->PS_ServiceNotAvailable) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->PS_ServiceNotAvailable_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABDataForwardingItem_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabdataforwardingitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABDataForwardingItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabdataforwardingitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABDataForwardingItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverPreparationFailure STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverpreparationfailure( + LIBLTE_S1AP_MESSAGE_HANDOVERPREPARATIONFAILURE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverPreparationFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverpreparationfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERPREPARATIONFAILURE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverPreparationFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemHOReq_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemhoreq_ext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemHOReq-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->Data_Forwarding_Not_Possible_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Data_Forwarding_Not_Possible + if(msg->Data_Forwarding_Not_Possible_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_data_forwarding_not_possible(&msg->Data_Forwarding_Not_Possible, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_DATA_FORWARDING_NOT_POSSIBLE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemhoreq_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->Data_Forwarding_Not_Possible_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemHOReq-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iData_Forwarding_Not_Possible) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Data_Forwarding_Not_Possible_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABAdmittedItem_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabadmitteditem_ext( + LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABAdmittedItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabadmitteditem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABAdmittedItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABFailedToSetupItemHOReqAckExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabfailedtosetupitemhoreqackext( + LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACKEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABFailedToSetupItemHOReqAckExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabfailedtosetupitemhoreqackext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACKEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABFailedToSetupItemHOReqAckExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverFailure STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverfailure( + LIBLTE_S1AP_MESSAGE_HANDOVERFAILURE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERFAILURE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverNotify STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovernotify( + LIBLTE_S1AP_MESSAGE_HANDOVERNOTIFY_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverNotifyIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 6; + if(!msg->Tunnel_Information_for_BBF_present) + n_ie--; + if(!msg->LHN_ID_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - EUTRAN_CGI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_eutran_cgi(&msg->EUTRAN_CGI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EUTRAN_CGI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TAI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tai(&msg->TAI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Tunnel_Information_for_BBF + if(msg->Tunnel_Information_for_BBF_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tunnelinformation(&msg->Tunnel_Information_for_BBF, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TUNNEL_INFORMATION_FOR_BBF, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - LHN_ID + if(msg->LHN_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lhn_id(&msg->LHN_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_LHN_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovernotify( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERNOTIFY_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->Tunnel_Information_for_BBF_present = false; + msg->LHN_ID_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverNotifyIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EUTRAN_CGI == ie_id) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &msg->EUTRAN_CGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TAI == ie_id) { + if(liblte_s1ap_unpack_tai(ptr, &msg->TAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TUNNEL_INFORMATION_FOR_BBF == ie_id) { + if(liblte_s1ap_unpack_tunnelinformation(ptr, &msg->Tunnel_Information_for_BBF) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Tunnel_Information_for_BBF_present = true; + } else if(LIBLTE_S1AP_IE_ID_LHN_ID == ie_id) { + if(liblte_s1ap_unpack_lhn_id(ptr, &msg->LHN_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->LHN_ID_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSwitchedDLItem_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitcheddlitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSwitchedDLItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitcheddlitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSwitchedDLItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSwitchedULItem_Ext STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitchedulitem_ext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_EXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSwitchedULItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitchedulitem_ext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_EXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSwitchedULItem-ExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message PathSwitchRequestFailure STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pathswitchrequestfailure( + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTFAILURE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("PathSwitchRequestFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pathswitchrequestfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTFAILURE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("PathSwitchRequestFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverCancel STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovercancel( + LIBLTE_S1AP_MESSAGE_HANDOVERCANCEL_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverCancelIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovercancel( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERCANCEL_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverCancelIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverCancelAcknowledge STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovercancelacknowledge( + LIBLTE_S1AP_MESSAGE_HANDOVERCANCELACKNOWLEDGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverCancelAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovercancelacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERCANCELACKNOWLEDGE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverCancelAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemBearerSUReqExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitembearersureqext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemBearerSUReqExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 2; + if(!msg->Correlation_ID_present) + n_ie--; + if(!msg->SIPTO_Correlation_ID_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Correlation_ID + if(msg->Correlation_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_correlation_id(&msg->Correlation_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CORRELATION_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SIPTO_Correlation_ID + if(msg->SIPTO_Correlation_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_correlation_id(&msg->SIPTO_Correlation_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SIPTO_CORRELATION_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitembearersureqext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->Correlation_ID_present = false; + msg->SIPTO_Correlation_ID_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemBearerSUReqExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iCorrelation_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Correlation_ID_present = true; + } else if(LIBLTE_S1AP_IE_ID_SIPTO_CORRELATION_ID == ie_id) { + if(liblte_s1ap_unpack_correlation_id(ptr, &msg->SIPTO_Correlation_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SIPTO_Correlation_ID_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABSetupItemBearerSUResExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitembearersuresext( + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURESEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupItemBearerSUResExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitembearersuresext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURESEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupItemBearerSUResExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeModifyItemBearerModReqExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobemodifyitembearermodreqext( + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFYITEMBEARERMODREQEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeModifyItemBearerModReqExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->TransportInformation_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - TransportInformation + if(msg->TransportInformation_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_transportinformation(&msg->TransportInformation, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TRANSPORTINFORMATION, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifyitembearermodreqext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFYITEMBEARERMODREQEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->TransportInformation_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeModifyItemBearerModReqExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iTransportInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->TransportInformation_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABModifyItemBearerModResExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyitembearermodresext( + LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRESEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABModifyItemBearerModResExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyitembearermodresext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRESEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABModifyItemBearerModResExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABReleaseCommand STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleasecommand( + LIBLTE_S1AP_MESSAGE_E_RABRELEASECOMMAND_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseCommandIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 5; + if(!msg->uEaggregateMaximumBitrate_present) + n_ie--; + if(!msg->NAS_PDU_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - uEaggregateMaximumBitrate + if(msg->uEaggregateMaximumBitrate_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueaggregatemaximumbitrate(&msg->uEaggregateMaximumBitrate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABToBeReleasedList + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rablist(&msg->E_RABToBeReleasedList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBERELEASEDLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - NAS_PDU + if(msg->NAS_PDU_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_nas_pdu(&msg->NAS_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_NAS_PDU, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleasecommand( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASECOMMAND_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->uEaggregateMaximumBitrate_present = false; + msg->NAS_PDU_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseCommandIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE == ie_id) { + if(liblte_s1ap_unpack_ueaggregatemaximumbitrate(ptr, &msg->uEaggregateMaximumBitrate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->uEaggregateMaximumBitrate_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABTOBERELEASEDLIST == ie_id) { + if(liblte_s1ap_unpack_e_rablist(ptr, &msg->E_RABToBeReleasedList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_NAS_PDU == ie_id) { + if(liblte_s1ap_unpack_nas_pdu(ptr, &msg->NAS_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->NAS_PDU_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABReleaseItemBearerRelCompExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseitembearerrelcompext( + LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMPEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseItemBearerRelCompExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseitembearerrelcompext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMPEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseItemBearerRelCompExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABReleaseIndication STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseindication( + LIBLTE_S1AP_MESSAGE_E_RABRELEASEINDICATION_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->UserLocationInformation_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABReleasedList + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rablist(&msg->E_RABReleasedList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABRELEASEDLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - UserLocationInformation + if(msg->UserLocationInformation_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_userlocationinformation(&msg->UserLocationInformation, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_USERLOCATIONINFORMATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASEINDICATION_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->UserLocationInformation_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABRELEASEDLIST == ie_id) { + if(liblte_s1ap_unpack_e_rablist(ptr, &msg->E_RABReleasedList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_USERLOCATIONINFORMATION == ie_id) { + if(liblte_s1ap_unpack_userlocationinformation(ptr, &msg->UserLocationInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->UserLocationInformation_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemCtxtSUReqExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemctxtsureqext( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemCtxtSUReqExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 2; + if(!msg->Correlation_ID_present) + n_ie--; + if(!msg->SIPTO_Correlation_ID_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Correlation_ID + if(msg->Correlation_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_correlation_id(&msg->Correlation_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CORRELATION_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SIPTO_Correlation_ID + if(msg->SIPTO_Correlation_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_correlation_id(&msg->SIPTO_Correlation_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SIPTO_CORRELATION_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemctxtsureqext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->Correlation_ID_present = false; + msg->SIPTO_Correlation_ID_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemCtxtSUReqExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iCorrelation_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Correlation_ID_present = true; + } else if(LIBLTE_S1AP_IE_ID_SIPTO_CORRELATION_ID == ie_id) { + if(liblte_s1ap_unpack_correlation_id(ptr, &msg->SIPTO_Correlation_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SIPTO_Correlation_ID_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABSetupItemCtxtSUResExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitemctxtsuresext( + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURESEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupItemCtxtSUResExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitemctxtsuresext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURESEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupItemCtxtSUResExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message InitialContextSetupFailure STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initialcontextsetupfailure( + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPFAILURE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("InitialContextSetupFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initialcontextsetupfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPFAILURE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("InitialContextSetupFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TAIItemExt STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taiitemext( + LIBLTE_S1AP_MESSAGE_TAIITEMEXT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TAIItemExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taiitemext( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAIITEMEXT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TAIItemExtIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UEContextReleaseRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextreleaserequest( + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextReleaseRequest-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->GWContextReleaseIndication_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - GWContextReleaseIndication + if(msg->GWContextReleaseIndication_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_gwcontextreleaseindication(&msg->GWContextReleaseIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GWCONTEXTRELEASEINDICATION, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextreleaserequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASEREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->GWContextReleaseIndication_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextReleaseRequest-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_GWCONTEXTRELEASEINDICATION == ie_id) { + if(liblte_s1ap_unpack_gwcontextreleaseindication(ptr, &msg->GWContextReleaseIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GWContextReleaseIndication_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UEContextReleaseCommand STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextreleasecommand( + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextReleaseCommand-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 2; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - UE_S1AP_IDs + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ue_s1ap_ids(&msg->UE_S1AP_IDs, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UE_S1AP_IDS, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextreleasecommand( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMAND_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextReleaseCommand-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iUE_S1AP_IDs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UEContextReleaseComplete STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextreleasecomplete( + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextReleaseComplete-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + if(!msg->UserLocationInformation_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - UserLocationInformation + if(msg->UserLocationInformation_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_userlocationinformation(&msg->UserLocationInformation, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_USERLOCATIONINFORMATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextreleasecomplete( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMPLETE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + msg->UserLocationInformation_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextReleaseComplete-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } else if(LIBLTE_S1AP_IE_ID_USERLOCATIONINFORMATION == ie_id) { + if(liblte_s1ap_unpack_userlocationinformation(ptr, &msg->UserLocationInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->UserLocationInformation_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UEContextModificationRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextmodificationrequest( + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextModificationRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 10; + if(!msg->SecurityKey_present) + n_ie--; + if(!msg->SubscriberProfileIDforRFP_present) + n_ie--; + if(!msg->uEaggregateMaximumBitrate_present) + n_ie--; + if(!msg->CSFallbackIndicator_present) + n_ie--; + if(!msg->UESecurityCapabilities_present) + n_ie--; + if(!msg->CSGMembershipStatus_present) + n_ie--; + if(!msg->RegisteredLAI_present) + n_ie--; + if(!msg->AdditionalCSFallbackIndicator_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - SecurityKey + if(msg->SecurityKey_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_securitykey(&msg->SecurityKey, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SECURITYKEY, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SubscriberProfileIDforRFP + if(msg->SubscriberProfileIDforRFP_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_subscriberprofileidforrfp(&msg->SubscriberProfileIDforRFP, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SUBSCRIBERPROFILEIDFORRFP, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - uEaggregateMaximumBitrate + if(msg->uEaggregateMaximumBitrate_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueaggregatemaximumbitrate(&msg->uEaggregateMaximumBitrate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSFallbackIndicator + if(msg->CSFallbackIndicator_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csfallbackindicator(&msg->CSFallbackIndicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSFALLBACKINDICATOR, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - UESecurityCapabilities + if(msg->UESecurityCapabilities_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_uesecuritycapabilities(&msg->UESecurityCapabilities, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSGMembershipStatus + if(msg->CSGMembershipStatus_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csgmembershipstatus(&msg->CSGMembershipStatus, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - RegisteredLAI + if(msg->RegisteredLAI_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lai(&msg->RegisteredLAI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_REGISTEREDLAI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - AdditionalCSFallbackIndicator + if(msg->AdditionalCSFallbackIndicator_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_additionalcsfallbackindicator(&msg->AdditionalCSFallbackIndicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ADDITIONALCSFALLBACKINDICATOR, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextmodificationrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->SecurityKey_present = false; + msg->SubscriberProfileIDforRFP_present = false; + msg->uEaggregateMaximumBitrate_present = false; + msg->CSFallbackIndicator_present = false; + msg->UESecurityCapabilities_present = false; + msg->CSGMembershipStatus_present = false; + msg->RegisteredLAI_present = false; + msg->AdditionalCSFallbackIndicator_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextModificationRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SECURITYKEY == ie_id) { + if(liblte_s1ap_unpack_securitykey(ptr, &msg->SecurityKey) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SecurityKey_present = true; + } else if(LIBLTE_S1AP_IE_ID_SUBSCRIBERPROFILEIDFORRFP == ie_id) { + if(liblte_s1ap_unpack_subscriberprofileidforrfp(ptr, &msg->SubscriberProfileIDforRFP) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SubscriberProfileIDforRFP_present = true; + } else if(LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE == ie_id) { + if(liblte_s1ap_unpack_ueaggregatemaximumbitrate(ptr, &msg->uEaggregateMaximumBitrate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->uEaggregateMaximumBitrate_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSFALLBACKINDICATOR == ie_id) { + if(liblte_s1ap_unpack_csfallbackindicator(ptr, &msg->CSFallbackIndicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSFallbackIndicator_present = true; + } else if(LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES == ie_id) { + if(liblte_s1ap_unpack_uesecuritycapabilities(ptr, &msg->UESecurityCapabilities) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->UESecurityCapabilities_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS == ie_id) { + if(liblte_s1ap_unpack_csgmembershipstatus(ptr, &msg->CSGMembershipStatus) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSGMembershipStatus_present = true; + } else if(LIBLTE_S1AP_IE_ID_REGISTEREDLAI == ie_id) { + if(liblte_s1ap_unpack_lai(ptr, &msg->RegisteredLAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->RegisteredLAI_present = true; + } else if(LIBLTE_S1AP_IE_ID_ADDITIONALCSFALLBACKINDICATOR == ie_id) { + if(liblte_s1ap_unpack_additionalcsfallbackindicator(ptr, &msg->AdditionalCSFallbackIndicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UEContextModificationResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextmodificationresponse( + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONRESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextModificationResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextmodificationresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONRESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextModificationResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UEContextModificationFailure STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecontextmodificationfailure( + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONFAILURE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextModificationFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecontextmodificationfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONFAILURE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UEContextModificationFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UERadioCapabilityMatchRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueradiocapabilitymatchrequest( + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UERadioCapabilityMatchRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->UERadioCapability_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - UERadioCapability + if(msg->UERadioCapability_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueradiocapability(&msg->UERadioCapability, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UERADIOCAPABILITY, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueradiocapabilitymatchrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->UERadioCapability_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UERadioCapabilityMatchRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UERADIOCAPABILITY == ie_id) { + if(liblte_s1ap_unpack_ueradiocapability(ptr, &msg->UERadioCapability) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->UERadioCapability_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UERadioCapabilityMatchResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ueradiocapabilitymatchresponse( + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHRESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UERadioCapabilityMatchResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - VoiceSupportMatchIndicator + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_voicesupportmatchindicator(&msg->VoiceSupportMatchIndicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_VOICESUPPORTMATCHINDICATOR, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ueradiocapabilitymatchresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UERADIOCAPABILITYMATCHRESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UERadioCapabilityMatchResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_VOICESUPPORTMATCHINDICATOR == ie_id) { + if(liblte_s1ap_unpack_voicesupportmatchindicator(ptr, &msg->VoiceSupportMatchIndicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message DownlinkNASTransport STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinknastransport( + LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("DownlinkNASTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 5; + if(!msg->HandoverRestrictionList_present) + n_ie--; + if(!msg->SubscriberProfileIDforRFP_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - NAS_PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_nas_pdu(&msg->NAS_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_NAS_PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - HandoverRestrictionList + if(msg->HandoverRestrictionList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_handoverrestrictionlist(&msg->HandoverRestrictionList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_HANDOVERRESTRICTIONLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SubscriberProfileIDforRFP + if(msg->SubscriberProfileIDforRFP_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_subscriberprofileidforrfp(&msg->SubscriberProfileIDforRFP, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SUBSCRIBERPROFILEIDFORRFP, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinknastransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->HandoverRestrictionList_present = false; + msg->SubscriberProfileIDforRFP_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("DownlinkNASTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_NAS_PDU == ie_id) { + if(liblte_s1ap_unpack_nas_pdu(ptr, &msg->NAS_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_HANDOVERRESTRICTIONLIST == ie_id) { + if(liblte_s1ap_unpack_handoverrestrictionlist(ptr, &msg->HandoverRestrictionList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->HandoverRestrictionList_present = true; + } else if(LIBLTE_S1AP_IE_ID_SUBSCRIBERPROFILEIDFORRFP == ie_id) { + if(liblte_s1ap_unpack_subscriberprofileidforrfp(ptr, &msg->SubscriberProfileIDforRFP) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SubscriberProfileIDforRFP_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message InitialUEMessage STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initialuemessage( + LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("InitialUEMessage-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 15; + if(!msg->S_TMSI_present) + n_ie--; + if(!msg->CSG_Id_present) + n_ie--; + if(!msg->GUMMEI_ID_present) + n_ie--; + if(!msg->CellAccessMode_present) + n_ie--; + if(!msg->GW_TransportLayerAddress_present) + n_ie--; + if(!msg->RelayNode_Indicator_present) + n_ie--; + if(!msg->GUMMEIType_present) + n_ie--; + if(!msg->Tunnel_Information_for_BBF_present) + n_ie--; + if(!msg->SIPTO_L_GW_TransportLayerAddress_present) + n_ie--; + if(!msg->LHN_ID_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - NAS_PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_nas_pdu(&msg->NAS_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_NAS_PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TAI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tai(&msg->TAI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAI, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - EUTRAN_CGI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_eutran_cgi(&msg->EUTRAN_CGI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EUTRAN_CGI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - RRC_Establishment_Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_rrc_establishment_cause(&msg->RRC_Establishment_Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_RRC_ESTABLISHMENT_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - S_TMSI + if(msg->S_TMSI_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_s_tmsi(&msg->S_TMSI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_S_TMSI, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSG_Id + if(msg->CSG_Id_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csg_id(&msg->CSG_Id, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSG_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - GUMMEI_ID + if(msg->GUMMEI_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_gummei(&msg->GUMMEI_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GUMMEI_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CellAccessMode + if(msg->CellAccessMode_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cellaccessmode(&msg->CellAccessMode, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CELLACCESSMODE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - GW_TransportLayerAddress + if(msg->GW_TransportLayerAddress_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_transportlayeraddress(&msg->GW_TransportLayerAddress, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GW_TRANSPORTLAYERADDRESS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - RelayNode_Indicator + if(msg->RelayNode_Indicator_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_relaynode_indicator(&msg->RelayNode_Indicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_RELAYNODE_INDICATOR, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - GUMMEIType + if(msg->GUMMEIType_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_gummeitype(&msg->GUMMEIType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GUMMEITYPE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - Tunnel_Information_for_BBF + if(msg->Tunnel_Information_for_BBF_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tunnelinformation(&msg->Tunnel_Information_for_BBF, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TUNNEL_INFORMATION_FOR_BBF, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SIPTO_L_GW_TransportLayerAddress + if(msg->SIPTO_L_GW_TransportLayerAddress_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_transportlayeraddress(&msg->SIPTO_L_GW_TransportLayerAddress, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SIPTO_L_GW_TRANSPORTLAYERADDRESS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - LHN_ID + if(msg->LHN_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lhn_id(&msg->LHN_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_LHN_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initialuemessage( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_INITIALUEMESSAGE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->S_TMSI_present = false; + msg->CSG_Id_present = false; + msg->GUMMEI_ID_present = false; + msg->CellAccessMode_present = false; + msg->GW_TransportLayerAddress_present = false; + msg->RelayNode_Indicator_present = false; + msg->GUMMEIType_present = false; + msg->Tunnel_Information_for_BBF_present = false; + msg->SIPTO_L_GW_TransportLayerAddress_present = false; + msg->LHN_ID_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("InitialUEMessage-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;ieNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_NAS_PDU == ie_id) { + if(liblte_s1ap_unpack_nas_pdu(ptr, &msg->NAS_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TAI == ie_id) { + if(liblte_s1ap_unpack_tai(ptr, &msg->TAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EUTRAN_CGI == ie_id) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &msg->EUTRAN_CGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_RRC_ESTABLISHMENT_CAUSE == ie_id) { + if(liblte_s1ap_unpack_rrc_establishment_cause(ptr, &msg->RRC_Establishment_Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_S_TMSI == ie_id) { + if(liblte_s1ap_unpack_s_tmsi(ptr, &msg->S_TMSI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->S_TMSI_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSG_ID == ie_id) { + if(liblte_s1ap_unpack_csg_id(ptr, &msg->CSG_Id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSG_Id_present = true; + } else if(LIBLTE_S1AP_IE_ID_GUMMEI_ID == ie_id) { + if(liblte_s1ap_unpack_gummei(ptr, &msg->GUMMEI_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GUMMEI_ID_present = true; + } else if(LIBLTE_S1AP_IE_ID_CELLACCESSMODE == ie_id) { + if(liblte_s1ap_unpack_cellaccessmode(ptr, &msg->CellAccessMode) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CellAccessMode_present = true; + } else if(LIBLTE_S1AP_IE_ID_GW_TRANSPORTLAYERADDRESS == ie_id) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &msg->GW_TransportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GW_TransportLayerAddress_present = true; + } else if(LIBLTE_S1AP_IE_ID_RELAYNODE_INDICATOR == ie_id) { + if(liblte_s1ap_unpack_relaynode_indicator(ptr, &msg->RelayNode_Indicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->RelayNode_Indicator_present = true; + } else if(LIBLTE_S1AP_IE_ID_GUMMEITYPE == ie_id) { + if(liblte_s1ap_unpack_gummeitype(ptr, &msg->GUMMEIType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GUMMEIType_present = true; + } else if(LIBLTE_S1AP_IE_ID_TUNNEL_INFORMATION_FOR_BBF == ie_id) { + if(liblte_s1ap_unpack_tunnelinformation(ptr, &msg->Tunnel_Information_for_BBF) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Tunnel_Information_for_BBF_present = true; + } else if(LIBLTE_S1AP_IE_ID_SIPTO_L_GW_TRANSPORTLAYERADDRESS == ie_id) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &msg->SIPTO_L_GW_TransportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SIPTO_L_GW_TransportLayerAddress_present = true; + } else if(LIBLTE_S1AP_IE_ID_LHN_ID == ie_id) { + if(liblte_s1ap_unpack_lhn_id(ptr, &msg->LHN_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->LHN_ID_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UplinkNASTransport STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uplinknastransport( + LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UplinkNASTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 8; + if(!msg->GW_TransportLayerAddress_present) + n_ie--; + if(!msg->SIPTO_L_GW_TransportLayerAddress_present) + n_ie--; + if(!msg->LHN_ID_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - NAS_PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_nas_pdu(&msg->NAS_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_NAS_PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - EUTRAN_CGI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_eutran_cgi(&msg->EUTRAN_CGI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EUTRAN_CGI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TAI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tai(&msg->TAI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - GW_TransportLayerAddress + if(msg->GW_TransportLayerAddress_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_transportlayeraddress(&msg->GW_TransportLayerAddress, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GW_TRANSPORTLAYERADDRESS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SIPTO_L_GW_TransportLayerAddress + if(msg->SIPTO_L_GW_TransportLayerAddress_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_transportlayeraddress(&msg->SIPTO_L_GW_TransportLayerAddress, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SIPTO_L_GW_TRANSPORTLAYERADDRESS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - LHN_ID + if(msg->LHN_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lhn_id(&msg->LHN_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_LHN_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinknastransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->GW_TransportLayerAddress_present = false; + msg->SIPTO_L_GW_TransportLayerAddress_present = false; + msg->LHN_ID_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UplinkNASTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_NAS_PDU == ie_id) { + if(liblte_s1ap_unpack_nas_pdu(ptr, &msg->NAS_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EUTRAN_CGI == ie_id) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &msg->EUTRAN_CGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TAI == ie_id) { + if(liblte_s1ap_unpack_tai(ptr, &msg->TAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_GW_TRANSPORTLAYERADDRESS == ie_id) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &msg->GW_TransportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GW_TransportLayerAddress_present = true; + } else if(LIBLTE_S1AP_IE_ID_SIPTO_L_GW_TRANSPORTLAYERADDRESS == ie_id) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &msg->SIPTO_L_GW_TransportLayerAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SIPTO_L_GW_TransportLayerAddress_present = true; + } else if(LIBLTE_S1AP_IE_ID_LHN_ID == ie_id) { + if(liblte_s1ap_unpack_lhn_id(ptr, &msg->LHN_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->LHN_ID_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message NASNonDeliveryIndication STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_nasnondeliveryindication( + LIBLTE_S1AP_MESSAGE_NASNONDELIVERYINDICATION_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("NASNonDeliveryIndication-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - NAS_PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_nas_pdu(&msg->NAS_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_NAS_PDU, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_nasnondeliveryindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_NASNONDELIVERYINDICATION_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("NASNonDeliveryIndication-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_NAS_PDU == ie_id) { + if(liblte_s1ap_unpack_nas_pdu(ptr, &msg->NAS_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UE_associatedLogicalS1_ConnectionItem STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitem( + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UE-associatedLogicalS1-ConnectionItemRes error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - UE_associatedLogicalS1_ConnectionItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ue_associatedlogicals1_connectionitem(&msg->UE_associatedLogicalS1_ConnectionItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UE-associatedLogicalS1-ConnectionItemRes error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iUE_associatedLogicalS1_ConnectionItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UE_associatedLogicalS1_ConnectionItemRes STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_ue_associatedlogicals1_connectionitemres( + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UE-associatedLogicalS1-ConnectionItemResAck error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - UE_associatedLogicalS1_ConnectionItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ue_associatedlogicals1_connectionitem(&msg->UE_associatedLogicalS1_ConnectionItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_ue_associatedlogicals1_connectionitemres( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UE_ASSOCIATEDLOGICALS1_CONNECTIONITEMRES_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UE-associatedLogicalS1-ConnectionItemResAck error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iUE_associatedLogicalS1_ConnectionItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ErrorIndication STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_errorindication( + LIBLTE_S1AP_MESSAGE_ERRORINDICATION_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ErrorIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->MME_UE_S1AP_ID_present) + n_ie--; + if(!msg->eNB_UE_S1AP_ID_present) + n_ie--; + if(!msg->Cause_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + if(msg->MME_UE_S1AP_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - eNB_UE_S1AP_ID + if(msg->eNB_UE_S1AP_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - Cause + if(msg->Cause_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_errorindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ERRORINDICATION_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->MME_UE_S1AP_ID_present = false; + msg->eNB_UE_S1AP_ID_present = false; + msg->Cause_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ErrorIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MME_UE_S1AP_ID_present = true; + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->eNB_UE_S1AP_ID_present = true; + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Cause_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message S1SetupRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s1setuprequest( + LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("S1SetupRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 5; + if(!msg->eNBname_present) + n_ie--; + if(!msg->CSG_IdList_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Global_ENB_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_global_enb_id(&msg->Global_ENB_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GLOBAL_ENB_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNBname + if(msg->eNBname_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enbname(&msg->eNBname, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENBNAME, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SupportedTAs + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_supportedtas(&msg->SupportedTAs, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SUPPORTEDTAS, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - DefaultPagingDRX + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_pagingdrx(&msg->DefaultPagingDRX, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_DEFAULTPAGINGDRX, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CSG_IdList + if(msg->CSG_IdList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csg_idlist(&msg->CSG_IdList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSG_IDLIST, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s1setuprequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_S1SETUPREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->eNBname_present = false; + msg->CSG_IdList_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("S1SetupRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iGlobal_ENB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENBNAME == ie_id) { + if(liblte_s1ap_unpack_enbname(ptr, &msg->eNBname) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->eNBname_present = true; + } else if(LIBLTE_S1AP_IE_ID_SUPPORTEDTAS == ie_id) { + if(liblte_s1ap_unpack_supportedtas(ptr, &msg->SupportedTAs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_DEFAULTPAGINGDRX == ie_id) { + if(liblte_s1ap_unpack_pagingdrx(ptr, &msg->DefaultPagingDRX) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CSG_IDLIST == ie_id) { + if(liblte_s1ap_unpack_csg_idlist(ptr, &msg->CSG_IdList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSG_IdList_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message S1SetupResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s1setupresponse( + LIBLTE_S1AP_MESSAGE_S1SETUPRESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("S1SetupResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 5; + if(!msg->MMEname_present) + n_ie--; + if(!msg->MMERelaySupportIndicator_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MMEname + if(msg->MMEname_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mmename(&msg->MMEname, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MMENAME, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - ServedGUMMEIs + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_servedgummeis(&msg->ServedGUMMEIs, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SERVEDGUMMEIS, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - RelativeMMECapacity + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_relativemmecapacity(&msg->RelativeMMECapacity, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_RELATIVEMMECAPACITY, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - MMERelaySupportIndicator + if(msg->MMERelaySupportIndicator_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mmerelaysupportindicator(&msg->MMERelaySupportIndicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MMERELAYSUPPORTINDICATOR, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s1setupresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_S1SETUPRESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->MMEname_present = false; + msg->MMERelaySupportIndicator_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("S1SetupResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMMEname) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MMEname_present = true; + } else if(LIBLTE_S1AP_IE_ID_SERVEDGUMMEIS == ie_id) { + if(liblte_s1ap_unpack_servedgummeis(ptr, &msg->ServedGUMMEIs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_RELATIVEMMECAPACITY == ie_id) { + if(liblte_s1ap_unpack_relativemmecapacity(ptr, &msg->RelativeMMECapacity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_MMERELAYSUPPORTINDICATOR == ie_id) { + if(liblte_s1ap_unpack_mmerelaysupportindicator(ptr, &msg->MMERelaySupportIndicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MMERelaySupportIndicator_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message S1SetupFailure STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s1setupfailure( + LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("S1SetupFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->TimeToWait_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TimeToWait + if(msg->TimeToWait_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_timetowait(&msg->TimeToWait, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TIMETOWAIT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s1setupfailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_S1SETUPFAILURE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->TimeToWait_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("S1SetupFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iCause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TIMETOWAIT == ie_id) { + if(liblte_s1ap_unpack_timetowait(ptr, &msg->TimeToWait) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->TimeToWait_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ENBConfigurationUpdate STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbconfigurationupdate( + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBConfigurationUpdateIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->eNBname_present) + n_ie--; + if(!msg->SupportedTAs_present) + n_ie--; + if(!msg->CSG_IdList_present) + n_ie--; + if(!msg->DefaultPagingDRX_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - eNBname + if(msg->eNBname_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enbname(&msg->eNBname, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENBNAME, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SupportedTAs + if(msg->SupportedTAs_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_supportedtas(&msg->SupportedTAs, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SUPPORTEDTAS, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSG_IdList + if(msg->CSG_IdList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csg_idlist(&msg->CSG_IdList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSG_IDLIST, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - DefaultPagingDRX + if(msg->DefaultPagingDRX_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_pagingdrx(&msg->DefaultPagingDRX, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_DEFAULTPAGINGDRX, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbconfigurationupdate( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->eNBname_present = false; + msg->SupportedTAs_present = false; + msg->CSG_IdList_present = false; + msg->DefaultPagingDRX_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBConfigurationUpdateIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;ieNBname) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->eNBname_present = true; + } else if(LIBLTE_S1AP_IE_ID_SUPPORTEDTAS == ie_id) { + if(liblte_s1ap_unpack_supportedtas(ptr, &msg->SupportedTAs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SupportedTAs_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSG_IDLIST == ie_id) { + if(liblte_s1ap_unpack_csg_idlist(ptr, &msg->CSG_IdList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSG_IdList_present = true; + } else if(LIBLTE_S1AP_IE_ID_DEFAULTPAGINGDRX == ie_id) { + if(liblte_s1ap_unpack_pagingdrx(ptr, &msg->DefaultPagingDRX) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->DefaultPagingDRX_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ENBConfigurationUpdateAcknowledge STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbconfigurationupdateacknowledge( + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEACKNOWLEDGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBConfigurationUpdateAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbconfigurationupdateacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEACKNOWLEDGE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBConfigurationUpdateAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iCriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ENBConfigurationUpdateFailure STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbconfigurationupdatefailure( + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEFAILURE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBConfigurationUpdateFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->TimeToWait_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TimeToWait + if(msg->TimeToWait_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_timetowait(&msg->TimeToWait, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TIMETOWAIT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbconfigurationupdatefailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONUPDATEFAILURE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->TimeToWait_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBConfigurationUpdateFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iCause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TIMETOWAIT == ie_id) { + if(liblte_s1ap_unpack_timetowait(ptr, &msg->TimeToWait) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->TimeToWait_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message MMEConfigurationUpdate STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmeconfigurationupdate( + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEConfigurationUpdateIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->MMEname_present) + n_ie--; + if(!msg->ServedGUMMEIs_present) + n_ie--; + if(!msg->RelativeMMECapacity_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MMEname + if(msg->MMEname_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mmename(&msg->MMEname, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MMENAME, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - ServedGUMMEIs + if(msg->ServedGUMMEIs_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_servedgummeis(&msg->ServedGUMMEIs, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SERVEDGUMMEIS, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - RelativeMMECapacity + if(msg->RelativeMMECapacity_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_relativemmecapacity(&msg->RelativeMMECapacity, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_RELATIVEMMECAPACITY, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmeconfigurationupdate( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->MMEname_present = false; + msg->ServedGUMMEIs_present = false; + msg->RelativeMMECapacity_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEConfigurationUpdateIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMMEname) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MMEname_present = true; + } else if(LIBLTE_S1AP_IE_ID_SERVEDGUMMEIS == ie_id) { + if(liblte_s1ap_unpack_servedgummeis(ptr, &msg->ServedGUMMEIs) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ServedGUMMEIs_present = true; + } else if(LIBLTE_S1AP_IE_ID_RELATIVEMMECAPACITY == ie_id) { + if(liblte_s1ap_unpack_relativemmecapacity(ptr, &msg->RelativeMMECapacity) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->RelativeMMECapacity_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message MMEConfigurationUpdateAcknowledge STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmeconfigurationupdateacknowledge( + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEACKNOWLEDGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEConfigurationUpdateAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmeconfigurationupdateacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEACKNOWLEDGE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEConfigurationUpdateAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iCriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message MMEConfigurationUpdateFailure STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmeconfigurationupdatefailure( + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEFAILURE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEConfigurationUpdateFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->TimeToWait_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TimeToWait + if(msg->TimeToWait_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_timetowait(&msg->TimeToWait, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TIMETOWAIT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmeconfigurationupdatefailure( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONUPDATEFAILURE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->TimeToWait_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEConfigurationUpdateFailureIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iCause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TIMETOWAIT == ie_id) { + if(liblte_s1ap_unpack_timetowait(ptr, &msg->TimeToWait) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->TimeToWait_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UplinkS1cdma2000tunneling STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uplinks1cdma2000tunneling( + LIBLTE_S1AP_MESSAGE_UPLINKS1CDMA2000TUNNELING_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UplinkS1cdma2000tunnelingIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 9; + if(!msg->cdma2000HORequiredIndication_present) + n_ie--; + if(!msg->cdma2000OneXSRVCCInfo_present) + n_ie--; + if(!msg->cdma2000OneXRAND_present) + n_ie--; + if(!msg->EUTRANRoundTripDelayEstimationInfo_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - cdma2000RATType + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000rattype(&msg->cdma2000RATType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000RATTYPE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - cdma2000SectorID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000sectorid(&msg->cdma2000SectorID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000SECTORID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - cdma2000HORequiredIndication + if(msg->cdma2000HORequiredIndication_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000horequiredindication(&msg->cdma2000HORequiredIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000HOREQUIREDINDICATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - cdma2000OneXSRVCCInfo + if(msg->cdma2000OneXSRVCCInfo_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000onexsrvccinfo(&msg->cdma2000OneXSRVCCInfo, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000ONEXSRVCCINFO, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - cdma2000OneXRAND + if(msg->cdma2000OneXRAND_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000onexrand(&msg->cdma2000OneXRAND, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000ONEXRAND, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - cdma2000PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000pdu(&msg->cdma2000PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - EUTRANRoundTripDelayEstimationInfo + if(msg->EUTRANRoundTripDelayEstimationInfo_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_eutranroundtripdelayestimationinfo(&msg->EUTRANRoundTripDelayEstimationInfo, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EUTRANROUNDTRIPDELAYESTIMATIONINFO, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinks1cdma2000tunneling( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UPLINKS1CDMA2000TUNNELING_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->cdma2000HORequiredIndication_present = false; + msg->cdma2000OneXSRVCCInfo_present = false; + msg->cdma2000OneXRAND_present = false; + msg->EUTRANRoundTripDelayEstimationInfo_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UplinkS1cdma2000tunnelingIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CDMA2000RATTYPE == ie_id) { + if(liblte_s1ap_unpack_cdma2000rattype(ptr, &msg->cdma2000RATType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CDMA2000SECTORID == ie_id) { + if(liblte_s1ap_unpack_cdma2000sectorid(ptr, &msg->cdma2000SectorID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CDMA2000HOREQUIREDINDICATION == ie_id) { + if(liblte_s1ap_unpack_cdma2000horequiredindication(ptr, &msg->cdma2000HORequiredIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->cdma2000HORequiredIndication_present = true; + } else if(LIBLTE_S1AP_IE_ID_CDMA2000ONEXSRVCCINFO == ie_id) { + if(liblte_s1ap_unpack_cdma2000onexsrvccinfo(ptr, &msg->cdma2000OneXSRVCCInfo) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->cdma2000OneXSRVCCInfo_present = true; + } else if(LIBLTE_S1AP_IE_ID_CDMA2000ONEXRAND == ie_id) { + if(liblte_s1ap_unpack_cdma2000onexrand(ptr, &msg->cdma2000OneXRAND) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->cdma2000OneXRAND_present = true; + } else if(LIBLTE_S1AP_IE_ID_CDMA2000PDU == ie_id) { + if(liblte_s1ap_unpack_cdma2000pdu(ptr, &msg->cdma2000PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EUTRANROUNDTRIPDELAYESTIMATIONINFO == ie_id) { + if(liblte_s1ap_unpack_eutranroundtripdelayestimationinfo(ptr, &msg->EUTRANRoundTripDelayEstimationInfo) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->EUTRANRoundTripDelayEstimationInfo_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UECapabilityInfoIndication STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uecapabilityinfoindication( + LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UECapabilityInfoIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - UERadioCapability + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueradiocapability(&msg->UERadioCapability, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UERADIOCAPABILITY, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uecapabilityinfoindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UECAPABILITYINFOINDICATION_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UECapabilityInfoIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UERADIOCAPABILITY == ie_id) { + if(liblte_s1ap_unpack_ueradiocapability(ptr, &msg->UERadioCapability) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ENBStatusTransfer STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbstatustransfer( + LIBLTE_S1AP_MESSAGE_ENBSTATUSTRANSFER_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBStatusTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_StatusTransfer_TransparentContainer + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_statustransfer_transparentcontainer(&msg->eNB_StatusTransfer_TransparentContainer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbstatustransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBSTATUSTRANSFER_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBStatusTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER == ie_id) { + if(liblte_s1ap_unpack_enb_statustransfer_transparentcontainer(ptr, &msg->eNB_StatusTransfer_TransparentContainer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message MMEStatusTransfer STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmestatustransfer( + LIBLTE_S1AP_MESSAGE_MMESTATUSTRANSFER_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEStatusTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_StatusTransfer_TransparentContainer + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_statustransfer_transparentcontainer(&msg->eNB_StatusTransfer_TransparentContainer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmestatustransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMESTATUSTRANSFER_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEStatusTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_STATUSTRANSFER_TRANSPARENTCONTAINER == ie_id) { + if(liblte_s1ap_unpack_enb_statustransfer_transparentcontainer(ptr, &msg->eNB_StatusTransfer_TransparentContainer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TraceStart STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tracestart( + LIBLTE_S1AP_MESSAGE_TRACESTART_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TraceStartIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TraceActivation + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_traceactivation(&msg->TraceActivation, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TRACEACTIVATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tracestart( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TRACESTART_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TraceStartIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TRACEACTIVATION == ie_id) { + if(liblte_s1ap_unpack_traceactivation(ptr, &msg->TraceActivation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TraceFailureIndication STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_tracefailureindication( + LIBLTE_S1AP_MESSAGE_TRACEFAILUREINDICATION_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TraceFailureIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_UTRAN_Trace_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_utran_trace_id(&msg->E_UTRAN_Trace_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_UTRAN_TRACE_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_tracefailureindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TRACEFAILUREINDICATION_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TraceFailureIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_UTRAN_TRACE_ID == ie_id) { + if(liblte_s1ap_unpack_e_utran_trace_id(ptr, &msg->E_UTRAN_Trace_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message DeactivateTrace STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_deactivatetrace( + LIBLTE_S1AP_MESSAGE_DEACTIVATETRACE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("DeactivateTraceIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_UTRAN_Trace_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_utran_trace_id(&msg->E_UTRAN_Trace_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_UTRAN_TRACE_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_deactivatetrace( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DEACTIVATETRACE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("DeactivateTraceIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_UTRAN_TRACE_ID == ie_id) { + if(liblte_s1ap_unpack_e_utran_trace_id(ptr, &msg->E_UTRAN_Trace_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message CellTrafficTrace STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_celltraffictrace( + LIBLTE_S1AP_MESSAGE_CELLTRAFFICTRACE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("CellTrafficTraceIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 6; + if(!msg->PrivacyIndicator_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_UTRAN_Trace_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_utran_trace_id(&msg->E_UTRAN_Trace_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_UTRAN_TRACE_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - EUTRAN_CGI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_eutran_cgi(&msg->EUTRAN_CGI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EUTRAN_CGI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TraceCollectionEntityIPAddress + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_transportlayeraddress(&msg->TraceCollectionEntityIPAddress, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TRACECOLLECTIONENTITYIPADDRESS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - PrivacyIndicator + if(msg->PrivacyIndicator_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_privacyindicator(&msg->PrivacyIndicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_PRIVACYINDICATOR, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_celltraffictrace( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_CELLTRAFFICTRACE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->PrivacyIndicator_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("CellTrafficTraceIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_UTRAN_TRACE_ID == ie_id) { + if(liblte_s1ap_unpack_e_utran_trace_id(ptr, &msg->E_UTRAN_Trace_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EUTRAN_CGI == ie_id) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &msg->EUTRAN_CGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TRACECOLLECTIONENTITYIPADDRESS == ie_id) { + if(liblte_s1ap_unpack_transportlayeraddress(ptr, &msg->TraceCollectionEntityIPAddress) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_PRIVACYINDICATOR == ie_id) { + if(liblte_s1ap_unpack_privacyindicator(ptr, &msg->PrivacyIndicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->PrivacyIndicator_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message LocationReportingControl STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_locationreportingcontrol( + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGCONTROL_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("LocationReportingControlIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - RequestType + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_requesttype(&msg->RequestType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_REQUESTTYPE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_locationreportingcontrol( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGCONTROL_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("LocationReportingControlIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_REQUESTTYPE == ie_id) { + if(liblte_s1ap_unpack_requesttype(ptr, &msg->RequestType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message LocationReportingFailureIndication STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_locationreportingfailureindication( + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGFAILUREINDICATION_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("LocationReportingFailureIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_locationreportingfailureindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LOCATIONREPORTINGFAILUREINDICATION_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("LocationReportingFailureIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message LocationReport STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_locationreport( + LIBLTE_S1AP_MESSAGE_LOCATIONREPORT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("LocationReportIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 5; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - EUTRAN_CGI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_eutran_cgi(&msg->EUTRAN_CGI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EUTRAN_CGI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TAI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tai(&msg->TAI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - RequestType + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_requesttype(&msg->RequestType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_REQUESTTYPE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_locationreport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_LOCATIONREPORT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("LocationReportIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EUTRAN_CGI == ie_id) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &msg->EUTRAN_CGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TAI == ie_id) { + if(liblte_s1ap_unpack_tai(ptr, &msg->TAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_REQUESTTYPE == ie_id) { + if(liblte_s1ap_unpack_requesttype(ptr, &msg->RequestType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message OverloadStart STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_overloadstart( + LIBLTE_S1AP_MESSAGE_OVERLOADSTART_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("OverloadStartIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 3; + if(!msg->GUMMEIList_present) + n_ie--; + if(!msg->TrafficLoadReductionIndication_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - OverloadResponse + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_overloadresponse(&msg->OverloadResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_OVERLOADRESPONSE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - GUMMEIList + if(msg->GUMMEIList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_gummeilist(&msg->GUMMEIList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GUMMEILIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - TrafficLoadReductionIndication + if(msg->TrafficLoadReductionIndication_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_trafficloadreductionindication(&msg->TrafficLoadReductionIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TRAFFICLOADREDUCTIONINDICATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_overloadstart( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_OVERLOADSTART_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->GUMMEIList_present = false; + msg->TrafficLoadReductionIndication_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("OverloadStartIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iOverloadResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_GUMMEILIST == ie_id) { + if(liblte_s1ap_unpack_gummeilist(ptr, &msg->GUMMEIList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GUMMEIList_present = true; + } else if(LIBLTE_S1AP_IE_ID_TRAFFICLOADREDUCTIONINDICATION == ie_id) { + if(liblte_s1ap_unpack_trafficloadreductionindication(ptr, &msg->TrafficLoadReductionIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->TrafficLoadReductionIndication_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message OverloadStop STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_overloadstop( + LIBLTE_S1AP_MESSAGE_OVERLOADSTOP_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("OverloadStopIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->GUMMEIList_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - GUMMEIList + if(msg->GUMMEIList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_gummeilist(&msg->GUMMEIList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GUMMEILIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_overloadstop( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_OVERLOADSTOP_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->GUMMEIList_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("OverloadStopIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iGUMMEIList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GUMMEIList_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message WriteReplaceWarningRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_writereplacewarningrequest( + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("WriteReplaceWarningRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 11; + if(!msg->WarningAreaList_present) + n_ie--; + if(!msg->ExtendedRepetitionPeriod_present) + n_ie--; + if(!msg->WarningType_present) + n_ie--; + if(!msg->WarningSecurityInfo_present) + n_ie--; + if(!msg->DataCodingScheme_present) + n_ie--; + if(!msg->WarningMessageContents_present) + n_ie--; + if(!msg->ConcurrentWarningMessageIndicator_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MessageIdentifier + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_messageidentifier(&msg->MessageIdentifier, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MESSAGEIDENTIFIER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - SerialNumber + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_serialnumber(&msg->SerialNumber, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SERIALNUMBER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - WarningAreaList + if(msg->WarningAreaList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_warningarealist(&msg->WarningAreaList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_WARNINGAREALIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - RepetitionPeriod + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_repetitionperiod(&msg->RepetitionPeriod, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_REPETITIONPERIOD, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - ExtendedRepetitionPeriod + if(msg->ExtendedRepetitionPeriod_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_extendedrepetitionperiod(&msg->ExtendedRepetitionPeriod, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EXTENDEDREPETITIONPERIOD, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - NumberofBroadcastRequest + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_numberofbroadcastrequest(&msg->NumberofBroadcastRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_NUMBEROFBROADCASTREQUEST, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - WarningType + if(msg->WarningType_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_warningtype(&msg->WarningType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_WARNINGTYPE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - WarningSecurityInfo + if(msg->WarningSecurityInfo_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_warningsecurityinfo(&msg->WarningSecurityInfo, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_WARNINGSECURITYINFO, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - DataCodingScheme + if(msg->DataCodingScheme_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_datacodingscheme(&msg->DataCodingScheme, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_DATACODINGSCHEME, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - WarningMessageContents + if(msg->WarningMessageContents_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_warningmessagecontents(&msg->WarningMessageContents, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_WARNINGMESSAGECONTENTS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - ConcurrentWarningMessageIndicator + if(msg->ConcurrentWarningMessageIndicator_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_concurrentwarningmessageindicator(&msg->ConcurrentWarningMessageIndicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CONCURRENTWARNINGMESSAGEINDICATOR, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_writereplacewarningrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->WarningAreaList_present = false; + msg->ExtendedRepetitionPeriod_present = false; + msg->WarningType_present = false; + msg->WarningSecurityInfo_present = false; + msg->DataCodingScheme_present = false; + msg->WarningMessageContents_present = false; + msg->ConcurrentWarningMessageIndicator_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("WriteReplaceWarningRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMessageIdentifier) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SERIALNUMBER == ie_id) { + if(liblte_s1ap_unpack_serialnumber(ptr, &msg->SerialNumber) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_WARNINGAREALIST == ie_id) { + if(liblte_s1ap_unpack_warningarealist(ptr, &msg->WarningAreaList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->WarningAreaList_present = true; + } else if(LIBLTE_S1AP_IE_ID_REPETITIONPERIOD == ie_id) { + if(liblte_s1ap_unpack_repetitionperiod(ptr, &msg->RepetitionPeriod) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EXTENDEDREPETITIONPERIOD == ie_id) { + if(liblte_s1ap_unpack_extendedrepetitionperiod(ptr, &msg->ExtendedRepetitionPeriod) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ExtendedRepetitionPeriod_present = true; + } else if(LIBLTE_S1AP_IE_ID_NUMBEROFBROADCASTREQUEST == ie_id) { + if(liblte_s1ap_unpack_numberofbroadcastrequest(ptr, &msg->NumberofBroadcastRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_WARNINGTYPE == ie_id) { + if(liblte_s1ap_unpack_warningtype(ptr, &msg->WarningType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->WarningType_present = true; + } else if(LIBLTE_S1AP_IE_ID_WARNINGSECURITYINFO == ie_id) { + if(liblte_s1ap_unpack_warningsecurityinfo(ptr, &msg->WarningSecurityInfo) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->WarningSecurityInfo_present = true; + } else if(LIBLTE_S1AP_IE_ID_DATACODINGSCHEME == ie_id) { + if(liblte_s1ap_unpack_datacodingscheme(ptr, &msg->DataCodingScheme) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->DataCodingScheme_present = true; + } else if(LIBLTE_S1AP_IE_ID_WARNINGMESSAGECONTENTS == ie_id) { + if(liblte_s1ap_unpack_warningmessagecontents(ptr, &msg->WarningMessageContents) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->WarningMessageContents_present = true; + } else if(LIBLTE_S1AP_IE_ID_CONCURRENTWARNINGMESSAGEINDICATOR == ie_id) { + if(liblte_s1ap_unpack_concurrentwarningmessageindicator(ptr, &msg->ConcurrentWarningMessageIndicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ConcurrentWarningMessageIndicator_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message WriteReplaceWarningResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_writereplacewarningresponse( + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGRESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("WriteReplaceWarningResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->BroadcastCompletedAreaList_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MessageIdentifier + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_messageidentifier(&msg->MessageIdentifier, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MESSAGEIDENTIFIER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - SerialNumber + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_serialnumber(&msg->SerialNumber, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SERIALNUMBER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - BroadcastCompletedAreaList + if(msg->BroadcastCompletedAreaList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_broadcastcompletedarealist(&msg->BroadcastCompletedAreaList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_BROADCASTCOMPLETEDAREALIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_writereplacewarningresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_WRITEREPLACEWARNINGRESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->BroadcastCompletedAreaList_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("WriteReplaceWarningResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMessageIdentifier) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SERIALNUMBER == ie_id) { + if(liblte_s1ap_unpack_serialnumber(ptr, &msg->SerialNumber) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_BROADCASTCOMPLETEDAREALIST == ie_id) { + if(liblte_s1ap_unpack_broadcastcompletedarealist(ptr, &msg->BroadcastCompletedAreaList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->BroadcastCompletedAreaList_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message MMEDirectInformationTransfer STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmedirectinformationtransfer( + LIBLTE_S1AP_MESSAGE_MMEDIRECTINFORMATIONTRANSFER_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEDirectInformationTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Inter_SystemInformationTransferTypeMDT + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_inter_systeminformationtransfertype(&msg->Inter_SystemInformationTransferTypeMDT, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_INTER_SYSTEMINFORMATIONTRANSFERTYPEMDT, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmedirectinformationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMEDIRECTINFORMATIONTRANSFER_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEDirectInformationTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iInter_SystemInformationTransferTypeMDT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ENBConfigurationTransfer STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbconfigurationtransfer( + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONTRANSFER_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBConfigurationTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->SONConfigurationTransferECT_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - SONConfigurationTransferECT + if(msg->SONConfigurationTransferECT_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_sonconfigurationtransfer(&msg->SONConfigurationTransferECT, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SONCONFIGURATIONTRANSFERECT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbconfigurationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBCONFIGURATIONTRANSFER_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->SONConfigurationTransferECT_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBConfigurationTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iSONConfigurationTransferECT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SONConfigurationTransferECT_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message MMEConfigurationTransfer STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_mmeconfigurationtransfer( + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONTRANSFER_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEConfigurationTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + if(!msg->SONConfigurationTransferMCT_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - SONConfigurationTransferMCT + if(msg->SONConfigurationTransferMCT_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_sonconfigurationtransfer(&msg->SONConfigurationTransferMCT, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SONCONFIGURATIONTRANSFERMCT, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_mmeconfigurationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_MMECONFIGURATIONTRANSFER_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->SONConfigurationTransferMCT_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("MMEConfigurationTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iSONConfigurationTransferMCT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SONConfigurationTransferMCT_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message PrivateMessage STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_privatemessage( + LIBLTE_S1AP_MESSAGE_PRIVATEMESSAGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("PrivateMessageIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 0; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_privatemessage( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PRIVATEMESSAGE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("PrivateMessageIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message KillRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_killrequest( + LIBLTE_S1AP_MESSAGE_KILLREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("KillRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->WarningAreaList_present) + n_ie--; + if(!msg->KillAllWarningMessages_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MessageIdentifier + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_messageidentifier(&msg->MessageIdentifier, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MESSAGEIDENTIFIER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - SerialNumber + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_serialnumber(&msg->SerialNumber, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SERIALNUMBER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - WarningAreaList + if(msg->WarningAreaList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_warningarealist(&msg->WarningAreaList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_WARNINGAREALIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - KillAllWarningMessages + if(msg->KillAllWarningMessages_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_killallwarningmessages(&msg->KillAllWarningMessages, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_KILLALLWARNINGMESSAGES, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_killrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_KILLREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->WarningAreaList_present = false; + msg->KillAllWarningMessages_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("KillRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMessageIdentifier) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SERIALNUMBER == ie_id) { + if(liblte_s1ap_unpack_serialnumber(ptr, &msg->SerialNumber) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_WARNINGAREALIST == ie_id) { + if(liblte_s1ap_unpack_warningarealist(ptr, &msg->WarningAreaList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->WarningAreaList_present = true; + } else if(LIBLTE_S1AP_IE_ID_KILLALLWARNINGMESSAGES == ie_id) { + if(liblte_s1ap_unpack_killallwarningmessages(ptr, &msg->KillAllWarningMessages) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->KillAllWarningMessages_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message KillResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_killresponse( + LIBLTE_S1AP_MESSAGE_KILLRESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("KillResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->BroadcastCancelledAreaList_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MessageIdentifier + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_messageidentifier(&msg->MessageIdentifier, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MESSAGEIDENTIFIER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - SerialNumber + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_serialnumber(&msg->SerialNumber, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SERIALNUMBER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - BroadcastCancelledAreaList + if(msg->BroadcastCancelledAreaList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_broadcastcancelledarealist(&msg->BroadcastCancelledAreaList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_BROADCASTCANCELLEDAREALIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_killresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_KILLRESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->BroadcastCancelledAreaList_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("KillResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMessageIdentifier) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SERIALNUMBER == ie_id) { + if(liblte_s1ap_unpack_serialnumber(ptr, &msg->SerialNumber) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_BROADCASTCANCELLEDAREALIST == ie_id) { + if(liblte_s1ap_unpack_broadcastcancelledarealist(ptr, &msg->BroadcastCancelledAreaList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->BroadcastCancelledAreaList_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message PWSRestartIndication STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pwsrestartindication( + LIBLTE_S1AP_MESSAGE_PWSRESTARTINDICATION_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("PWSRestartIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->EmergencyAreaIDListForRestart_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - ECGIListForRestart + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ecgilistforrestart(&msg->ECGIListForRestart, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ECGILISTFORRESTART, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Global_ENB_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_global_enb_id(&msg->Global_ENB_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GLOBAL_ENB_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TAIListForRestart + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tailistforrestart(&msg->TAIListForRestart, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAILISTFORRESTART, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - EmergencyAreaIDListForRestart + if(msg->EmergencyAreaIDListForRestart_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_emergencyareaidlistforrestart(&msg->EmergencyAreaIDListForRestart, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EMERGENCYAREAIDLISTFORRESTART, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pwsrestartindication( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PWSRESTARTINDICATION_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->EmergencyAreaIDListForRestart_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("PWSRestartIndicationIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iECGIListForRestart) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_GLOBAL_ENB_ID == ie_id) { + if(liblte_s1ap_unpack_global_enb_id(ptr, &msg->Global_ENB_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TAILISTFORRESTART == ie_id) { + if(liblte_s1ap_unpack_tailistforrestart(ptr, &msg->TAIListForRestart) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EMERGENCYAREAIDLISTFORRESTART == ie_id) { + if(liblte_s1ap_unpack_emergencyareaidlistforrestart(ptr, &msg->EmergencyAreaIDListForRestart) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->EmergencyAreaIDListForRestart_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message DownlinkUEAssociatedLPPaTransport STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinkueassociatedlppatransport( + LIBLTE_S1AP_MESSAGE_DOWNLINKUEASSOCIATEDLPPATRANSPORT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("DownlinkUEAssociatedLPPaTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Routing_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_routing_id(&msg->Routing_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ROUTING_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - LPPa_PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lppa_pdu(&msg->LPPa_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_LPPA_PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinkueassociatedlppatransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKUEASSOCIATEDLPPATRANSPORT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("DownlinkUEAssociatedLPPaTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ROUTING_ID == ie_id) { + if(liblte_s1ap_unpack_routing_id(ptr, &msg->Routing_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_LPPA_PDU == ie_id) { + if(liblte_s1ap_unpack_lppa_pdu(ptr, &msg->LPPa_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UplinkUEAssociatedLPPaTransport STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uplinkueassociatedlppatransport( + LIBLTE_S1AP_MESSAGE_UPLINKUEASSOCIATEDLPPATRANSPORT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UplinkUEAssociatedLPPaTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Routing_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_routing_id(&msg->Routing_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ROUTING_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - LPPa_PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lppa_pdu(&msg->LPPa_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_LPPA_PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinkueassociatedlppatransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UPLINKUEASSOCIATEDLPPATRANSPORT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UplinkUEAssociatedLPPaTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ROUTING_ID == ie_id) { + if(liblte_s1ap_unpack_routing_id(ptr, &msg->Routing_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_LPPA_PDU == ie_id) { + if(liblte_s1ap_unpack_lppa_pdu(ptr, &msg->LPPa_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message DownlinkNonUEAssociatedLPPaTransport STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinknonueassociatedlppatransport( + LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("DownlinkNonUEAssociatedLPPaTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 2; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Routing_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_routing_id(&msg->Routing_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ROUTING_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - LPPa_PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lppa_pdu(&msg->LPPa_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_LPPA_PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinknonueassociatedlppatransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("DownlinkNonUEAssociatedLPPaTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iRouting_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_LPPA_PDU == ie_id) { + if(liblte_s1ap_unpack_lppa_pdu(ptr, &msg->LPPa_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message UplinkNonUEAssociatedLPPaTransport STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_uplinknonueassociatedlppatransport( + LIBLTE_S1AP_MESSAGE_UPLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("UplinkNonUEAssociatedLPPaTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 2; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Routing_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_routing_id(&msg->Routing_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ROUTING_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - LPPa_PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lppa_pdu(&msg->LPPa_PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_LPPA_PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_uplinknonueassociatedlppatransport( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_UPLINKNONUEASSOCIATEDLPPATRANSPORT_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("UplinkNonUEAssociatedLPPaTransport-IEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iRouting_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_LPPA_PDU == ie_id) { + if(liblte_s1ap_unpack_lppa_pdu(ptr, &msg->LPPa_PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ENBDirectInformationTransfer STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_enbdirectinformationtransfer( + LIBLTE_S1AP_MESSAGE_ENBDIRECTINFORMATIONTRANSFER_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBDirectInformationTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Inter_SystemInformationTransferTypeEDT + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_inter_systeminformationtransfertype(&msg->Inter_SystemInformationTransferTypeEDT, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_INTER_SYSTEMINFORMATIONTRANSFERTYPEEDT, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_enbdirectinformationtransfer( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_ENBDIRECTINFORMATIONTRANSFER_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ENBDirectInformationTransferIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iInter_SystemInformationTransferTypeEDT) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABDataForwardingItem STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabdataforwardingitem( + LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABDataForwardingItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABDataForwardingItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabdataforwardingitem(&msg->E_RABDataForwardingItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABDATAFORWARDINGITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabdataforwardingitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABDATAFORWARDINGITEM_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABDataForwardingItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABDataForwardingItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemHOReq STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemhoreq( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemHOReqIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABToBeSetupItemHOReq + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetupitemhoreq(&msg->E_RABToBeSetupItemHOReq, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMHOREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemhoreq( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMHOREQ_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemHOReqIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABToBeSetupItemHOReq) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABAdmittedItem STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabadmitteditem( + LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABAdmittedItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABAdmittedItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabadmitteditem(&msg->E_RABAdmittedItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABADMITTEDITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabadmitteditem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABADMITTEDITEM_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABAdmittedItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABAdmittedItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABFailedtoSetupItemHOReqAck STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabfailedtosetupitemhoreqack( + LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABFailedtoSetupItemHOReqAckIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABFailedtoSetupItemHOReqAck + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabfailedtosetupitemhoreqack(&msg->E_RABFailedtoSetupItemHOReqAck, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPITEMHOREQACK, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabfailedtosetupitemhoreqack( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABFAILEDTOSETUPITEMHOREQACK_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABFailedtoSetupItemHOReqAckIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABFailedtoSetupItemHOReqAck) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSwitchedDLItem STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitcheddlitem( + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSwitchedDLItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABToBeSwitchedDLItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobeswitcheddlitem(&msg->E_RABToBeSwitchedDLItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDDLITEM, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitcheddlitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDDLITEM_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSwitchedDLItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABToBeSwitchedDLItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSwitchedULItem STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobeswitchedulitem( + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSwitchedULItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABToBeSwitchedULItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobeswitchedulitem(&msg->E_RABToBeSwitchedULItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDULITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobeswitchedulitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESWITCHEDULITEM_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSwitchedULItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABToBeSwitchedULItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemBearerSUReq STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitembearersureq( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemBearerSUReqIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABToBeSetupItemBearerSUReq + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetupitembearersureq(&msg->E_RABToBeSetupItemBearerSUReq, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMBEARERSUREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitembearersureq( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMBEARERSUREQ_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemBearerSUReqIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABToBeSetupItemBearerSUReq) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABSetupItemBearerSURes STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitembearersures( + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURES_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupItemBearerSUResIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABSetupItemBearerSURes + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabsetupitembearersures(&msg->E_RABSetupItemBearerSURes, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABSETUPITEMBEARERSURES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitembearersures( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMBEARERSURES_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupItemBearerSUResIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABSetupItemBearerSURes) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeModifiedItemBearerModReq STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobemodifieditembearermodreq( + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeModifiedItemBearerModReqIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABToBeModifiedItemBearerModReq + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobemodifieditembearermodreq(&msg->E_RABToBeModifiedItemBearerModReq, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBEMODIFIEDITEMBEARERMODREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobemodifieditembearermodreq( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBEMODIFIEDITEMBEARERMODREQ_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeModifiedItemBearerModReqIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABToBeModifiedItemBearerModReq) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABModifyItemBearerModRes STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyitembearermodres( + LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRES_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABModifyItemBearerModResIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABModifyItemBearerModRes + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabmodifyitembearermodres(&msg->E_RABModifyItemBearerModRes, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABMODIFYITEMBEARERMODRES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyitembearermodres( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABMODIFYITEMBEARERMODRES_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABModifyItemBearerModResIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABModifyItemBearerModRes) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABReleaseItemBearerRelComp STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseitembearerrelcomp( + LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMP_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseItemBearerRelCompIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABReleaseItemBearerRelComp + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabreleaseitembearerrelcomp(&msg->E_RABReleaseItemBearerRelComp, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABRELEASEITEMBEARERRELCOMP, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseitembearerrelcomp( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASEITEMBEARERRELCOMP_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseItemBearerRelCompIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABReleaseItemBearerRelComp) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABToBeSetupItemCtxtSUReq STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabtobesetupitemctxtsureq( + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemCtxtSUReqIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABToBeSetupItemCtxtSUReq + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetupitemctxtsureq(&msg->E_RABToBeSetupItemCtxtSUReq, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPITEMCTXTSUREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabtobesetupitemctxtsureq( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABToBeSetupItemCtxtSUReqIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABToBeSetupItemCtxtSUReq) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABSetupItemCtxtSURes STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupitemctxtsures( + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURES_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupItemCtxtSUResIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - E_RABSetupItemCtxtSURes + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabsetupitemctxtsures(&msg->E_RABSetupItemCtxtSURes, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABSETUPITEMCTXTSURES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupitemctxtsures( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPITEMCTXTSURES_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupItemCtxtSUResIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iE_RABSetupItemCtxtSURes) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message TAIItem STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_taiitem( + LIBLTE_S1AP_MESSAGE_TAIITEM_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("TAIItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 1; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - TAIItem + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_taiitem(&msg->TAIItem, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAIITEM, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_taiitem( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_TAIITEM_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("TAIItemIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iTAIItem) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message ResetAcknowledge STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_resetacknowledge( + LIBLTE_S1AP_MESSAGE_RESETACKNOWLEDGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ResetAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 2; + if(!msg->UE_associatedLogicalS1_ConnectionListResAck_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - UE_associatedLogicalS1_ConnectionListResAck + if(msg->UE_associatedLogicalS1_ConnectionListResAck_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ue_associatedlogicals1_connectionlistresack(&msg->UE_associatedLogicalS1_ConnectionListResAck, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UE_ASSOCIATEDLOGICALS1_CONNECTIONLISTRESACK, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_resetacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_RESETACKNOWLEDGE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->UE_associatedLogicalS1_ConnectionListResAck_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ResetAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iUE_associatedLogicalS1_ConnectionListResAck) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->UE_associatedLogicalS1_ConnectionListResAck_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message Reset STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_reset( + LIBLTE_S1AP_MESSAGE_RESET_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("ResetIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 2; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - ResetType + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_resettype(&msg->ResetType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_RESETTYPE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_reset( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_RESET_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("ResetIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iCause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_RESETTYPE == ie_id) { + if(liblte_s1ap_unpack_resettype(ptr, &msg->ResetType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message DownlinkS1cdma2000tunneling STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_downlinks1cdma2000tunneling( + LIBLTE_S1AP_MESSAGE_DOWNLINKS1CDMA2000TUNNELING_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("DownlinkS1cdma2000tunnelingIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 6; + if(!msg->E_RABSubjecttoDataForwardingList_present) + n_ie--; + if(!msg->cdma2000HOStatus_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABSubjecttoDataForwardingList + if(msg->E_RABSubjecttoDataForwardingList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabsubjecttodataforwardinglist(&msg->E_RABSubjecttoDataForwardingList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABSUBJECTTODATAFORWARDINGLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - cdma2000HOStatus + if(msg->cdma2000HOStatus_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000hostatus(&msg->cdma2000HOStatus, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000HOSTATUS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - cdma2000RATType + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000rattype(&msg->cdma2000RATType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000RATTYPE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - cdma2000PDU + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cdma2000pdu(&msg->cdma2000PDU, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CDMA2000PDU, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_downlinks1cdma2000tunneling( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_DOWNLINKS1CDMA2000TUNNELING_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->E_RABSubjecttoDataForwardingList_present = false; + msg->cdma2000HOStatus_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("DownlinkS1cdma2000tunnelingIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABSUBJECTTODATAFORWARDINGLIST == ie_id) { + if(liblte_s1ap_unpack_e_rabsubjecttodataforwardinglist(ptr, &msg->E_RABSubjecttoDataForwardingList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABSubjecttoDataForwardingList_present = true; + } else if(LIBLTE_S1AP_IE_ID_CDMA2000HOSTATUS == ie_id) { + if(liblte_s1ap_unpack_cdma2000hostatus(ptr, &msg->cdma2000HOStatus) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->cdma2000HOStatus_present = true; + } else if(LIBLTE_S1AP_IE_ID_CDMA2000RATTYPE == ie_id) { + if(liblte_s1ap_unpack_cdma2000rattype(ptr, &msg->cdma2000RATType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CDMA2000PDU == ie_id) { + if(liblte_s1ap_unpack_cdma2000pdu(ptr, &msg->cdma2000PDU) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverCommand STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handovercommand( + LIBLTE_S1AP_MESSAGE_HANDOVERCOMMAND_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverCommandIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 9; + if(!msg->NASSecurityParametersfromE_UTRAN_present) + n_ie--; + if(!msg->E_RABSubjecttoDataForwardingList_present) + n_ie--; + if(!msg->E_RABtoReleaseListHOCmd_present) + n_ie--; + if(!msg->Target_ToSource_TransparentContainer_Secondary_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - HandoverType + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_handovertype(&msg->HandoverType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_HANDOVERTYPE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - NASSecurityParametersfromE_UTRAN + if(msg->NASSecurityParametersfromE_UTRAN_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_nassecurityparametersfrome_utran(&msg->NASSecurityParametersfromE_UTRAN, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_NASSECURITYPARAMETERSFROME_UTRAN, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABSubjecttoDataForwardingList + if(msg->E_RABSubjecttoDataForwardingList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabsubjecttodataforwardinglist(&msg->E_RABSubjecttoDataForwardingList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABSUBJECTTODATAFORWARDINGLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABtoReleaseListHOCmd + if(msg->E_RABtoReleaseListHOCmd_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rablist(&msg->E_RABtoReleaseListHOCmd, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTORELEASELISTHOCMD, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - Target_ToSource_TransparentContainer + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_target_tosource_transparentcontainer(&msg->Target_ToSource_TransparentContainer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TARGET_TOSOURCE_TRANSPARENTCONTAINER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Target_ToSource_TransparentContainer_Secondary + if(msg->Target_ToSource_TransparentContainer_Secondary_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_target_tosource_transparentcontainer(&msg->Target_ToSource_TransparentContainer_Secondary, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TARGET_TOSOURCE_TRANSPARENTCONTAINER_SECONDARY, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handovercommand( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERCOMMAND_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->NASSecurityParametersfromE_UTRAN_present = false; + msg->E_RABSubjecttoDataForwardingList_present = false; + msg->E_RABtoReleaseListHOCmd_present = false; + msg->Target_ToSource_TransparentContainer_Secondary_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverCommandIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_HANDOVERTYPE == ie_id) { + if(liblte_s1ap_unpack_handovertype(ptr, &msg->HandoverType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_NASSECURITYPARAMETERSFROME_UTRAN == ie_id) { + if(liblte_s1ap_unpack_nassecurityparametersfrome_utran(ptr, &msg->NASSecurityParametersfromE_UTRAN) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABSUBJECTTODATAFORWARDINGLIST == ie_id) { + if(liblte_s1ap_unpack_e_rabsubjecttodataforwardinglist(ptr, &msg->E_RABSubjecttoDataForwardingList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABSubjecttoDataForwardingList_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABTORELEASELISTHOCMD == ie_id) { + if(liblte_s1ap_unpack_e_rablist(ptr, &msg->E_RABtoReleaseListHOCmd) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABtoReleaseListHOCmd_present = true; + } else if(LIBLTE_S1AP_IE_ID_TARGET_TOSOURCE_TRANSPARENTCONTAINER == ie_id) { + if(liblte_s1ap_unpack_target_tosource_transparentcontainer(ptr, &msg->Target_ToSource_TransparentContainer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TARGET_TOSOURCE_TRANSPARENTCONTAINER_SECONDARY == ie_id) { + if(liblte_s1ap_unpack_target_tosource_transparentcontainer(ptr, &msg->Target_ToSource_TransparentContainer_Secondary) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Target_ToSource_TransparentContainer_Secondary_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrequest( + LIBLTE_S1AP_MESSAGE_HANDOVERREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 19; + if(!msg->HandoverRestrictionList_present) + n_ie--; + if(!msg->TraceActivation_present) + n_ie--; + if(!msg->RequestType_present) + n_ie--; + if(!msg->SRVCCOperationPossible_present) + n_ie--; + if(!msg->NASSecurityParameterstoE_UTRAN_present) + n_ie--; + if(!msg->CSG_Id_present) + n_ie--; + if(!msg->CSGMembershipStatus_present) + n_ie--; + if(!msg->GUMMEI_ID_present) + n_ie--; + if(!msg->MME_UE_S1AP_ID_2_present) + n_ie--; + if(!msg->ManagementBasedMDTAllowed_present) + n_ie--; + if(!msg->ManagementBasedMDTPLMNList_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - HandoverType + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_handovertype(&msg->HandoverType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_HANDOVERTYPE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Cause + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cause(&msg->Cause, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CAUSE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - uEaggregateMaximumBitrate + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueaggregatemaximumbitrate(&msg->uEaggregateMaximumBitrate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABToBeSetupListHOReq + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetuplisthoreq(&msg->E_RABToBeSetupListHOReq, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTHOREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - Source_ToTarget_TransparentContainer + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_source_totarget_transparentcontainer(&msg->Source_ToTarget_TransparentContainer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SOURCE_TOTARGET_TRANSPARENTCONTAINER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - UESecurityCapabilities + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_uesecuritycapabilities(&msg->UESecurityCapabilities, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - HandoverRestrictionList + if(msg->HandoverRestrictionList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_handoverrestrictionlist(&msg->HandoverRestrictionList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_HANDOVERRESTRICTIONLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - TraceActivation + if(msg->TraceActivation_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_traceactivation(&msg->TraceActivation, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TRACEACTIVATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - RequestType + if(msg->RequestType_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_requesttype(&msg->RequestType, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_REQUESTTYPE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SRVCCOperationPossible + if(msg->SRVCCOperationPossible_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_srvccoperationpossible(&msg->SRVCCOperationPossible, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SRVCCOPERATIONPOSSIBLE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SecurityContext + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_securitycontext(&msg->SecurityContext, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SECURITYCONTEXT, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - NASSecurityParameterstoE_UTRAN + if(msg->NASSecurityParameterstoE_UTRAN_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_nassecurityparameterstoe_utran(&msg->NASSecurityParameterstoE_UTRAN, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_NASSECURITYPARAMETERSTOE_UTRAN, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSG_Id + if(msg->CSG_Id_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csg_id(&msg->CSG_Id, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSG_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSGMembershipStatus + if(msg->CSGMembershipStatus_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csgmembershipstatus(&msg->CSGMembershipStatus, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - GUMMEI_ID + if(msg->GUMMEI_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_gummei(&msg->GUMMEI_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GUMMEI_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - MME_UE_S1AP_ID_2 + if(msg->MME_UE_S1AP_ID_2_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID_2, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID_2, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - ManagementBasedMDTAllowed + if(msg->ManagementBasedMDTAllowed_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_managementbasedmdtallowed(&msg->ManagementBasedMDTAllowed, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTALLOWED, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - ManagementBasedMDTPLMNList + if(msg->ManagementBasedMDTPLMNList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mdtplmnlist(&msg->ManagementBasedMDTPLMNList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTPLMNLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->HandoverRestrictionList_present = false; + msg->TraceActivation_present = false; + msg->RequestType_present = false; + msg->SRVCCOperationPossible_present = false; + msg->NASSecurityParameterstoE_UTRAN_present = false; + msg->CSG_Id_present = false; + msg->CSGMembershipStatus_present = false; + msg->GUMMEI_ID_present = false; + msg->MME_UE_S1AP_ID_2_present = false; + msg->ManagementBasedMDTAllowed_present = false; + msg->ManagementBasedMDTPLMNList_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_HANDOVERTYPE == ie_id) { + if(liblte_s1ap_unpack_handovertype(ptr, &msg->HandoverType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CAUSE == ie_id) { + if(liblte_s1ap_unpack_cause(ptr, &msg->Cause) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE == ie_id) { + if(liblte_s1ap_unpack_ueaggregatemaximumbitrate(ptr, &msg->uEaggregateMaximumBitrate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTHOREQ == ie_id) { + if(liblte_s1ap_unpack_e_rabtobesetuplisthoreq(ptr, &msg->E_RABToBeSetupListHOReq) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SOURCE_TOTARGET_TRANSPARENTCONTAINER == ie_id) { + if(liblte_s1ap_unpack_source_totarget_transparentcontainer(ptr, &msg->Source_ToTarget_TransparentContainer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES == ie_id) { + if(liblte_s1ap_unpack_uesecuritycapabilities(ptr, &msg->UESecurityCapabilities) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_HANDOVERRESTRICTIONLIST == ie_id) { + if(liblte_s1ap_unpack_handoverrestrictionlist(ptr, &msg->HandoverRestrictionList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->HandoverRestrictionList_present = true; + } else if(LIBLTE_S1AP_IE_ID_TRACEACTIVATION == ie_id) { + if(liblte_s1ap_unpack_traceactivation(ptr, &msg->TraceActivation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->TraceActivation_present = true; + } else if(LIBLTE_S1AP_IE_ID_REQUESTTYPE == ie_id) { + if(liblte_s1ap_unpack_requesttype(ptr, &msg->RequestType) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->RequestType_present = true; + } else if(LIBLTE_S1AP_IE_ID_SRVCCOPERATIONPOSSIBLE == ie_id) { + if(liblte_s1ap_unpack_srvccoperationpossible(ptr, &msg->SRVCCOperationPossible) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SRVCCOperationPossible_present = true; + } else if(LIBLTE_S1AP_IE_ID_SECURITYCONTEXT == ie_id) { + if(liblte_s1ap_unpack_securitycontext(ptr, &msg->SecurityContext) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_NASSECURITYPARAMETERSTOE_UTRAN == ie_id) { + if(liblte_s1ap_unpack_nassecurityparameterstoe_utran(ptr, &msg->NASSecurityParameterstoE_UTRAN) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CSG_ID == ie_id) { + if(liblte_s1ap_unpack_csg_id(ptr, &msg->CSG_Id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSG_Id_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS == ie_id) { + if(liblte_s1ap_unpack_csgmembershipstatus(ptr, &msg->CSGMembershipStatus) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSGMembershipStatus_present = true; + } else if(LIBLTE_S1AP_IE_ID_GUMMEI_ID == ie_id) { + if(liblte_s1ap_unpack_gummei(ptr, &msg->GUMMEI_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GUMMEI_ID_present = true; + } else if(LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID_2 == ie_id) { + if(liblte_s1ap_unpack_mme_ue_s1ap_id(ptr, &msg->MME_UE_S1AP_ID_2) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MME_UE_S1AP_ID_2_present = true; + } else if(LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTALLOWED == ie_id) { + if(liblte_s1ap_unpack_managementbasedmdtallowed(ptr, &msg->ManagementBasedMDTAllowed) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ManagementBasedMDTAllowed_present = true; + } else if(LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTPLMNLIST == ie_id) { + if(liblte_s1ap_unpack_mdtplmnlist(ptr, &msg->ManagementBasedMDTPLMNList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ManagementBasedMDTPLMNList_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message PathSwitchRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pathswitchrequest( + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("PathSwitchRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 12; + if(!msg->CSG_Id_present) + n_ie--; + if(!msg->CellAccessMode_present) + n_ie--; + if(!msg->SourceMME_GUMMEI_present) + n_ie--; + if(!msg->CSGMembershipStatus_present) + n_ie--; + if(!msg->Tunnel_Information_for_BBF_present) + n_ie--; + if(!msg->LHN_ID_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABToBeSwitchedDLList + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobeswitcheddllist(&msg->E_RABToBeSwitchedDLList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDDLLIST, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - SourceMME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->SourceMME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SOURCEMME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - EUTRAN_CGI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_eutran_cgi(&msg->EUTRAN_CGI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_EUTRAN_CGI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TAI + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tai(&msg->TAI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - UESecurityCapabilities + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_uesecuritycapabilities(&msg->UESecurityCapabilities, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CSG_Id + if(msg->CSG_Id_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csg_id(&msg->CSG_Id, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSG_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CellAccessMode + if(msg->CellAccessMode_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cellaccessmode(&msg->CellAccessMode, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CELLACCESSMODE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SourceMME_GUMMEI + if(msg->SourceMME_GUMMEI_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_gummei(&msg->SourceMME_GUMMEI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SOURCEMME_GUMMEI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSGMembershipStatus + if(msg->CSGMembershipStatus_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csgmembershipstatus(&msg->CSGMembershipStatus, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - Tunnel_Information_for_BBF + if(msg->Tunnel_Information_for_BBF_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tunnelinformation(&msg->Tunnel_Information_for_BBF, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TUNNEL_INFORMATION_FOR_BBF, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - LHN_ID + if(msg->LHN_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lhn_id(&msg->LHN_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_LHN_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pathswitchrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->CSG_Id_present = false; + msg->CellAccessMode_present = false; + msg->SourceMME_GUMMEI_present = false; + msg->CSGMembershipStatus_present = false; + msg->Tunnel_Information_for_BBF_present = false; + msg->LHN_ID_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("PathSwitchRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;ieNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDDLLIST == ie_id) { + if(liblte_s1ap_unpack_e_rabtobeswitcheddllist(ptr, &msg->E_RABToBeSwitchedDLList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SOURCEMME_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_mme_ue_s1ap_id(ptr, &msg->SourceMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_EUTRAN_CGI == ie_id) { + if(liblte_s1ap_unpack_eutran_cgi(ptr, &msg->EUTRAN_CGI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TAI == ie_id) { + if(liblte_s1ap_unpack_tai(ptr, &msg->TAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES == ie_id) { + if(liblte_s1ap_unpack_uesecuritycapabilities(ptr, &msg->UESecurityCapabilities) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CSG_ID == ie_id) { + if(liblte_s1ap_unpack_csg_id(ptr, &msg->CSG_Id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSG_Id_present = true; + } else if(LIBLTE_S1AP_IE_ID_CELLACCESSMODE == ie_id) { + if(liblte_s1ap_unpack_cellaccessmode(ptr, &msg->CellAccessMode) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CellAccessMode_present = true; + } else if(LIBLTE_S1AP_IE_ID_SOURCEMME_GUMMEI == ie_id) { + if(liblte_s1ap_unpack_gummei(ptr, &msg->SourceMME_GUMMEI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SourceMME_GUMMEI_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS == ie_id) { + if(liblte_s1ap_unpack_csgmembershipstatus(ptr, &msg->CSGMembershipStatus) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSGMembershipStatus_present = true; + } else if(LIBLTE_S1AP_IE_ID_TUNNEL_INFORMATION_FOR_BBF == ie_id) { + if(liblte_s1ap_unpack_tunnelinformation(ptr, &msg->Tunnel_Information_for_BBF) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->Tunnel_Information_for_BBF_present = true; + } else if(LIBLTE_S1AP_IE_ID_LHN_ID == ie_id) { + if(liblte_s1ap_unpack_lhn_id(ptr, &msg->LHN_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->LHN_ID_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message PathSwitchRequestAcknowledge STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_pathswitchrequestacknowledge( + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTACKNOWLEDGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("PathSwitchRequestAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 9; + if(!msg->uEaggregateMaximumBitrate_present) + n_ie--; + if(!msg->E_RABToBeSwitchedULList_present) + n_ie--; + if(!msg->E_RABToBeReleasedList_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + if(!msg->MME_UE_S1AP_ID_2_present) + n_ie--; + if(!msg->CSGMembershipStatus_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - uEaggregateMaximumBitrate + if(msg->uEaggregateMaximumBitrate_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueaggregatemaximumbitrate(&msg->uEaggregateMaximumBitrate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABToBeSwitchedULList + if(msg->E_RABToBeSwitchedULList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobeswitchedullist(&msg->E_RABToBeSwitchedULList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDULLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABToBeReleasedList + if(msg->E_RABToBeReleasedList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rablist(&msg->E_RABToBeReleasedList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBERELEASEDLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SecurityContext + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_securitycontext(&msg->SecurityContext, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SECURITYCONTEXT, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - MME_UE_S1AP_ID_2 + if(msg->MME_UE_S1AP_ID_2_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID_2, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID_2, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSGMembershipStatus + if(msg->CSGMembershipStatus_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csgmembershipstatus(&msg->CSGMembershipStatus, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_pathswitchrequestacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PATHSWITCHREQUESTACKNOWLEDGE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->uEaggregateMaximumBitrate_present = false; + msg->E_RABToBeSwitchedULList_present = false; + msg->E_RABToBeReleasedList_present = false; + msg->CriticalityDiagnostics_present = false; + msg->MME_UE_S1AP_ID_2_present = false; + msg->CSGMembershipStatus_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("PathSwitchRequestAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE == ie_id) { + if(liblte_s1ap_unpack_ueaggregatemaximumbitrate(ptr, &msg->uEaggregateMaximumBitrate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->uEaggregateMaximumBitrate_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABTOBESWITCHEDULLIST == ie_id) { + if(liblte_s1ap_unpack_e_rabtobeswitchedullist(ptr, &msg->E_RABToBeSwitchedULList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABToBeSwitchedULList_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABTOBERELEASEDLIST == ie_id) { + if(liblte_s1ap_unpack_e_rablist(ptr, &msg->E_RABToBeReleasedList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABToBeReleasedList_present = true; + } else if(LIBLTE_S1AP_IE_ID_SECURITYCONTEXT == ie_id) { + if(liblte_s1ap_unpack_securitycontext(ptr, &msg->SecurityContext) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } else if(LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID_2 == ie_id) { + if(liblte_s1ap_unpack_mme_ue_s1ap_id(ptr, &msg->MME_UE_S1AP_ID_2) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MME_UE_S1AP_ID_2_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS == ie_id) { + if(liblte_s1ap_unpack_csgmembershipstatus(ptr, &msg->CSGMembershipStatus) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSGMembershipStatus_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABSetupRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetuprequest( + LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->uEaggregateMaximumBitrate_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - uEaggregateMaximumBitrate + if(msg->uEaggregateMaximumBitrate_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueaggregatemaximumbitrate(&msg->uEaggregateMaximumBitrate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABToBeSetupListBearerSUReq + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetuplistbearersureq(&msg->E_RABToBeSetupListBearerSUReq, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTBEARERSUREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetuprequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->uEaggregateMaximumBitrate_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE == ie_id) { + if(liblte_s1ap_unpack_ueaggregatemaximumbitrate(ptr, &msg->uEaggregateMaximumBitrate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->uEaggregateMaximumBitrate_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTBEARERSUREQ == ie_id) { + if(liblte_s1ap_unpack_e_rabtobesetuplistbearersureq(ptr, &msg->E_RABToBeSetupListBearerSUReq) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABSetupResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabsetupresponse( + LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 5; + if(!msg->E_RABSetupListBearerSURes_present) + n_ie--; + if(!msg->E_RABFailedToSetupListBearerSURes_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABSetupListBearerSURes + if(msg->E_RABSetupListBearerSURes_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabsetuplistbearersures(&msg->E_RABSetupListBearerSURes, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABSETUPLISTBEARERSURES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABFailedToSetupListBearerSURes + if(msg->E_RABFailedToSetupListBearerSURes_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rablist(&msg->E_RABFailedToSetupListBearerSURes, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTBEARERSURES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabsetupresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABSETUPRESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->E_RABSetupListBearerSURes_present = false; + msg->E_RABFailedToSetupListBearerSURes_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABSetupResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABSETUPLISTBEARERSURES == ie_id) { + if(liblte_s1ap_unpack_e_rabsetuplistbearersures(ptr, &msg->E_RABSetupListBearerSURes) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABSetupListBearerSURes_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTBEARERSURES == ie_id) { + if(liblte_s1ap_unpack_e_rablist(ptr, &msg->E_RABFailedToSetupListBearerSURes) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABFailedToSetupListBearerSURes_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABModifyRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyrequest( + LIBLTE_S1AP_MESSAGE_E_RABMODIFYREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABModifyRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 4; + if(!msg->uEaggregateMaximumBitrate_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - uEaggregateMaximumBitrate + if(msg->uEaggregateMaximumBitrate_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueaggregatemaximumbitrate(&msg->uEaggregateMaximumBitrate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABToBeModifiedListBearerModReq + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobemodifiedlistbearermodreq(&msg->E_RABToBeModifiedListBearerModReq, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBEMODIFIEDLISTBEARERMODREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyrequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABMODIFYREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->uEaggregateMaximumBitrate_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABModifyRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE == ie_id) { + if(liblte_s1ap_unpack_ueaggregatemaximumbitrate(ptr, &msg->uEaggregateMaximumBitrate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->uEaggregateMaximumBitrate_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABTOBEMODIFIEDLISTBEARERMODREQ == ie_id) { + if(liblte_s1ap_unpack_e_rabtobemodifiedlistbearermodreq(ptr, &msg->E_RABToBeModifiedListBearerModReq) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABModifyResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabmodifyresponse( + LIBLTE_S1AP_MESSAGE_E_RABMODIFYRESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABModifyResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 5; + if(!msg->E_RABModifyListBearerModRes_present) + n_ie--; + if(!msg->E_RABFailedToModifyList_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABModifyListBearerModRes + if(msg->E_RABModifyListBearerModRes_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabmodifylistbearermodres(&msg->E_RABModifyListBearerModRes, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABMODIFYLISTBEARERMODRES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABFailedToModifyList + if(msg->E_RABFailedToModifyList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rablist(&msg->E_RABFailedToModifyList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOMODIFYLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabmodifyresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABMODIFYRESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->E_RABModifyListBearerModRes_present = false; + msg->E_RABFailedToModifyList_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABModifyResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABMODIFYLISTBEARERMODRES == ie_id) { + if(liblte_s1ap_unpack_e_rabmodifylistbearermodres(ptr, &msg->E_RABModifyListBearerModRes) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABModifyListBearerModRes_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABFAILEDTOMODIFYLIST == ie_id) { + if(liblte_s1ap_unpack_e_rablist(ptr, &msg->E_RABFailedToModifyList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABFailedToModifyList_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message E_RABReleaseResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_e_rabreleaseresponse( + LIBLTE_S1AP_MESSAGE_E_RABRELEASERESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 6; + if(!msg->E_RABReleaseListBearerRelComp_present) + n_ie--; + if(!msg->E_RABFailedToReleaseList_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + if(!msg->UserLocationInformation_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABReleaseListBearerRelComp + if(msg->E_RABReleaseListBearerRelComp_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabreleaselistbearerrelcomp(&msg->E_RABReleaseListBearerRelComp, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABRELEASELISTBEARERRELCOMP, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - E_RABFailedToReleaseList + if(msg->E_RABFailedToReleaseList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rablist(&msg->E_RABFailedToReleaseList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTORELEASELIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - UserLocationInformation + if(msg->UserLocationInformation_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_userlocationinformation(&msg->UserLocationInformation, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_USERLOCATIONINFORMATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_e_rabreleaseresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_E_RABRELEASERESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->E_RABReleaseListBearerRelComp_present = false; + msg->E_RABFailedToReleaseList_present = false; + msg->CriticalityDiagnostics_present = false; + msg->UserLocationInformation_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("E-RABReleaseResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABRELEASELISTBEARERRELCOMP == ie_id) { + if(liblte_s1ap_unpack_e_rabreleaselistbearerrelcomp(ptr, &msg->E_RABReleaseListBearerRelComp) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABReleaseListBearerRelComp_present = true; + } else if(LIBLTE_S1AP_IE_ID_E_RABFAILEDTORELEASELIST == ie_id) { + if(liblte_s1ap_unpack_e_rablist(ptr, &msg->E_RABFailedToReleaseList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABFailedToReleaseList_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } else if(LIBLTE_S1AP_IE_ID_USERLOCATIONINFORMATION == ie_id) { + if(liblte_s1ap_unpack_userlocationinformation(ptr, &msg->UserLocationInformation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->UserLocationInformation_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message InitialContextSetupRequest STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initialcontextsetuprequest( + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("InitialContextSetupRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 19; + if(!msg->TraceActivation_present) + n_ie--; + if(!msg->HandoverRestrictionList_present) + n_ie--; + if(!msg->UERadioCapability_present) + n_ie--; + if(!msg->SubscriberProfileIDforRFP_present) + n_ie--; + if(!msg->CSFallbackIndicator_present) + n_ie--; + if(!msg->SRVCCOperationPossible_present) + n_ie--; + if(!msg->CSGMembershipStatus_present) + n_ie--; + if(!msg->RegisteredLAI_present) + n_ie--; + if(!msg->GUMMEI_ID_present) + n_ie--; + if(!msg->MME_UE_S1AP_ID_2_present) + n_ie--; + if(!msg->ManagementBasedMDTAllowed_present) + n_ie--; + if(!msg->ManagementBasedMDTPLMNList_present) + n_ie--; + if(!msg->AdditionalCSFallbackIndicator_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - uEaggregateMaximumBitrate + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueaggregatemaximumbitrate(&msg->uEaggregateMaximumBitrate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABToBeSetupListCtxtSUReq + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabtobesetuplistctxtsureq(&msg->E_RABToBeSetupListCtxtSUReq, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTCTXTSUREQ, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - UESecurityCapabilities + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_uesecuritycapabilities(&msg->UESecurityCapabilities, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - SecurityKey + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_securitykey(&msg->SecurityKey, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SECURITYKEY, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TraceActivation + if(msg->TraceActivation_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_traceactivation(&msg->TraceActivation, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TRACEACTIVATION, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - HandoverRestrictionList + if(msg->HandoverRestrictionList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_handoverrestrictionlist(&msg->HandoverRestrictionList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_HANDOVERRESTRICTIONLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - UERadioCapability + if(msg->UERadioCapability_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueradiocapability(&msg->UERadioCapability, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UERADIOCAPABILITY, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SubscriberProfileIDforRFP + if(msg->SubscriberProfileIDforRFP_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_subscriberprofileidforrfp(&msg->SubscriberProfileIDforRFP, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SUBSCRIBERPROFILEIDFORRFP, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSFallbackIndicator + if(msg->CSFallbackIndicator_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csfallbackindicator(&msg->CSFallbackIndicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSFALLBACKINDICATOR, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - SRVCCOperationPossible + if(msg->SRVCCOperationPossible_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_srvccoperationpossible(&msg->SRVCCOperationPossible, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_SRVCCOPERATIONPOSSIBLE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CSGMembershipStatus + if(msg->CSGMembershipStatus_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csgmembershipstatus(&msg->CSGMembershipStatus, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - RegisteredLAI + if(msg->RegisteredLAI_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_lai(&msg->RegisteredLAI, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_REGISTEREDLAI, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - GUMMEI_ID + if(msg->GUMMEI_ID_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_gummei(&msg->GUMMEI_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_GUMMEI_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - MME_UE_S1AP_ID_2 + if(msg->MME_UE_S1AP_ID_2_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID_2, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID_2, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - ManagementBasedMDTAllowed + if(msg->ManagementBasedMDTAllowed_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_managementbasedmdtallowed(&msg->ManagementBasedMDTAllowed, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTALLOWED, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - ManagementBasedMDTPLMNList + if(msg->ManagementBasedMDTPLMNList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mdtplmnlist(&msg->ManagementBasedMDTPLMNList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTPLMNLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - AdditionalCSFallbackIndicator + if(msg->AdditionalCSFallbackIndicator_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_additionalcsfallbackindicator(&msg->AdditionalCSFallbackIndicator, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ADDITIONALCSFALLBACKINDICATOR, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initialcontextsetuprequest( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->TraceActivation_present = false; + msg->HandoverRestrictionList_present = false; + msg->UERadioCapability_present = false; + msg->SubscriberProfileIDforRFP_present = false; + msg->CSFallbackIndicator_present = false; + msg->SRVCCOperationPossible_present = false; + msg->CSGMembershipStatus_present = false; + msg->RegisteredLAI_present = false; + msg->GUMMEI_ID_present = false; + msg->MME_UE_S1AP_ID_2_present = false; + msg->ManagementBasedMDTAllowed_present = false; + msg->ManagementBasedMDTPLMNList_present = false; + msg->AdditionalCSFallbackIndicator_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("InitialContextSetupRequestIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UEAGGREGATEMAXIMUMBITRATE == ie_id) { + if(liblte_s1ap_unpack_ueaggregatemaximumbitrate(ptr, &msg->uEaggregateMaximumBitrate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABTOBESETUPLISTCTXTSUREQ == ie_id) { + if(liblte_s1ap_unpack_e_rabtobesetuplistctxtsureq(ptr, &msg->E_RABToBeSetupListCtxtSUReq) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UESECURITYCAPABILITIES == ie_id) { + if(liblte_s1ap_unpack_uesecuritycapabilities(ptr, &msg->UESecurityCapabilities) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_SECURITYKEY == ie_id) { + if(liblte_s1ap_unpack_securitykey(ptr, &msg->SecurityKey) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TRACEACTIVATION == ie_id) { + if(liblte_s1ap_unpack_traceactivation(ptr, &msg->TraceActivation) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->TraceActivation_present = true; + } else if(LIBLTE_S1AP_IE_ID_HANDOVERRESTRICTIONLIST == ie_id) { + if(liblte_s1ap_unpack_handoverrestrictionlist(ptr, &msg->HandoverRestrictionList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->HandoverRestrictionList_present = true; + } else if(LIBLTE_S1AP_IE_ID_UERADIOCAPABILITY == ie_id) { + if(liblte_s1ap_unpack_ueradiocapability(ptr, &msg->UERadioCapability) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->UERadioCapability_present = true; + } else if(LIBLTE_S1AP_IE_ID_SUBSCRIBERPROFILEIDFORRFP == ie_id) { + if(liblte_s1ap_unpack_subscriberprofileidforrfp(ptr, &msg->SubscriberProfileIDforRFP) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SubscriberProfileIDforRFP_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSFALLBACKINDICATOR == ie_id) { + if(liblte_s1ap_unpack_csfallbackindicator(ptr, &msg->CSFallbackIndicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSFallbackIndicator_present = true; + } else if(LIBLTE_S1AP_IE_ID_SRVCCOPERATIONPOSSIBLE == ie_id) { + if(liblte_s1ap_unpack_srvccoperationpossible(ptr, &msg->SRVCCOperationPossible) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->SRVCCOperationPossible_present = true; + } else if(LIBLTE_S1AP_IE_ID_CSGMEMBERSHIPSTATUS == ie_id) { + if(liblte_s1ap_unpack_csgmembershipstatus(ptr, &msg->CSGMembershipStatus) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSGMembershipStatus_present = true; + } else if(LIBLTE_S1AP_IE_ID_REGISTEREDLAI == ie_id) { + if(liblte_s1ap_unpack_lai(ptr, &msg->RegisteredLAI) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->RegisteredLAI_present = true; + } else if(LIBLTE_S1AP_IE_ID_GUMMEI_ID == ie_id) { + if(liblte_s1ap_unpack_gummei(ptr, &msg->GUMMEI_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->GUMMEI_ID_present = true; + } else if(LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID_2 == ie_id) { + if(liblte_s1ap_unpack_mme_ue_s1ap_id(ptr, &msg->MME_UE_S1AP_ID_2) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->MME_UE_S1AP_ID_2_present = true; + } else if(LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTALLOWED == ie_id) { + if(liblte_s1ap_unpack_managementbasedmdtallowed(ptr, &msg->ManagementBasedMDTAllowed) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ManagementBasedMDTAllowed_present = true; + } else if(LIBLTE_S1AP_IE_ID_MANAGEMENTBASEDMDTPLMNLIST == ie_id) { + if(liblte_s1ap_unpack_mdtplmnlist(ptr, &msg->ManagementBasedMDTPLMNList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->ManagementBasedMDTPLMNList_present = true; + } else if(LIBLTE_S1AP_IE_ID_ADDITIONALCSFALLBACKINDICATOR == ie_id) { + if(liblte_s1ap_unpack_additionalcsfallbackindicator(ptr, &msg->AdditionalCSFallbackIndicator) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message InitialContextSetupResponse STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initialcontextsetupresponse( + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("InitialContextSetupResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 5; + if(!msg->E_RABFailedToSetupListCtxtSURes_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABSetupListCtxtSURes + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabsetuplistctxtsures(&msg->E_RABSetupListCtxtSURes, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABSETUPLISTCTXTSURES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABFailedToSetupListCtxtSURes + if(msg->E_RABFailedToSetupListCtxtSURes_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rablist(&msg->E_RABFailedToSetupListCtxtSURes, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTCTXTSURES, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initialcontextsetupresponse( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPRESPONSE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->E_RABFailedToSetupListCtxtSURes_present = false; + msg->CriticalityDiagnostics_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("InitialContextSetupResponseIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABSETUPLISTCTXTSURES == ie_id) { + if(liblte_s1ap_unpack_e_rabsetuplistctxtsures(ptr, &msg->E_RABSetupListCtxtSURes) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTCTXTSURES == ie_id) { + if(liblte_s1ap_unpack_e_rablist(ptr, &msg->E_RABFailedToSetupListCtxtSURes) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABFailedToSetupListCtxtSURes_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message Paging STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_paging( + LIBLTE_S1AP_MESSAGE_PAGING_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("PagingIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 7; + if(!msg->pagingDRX_present) + n_ie--; + if(!msg->CSG_IdList_present) + n_ie--; + if(!msg->PagingPriority_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - UEIdentityIndexValue + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_ueidentityindexvalue(&msg->UEIdentityIndexValue, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEIDENTITYINDEXVALUE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - UEPagingID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_uepagingid(&msg->UEPagingID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_UEPAGINGID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - pagingDRX + if(msg->pagingDRX_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_pagingdrx(&msg->pagingDRX, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_PAGINGDRX, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CNDomain + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cndomain(&msg->CNDomain, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CNDOMAIN, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - TAIList + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_tailist(&msg->TAIList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TAILIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CSG_IdList + if(msg->CSG_IdList_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csg_idlist(&msg->CSG_IdList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSG_IDLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - PagingPriority + if(msg->PagingPriority_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_pagingpriority(&msg->PagingPriority, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_PAGINGPRIORITY, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_paging( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_PAGING_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->pagingDRX_present = false; + msg->CSG_IdList_present = false; + msg->PagingPriority_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("PagingIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iUEIdentityIndexValue) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_UEPAGINGID == ie_id) { + if(liblte_s1ap_unpack_uepagingid(ptr, &msg->UEPagingID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_PAGINGDRX == ie_id) { + if(liblte_s1ap_unpack_pagingdrx(ptr, &msg->pagingDRX) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->pagingDRX_present = true; + } else if(LIBLTE_S1AP_IE_ID_CNDOMAIN == ie_id) { + if(liblte_s1ap_unpack_cndomain(ptr, &msg->CNDomain) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_TAILIST == ie_id) { + if(liblte_s1ap_unpack_tailist(ptr, &msg->TAIList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CSG_IDLIST == ie_id) { + if(liblte_s1ap_unpack_csg_idlist(ptr, &msg->CSG_IdList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSG_IdList_present = true; + } else if(LIBLTE_S1AP_IE_ID_PAGINGPRIORITY == ie_id) { + if(liblte_s1ap_unpack_pagingpriority(ptr, &msg->PagingPriority) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->PagingPriority_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* Protocol Message HandoverRequestAcknowledge STRUCT +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_handoverrequestacknowledge( + LIBLTE_S1AP_MESSAGE_HANDOVERREQUESTACKNOWLEDGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + + // Extension + liblte_value_2_bits(msg->ext?1:0, ptr, 1); + liblte_align_up_zero(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverRequestAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_ENCODE_FAIL; + } + + // No. of ProtocolIE + uint32_t n_ie = 8; + if(!msg->E_RABFailedToSetupListHOReqAck_present) + n_ie--; + if(!msg->CSG_Id_present) + n_ie--; + if(!msg->CriticalityDiagnostics_present) + n_ie--; + if(!msg->CellAccessMode_present) + n_ie--; + liblte_value_2_bits(n_ie, ptr, 16); + + // Temp container for IEs + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr; + + // ProtocolIE - MME_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_mme_ue_s1ap_id(&msg->MME_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_MME_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - eNB_UE_S1AP_ID + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_enb_ue_s1ap_id(&msg->eNB_UE_S1AP_ID, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABAdmittedList + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabadmittedlist(&msg->E_RABAdmittedList, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABADMITTEDLIST, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - E_RABFailedToSetupListHOReqAck + if(msg->E_RABFailedToSetupListHOReqAck_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_e_rabfailedtosetuplisthoreqack(&msg->E_RABFailedToSetupListHOReqAck, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTHOREQACK, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - Target_ToSource_TransparentContainer + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_target_tosource_transparentcontainer(&msg->Target_ToSource_TransparentContainer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_TARGET_TOSOURCE_TRANSPARENTCONTAINER, + LIBLTE_S1AP_CRITICALITY_REJECT, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + // ProtocolIE - CSG_Id + if(msg->CSG_Id_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_csg_id(&msg->CSG_Id, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CSG_ID, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CriticalityDiagnostics + if(msg->CriticalityDiagnostics_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_criticalitydiagnostics(&msg->CriticalityDiagnostics, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + // ProtocolIE - CellAccessMode + if(msg->CellAccessMode_present) { + tmp_msg.reset(); + tmp_ptr = tmp_msg.msg; + if(liblte_s1ap_pack_cellaccessmode(&msg->CellAccessMode, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + liblte_align_up_zero(&tmp_ptr, 8); + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + if(liblte_s1ap_pack_protocolie_header(tmp_msg.N_bits / 8, + LIBLTE_S1AP_IE_ID_CELLACCESSMODE, + LIBLTE_S1AP_CRITICALITY_IGNORE, + ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_handoverrequestacknowledge( + uint8_t **ptr, + LIBLTE_S1AP_MESSAGE_HANDOVERREQUESTACKNOWLEDGE_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_S1AP_CRITICALITY_ENUM crit; + uint32_t ie_id; + uint32_t len; + uint32_t n_ie; + uint32_t i; + + // Set booleans + msg->E_RABFailedToSetupListHOReqAck_present = false; + msg->CSG_Id_present = false; + msg->CriticalityDiagnostics_present = false; + msg->CellAccessMode_present = false; + + // Extension + msg->ext = liblte_bits_2_value(ptr, 1); + liblte_align_up(ptr, 8); + if(msg->ext) { + liblte_log_print("HandoverRequestAcknowledgeIEs error: S1AP ASN extensions not currently supported\n"); + return LIBLTE_ERROR_DECODE_FAIL; + } + + // No. of ProtocolIE-Container + n_ie = liblte_bits_2_value(ptr, 16); + + // Unpack ProtocolIE Fields + for(i=0;iMME_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_ENB_UE_S1AP_ID == ie_id) { + if(liblte_s1ap_unpack_enb_ue_s1ap_id(ptr, &msg->eNB_UE_S1AP_ID) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABADMITTEDLIST == ie_id) { + if(liblte_s1ap_unpack_e_rabadmittedlist(ptr, &msg->E_RABAdmittedList) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_E_RABFAILEDTOSETUPLISTHOREQACK == ie_id) { + if(liblte_s1ap_unpack_e_rabfailedtosetuplisthoreqack(ptr, &msg->E_RABFailedToSetupListHOReqAck) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->E_RABFailedToSetupListHOReqAck_present = true; + } else if(LIBLTE_S1AP_IE_ID_TARGET_TOSOURCE_TRANSPARENTCONTAINER == ie_id) { + if(liblte_s1ap_unpack_target_tosource_transparentcontainer(ptr, &msg->Target_ToSource_TransparentContainer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + } else if(LIBLTE_S1AP_IE_ID_CSG_ID == ie_id) { + if(liblte_s1ap_unpack_csg_id(ptr, &msg->CSG_Id) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CSG_Id_present = true; + } else if(LIBLTE_S1AP_IE_ID_CRITICALITYDIAGNOSTICS == ie_id) { + if(liblte_s1ap_unpack_criticalitydiagnostics(ptr, &msg->CriticalityDiagnostics) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CriticalityDiagnostics_present = true; + } else if(LIBLTE_S1AP_IE_ID_CELLACCESSMODE == ie_id) { + if(liblte_s1ap_unpack_cellaccessmode(ptr, &msg->CellAccessMode) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + liblte_align_up(ptr, 8); + msg->CellAccessMode_present = true; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* ProtocolIE-Field +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_protocolie_header( + uint32_t len, + uint32_t ie_id, + LIBLTE_S1AP_CRITICALITY_ENUM crit, + uint8_t **ptr) +{ + liblte_value_2_bits(ie_id, ptr, 16); // ProtocolIE-ID + liblte_value_2_bits(crit, ptr, 2); // Criticality + liblte_align_up_zero(ptr, 8); + if(len < 128) { // Length + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(len, ptr, 7); + } else if(len < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(len, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + return LIBLTE_SUCCESS; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_protocolie_header( + uint8_t **ptr, + uint32_t *ie_id, + LIBLTE_S1AP_CRITICALITY_ENUM *crit, + uint32_t *len) +{ + *ie_id = liblte_bits_2_value(ptr, 16); // ProtocolIE-ID + *crit = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); // Criticality + liblte_align_up(ptr, 8); + if(0 == liblte_bits_2_value(ptr, 1)) { // Length + *len = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + *len = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + return LIBLTE_SUCCESS; +} + +/******************************************************************************* +/* InitiatingMessage CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_initiatingmessage( + LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr = tmp_msg.msg; + + // Message + if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORTINGCONTROL) { + if(liblte_s1ap_pack_locationreportingcontrol(&msg->choice.LocationReportingControl, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKS1CDMA2000TUNNELING) { + if(liblte_s1ap_pack_downlinks1cdma2000tunneling(&msg->choice.DownlinkS1cdma2000tunneling, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_S1SETUPREQUEST) { + if(liblte_s1ap_pack_s1setuprequest(&msg->choice.S1SetupRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECAPABILITYINFOINDICATION) { + if(liblte_s1ap_pack_uecapabilityinfoindication(&msg->choice.UECapabilityInfoIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORT) { + if(liblte_s1ap_pack_locationreport(&msg->choice.LocationReport, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKNONUEASSOCIATEDLPPATRANSPORT) { + if(liblte_s1ap_pack_uplinknonueassociatedlppatransport(&msg->choice.UplinkNonUEAssociatedLPPaTransport, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKS1CDMA2000TUNNELING) { + if(liblte_s1ap_pack_uplinks1cdma2000tunneling(&msg->choice.UplinkS1cdma2000tunneling, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMECONFIGURATIONTRANSFER) { + if(liblte_s1ap_pack_mmeconfigurationtransfer(&msg->choice.MMEConfigurationTransfer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_TRACESTART) { + if(liblte_s1ap_pack_tracestart(&msg->choice.TraceStart, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERCANCEL) { + if(liblte_s1ap_pack_handovercancel(&msg->choice.HandoverCancel, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UERADIOCAPABILITYMATCHREQUEST) { + if(liblte_s1ap_pack_ueradiocapabilitymatchrequest(&msg->choice.UERadioCapabilityMatchRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKNASTRANSPORT) { + if(liblte_s1ap_pack_downlinknastransport(&msg->choice.DownlinkNASTransport, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALCONTEXTSETUPREQUEST) { + if(liblte_s1ap_pack_initialcontextsetuprequest(&msg->choice.InitialContextSetupRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERREQUIRED) { + if(liblte_s1ap_pack_handoverrequired(&msg->choice.HandoverRequired, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMEDIRECTINFORMATIONTRANSFER) { + if(liblte_s1ap_pack_mmedirectinformationtransfer(&msg->choice.MMEDirectInformationTransfer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_TRACEFAILUREINDICATION) { + if(liblte_s1ap_pack_tracefailureindication(&msg->choice.TraceFailureIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMECONFIGURATIONUPDATE) { + if(liblte_s1ap_pack_mmeconfigurationupdate(&msg->choice.MMEConfigurationUpdate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_WRITEREPLACEWARNINGREQUEST) { + if(liblte_s1ap_pack_writereplacewarningrequest(&msg->choice.WriteReplaceWarningRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBDIRECTINFORMATIONTRANSFER) { + if(liblte_s1ap_pack_enbdirectinformationtransfer(&msg->choice.ENBDirectInformationTransfer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKUEASSOCIATEDLPPATRANSPORT) { + if(liblte_s1ap_pack_downlinkueassociatedlppatransport(&msg->choice.DownlinkUEAssociatedLPPaTransport, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABRELEASECOMMAND) { + if(liblte_s1ap_pack_e_rabreleasecommand(&msg->choice.E_RABReleaseCommand, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_NASNONDELIVERYINDICATION) { + if(liblte_s1ap_pack_nasnondeliveryindication(&msg->choice.NASNonDeliveryIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBCONFIGURATIONUPDATE) { + if(liblte_s1ap_pack_enbconfigurationupdate(&msg->choice.ENBConfigurationUpdate, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKUEASSOCIATEDLPPATRANSPORT) { + if(liblte_s1ap_pack_uplinkueassociatedlppatransport(&msg->choice.UplinkUEAssociatedLPPaTransport, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALUEMESSAGE) { + if(liblte_s1ap_pack_initialuemessage(&msg->choice.InitialUEMessage, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABMODIFYREQUEST) { + if(liblte_s1ap_pack_e_rabmodifyrequest(&msg->choice.E_RABModifyRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTMODIFICATIONREQUEST) { + if(liblte_s1ap_pack_uecontextmodificationrequest(&msg->choice.UEContextModificationRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABSETUPREQUEST) { + if(liblte_s1ap_pack_e_rabsetuprequest(&msg->choice.E_RABSetupRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_RESET) { + if(liblte_s1ap_pack_reset(&msg->choice.Reset, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_OVERLOADSTART) { + if(liblte_s1ap_pack_overloadstart(&msg->choice.OverloadStart, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABRELEASEINDICATION) { + if(liblte_s1ap_pack_e_rabreleaseindication(&msg->choice.E_RABReleaseIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORTINGFAILUREINDICATION) { + if(liblte_s1ap_pack_locationreportingfailureindication(&msg->choice.LocationReportingFailureIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DEACTIVATETRACE) { + if(liblte_s1ap_pack_deactivatetrace(&msg->choice.DeactivateTrace, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PATHSWITCHREQUEST) { + if(liblte_s1ap_pack_pathswitchrequest(&msg->choice.PathSwitchRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERREQUEST) { + if(liblte_s1ap_pack_handoverrequest(&msg->choice.HandoverRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT) { + if(liblte_s1ap_pack_downlinknonueassociatedlppatransport(&msg->choice.DownlinkNonUEAssociatedLPPaTransport, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_OVERLOADSTOP) { + if(liblte_s1ap_pack_overloadstop(&msg->choice.OverloadStop, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PAGING) { + if(liblte_s1ap_pack_paging(&msg->choice.Paging, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERNOTIFY) { + if(liblte_s1ap_pack_handovernotify(&msg->choice.HandoverNotify, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PWSRESTARTINDICATION) { + if(liblte_s1ap_pack_pwsrestartindication(&msg->choice.PWSRestartIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASEREQUEST) { + if(liblte_s1ap_pack_uecontextreleaserequest(&msg->choice.UEContextReleaseRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKNASTRANSPORT) { + if(liblte_s1ap_pack_uplinknastransport(&msg->choice.UplinkNASTransport, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBCONFIGURATIONTRANSFER) { + if(liblte_s1ap_pack_enbconfigurationtransfer(&msg->choice.ENBConfigurationTransfer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMESTATUSTRANSFER) { + if(liblte_s1ap_pack_mmestatustransfer(&msg->choice.MMEStatusTransfer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_CELLTRAFFICTRACE) { + if(liblte_s1ap_pack_celltraffictrace(&msg->choice.CellTrafficTrace, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASECOMMAND) { + if(liblte_s1ap_pack_uecontextreleasecommand(&msg->choice.UEContextReleaseCommand, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_KILLREQUEST) { + if(liblte_s1ap_pack_killrequest(&msg->choice.KillRequest, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PRIVATEMESSAGE) { + if(liblte_s1ap_pack_privatemessage(&msg->choice.PrivateMessage, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBSTATUSTRANSFER) { + if(liblte_s1ap_pack_enbstatustransfer(&msg->choice.ENBStatusTransfer, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ERRORINDICATION) { + if(liblte_s1ap_pack_errorindication(&msg->choice.ErrorIndication, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + + // Procedure code + liblte_value_2_bits(msg->procedureCode, ptr, 8); + + // Criticality + LIBLTE_S1AP_CRITICALITY_ENUM crit = liblte_s1ap_procedure_criticality[msg->procedureCode]; + liblte_value_2_bits(crit, ptr, 2); + liblte_align_up_zero(ptr, 8); + + // Length + uint32_t len = (tmp_msg.N_bits + 7) / 8; + if(len < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(len, ptr, 7); + } else if(len < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(len, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_initiatingmessage( + uint8_t **ptr, + LIBLTE_S1AP_INITIATINGMESSAGE_STRUCT *msg) +{ LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + // Procedure code + msg->procedureCode = liblte_bits_2_value(ptr, 8); + + // Criticality + msg->criticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + + // Length + uint32_t len = 0; + if(0 == liblte_bits_2_value(ptr, 1)) { + len = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + len = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Message + if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_LOCATIONREPORTINGCONTROL) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORTINGCONTROL; + if(liblte_s1ap_unpack_locationreportingcontrol(ptr, &msg->choice.LocationReportingControl) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_DOWNLINKS1CDMA2000TUNNELING) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKS1CDMA2000TUNNELING; + if(liblte_s1ap_unpack_downlinks1cdma2000tunneling(ptr, &msg->choice.DownlinkS1cdma2000tunneling) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_S1SETUP) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_S1SETUPREQUEST; + if(liblte_s1ap_unpack_s1setuprequest(ptr, &msg->choice.S1SetupRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UECAPABILITYINFOINDICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECAPABILITYINFOINDICATION; + if(liblte_s1ap_unpack_uecapabilityinfoindication(ptr, &msg->choice.UECapabilityInfoIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_LOCATIONREPORT) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORT; + if(liblte_s1ap_unpack_locationreport(ptr, &msg->choice.LocationReport) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UPLINKNONUEASSOCIATEDLPPATRANSPORT) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKNONUEASSOCIATEDLPPATRANSPORT; + if(liblte_s1ap_unpack_uplinknonueassociatedlppatransport(ptr, &msg->choice.UplinkNonUEAssociatedLPPaTransport) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UPLINKS1CDMA2000TUNNELING) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKS1CDMA2000TUNNELING; + if(liblte_s1ap_unpack_uplinks1cdma2000tunneling(ptr, &msg->choice.UplinkS1cdma2000tunneling) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_MMECONFIGURATIONTRANSFER) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMECONFIGURATIONTRANSFER; + if(liblte_s1ap_unpack_mmeconfigurationtransfer(ptr, &msg->choice.MMEConfigurationTransfer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_TRACESTART) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_TRACESTART; + if(liblte_s1ap_unpack_tracestart(ptr, &msg->choice.TraceStart) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERCANCEL) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERCANCEL; + if(liblte_s1ap_unpack_handovercancel(ptr, &msg->choice.HandoverCancel) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UERADIOCAPABILITYMATCH) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UERADIOCAPABILITYMATCHREQUEST; + if(liblte_s1ap_unpack_ueradiocapabilitymatchrequest(ptr, &msg->choice.UERadioCapabilityMatchRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_DOWNLINKNASTRANSPORT) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKNASTRANSPORT; + if(liblte_s1ap_unpack_downlinknastransport(ptr, &msg->choice.DownlinkNASTransport) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_INITIALCONTEXTSETUP) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALCONTEXTSETUPREQUEST; + if(liblte_s1ap_unpack_initialcontextsetuprequest(ptr, &msg->choice.InitialContextSetupRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERPREPARATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERREQUIRED; + if(liblte_s1ap_unpack_handoverrequired(ptr, &msg->choice.HandoverRequired) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_MMEDIRECTINFORMATIONTRANSFER) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMEDIRECTINFORMATIONTRANSFER; + if(liblte_s1ap_unpack_mmedirectinformationtransfer(ptr, &msg->choice.MMEDirectInformationTransfer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_TRACEFAILUREINDICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_TRACEFAILUREINDICATION; + if(liblte_s1ap_unpack_tracefailureindication(ptr, &msg->choice.TraceFailureIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_MMECONFIGURATIONUPDATE) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMECONFIGURATIONUPDATE; + if(liblte_s1ap_unpack_mmeconfigurationupdate(ptr, &msg->choice.MMEConfigurationUpdate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_WRITEREPLACEWARNING) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_WRITEREPLACEWARNINGREQUEST; + if(liblte_s1ap_unpack_writereplacewarningrequest(ptr, &msg->choice.WriteReplaceWarningRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_ENBDIRECTINFORMATIONTRANSFER) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBDIRECTINFORMATIONTRANSFER; + if(liblte_s1ap_unpack_enbdirectinformationtransfer(ptr, &msg->choice.ENBDirectInformationTransfer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_DOWNLINKUEASSOCIATEDLPPATRANSPORT) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKUEASSOCIATEDLPPATRANSPORT; + if(liblte_s1ap_unpack_downlinkueassociatedlppatransport(ptr, &msg->choice.DownlinkUEAssociatedLPPaTransport) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_E_RABRELEASE) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABRELEASECOMMAND; + if(liblte_s1ap_unpack_e_rabreleasecommand(ptr, &msg->choice.E_RABReleaseCommand) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_NASNONDELIVERYINDICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_NASNONDELIVERYINDICATION; + if(liblte_s1ap_unpack_nasnondeliveryindication(ptr, &msg->choice.NASNonDeliveryIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_ENBCONFIGURATIONUPDATE) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBCONFIGURATIONUPDATE; + if(liblte_s1ap_unpack_enbconfigurationupdate(ptr, &msg->choice.ENBConfigurationUpdate) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UPLINKUEASSOCIATEDLPPATRANSPORT) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKUEASSOCIATEDLPPATRANSPORT; + if(liblte_s1ap_unpack_uplinkueassociatedlppatransport(ptr, &msg->choice.UplinkUEAssociatedLPPaTransport) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_INITIALUEMESSAGE) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_INITIALUEMESSAGE; + if(liblte_s1ap_unpack_initialuemessage(ptr, &msg->choice.InitialUEMessage) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_E_RABMODIFY) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABMODIFYREQUEST; + if(liblte_s1ap_unpack_e_rabmodifyrequest(ptr, &msg->choice.E_RABModifyRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UECONTEXTMODIFICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTMODIFICATIONREQUEST; + if(liblte_s1ap_unpack_uecontextmodificationrequest(ptr, &msg->choice.UEContextModificationRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_E_RABSETUP) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABSETUPREQUEST; + if(liblte_s1ap_unpack_e_rabsetuprequest(ptr, &msg->choice.E_RABSetupRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_RESET) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_RESET; + if(liblte_s1ap_unpack_reset(ptr, &msg->choice.Reset) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_OVERLOADSTART) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_OVERLOADSTART; + if(liblte_s1ap_unpack_overloadstart(ptr, &msg->choice.OverloadStart) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_E_RABRELEASEINDICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_E_RABRELEASEINDICATION; + if(liblte_s1ap_unpack_e_rabreleaseindication(ptr, &msg->choice.E_RABReleaseIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_LOCATIONREPORTINGFAILUREINDICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_LOCATIONREPORTINGFAILUREINDICATION; + if(liblte_s1ap_unpack_locationreportingfailureindication(ptr, &msg->choice.LocationReportingFailureIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_DEACTIVATETRACE) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DEACTIVATETRACE; + if(liblte_s1ap_unpack_deactivatetrace(ptr, &msg->choice.DeactivateTrace) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_PATHSWITCHREQUEST) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PATHSWITCHREQUEST; + if(liblte_s1ap_unpack_pathswitchrequest(ptr, &msg->choice.PathSwitchRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERRESOURCEALLOCATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERREQUEST; + if(liblte_s1ap_unpack_handoverrequest(ptr, &msg->choice.HandoverRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_DOWNLINKNONUEASSOCIATEDLPPATRANSPORT; + if(liblte_s1ap_unpack_downlinknonueassociatedlppatransport(ptr, &msg->choice.DownlinkNonUEAssociatedLPPaTransport) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_OVERLOADSTOP) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_OVERLOADSTOP; + if(liblte_s1ap_unpack_overloadstop(ptr, &msg->choice.OverloadStop) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_PAGING) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PAGING; + if(liblte_s1ap_unpack_paging(ptr, &msg->choice.Paging) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERNOTIFICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERNOTIFY; + if(liblte_s1ap_unpack_handovernotify(ptr, &msg->choice.HandoverNotify) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_PWSRESTARTINDICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PWSRESTARTINDICATION; + if(liblte_s1ap_unpack_pwsrestartindication(ptr, &msg->choice.PWSRestartIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASEREQUEST) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASEREQUEST; + if(liblte_s1ap_unpack_uecontextreleaserequest(ptr, &msg->choice.UEContextReleaseRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UPLINKNASTRANSPORT) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UPLINKNASTRANSPORT; + if(liblte_s1ap_unpack_uplinknastransport(ptr, &msg->choice.UplinkNASTransport) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_ENBCONFIGURATIONTRANSFER) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBCONFIGURATIONTRANSFER; + if(liblte_s1ap_unpack_enbconfigurationtransfer(ptr, &msg->choice.ENBConfigurationTransfer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_MMESTATUSTRANSFER) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_MMESTATUSTRANSFER; + if(liblte_s1ap_unpack_mmestatustransfer(ptr, &msg->choice.MMEStatusTransfer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_CELLTRAFFICTRACE) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_CELLTRAFFICTRACE; + if(liblte_s1ap_unpack_celltraffictrace(ptr, &msg->choice.CellTrafficTrace) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASE) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_UECONTEXTRELEASECOMMAND; + if(liblte_s1ap_unpack_uecontextreleasecommand(ptr, &msg->choice.UEContextReleaseCommand) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_KILL) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_KILLREQUEST; + if(liblte_s1ap_unpack_killrequest(ptr, &msg->choice.KillRequest) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_PRIVATEMESSAGE) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_PRIVATEMESSAGE; + if(liblte_s1ap_unpack_privatemessage(ptr, &msg->choice.PrivateMessage) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_ENBSTATUSTRANSFER) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ENBSTATUSTRANSFER; + if(liblte_s1ap_unpack_enbstatustransfer(ptr, &msg->choice.ENBStatusTransfer) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_ERRORINDICATION) { + msg->choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_ERRORINDICATION; + if(liblte_s1ap_unpack_errorindication(ptr, &msg->choice.ErrorIndication) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* UnsuccessfulOutcome CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_unsuccessfuloutcome( + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr = tmp_msg.msg; + + // Message + if(msg->choice_type == LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_S1SETUPFAILURE) { + if(liblte_s1ap_pack_s1setupfailure(&msg->choice.S1SetupFailure, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_PATHSWITCHREQUESTFAILURE) { + if(liblte_s1ap_pack_pathswitchrequestfailure(&msg->choice.PathSwitchRequestFailure, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_UECONTEXTMODIFICATIONFAILURE) { + if(liblte_s1ap_pack_uecontextmodificationfailure(&msg->choice.UEContextModificationFailure, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_INITIALCONTEXTSETUPFAILURE) { + if(liblte_s1ap_pack_initialcontextsetupfailure(&msg->choice.InitialContextSetupFailure, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_ENBCONFIGURATIONUPDATEFAILURE) { + if(liblte_s1ap_pack_enbconfigurationupdatefailure(&msg->choice.ENBConfigurationUpdateFailure, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_HANDOVERPREPARATIONFAILURE) { + if(liblte_s1ap_pack_handoverpreparationfailure(&msg->choice.HandoverPreparationFailure, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_HANDOVERFAILURE) { + if(liblte_s1ap_pack_handoverfailure(&msg->choice.HandoverFailure, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_MMECONFIGURATIONUPDATEFAILURE) { + if(liblte_s1ap_pack_mmeconfigurationupdatefailure(&msg->choice.MMEConfigurationUpdateFailure, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + + // Procedure code + liblte_value_2_bits(msg->procedureCode, ptr, 8); + + // Criticality + LIBLTE_S1AP_CRITICALITY_ENUM crit = liblte_s1ap_procedure_criticality[msg->procedureCode]; + liblte_value_2_bits(crit, ptr, 2); + liblte_align_up_zero(ptr, 8); + + // Length + uint32_t len = (tmp_msg.N_bits + 7) / 8; + if(len < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(len, ptr, 7); + } else if(len < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(len, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_unsuccessfuloutcome( + uint8_t **ptr, + LIBLTE_S1AP_UNSUCCESSFULOUTCOME_STRUCT *msg) +{ LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + // Procedure code + msg->procedureCode = liblte_bits_2_value(ptr, 8); + + // Criticality + msg->criticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + + // Length + uint32_t len = 0; + if(0 == liblte_bits_2_value(ptr, 1)) { + len = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + len = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Message + if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_S1SETUP) { + msg->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_S1SETUPFAILURE; + if(liblte_s1ap_unpack_s1setupfailure(ptr, &msg->choice.S1SetupFailure) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_PATHSWITCHREQUEST) { + msg->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_PATHSWITCHREQUESTFAILURE; + if(liblte_s1ap_unpack_pathswitchrequestfailure(ptr, &msg->choice.PathSwitchRequestFailure) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UECONTEXTMODIFICATION) { + msg->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_UECONTEXTMODIFICATIONFAILURE; + if(liblte_s1ap_unpack_uecontextmodificationfailure(ptr, &msg->choice.UEContextModificationFailure) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_INITIALCONTEXTSETUP) { + msg->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_INITIALCONTEXTSETUPFAILURE; + if(liblte_s1ap_unpack_initialcontextsetupfailure(ptr, &msg->choice.InitialContextSetupFailure) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_ENBCONFIGURATIONUPDATE) { + msg->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_ENBCONFIGURATIONUPDATEFAILURE; + if(liblte_s1ap_unpack_enbconfigurationupdatefailure(ptr, &msg->choice.ENBConfigurationUpdateFailure) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERPREPARATION) { + msg->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_HANDOVERPREPARATIONFAILURE; + if(liblte_s1ap_unpack_handoverpreparationfailure(ptr, &msg->choice.HandoverPreparationFailure) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERRESOURCEALLOCATION) { + msg->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_HANDOVERFAILURE; + if(liblte_s1ap_unpack_handoverfailure(ptr, &msg->choice.HandoverFailure) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_MMECONFIGURATIONUPDATE) { + msg->choice_type = LIBLTE_S1AP_UNSUCCESSFULOUTCOME_CHOICE_MMECONFIGURATIONUPDATEFAILURE; + if(liblte_s1ap_unpack_mmeconfigurationupdatefailure(ptr, &msg->choice.MMEConfigurationUpdateFailure) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + +/******************************************************************************* +/* SuccessfulOutcome CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_successfuloutcome( + LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg, + uint8_t **ptr) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + LIBLTE_BIT_MSG_STRUCT tmp_msg; + uint8_t *tmp_ptr = tmp_msg.msg; + + // Message + if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERREQUESTACKNOWLEDGE) { + if(liblte_s1ap_pack_handoverrequestacknowledge(&msg->choice.HandoverRequestAcknowledge, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UECONTEXTRELEASECOMPLETE) { + if(liblte_s1ap_pack_uecontextreleasecomplete(&msg->choice.UEContextReleaseComplete, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UERADIOCAPABILITYMATCHRESPONSE) { + if(liblte_s1ap_pack_ueradiocapabilitymatchresponse(&msg->choice.UERadioCapabilityMatchResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_INITIALCONTEXTSETUPRESPONSE) { + if(liblte_s1ap_pack_initialcontextsetupresponse(&msg->choice.InitialContextSetupResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABSETUPRESPONSE) { + if(liblte_s1ap_pack_e_rabsetupresponse(&msg->choice.E_RABSetupResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_PATHSWITCHREQUESTACKNOWLEDGE) { + if(liblte_s1ap_pack_pathswitchrequestacknowledge(&msg->choice.PathSwitchRequestAcknowledge, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_MMECONFIGURATIONUPDATEACKNOWLEDGE) { + if(liblte_s1ap_pack_mmeconfigurationupdateacknowledge(&msg->choice.MMEConfigurationUpdateAcknowledge, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_RESETACKNOWLEDGE) { + if(liblte_s1ap_pack_resetacknowledge(&msg->choice.ResetAcknowledge, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_ENBCONFIGURATIONUPDATEACKNOWLEDGE) { + if(liblte_s1ap_pack_enbconfigurationupdateacknowledge(&msg->choice.ENBConfigurationUpdateAcknowledge, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABMODIFYRESPONSE) { + if(liblte_s1ap_pack_e_rabmodifyresponse(&msg->choice.E_RABModifyResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_WRITEREPLACEWARNINGRESPONSE) { + if(liblte_s1ap_pack_writereplacewarningresponse(&msg->choice.WriteReplaceWarningResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_S1SETUPRESPONSE) { + if(liblte_s1ap_pack_s1setupresponse(&msg->choice.S1SetupResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_KILLRESPONSE) { + if(liblte_s1ap_pack_killresponse(&msg->choice.KillResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UECONTEXTMODIFICATIONRESPONSE) { + if(liblte_s1ap_pack_uecontextmodificationresponse(&msg->choice.UEContextModificationResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERCOMMAND) { + if(liblte_s1ap_pack_handovercommand(&msg->choice.HandoverCommand, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERCANCELACKNOWLEDGE) { + if(liblte_s1ap_pack_handovercancelacknowledge(&msg->choice.HandoverCancelAcknowledge, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(msg->choice_type == LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABRELEASERESPONSE) { + if(liblte_s1ap_pack_e_rabreleaseresponse(&msg->choice.E_RABReleaseResponse, &tmp_ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + tmp_msg.N_bits = tmp_ptr - tmp_msg.msg; + + // Procedure code + liblte_value_2_bits(msg->procedureCode, ptr, 8); + + // Criticality + LIBLTE_S1AP_CRITICALITY_ENUM crit = liblte_s1ap_procedure_criticality[msg->procedureCode]; + liblte_value_2_bits(crit, ptr, 2); + liblte_align_up_zero(ptr, 8); + + // Length + uint32_t len = (tmp_msg.N_bits + 7) / 8; + if(len < 128) { + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(len, ptr, 7); + } else if(len < 16383) { + liblte_value_2_bits(1, ptr, 1); + liblte_value_2_bits(0, ptr, 1); + liblte_value_2_bits(len, ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + + memcpy(*ptr, tmp_msg.msg, tmp_msg.N_bits); + *ptr += tmp_msg.N_bits; + + err = LIBLTE_SUCCESS; + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_successfuloutcome( + uint8_t **ptr, + LIBLTE_S1AP_SUCCESSFULOUTCOME_STRUCT *msg) +{ LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + + if(msg != NULL && + ptr != NULL) + { + // Procedure code + msg->procedureCode = liblte_bits_2_value(ptr, 8); + + // Criticality + msg->criticality = (LIBLTE_S1AP_CRITICALITY_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + + // Length + uint32_t len = 0; + if(0 == liblte_bits_2_value(ptr, 1)) { + len = liblte_bits_2_value(ptr, 7); + } else { + if(0 == liblte_bits_2_value(ptr, 1)) { + len = liblte_bits_2_value(ptr, 14); + } else { + // FIXME: Unlikely to have more than 16K of octets + } + } + + // Message + if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERRESOURCEALLOCATION) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERREQUESTACKNOWLEDGE; + if(liblte_s1ap_unpack_handoverrequestacknowledge(ptr, &msg->choice.HandoverRequestAcknowledge) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UECONTEXTRELEASE) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UECONTEXTRELEASECOMPLETE; + if(liblte_s1ap_unpack_uecontextreleasecomplete(ptr, &msg->choice.UEContextReleaseComplete) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UERADIOCAPABILITYMATCH) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UERADIOCAPABILITYMATCHRESPONSE; + if(liblte_s1ap_unpack_ueradiocapabilitymatchresponse(ptr, &msg->choice.UERadioCapabilityMatchResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_INITIALCONTEXTSETUP) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_INITIALCONTEXTSETUPRESPONSE; + if(liblte_s1ap_unpack_initialcontextsetupresponse(ptr, &msg->choice.InitialContextSetupResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_E_RABSETUP) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABSETUPRESPONSE; + if(liblte_s1ap_unpack_e_rabsetupresponse(ptr, &msg->choice.E_RABSetupResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_PATHSWITCHREQUEST) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_PATHSWITCHREQUESTACKNOWLEDGE; + if(liblte_s1ap_unpack_pathswitchrequestacknowledge(ptr, &msg->choice.PathSwitchRequestAcknowledge) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_MMECONFIGURATIONUPDATE) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_MMECONFIGURATIONUPDATEACKNOWLEDGE; + if(liblte_s1ap_unpack_mmeconfigurationupdateacknowledge(ptr, &msg->choice.MMEConfigurationUpdateAcknowledge) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_RESET) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_RESETACKNOWLEDGE; + if(liblte_s1ap_unpack_resetacknowledge(ptr, &msg->choice.ResetAcknowledge) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_ENBCONFIGURATIONUPDATE) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_ENBCONFIGURATIONUPDATEACKNOWLEDGE; + if(liblte_s1ap_unpack_enbconfigurationupdateacknowledge(ptr, &msg->choice.ENBConfigurationUpdateAcknowledge) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_E_RABMODIFY) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABMODIFYRESPONSE; + if(liblte_s1ap_unpack_e_rabmodifyresponse(ptr, &msg->choice.E_RABModifyResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_WRITEREPLACEWARNING) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_WRITEREPLACEWARNINGRESPONSE; + if(liblte_s1ap_unpack_writereplacewarningresponse(ptr, &msg->choice.WriteReplaceWarningResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_S1SETUP) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_S1SETUPRESPONSE; + if(liblte_s1ap_unpack_s1setupresponse(ptr, &msg->choice.S1SetupResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_KILL) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_KILLRESPONSE; + if(liblte_s1ap_unpack_killresponse(ptr, &msg->choice.KillResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_UECONTEXTMODIFICATION) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_UECONTEXTMODIFICATIONRESPONSE; + if(liblte_s1ap_unpack_uecontextmodificationresponse(ptr, &msg->choice.UEContextModificationResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERPREPARATION) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERCOMMAND; + if(liblte_s1ap_unpack_handovercommand(ptr, &msg->choice.HandoverCommand) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_HANDOVERCANCEL) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_HANDOVERCANCELACKNOWLEDGE; + if(liblte_s1ap_unpack_handovercancelacknowledge(ptr, &msg->choice.HandoverCancelAcknowledge) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } else if(msg->procedureCode == LIBLTE_S1AP_PROC_ID_E_RABRELEASE) { + msg->choice_type = LIBLTE_S1AP_SUCCESSFULOUTCOME_CHOICE_E_RABRELEASERESPONSE; + if(liblte_s1ap_unpack_e_rabreleaseresponse(ptr, &msg->choice.E_RABReleaseResponse) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + err = LIBLTE_SUCCESS; + } + return err; +} + + +/******************************************************************************* +/* S1AP_PDU CHOICE +********************************************************************************/ +LIBLTE_ERROR_ENUM liblte_s1ap_pack_s1ap_pdu( + LIBLTE_S1AP_S1AP_PDU_STRUCT *s1ap_pdu, + LIBLTE_BYTE_MSG_STRUCT *msg) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + LIBLTE_BIT_MSG_STRUCT bit_msg; + + if(s1ap_pdu != NULL && + msg != NULL) + { + uint8_t *p = bit_msg.msg; + uint8_t **ptr = &p; + + // Extension + liblte_value_2_bits(s1ap_pdu->ext?1:0, ptr, 1); + + // Message choice + liblte_value_2_bits(s1ap_pdu->choice_type, ptr, 2); + liblte_align_up_zero(ptr, 8); + + // Message + if(LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE == s1ap_pdu->choice_type) { + if(liblte_s1ap_pack_initiatingmessage(&s1ap_pdu->choice.initiatingMessage, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } else if(LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME == s1ap_pdu->choice_type) { + if(liblte_s1ap_pack_successfuloutcome(&s1ap_pdu->choice.successfulOutcome, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + }else if(LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME == s1ap_pdu->choice_type) { + if(liblte_s1ap_pack_unsuccessfuloutcome(&s1ap_pdu->choice.unsuccessfulOutcome, ptr) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_ENCODE_FAIL; + } + } + + liblte_align_up_zero(ptr, 8); + bit_msg.N_bits += (*ptr - bit_msg.msg); + + liblte_pack(&bit_msg, msg); + err = LIBLTE_SUCCESS; + + } + return err; +} + +LIBLTE_ERROR_ENUM liblte_s1ap_unpack_s1ap_pdu( + LIBLTE_BYTE_MSG_STRUCT *msg, + LIBLTE_S1AP_S1AP_PDU_STRUCT *s1ap_pdu) +{ + LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; + LIBLTE_BIT_MSG_STRUCT bit_msg; + + if(s1ap_pdu != NULL && + msg != NULL) + { + liblte_unpack(msg, &bit_msg); + + uint8_t *p = bit_msg.msg; + uint8_t **ptr = &p; + + // Extension + s1ap_pdu->ext = liblte_bits_2_value(ptr, 1); + + // Message choice + s1ap_pdu->choice_type = (LIBLTE_S1AP_S1AP_PDU_CHOICE_ENUM)liblte_bits_2_value(ptr, 2); + liblte_align_up(ptr, 8); + + // Message + if(LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE == s1ap_pdu->choice_type) { + if(liblte_s1ap_unpack_initiatingmessage(ptr, &s1ap_pdu->choice.initiatingMessage) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + }else if(LIBLTE_S1AP_S1AP_PDU_CHOICE_SUCCESSFULOUTCOME == s1ap_pdu->choice_type) { + if(liblte_s1ap_unpack_successfuloutcome(ptr, &s1ap_pdu->choice.successfulOutcome) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + }else if(LIBLTE_S1AP_S1AP_PDU_CHOICE_UNSUCCESSFULOUTCOME == s1ap_pdu->choice_type) { + if(liblte_s1ap_unpack_unsuccessfuloutcome(ptr, &s1ap_pdu->choice.unsuccessfulOutcome) != LIBLTE_SUCCESS) { + return LIBLTE_ERROR_DECODE_FAIL; + } + } + + err = LIBLTE_SUCCESS; + } + return err; +} diff --git a/lib/src/common/pdu_queue.cc b/lib/src/common/pdu_queue.cc index bbccc2e27..a1bf7cd59 100644 --- a/lib/src/common/pdu_queue.cc +++ b/lib/src/common/pdu_queue.cc @@ -74,10 +74,11 @@ void pdu_queue::deallocate(uint8_t* pdu) * This function enqueues the packet and returns quicly because ACK * deadline is important here. */ -void pdu_queue::push(uint8_t *ptr, uint32_t len) +void pdu_queue::push(uint8_t *ptr, uint32_t len, uint32_t tstamp) { - pdu_t *pdu = (pdu_t*) ptr; - pdu->len = len; + pdu_t *pdu = (pdu_t*) ptr; + pdu->len = len; + pdu->tstamp = tstamp; pdu_q.push(pdu); } @@ -88,7 +89,7 @@ bool pdu_queue::process_pdus() pdu_t *pdu; while(pdu_q.try_pop(&pdu)) { if (callback) { - callback->process_pdu(pdu->ptr, pdu->len); + callback->process_pdu(pdu->ptr, pdu->len, pdu->tstamp); } if (!pool.deallocate(pdu)) { log_h->warning("Error deallocating from buffer pool: buffer not created in this pool.\n"); diff --git a/lib/src/common/security.cc b/lib/src/common/security.cc index d9d7f4e21..f0ad1ce7e 100644 --- a/lib/src/common/security.cc +++ b/lib/src/common/security.cc @@ -29,9 +29,7 @@ #include "srslte/common/liblte_security.h" #include "srslte/common/snow_3g.h" -using namespace srslte; - -namespace srsue{ +namespace srslte { /****************************************************************************** * Key Generation diff --git a/lib/src/upper/gw.cc b/lib/src/upper/gw.cc index 57c239e36..a5ef8f342 100644 --- a/lib/src/upper/gw.cc +++ b/lib/src/upper/gw.cc @@ -38,15 +38,13 @@ #include -using namespace srslte; - -namespace srsue{ +namespace srslte { gw::gw() :if_up(false) {} -void gw::init(pdcp_interface_gw *pdcp_, rrc_interface_gw *rrc_, ue_interface *ue_, srslte::log *gw_log_) +void gw::init(srsue::pdcp_interface_gw *pdcp_, srsue::rrc_interface_gw *rrc_, srsue::ue_interface *ue_, log *gw_log_) { pool = byte_buffer_pool::get_instance(); pdcp = pdcp_; @@ -105,7 +103,7 @@ void gw::get_metrics(gw_metrics_t &m) /******************************************************************************* PDCP interface *******************************************************************************/ -void gw::write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) +void gw::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { gw_log->info_hex(pdu->msg, pdu->N_bytes, "RX PDU"); gw_log->info("RX PDU. Stack latency: %ld us\n", pdu->get_latency_us()); @@ -126,7 +124,7 @@ void gw::write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) /******************************************************************************* NAS interface *******************************************************************************/ -srslte::error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str) +error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str) { if(!if_up) { @@ -164,7 +162,7 @@ srslte::error_t gw::setup_if_addr(uint32_t ip_addr, char *err_str) return(ERROR_NONE); } -srslte::error_t gw::init_if(char *err_str) +error_t gw::init_if(char *err_str) { if(if_up) { diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index b1be301d8..c1ebd7463 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -27,14 +27,12 @@ #include "srslte/upper/pdcp.h" -using namespace srslte; - -namespace srsue{ +namespace srslte { pdcp::pdcp() {} -void pdcp::init(rlc_interface_pdcp *rlc_, rrc_interface_pdcp *rrc_, gw_interface_pdcp *gw_, srslte::log *pdcp_log_, uint8_t direction_) +void pdcp::init(srsue::rlc_interface_pdcp *rlc_, srsue::rrc_interface_pdcp *rrc_, srsue::gw_interface_pdcp *gw_, log *pdcp_log_, uint8_t direction_) { rlc = rlc_; rrc = rrc_; diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index 7a2dc113e..23fe8768d 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -28,9 +28,7 @@ #include "srslte/upper/pdcp_entity.h" #include "srslte/common/security.h" -using namespace srslte; - -namespace srsue{ +namespace srslte { pdcp_entity::pdcp_entity() :active(false) @@ -42,10 +40,10 @@ pdcp_entity::pdcp_entity() pool = byte_buffer_pool::get_instance(); } -void pdcp_entity::init(rlc_interface_pdcp *rlc_, - rrc_interface_pdcp *rrc_, - gw_interface_pdcp *gw_, - srslte::log *log_, +void pdcp_entity::init(srsue::rlc_interface_pdcp *rlc_, + srsue::rrc_interface_pdcp *rrc_, + srsue::gw_interface_pdcp *gw_, + srslte::log *log_, uint32_t lcid_, u_int8_t direction_, LIBLTE_RRC_PDCP_CONFIG_STRUCT *cnfg) diff --git a/lib/src/upper/rlc.cc b/lib/src/upper/rlc.cc index 73df8d46f..ef3b6c325 100644 --- a/lib/src/upper/rlc.cc +++ b/lib/src/upper/rlc.cc @@ -30,20 +30,18 @@ #include "srslte/upper/rlc_um.h" #include "srslte/upper/rlc_am.h" -using namespace srslte; - -namespace srsue{ +namespace srslte { rlc::rlc() { pool = byte_buffer_pool::get_instance(); } -void rlc::init(pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - ue_interface *ue_, - srslte::log *rlc_log_, - mac_interface_timers *mac_timers_) +void rlc::init(srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + srsue::ue_interface *ue_, + log *rlc_log_, + mac_interface_timers *mac_timers_) { pdcp = pdcp_; rrc = rrc_; diff --git a/lib/src/upper/rlc_am.cc b/lib/src/upper/rlc_am.cc index 45529a581..6949356b9 100644 --- a/lib/src/upper/rlc_am.cc +++ b/lib/src/upper/rlc_am.cc @@ -34,9 +34,7 @@ #define RX_MOD_BASE(x) (x-vr_r)%1024 #define TX_MOD_BASE(x) (x-vt_a)%1024 -using namespace srslte; - -namespace srsue{ +namespace srslte { rlc_am::rlc_am() : tx_sdu_queue(16) { @@ -64,11 +62,11 @@ rlc_am::rlc_am() : tx_sdu_queue(16) do_status = false; } -void rlc_am::init(srslte::log *log_, - uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - mac_interface_timers *mac_timers) +void rlc_am::init(srslte::log *log_, + uint32_t lcid_, + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + srslte::mac_interface_timers *mac_timers) { log = log_; lcid = lcid_; diff --git a/lib/src/upper/rlc_entity.cc b/lib/src/upper/rlc_entity.cc index ba0e9109d..ace991b10 100644 --- a/lib/src/upper/rlc_entity.cc +++ b/lib/src/upper/rlc_entity.cc @@ -26,19 +26,19 @@ #include "srslte/upper/rlc_entity.h" -namespace srsue { +namespace srslte { rlc_entity::rlc_entity() :rlc(NULL) { } -void rlc_entity::init(rlc_mode_t mode, - srslte::log *rlc_entity_log_, - uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - srslte::mac_interface_timers *mac_timers_) +void rlc_entity::init(rlc_mode_t mode, + log *rlc_entity_log_, + uint32_t lcid_, + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + mac_interface_timers *mac_timers_) { tm.reset(); um.reset(); diff --git a/lib/src/upper/rlc_tm.cc b/lib/src/upper/rlc_tm.cc index fbe17e1bf..c4cddd863 100644 --- a/lib/src/upper/rlc_tm.cc +++ b/lib/src/upper/rlc_tm.cc @@ -27,20 +27,18 @@ #include "srslte/upper/rlc_tm.h" -using namespace srslte; - -namespace srsue{ +namespace srslte { rlc_tm::rlc_tm() : ul_queue(16) { pool = byte_buffer_pool::get_instance(); } -void rlc_tm::init(srslte::log *log_, - uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, - mac_interface_timers *mac_timers) +void rlc_tm::init(srslte::log *log_, + uint32_t lcid_, + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, + mac_interface_timers *mac_timers) { log = log_; lcid = lcid_; diff --git a/lib/src/upper/rlc_um.cc b/lib/src/upper/rlc_um.cc index 411839b3f..83cededc3 100644 --- a/lib/src/upper/rlc_um.cc +++ b/lib/src/upper/rlc_um.cc @@ -29,9 +29,7 @@ #define RX_MOD_BASE(x) (x-vr_uh-rx_window_size)%rx_mod -using namespace srslte; - -namespace srsue{ +namespace srslte { rlc_um::rlc_um() : tx_sdu_queue(16) { @@ -53,10 +51,10 @@ rlc_um::rlc_um() : tx_sdu_queue(16) pdu_lost = false; } -void rlc_um::init(srslte::log *log_, - uint32_t lcid_, - pdcp_interface_rlc *pdcp_, - rrc_interface_rlc *rrc_, +void rlc_um::init(srslte::log *log_, + uint32_t lcid_, + srsue::pdcp_interface_rlc *pdcp_, + srsue::rrc_interface_rlc *rrc_, srslte::mac_interface_timers *mac_timers_) { log = log_; diff --git a/lib/test/upper/rlc_am_control_test.cc b/lib/test/upper/rlc_am_control_test.cc index e0377dd27..874b256d1 100644 --- a/lib/test/upper/rlc_am_control_test.cc +++ b/lib/test/upper/rlc_am_control_test.cc @@ -37,7 +37,7 @@ uint8_t pdu2[] = {0x00 ,0x22 ,0x00 ,0x40 ,0x0C ,0x01 ,0xC0 ,0x20}; uint32_t PDU2_LEN = 8; int main(int argc, char **argv) { - srsue::rlc_status_pdu_t s; + srslte::rlc_status_pdu_t s; srslte::byte_buffer_t b1,b2; memcpy(b1.msg, &pdu1[0], PDU1_LEN); @@ -52,7 +52,7 @@ int main(int argc, char **argv) { b1.reset(); b2.reset(); - memset(&s, 0, sizeof(srsue::rlc_status_pdu_t)); + memset(&s, 0, sizeof(srslte::rlc_status_pdu_t)); memcpy(b1.msg, &pdu2[0], PDU2_LEN); b1.N_bytes = PDU2_LEN; diff --git a/lib/test/upper/rlc_am_data_test.cc b/lib/test/upper/rlc_am_data_test.cc index 47294c96f..faeb07eb5 100644 --- a/lib/test/upper/rlc_am_data_test.cc +++ b/lib/test/upper/rlc_am_data_test.cc @@ -43,8 +43,8 @@ uint32_t PDU3_LEN = 7; using namespace srsue; int main(int argc, char **argv) { - rlc_amd_pdu_header_t h; - byte_buffer_t b1,b2; + srslte::rlc_amd_pdu_header_t h; + srslte::byte_buffer_t b1,b2; memcpy(b1.msg, &pdu1[0], PDU1_LEN); b1.N_bytes = PDU1_LEN; @@ -64,7 +64,7 @@ int main(int argc, char **argv) { b1.reset(); b2.reset(); - memset(&h, 0, sizeof(rlc_amd_pdu_header_t)); + memset(&h, 0, sizeof(srslte::rlc_amd_pdu_header_t)); memcpy(b1.msg, &pdu2[0], PDU2_LEN); b1.N_bytes = PDU2_LEN; @@ -86,7 +86,7 @@ int main(int argc, char **argv) { b1.reset(); b2.reset(); - memset(&h, 0, sizeof(rlc_amd_pdu_header_t)); + memset(&h, 0, sizeof(srslte::rlc_amd_pdu_header_t)); memcpy(b1.msg, &pdu3[0], PDU3_LEN); b1.N_bytes = PDU3_LEN; diff --git a/lib/test/upper/rlc_um_data_test.cc b/lib/test/upper/rlc_um_data_test.cc index 942a0ff81..bde751bdc 100644 --- a/lib/test/upper/rlc_um_data_test.cc +++ b/lib/test/upper/rlc_um_data_test.cc @@ -39,12 +39,12 @@ uint32_t PDU2_LEN = 4; using namespace srsue; int main(int argc, char **argv) { - rlc_umd_pdu_header_t h; + srslte::rlc_umd_pdu_header_t h; srslte::byte_buffer_t b1,b2; memcpy(b1.msg, &pdu1[0], PDU1_LEN); b1.N_bytes = PDU1_LEN; - rlc_um_read_data_pdu_header(&b1, RLC_UMD_SN_SIZE_10_BITS, &h); + rlc_um_read_data_pdu_header(&b1, srslte::RLC_UMD_SN_SIZE_10_BITS, &h); assert(0x03 == h.fi); assert(0 == h.N_li); assert(226 == h.sn); @@ -55,11 +55,11 @@ int main(int argc, char **argv) { b1.reset(); b2.reset(); - memset(&h, 0, sizeof(rlc_umd_pdu_header_t)); + memset(&h, 0, sizeof(srslte::rlc_umd_pdu_header_t)); memcpy(b1.msg, &pdu2[0], PDU2_LEN); b1.N_bytes = PDU2_LEN; - rlc_um_read_data_pdu_header(&b1, RLC_UMD_SN_SIZE_10_BITS, &h); + rlc_um_read_data_pdu_header(&b1, srslte::RLC_UMD_SN_SIZE_10_BITS, &h); assert(0x03 == h.fi); assert(225 == h.sn); assert(1 == h.N_li); diff --git a/srsue/hdr/mac/demux.h b/srsue/hdr/mac/demux.h index f43232d19..f537d7377 100644 --- a/srsue/hdr/mac/demux.h +++ b/srsue/hdr/mac/demux.h @@ -27,9 +27,7 @@ #ifndef DEMUX_H #define DEMUX_H -#include "srslte/common/interfaces.h" -#include "srslte/common/phy_interface.h" -#include "srslte/common/mac_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/pdu_queue.h" #include "srslte/common/log.h" #include "srslte/common/timers.h" @@ -56,7 +54,7 @@ public: void set_uecrid_callback(bool (*callback)(void*, uint64_t), void *arg); bool get_uecrid_successful(); - void process_pdu(uint8_t *pdu, uint32_t nof_bytes); + void process_pdu(uint8_t *pdu, uint32_t nof_bytes, uint32_t tstamp); private: const static int NOF_HARQ_PID = 8; diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index cac9f649e..e64e204c6 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -33,7 +33,7 @@ #include "mac/dl_sps.h" #include "srslte/common/mac_pcap.h" -#include "srslte/common/mac_interface.h" +#include "srslte/interfaces/ue_interfaces.h" /* Downlink HARQ entity as defined in 5.3.2 of 36.321 */ diff --git a/srsue/hdr/mac/dl_sps.h b/srsue/hdr/mac/dl_sps.h index b683d9cd7..8ec83cb52 100644 --- a/srsue/hdr/mac/dl_sps.h +++ b/srsue/hdr/mac/dl_sps.h @@ -27,7 +27,6 @@ #ifndef DL_SPS_H #define DL_SPS_H -#include "srslte/common/mac_interface.h" #include "srslte/common/log.h" #include "srslte/common/timers.h" diff --git a/srsue/hdr/mac/mac.h b/srsue/hdr/mac/mac.h index 051bf96e0..f6f22f334 100644 --- a/srsue/hdr/mac/mac.h +++ b/srsue/hdr/mac/mac.h @@ -39,8 +39,7 @@ #include "mac/mux.h" #include "mac/demux.h" #include "srslte/common/mac_pcap.h" -#include "srslte/common/phy_interface.h" -#include "srslte/common/mac_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/tti_sync_cv.h" #include "srslte/common/threads.h" diff --git a/srsue/hdr/mac/mux.h b/srsue/hdr/mac/mux.h index 806a86d8f..db98ebe78 100644 --- a/srsue/hdr/mac/mux.h +++ b/srsue/hdr/mac/mux.h @@ -32,7 +32,7 @@ #include #include "srslte/common/log.h" -#include "srslte/common/mac_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/pdu.h" #include "mac/proc_bsr.h" #include "mac/proc_phr.h" diff --git a/srsue/hdr/mac/proc_bsr.h b/srsue/hdr/mac/proc_bsr.h index b2750a094..bbfaa1c90 100644 --- a/srsue/hdr/mac/proc_bsr.h +++ b/srsue/hdr/mac/proc_bsr.h @@ -30,8 +30,7 @@ #include #include "srslte/common/log.h" -#include "srslte/common/mac_interface.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/timers.h" /* Buffer status report procedure */ diff --git a/srsue/hdr/mac/proc_phr.h b/srsue/hdr/mac/proc_phr.h index 6b6530bd4..942f30456 100644 --- a/srsue/hdr/mac/proc_phr.h +++ b/srsue/hdr/mac/proc_phr.h @@ -29,10 +29,9 @@ #include #include "srslte/common/timers.h" -#include "srslte/common/phy_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/log.h" -#include "srslte/common/mac_interface.h" /* Power headroom report procedure */ diff --git a/srsue/hdr/mac/proc_sr.h b/srsue/hdr/mac/proc_sr.h index 5aa575f31..9425481dd 100644 --- a/srsue/hdr/mac/proc_sr.h +++ b/srsue/hdr/mac/proc_sr.h @@ -28,8 +28,7 @@ #define PROCSR_H #include -#include "srslte/common/phy_interface.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/log.h" /* Scheduling Request procedure as defined in 5.4.4 of 36.321 */ diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index fec7b3f3c..cea469e33 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -27,7 +27,7 @@ #ifndef ULHARQ_H #define ULHARQ_H -#include "srslte/common/mac_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/log.h" #include "mac/mux.h" #include "mac/ul_sps.h" diff --git a/srsue/hdr/phy/phch_common.h b/srsue/hdr/phy/phch_common.h index 5add2c5e2..7f0075e33 100644 --- a/srsue/hdr/phy/phch_common.h +++ b/srsue/hdr/phy/phch_common.h @@ -31,8 +31,7 @@ #include #include #include "srslte/srslte.h" -#include "srslte/common/mac_interface.h" -#include "srslte/common/phy_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" #include "srslte/common/log.h" #include "phy/phy_metrics.h" diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index a63e09262..838d49d30 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -35,7 +35,7 @@ #include "phy/prach.h" #include "phy/phch_worker.h" #include "phy/phch_common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" namespace srsue { diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 557200647..669422981 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -30,7 +30,6 @@ #include #include "srslte/srslte.h" #include "srslte/common/thread_pool.h" -#include "srslte/common/phy_interface.h" #include "srslte/common/trace.h" #include "phy/phch_common.h" diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 6a26875c9..b478bbcdd 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -28,7 +28,6 @@ #define UEPHY_H #include "srslte/srslte.h" -#include "srslte/common/phy_interface.h" #include "srslte/common/log.h" #include "phy/phy_metrics.h" #include "phy/phch_recv.h" @@ -38,8 +37,7 @@ #include "srslte/radio/radio.h" #include "srslte/common/task_dispatcher.h" #include "srslte/common/trace.h" -#include "srslte/common/mac_interface.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" namespace srsue { diff --git a/srsue/hdr/phy/prach.h b/srsue/hdr/phy/prach.h index e96b5e5eb..694353926 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -32,7 +32,7 @@ #include "srslte/srslte.h" #include "srslte/radio/radio.h" #include "srslte/common/log.h" -#include "srslte/common/phy_interface.h" +#include "srslte/interfaces/ue_interfaces.h" namespace srsue { diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 7c655b592..f401697e9 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -48,7 +48,7 @@ #include "upper/usim.h" #include "srslte/common/buffer_pool.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/logger.h" #include "srslte/common/log_filter.h" @@ -163,15 +163,15 @@ private: virtual ~ue(); srslte::radio_multi radio; - srsue::phy phy; - srsue::mac mac; + srsue::phy phy; + srsue::mac mac; srslte::mac_pcap mac_pcap; - srsue::rlc rlc; - srsue::pdcp pdcp; - srsue::rrc rrc; - srsue::nas nas; - srsue::gw gw; - srsue::usim usim; + srslte::rlc rlc; + srslte::pdcp pdcp; + srsue::rrc rrc; + srsue::nas nas; + srslte::gw gw; + srsue::usim usim; srslte::logger logger; srslte::log_filter rf_log; diff --git a/srsue/hdr/ue_metrics_interface.h b/srsue/hdr/ue_metrics_interface.h index 9929f27c1..70688863e 100644 --- a/srsue/hdr/ue_metrics_interface.h +++ b/srsue/hdr/ue_metrics_interface.h @@ -44,11 +44,11 @@ typedef struct { }rf_metrics_t; typedef struct { - rf_metrics_t rf; - phy_metrics_t phy; - mac_metrics_t mac; - rlc_metrics_t rlc; - gw_metrics_t gw; + rf_metrics_t rf; + phy_metrics_t phy; + mac_metrics_t mac; + srslte::rlc_metrics_t rlc; + srslte::gw_metrics_t gw; }ue_metrics_t; // UE interface diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 248d07dc1..5e3a8b098 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -30,7 +30,7 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/security.h" #include "srslte/asn1/liblte_mme.h" @@ -106,8 +106,8 @@ private: uint8_t k_nas_enc[32]; uint8_t k_nas_int[32]; - CIPHERING_ALGORITHM_ID_ENUM cipher_algo; - INTEGRITY_ALGORITHM_ID_ENUM integ_algo; + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; void integrity_generate(uint8_t *key_128, uint32_t count, diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index d31d5f8d2..cc1a22fd1 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -32,7 +32,7 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/security.h" #include @@ -112,8 +112,8 @@ private: uint8_t k_up_enc[32]; uint8_t k_up_int[32]; // Not used: only for relay nodes (3GPP 33.401 Annex A.7) - CIPHERING_ALGORITHM_ID_ENUM cipher_algo; - INTEGRITY_ALGORITHM_ID_ENUM integ_algo; + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; LIBLTE_RRC_MIB_STRUCT mib; LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT sib1; diff --git a/srsue/hdr/upper/usim.h b/srsue/hdr/upper/usim.h index 6c32a77bb..bb4e394bd 100644 --- a/srsue/hdr/upper/usim.h +++ b/srsue/hdr/upper/usim.h @@ -30,7 +30,7 @@ #include #include "srslte/common/log.h" #include "srslte/common/common.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/security.h" namespace srsue { @@ -71,8 +71,8 @@ public: void generate_nas_keys(uint8_t *k_nas_enc, uint8_t *k_nas_int, - CIPHERING_ALGORITHM_ID_ENUM cipher_algo, - INTEGRITY_ALGORITHM_ID_ENUM integ_algo); + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo, + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo); // RRC interface void generate_as_keys(uint32_t count_ul, @@ -80,8 +80,8 @@ public: uint8_t *k_rrc_int, uint8_t *k_up_enc, uint8_t *k_up_int, - CIPHERING_ALGORITHM_ID_ENUM cipher_algo, - INTEGRITY_ALGORITHM_ID_ENUM integ_algo); + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo, + srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo); private: diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index 986a9ab3d..e0f743217 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -32,7 +32,7 @@ #include "mac/mac.h" #include "mac/demux.h" -#include "srslte/common/phy_interface.h" +#include "srslte/interfaces/ue_interfaces.h" namespace srsue { @@ -139,7 +139,7 @@ bool demux::process_pdus() return pdus.process_pdus(); } -void demux::process_pdu(uint8_t *mac_pdu, uint32_t nof_bytes) +void demux::process_pdu(uint8_t *mac_pdu, uint32_t nof_bytes, uint32_t tstamp) { // Unpack DLSCH MAC PDU mac_msg.init_rx(nof_bytes); diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index f4abf89aa..f583dd2df 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -155,7 +155,9 @@ void mac::run_thread() { if (started) { log_h->step(tti); - + + timers_db.step_all(); + // Step all procedures bsr_procedure.step(tti); phr_procedure.step(tti); diff --git a/srsue/src/mac/proc_phr.cc b/srsue/src/mac/proc_phr.cc index 3acdf9e8c..b432f1c06 100644 --- a/srsue/src/mac/proc_phr.cc +++ b/srsue/src/mac/proc_phr.cc @@ -32,7 +32,7 @@ #include "mac/proc_phr.h" #include "mac/mac.h" #include "mac/mux.h" -#include "srslte/common/phy_interface.h" +#include "srslte/interfaces/ue_interfaces.h" namespace srsue { diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 5281ffeea..14de9b51a 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -27,8 +27,7 @@ #include #include #include "phy/phch_worker.h" -#include "srslte/common/mac_interface.h" -#include "srslte/common/phy_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/asn1/liblte_rrc.h" #define Error(fmt, ...) if (SRSLTE_DEBUG_ENABLED) phy->log_h->error_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index 1a6f96bf6..62980c623 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -32,7 +32,7 @@ #include "srslte/common/log.h" #include "phy/prach.h" #include "phy/phy.h" -#include "srslte/common/phy_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #define Error(fmt, ...) if (SRSLTE_DEBUG_ENABLED) log_h->error_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) #define Warning(fmt, ...) if (SRSLTE_DEBUG_ENABLED) log_h->warning_line(__FILE__, __LINE__, fmt, ##__VA_ARGS__) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index cdac8109b..f91ef6dba 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -29,7 +29,7 @@ #include #include "upper/rrc.h" -#include +#include "srslte/phy/utils/bit.h" #include "srslte/common/security.h" #include "srslte/common/bcd_helpers.h" diff --git a/srsue/test/mac/mac_test.cc b/srsue/test/mac/mac_test.cc index b63b05c0b..7c7e19cf0 100644 --- a/srsue/test/mac/mac_test.cc +++ b/srsue/test/mac/mac_test.cc @@ -31,7 +31,7 @@ #include "srslte/asn1/liblte_rrc.h" #include "srslte/radio/radio_multi.h" #include "phy/phy.h" -#include "srslte/common/mac_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/log_stdout.h" #include "mac/mac.h" #include "srslte/common/mac_pcap.h" diff --git a/srsue/test/phy/ue_itf_test_prach.cc b/srsue/test/phy/ue_itf_test_prach.cc index 818e32fc2..91df6a2fc 100644 --- a/srsue/test/phy/ue_itf_test_prach.cc +++ b/srsue/test/phy/ue_itf_test_prach.cc @@ -28,7 +28,7 @@ #include "srslte/phy/utils/debug.h" #include "phy/phy.h" -#include "srslte/common/phy_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/log_stdout.h" #include "srslte/radio/radio_multi.h" diff --git a/srsue/test/phy/ue_itf_test_sib1.cc b/srsue/test/phy/ue_itf_test_sib1.cc index 5c10e14dc..08116b22c 100644 --- a/srsue/test/phy/ue_itf_test_sib1.cc +++ b/srsue/test/phy/ue_itf_test_sib1.cc @@ -29,7 +29,7 @@ #include "srslte/phy/utils/debug.h" #include "phy/phy.h" #include "srslte/common/log_stdout.h" -#include "srslte/common/mac_interface.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio_multi.h" diff --git a/srsue/test/upper/ip_test.cc b/srsue/test/upper/ip_test.cc index 224fedcd9..63deedc45 100644 --- a/srsue/test/upper/ip_test.cc +++ b/srsue/test/upper/ip_test.cc @@ -124,7 +124,7 @@ public: read_enable = true; } - void init(srsue::phy *phy_, srsue::mac *mac_, srsue::rlc *rlc_, srslte::log *log_h_, std::string ip_address) { + void init(srsue::phy *phy_, srsue::mac *mac_, srslte::rlc *rlc_, srslte::log *log_h_, std::string ip_address) { log_h = log_h_; rlc = rlc_; mac = mac_; @@ -333,7 +333,7 @@ private: bool running; srslte::log *log_h; srslte::byte_buffer_pool *pool; - srsue::rlc *rlc; + srslte::rlc *rlc; srsue::mac *mac; srsue::phy *phy; srslte::bit_buffer_t bit_buf; @@ -472,7 +472,7 @@ srslte::log_filter log_tester; srslte::mac_pcap mac_pcap; srsue::phy my_phy; srsue::mac my_mac; -srsue::rlc rlc; +srslte::rlc rlc; srslte::radio_multi my_radio; // Local classes for testing diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index eac9ecff8..0af342dca 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -33,7 +33,7 @@ #include "srslte/upper/pdcp_entity.h" #include "srslte/upper/pdcp.h" #include "srslte/common/log_stdout.h" -#include "srslte/common/interfaces.h" +#include "srslte/interfaces/ue_interfaces.h" using namespace srsue;