/* USSD Filter Code */

/*
 * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010-2011 by On-Waves
 * 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/>.
 *
 */

#include <osmocom/core/socket.h>

#include <osmocom/bsc/bsc_nat.h>
#include <osmocom/bsc/bsc_nat_sccp.h>
#include <osmocom/bsc/bsc_msg_filter.h>
#include <osmocom/bsc/ipaccess.h>
#include <osmocom/bsc/debug.h>

#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm0480.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gsm/ipa.h>
#include <osmocom/gsm/gsm0480.h>

#include <osmocom/sccp/sccp.h>

#include <osmocom/abis/ipa.h>

#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#define USSD_LAC_IE	0
#define USSD_CI_IE	1

static void ussd_auth_con(struct tlv_parsed *, struct bsc_nat_ussd_con *);

static struct bsc_nat_ussd_con *bsc_nat_ussd_alloc(struct bsc_nat *nat)
{
	struct bsc_nat_ussd_con *con;

	con = talloc_zero(nat, struct bsc_nat_ussd_con);
	if (!con)
		return NULL;

	con->nat = nat;
	return con;
}

static void bsc_nat_ussd_destroy(struct bsc_nat_ussd_con *con)
{
	if (con->nat->ussd_con == con) {
		bsc_ussd_close_connections(con->nat);
		con->nat->ussd_con = NULL;
	}

	close(con->queue.bfd.fd);
	osmo_fd_unregister(&con->queue.bfd);
	osmo_timer_del(&con->auth_timeout);
	osmo_wqueue_clear(&con->queue);

	msgb_free(con->pending_msg);
	talloc_free(con);
}

static void ussd_pong(struct bsc_nat_ussd_con *conn)
{
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "pong message");
	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate pong msg\n");
		return;
	}

	msgb_v_put(msg, IPAC_MSGT_PONG);
	bsc_do_write(&conn->queue, msg, IPAC_PROTO_IPACCESS);
}

static int forward_sccp(struct bsc_nat *nat, struct msgb *msg)
{
	struct nat_sccp_connection *con;
	struct bsc_nat_parsed *parsed;


	parsed = bsc_nat_parse(msg);
	if (!parsed) {
		LOGP(DNAT, LOGL_ERROR, "Can not parse msg from USSD.\n");
		msgb_free(msg);
		return -1;
	}

	if (!parsed->dest_local_ref) {
		LOGP(DNAT, LOGL_ERROR, "No destination local reference.\n");
		msgb_free(msg);
		return -1;
	}

	con = bsc_nat_find_con_by_bsc(nat, parsed->dest_local_ref);
	if (!con || !con->bsc) {
		LOGP(DNAT, LOGL_ERROR, "No active connection found.\n");
		msgb_free(msg);
		return -1;
	}

	talloc_free(parsed);
	bsc_write_msg(&con->bsc->write_queue, msg);
	return 0;
}

static int ussd_read_cb(struct osmo_fd *bfd)
{
	struct bsc_nat_ussd_con *conn = bfd->data;
	struct msgb *msg = NULL;
	struct ipaccess_head *hh;
	int ret;

	ret = ipa_msg_recv_buffered(bfd->fd, &msg, &conn->pending_msg);
	if (ret <= 0) {
		if (ret == -EAGAIN)
			return 0;
		LOGP(DNAT, LOGL_ERROR, "USSD Connection was lost.\n");
		bsc_nat_ussd_destroy(conn);
		return -1;
	}

	LOGP(DNAT, LOGL_NOTICE, "MSG from USSD: %s proto: %d\n",
		osmo_hexdump(msg->data, msg->len), msg->l2h[0]);
	hh = (struct ipaccess_head *) msg->data;

	if (hh->proto == IPAC_PROTO_IPACCESS) {
		if (msg->l2h[0] == IPAC_MSGT_ID_RESP) {
			struct tlv_parsed tvp;
			int ret;
			ret = ipa_ccm_idtag_parse(&tvp,
					     (unsigned char *) msg->l2h + 2,
					     msgb_l2len(msg) - 2);
			if (ret < 0) {
				LOGP(DNAT, LOGL_ERROR, "ignoring IPA response "
					"message with malformed TLVs\n");
				msgb_free(msg);
				return ret;
			}
			if (TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME))
				ussd_auth_con(&tvp, conn);
		} else if (msg->l2h[0] == IPAC_MSGT_PING) {
			LOGP(DNAT, LOGL_DEBUG, "Got USSD ping request.\n");
			ussd_pong(conn);
		} else {
			LOGP(DNAT, LOGL_NOTICE, "Got unknown IPACCESS message 0x%02x.\n", msg->l2h[0]);
		}

		msgb_free(msg);
	} else if (hh->proto == IPAC_PROTO_SCCP) {
		forward_sccp(conn->nat, msg);
	} else {
		msgb_free(msg);
	}

	return 0;
}

static void ussd_auth_cb(void *_data)
{
	LOGP(DNAT, LOGL_ERROR, "USSD module didn't authenticate\n");
	bsc_nat_ussd_destroy((struct bsc_nat_ussd_con *) _data);
}

static void ussd_auth_con(struct tlv_parsed *tvp, struct bsc_nat_ussd_con *conn)
{
	const char *token;
	int len;
	if (!conn->nat->ussd_token) {
		LOGP(DNAT, LOGL_ERROR, "No USSD token set. Closing\n");
		bsc_nat_ussd_destroy(conn);
		return;
	}

	token = (const char *) TLVP_VAL(tvp, IPAC_IDTAG_UNITNAME);
 	len = TLVP_LEN(tvp, IPAC_IDTAG_UNITNAME);

	/* last byte should be a NULL */
	if (strlen(conn->nat->ussd_token) != len - 1)
		goto disconnect;
	/* compare everything including the null byte */
	if (memcmp(conn->nat->ussd_token, token, len) != 0)
		goto disconnect;

	/* it is authenticated now */
	if (conn->nat->ussd_con && conn->nat->ussd_con != conn)
		bsc_nat_ussd_destroy(conn->nat->ussd_con);

	LOGP(DNAT, LOGL_ERROR, "USSD token specified. USSD provider is connected.\n");
	osmo_timer_del(&conn->auth_timeout);
	conn->authorized = 1;
	conn->nat->ussd_con = conn;
	return;

disconnect:
	LOGP(DNAT, LOGL_ERROR, "Wrong USSD token by client: %d\n",
		conn->queue.bfd.fd);
	bsc_nat_ussd_destroy(conn);
}

static void ussd_start_auth(struct bsc_nat_ussd_con *conn)
{
	struct msgb *msg;

	osmo_timer_setup(&conn->auth_timeout, ussd_auth_cb, conn);
	osmo_timer_schedule(&conn->auth_timeout, conn->nat->auth_timeout, 0);

	msg = msgb_alloc_headroom(4096, 128, "auth message");
	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate auth msg\n");
		return;
	}

	msgb_v_put(msg, IPAC_MSGT_ID_GET);
	bsc_do_write(&conn->queue, msg, IPAC_PROTO_IPACCESS);
}

static int ussd_listen_cb(struct osmo_fd *bfd, unsigned int what)
{
	struct bsc_nat_ussd_con *conn;
	struct bsc_nat *nat;
	struct sockaddr_in sa;
	socklen_t sa_len = sizeof(sa);
	int fd;

	if (!(what & BSC_FD_READ))
		return 0;

	fd = accept(bfd->fd, (struct sockaddr *) &sa, &sa_len);
	if (fd < 0) {
		perror("accept");
		return fd;
	}

	nat = (struct bsc_nat *) bfd->data;
	osmo_counter_inc(nat->stats.ussd.reconn);

	conn = bsc_nat_ussd_alloc(nat);
	if (!conn) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate USSD con struct.\n");
		close(fd);
		return -1;
	}

	osmo_wqueue_init(&conn->queue, 10);
	conn->queue.bfd.data = conn;
	conn->queue.bfd.fd = fd;
	conn->queue.bfd.when = BSC_FD_READ;
	conn->queue.read_cb = ussd_read_cb;
	conn->queue.write_cb = bsc_write_cb;

	if (osmo_fd_register(&conn->queue.bfd) < 0) {
		LOGP(DNAT, LOGL_ERROR, "Failed to register USSD fd.\n");
		bsc_nat_ussd_destroy(conn);
		return -1;
	}

	LOGP(DNAT, LOGL_NOTICE, "USSD Connection on %d with IP: %s\n",
	     fd, inet_ntoa(sa.sin_addr));

	/* do authentication */
	ussd_start_auth(conn);
	return 0;
}

int bsc_ussd_init(struct bsc_nat *nat)
{
	nat->ussd_listen.cb = ussd_listen_cb;
	nat->ussd_listen.data = nat;
	return osmo_sock_init_ofd(&nat->ussd_listen, AF_INET, SOCK_STREAM, IPPROTO_TCP, 
				  nat->ussd_local, 5001, OSMO_SOCK_F_BIND);
}

static int forward_ussd_simple(struct nat_sccp_connection *con, struct msgb *input)
{
	struct msgb *copy;
	struct bsc_nat_ussd_con *ussd;

	if (!con->bsc->nat->ussd_con)
		return -1;

	copy = msgb_alloc_headroom(4096, 128, "forward bts");
	if (!copy) {
		LOGP(DNAT, LOGL_ERROR, "Allocation failed, not forwarding.\n");
		return -1;
	}

	/* copy the data into the copy */
	copy->l2h = msgb_put(copy, msgb_l2len(input));
	memcpy(copy->l2h, input->l2h, msgb_l2len(input));

	/* send it out */
	ussd = con->bsc->nat->ussd_con;
	bsc_do_write(&ussd->queue, copy, IPAC_PROTO_SCCP);
	return 0;
}

static int forward_ussd(struct nat_sccp_connection *con, const struct ussd_request *req,
			struct msgb *input)
{
	struct msgb *msg, *copy;
	struct ipac_msgt_sccp_state *state;
	struct bsc_nat_ussd_con *ussd;
	uint16_t lac, ci;

	if (!con->bsc->nat->ussd_con)
		return -1;

	msg = msgb_alloc_headroom(4096, 128, "forward ussd");
	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "Allocation failed, not forwarding.\n");
		return -1;
	}

	copy = msgb_alloc_headroom(4096, 128, "forward bts");
	if (!copy) {
		LOGP(DNAT, LOGL_ERROR, "Allocation failed, not forwarding.\n");
		msgb_free(msg);
		return -1;
	}

	copy->l2h = msgb_put(copy, msgb_l2len(input));
	memcpy(copy->l2h, input->l2h, msgb_l2len(input));

	msg->l2h = msgb_put(msg, 1);
	msg->l2h[0] = IPAC_MSGT_SCCP_OLD;

	/* fill out the data */
	state = (struct ipac_msgt_sccp_state *) msgb_put(msg, sizeof(*state));
	state->trans_id = req->transaction_id;
	state->invoke_id = req->invoke_id;
	memcpy(&state->src_ref, &con->remote_ref, sizeof(con->remote_ref));
	memcpy(&state->dst_ref, &con->real_ref, sizeof(con->real_ref));
	memcpy(state->imsi, con->filter_state.imsi, strlen(con->filter_state.imsi));

	/* add additional tag/values */
	lac = htons(con->lac);
	ci = htons(con->ci);
	msgb_tv_fixed_put(msg, USSD_LAC_IE, sizeof(lac), (const uint8_t *) &lac);
	msgb_tv_fixed_put(msg, USSD_CI_IE, sizeof(ci), (const uint8_t *) &ci);

	ussd = con->bsc->nat->ussd_con;
	bsc_do_write(&ussd->queue, msg, IPAC_PROTO_IPACCESS);
	bsc_do_write(&ussd->queue, copy, IPAC_PROTO_SCCP);

	return 0;
}

int bsc_ussd_check(struct nat_sccp_connection *con, struct bsc_nat_parsed *parsed,
		   struct msgb *msg)
{
	uint32_t len;
	uint8_t msg_type;
	uint8_t proto;
	uint8_t ti;
	struct gsm48_hdr *hdr48;
	struct bsc_msg_acc_lst *lst;
	struct ussd_request req;

	/*
	 * various checks to avoid the decoding work. Right now we only want to
	 * decode if the connection was created for USSD, we do have a USSD access
	 * list, a query, a IMSI and such...
	 */
	if (con->filter_state.con_type != FLT_CON_TYPE_SSA)
		return 0;

	if (!con->filter_state.imsi)
		return 0;

	/* We have not verified the IMSI yet */
	if (!con->authorized)
		return 0;

	if (!con->bsc->nat->ussd_lst_name)
		return 0;
	if (!con->bsc->nat->ussd_query)
		return 0;

	if (parsed->bssap != BSSAP_MSG_DTAP)
		return 0;

	if (strlen(con->filter_state.imsi) > GSM23003_IMSI_MAX_DIGITS)
		return 0;

	hdr48 = bsc_unpack_dtap(parsed, msg, &len);
	if (!hdr48)
		return 0;

	proto = gsm48_hdr_pdisc(hdr48);
	msg_type = gsm48_hdr_msg_type(hdr48);
	ti = gsm48_hdr_trans_id_no_ti(hdr48);
	if (proto != GSM48_PDISC_NC_SS)
		return 0;

	if (msg_type == GSM0480_MTYPE_REGISTER) {

		/* now check if it is a IMSI we care about */
		lst = bsc_msg_acc_lst_find(&con->bsc->nat->access_lists,
					   con->bsc->nat->ussd_lst_name);
		if (!lst)
			return 0;

		if (bsc_msg_acc_lst_check_allow(lst, con->filter_state.imsi) != 0)
			return 0;

		/* now decode the message and see if we really want to handle it */
		memset(&req, 0, sizeof(req));
		if (gsm0480_decode_ussd_request(hdr48, len, &req) != 1)
			return 0;
		if (req.text[0] == 0xff)
			return 0;

		if (regexec(&con->bsc->nat->ussd_query_re,
			    req.text, 0, NULL, 0) == REG_NOMATCH)
			return 0;

		/* found a USSD query for our subscriber */
		LOGP(DNAT, LOGL_NOTICE, "Found USSD query for %s\n",
			con->filter_state.imsi);
		con->ussd_ti[ti] = 1;
		if (forward_ussd(con, &req, msg) != 0)
			return 0;
		return 1;
	} else if (msg_type == GSM0480_MTYPE_FACILITY && con->ussd_ti[ti]) {
		LOGP(DNAT, LOGL_NOTICE, "Forwarding message part of TI: %d %s\n",
		     ti, con->filter_state.imsi);
		if (forward_ussd_simple(con, msg) != 0)
			return 0;
		return 1;
	}

	return 0;
}
