ASCI: Add 3GPP TS 44.068 and 44.069 protocol definitions

Change-Id: I3554cea47e714c8fca18c3e9c0e6e80695915a90
diff --git a/include/osmocom/gsm/protocol/Makefile.am b/include/osmocom/gsm/protocol/Makefile.am
index 5c8e2a6..23429dc 100644
--- a/include/osmocom/gsm/protocol/Makefile.am
+++ b/include/osmocom/gsm/protocol/Makefile.am
@@ -18,6 +18,7 @@
 	gsm_29_118.h \
 	gsm_44_004.h \
 	gsm_44_060.h \
+	gsm_44_068.h \
 	gsm_44_318.h \
 	gsm_48_049.h \
 	gsm_48_071.h \
diff --git a/include/osmocom/gsm/protocol/gsm_44_068.h b/include/osmocom/gsm/protocol/gsm_44_068.h
new file mode 100644
index 0000000..b1c4b45
--- /dev/null
+++ b/include/osmocom/gsm/protocol/gsm_44_068.h
@@ -0,0 +1,136 @@
+#pragma once
+#include <stdint.h>
+#include <osmocom/core/utils.h>
+
+/* Group Call Control (GCC) is an ETSI/3GPP standard protocol used between
+ * MS (Mobile Station) and MSC (Mobile Switchting Center) in 2G/GSM-R network.
+ * It is specified in 3GPP TS 44.068.
+ *
+ * (C) 2023 by Sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* 9 Information Element Identifiers */
+enum osmo_gsm44068_iei {
+	OSMO_GSM44068_IEI_MOBILE_IDENTITY		= 0x17,
+	OSMO_GSM44068_IEI_USER_USER			= 0x7E,
+	OSMO_GSM44068_IEI_CALL_STATE			= 0xA0,
+	OSMO_GSM44068_IEI_STATE_ATTRIBUTES		= 0xB0,
+	OSMO_GSM44068_IEI_TALKER_PRIORITY		= 0xC0,
+	OSMO_GSM44068_IEI_SMS_INDICATIONS		= 0xD0,
+};
+
+/* 9.3 Message Type */
+enum osmo_gsm44068_msg_type {
+	OSMO_GSM44068_MSGT_IMMEDIATE_SETUP		= 0x31,
+	OSMO_GSM44068_MSGT_SETUP			= 0x32,
+	OSMO_GSM44068_MSGT_CONNECT			= 0x33,
+	OSMO_GSM44068_MSGT_TERMINATION			= 0x34,
+	OSMO_GSM44068_MSGT_TERMINATION_REQUEST		= 0x35,
+	OSMO_GSM44068_MSGT_TERMINATION_REJECT		= 0x36,
+	OSMO_GSM44068_MSGT_STATUS			= 0x38,
+	OSMO_GSM44068_MSGT_GET_STATUS			= 0x39,
+	OSMO_GSM44068_MSGT_SET_PARAMETER		= 0x3a,
+	OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2		= 0x3b,
+};
+
+/* Table 9.2 priority */
+enum osmo_gsm44068_priority_level {
+	OSMO_GSM44068_PRIO_LEVEL_4			= 0x1,
+	OSMO_GSM44068_PRIO_LEVEL_3			= 0x2,
+	OSMO_GSM44068_PRIO_LEVEL_2			= 0x3,
+	OSMO_GSM44068_PRIO_LEVEL_1			= 0x4,
+	OSMO_GSM44068_PRIO_LEVEL_0			= 0x5,
+	OSMO_GSM44068_PRIO_LEVEL_B			= 0x6,
+	OSMO_GSM44068_PRIO_LEVEL_A			= 0x7,
+};
+
+/* 9.4.2 Call State */
+enum osmo_gsm44068_call_state {
+	OSMO_GSM44068_CSTATE_U0				= 0x0,
+	OSMO_GSM44068_CSTATE_U1				= 0x1,
+	OSMO_GSM44068_CSTATE_U2sl			= 0x2,
+	OSMO_GSM44068_CSTATE_U3				= 0x3,
+	OSMO_GSM44068_CSTATE_U4				= 0x4,
+	OSMO_GSM44068_CSTATE_U5				= 0x5,
+	OSMO_GSM44068_CSTATE_U0p			= 0x6,
+	OSMO_GSM44068_CSTATE_Uwr			= 0x7,
+	OSMO_GSM44068_CSTATE_U2r			= 0x8,
+	OSMO_GSM44068_CSTATE_U2ws			= 0x9,
+	OSMO_GSM44068_CSTATE_U2sr			= 0xa,
+	OSMO_GSM44068_CSTATE_U2nc			= 0xb,
+};
+
+/* 9.4.3 Cause */
+enum osmo_gsm44068_cause {
+	OSMO_GSM44068_CAUSE_ILLEGAL_MS			= 0x03,
+	OSMO_GSM44068_CAUSE_IMEI_NOT_ACCEPTED		= 0x05,
+	OSMO_GSM44068_CAUSE_ILLEGAL_ME			= 0x06,
+	OSMO_GSM44068_CAUSE_SERVICE_NOT_AUTHORIZED	= 0x08,
+	OSMO_GSM44068_CAUSE_APP_NOT_SUPPORTED_ON_PROTO	= 0x09,
+	OSMO_GSM44068_CAUSE_RR_CONNECTION_ABORTED	= 0x0a,
+	OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING	= 0x10,
+	OSMO_GSM44068_CAUSE_NETWORK_FAILURE		= 0x11,
+	OSMO_GSM44068_CAUSE_BUSY			= 0x14,
+	OSMO_GSM44068_CAUSE_CONGESTION			= 0x16,
+	OSMO_GSM44068_CAUSE_USER_NOT_ORIGINATOR		= 0x17,
+	OSMO_GSM44068_CAUSE_NET_WANTS_TO_MAINTAIN_CALL	= 0x18,
+	OSMO_GSM44068_CAUSE_RESPONSE_TO_GET_STATUS	= 0x1e,
+	OSMO_GSM44068_CAUSE_SERVICE_OPTION_NOT_SUBSCR	= 0x20,
+	OSMO_GSM44068_CAUSE_REQUESTED_SERVICE_NOT_SUB	= 0x21,
+	OSMO_GSM44068_CAUSE_SERVICE_OPTION_OOO		= 0x22,
+	OSMO_GSM44068_CAUSE_CALL_CANNOT_BE_IDENTIFIED	= 0x26,
+	OSMO_GSM44068_CAUSE_RETRY_UPON_ENTRY_NEW_CALL	= 0x30, /* up to 0x3f */
+	OSMO_GSM44068_CAUSE_INVALID_TRANSACTION_ID	= 0x51,
+	OSMO_GSM44068_CAUSE_SEMANTICALLY_INCORRECT_MSG	= 0x5f,
+	OSMO_GSM44068_CAUSE_INVALID_MANDATORY_INFO	= 0x60,
+	OSMO_GSM44068_CAUSE_MESSAGE_TYPE_NON_EXISTENT	= 0x61,
+	OSMO_GSM44068_CAUSE_MESSAGE_TYPE_NOT_COMPAT	= 0x62,
+	OSMO_GSM44068_CAUSE_IE_NON_EXISTENT		= 0x63,
+	OSMO_GSM44068_CAUSE_IE_NOT_COMPAT		= 0x64,
+	OSMO_GSM44068_CAUSE_PROTOCOL_ERROR		= 0x70,
+};
+
+/* 9.4.4 Originator Indication */
+#define OSMO_GSM44068_OI_MS_IS_ORIGINATOR		0x01
+
+/* 9.4.7 State Attributes */
+#define OSMO_GSM44068_DA_DOWNLINK_ATTACHED		0x08
+#define OSMO_GSM44068_UA_UPLINK_ATTACHED		0x04
+#define OSMO_GSM44068_COMM_T				0x02
+
+/* 9.4.9 Talker Priority */
+enum osmo_gsm44068_talker_priority {
+	OSMO_GSM44068_PRIO_NORMAL			= 0x0,
+	OSMO_GSM44068_PRIO_PRIVILEGED			= 0x1,
+	OSMO_GSM44068_PRIO_EMERGENCY			= 0x2,
+};
+
+/* 9.4.10 SMS Indications */
+#define OSMO_GSM44068_DC_DATA_CONFIDENTALLY_RQD		0x02
+#define OSMO_GSM44068_GP_GUARANTEED_PRIVACY_RQD		0x01
+
+extern const struct value_string osmo_gsm44068_msg_type_names[];
+extern const struct value_string osmo_gsm44068_priority_level_names[];
+extern const struct value_string osmo_gsm44068_cause_names[];
+extern const struct value_string osmo_gsm44068_call_state_names[];
+extern const struct value_string osmo_gsm44068_talker_priority_names[];
+
+extern const struct tlv_definition osmo_gsm44068_att_tlvdef;
diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am
index ce0b1f4..ca850d2 100644
--- a/src/gsm/Makefile.am
+++ b/src/gsm/Makefile.am
@@ -33,7 +33,7 @@
 			gsup.c gsup_sms.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \
 			gsm23003.c gsm23236.c mncc.c bts_features.c oap_client.c \
 			gsm29118.c gsm48_rest_octets.c cbsp.c gsm48049.c \
-			gad.c bsslap.c bssmap_le.c kdf.c iuup.c gsm44021.c
+			gad.c bsslap.c bssmap_le.c kdf.c iuup.c gsm44021.c gsm44068.c
 
 libgsmint_la_LDFLAGS = -no-undefined
 libgsmint_la_LIBADD = $(top_builddir)/src/core/libosmocore.la $(top_builddir)/src/isdn/libosmoisdn.la
diff --git a/src/gsm/gsm44068.c b/src/gsm/gsm44068.c
new file mode 100644
index 0000000..7da5ae2
--- /dev/null
+++ b/src/gsm/gsm44068.c
@@ -0,0 +1,121 @@
+/* Group Call Control (GCC) is an ETSI/3GPP standard protocol used between
+ * MS (Mobile Station) and MSC (Mobile Switchting Center) in 2G/GSM-R network.
+ * It is specified in 3GPP TS 44.068.
+ *
+ * (C) 2023 by Sysmocom s.f.m.c. GmbH
+ * All Rights Reserved
+ *
+ * Author: Andreas Eversberg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <stddef.h>
+#include <osmocom/gsm/tlv.h>
+#include <osmocom/gsm/protocol/gsm_44_068.h>
+
+/***********************************************************************
+ * Protocol Definitions
+ ***********************************************************************/
+
+const struct value_string osmo_gsm44068_msg_type_names[] = {
+	{ OSMO_GSM44068_MSGT_IMMEDIATE_SETUP,		"IMMEDIATE SETUP" },
+	{ OSMO_GSM44068_MSGT_SETUP,			"SETUP" },
+	{ OSMO_GSM44068_MSGT_CONNECT,			"CONNECT" },
+	{ OSMO_GSM44068_MSGT_TERMINATION,		"TERMINATION" },
+	{ OSMO_GSM44068_MSGT_TERMINATION_REQUEST,	"TERMINATION REQUEST" },
+	{ OSMO_GSM44068_MSGT_TERMINATION_REJECT,	"TERMINATION REJECT" },
+	{ OSMO_GSM44068_MSGT_STATUS,			"STATUS" },
+	{ OSMO_GSM44068_MSGT_GET_STATUS,		"GET STATUS" },
+	{ OSMO_GSM44068_MSGT_SET_PARAMETER,		"SET PARAMETER" },
+	{ OSMO_GSM44068_MSGT_IMMEDIATE_SETUP_2,		"IMMEDIATE SETUP 2" },
+	{ 0, NULL }
+};
+
+const struct value_string osmo_gsm44068_priority_level_names[] = {
+	{ OSMO_GSM44068_PRIO_LEVEL_4,			"priority level 4" },
+	{ OSMO_GSM44068_PRIO_LEVEL_3,			"priority level 3" },
+	{ OSMO_GSM44068_PRIO_LEVEL_2,			"priority level 2" },
+	{ OSMO_GSM44068_PRIO_LEVEL_1,			"priority level 1" },
+	{ OSMO_GSM44068_PRIO_LEVEL_0,			"priority level 0" },
+	{ OSMO_GSM44068_PRIO_LEVEL_B,			"priority level B" },
+	{ OSMO_GSM44068_PRIO_LEVEL_A,			"priority level A" },
+	{ 0, NULL }
+};
+
+const struct value_string osmo_gsm44068_cause_names[] = {
+	{ OSMO_GSM44068_CAUSE_ILLEGAL_MS,		"Illegal MS" },
+	{ OSMO_GSM44068_CAUSE_IMEI_NOT_ACCEPTED,	"IMEI not accepted" },
+	{ OSMO_GSM44068_CAUSE_ILLEGAL_ME,		"Illegal ME" },
+	{ OSMO_GSM44068_CAUSE_SERVICE_NOT_AUTHORIZED,	"Service not authorized" },
+	{ OSMO_GSM44068_CAUSE_APP_NOT_SUPPORTED_ON_PROTO, "Application not supported on the protocol" },
+	{ OSMO_GSM44068_CAUSE_RR_CONNECTION_ABORTED,	"RR connection aborted" },
+	{ OSMO_GSM44068_CAUSE_NORMAL_CALL_CLEARING,	"Normal call clearing" },
+	{ OSMO_GSM44068_CAUSE_NETWORK_FAILURE,		"Network failure" },
+	{ OSMO_GSM44068_CAUSE_BUSY,			"Busy" },
+	{ OSMO_GSM44068_CAUSE_CONGESTION,		"Congestion" },
+	{ OSMO_GSM44068_CAUSE_USER_NOT_ORIGINATOR,	"User not originator of call" },
+	{ OSMO_GSM44068_CAUSE_NET_WANTS_TO_MAINTAIN_CALL, "Network wants to maintain call" },
+	{ OSMO_GSM44068_CAUSE_RESPONSE_TO_GET_STATUS,	"Response to GET STATUS" },
+	{ OSMO_GSM44068_CAUSE_SERVICE_OPTION_NOT_SUBSCR, "Service option not supported" },
+	{ OSMO_GSM44068_CAUSE_REQUESTED_SERVICE_NOT_SUB, "Requested service option not subscribed" },
+	{ OSMO_GSM44068_CAUSE_SERVICE_OPTION_OOO,	"Service option temporarily out of order" },
+	{ OSMO_GSM44068_CAUSE_CALL_CANNOT_BE_IDENTIFIED, "Call cannot be identified" },
+	{ OSMO_GSM44068_CAUSE_RETRY_UPON_ENTRY_NEW_CALL, "retry upon entry into a new cell" },
+	{ OSMO_GSM44068_CAUSE_INVALID_TRANSACTION_ID,	"Invalid transaction identifier value" },
+	{ OSMO_GSM44068_CAUSE_SEMANTICALLY_INCORRECT_MSG, "Semantically incorrect message" },
+	{ OSMO_GSM44068_CAUSE_INVALID_MANDATORY_INFO,	"Invalid mandatory information" },
+	{ OSMO_GSM44068_CAUSE_MESSAGE_TYPE_NON_EXISTENT, "Message type non-existent or not implemented" },
+	{ OSMO_GSM44068_CAUSE_MESSAGE_TYPE_NOT_COMPAT,	"Message type not compatible with the protocol state" },
+	{ OSMO_GSM44068_CAUSE_IE_NON_EXISTENT,		"Information element non-existent or not implemented" },
+	{ OSMO_GSM44068_CAUSE_IE_NOT_COMPAT,		"Message type not compatible with the protocol state" },
+	{ OSMO_GSM44068_CAUSE_PROTOCOL_ERROR,		"Protocol error, unspecified" },
+	{ 0, NULL }
+};
+
+const struct value_string osmo_gsm44068_call_state_names[] = {
+	{ OSMO_GSM44068_CSTATE_U0,			"U0" },
+	{ OSMO_GSM44068_CSTATE_U1,			"U1" },
+	{ OSMO_GSM44068_CSTATE_U2sl,			"U2sl/U2" },
+	{ OSMO_GSM44068_CSTATE_U3,			"U3" },
+	{ OSMO_GSM44068_CSTATE_U4,			"U4" },
+	{ OSMO_GSM44068_CSTATE_U5,			"U5" },
+	{ OSMO_GSM44068_CSTATE_U0p,			"U0.p" },
+	{ OSMO_GSM44068_CSTATE_Uwr,			"Uwr" },
+	{ OSMO_GSM44068_CSTATE_U2r,			"U2r" },
+	{ OSMO_GSM44068_CSTATE_U2ws,			"U2ws" },
+	{ OSMO_GSM44068_CSTATE_U2sr,			"U2sr" },
+	{ OSMO_GSM44068_CSTATE_U2nc,			"U2nc" },
+	{ 0, NULL }
+};
+
+const struct value_string osmo_gsm44068_talker_priority_names[] = {
+	{ OSMO_GSM44068_PRIO_NORMAL,			"Normal" },
+	{ OSMO_GSM44068_PRIO_PRIVILEGED,		"Privileged" },
+	{ OSMO_GSM44068_PRIO_EMERGENCY,			"Emergency" },
+	{ 0, NULL }
+};
+
+const struct tlv_definition osmo_gsm44068_att_tlvdef = {
+	.def = {
+		[OSMO_GSM44068_IEI_MOBILE_IDENTITY] =	{ TLV_TYPE_TLV },
+		[OSMO_GSM44068_IEI_USER_USER] =		{ TLV_TYPE_TLV },
+		[OSMO_GSM44068_IEI_CALL_STATE] =	{ TLV_TYPE_SINGLE_TV },
+		[OSMO_GSM44068_IEI_STATE_ATTRIBUTES] =	{ TLV_TYPE_SINGLE_TV },
+		[OSMO_GSM44068_IEI_TALKER_PRIORITY] =	{ TLV_TYPE_SINGLE_TV },
+		[OSMO_GSM44068_IEI_SMS_INDICATIONS] =	{ TLV_TYPE_SINGLE_TV },
+	},
+};
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 003d6e8..8bc1272 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -471,6 +471,13 @@
 gsm48_pdisc_msgtype_name_c;
 gsm48_reject_value_names;
 
+osmo_gsm44068_msg_type_names;
+osmo_gsm44068_priority_level_names;
+osmo_gsm44068_cause_names;
+osmo_gsm44068_call_state_names;
+osmo_gsm44068_talker_priority_names;
+osmo_gsm44068_att_tlvdef;
+
 gsm_7bit_decode;
 gsm_7bit_decode_ussd;
 gsm_7bit_encode;