#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable

-mode(compile).

%% Please check 8.1.1 chapter in "3GPP TS 29.244 rel 16"
raw_ies() ->
    [
     {1, "Create PDR",
      [{"Group", 0, {type, v1_grouped}}]},
     {2, "PDI",
      [{"Group", 0, {type, v1_grouped}}]},
     {3, "Create FAR",
      [{"Group", 0, {type, v1_grouped}}]},
     {4, "Forwarding Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {5, "Duplicating Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {6, "Create URR",
      [{"Group", 0, {type, v1_grouped}}]},
     {7, "Create QER",
      [{"Group", 0, {type, v1_grouped}}]},
     {8, "Created PDR",
      [{"Group", 0, {type, v1_grouped}}]},
     {9, "Update PDR",
      [{"Group", 0, {type, v1_grouped}}]},
     {10, "Update FAR",
      [{"Group", 0, {type, v1_grouped}}]},
     {11, "Update Forwarding Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {12, "Update BAR Response",
      [{"Group", 0, {type, v1_grouped}}]},
     {13, "Update URR",
      [{"Group", 0, {type, v1_grouped}}]},
     {14, "Update QER",
      [{"Group", 0, {type, v1_grouped}}]},
     {15, "Remove PDR",
      [{"Group", 0, {type, v1_grouped}}]},
     {16, "Remove FAR",
      [{"Group", 0, {type, v1_grouped}}]},
     {17, "Remove URR",
      [{"Group", 0, {type, v1_grouped}}]},
     {18, "Remove QER",
      [{"Group", 0, {type, v1_grouped}}]},
     {19, "PFCP Cause",
      [{"Cause", 8, {enum, [{0 , "Reserved"},
			    {1,  "Request accepted"},
			    {2,  "More Usage Report to send"},
			    {64, "Request rejected"},
			    {65, "Session context not found"},
			    {66, "Mandatory IE missing"},
			    {67, "Conditional IE missing"},
			    {68, "Invalid length"},
			    {69, "Mandatory IE incorrect"},
			    {70, "Invalid Forwarding Policy"},
			    {71, "Invalid F-TEID allocation option"},
			    {72, "No established Sx Association"},
			    {73, "Rule creation/modification Failure"},
			    {74, "PFCP entity in congestion"},
			    {75, "No resources available"},
			    {76, "Service not supported"},
			    {77, "System failure"},
			    {78, "Redirection Requested"},
			    {79, "All dynamic addresses are occupied"}]}}]},
     {20, "Source Interface",
      [{'_', 4},
       {"Interface", 4, {enum, [{0, "Access"},
				{1, "Core"},
				{2, "SGi-LAN"},
				{3, "CP-function"},
				{4, "5G VN Internal"}]}},
       {'_', 0}]},
     {21, "F-TEID", f_teid},
     {22, "Network Instance",
      [{"Instance", 0, binary}]},
     {23, "SDF Filter", sdf_filter},
     {24, "Application ID",
      [{"Id", 0, binary}]},
     {25, "Gate Status",
      [{'_', 4},
       {"UL", 2, {enum, [{0, "OPEN"},
			 {1, "CLOSED"}]}},
       {"DL", 2, {enum, [{0, "OPEN"},
			 {1, "CLOSED"}]}},
       {'_', 0}]},
     {26, "MBR",
      [{"UL", 40, integer},
       {"DL", 40, integer},
       {'_', 0}]},
     {27, "GBR",
      [{"UL", 40, integer},
       {"DL", 40, integer},
       {'_', 0}]},
     {28, "QER Correlation ID",
      [{"Id", 32, integer},
       {'_', 0}]},
     {29, "Precedence",
      [{"Precedence", 32, integer},
       {'_', 0}]},
     {30, "Transport Level Marking",
      [{"TOS", 16, integer},
       {'_', 0}]},
     {31, "Volume Threshold", volume_threshold},
     {32, "Time Threshold",
      [{"Threshold", 32, integer},
       {'_', 0}]},
     {33, "Monitoring Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {34, "Subsequent Volume Threshold", volume_threshold},
     {35, "Subsequent Time Threshold",
      [{"Threshold", 32, integer},
       {'_', 0}]},
     {36, "Inactivity Detection Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {37, "Reporting Triggers",
      [{"Flags", 16,
	{flags,	["LIUSA", "DROTH", "STOPT", "START", "QUHTI", "TIMTH", "VOLTH", "PERIO",
		 "QUVTI", "IPMJL", "EVEQU", "EVETH", "MACAR", "ENVCL", "TIMQU", "VOLQU",
		 '_', '_', '_', '_', '_', '_', "UPINT", "REEMR"]}}]},
     {38, "Redirect Information",
      [{'_', 4},
       {"Type", 4, {enum, [{0, "IPv4"},
			   {1, "IPv6"},
			   {2, "URL"},
			   {3, "SIP URI"},
			   {4, "IPv4 and IPv6 addresses"}]}},
       {"Address", 16, length_binary},
       {"Other Address", 16, length_binary},
       {'_', 0}]},
     {39, "Report Type",
      [{"Flags", 8,
	{flags,	['_', "UISR", "SESR", "PMIR", "UPIR", "ERIR", "USAR", "DLDR"]}}]},
     {40, "Offending IE",
      [{"Type", 16, integer}]},
     {41, "Forwarding Policy",
      [{"Policy Identifier", 8, length_binary},
       {'_', 0}]},
     {42, "Destination Interface",
      [{'_', 4},
       {"Interface", 4, {enum, [{0, "Access"},
				{1, "Core"},
				{2, "SGi-LAN"},
				{3, "CP-function"},
				{4, "LI-function"},
				{5, "5G VN Internal"}]}},
       {'_', 0}]},
     {43, "UP Function Features",
      [{"Flags", 8,
	{flags,	["TREU", "HEEU", "PFDM", "FTUP", "TRST", "DLBD", "DDND", "BUCP",
		 "EPFAR", "PFDE", "FRRT", "TRACE", "QUOAC", "UDBC", "PDIU", "EMPU",
		 "GCOM", "BUNDL", "MTE", "MNOP", "SSET", "UEIP", "ADPDP", "DPDRA",
		 "MPTCP", "TSCU", "IP6PL", "IPTV", "NORP", "VTIME", "RTTL", "MPAS",
		 "RDS", "DDDS", "ETHAR", "CIOT", "MT-EDT", "GPQM", "QFQM", "ATSSS-LL",
		 '_', '_', '_', '_', '_', '_', '_', "RTTWP"]}}]},
     {44, "Apply Action",
      [{"Flags", 8,
	{flags,	["DFRT", "IPMD", "IPMA", "DUPL", "NOCP", "BUFF", "FORW", "DROP",
		 '_', '_', '_', '_', '_', "DDPN", "BDPN", "EDRT"]}}]},
     {45, "Downlink Data Service Information", downlink_data_service_information},
     {46, "Downlink Data Notification Delay",
      [{"Delay", 8, integer},
       {'_', 0}]},
     {47, "DL Buffering Duration",
      [{"DL Buffer Unit", 3,  {enum, [{0 , "2 seconds"},
				      {1 , "1 minute"},
				      {2 , "10 minutes"},
				      {3 , "1 hour"},
				      {4 , "10 hours"},
				      {7 , "infinite"}]}},
       {"DL Buffer Value", 5, integer},
       {'_', 0}]},
     {48, "DL Buffering Suggested Packet Count", dl_buffering_suggested_packet_count},
     {49, "SxSMReq-Flags",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', "QAURR", "SNDEM", "DROBU"]}}]},
     {50, "SxSRRsp-Flags",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "DROBU"]}}]},
     {51, "Load Control Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {52, "Sequence Number",
      [{"Number", 32, integer}]},
     {53, "Metric",
      [{"Metric", 8, integer}]},
     {54, "Overload Control Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {55, "Timer",
      [{"Timer Unit", 3,  {enum, [{0 , "2 seconds"},
				  {1 , "1 minute"},
				  {2 , "10 minutes"},
				  {3 , "1 hour"},
				  {4 , "10 hours"},
				  {7 , "infinite"}]}},
       {"Timer Value", 5, integer},
       {'_', 0}]},
      {56, "PDR ID",
       [{"Id", 16, integer},
	{'_', 0}]},
     {57, "F-SEID", f_seid},
     {58, "Application ID PFDs",
      [{"Group", 0, {type, v1_grouped}}]},
     {59, "PFD context",
      [{"Group", 0, {type, v1_grouped}}]},
     {60, "Node ID", node_id},
     {61, "PFD contents", pfd_contents},
     {62, "Measurement Method",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', "EVENT", "VOLUM", "DURAT"]}}]},
     {63, "Usage Report Trigger",
      [{"Flags", 16,
	{flags,	["IMMER", "DROTH", "STOPT", "START", "QUHTI", "TIMTH", "VOLTH", "PERIO",
		 "EVETH", "MACAR", "ENVCL", "MONIT", "TERMR", "LIUSA", "TIMQU", "VOLQU",
		 '_', '_', '_', "EMRRE", "QUVTI", "IPMJL", "TEBUR", "EVEQU"]}}]},
     {64, "Measurement Period",
      [{"Period", 32, integer},
       {'_', 0}]},
     {65, "FQ-CSID", fq_csid},
     {66, "Volume Measurement", volume_measurement},
     {67, "Duration Measurement",
      [{"Duration", 32, integer},
       {'_', 0}]},
     {68, "Application Detection Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {69, "Time of First Packet",
      [{"Time", 32, integer},
       {'_', 0}]},
     {70, "Time of Last Packet",
      [{"Time", 32, integer},
       {'_', 0}]},
     {71, "Quota Holding Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {72, "Dropped DL Traffic Threshold", dropped_dl_traffic_threshold},
     {73, "Volume Quota", volume_threshold},
     {74, "Time Quota",
      [{"Quota", 32, integer},
       {'_', 0}]},
     {75, "Start Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {76, "End Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {77, "Query URR",
      [{"Group", 0, {type, v1_grouped}}]},
     {78, "Usage Report SMR",
      [{"Group", 0, {type, v1_grouped}}]},
     {79, "Usage Report SDR",
      [{"Group", 0, {type, v1_grouped}}]},
     {80, "Usage Report SRR",
      [{"Group", 0, {type, v1_grouped}}]},
     {81, "URR ID",
      [{"Id", 32, integer},
       {'_', 0}]},
     {82, "Linked URR ID",
      [{"Id", 32, integer},
       {'_', 0}]},
     {83, "Downlink Data Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {84, "Outer Header Creation", outer_header_creation},
     {85, "Create BAR",
      [{"Group", 0, {type, v1_grouped}}]},
     {86, "Update BAR Request",
      [{"Group", 0, {type, v1_grouped}}]},
     {87, "Remove BAR",
      [{"Group", 0, {type, v1_grouped}}]},
     {88, "BAR ID",
      [{"Id", 8, integer},
       {'_', 0}]},
     {89, "CP Function Features",
      [{"Flags", 8,
	{flags,	["UIAUR", "ARDR", "MPAS", "BUNDL", "SSET", "EPFAR", "OVRL", "LOAD"]}}]},
     {90, "Usage Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', "UBE", "UAE", "AFT", "BEF"]}}]},
     {91, "Application Instance ID",
      [{"Id", 0, binary}]},
     {92, "Flow Information",
      [{'_', 4},
       {"Direction", 4,  {enum, [{0, "Unspecified"},
				 {1, "Downlink"},
				 {2, "Uplink"},
				 {3, "Bidirectional"}]}},
       {"Flow", 16, length_binary},
       {'_', 0}]},
     {93, "UE IP Address", ue_ip_address},
     {94, "Packet Rate", packet_rate},
     {95, "Outer Header Removal",
      [{"Header", 8, {enum, [{0, "GTP-U/UDP/IPv4"},
			     {1, "GTP-U/UDP/IPv6"},
			     {2, "UDP/IPv4"},
			     {3, "UDP/IPv6"},
			     {4, "IPv4"},
			     {5, "IPv6"},
			     {6, "GTP-U/UDP/IP"},
			     {7, "VLAN S-TAG"},
			     {8, "S-TAG and C-TAG"}]}},
       {'_', 0}]},
     {96, "Recovery Time Stamp",
      [{"Time", 32, integer},
       {'_', 0}]},
     {97, "DL Flow Level Marking", dl_flow_level_marking},
     {98, "Header Enrichment",
      [{'_', 4},
       {"Header Type", 4,  {enum, [{0, "HTTP"}]}},
       {"Name", 8, length_binary},
       {"Value", 8, length_binary},
       {'_', 0}]},
     {99, "Error Indication Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {100, "Measurement Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', "MNOP", "ISTM", "RADI", "INAM", "MBQE"]}}]},
     {101, "Node Report Type",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', "GPQR", "CKDR", "UPRR", "UPFR"]}}]},
     {102, "User Plane Path Failure Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {103, "Remote GTP-U Peer", remote_peer},
     {104, "UR-SEQN",
      [{"Number", 32, integer}]},
     {105, "Update Duplicating Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {106, "Activate Predefined Rules",
      [{"Name", 0, binary}]},
     {107, "Deactivate Predefined Rules",
      [{"Name", 0, binary}]},
     {108, "FAR ID",
      [{"Id", 32, integer},
       {'_', 0}]},
     {109, "QER ID",
      [{"Id", 32, integer},
       {'_', 0}]},
     {110, "OCI Flags",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "AOCI"]}}]},
     {111, "Sx Association Release Request",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', "URSS", "SARR"]}}]},
     {112, "Graceful Release Period",
      [{"Release Timer Unit", 3,  {enum, [{0 , "2 seconds"},
					  {1 , "1 minute"},
					  {2 , "10 minutes"},
					  {3 , "1 hour"},
					  {4 , "10 hours"},
					  {7 , "infinite"}]}},
       {"Release Timer Value", 5, integer},
       {'_', 0}]},
     {113, "PDN Type",
      [{'_', 5},
       {"PDN Type", 3,  {enum, [{1, "IPv4"},
				{2, "IPv6"},
				{3, "IPv4v6"},
				{4, "Non-IP"},
				{5, "Ethernet"}]}},
       {'_', 0}]},
     {114, "Failed Rule ID", failed_rule_id},
     {115, "Time Quota Mechanism",
      [{'_', 6},
       {"Base Time Interval Type", 2,  {enum, [{0 , "CTP"},
					       {1 , "DTP"}]}},
       {"Interval", 32, integer},
       {'_', 0}]},
     {116, "User Plane IP Resource Information", user_plane_ip_resource_information},
     {117, "User Plane Inactivity Timer",
      [{"Timer", 32, integer},
       {'_', 0}]},
     {118, "Aggregated URRs",
      [{"Group", 0, {type, v1_grouped}}]},
     {119, "Multiplier",
      [{"Digits", 64, 'signed-integer'},
       {"Exponent", 32, 'signed-integer'}]},
     {120, "Aggregated URR ID",
      [{"Id", 32, integer}]},
     {121, "Subsequent Volume Quota", volume_threshold},
     {122, "Subsequent Time Quota",
      [{"Quota", 32, integer},
       {'_', 0}]},
     {123, "RQI",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "RQI"]}}]},
     {124, "QFI",
      [{'_', 2},
       {"QFI", 6, integer},
       {'_', 0}]},
     {125, "Query URR Reference",
      [{"Reference", 32, integer},
       {'_', 0}]},
     {126, "Additional Usage Reports Information",
      [{"AURI", 1, integer},
       {"Reports", 15, integer},
       {'_', 0}]},
     {127, "Create Traffic Endpoint",
      [{"Group", 0, {type, v1_grouped}}]},
     {128, "Created Traffic Endpoint",
      [{"Group", 0, {type, v1_grouped}}]},
     {129, "Update Traffic Endpoint",
      [{"Group", 0, {type, v1_grouped}}]},
     {130, "Remove Traffic Endpoint",
      [{"Group", 0, {type, v1_grouped}}]},
     {131, "Traffic Endpoint ID",
      [{"Id", 8, integer},
       {'_', 0}]},
     {132, "Ethernet Packet Filter",
      [{"Group", 0, {type, v1_grouped}}]},
     {133, "MAC address", mac_address},
     {134, "C-TAG", vlan_tag},
     {135, "S-TAG", vlan_tag},
     {136, "Ethertype",
      [{"Type", 16, integer},
       {'_', 0}]},
     {137, "Proxying",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', "INS", "ARP"]}}]},
     {138, "Ethernet Filter ID",
      [{"Id", 32, integer},
       {'_', 0}]},
     {139, "Ethernet Filter Properties",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "BIDE"]}}]},
     {140, "Suggested Buffering Packets Count",
      [{"Count", 8, integer},
       {'_', 0}]},
     {141, "User ID", user_id},
     {142, "Ethernet PDU Session Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "ETHI"]}}]},
     {143, "Ethernet Traffic Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {144, "MAC Addresses Detected", mac_addresses},
     {145, "MAC Addresses Removed", mac_addresses},
     {146, "Ethernet Inactivity Timer",
      [{"Timer", 32, integer},
       {'_', 0}]},
     {147, "Additional Monitoring Time",
      [{"Group", 0, {type, v1_grouped}}]},
     {148, "Event Quota",
      [{"Quota", 32, integer},
       {'_', 0}]},
     {149, "Event Threshold",
      [{"Threshold", 32, integer},
       {'_', 0}]},
     {150, "Subsequent Event Quota",
      [{"Quota", 32, integer},
       {'_', 0}]},
     {151, "Subsequent Event Threshold",
      [{"Threshold", 32, integer},
       {'_', 0}]},
     {152, "Trace Information",
      [{"MCCMNC", mccmnc},
       {"Trace ID", 3, binary},
       {"Events", 8, length_binary},
       {"Session Trace Depth", 8, integer},
       {"Interfaces", 8, length_binary},
       {"IP Address", 8, length_binary},
       {'_', 0}]},
     {153, "Framed-Route",
      [{"Value", 0, binary}]},
     {154, "Framed-Routing",
      [{"Value", 32, integer}]},
     {155, "Framed-IPv6-Route",
      [{"Value", 0, binary}]},
     {156, "Event Time Stamp",
      [{"Time", 32, integer},
       {'_', 0}]},
     {157, "Averaging Window",
      [{"Window", 32, integer},
       {'_', 0}]},
     {158, "Paging Policy Indicator",
      [{'_', 5},
       {"PPI", 3, integer},
       {'_', 0}]},
     {159, "APN/DNN",
      [{"APN", 0, binary}]},
     {160, "TGPP Interface Type",
      [{'_', 2},
       {"Type", 6,  {enum, [{0, "S1-U"},
			    {1, "S5 /S8-U"},
			    {2, "S4-U"},
			    {3, "S11-U"},
			    {4, "S12-U"},
			    {5, "Gn/Gp-U"},
			    {6, "S2a-U"},
			    {7, "S2b-U"},
			    {8, "eNodeB GTP-U interface for DL data forwarding"},
			    {9, "eNodeB GTP-U interface for UL data forwarding"},
			    {10, "SGW/UPF GTP-U interface for DL data forwarding"},
			    {11, "N3 3GPP Access"},
			    {12, "N3 Trusted Non-3GPP Access"},
			    {13, "N3 Untrusted Non-3GPP Access"},
			    {14, "N3 for data forwarding"},
			    {15, "N9"},
			    {16, "SGi"},
			    {17, "N6"},
			    {18, "N19"},
			    {19, "S8-U"},
			    {20, "Gp-U"}]}},
       {'_', 0}]},
     {161, "PFCPSRReq-Flags",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "PSDBU"]}}]},
     {162, "PFCPAUReq-Flags",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "PARPS"]}}]},
     {163, "Activation Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {164, "Deactivation Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {165, "Create MAR",
      [{"Group", 0, {type, v1_grouped}}]},
     {166, "TGPP Access Forwarding Action Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {167, "Non-TGPP Access Forwarding Action Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {168, "Remove MAR",
      [{"Group", 0, {type, v1_grouped}}]},
     {169, "Update MAR",
      [{"Group", 0, {type, v1_grouped}}]},
     {170, "MAR ID",
      [{"Id", 16, integer},
	{'_', 0}]},
     {171, "Steering Functionality",
      [{'_', 4},
       {"Functionality", 4,  {enum, [{0, "ATSSS-LL"},
				     {1, "MPTCP"}]}},
       {'_', 0}]},
     {172, "Steering Mode",
      [{'_', 4},
       {"Mode", 4,  {enum, [{0, "Active-Standby"},
			    {1, "Smallest Delay"},
			    {2, "Load Balancing"},
			    {3, "Priority-based"}]}},
       {'_', 0}]},
     {173, "Weight",
      [{"Value", 32, integer}]},
     {174, "Priority",
      [{'_', 4},
       {"Priority", 4, integer},
       {'_', 0}]},
     {175, "Update TGPP Access Forwarding Action Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {176, "Update Non-TGPP Access Forwarding Action Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {177, "UE IP address Pool Identity",
      [{"Identity", 16, length_binary},
       {'_', 0}]},
     {178, "Alternative SMF IP Address", alternative_smf_ip_address},
     {179, "Packet Replication and Detection Carry-On Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', "DCARONI", "PRIN6I", "PRIN19I", "PRIUEAI"]}}]},
     {180, "SMF Set ID",
      [{'_', 8},
       {"FQDN", 0, {type, fqdn}}]},
     {181, "Quota Validity Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {182, "Number of Reports",
      [{"Reports", 16, integer},
       {'_', 0}]},
     {183, "PFCP Session Retention Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {184, "PFCPASRsp-Flags",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "PSREI"]}}]},
     {185, "CP PFCP Entity IP Address", cp_pfcp_entity_ip_address},
     {186, "PFCPSEReq-Flags",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "RESTI"]}}]},
     {187, "User Plane Path Recovery Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {188, "IP Multicast Addressing Info",
      [{"Group", 0, {type, v1_grouped}}]},
     {189, "Join IP Multicast Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {190, "Leave IP Multicast Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {191, "IP Multicast Address", ip_multicast_address},
     {192, "Source IP Address", source_ip_address},
     {193, "Packet Rate Status", packet_rate_status},
     {194, "Create Bridge Info for TSC",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "BII"]}}]},
     {195, "Created Bridge Info for TSC",
      [{"Group", 0, {type, v1_grouped}}]},
     {196, "DS-TT Port Number",
      [{"Value", 32, integer}]},
     {197, "NW-TT Port Number",
      [{"Value", 32, integer}]},
     {198, "TSN Bridge ID", tsn_bridge_id},
     {199, "Port Management Information for TSC",
      [{"Group", 0, {type, v1_grouped}}]},
     {200, "Port Management Information for TSC SMR",
      [{"Group", 0, {type, v1_grouped}}]},
     {201, "Port Management Information for TSC SDR",
      [{"Group", 0, {type, v1_grouped}}]},
     {202, "Port Management Information Container",
      [{"Value", 0, binary}]},
     {203, "Clock Drift Control Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {204, "Requested Clock Drift Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', "RRCR", "RRTO"]}}]},
     {205, "Clock Drift Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {206, "TSN Time Domain Number",
      [{"Number", 8, integer},
       {'_', 0}]},
     {207, "Time Offset Threshold",
      [{"Threshold", 64, 'signed-integer'},
       {'_', 0}]},
     {208, "Cumulative rateRatio Threshold",
      [{"Threshold", 32, integer},
       {'_', 0}]},
     {209, "Time Offset Measurement",
      [{"Measurement", 64, 'signed-integer'},
       {'_', 0}]},
     {210, "Cumulative rateRatio Measurement",
      [{"Measurement", 32, integer},
       {'_', 0}]},
     {211, "Remove SRR",
      [{"Group", 0, {type, v1_grouped}}]},
     {212, "Create SRR",
      [{"Group", 0, {type, v1_grouped}}]},
     {213, "Update SRR",
      [{"Group", 0, {type, v1_grouped}}]},
     {214, "Session Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {215, "SRR ID",
      [{"Id", 8, integer},
       {'_', 0}]},
     {216, "Access Availability Control Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {217, "Requested Access Availability Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "RRCA"]}}]},
     {218, "Access Availability Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {219, "Access Availability Information",
       [{'_', 4},
	{"Status", 2,  {enum, [{0 , "unavailable"},
			       {1 , "available"}]}},
	{"Type", 2,  {enum, [{0 , "TGPP"},
			     {1 , "Non-TGPP"}]}},
       {'_', 0}]},
     {220, "Provide ATSSS Control Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {221, "ATSSS Control Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {222, "MPTCP Control Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "TCI"]}}]},
     {223, "ATSSS-LL Control Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "LLI"]}}]},
     {224, "PMF Control Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "PMFI"]}}]},
     {225, "MPTCP Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {226, "ATSSS-LL Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {227, "PMF Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {228, "MPTCP Address Information", mptcp_address_information},
     {229, "UE Link-Specific IP Address", ue_link_specific_ip_address},
     {230, "PMF Address Information", pmf_address_information},
     {231, "ATSSS-LL Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "LLI"]}}]},
     {232, "Data Network Access Identifier",
      [{"Value", 0, binary}]},
     {233, "UE IP Address Pool Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {234, "Average Packet Delay",
      [{"Delay", 32, integer},
       {'_', 0}]},
     {235, "Minimum Packet Delay",
      [{"Delay", 32, integer},
       {'_', 0}]},
     {236, "Maximum Packet Delay",
      [{"Delay", 32, integer},
       {'_', 0}]},
     {237, "QoS Report Trigger",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', "IRE", "THR", "PER"]}}]},
     {238, "GTP-U Path QoS Control Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {239, "GTP-U Path QoS Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {240, "Path Report QoS Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {241, "GTP-U Path Interface Type",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', "N3", "N9"]}}]},
     {242, "QoS Monitoring per QoS flow Control Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {243, "Requested QoS Monitoring",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', "RP", "UL", "DL"]}}]},
     {244, "Reporting Frequency",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', "SESRL", "PERIO", "EVETT"]}}]},
    {245, "Packet Delay Thresholds", packet_delay_thresholds},
     {246, "Minimum Wait Time",
      [{"Time", 32, integer},
       {'_', 0}]},
     {247, "QoS Monitoring Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {248, "QoS Monitoring Measurement", qos_monitoring_measurement},
     {249, "MT-EDT Control Information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "RDSI"]}}]},
     {250, "DL Data Packets Size",
      [{"Size", 16, integer},
       {'_', 0}]},
     {251, "QER Control Indications",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', "NORD", "MOED", "RCSRT"]}}]},
     {252, "Packet Rate Status Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {253, "NF Instance ID",
      [{"Value", 16, binary}]},
     {254, "Ethernet Context Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {255, "Redundant Transmission Parameters",
      [{"Group", 0, {type, v1_grouped}}]},
     {256, "Updated PDR",
      [{"Group", 0, {type, v1_grouped}}]},
     {257, "S-NSSAI",
      [{"SST", 8, integer},
       {"SD", 24, integer}]},
     {258, "IP version",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', "V6", "V4"]}}]},
     {259, "PFCPASReq-Flags",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "UUPSI"]}}]},
     {260, "Data Status",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', "BUFF", "DROP"]}}]},
     {261, "Provide RDS configuration information",
      [{"Group", 0, {type, v1_grouped}}]},
     {262, "RDS configuration information",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "RDS"]}}]},
     {263, "Query Packet Rate Status IE SMReq",
      [{"Group", 0, {type, v1_grouped}}]},
     {264, "Packet Rate Status Report IE SMResp",
      [{"Group", 0, {type, v1_grouped}}]},
     {265, "MPTCP Applicable Indication",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "MAI"]}}]},
     {266, "Bridge Management Information Container",
      [{"Value", 0, binary}]},
     {267, "UE IP Address Usage Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {268, "Number of UE IP Addresses", number_of_ue_ip_addresses},
     {269, "Validity Timer",
      [{"Validity Timer", 16, integer},
       {'_', 0}]},
     {270, "Redundant Transmission Forwarding",
      [{"Group", 0, {type, v1_grouped}}]},
     {271, "Transport Delay Reporting",
      [{"Group", 0, {type, v1_grouped}}]},

     {{3561, 0}, "BBF UP Function Features",
      [{"Flags", 32,
	{flags,	['_', "NAT-UP", "NAT-CP", "LCP keepalive offload",
		 "LNS", "LAC", "IPoE", "PPPoE"]}}]},
     {{3561, 1}, "Logical Port",
      [{"Port", 0, binary}]},
     {{3561, 2}, "BBF Outer Header Creation",
      [{"Flags", 16,
	{fixed_flags, ['_', '_', '_', '_', "CPR-NSH", "Traffic-Endpoint", "L2TP", "PPP"]}},
       {"Tunnel ID", 16, integer},
       {"Session ID", 16, integer},
       {'_', 0}]},
     {{3561, 3}, "BBF Outer Header Removal",
      [{"Header", 8, {enum, [{1, "Ethernet"},
			     {2, "PPPoE / Ethernet"},
			     {3, "PPP / PPPoE / Ethernet"},
			     {4, "L2TP"},
			     {5, "PPP / L2TP"}]}},
       {'_', 0}]},
     {{3561, 4}, "PPPoE Session ID",
      [{"ID", 16, integer},
       {'_', 0}]},
     {{3561, 5}, "PPP protocol", ppp_protocol},
     {{3561, 6}, "Verification Timers",
      [{"interval", 16, integer},
       {"count", 8, integer},
       {'_', 0}]},
     {{3561, 7}, "PPP LCP Magic Number",
      [{"tx", 32, integer},
       {"rx", 32, integer},
       {'_', 0}]},
     {{3561, 8}, "MTU",
      [{"mtu", 16, integer},
       {'_', 0}]},
     {{3561, 9}, "L2TP Tunnel Endpoint", l2tp_tunnel_endpoint},
     {{3561, 10}, "L2TP Session ID",
      [{"ID", 16, integer},
       {'_', 0}]},
     {{3561, 11}, "L2TP Type",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "type"]}}]},
     {{3561, 12}, "PPP LCP Connectivity",
      [{"Group", 0, {type, v1_grouped}}]},
     {{3561, 13}, "L2TP Tunnel",
      [{"Group", 0, {type, v1_grouped}}]},

     %% TBD: the id assigment table and the IE specification are somewhat inconsistent
     %%      at the time of writing -- 2021-04-26
     {{3561, 14}, "BBF NAT Outside Address",
      [{"IPv4", 4, bytes}]},
     {{3561, 15}, "BBF Apply Action",
      [{"Flags", 8,
	{flags,	['_', '_', '_', '_', '_', '_', '_', "NAT"]}}]},
     {{3561, 16}, "BBF NAT external Port Range", bbf_nat_external_port_range},
     {{3561, 17}, "BBF NAT Port Forward", bbf_nat_port_forward},
     {{3561, 18}, "BBF NAT Port Block",
      [{"Block", 0, binary}]},
     {{3561, 19}, "BBF dynamic port block starting port",
      [{"Start", 16, integer},
       {'_', 0}]},

     {{18681, 1}, "TP Packet Measurement", volume_threshold},
     {{18681, 2}, "TP Build Identifier",
      [{"Id", 0, binary}]},
     {{18681, 3}, "TP Now",
      [{"Seconds", 32, integer},
       {"Fraction", 32, integer},
       {'_', 0}]},
     {{18681, 4}, "TP Start Time",
      [{"Seconds", 32, integer},
       {"Fraction", 32, integer},
       {'_', 0}]},
     {{18681, 5}, "TP Stop Time",
      [{"Seconds", 32, integer},
       {"Fraction", 32, integer},
       {'_', 0}]},
     {{18681, 6}, "TP Error Report",
      [{"Group", 0, {type, v1_grouped}}]},
     {{18681, 7}, "TP Error Message",
      [{"Message", 0, binary}]},
     {{18681, 8}, "TP File Name",
      [{"File Name", 0, binary}]},
     {{18681, 9}, "TP Line Number",
      [{"Line", 32, integer},
       {'_', 0}]},
     {{18681, 10}, "TP Created NAT Binding",
      [{"Group", 0, {type, v1_grouped}}]},
     {{18681, 11}, "TP IPFIX Policy",
      [{"Policy", 0, binary}]},
     {{18681, 12}, "TP Trace Information",
      [{"Group", 0, {type, v1_grouped}}]},
     {{18681, 13}, "TP Trace Parent",
      [{"Parent", 0, binary}]},
     {{18681, 14}, "TP Trace State",
      [{"State", 0, binary}]}
    ].


%% Please check 7.3, 7.4, 7.5 chapters in "3GPP TS 29.244 rel 16"
%% In the following list the tuple positions correspond to the Sxa, Sxb, Sxc and N4 ref points

msgs() ->
    [{1, "Heartbeat Request",				{'X', 'X', 'X', 'X'},
      [{"Recovery Time Stamp",			   'M', {'X', 'X', 'X', 'X'}},
       {"Source IP Address",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {2, "Heartbeat Response",				{'X', 'X', 'X', 'X'},
      [{"Recovery Time Stamp",			   'M', {'X', 'X', 'X', 'X'}},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {3, "PFD Management Request",			{'-', 'X', 'X', 'X'},
      [{"Application ID's PFDs",		   'M', {'-', 'X', 'X', 'X'},
	[{"Application ID",			   'M', {'-', 'X', 'X', 'X'}},
	 {"PFD context",			   'C', {'-', 'X', 'X', 'X'},
	  [{"PFD Contents",			   'M', {'-', 'X', 'X', 'X'}}]}
	]}
      ]},
     {4, "PFD Management Response",			{'-', 'X', 'X', 'X'},
      [{"PFCP Cause",				   'M', {'-', 'X', 'X', 'X'}},
       {"Offending IE",				   'C', {'-', 'X', 'X', 'X'}}]},
     {5, "Association Setup Request",			{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"Recovery Time Stamp",			   'M', {'X', 'X', 'X', 'X'}},
       {"UP Function Features",			   'C', {'X', 'X', 'X', 'X'}},
       {"CP Function Features",			   'C', {'X', 'X', 'X', 'X'}},
       {"BBF UP Function Features",		   'C', {'X', 'X', 'X', 'X'}},
       {"User Plane IP Resource Information",	   'O', {'X', 'X', 'X', 'X'}},    %% Removed in R16
       {"Alternative SMF IP Address",		   'O', {'X', 'X', 'X', 'X'}},
       {"SMF Set ID",				   'C', {'X', 'X', 'X', 'X'}},
       {"PFCP Session Retention Information",	   'O', {'X', 'X', 'X', 'X'},
	[{"CP PFCP Entity IP Address",		   'O', {'X', 'X', 'X', 'X'}}]},
       {"UE IP Address Pool Information",	   'O', {'X', 'X', 'X', 'X'},
	[{"UE IP address Pool Identity",	   'M', {'-', 'X', '-', 'X'}},
	 {"Network Instance",			   'O', {'-', 'X', '-', 'X'}},
	 {"S-NSSAI",				   'O', {'-', '-', '-', 'X'}},
	 {"IP version",				   'O', {'-', '-', '-', 'X'}}]},
       {"GTP-U Path QoS Control Information",	   'C', {'X', 'X', 'X', 'X'},
	[{"Remote GTP-U Peer",			   'C', {'-', '-', '-', 'X'}},
	 {"GTP-U Path Interface Type",		   'C', {'-', '-', '-', 'X'}},
	 {"QoS Report Trigger",			   'M', {'-', '-', '-', 'X'}},
	 {"Transport Level Marking",		   'C', {'-', '-', '-', 'X'}},
	 {"Measurement Period",			   'C', {'-', '-', '-', 'X'}},
	 {"Average Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Minimum Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Maximum Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Timer",				   'C', {'-', '-', '-', 'X'}}]},
       {"Clock Drift Control Information",	   'O', {'X', 'X', 'X', 'X'},
	[{"Requested Clock Drift Information",	   'M', {'-', '-', '-', 'X'}},
	 {"TSN Time Domain Number",		   'C', {'-', '-', '-', 'X'}},
	 {"Time Offset Threshold",		   'C', {'-', '-', '-', 'X'}},
	 {"Cumulative rateRatio Threshold",	   'C', {'-', '-', '-', 'X'}}]},
       {"NF Instance ID",			   'O', {'X', 'X', 'X', 'X'}},
       {"PFCPASReq-Flags",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {6, "Association Setup Response",			{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"PFCP Cause",				   'M', {'X', 'X', 'X', 'X'}},
       {"Recovery Time Stamp",			   'M', {'X', 'X', 'X', 'X'}},
       {"UP Function Features",			   'C', {'X', 'X', 'X', 'X'}},
       {"CP Function Features",			   'C', {'X', 'X', 'X', 'X'}},
       {"BBF UP Function Features",		   'C', {'X', 'X', 'X', 'X'}},
       {"User Plane IP Resource Information",	   'O', {'X', 'X', 'X', 'X'}},    %% Removed in R16
       {"Alternative SMF IP Address",		   'O', {'X', 'X', 'X', 'X'}},
       {"SMF Set ID",				   'C', {'X', 'X', 'X', 'X'}},
       {"PFCPASRsp-Flags",			   'O', {'X', 'X', 'X', 'X'}},
       {"Clock Drift Control Information",	   'C', {'X', 'X', 'X', 'X'},
	[{"Requested Clock Drift Information",	   'M', {'-', '-', '-', 'X'}},
	 {"TSN Time Domain Number",		   'C', {'-', '-', '-', 'X'}},
	 {"Time Offset Threshold",		   'C', {'-', '-', '-', 'X'}},
	 {"Cumulative rateRatio Threshold",	   'C', {'-', '-', '-', 'X'}}]},
       {"UE IP Address Pool Information",	   'O', {'X', 'X', 'X', 'X'},
	[{"UE IP address Pool Identity",	   'M', {'-', 'X', '-', 'X'}},
	 {"Network Instance",			   'O', {'-', 'X', '-', 'X'}},
	 {"S-NSSAI",				   'O', {'-', '-', '-', 'X'}},
	 {"IP version",				   'O', {'-', '-', '-', 'X'}}]},
       {"GTP-U Path QoS Control Information",	   'C', {'X', 'X', 'X', 'X'},
	[{"Remote GTP-U Peer",			   'C', {'-', '-', '-', 'X'}},
	 {"GTP-U Path Interface Type",		   'C', {'-', '-', '-', 'X'}},
	 {"QoS Report Trigger",			   'M', {'-', '-', '-', 'X'}},
	 {"Transport Level Marking",		   'C', {'-', '-', '-', 'X'}},
	 {"Measurement Period",			   'C', {'-', '-', '-', 'X'}},
	 {"Average Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Minimum Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Maximum Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Timer",				   'C', {'-', '-', '-', 'X'}}]},
       {"NF Instance ID",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {7, "Association Update Request",			{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"UP Function Features",			   'O', {'X', 'X', 'X', 'X'}},
       {"CP Function Features",			   'O', {'X', 'X', 'X', 'X'}},
       {"BBF UP Function Features",		   'C', {'X', 'X', 'X', 'X'}},
       {"PFCP Association Release Request",	   'C', {'X', 'X', 'X', 'X'}},
       {"Graceful Release Period",		   'C', {'X', 'X', 'X', 'X'}},
       {"User Plane IP Resource Information",	   'O', {'X', 'X', 'X', 'X'}},    %% Removed in R16
       {"PFCPAUReq-Flags",			   'O', {'X', 'X', 'X', 'X'}},
       {"Alternative SMF IP Address",		   'O', {'X', 'X', 'X', 'X'}},
       {"SMF Set ID",				   'C', {'X', 'X', 'X', 'X'}},
       {"Clock Drift Control Information",	   'C', {'X', 'X', 'X', 'X'},
	[{"Requested Clock Drift Information",	   'M', {'-', '-', '-', 'X'}},
	 {"TSN Time Domain Number",		   'C', {'-', '-', '-', 'X'}},
	 {"Time Offset Threshold",		   'C', {'-', '-', '-', 'X'}},
	 {"Cumulative rateRatio Threshold",	   'C', {'-', '-', '-', 'X'}}]},
       {"UE IP Address Pool Information",	   'O', {'X', 'X', 'X', 'X'},
	[{"UE IP address Pool Identity",	   'M', {'-', 'X', '-', 'X'}},
	 {"Network Instance",			   'O', {'-', 'X', '-', 'X'}},
	 {"S-NSSAI",				   'O', {'-', '-', '-', 'X'}},
	 {"IP version",				   'O', {'-', '-', '-', 'X'}}]},
       {"GTP-U Path QoS Information",		   'C', {'X', 'X', 'X', 'X'},
	[{"Remote GTP-U Peer",			   'C', {'-', '-', '-', 'X'}},
	 {"GTP-U Path Interface Type",		   'C', {'-', '-', '-', 'X'}},
	 {"QoS Report Trigger",			   'M', {'-', '-', '-', 'X'}},
	 {"Transport Level Marking",		   'C', {'-', '-', '-', 'X'}},
	 {"Measurement Period",			   'C', {'-', '-', '-', 'X'}},
	 {"Average Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Minimum Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Maximum Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	 {"Timer",				   'C', {'-', '-', '-', 'X'}}]},
       {"UE IP Address Usage Information",	   'O', {'X', 'X', 'X', 'X'},
	[{"Sequence Number",			   'M', {'-', 'X', '-', 'X'}},
	 {"Metric",				   'M', {'-', 'X', '-', 'X'}},
	 {"Validity Timer",			   'M', {'-', 'X', '-', 'X'}},
	 {"Number of UE IP Addresses",		   'M', {'-', 'X', '-', 'X'}},
	 {"Network Instance",			   'M', {'-', 'X', '-', 'X'}},
	 {"UE IP address Pool Identity",	   'O', {'-', 'X', '-', 'X'}}]},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {8, "Association Update Response",			{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"PFCP Cause",				   'M', {'X', 'X', 'X', 'X'}},
       {"UP Function Features",			   'O', {'X', 'X', 'X', 'X'}},
       {"CP Function Features",			   'O', {'X', 'X', 'X', 'X'}},
       {"BBF UP Function Features",		   'C', {'X', 'X', 'X', 'X'}},
       {"UE IP Address Usage Information",	   'O', {'X', 'X', 'X', 'X'},
	[{"Sequence Number",			   'M', {'-', 'X', '-', 'X'}},
	 {"Metric",				   'M', {'-', 'X', '-', 'X'}},
	 {"Validity Timer",			   'M', {'-', 'X', '-', 'X'}},
	 {"Number of UE IP Addresses",		   'M', {'-', 'X', '-', 'X'}},
	 {"Network Instance",			   'M', {'-', 'X', '-', 'X'}},
	 {"UE IP address Pool Identity",	   'O', {'-', 'X', '-', 'X'}}]},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {9, "Association Release Request",			{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {10, "Association Release Response",		{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"PFCP Cause",				   'M', {'X', 'X', 'X', 'X'}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {11, "Version Not Supported Response",		{'X', 'X', 'X', 'X'},
      []},
     {12, "Node Report Request",			{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"Node Report Type",			   'M', {'X', 'X', 'X', 'X'}},
       {"User Plane Path Failure Report",	   'C', {'X', 'X', '-', 'X'},
	[{"Remote GTP-U Peer",			   'M', {'X', 'X', '-', 'X'}}]},
       {"User Plane Path Recovery Report",	   'C', {'X', 'X', '-', 'X'},
	[{"Remote GTP-U Peer",			   'M', {'X', 'X', '-', 'X'}}]},
       {"Clock Drift Report",			   'C', {'-', '-', '-', 'X'},
	[{"TSN Time Domain Number",		   'C', {'-', '-', '-', 'X'}},
	 {"Time Offset Measurement",		   'M', {'-', '-', '-', 'X'}},
	 {"Cumulative rateRatio Measurement",	   'O', {'-', '-', '-', 'X'}},
	 {"Time Stamp",				   'O', {'-', '-', '-', 'X'}}]},
       {"GTP-U Path QoS Report",		   'C', {'-', '-', '-', 'X'},
	[{"Remote GTP-U Peer",			   'M', {'-', '-', '-', 'X'}},
	 {"GTP-U Path Interface Type",		   'C', {'-', '-', '-', 'X'}},
	 {"QoS Report Trigger",			   'M', {'-', '-', '-', 'X'}},
	 {"Event Time Stamp",			   'M', {'-', '-', '-', 'X'}},
	 {"Start Time",				   'C', {'-', '-', '-', 'X'}},
	 {"Path Report QoS Information",	   'M', {'-', '-', '-', 'X'},
	  [{"Average Packet Delay",		   'M', {'-', '-', '-', 'X'}},
	   {"Minimum Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	   {"Maximum Packet Delay",		   'C', {'-', '-', '-', 'X'}},
	   {"Transport Level Marking",		   'C', {'-', '-', '-', 'X'}}]}]},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}}]},
     {13, "Node Report Response",			{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"PFCP Cause",				   'M', {'X', 'X', 'X', 'X'}},
       {"Offending IE",				   'C', {'X', 'X', 'X', 'X'}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]}]},
     {14, "Session Set Deletion Request",		{'X', 'X', '-', ' '},
      [{"Node ID",				   'M', {'X', 'X', '-', ' '}},
       {"FQ-CSID",				   'C', {'X', 'X', '-', ' '}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]}]},
     {15, "Session Set Deletion Response",		{'X', 'X', '-', ' '},
      [{"Node ID",				   'M', {'X', 'X', '-', ' '}},
       {"PFCP Cause",				   'M', {'X', 'X', '-', ' '}},
       {"Offending IE",				   'C', {'X', 'X', '-', ' '}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]}]},
     {50, "Session Establishment Request",		{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"F-SEID",				   'M', {'X', 'X', 'X', 'X'}},
       {"Create PDR",				   'M', {'X', 'X', 'X', 'X'},
	[{"PDR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Precedence",				   'M', {'-', 'X', 'X', 'X'}},
	 {"PDI",				   'M', {'X', 'X', 'X', 'X'},
	  [{"Source Interface",			   'M', {'X', 'X', 'X', 'X'}},
	   {"F-TEID",				   'O', {'X', 'X', '-', 'X'}},
	   {"Network Instance",			   'O', {'X', 'X', 'X', 'X'}},
	   {"Redundant Transmission Parameters",   'O', {'-', '-', '-', 'X'},
	    [{"F-TEID",				   'M', {'-', '-', '-', 'X'}},
	     {"Network Instance",		   'O', {'-', '-', '-', 'X'}}]},
	   {"UE IP address",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Traffic Endpoint ID",		   'C', {'X', 'X', 'X', 'X'}},
	   {"SDF Filter",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Application ID",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Ethernet PDU Session Information",	   'O', {'-', '-', '-', 'X'}},
	   {"Ethernet Packet Filter",		   'O', {'-', '-', '-', 'X'},
	    [{"Ethernet Filter ID",		   'C', {'-', '-', '-', 'X'}},
	     {"Ethernet Filter Properties",	   'C', {'-', '-', '-', 'X'}},
	     {"MAC address",			   'O', {'-', '-', '-', 'X'}},
	     {"Ethertype",			   'O', {'-', '-', '-', 'X'}},
	     {"C-TAG",				   'O', {'-', '-', '-', 'X'}},
	     {"S-TAG",				   'O', {'-', '-', '-', 'X'}},
	     {"SDF Filter",			   'O', {'-', '-', '-', 'X'}}]},
	   {"QFI",				   'O', {'-', '-', '-', 'X'}},
	   {"Framed-Route",			   'O', {'-', 'X', '-', 'X'}},
	   {"Framed-Routing",			   'O', {'-', 'X', '-', 'X'}},
	   {"Framed-IPv6-Route",		   'O', {'-', 'X', '-', 'X'}},
	   {"TGPP Interface Type",		   'O', {'X', 'X', '-', 'X'}},
	   {"IP Multicast Addressing Info",	   'O', {'-', '-', '-', 'X'},
	    [{"IP Multicast Address",		   'M', {'-', '-', '-', 'X'}},
	     {"Source IP Address",		   'O', {'-', '-', '-', 'X'}}]}]},
	 {"Outer Header Removal",		   'C', {'X', 'X', '-', 'X'}},
	 {"FAR ID",				   'C', {'X', 'X', 'X', 'X'}},
	 {"URR ID",				   'C', {'X', 'X', 'X', 'X'}},
	 {"QER ID",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Activate Predefined Rules",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Activation Time",			   'O', {'-', 'X', 'X', 'X'}},
	 {"Deactivation Time",			   'O', {'-', 'X', 'X', 'X'}},
	 {"MAR ID",				   'C', {'-', '-', '-', 'X'}},
	 {"Packet Replication and Detection Carry-On Information",
						   'C', {'-', '-', '-', 'X'}},
	 {"IP Multicast Addressing Info",	   'O', {'-', '-', '-', 'X'},
	  [{"IP Multicast Address",		   'M', {'-', '-', '-', 'X'}},
	   {"Source IP Address",		   'O', {'-', '-', '-', 'X'}}]},
	 {"UE IP Address Pool Identity",	   'O', {'-', 'X', '-', 'X'}},
	 {"MPTCP Applicable Indication",	   'C', {'-', '-', '-', 'X'}},
	 {"Transport Delay Reporting",		   'C', {'-', '-', '-', 'X'},
	  [{"Remote GTP-U Peer",		   'M', {'-', '-', '-', 'X'}},
	   {"Transport Level Marking",		   'O', {'-', '-', '-', 'X'}}]}]},
       {"Create FAR",				   'M', {'X', 'X', 'X', 'X'},
	[{"FAR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Apply Action",			   'M', {'X', 'X', 'X', 'X'}},
	 {"Forwarding Parameters",		   'C', {'X', 'X', 'X', 'X'},
	  [{"Destination Interface",		   'M', {'X', 'X', 'X', 'X'}},
	   {"Network Instance",			   'O', {'X', 'X', 'X', 'X'}},
	   {"Redirect Information",		   'C', {'-', 'X', 'X', 'X'}},
	   {"Outer Header Creation",		   'C', {'X', 'X', '-', 'X'}},
	   {"Transport Level Marking",		   'C', {'X', 'X', '-', 'X'}},
	   {"Forwarding Policy",		   'C', {'-', 'X', 'X', 'X'}},
	   {"Header Enrichment",		   'O', {'-', 'X', 'X', 'X'}},
	   {"Traffic Endpoint ID",		   'C', {'X', 'X', '-', 'X'}},
	   {"Proxying",				   'C', {'-', '-', '-', 'X'}},
	   {"TGPP Interface Type",		   'O', {'X', 'X', '-', 'X'}},
	   {"Data Network Access Identifier",	   'C', {'-', '-', '-', '-'}},
	   {"BBF Apply Action",			   'O', {'-', 'X', '-', 'X'}},
	   {"BBF NAT Port Block",		   'O', {'-', 'X', '-', 'X'}}]},
	 {"Duplicating Parameters",		   'C', {'X', 'X', '-', 'X'},
	  [{"Destination Interface",		   'M', {'X', 'X', '-', 'X'}},
	   {"Outer Header Creation",		   'C', {'X', 'X', '-', 'X'}},
	   {"Transport Level Marking",		   'C', {'X', 'X', '-', 'X'}},
	   {"Forwarding Policy",		   'C', {'X', 'X', '-', 'X'}}]},
	 {"BAR ID",				   'O', {'X', '-', '-', 'X'}},
	 {"Redundant Transmission Parameters",	   'C', {'-', '-', '-', 'X'},
	  [{"F-TEID",				   'M', {'-', '-', '-', 'X'}},
	   {"Network Instance",			   'C', {'-', '-', '-', 'X'}}]},
	 {"TP IPFIX Policy",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"Create URR",				   'C', {'X', 'X', 'X', 'X'},
	[{"URR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Measurement Method",			   'M', {'X', 'X', 'X', 'X'}},
	 {"Reporting Triggers",			   'M', {'X', 'X', 'X', 'X'}},
	 {"Measurement Period",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Threshold",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Quota",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Event Threshold",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Event Quota",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Time Threshold",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Time Quota",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Quota Holding Time",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Dropped DL Traffic Threshold",	   'C', {'X', '-', '-', 'X'}},
	 {"Quota Validity Time",		   'C', {'-', 'X', '-', 'X'}},
	 {"Monitoring Time",			   'O', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Volume Threshold",	   'O', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Time Threshold",		   'O', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Volume Quota",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Time Quota",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Event Threshold",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Event Quota",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Inactivity Detection Time",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Linked URR ID",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Measurement Information",		   'C', {'X', 'X', 'X', 'X'}},
	 {"Time Quota Mechanism",		   'C', {'-', 'X', '-', '-'}},
	 {"Aggregated URRs",			   'C', {'-', 'X', '-', ' '},
	  [{"Aggregated URR ID",		   'M', {'-', 'X', '-', '-'}},
	   {"Multiplier",			   'M', {'-', 'X', '-', '-'}}]},
	 {"FAR ID",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Ethernet Inactivity Timer",		   'C', {'-', '-', '-', 'X'}},
	 {"Additional Monitoring Time",		   'O', {'X', 'X', 'X', 'X'},
	  [{"Monitoring Time",			   'M', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Volume Threshold",	   'O', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Time Threshold",	   'O', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Volume Quota",		   'O', {'-', 'X', 'X', 'X'}},
	   {"Subsequent Time Quota",		   'O', {'-', 'X', 'X', 'X'}},
	   {"Event Threshold",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Event Quota",			   'O', {'-', 'X', 'X', 'X'}}]},
	 {"Number of Reports",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"Create QER",				   'C', {'-', 'X', 'X', 'X'},
	[{"QER ID",				   'M', {'-', 'X', 'X', 'X'}},
	 {"QER Correlation ID",			   'C', {'-', 'X', '-', 'X'}},
	 {"Gate Status",			   'M', {'-', 'X', 'X', 'X'}},
	 {"MBR",				   'C', {'-', 'X', 'X', 'X'}},
	 {"GBR",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Packet Rate",			   'C', {'-', 'X', '-', '-'}},
	 {"Packet Rate Status",			   'C', {'-', 'X', '-', 'X'}},
	 {"DL Flow Level Marking",		   'C', {'-', 'X', 'X', '-'}},
	 {"QFI",				   'C', {'-', '-', '-', 'X'}},
	 {"RQI",				   'C', {'-', '-', '-', 'X'}},
	 {"Paging Policy Indicator",		   'C', {'-', '-', '-', 'X'}},
	 {"Averaging Window",			   'O', {'-', '-', '-', 'X'}},
	 {"QER Control Indications",		   'C', {'-', 'X', '-', 'X'}}]},
       {"Create BAR",				   'O', {'X', '-', '-', 'X'},
	[{"BAR ID",				   'M', {'X', '-', '-', 'X'}},
	 {"Downlink Data Notification Delay",	   'C', {'X', '-', '-', '-'}},
	 {"Suggested Buffering Packets Count",	   'C', {' ', 'X', 'X', 'X'}},
	 {"MT-EDT Control Information",		   'O', {'X', '-', '-', '-'}}]},
       {"Create Traffic Endpoint",		   'C', {'X', 'X', 'X', 'X'},
	[{"Traffic Endpoint ID",		   'M', {'X', 'X', 'X', 'X'}},
	 {"F-TEID",				   'O', {'X', 'X', '-', 'X'}},
	 {"Network Instance",			   'O', {'X', 'X', 'X', 'X'}},
	 {"Redundant Transmission Parameters",	   'O', {'-', '-', '-', 'X'},
	  [{"F-TEID",				   'M', {'-', '-', '-', 'X'}},
	   {"Network Instance",			   'C', {'-', '-', '-', 'X'}}]},
	 {"UE IP address",			   'O', {'-', 'X', 'X', 'X'}},
	 {"Ethernet PDU Session Information",	   'O', {'-', '-', '-', 'X'}},
	 {"Framed-Route",			   'O', {'-', 'X', '-', 'X'}},
	 {"Framed-Routing",			   'O', {'-', 'X', '-', 'X'}},
	 {"Framed-IPv6-Route",			   'O', {'-', 'X', '-', 'X'}},
	 {"QFI",				   'C', {'-', '-', '-', 'X'}},
	 {"TGPP Interface Type",		   'O', {'X', 'X', '-', 'X'}}]},
       {"PDN Type",				   'C', {'X', 'X', '-', 'X'}},
       {"FQ-CSID",				   'C', {'-', 'X', '-', '-'}},
       {"User Plane Inactivity Timer",		   'O', {'-', 'X', 'X', 'X'}},
       {"User ID",				   'O', {'X', 'X', 'X', 'X'}},
       {"Trace Information",			   'O', {'X', 'X', 'X', 'X'}},
       {"APN/DNN",				   'O', {'X', 'X', '-', 'X'}},
       {"Create MAR",				   'C', {'-', '-', '-', 'X'},
	[{"MAR ID",					   'M', {'-', '-', '-', 'X'}},
	 {"Steering Functionality",			   'M', {'-', '-', '-', 'X'}},
	 {"Steering Mode",				   'M', {'-', '-', '-', 'X'}},
	 {"TGPP Access Forwarding Action Information",	   'C', {'-', '-', '-', 'X'},
	  [{"FAR ID",					   'M', {'-', '-', '-', 'X'}},
	   {"Weight",					   'C', {'-', '-', '-', 'X'}},
	   {"Priority",					   'C', {'-', '-', '-', 'X'}},
	   {"URR ID",					   'C', {'-', '-', '-', 'X'}}]},
	 {"Non-TGPP Access Forwarding Action Information",	   'C', {'-', '-', '-', 'X'},
	  [{"FAR ID",					   'M', {'-', '-', '-', 'X'}},
	   {"Weight",					   'C', {'-', '-', '-', 'X'}},
	   {"Priority",					   'C', {'-', '-', '-', 'X'}},
	   {"URR ID",					   'C', {'-', '-', '-', 'X'}}]}]},
       {"PFCPSEReq-Flags",			   'C', {'X', 'X', '-', 'X'}},
       {"Create Bridge Info for TSC",		   'C', {'-', '-', '-', 'X'}},
       {"Create SRR",				   'O', {'-', '-', '-', 'X'},
	[{"SRR ID",						   'M', {'-', '-', '-', 'X'}},
	 {"Access Availability Control Information",		   'C', {'-', '-', '-', 'X'},
	  [{"Requested Access Availability Information",	   'M', {'-', '-', '-', 'X'}}]},
	 {"QoS Monitoring per QoS flow Control Information",	   'C', {'-', '-', '-', 'X'},
	  [{"QFI",						   'M', {'-', '-', '-', 'X'}},
	   {"Requested QoS Monitoring",				   'M', {'-', '-', '-', 'X'}},
	   {"Reporting Frequency",				   'M', {'-', '-', '-', 'X'}},
	   {"Packet Delay Thresholds",				   'C', {'-', '-', '-', 'X'}},
	   {"Minimum Wait Time",				   'C', {'-', '-', '-', 'X'}},
	   {"Measurement Period",				   'C', {'-', '-', '-', 'X'}}]}
	]},
       {"Provide ATSSS Control Information",	   'C', {'-', '-', '-', 'X'},
	[{"MPTCP Control Information",		   'C', {'-', '-', '-', 'X'}},
	 {"ATSSS-LL Control Information",	   'C', {'-', '-', '-', 'X'}},
	 {"PMF Control Information",		   'C', {'-', '-', '-', 'X'}}]},
       {"Recovery Time Stamp",			   'O', {'X', 'X', 'X', 'X'}},
       {"S-NSSAI",				   'O', {'-', '-', '-', 'X'}},
       {"Provide RDS configuration information",   'O', {'-', 'X', '-', 'X'}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {51, "Session Establishment Response",		{'X', 'X', 'X', 'X'},
      [{"Node ID",				   'M', {'X', 'X', 'X', 'X'}},
       {"PFCP Cause",				   'M', {'X', 'X', 'X', 'X'}},
       {"Offending IE",				   'C', {'X', 'X', 'X', 'X'}},
       {"F-SEID",				   'C', {'X', 'X', 'X', 'X'}},
       {"Created PDR",				   'C', {'X', 'X', '-', 'X'},
	[{"PDR ID",				   'M', {'X', 'X', '-', 'X'}},
	 {"F-TEID",				   'C', {'X', 'X', '-', 'X'}},
	 {"F-TEID",				   'C', {'-', '-', '-', 'X'}},
	 {"UE IP Address",			   'C', {'-', 'X', '-', 'X'}}]},
       {"Load Control Information",		   'O', {'X', 'X', 'X', 'X'},
	[{"Sequence Number",			   'M', {'X', 'X', 'X', 'X'}},
	 {"Metric",				   'M', {'X', 'X', 'X', 'X'}}]},
       {"Overload Control Information",		   'O', {'X', 'X', 'X', 'X'},
	[{"Sequence Number",			   'M', {'X', 'X', 'X', 'X'}},
	 {"Metric",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Timer",				   'M', {'X', 'X', 'X', 'X'}},
	 {"OCI Flags",				   'C', {'X', 'X', 'X', 'X'}}]},
       {"FQ-CSID",				   'C', {'X', '-', '-', '-'}},
       {"FQ-CSID",				   'C', {'-', 'X', '-', '-'}},
       {"Failed Rule ID",			   'C', {'X', 'X', 'X', 'X'}},
       {"Created Traffic Endpoint",		   'C', {'X', 'X', '-', 'X'},
	[{"Traffic Endpoint ID",		   'M', {'X', 'X', '-', 'X'}},
	 {"F-TEID",				   'C', {'X', 'X', '-', 'X'}},
	 {"F-TEID",				   'C', {'-', '-', '-', 'X'}},
	 {"UE IP Address",			   'C', {'-', 'X', '-', 'X'}}]},
       {"Created Bridge Info for TSC",		   'C', {'-', '-', '-', 'X'},
	[{"DS-TT Port Number",			   'C', {'-', '-', '-', 'X'}},
	 {"NW-TT Port Number",			   'C', {'-', '-', '-', 'X'}},
	 {"TSN Bridge ID",			   'C', {'-', '-', '-', 'X'}}]},
       {"ATSSS Control Parameters",		   'C', {'-', '-', '-', 'X'},
	[{"MPTCP Parameters",			   'C', {'-', '-', '-', 'X'},
	  [{"MPTCP Address Information",	   'M', {'-', '-', '-', 'X'}},
	   {"UE Link-Specific IP Address",	   'M', {'-', '-', '-', 'X'}}]},
	 {"ATSSS-LL Parameters",		   'C', {'-', '-', '-', 'X'},
	  [{"ATSSS-LL Information",		   'M', {'-', '-', '-', 'X'}}]},
	 {"PMF Parameters",			   'C', {'-', '-', '-', 'X'},
	  [{"PMF Address Information",		   'M', {'-', '-', '-', 'X'}}]}]},
       {"RDS configuration information",	   'O', {'-', 'X', '-', 'X'}},
       {"TP Build Identifier",			   'O', {'X', 'X', 'X', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"TP Created NAT Binding",		   'C', {'-', 'X', 'X', 'X'},
	[{"BBF NAT Outside Address",		   'C', {'-', 'X', 'X', 'X'}},
	 {"BBF NAT Port Block",			   'C', {'-', 'X', 'X', 'X'}}]}
      ]},
     {52, "Session Modification Request",		{'X', 'X', 'X', 'X'},
      [{"F-SEID",				   'C', {'X', 'X', 'X', 'X'}},
       {"Remove PDR",				   'C', {'X', 'X', 'X', 'X'},
	[{"PDR ID",				   'M', {'X', 'X', 'X', 'X'}}]},
       {"Remove FAR",				   'C', {'X', 'X', 'X', 'X'},
	[{"FAR ID",				   'M', {'X', 'X', 'X', 'X'}}]},
       {"Remove URR",				   'C', {'X', 'X', 'X', 'X'},
	[{"URR ID",				   'M', {'X', 'X', 'X', 'X'}}]},
       {"Remove QER",				   'C', {'-', 'X', 'X', 'X'},
	[{"QER ID",				   'M', {'X', 'X', 'X', 'X'}}]},
       {"Remove BAR",				   'C', {'X', '-', '-', 'X'},
	[{"BAR ID",				   'M', {'X', 'X', 'X', 'X'}}]},
       {"Remove Traffic Endpoint",		   'C', {'X', 'X', 'X', 'X'},
	[{"Traffic Endpoint ID",		   'M', {'X', 'X', 'X', 'X'}}]},
       {"Create PDR",				   'C', {'X', 'X', 'X', 'X'},
	[{"PDR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Precedence",				   'M', {'-', 'X', 'X', 'X'}},
	 {"PDI",				   'M', {'X', 'X', 'X', 'X'},
	  [{"Source Interface",			   'M', {'X', 'X', 'X', 'X'}},
	   {"F-TEID",				   'O', {'X', 'X', '-', 'X'}},
	   {"Network Instance",			   'O', {'X', 'X', 'X', 'X'}},
	   {"Redundant Transmission Parameters",   'O', {'-', '-', '-', 'X'},
	    [{"F-TEID",				   'M', {'-', '-', '-', 'X'}},
	     {"Network Instance",		   'O', {'-', '-', '-', 'X'}}]},
	   {"UE IP address",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Traffic Endpoint ID",		   'C', {'X', 'X', 'X', 'X'}},
	   {"SDF Filter",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Application ID",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Ethernet PDU Session Information",	   'O', {'-', '-', '-', 'X'}},
	   {"Ethernet Packet Filter",		   'O', {'-', '-', '-', 'X'},
	    [{"Ethernet Filter ID",		   'C', {'-', '-', '-', 'X'}},
	     {"Ethernet Filter Properties",	   'C', {'-', '-', '-', 'X'}},
	     {"MAC address",			   'O', {'-', '-', '-', 'X'}},
	     {"Ethertype",			   'O', {'-', '-', '-', 'X'}},
	     {"C-TAG",				   'O', {'-', '-', '-', 'X'}},
	     {"S-TAG",				   'O', {'-', '-', '-', 'X'}},
	     {"SDF Filter",			   'O', {'-', '-', '-', 'X'}}]},
	   {"QFI",				   'O', {'-', '-', '-', 'X'}},
	   {"Framed-Route",			   'O', {'-', 'X', '-', 'X'}},
	   {"Framed-Routing",			   'O', {'-', 'X', '-', 'X'}},
	   {"Framed-IPv6-Route",		   'O', {'-', 'X', '-', 'X'}},
	   {"TGPP Interface Type",		   'O', {'X', 'X', '-', 'X'}},
	   {"IP Multicast Addressing Info",	   'O', {'-', '-', '-', 'X'},
	    [{"IP Multicast Address",		   'M', {'-', '-', '-', 'X'}},
	     {"Source IP Address",		   'O', {'-', '-', '-', 'X'}}]}]},
	 {"Outer Header Removal",		   'C', {'X', 'X', '-', 'X'}},
	 {"FAR ID",				   'C', {'X', 'X', 'X', 'X'}},
	 {"URR ID",				   'C', {'X', 'X', 'X', 'X'}},
	 {"QER ID",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Activate Predefined Rules",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Activation Time",			   'O', {'-', 'X', 'X', 'X'}},
	 {"Deactivation Time",			   'O', {'-', 'X', 'X', 'X'}},
	 {"MAR ID",				   'C', {'-', '-', '-', 'X'}},
	 {"Packet Replication and Detection Carry-On Information",
						   'C', {'-', '-', '-', 'X'}},
	 {"IP Multicast Addressing Info",	   'O', {'-', '-', '-', 'X'},
	  [{"IP Multicast Address",		   'M', {'-', '-', '-', 'X'}},
	   {"Source IP Address",		   'O', {'-', '-', '-', 'X'}}]},
	 {"UE IP Address Pool Identity",	   'O', {'-', 'X', '-', 'X'}}]},
       {"Create FAR",				   'C', {'X', 'X', 'X', 'X'},
	[{"FAR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Apply Action",			   'M', {'X', 'X', 'X', 'X'}},
	 {"Forwarding Parameters",		   'C', {'X', 'X', 'X', 'X'},
	  [{"Destination Interface",		   'M', {'X', 'X', 'X', 'X'}},
	   {"Network Instance",			   'O', {'X', 'X', 'X', 'X'}},
	   {"Redirect Information",		   'C', {'-', 'X', 'X', 'X'}},
	   {"Outer Header Creation",		   'C', {'X', 'X', '-', 'X'}},
	   {"Transport Level Marking",		   'C', {'X', 'X', '-', 'X'}},
	   {"Forwarding Policy",		   'C', {'-', 'X', 'X', 'X'}},
	   {"Header Enrichment",		   'O', {'-', 'X', 'X', 'X'}},
	   {"Traffic Endpoint ID",		   'C', {'X', 'X', '-', 'X'}},
	   {"Proxying",				   'C', {'-', '-', '-', 'X'}},
	   {"TGPP Interface Type",		   'O', {'X', 'X', '-', 'X'}},
	   {"Data Network Access Identifier",	   'C', {'-', '-', '-', '-'}},
	   {"BBF Apply Action",			   'O', {'-', 'X', '-', 'X'}},
	   {"BBF NAT Port Block",		   'O', {'-', 'X', '-', 'X'}}]},
	 {"Duplicating Parameters",		   'C', {'X', 'X', '-', 'X'},
	  [{"Destination Interface",		   'M', {'X', 'X', '-', 'X'}},
	   {"Outer Header Creation",		   'C', {'X', 'X', '-', 'X'}},
	   {"Transport Level Marking",		   'C', {'X', 'X', '-', 'X'}},
	   {"Forwarding Policy",		   'C', {'X', 'X', '-', 'X'}}]},
	 {"BAR ID",				   'O', {'X', '-', '-', 'X'}},
	 {"Redundant Transmission Parameters",	   'C', {'-', '-', '-', 'X'},
	  [{"F-TEID",				   'M', {'-', '-', '-', 'X'}},
	   {"Network Instance",			   'C', {'-', '-', '-', 'X'}}]}]},
       {"Create URR",				   'C', {'X', 'X', 'X', 'X'},
	[{"URR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Measurement Method",			   'M', {'X', 'X', 'X', 'X'}},
	 {"Reporting Triggers",			   'M', {'X', 'X', 'X', 'X'}},
	 {"Measurement Period",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Threshold",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Quota",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Event Threshold",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Event Quota",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Time Threshold",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Time Quota",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Quota Holding Time",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Dropped DL Traffic Threshold",	   'C', {'X', '-', '-', 'X'}},
	 {"Quota Validity Time",		   'C', {'-', 'X', '-', 'X'}},
	 {"Monitoring Time",			   'O', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Volume Threshold",	   'O', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Time Threshold",		   'O', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Volume Quota",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Time Quota",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Event Threshold",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Event Quota",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Inactivity Detection Time",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Linked URR ID",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Measurement Information",		   'C', {'X', 'X', 'X', 'X'}},
	 {"Time Quota Mechanism",		   'C', {'-', 'X', '-', '-'}},
	 {"Aggregated URRs",			   'C', {'-', 'X', '-', ' '},
	  [{"Aggregated URR ID",		   'M', {'-', 'X', '-', '-'}},
	   {"Multiplier",			   'M', {'-', 'X', '-', '-'}}]},
	 {"FAR ID",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Ethernet Inactivity Timer",		   'C', {'-', '-', '-', 'X'}},
	 {"Additional Monitoring Time",		   'O', {'X', 'X', 'X', 'X'},
	  [{"Monitoring Time",			   'M', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Volume Threshold",	   'O', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Time Threshold",	   'O', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Volume Quota",		   'O', {'-', 'X', 'X', 'X'}},
	   {"Subsequent Time Quota",		   'O', {'-', 'X', 'X', 'X'}},
	   {"Event Threshold",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Event Quota",			   'O', {'-', 'X', 'X', 'X'}}]},
	 {"Number of Reports",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"Create QER",				   'C', {'-', 'X', 'X', 'X'},
	[{"QER ID",				   'M', {'-', 'X', 'X', 'X'}},
	 {"QER Correlation ID",			   'C', {'-', 'X', '-', 'X'}},
	 {"Gate Status",			   'M', {'-', 'X', 'X', 'X'}},
	 {"MBR",				   'C', {'-', 'X', 'X', 'X'}},
	 {"GBR",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Packet Rate",			   'C', {'-', 'X', '-', '-'}},
	 {"Packet Rate Status",			   'C', {'-', 'X', '-', 'X'}},
	 {"DL Flow Level Marking",		   'C', {'-', 'X', 'X', '-'}},
	 {"QFI",				   'C', {'-', '-', '-', 'X'}},
	 {"RQI",				   'C', {'-', '-', '-', 'X'}},
	 {"Paging Policy Indicator",		   'C', {'-', '-', '-', 'X'}},
	 {"Averaging Window",			   'O', {'-', '-', '-', 'X'}},
	 {"QER Control Indications",		   'C', {'-', 'X', '-', 'X'}}]},
       {"Create BAR",				   'C', {'X', '-', '-', 'X'},
	[{"BAR ID",				   'M', {'X', '-', '-', 'X'}},
	 {"Downlink Data Notification Delay",	   'C', {'X', '-', '-', '-'}},
	 {"Suggested Buffering Packets Count",	   'C', {' ', 'X', 'X', 'X'}},
	 {"MT-EDT Control Information",		   'O', {'X', '-', '-', '-'}}]},
       {"Create Traffic Endpoint",		   'C', {'X', 'X', 'X', 'X'},
	[{"Traffic Endpoint ID",		   'M', {'X', 'X', 'X', 'X'}},
	 {"F-TEID",				   'O', {'X', 'X', '-', 'X'}},
	 {"Network Instance",			   'O', {'X', 'X', 'X', 'X'}},
	 {"Redundant Transmission Parameters",	   'O', {'-', '-', '-', 'X'},
	  [{"F-TEID",				   'M', {'-', '-', '-', 'X'}},
	   {"Network Instance",			   'C', {'-', '-', '-', 'X'}}]},
	 {"UE IP address",			   'O', {'-', 'X', 'X', 'X'}},
	 {"Ethernet PDU Session Information",	   'O', {'-', '-', '-', 'X'}},
	 {"Framed-Route",			   'O', {'-', 'X', '-', 'X'}},
	 {"Framed-Routing",			   'O', {'-', 'X', '-', 'X'}},
	 {"Framed-IPv6-Route",			   'O', {'-', 'X', '-', 'X'}},
	 {"QFI",				   'C', {'-', '-', '-', 'X'}}]},
       {"Update PDR",				   'C', {'X', 'X', 'X', 'X'},
	[{"PDR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Outer Header Removal",		   'C', {'X', 'X', '-', 'X'}},
	 {"Precedence",				   'C', {'-', 'X', 'X', 'X'}},
	 {"PDI",				   'C', {'X', 'X', 'X', 'X'},
	  [{"Source Interface",			   'M', {'X', 'X', 'X', 'X'}},
	   {"F-TEID",				   'O', {'X', 'X', '-', 'X'}},
	   {"Network Instance",			   'O', {'X', 'X', 'X', 'X'}},
	   {"UE IP address",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Traffic Endpoint ID",		   'C', {'X', 'X', 'X', 'X'}},
	   {"SDF Filter",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Application ID",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Ethernet PDU Session Information",	   'O', {'-', '-', '-', 'X'}},
	   {"Ethernet Packet Filter",		   'O', {'-', '-', '-', 'X'},
	    [{"Ethernet Filter ID",		   'C', {'-', '-', '-', 'X'}},
	     {"Ethernet Filter Properties",	   'C', {'-', '-', '-', 'X'}},
	     {"MAC address",			   'O', {'-', '-', '-', 'X'}},
	     {"Ethertype",			   'O', {'-', '-', '-', 'X'}},
	     {"C-TAG",				   'O', {'-', '-', '-', 'X'}},
	     {"S-TAG",				   'O', {'-', '-', '-', 'X'}},
	     {"SDF Filter",			   'O', {'-', '-', '-', 'X'}}]},
	   {"QFI",				   'O', {'-', '-', '-', 'X'}},
	   {"Framed-Route",			   'O', {'-', 'X', '-', 'X'}},
	   {"Framed-Routing",			   'O', {'-', 'X', '-', 'X'}},
	   {"Framed-IPv6-Route",		   'O', {'-', 'X', '-', 'X'}}]},
	 {"FAR ID",				   'C', {'X', 'X', 'X', 'X'}},
	 {"URR ID",				   'C', {'X', 'X', 'X', 'X'}},
	 {"QER ID",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Activate Predefined Rules",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Deactivate Predefined Rules",	   'C', {'-', 'X', 'X', 'X'}},
	 {"Activation Time",			   'O', {'-', 'X', 'X', 'X'}},
	 {"Deactivation Time",			   'O', {'-', 'X', 'X', 'X'}},
	 {"IP Multicast Addressing Info",	   'O', {'-', '-', '-', 'X'},
	  [{"IP Multicast Address",		   'M', {'-', '-', '-', 'X'}},
	   {"Source IP Address",		   'O', {'-', '-', '-', 'X'}}]}]},
       {"Update FAR",				   'C', {'X', 'X', 'X', 'X'},
	[{"FAR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Apply Action",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Update Forwarding Parameters",	   'C', {'X', 'X', 'X', 'X'},
	  [{"Destination Interface",		   'C', {'X', 'X', 'X', 'X'}},
	   {"Network Instance",			   'C', {'X', 'X', 'X', 'X'}},
	   {"Redirect Information",		   'C', {'-', 'X', 'X', 'X'}},
	   {"Outer Header Creation",		   'C', {'X', 'X', '-', 'X'}},
	   {"Transport Level Marking",		   'C', {'X', 'X', '-', 'X'}},
	   {"Forwarding Policy",		   'C', {'-', 'X', 'X', 'X'}},
	   {"Header Enrichment",		   'C', {'-', 'X', 'X', 'X'}},
	   {"SxSMReq-Flags",			   'C', {'X', 'X', '-', 'X'}},
	   {"Traffic Endpoint ID",		   'C', {'X', 'X', '-', 'X'}},
	   {"TGPP Interface Type",		   'C', {'X', 'X', '-', 'X'}},
	   {"Data Network Access Identifier",	   'C', {'-', '-', '-', '-'}},
	   {"BBF Apply Action",			   'O', {'-', 'X', '-', 'X'}},
	   {"BBF NAT Port Block",		   'O', {'-', 'X', '-', 'X'}}]},
	 {"Update Duplicating Parameters",	   'C', {'X', 'X', '-', 'X'},
	  [{"Destination Interface",		   'C', {'X', 'X', '-', 'X'}},
	   {"Outer Header Creation",		   'C', {'X', 'X', '-', 'X'}},
	   {"Transport Level Marking",		   'C', {'X', 'X', '-', 'X'}},
	   {"Forwarding Policy",		   'C', {'-', 'X', '-', 'X'}}]},
	 {"Redundant Transmission Parameters",	   'C', {'-', '-', '-', 'X'},
	    [{"F-TEID",				   'M', {'-', '-', '-', 'X'}},
	     {"Network Instance",		   'O', {'-', '-', '-', 'X'}}]},
	 {"BAR ID",				   'C', {'X', '-', '-', 'X'}},
	 {"TP IPFIX Policy",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"Update URR",				   'C', {'X', 'X', 'X', 'X'},
	[{"URR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Measurement Method",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Reporting Triggers",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Measurement Period",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Threshold",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Quota",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Time Threshold",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Time Quota",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Event Threshold",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Event Quota",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Quota Holding Time",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Dropped DL Traffic Threshold",	   'C', {'X', '-', '-', 'X'}},
	 {"Quota Validity Time",		   'C', {'-', 'X', '-', 'X'}},
	 {"Monitoring Time",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Volume Threshold",	   'C', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Time Threshold",		   'C', {'X', 'X', 'X', 'X'}},
	 {"Subsequent Volume Quota",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Time Quota",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Event Threshold",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Subsequent Event Quota",		   'O', {'-', 'X', 'X', 'X'}},
	 {"Inactivity Detection Time",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Linked URR ID",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Measurement Information",		   'C', {'-', 'X', '-', 'X'}},
	 {"Time Quota Mechanism",		   'C', {'-', 'X', '-', '-'}},
	 {"Aggregated URRs",			   'C', {'-', 'X', '-', ' '}},
	 {"FAR ID",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Ethernet Inactivity Timer",		   'C', {'-', '-', '-', 'X'}},
	 {"Additional Monitoring Time",		   'O', {'X', 'X', 'X', 'X'},
	  [{"Monitoring Time",			   'M', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Volume Threshold",	   'O', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Time Threshold",	   'O', {'X', 'X', 'X', 'X'}},
	   {"Subsequent Volume Quota",		   'O', {'-', 'X', 'X', 'X'}},
	   {"Subsequent Time Quota",		   'O', {'-', 'X', 'X', 'X'}},
	   {"Event Threshold",			   'O', {'-', 'X', 'X', 'X'}},
	   {"Event Quota",			   'O', {'-', 'X', 'X', 'X'}}]},
	 {"Number of Reports",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"Update QER",				   'C', {'-', 'X', 'X', 'X'},
	[{"QER ID",				   'M', {'-', 'X', 'X', 'X'}},
	 {"QER Correlation ID",			   'C', {'-', 'X', '-', 'X'}},
	 {"Gate Status",			   'C', {'-', 'X', 'X', 'X'}},
	 {"MBR",				   'C', {'-', 'X', 'X', 'X'}},
	 {"GBR",				   'C', {'-', 'X', 'X', 'X'}},
	 {"Packet Rate",			   'C', {'-', 'X', '-', ' '}},
	 {"DL Flow Level Marking",		   'C', {'-', 'X', 'X', '-'}},
	 {"QFI",				   'C', {'-', '-', '-', 'X'}},
	 {"RQI",				   'C', {'-', '-', '-', 'X'}},
	 {"Paging Policy Indicator",		   'C', {'-', '-', '-', 'X'}},
	 {"Averaging Window",			   'O', {'-', '-', '-', 'X'}},
	 {"QER Control Indications",		   'C', {'-', 'X', '-', 'X'}}]},
       {"Update BAR",				   'C', {'X', '-', '-', 'X'},
	[{"BAR ID",				   'M', {'X', '-', '-', 'X'}},
	 {"Downlink Data Notification Delay",	   'C', {'X', '-', '-', 'X'}},
	 {"Suggested Buffering Packets Count",	   'C', {' ', 'X', 'X', 'X'}},
	 {"MT-EDT Control Information",		   'C', {'X', '-', '-', '-'}}]},
       {"Update Traffic Endpoint",		   'C', {'X', 'X', 'X', 'X'},
	[{"Traffic Endpoint ID",		   'M', {'X', 'X', 'X', 'X'}},
	 {"F-TEID",				   'C', {'X', '-', '-', 'X'}},
	 {"Network Instance",			   'O', {'X', 'X', 'X', 'X'}},
	 {"Redundant Transmission Parameters",	   'O', {'-', '-', '-', 'X'},
	  [{"F-TEID",				   'M', {'-', '-', '-', 'X'}},
	   {"Network Instance",			   'C', {'-', '-', '-', 'X'}}]},
	 {"UE IP address",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Framed-Route",			   'C', {'-', 'X', '-', 'X'}},
	 {"Framed-Routing",			   'C', {'-', 'X', '-', 'X'}},
	 {"Framed-IPv6-Route",			   'C', {'-', 'X', '-', 'X'}},
	 {"QFI",				   'C', {'-', '-', '-', 'X'}},
	 {"TGPP Interface Type",		   'C', {'X', 'X', '-', 'X'}}]},
       {"SxSMReq-Flags",			   'C', {'X', 'X', 'X', 'X'}},
       {"Query URR",				   'C', {'X', 'X', 'X', 'X'},
	[{"URR ID",				   'M', {'X', 'X', 'X', 'X'}}]},
       {"FQ-CSID",				   'C', {'X', 'X', '-', '-'}},
       {"User Plane Inactivity Timer",		   'C', {'-', 'X', 'X', 'X'}},
       {"Query URR Reference",			   'O', {'X', 'X', 'X', 'X'}},
       {"Trace Information",			   'O', {'X', 'X', 'X', 'X'}},
       {"Remove MAR",				   'C', {'-', '-', '-', 'X'},
	[{"MAR ID",				   'M', {'-', '-', '-', 'X'}}]},
       {"Update MAR",				   'C', {'-', '-', '-', 'X'},
	[{"MAR ID",					   'M', {'-', '-', '-', 'X'}},
	 {"Steering Functionality",			   'C', {'-', '-', '-', 'X'}},
	 {"Steering Mode",				   'C', {'-', '-', '-', 'X'}},
	 {"Update TGPP Access Forwarding Action Information",	   'C', {'-', '-', '-', 'X'},
	  [{"FAR ID",					   'C', {'-', '-', '-', 'X'}},
	   {"Weight",					   'C', {'-', '-', '-', 'X'}},
	   {"Priority",					   'C', {'-', '-', '-', 'X'}},
	   {"URR ID",					   'C', {'-', '-', '-', 'X'}}]},
	 {"Update Non-TGPP Access Forwarding Action Information",  'C', {'-', '-', '-', 'X'},
	  [{"FAR ID",					   'C', {'-', '-', '-', 'X'}},
	   {"Weight",					   'C', {'-', '-', '-', 'X'}},
	   {"Priority",					   'C', {'-', '-', '-', 'X'}},
	   {"URR ID",					   'C', {'-', '-', '-', 'X'}}]},
	 {"TGPP Access Forwarding Action Information",	   'C', {'-', '-', '-', 'X'},
	  [{"FAR ID",					   'M', {'-', '-', '-', 'X'}},
	   {"Weight",					   'C', {'-', '-', '-', 'X'}},
	   {"Priority",					   'C', {'-', '-', '-', 'X'}},
	   {"URR ID",					   'C', {'-', '-', '-', 'X'}}]},
	 {"Non-TGPP Access Forwarding Action Information",	   'C', {'-', '-', '-', 'X'},
	  [{"FAR ID",					   'M', {'-', '-', '-', 'X'}},
	   {"Weight",					   'C', {'-', '-', '-', 'X'}},
	   {"Priority",					   'C', {'-', '-', '-', 'X'}},
	   {"URR ID",					   'C', {'-', '-', '-', 'X'}}]}]},
       {"Create MAR",				   'C', {'-', '-', '-', 'X'},
	[{"MAR ID",					   'M', {'-', '-', '-', 'X'}},
	 {"Steering Functionality",			   'M', {'-', '-', '-', 'X'}},
	 {"Steering Mode",				   'M', {'-', '-', '-', 'X'}},
	 {"TGPP Access Forwarding Action Information",	   'C', {'-', '-', '-', 'X'},
	  [{"FAR ID",					   'M', {'-', '-', '-', 'X'}},
	   {"Weight",					   'C', {'-', '-', '-', 'X'}},
	   {"Priority",					   'C', {'-', '-', '-', 'X'}},
	   {"URR ID",					   'C', {'-', '-', '-', 'X'}}]},
	 {"Non-TGPP Access Forwarding Action Information",	   'C', {'-', '-', '-', 'X'},
	  [{"FAR ID",					   'M', {'-', '-', '-', 'X'}},
	   {"Weight",					   'C', {'-', '-', '-', 'X'}},
	   {"Priority",					   'C', {'-', '-', '-', 'X'}},
	   {"URR ID",					   'C', {'-', '-', '-', 'X'}}]}]},
       {"Node ID",				   'C', {'-', '-', '-', 'X'}},
       {"Port Management Information for TSC",	   'C', {'-', '-', '-', 'X'},
	[{"Port Management Information ContainerD",'M', {'-', '-', '-', 'X'}}]},
       {"Remove SRR",				   'C', {'-', '-', '-', 'X'},
	[{"SRR ID",				   'M', {'-', '-', '-', 'X'}}]},
       {"Create SRR",				   'C', {'-', '-', '-', 'X'},
	[{"SRR ID",						   'M', {'-', '-', '-', 'X'}},
	 {"Access Availability Control Information",		   'C', {'-', '-', '-', 'X'},
	  [{"Requested Access Availability Information",	   'M', {'-', '-', '-', 'X'}}]},
	 {"QoS Monitoring per QoS flow Control Information",	   'C', {'-', '-', '-', 'X'},
	  [{"QFI",						   'M', {'-', '-', '-', 'X'}},
	   {"Requested QoS Monitoring",			   'M', {'-', '-', '-', 'X'}},
	   {"Reporting Frequency",				   'M', {'-', '-', '-', 'X'}},
	   {"Packet Delay Thresholds",			   'C', {'-', '-', '-', 'X'}},
	   {"Minimum Wait Time",				   'C', {'-', '-', '-', 'X'}},
	   {"Measurement Period",				   'C', {'-', '-', '-', 'X'}}]}
	]},
       {"Update SRR",				   'C', {'-', '-', '-', 'X'},
	[{"SRR ID",						   'M', {'-', '-', '-', 'X'}},
	 {"Access Availability Control Information",		   'C', {'-', '-', '-', 'X'},
	  [{"Requested Access Availability Information",	   'M', {'-', '-', '-', 'X'}}]},
	 {"QoS Monitoring per QoS flow Control Information",	   'C', {'-', '-', '-', 'X'},
	  [{"QFI",						   'M', {'-', '-', '-', 'X'}},
	   {"Requested QoS Monitoring",			   'M', {'-', '-', '-', 'X'}},
	   {"Reporting Frequency",				   'M', {'-', '-', '-', 'X'}},
	   {"Packet Delay Thresholds",			   'C', {'-', '-', '-', 'X'}},
	   {"Minimum Wait Time",				   'C', {'-', '-', '-', 'X'}},
	   {"Measurement Period",				   'C', {'-', '-', '-', 'X'}}]}
	]},
       {"Provide ATSSS Control Information",	   'C', {'-', '-', '-', 'X'},
	[{"MPTCP Control Information",		   'C', {'-', '-', '-', 'X'}},
	 {"ATSSS-LL Control Information",	   'C', {'-', '-', '-', 'X'}},
	 {"PMF Control Information",		   'C', {'-', '-', '-', 'X'}}]},
       {"Ethernet Context Information",		   'C', {'-', '-', '-', 'X'},
	[{"MAC Addressed Detected",		   'M', {'-', '-', '-', 'X'}}]},
       {"Access Availability Information",	   'O', {'-', '-', '-', 'X'}},
       {"Query Packet Rate Status IE SMReq",	   'C', {'-', 'X', '-', 'X'},
	[{"QER ID",				   'M', {'-', 'X', '-', 'X'}}]},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {53, "Session Modification Response",		{'X', 'X', 'X', 'X'},
      [{"PFCP Cause",				   'M', {'X', 'X', 'X', 'X'}},
       {"Offending IE",				   'C', {'X', 'X', 'X', 'X'}},
       {"Created PDR",				   'C', {'X', 'X', '-', 'X'}},
       {"Load Control Information",		   'O', {'X', 'X', 'X', 'X'}},
       {"Overload Control Information",		   'O', {'X', 'X', 'X', 'X'}},
       {"Usage Report SMR",			   'C', {'X', 'X', 'X', 'X'},
	[{"URR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"UR-SEQN",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Usage Report Trigger",		   'M', {'X', 'X', 'X', 'X'}},
	 {"Start Time",				   'C', {'X', 'X', 'X', 'X'}},
	 {"End Time",				   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Measurement",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Duration Measurement",		   'C', {'X', 'X', 'X', 'X'}},
	 {"Time of First Packet",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Time of Last Packet",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Usage Information",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Query URR Reference",		   'C', {'X', 'X', 'X', 'X'}},
	 {"Ethernet Traffic Information",	   'C', {'-', '-', '-', 'X'},
	  [{"MAC Addresses Detected",		   'C', {'-', '-', '-', 'X'}},
	   {"MAC Addresses Removed",		   'C', {'-', '-', '-', 'X'}}]},
	 {"TP Now",				   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Start Time",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP End Time",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"Failed Rule ID",			   'C', {'X', 'X', 'X', 'X'}},
       {"Additional Usage Reports Information",	   'C', {'X', 'X', 'X', 'X'}},
       {"Created Traffic Endpoint",		   'C', {'X', 'X', '-', 'X'},
	[{"Traffic Endpoint ID",		   'M', {'X', 'X', '-', 'X'}},
	 {"F-TEID",				   'C', {'X', 'X', '-', 'X'}},
	 {"F-TEID",				   'C', {'-', '-', '-', 'X'}},
	 {"UE IP Address",			   'C', {'-', 'X', '-', 'X'}}]},
       {"Port Management Information for TSC SMR", 'C', {'-', '-', '-', 'X'},
	[{"Port Management Information Container", 'O', {'-', '-', '-', 'X'}}]},
       {"ATSSS Control Parameters",		   'C', {'-', '-', '-', 'X'},
	[{"MPTCP Parameters",			   'C', {'-', '-', '-', 'X'},
	  [{"MPTCP Address Information",	   'M', {'-', '-', '-', 'X'}},
	   {"UE Link-Specific IP Address",	   'M', {'-', '-', '-', 'X'}}]},
	 {"ATSSS-LL Parameters",		   'C', {'-', '-', '-', 'X'},
	  [{"ATSSS-LL Information",		   'M', {'-', '-', '-', 'X'}}]},
	 {"PMF Parameters",			   'C', {'-', '-', '-', 'X'},
	  [{"PMF Address Information",		   'M', {'-', '-', '-', 'X'}}]}]},
       {"Updated PDR",				   'C', {'-', '-', '-', 'X'},
	[{"PDR ID",				   'M', {'-', '-', '-', 'X'}},
	 {"F-TEID",				   'C', {'-', '-', '-', 'X'}}]},
       {"Packet Rate Status Report IE SMResp",	   'C', {'-', 'X', '-', 'X'},
	[{"QER ID",				   'M', {'-', 'X', '-', 'X'}},
	 {"Packet Rate Status",			   'M', {'-', 'X', '-', 'X'}}]},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"TP Created NAT Binding",		   'C', {'-', 'X', 'X', 'X'},
	[{"BBF NAT Outside Address",		   'C', {'-', 'X', 'X', 'X'}},
	 {"BBF NAT Port Block",			   'C', {'-', 'X', 'X', 'X'}}]}
      ]},
     {54, "Session Deletion Request",			{'X', 'X', 'X', 'X'},
      [{"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {55, "Session Deletion Response",			{'X', 'X', 'X', 'X'},
      [{"PFCP Cause",				   'M', {'X', 'X', 'X', 'X'}},
       {"Offending IE",				   'C', {'X', 'X', 'X', 'X'}},
       {"Load Control Information",		   'O', {'X', 'X', 'X', 'X'}},
       {"Overload Control Information",		   'O', {'X', 'X', 'X', 'X'}},
       {"Usage Report SDR",			   'C', {'X', 'X', 'X', 'X'},
	[{"URR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"UR-SEQN",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Usage Report Trigger",		   'M', {'X', 'X', 'X', 'X'}},
	 {"Start Time",				   'C', {'X', 'X', 'X', 'X'}},
	 {"End Time",				   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Measurement",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Duration Measurement",		   'C', {'X', 'X', 'X', 'X'}},
	 {"Time of First Packet",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Time of Last Packet",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Usage Information",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Ethernet Traffic Information",	   'C', {'-', '-', '-', 'X'},
	  [{"MAC Addresses Detected",		   'C', {'-', '-', '-', 'X'}},
	   {"MAC Addresses Removed",		   'C', {'-', '-', '-', 'X'}}]},
	 {"TP Now",				   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Start Time",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP End Time",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"Additional Usage Reports Information",	   'C', {'X', 'X', 'X', 'X'}},
       {"Packet Rate Status Report",		   'C', {'-', 'X', '-', 'X'},
	[{"QER ID",				   'M', {'-', 'X', '-', 'X'}},
	 {"Packet Rate Status",			   'M', {'-', 'X', '-', 'X'}}]},
       {"Session Report",			   'C', {'-', '-', '-', 'X'},
	[{"SRR ID",				   'M', {'-', '-', '-', 'X'}},
	 {"Access Availability Report",		   'C', {'-', '-', '-', 'X'},
	  [{"Access Availability Information",	   'M', {'-', '-', '-', 'X'}}]},
	 {"QoS Monitoring Report",		   'C', {'-', '-', '-', 'X'},
	  [{"QFI",				   'M', {'-', '-', '-', 'X'}},
	   {"QoS Monitoring Measurement",	   'M', {'-', '-', '-', 'X'}},
	   {"Time Stamp",			   'M', {'-', '-', '-', 'X'}},
	   {"Start Time",			   'O', {'-', '-', '-', 'X'}}]}]},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]}
      ]},
     {56, "Session Report Request",			{'X', 'X', 'X', 'X'},
      [{"Report Type",				   'M', {'X', 'X', 'X', 'X'}},
       {"Downlink Data Report",			   'C', {'X', '-', '-', 'X'},
	[{"PDR ID",				   'M', {'X', '-', '-', 'X'}},
	 {"Downlink Data Service Information",	   'C', {'X', '-', '-', 'X'}},
	 {"DL Data Packets Size",		   'C', {'X', '-', '-', '-'}}]},
       {"Usage Report SRR",			   'C', {'X', 'X', 'X', 'X'},
	[{"URR ID",				   'M', {'X', 'X', 'X', 'X'}},
	 {"UR-SEQN",				   'M', {'X', 'X', 'X', 'X'}},
	 {"Usage Report Trigger",		   'M', {'X', 'X', 'X', 'X'}},
	 {"Start Time",				   'C', {'X', 'X', 'X', 'X'}},
	 {"End Time",				   'C', {'X', 'X', 'X', 'X'}},
	 {"Volume Measurement",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Duration Measurement",		   'C', {'X', 'X', 'X', 'X'}},
	 {"Application Detection Information",	   'C', {'-', 'X', 'X', 'X'},
	  [{"Application ID",			   'M', {'-', 'X', 'X', 'X'}},
	   {"Application Instance ID",		   'C', {'-', 'X', 'X', 'X'}},
	   {"Flow Information",			   'C', {'-', 'X', 'X', 'X'}},
	   {"PDR ID",				   'O', {'-', 'X', 'X', 'X'}}]},
	 {"UE IP address",			   'C', {'-', '-', 'X', 'X'}},
	 {"Network Instance",			   'C', {'-', '-', 'X', 'X'}},
	 {"Time of First Packet",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Time of Last Packet",		   'C', {'-', 'X', 'X', 'X'}},
	 {"Usage Information",			   'C', {'X', 'X', 'X', 'X'}},
	 {"Query URR Reference",		   'C', {'X', 'X', 'X', 'X'}},
	 {"Event Time Stamp",			   'C', {'-', 'X', 'X', 'X'}},
	 {"Ethernet Traffic Information",	   'C', {'-', '-', '-', 'X'},
	  [{"MAC Addresses Detected",		   'C', {'-', '-', '-', 'X'}},
	   {"MAC Addresses Removed",		   'C', {'-', '-', '-', 'X'}}]},
	 {"Join IP Multicast Information",	   'C', {'-', '-', '-', 'X'},
	  [{"IP Multicast Address",		   'M', {'-', '-', '-', 'X'}},
	   {"Source IP Address",		   'C', {'-', '-', '-', 'X'}}]},
	 {"Leave IP Multicast Information",	   'C', {'-', '-', '-', 'X'},
	  [{"IP Multicast Address",		   'M', {'-', '-', '-', 'X'}},
	   {"Source IP Address",		   'C', {'-', '-', '-', 'X'}}]},
	 {"TP Now",				   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Start Time",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP End Time",			   'O', {'X', 'X', 'X', 'X'}}]},
       {"Error Indication Report",		   'C', {'X', 'X', '-', 'X'},
	[{"F-TEID",				   'M', {'X', 'X', '-', 'X'}}]},
       {"Load Control Information",		   'O', {'X', 'X', 'X', 'X'}},
       {"Overload Control Information",		   'O', {'X', 'X', 'X', 'X'}},
       {"Additional Usage Reports Information",	   'C', {'X', 'X', 'X', 'X'}},
       {"PFCPSRReq-Flags",			   'C', {'X', 'X', 'X', 'X'}},
       {"F-SEID",				   'C', {'-', '-', '-', 'X'}},
       {"Packet Rate Status Report",		   'C', {'-', 'X', '-', 'X'},
	[{"QER ID",				   'M', {'-', 'X', '-', 'X'}},
	 {"Packet Rate Status",			   'M', {'-', 'X', '-', 'X'}}]},
       {"Port Management Information for TSC SDR", 'C', {'-', '-', '-', 'X'},
	[{"Port Management Information Container", 'O', {'-', '-', '-', 'X'}}]},
       {"Session Report",			   'C', {'-', '-', '-', 'X'},
	[{"SRR ID",				   'M', {'-', '-', '-', 'X'}},
	 {"Access Availability Report",		   'C', {'-', '-', '-', 'X'},
	  [{"Access Availability Information",	   'M', {'-', '-', '-', 'X'}}]},
	 {"QoS Monitoring Report",		   'C', {'-', '-', '-', 'X'},
	  [{"QFI",				   'M', {'-', '-', '-', 'X'}},
	   {"QoS Monitoring Measurement",	   'M', {'-', '-', '-', 'X'}},
	   {"Time Stamp",			   'M', {'-', '-', '-', 'X'}},
	   {"Start Time",			   'O', {'-', '-', '-', 'X'}}]}]},
       {"TP Trace Information",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Trace Parent",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Trace State",			   'O', {'X', 'X', 'X', 'X'}}
	]}]},
     {57, "Session Report Response",			{'X', 'X', 'X', 'X'},
      [{"PFCP Cause",				   'M', {'X', 'X', 'X', 'X'}},
       {"Offending IE",				   'C', {'X', 'X', 'X', 'X'}},
       {"Update BAR",				   'C', {'X', '-', '-', 'X'},
	[{"BAR ID",				   'M', {'X', '-', '-', 'X'}},
	 {"Downlink Data Notification Delay",	   'C', {'X', '-', '-', 'X'}},
	 {"DL Buffering Duration",		   'C', {'X', '-', '-', 'X'}},
	 {"DL Buffering Suggested Packet Count",   'O', {'X', '-', '-', 'X'}},
	 {"Suggested Buffering Packets Count",	   'C', {' ', 'X', 'X', 'X'}}]},
       {"SxSRRsp-Flags",			   'C', {'X', '-', '-', 'X'}},
       {"F-SEID",				   'O', {'-', '-', '-', 'X'}},
       {"F-TEID",				   'O', {'-', '-', '-', 'X'}},
       {"Alternative SMF IP Address",		   'O', {'-', '-', '-', 'X'}},
       {"TP Error Report",			   'O', {'X', 'X', 'X', 'X'},
	[{"TP Error Message",			   'M', {'X', 'X', 'X', 'X'}},
	 {"TP File Name",			   'O', {'X', 'X', 'X', 'X'}},
	 {"TP Line Number",			   'O', {'X', 'X', 'X', 'X'}}]}
      ]}].

%% -type flag() :: any().
%% -type enum() :: any().
%% -type array_def() :: any().
%% -type field_type() ::
%%     {flags, [flag()]} |
%%     {enum, [enum()]} |
%%     boolean |
%%     integer |
%%     bits |
%%     bytes |
%%     binary |
%%     length_binary |
%%     {array, array_def()} |
%%     tuple().

-record(ie, {id, name, type, field_spec, fields}).
-record(field, {rec, name, len, optional, type, spec}).

-define('WildCard', #field{type = '_', len = 0}).
-define('DecoderFunName', "decode_v1_element").
-define('EncoderFunName', "encode_v1_element").

ies() ->
    TypeFF = fun(Type,          F) when is_atom(Type) -> F#field{type = Type};
		({type,  Type}, F) when is_atom(Type) -> F#field{type = helper, spec = Type};
		({array, Size}, F) when is_integer(Size) -> F#field{type = array, spec = {Size, bytes}};
		({flags, Spec}, F) when is_list(Spec) ->
		     F#field{type = flags, spec = [f2a(S) || S <- Spec]};
		({fixed_flags, Spec}, F) when is_list(Spec) ->
		     F#field{type = fixed_flags, spec = [f2a(S) || S <- Spec]};
		({Type,  Spec}, F) when is_atom(Type) -> F#field{type = Type, spec = Spec}
	     end,
    FieldF = fun(Rec, {Name, Len, Type}, Optional, F) when is_integer(Len) ->
		     [TypeFF(Type, #field{rec = Rec, name = s2a(Name), len = Len,
					  optional = Optional}) | F];
		(Rec, {Name, Type}, Optional, F) when is_list(Name), is_atom(Type) ->
		     [#field{rec = Rec, name = s2a(Name), len = 0, optional = Optional,
			     type = helper, spec = Type} | F];
		(Rec, {'_', Len}, Optional, F) when is_integer(Len) ->
		     [#field{rec = Rec, len = Len, optional = Optional, type = '_'} | F]
	     end,
    SpecF = fun(Fields, #ie{name = Rec, field_spec = FieldSpc} = IE) when is_list(Fields) ->
		    MinLen = case FieldSpc of
				 [H|_] -> H;
				 _ -> undefined
			     end,
		    {FieldDef, _} =
			lists:foldl(
			  fun(Field, {F, Cnt}) ->
				  {FieldF(Rec, Field, Cnt >= MinLen, F), Cnt + 1} end,
			  {[], 0}, Fields),
		    IE#ie{fields = lists:reverse(FieldDef)};
	      (Helper, IE) when is_atom(Helper) ->
		    IE#ie{type = Helper}
	   end,
    lists:map(
      fun ({Id, Name, Spec}) ->
	      SpecF(Spec, #ie{id = Id, name = s2a(Name)});
	  ({Id, Name, MinLen, Spec}) when is_integer(MinLen), MinLen < length(Spec) ->
	      SpecF(Spec, #ie{id = Id, name = s2a(Name),
			      field_spec = lists:seq(MinLen, length(Spec))});
	  ({Id, Name, FieldSpc, Spec}) when is_list(FieldSpc) ->
	      SpecF(Spec, #ie{id = Id, name = s2a(Name), field_spec = FieldSpc})
      end, raw_ies()).


gen_record_def(#field{type = '_'}) ->
    [];
gen_record_def(#field{spec = mccmnc}) ->
    ["mcc = <<\"001\">>", "mnc = <<\"001\">>"];
gen_record_def(#field{name = Name, optional = true}) ->
    [to_string(Name)];
gen_record_def(#field{name = Name, type = flags}) ->
    [io_lib:format("~s = #{}", [Name])];
gen_record_def(#field{name = Name, type = fixed_flags}) ->
    [io_lib:format("~s = #{}", [Name])];
gen_record_def(#field{name = Name, type = enum, spec = [{_,H}|_]}) ->
    [io_lib:format("~s = ~w", [Name, s2e(H)])];
gen_record_def(#field{name = Name, type = enum, spec = [H|_]}) ->
    [io_lib:format("~s = ~w", [Name, s2e(H)])];
gen_record_def(#field{name = Name, type = boolean}) ->
    [io_lib:format("~s = false", [Name])];
gen_record_def(#field{name = Name, type = Type})
  when Type =:= integer; Type =:= 'signed-integer' ->
    [io_lib:format("~s = 0", [Name])];
gen_record_def(#field{name = Name, type = float}) ->
    [io_lib:format("~s = 0.0", [s2a(Name)])];
gen_record_def(#field{name = Name, len = Size, type = bits}) ->
    [io_lib:format("~s = ~w", [Name, <<0:Size>>])];
gen_record_def(#field{name = Name, len = Size, type = bytes}) ->
    [io_lib:format("~s = ~w", [Name, <<0:(Size * 8)>>])];
gen_record_def(#field{name = Name, type = Type})
  when Type =:= binary; Type =:= length_binary ->
    [io_lib:format("~s = <<>>", [Name])];
gen_record_def(#field{name = Name, type = array}) ->
    [io_lib:format("~s = []", [Name])];
gen_record_def(#field{name = Name}) ->
    [to_string(Name)].

gen_decoder_header_match(#field{type = '_', len = 0}) ->
    ["_/binary"];
gen_decoder_header_match(#field{type = '_', len = Size}) ->
    [io_lib:format("_:~w", [Size])];
%% gen_decoder_header_match(#field{Value, Size}) when is_integer(Value); is_atom(Value) ->
%%     [io_lib:format("~w:~w", [Value, Size])];
gen_decoder_header_match(#field{name = Name, spec = mccmnc}) ->
    [io_lib:format("M_~s:3/bytes", [Name])];
gen_decoder_header_match(#field{name = Name, type = flags}) ->
    [io_lib:format("M_~s/binary", [Name])];
gen_decoder_header_match(#field{name = Name, len = Size, type = fixed_flags}) ->
    [io_lib:format("M_~s:~w/bits", [Name, Size])];
gen_decoder_header_match(#field{name = Name, len = Size, type = enum}) ->
    [io_lib:format("M_~s:~w/integer", [Name, Size])];
gen_decoder_header_match(#field{name = Name, type = array, spec = Multi})
  when is_list(Multi) ->
    {stop, [io_lib:format("M_~s_Rest/binary", [Name])]};
gen_decoder_header_match(#field{name = Name, len = Len, type = array}) ->
    {stop, [io_lib:format("M_~s_len:~w/integer, M_~s_Rest/binary", [Name, Len, Name])]};
gen_decoder_header_match(#field{name = Name, len = Len, type = length_binary}) ->
    [io_lib:format("M_~s_len:~w/integer, M_~s:M_~s_len/bytes", [Name, Len, Name, Name])];
gen_decoder_header_match(#field{name = Name, len = 0, type = helper}) ->
    [io_lib:format("M_~s/binary", [Name])];
gen_decoder_header_match(#field{name = Name, len = Size, type = helper}) ->
    [io_lib:format("M_~s:~w/bits", [Name, Size])];
gen_decoder_header_match(#field{name = Name, len = Size, type = boolean}) ->
    [io_lib:format("M_~s:~w/integer", [Name, Size])];
gen_decoder_header_match(#field{name = Name, len = 0, type = Type}) ->
    [io_lib:format("M_~s/~w", [Name, Type])];
gen_decoder_header_match(#field{name = Name, len = Size, type = Type}) ->
    [io_lib:format("M_~s:~w/~s", [Name, Size, Type])].


gen_decoder_call(#field{name = Name, type = flags, spec = Flags}) ->
    io_lib:format("decode_flags(M_~s, ~p)",
		   [Name, Flags]);
gen_decoder_call(#field{name = Name, type = fixed_flags, spec = Flags}) ->
    io_lib:format("decode_flags(M_~s, ~p)",
		   [Name, Flags]);
gen_decoder_call(#field{rec = Rec, name = Name, type = enum}) ->
    io_lib:format("enum_v1_~s_~s(M_~s)", [Rec, Name, Name]);
gen_decoder_call(#field{name = Name, len = Size, type = array, spec = Multi})
  when is_list(Multi) ->
    io_lib:format("[X || <<X:~w/bytes>> <= M_~s]", [Size, Name]);
gen_decoder_call(#field{name = Name, type = array, spec = {Size, Type}}) ->
    io_lib:format("[X || <<X:~w/~s>> <= M_~s]", [Size, Type, Name]);
gen_decoder_call(#field{name = Name, type = helper, spec = TypeName}) ->
    io_lib:format("decode_~s(M_~s)", [TypeName, Name]);
gen_decoder_call(#field{name = Name, type = boolean}) ->
    io_lib:format("int2bool(M_~s)", [Name]);
gen_decoder_call(#field{name = Name}) ->
    io_lib:format("M_~s", [Name]).

gen_decoder_record_assign(#field{type = '_'}) ->
    [];
gen_decoder_record_assign(#field{name = Name, spec = mccmnc}) ->
    [io_lib:format("mcc = decode_mcc(M_~s)", [Name]),
     io_lib:format("mnc = decode_mnc(M_~s)", [Name])];
gen_decoder_record_assign(#field{name = Name} = Field) ->
    [io_lib:format("~s = ~s", [Name, gen_decoder_call(Field)])].

gen_encoder_record_assign(#field{type = '_'}) ->
    [];
gen_encoder_record_assign(#field{spec = mccmnc}) ->
    ["mcc = M_mcc", "mnc = M_mnc"];
gen_encoder_record_assign(#field{name = Name, type = undefined}) ->
    [io_lib:format("~s = undefined", [Name])];
gen_encoder_record_assign(#field{name = Name}) ->
    [io_lib:format("~s = M_~s", [Name, Name])].

enc_match_cond(#field{name = Name, type = flags}) ->
    io_lib:format("is_map(M_~s); is_list(M_~s)", [Name, Name]);
enc_match_cond(#field{name = Name, type = fixed_flags}) ->
    io_lib:format("is_map(M_~s); is_list(M_~s)", [Name, Name]);
enc_match_cond(#field{name = Name, type = enum}) ->
    io_lib:format("is_atom(M_~s); is_integer(M_~s)", [Name, Name]);
enc_match_cond(#field{name = Name, type = array}) ->
    io_lib:format("is_list(M_~s)", [Name]);
enc_match_cond(#field{name = Name, type = helper}) ->
    io_lib:format("is_map(M_~s)", [Name]);
enc_match_cond(#field{name = Name, type = length_binary}) ->
    io_lib:format("is_binary(M_~s)", [Name]);
enc_match_cond(#field{name = Name, type = bytes}) ->
    io_lib:format("is_binary(M_~s)", [Name]);
enc_match_cond(#field{name = Name, type = boolean}) ->
    io_lib:format("is_boolean(M_~s)", [Name]);
enc_match_cond(#field{name = Name, type = Type}) ->
    io_lib:format("is_~s(M_~s)", [Type, Name]).

%% gen_encoder_bin({Name, Size, float}) ->
%%     [io_lib:format("M_~s:~w/float", [s2a(Name), Size])];
%% gen_encoder_bin({Name, Size, 'signed-integer'}) ->
%%     [io_lib:format("M_~s:~w/signed", [s2a(Name), Size])];

gen_encoder_bin(#field{type = '_', len = 0}) ->
    [];
gen_encoder_bin(#field{type = '_', len = Size}) ->
    [io_lib:format("0:~w", [Size])];

%% gen_encoder_bin(#field{Value, Size}) when is_integer(Value); is_atom(Value) ->
%%     [io_lib:format("~w:~w", [Value, Size])];
gen_encoder_bin(#field{type = undefined}) ->
    [];
gen_encoder_bin(#field{spec = mccmnc}) ->
    ["(encode_mccmnc(M_mcc, M_mnc))/binary"];
gen_encoder_bin(#field{name = Name, len = MinSize, type = flags, spec = Flags}) ->
    [io_lib:format("(encode_min_int(~p, encode_flags(M_~s, ~p), little))/binary",
		   [MinSize, Name, reorder_flags(Flags)])];
gen_encoder_bin(#field{name = Name, len = Size, type = fixed_flags, spec = Flags}) ->
    [io_lib:format("(encode_min_int(~p, encode_flags(M_~s, ~p), little))/binary",
		   [Size, Name, reorder_flags(Flags)])];
gen_encoder_bin(#field{rec = Rec, name = Name, len = Size, type = enum}) ->
    [io_lib:format("(enum_v1_~s_~s(M_~s)):~w/integer", [Rec, Name, Name, Size])];
gen_encoder_bin(#field{name = Name, len = Len, type = array, spec = {Size, Type}}) ->
    [io_lib:format("(length(M_~s)):~w/integer, (<< <<X:~w/~w>> || X <- M_~s>>)/binary",
		   [Name, Len, Size, Type, Name])];
gen_encoder_bin(#field{name = Name, len = Len, type = array}) ->
    [io_lib:format("(length(M_~s)):~w/integer, (<< <<X/binary>> || X <- M_~s>>)/binary", [Name, Len, Name])];
gen_encoder_bin(#field{name = Name, len = 0, type = helper, spec = TypeName}) ->
    [io_lib:format("(encode_~s(M_~s))/binary", [TypeName, Name])];
gen_encoder_bin(#field{name = Name, len = Size, type = helper, spec = TypeName}) ->
    [io_lib:format("(encode_~s(M_~s)):~w/bits", [TypeName, Name, Size])];
gen_encoder_bin(#field{name = Name, len = Len, type = length_binary}) ->
    [io_lib:format("(byte_size(M_~s)):~w/integer, M_~s/binary", [Name, Len, Name])];
gen_encoder_bin(#field{name = Name, len = 0, type = Type}) ->
    [io_lib:format("M_~s/~w", [Name, Type])];
gen_encoder_bin(#field{name = Name, len = Size, type = boolean}) ->
    [io_lib:format("(bool2int(M_~s)):~w/integer", [Name, Size])];
gen_encoder_bin(#field{name = Name, len = Size, type = Type}) ->
    [io_lib:format("M_~s:~w/~s", [Name, Size, Type])].

indent(Atom, Extra) when is_atom(Atom) ->
    indent(atom_to_list(Atom), Extra);
indent(List, Extra) ->
    Indent = length(lists:flatten(List)) + Extra,
    Spaces = Indent rem 8,
    Tabs = Indent div 8,
    [lists:duplicate(Tabs, "\t"), lists:duplicate(Spaces, " ")].

f2a(Name) when is_atom(Name) ->
    Name;
f2a(Name) ->
    list_to_atom(Name).

s2a(Name) when is_atom(Name) ->
    Name;
s2a(Name) ->
    S = lists:map(fun(32) -> $_;
		     ($/) -> $_;
		     ($-) -> $_;
		     ($.) -> $_;
		     ($,) -> $_;
		     (C)  -> C
		  end,
		  string:to_lower(Name)),
    list_to_atom(S).

s2e(Name) ->
    list_to_atom(Name).
%%     [$', Name, $'].

to_string(S) when is_list(S)   -> S;
to_string(A) when is_atom(A)   -> atom_to_list(A);
to_string(B) when is_binary(B) -> binary_to_list(B).

append([], Acc) ->
    Acc;
append([H|T], Acc) ->
    append(T, [H|Acc]).

collect(_Fun, [], Acc) ->
    lists:reverse(Acc);
collect(Fun, [F|Fields], Acc) ->
    case Fun(F) of
	{stop, L} ->
	    lists:reverse(append(L, Acc));
	L ->
	    collect(Fun, Fields, append(L, Acc))
    end.

collect(Fun, Fields) ->
    collect(Fun, Fields, []).

gen_enum(Rec, Name, Value, Cnt, Next, {FwdFuns, RevFuns}) ->
    Fwd = io_lib:format("enum_v1_~s_~s(~w) -> ~w", [Rec, Name, s2e(Value), Cnt]),
    Rev = io_lib:format("enum_v1_~s_~s(~w) -> ~w", [Rec, Name, Cnt, s2e(Value)]),
    gen_enum(Rec, Name, Next, Cnt + 1, {[Fwd|FwdFuns], [Rev|RevFuns]}).

gen_enum(_, _, [], _, {FwdFuns, RevFuns}) ->
    {lists:reverse(FwdFuns), lists:reverse(RevFuns)};
gen_enum(Rec, Name, [{Cnt, Value}|Rest], _, Acc) ->
    gen_enum(Rec, Name, Value, Cnt, Rest, Acc);
gen_enum(Rec, Name, [Value|Rest], Cnt, Acc) ->
    gen_enum(Rec, Name, Value, Cnt, Rest, Acc).

reorder_flags([]) -> [];
reorder_flags(Flags) ->
    {Head, Tail} = lists:split(8, Flags),
    lists:reverse(Head) ++ reorder_flags(Tail).

gen_message_type(Value, Name, Next, {FwdFuns, RevFuns}) ->
    Fwd = io_lib:format("message_type_v1(~s) -> ~w", [s2a(Name), Value]),
    Rev = io_lib:format("message_type_v1(~w) -> ~s", [Value, s2a(Name)]),
    gen_message_type(Next, {[Fwd|FwdFuns], [Rev|RevFuns]}).

gen_message_type([], {FwdFuns, RevFuns}) ->
    {lists:reverse(FwdFuns), lists:reverse(RevFuns)};
gen_message_type([{Value, Name, _, _}|Rest], Acc) ->
    gen_message_type(Value, Name, Rest, Acc).

build_late_assign([]) ->
    [];
build_late_assign([H = #field{type = array} | T]) ->
    build_late_assign(H, T);
build_late_assign([_ | T]) ->
    build_late_assign(T).

build_late_assign(#field{name = Name, len = Len, type = array, spec = Multi}, T)
  when is_list(Multi) ->
    Init = io_lib:format("M_~s_size = M_~s * ~w", [Name, s2a(Multi), Len]),
    build_late_assign(Name, Init, T);
build_late_assign(#field{name = Name, type = array, spec = {Size, Type}}, T)
  when Type =:= integer; Type =:= bits ->
    Init = io_lib:format("M_~s_size = M_~s_len * ~w", [Name, Name, Size]),
    build_late_assign(Name, Init, T);
build_late_assign(#field{name = Name, type = array, spec = {Size, _}}, T) ->
    Init = io_lib:format("M_~s_size = M_~s_len * ~w * 8", [Name, Name, Size]),
    build_late_assign(Name, Init, T).

build_late_assign(Name, Init, Fields) ->
    Match = io_lib:format("M_~s:M_~s_size/bits", [Name, Name]),
    {Body, Next} = collect_late_assign(Fields, [Match]),
    M = io_lib:format("    <<~s>> = M_~s_Rest,", [string:join(Body, ",\n      "), Name]),
    ["    ", Init, ",\n", M, "\n"] ++ build_late_assign(Next).

collect_late_assign([], Acc) ->
    {lists:reverse(Acc), []};
collect_late_assign(Fields = [H | T], Acc) ->
    case gen_decoder_header_match(H) of
	{stop, Match} ->
	    {lists:reverse([Match|Acc]), Fields};
	Match ->
	    collect_late_assign(T, [Match|Acc])
    end.


collect_enum(#field{rec = Rec, name = Name, type = enum, spec = Enum}, Acc) ->
    {FwdFuns, RevFuns} = gen_enum(Rec, Name, Enum, 0, {[], []}),
    Wildcard = io_lib:format("enum_v1_~s_~s(X) when is_integer(X) -> X", [Rec, Name]),
    S = string:join(FwdFuns ++ RevFuns ++ [Wildcard], ";\n") ++ ".\n",
    maps:put({Rec, Name}, S, Acc);
collect_enum(_, Acc) ->
    Acc.

collect_enums(#ie{type = undefined, fields = Fields}, AccIn) ->
    lists:foldr(fun(X, Acc) -> collect_enum(X, Acc) end, AccIn, Fields);
collect_enums(_, AccIn) ->
    AccIn.

write_enums(IEs) ->
    E = lists:foldr(fun collect_enums/2, #{}, IEs),
    Str = maps:values(E),
    string:join(Str, "\n").

write_record(#ie{name = Name, type = undefined, fields = Fields})
  when length(Fields) > 1 ->
    Indent = "\t  ",
    RecordDef = string:join(collect(fun gen_record_def/1, Fields, []), [",\n", Indent]),
    [io_lib:format("-record(~s, {~n~s~s~n}).\n", [Name, Indent, RecordDef])];
write_record(_) ->
    [].

write_decoder(#ie{field_spec = FieldSpc, fields = Fields} = IE, Fns)
  when is_list(FieldSpc) ->
    SubIE = IE#ie{field_spec = undefined},
    lists:foldl(
      fun (Len, FnsSub) ->
	      {H,T} = lists:split(Len, Fields),
	      case T of
		  [] -> FnsSub;
		  _ ->
		      write_decoder(SubIE#ie{fields = H ++ [?WildCard]}, FnsSub)
	      end
      end, Fns, FieldSpc);

write_decoder(#ie{id = Id, type = undefined, name = Name, fields = [Field]}, Fns) ->
    MatchIdent = indent(?DecoderFunName, 3),
    Match = string:join(collect(fun gen_decoder_header_match/1, [Field]), [",\n", MatchIdent]),
    Decoder = gen_decoder_call(Field),
    F = io_lib:format("%% decode ~s~n~s(<<~s>>, ~w) ->~n    [~s, ~s]",
		      [Name, ?DecoderFunName, Match, Id, Name, Decoder]),
    [F | Fns];

write_decoder(#ie{id = Id, type = undefined, name = Name, fields = Fields}, Fns) ->
    MatchIdent = indent(?DecoderFunName, 3),
    Match = string:join(collect(fun gen_decoder_header_match/1, Fields), [",\n", MatchIdent]),
    Body = build_late_assign(Fields),
    RecIdent = indent(Name, 6),
    RecAssign = string:join(collect(fun gen_decoder_record_assign/1, Fields), [",\n", RecIdent]),
    F = io_lib:format("%% decode ~s~n~s(<<~s>>, ~w) ->~n~s    [~s, #~s{~s}]",
		      [Name, ?DecoderFunName, Match, Id, Body, Name, Name, RecAssign]),
    [F | Fns];

write_decoder(#ie{name = Name, id = Id, type = Helper}, Fns) ->
    F = io_lib:format("%% decode ~s~n~s(<<Data/binary>>, ~w) ->~n    decode_~s(Data, ~s)",
		      [Name, ?DecoderFunName, Id, Helper, Name]),
    [F | Fns].

write_encoder(#ie{field_spec = FieldSpc, fields = Fields} = IE, Fns)
  when is_list(FieldSpc) ->
    SubIE = IE#ie{field_spec = undefined},
    lists:foldr(
      fun (Len, FnsSub) ->
	      {H,T} = lists:split(Len, Fields),
	      case lists:dropwhile(fun (#field{type = Type}) -> Type == '_' end, T) of
		  [] ->
		      write_encoder(SubIE#ie{fields = H}, FnsSub);
		  [M|_] ->
		      write_encoder(SubIE#ie{fields = H ++ [M#field{type = undefined}]}, FnsSub)
	      end
      end, Fns, FieldSpc);

write_encoder(#ie{id = Id, name = Name, type = undefined,
		  fields = [#field{name = FieldName} = Field]}, Fns) ->
    MatchCond = enc_match_cond(Field),
    FunHead = io_lib:format("~s(~s, M_~s, Acc)~n  when ~s ->~n",
			    [?EncoderFunName, Name, FieldName, MatchCond]),
    DecHead = io_lib:format("    encode_tlv(~w, ", [Id]),
    BinIndent = indent(DecHead, 2),
    BinAssign = string:join(collect(fun gen_encoder_bin/1, [Field]), [",\n", BinIndent]),
    F = io_lib:format("~s~s<<~s>>, Acc)", [FunHead, DecHead, BinAssign]),
    [F | Fns];
write_encoder(#ie{id = Id, name = Name, type = undefined, fields = Fields}, Fns) ->
    RecIdent = indent(?EncoderFunName ++ "(#", 4),
    RecAssign = string:join(collect(fun gen_encoder_record_assign/1, Fields), [",\n", RecIdent]),
    FunHead = io_lib:format("~s(_, #~s{~n~s~s}, Acc) ->~n", [?EncoderFunName, Name, RecIdent, RecAssign]),
    DecHead = io_lib:format("    encode_tlv(~w, ", [Id]),
    BinIndent = indent(DecHead, 2),
    BinAssign = string:join(collect(fun gen_encoder_bin/1, Fields), [",\n", BinIndent]),
    F = io_lib:format("~s~s<<~s>>, Acc)", [FunHead, DecHead, BinAssign]),
    [F | Fns];

write_encoder(#ie{id = Id, name = Name, type = Helper}, Fns) ->
    F = io_lib:format("~s(_, #~s{} = IE, Acc) ->~n    encode_tlv(~w, encode_~s(IE), Acc)",
		      [?EncoderFunName, Name, Id, Helper]),
    [F | Fns].

write_pretty_print(_, #ie{name = Name, fields = Fields})
  when length(Fields) > 1 ->
    io_lib:format("?PRETTY_PRINT(pretty_print_v1, ~s);~n", [Name]);
write_pretty_print(_, _) ->
    [].

%% ie_v/2
ie_v(_, Atom) when is_atom(Atom) ->
    Atom;
ie_v(IfNo, Grp) ->
    lists:foldl(fun(IE, A) -> ie_v(IE, IfNo, A) end, #{}, Grp).

%% ie_v/4
ie_v(IE, P, 'X', Grp, IfNo, A) ->
    IEsV = ie_v(IfNo, Grp),
    A#{s2a(IE) => {P, IEsV}};
ie_v(_IE, _P, _, _Grp, _IfNo, A) ->
    A.

%% ie_v/3
ie_v({IE, P, Intf}, IfNo, A) ->
    ie_v(IE, P, element(IfNo, Intf), s2a(IE), IfNo, A);
ie_v({IE, P, Intf, Grp}, IfNo, A) ->
    ie_v(IE, P, element(IfNo, Intf), Grp, IfNo, A).

msg_v(Msg, 'X', IfNo, Grp, V) ->
    IEsV = ie_v(IfNo, Grp),
    V#{Msg => IEsV};
msg_v(_Msg, _, _IfNo, _IEs, V) ->
    V.

msg_validation([], V) ->
    V;
msg_validation({_Id, Msg, Ifs, IEs}, V) ->
    lists:foldl(
      fun({IfNo, IfId}, V0) ->
	      V1 = maps:get(IfId, V0, #{}),
	      V2 = msg_v(s2a(Msg), element(IfNo, Ifs), IfNo, IEs, V1),
	      maps:put(IfId, V2, V0)
      end, V, [{1, 'Sxa'}, {2, 'Sxb'}, {3, 'Sxc'}, {4, 'N4'}]);
msg_validation([H|T], V) ->
    msg_validation(H, msg_validation(T, V)).

main(_) ->
    IEs = ies(),

    MsgDescription = string:join(
		       [io_lib:format("msg_description_v1(~s) -> <<\"~s\">>",
				      [s2a(X), X]) || {_, X, _, _} <- msgs()]
		       ++ ["msg_description_v1(X) -> io_lib:format(\"~p\", [X])"], ";\n") ++ ".\n",

    {FwdFuns, RevFuns} = gen_message_type(msgs(), {[], []}),
    ErrorFun = ["message_type_v1(Type) -> error(badarg, [Type])"],
    MTypes = string:join(FwdFuns ++ RevFuns ++ ErrorFun, ";\n") ++ ".\n",

    %%Records = string:join([write_record(X) || X <- IEs], "\n"),
    Records = string:join(collect(fun write_record/1, IEs, []), "\n"),
    HrlRecs = io_lib:format("%% -include(\"pfcp_packet_v1_gen.hrl\").~n~n~s", [Records]),
    Enums = write_enums(IEs),

    CatchAnyDecoder = ?DecoderFunName ++ "(Value, Tag) ->\n    [Tag, Value]",

    DecoderFns = lists:foldr(fun write_decoder/2, [CatchAnyDecoder], IEs),
    Funs = string:join(DecoderFns, ";\n\n"),

    CatchAnyEncoder = "encode_v1_element(Tag, Value, Acc) when is_binary(Value) ->\n    encode_tlv(Tag, Value, Acc)",
    EncoderFns = lists:foldr(fun write_encoder/2, [CatchAnyEncoder], IEs),
    EncFuns = string:join(EncoderFns, ";\n\n"),

    CatchAnyPretty = "pretty_print_v1(_, _) ->\n    no",
    RecPrettyDefs = [write_pretty_print("pretty_print_v1", X) || X <- IEs]
	++ [CatchAnyPretty],

    Validate = string:replace(
		 io_lib:format("v1_msg_defs() ->~n    ~95p.~n", [msg_validation(msgs(), #{})]),
		 "        ", 9, all),

    ErlDecls = io_lib:format("%% -include(\"pfcp_packet_v1_gen.hrl\").~n~n~s~n~s~n~s~n~s.~n~n~s.~n~n~s.~n~n~s",
			     [MsgDescription, MTypes, Enums, Funs, EncFuns, RecPrettyDefs,
			     Validate]),

    {ok, HrlF0} = file:read_file("include/pfcp_packet.hrl"),
    [HrlHead, _] = binary:split(HrlF0, [<<"%% -include(\"pfcp_packet_v1_gen.hrl\").">>],[]),
    file:write_file("include/pfcp_packet.hrl", [HrlHead, HrlRecs]),

    {ok, ErlF0} = file:read_file("src/pfcp_packet.erl"),
    [ErlHead, _] = binary:split(ErlF0, [<<"%% -include(\"pfcp_packet_v1_gen.hrl\").">>],[]),
    file:write_file("src/pfcp_packet.erl", [ErlHead, ErlDecls]).
