/* 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>

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

/* Forward declarations of network-specific handler functions */
static int send_own_number(struct gsm_subscriber_connection *conn, const struct msgb *msg, const struct ss_request *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;
}

/* 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);
}
