Add support of Message Class IE

This IE was introduced together with inter-MSC handover implementation.
Message Class IE is mandatory for Inter-MSC GSUP messages and optional for Subscriber Management, SS and SMS messages.


diff --git a/include/gsup_protocol.hrl b/include/gsup_protocol.hrl
index 15d5718..37a183c 100644
--- a/include/gsup_protocol.hrl
+++ b/include/gsup_protocol.hrl
@@ -83,7 +83,8 @@
   sm_rp_mms => integer(),
   sm_alert_reason => integer(),
   imei => binary(),
-  imei_check_result => integer()
+  imei_check_result => integer(),
+  message_class => integer()
 }.
 
 -define(SESSION_STATE_BEGIN, 1).
@@ -99,6 +100,7 @@
 -define(FREEZE_P_TMSI, 16#07).
 -define(MSISDN, 16#08).
 -define(HLR_NUMBER, 16#09).
+-define(MESSAGE_CLASS, 16#0a).
 -define(PDP_CONTEXT_ID, 16#10).
 -define(PDP_TYPE, 16#11).
 -define(ACCESS_POINT_NAME, 16#12).
@@ -128,6 +130,8 @@
 
 -define(MANDATORY_DEFAULT, [imsi, message_type]).
 
+-define(OPTIONAL_DEFAULT, [message_class]).
+
 -define (GSUP_MESSAGES(), #{
   16#04 => #{message_type => location_upd_req, mandatory => [], optional => [cn_domain]},
   16#05 => #{message_type => location_upd_err, mandatory => [cause]},
diff --git a/src/gsup_protocol.erl b/src/gsup_protocol.erl
index 26c1211..92dfb05 100644
--- a/src/gsup_protocol.erl
+++ b/src/gsup_protocol.erl
@@ -82,6 +82,10 @@
   ?CHECK_LEN(hlr_number, Len, 0, 8),
   decode_ie(Tail, Map#{hlr_number => HLRNumber});
 
+decode_ie(<<?MESSAGE_CLASS, Len, MessageClass:Len/unit:8, Tail/binary>>, Map) ->
+  ?CHECK_LEN(message_class, Len, 1, 1),
+  decode_ie(Tail, Map#{message_class => MessageClass});
+
 decode_ie(<<?PDP_CONTEXT_ID, Len, PDPContextId:Len/unit:8, Tail/binary>>, Map) ->
   ?CHECK_LEN(pdp_context_id, Len, 1, 1),
   List = maps:get(pdp_context_id, Map, []),
@@ -248,7 +252,7 @@
   case ?GSUP_MESSAGES() of
     #{MsgType := #{message_type := MsgTypeAtom, mandatory := Mandatory0} = Map} ->
       Mandatory = Mandatory0 ++ ?MANDATORY_DEFAULT,
-      Possible = Mandatory ++ maps:get(optional, Map, []),
+      Possible = Mandatory ++ maps:get(optional, Map, []) ++ ?OPTIONAL_DEFAULT,
       case {maps:size(maps:with(Mandatory, GSUPMessage)) == length(Mandatory),
             maps:size(maps:without(Possible, GSUPMessage)) == 0} of
         {true, true} -> 
@@ -321,6 +325,11 @@
   ?CHECK_LEN(hlr_number, Len, 0, 8),
   encode_ie(maps:without([hlr_number], GSUPMessage), <<Head/binary, ?HLR_NUMBER, Len, Value/binary>>);
 
+encode_ie(#{message_class := Value} = GSUPMessage, Head) ->
+  Len = 1,
+  ?CHECK_SIZE(message_class, Len, Value),
+  encode_ie(maps:without([message_class], GSUPMessage), <<Head/binary, ?MESSAGE_CLASS, Len, Value:Len/unit:8>>);
+
 encode_ie(#{pdp_context_id := PDPCIdList0} = GSUPMessage, Head) ->
   Len = 1,
   PDPCIdList = <<