/* Network-specific handling of mobile-originated USSDs. */

/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
 * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2009 by Mike Haben <michael.haben@btinternet.com>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/* This module defines the network-specific handling of mobile-originated
   USSD messages. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <osmocom/msc/gsm_04_80.h>
#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/osmo_msc.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/gsm_04_08.h>

/* Declarations of USSD strings to be recognised */
const char USSD_TEXT_OWN_NUMBER[] = "*#100#";

/* A network-specific handler function */
static int send_own_number(struct gsm_subscriber_connection *conn, const struct msgb *msg, const struct ss_request *req)
{
	char *own_number = conn->vsub->msisdn;
	char response_string[GSM_EXTENSION_LENGTH + 20];

	DEBUGP(DMM, "%s: MSISDN = %s\n", vlr_subscr_name(conn->vsub),
	       own_number);

	/* Need trailing CR as EOT character */
	snprintf(response_string, sizeof(response_string), "Your extension is %s\r", own_number);
	return gsm0480_send_ussd_response(conn, msg, response_string, req);
}

/* Entrypoint - handler function common to all mobile-originated USSDs */
int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
	int rc;
	struct ss_request req;
	struct gsm48_hdr *gh;

	/* TODO: Use subscriber_connection ref-counting if we ever want
	 * to keep the connection alive due ot ongoing USSD exchange.
	 * As we answer everytying synchronously so far, there's no need
	 * yet */

	cm_service_request_concludes(conn, msg);

	memset(&req, 0, sizeof(req));
	gh = msgb_l3(msg);
	rc = gsm0480_decode_ss_request(gh, msgb_l3len(msg), &req);
	if (!rc) {
		DEBUGP(DMM, "Unhandled SS\n");
		rc = gsm0480_send_ussd_reject(conn, msg, &req);
		return rc;
	}

	/* Interrogation or releaseComplete? */
	if (req.ussd_text[0] == '\0' || req.ussd_text[0] == 0xFF) {
		if (req.ss_code > 0) {
			/* Assume interrogateSS or modification of it and reject */
			rc = gsm0480_send_ussd_reject(conn, msg, &req);
			return rc;
		}
		/* Still assuming a Release-Complete and returning */
		return 0;
	}

	msc_subscr_conn_communicating(conn);
	if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req.ussd_text)) {
		DEBUGP(DMM, "USSD: Own number requested\n");
		rc = send_own_number(conn, msg, &req);
	} else {
		DEBUGP(DMM, "Unhandled USSD %s\n", req.ussd_text);
		rc = gsm0480_send_ussd_reject(conn, msg, &req);
	}

	return rc;
}
