Add new PCO IE

Related: OS#6369
Related: osmo-gsm-manuals.git Change-Id Id912ead4e1205f84a40af6505a5ddf050d1e086d

Change-Id: I73629a8bf1f9a10a17c7509dee15c3c6dc36e939
diff --git a/include/gsup_protocol.hrl b/include/gsup_protocol.hrl
index d30f12c..f4ec03f 100644
--- a/include/gsup_protocol.hrl
+++ b/include/gsup_protocol.hrl
@@ -113,6 +113,7 @@
   hlr_number => binary(),
   pdp_context_id => [integer()],
   pdp_charging => integer(),
+  pco => binary(),
   rand => binary(),
   auts => binary(),
   cn_domain => integer(),
@@ -159,6 +160,7 @@
 -define(ACCESS_POINT_NAME, 16#12).
 -define(QUALITY_OF_SERVICE, 16#13).
 -define(PDP_CHARGING, 16#14).
+-define(PCO, 16#15).
 -define(RAND, 16#20).
 -define(SRES, 16#21).
 -define(KC, 16#22).
@@ -243,9 +245,9 @@
   16#47 => #{message_type => e_close, mandatory => [message_class, source_name, destination_name, session_id, session_state]},
   16#4b => #{message_type => e_abort, mandatory => [message_class, session_id, session_state, bssap_cause]},
   16#4e => #{message_type => e_routing_err, mandatory => [message_class, source_name, destination_name], optional => [session_id, session_state]},
-  16#50 => #{message_type => epdg_tunnel_request, mandatory => [message_class], optional => []},
+  16#50 => #{message_type => epdg_tunnel_request, mandatory => [message_class], optional => [pco]},
   16#51 => #{message_type => epdg_tunnel_error, mandatory => [message_class, cause], optional => []},
-  16#52 => #{message_type => epdg_tunnel_result, mandatory => [message_class, pdp_info_complete, pdp_info_list], optional => []}
+  16#52 => #{message_type => epdg_tunnel_result, mandatory => [message_class, pdp_info_complete, pdp_info_list], optional => [pco]}
 }).
 
 -define(AUTH_TUPLE_MANDATORY, []).
diff --git a/src/gsup_protocol.erl b/src/gsup_protocol.erl
index 1aea289..a7f3ef9 100644
--- a/src/gsup_protocol.erl
+++ b/src/gsup_protocol.erl
@@ -100,6 +100,10 @@
   ?CHECK_LEN(rand, Len, 16, 16),
   decode_ie(Tail, Map#{rand => Rand});
 
+decode_ie(<<?PCO, Len, PCO:Len/binary, Tail/binary>>, Map) ->
+  ?CHECK_LEN(pco, Len, 1, 251),
+  decode_ie(Tail, Map#{pco => PCO});
+
 decode_ie(<<?AUTS, Len, AUTS:Len/binary, Tail/binary>>, Map) ->
   ?CHECK_LEN(auts, Len, 14, 14),
   decode_ie(Tail, Map#{auts => AUTS});
@@ -408,6 +412,11 @@
   ?CHECK_SIZE(pdp_charging, Len, Value),
   encode_ie(maps:without([pdp_charging], GSUPMessage), <<Head/binary, ?PDP_CHARGING, Len, Value:Len/unit:8>>);
 
+encode_ie(#{pco := Value} = GSUPMessage, Head) ->
+  Len = size(Value),
+  ?CHECK_LEN(pco, Len, 1, 251),
+  encode_ie(maps:without([pco], GSUPMessage), <<Head/binary, ?PCO, Len, Value/binary>>);
+
 encode_ie(#{auts := Value} = GSUPMessage, Head) ->
   Len = 14,
   ?CHECK_LEN(auts, size(Value), Len, Len),