/* Common bits for RAN message handling */
/*
 * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * Author: Neels Hofmeyr
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <osmocom/core/utils.h>

#include <osmocom/msc/ran_msg.h>

const struct value_string ran_msg_type_names[] = {
	{ RAN_MSG_NONE, "NONE" },
	{ RAN_MSG_COMPL_L3, "COMPL_L3" },
	{ RAN_MSG_DTAP, "DTAP" },
	{ RAN_MSG_CLEAR_COMMAND, "CLEAR_COMMAND" },
	{ RAN_MSG_CLEAR_REQUEST, "CLEAR_REQUEST" },
	{ RAN_MSG_CLEAR_COMPLETE, "CLEAR_COMPLETE" },
	{ RAN_MSG_CLASSMARK_REQUEST, "CLASSMARK_REQUEST" },
	{ RAN_MSG_CLASSMARK_UPDATE, "CLASSMARK_UPDATE" },
	{ RAN_MSG_CIPHER_MODE_COMMAND, "CIPHER_MODE_COMMAND" },
	{ RAN_MSG_CIPHER_MODE_COMPLETE, "CIPHER_MODE_COMPLETE" },
	{ RAN_MSG_CIPHER_MODE_REJECT, "CIPHER_MODE_REJECT" },
	{ RAN_MSG_COMMON_ID, "COMMON_ID" },
	{ RAN_MSG_ASSIGNMENT_COMMAND, "ASSIGNMENT_COMMAND" },
	{ RAN_MSG_ASSIGNMENT_COMPLETE, "ASSIGNMENT_COMPLETE" },
	{ RAN_MSG_ASSIGNMENT_FAILURE, "ASSIGNMENT_FAILURE" },
	{ RAN_MSG_SAPI_N_REJECT, "SAPI_N_REJECT" },
	{ RAN_MSG_LCLS_STATUS, "LCLS_STATUS" },
	{ RAN_MSG_LCLS_BREAK_REQ, "LCLS_BREAK_REQ" },
	{ RAN_MSG_HANDOVER_COMMAND, "HANDOVER_COMMAND" },
	{ RAN_MSG_HANDOVER_SUCCEEDED, "HANDOVER_SUCCEEDED" },
	{ RAN_MSG_HANDOVER_PERFORMED, "HANDOVER_PERFORMED" },
	{ RAN_MSG_HANDOVER_REQUIRED, "HANDOVER_REQUIRED" },
	{ RAN_MSG_HANDOVER_REQUIRED_REJECT, "HANDOVER_REQUIRED_REJECT" },
	{ RAN_MSG_HANDOVER_REQUEST, "HANDOVER_REQUEST" },
	{ RAN_MSG_HANDOVER_REQUEST_ACK, "HANDOVER_REQUEST_ACK" },
	{ RAN_MSG_HANDOVER_DETECT, "HANDOVER_DETECT" },
	{ RAN_MSG_HANDOVER_COMPLETE, "HANDOVER_COMPLETE" },
	{ RAN_MSG_HANDOVER_FAILURE, "HANDOVER_FAILURE" },
	{}
};

/* extract the N(SD) and return the modulo value for a R99 message */
static uint8_t ran_dec_dtap_undup_determine_nsd_ret_modulo_r99(uint8_t pdisc, uint8_t msg_type, uint8_t *n_sd)
{
	switch (pdisc) {
	case GSM48_PDISC_MM:
	case GSM48_PDISC_CC:
	case GSM48_PDISC_NC_SS:
		*n_sd = (msg_type >> 6) & 0x3;
		return 4;
	case GSM48_PDISC_GROUP_CC:
	case GSM48_PDISC_BCAST_CC:
	case GSM48_PDISC_LOC:
		*n_sd = (msg_type >> 6) & 0x1;
		return 2;
	default:
		/* no sequence number, we cannot detect dups */
		return 0;
	}
}

/* extract the N(SD) and return the modulo value for a R98 message */
static uint8_t gsm0407_determine_nsd_ret_modulo_r98(uint8_t pdisc, uint8_t msg_type, uint8_t *n_sd)
{
	switch (pdisc) {
	case GSM48_PDISC_MM:
	case GSM48_PDISC_CC:
	case GSM48_PDISC_NC_SS:
	case GSM48_PDISC_GROUP_CC:
	case GSM48_PDISC_BCAST_CC:
	case GSM48_PDISC_LOC:
		*n_sd = (msg_type >> 6) & 0x1;
		return 2;
	default:
		/* no sequence number, we cannot detect dups */
		return 0;
	}
}

/* TS 24.007 11.2.3.2.3 Message Type Octet / Duplicate Detection.
 * (Not static for unit testing). */
int ran_dec_dtap_undup_pdisc_ctr_bin(uint8_t pdisc)
{
	switch (pdisc) {
	case GSM48_PDISC_MM:
	case GSM48_PDISC_CC:
	case GSM48_PDISC_NC_SS:
		return 0;
	case GSM48_PDISC_GROUP_CC:
		return 1;
	case GSM48_PDISC_BCAST_CC:
		return 2;
	case GSM48_PDISC_LOC:
		return 3;
	default:
		return -1;
	}
}

/* TS 24.007 11.2.3.2 Message Type Octet / Duplicate Detection */
bool ran_dec_dtap_undup_is_duplicate(struct osmo_fsm_inst *log_fi, uint8_t *n_sd_next, bool is_r99, struct msgb *l3)
{
	struct gsm48_hdr *gh;
	uint8_t pdisc;
	uint8_t n_sd, modulo;
	int bin;

	gh = msgb_l3(l3);
	pdisc = gsm48_hdr_pdisc(gh);

	if (is_r99) {
		modulo = ran_dec_dtap_undup_determine_nsd_ret_modulo_r99(pdisc, gh->msg_type, &n_sd);
	} else { /* pre R99 */
		modulo = gsm0407_determine_nsd_ret_modulo_r98(pdisc, gh->msg_type, &n_sd);
	}
	if (modulo == 0)
		return false;
	bin = ran_dec_dtap_undup_pdisc_ctr_bin(pdisc);
	if (bin < 0)
		return false;

	OSMO_ASSERT(bin >= 0 && bin < 4);
	if (n_sd != n_sd_next[bin]) {
		/* not what we expected: duplicate */
		LOGPFSML(log_fi, LOGL_NOTICE, "Duplicate DTAP: bin=%d, expected n_sd == %u, got %u\n",
			 bin, n_sd_next[bin], n_sd);
		return true;
	} else {
		/* as expected: no dup; update expected counter for next message */
		n_sd_next[bin] = (n_sd + 1) % modulo;
		return false;
	}
}

/* convenience: RAN decode implementations can call this to dispatch the decode_cb with a decoded ran_msg. */
int ran_decoded(struct ran_dec *ran_dec, struct ran_msg *ran_msg)
{
	if (!ran_dec->decode_cb)
		return -1;
	return ran_dec->decode_cb(ran_dec->caller_fi, ran_dec->caller_data, ran_msg);
}
