diff options
-rw-r--r-- | include/osmocom/gsm/protocol/Makefile.am | 1 | ||||
-rw-r--r-- | include/osmocom/gsm/protocol/gsm_44_068.h | 136 | ||||
-rw-r--r-- | src/gsm/Makefile.am | 2 | ||||
-rw-r--r-- | src/gsm/gsm44068.c | 121 | ||||
-rw-r--r-- | src/gsm/libosmogsm.map | 7 |
5 files changed, 266 insertions, 1 deletions
diff --git a/include/osmocom/gsm/protocol/Makefile.am b/include/osmocom/gsm/protocol/Makefile.am index 5c8e2a68..23429dcd 100644 --- a/include/osmocom/gsm/protocol/Makefile.am +++ b/include/osmocom/gsm/protocol/Makefile.am @@ -18,6 +18,7 @@ osmogsmproto_HEADERS = \ 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 00000000..b1c4b45d --- /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 ce0b1f4f..ca850d28 100644 --- a/src/gsm/Makefile.am +++ b/src/gsm/Makefile.am @@ -33,7 +33,7 @@ libgsmint_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c comp128v23.c \ 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 00000000..7da5ae22 --- /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 003d6e80..8bc1272c 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -471,6 +471,13 @@ gsm48_pdisc_msgtype_name_buf; 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; |