/* Simple, blocking client API against the Osmocom CTRL interface */

/* (C) 2018 by Harald Welte <laforge@gnumonks.org>
 * All Rights Reserved.
 *
 * 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 <unistd.h>
#include <stdint.h>
#include <talloc.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>

#include <netinet/in.h>

#include <osmocom/core/msgb.h>
#include <osmocom/core/socket.h>
#include <osmocom/gsm/ipa.h>
#include <osmocom/gsm/protocol/ipaccess.h>

#include "simple_ctrl.h"

/***********************************************************************
 * blocking I/O with timeout helpers
 ***********************************************************************/

static struct timeval *timeval_from_msec(uint32_t tout_msec)
{
	static struct timeval tout;

	if (tout_msec == 0)
		return NULL;
	tout.tv_sec = tout_msec/1000;
	tout.tv_usec = (tout_msec%1000)*1000;

	return &tout;
}

static ssize_t read_timeout(int fd, void *buf, size_t count, uint32_t tout_msec)
{
	fd_set readset;
	int rc;

	FD_ZERO(&readset);
	FD_SET(fd, &readset);

	rc = select(fd+1, &readset, NULL, NULL, timeval_from_msec(tout_msec));
	if (rc < 0)
		return rc;

	if (FD_ISSET(fd, &readset))
		return read(fd, buf, count);

	return -ETIMEDOUT;
}

static ssize_t write_timeout(int fd, const void *buf, size_t count, uint32_t tout_msec)
{
	fd_set writeset;
	int rc;

	FD_ZERO(&writeset);
	FD_SET(fd, &writeset);

	rc = select(fd+1, NULL, &writeset, NULL, timeval_from_msec(tout_msec));
	if (rc < 0)
		return rc;

	if (FD_ISSET(fd, &writeset))
		return write(fd, buf, count);

	return -ETIMEDOUT;
}


/***********************************************************************
 * actual CTRL client API
 ***********************************************************************/

struct simple_ctrl_handle {
	int fd;
	uint32_t next_id;
	uint32_t tout_msec;
};

struct simple_ctrl_handle *simple_ctrl_open(void *ctx, const char *host, uint16_t dport,
					    uint32_t tout_msec)
{
	struct simple_ctrl_handle *sch;
	fd_set writeset;
	int off = 0;
	int rc, fd;

	fd = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP, host, dport,
			    OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_NONBLOCK);
	if (fd < 0) {
		fprintf(stderr, "CTRL: error connecting socket: %s\n", strerror(errno));
		return NULL;
	}

	/* wait until connect (or timeout) happens */
	FD_ZERO(&writeset);
	FD_SET(fd, &writeset);
	rc = select(fd+1, NULL, &writeset, NULL, timeval_from_msec(tout_msec));
	if (rc == 0) {
		fprintf(stderr, "CTRL: timeout during connect\n");
		goto out_close;
	}
	if (rc < 0) {
		fprintf(stderr, "CTRL: error connecting socket: %s\n", strerror(errno));
		goto out_close;
	}

	/* set FD blocking again */
	if (ioctl(fd, FIONBIO, (unsigned char *)&off) < 0) {
		fprintf(stderr, "CTRL: cannot set socket blocking: %s\n", strerror(errno));
		goto out_close;
	}

	sch = talloc_zero(ctx, struct simple_ctrl_handle);
	if (!sch)
		goto out_close;
	sch->fd = fd;
	sch->tout_msec = tout_msec;
	return sch;

out_close:
	close(fd);
	return NULL;
}

void simple_ctrl_set_timeout(struct simple_ctrl_handle *sch, uint32_t tout_msec)
{
	sch->tout_msec = tout_msec;
}

void simple_ctrl_close(struct simple_ctrl_handle *sch)
{
	close(sch->fd);
	talloc_free(sch);
}

static struct msgb *simple_ipa_receive(struct simple_ctrl_handle *sch)
{
	struct ipaccess_head hh;
	struct msgb *resp;
	int rc, len;

	rc = read_timeout(sch->fd, (uint8_t *) &hh, sizeof(hh), sch->tout_msec);
	if (rc < 0) {
		fprintf(stderr, "CTRL: Error during read: %d\n", rc);
		return NULL;
	} else if (rc < sizeof(hh)) {
		fprintf(stderr, "CTRL: ERROR: short read (header)\n");
		return NULL;
	}
	len = ntohs(hh.len);

	resp = msgb_alloc(len+sizeof(hh)+1, "CTRL Rx");
	if (!resp)
		return NULL;
	resp->l1h = msgb_put(resp, sizeof(hh));
	memcpy(resp->l1h, (uint8_t *) &hh, sizeof(hh));

	resp->l2h = resp->tail;
	rc = read(sch->fd, resp->l2h, len);
	if (rc < len) {
		fprintf(stderr, "CTRL: ERROR: short read (payload)\n");
		msgb_free(resp);
		return NULL;
	}
	msgb_put(resp, rc);

	return resp;
}

struct msgb *simple_ctrl_receive(struct simple_ctrl_handle *sch)
{
	struct msgb *resp;
	struct ipaccess_head *ih;
	struct ipaccess_head_ext *ihe;
	unsigned char *tmp;

	/* loop until we've received a CTRL message */
	while (true) {
		resp = simple_ipa_receive(sch);
		if (!resp)
			return NULL;

		ih = (struct ipaccess_head *) resp->l1h;
		if (ih->proto == IPAC_PROTO_OSMO)
			resp->l2h = resp->l2h+1;
		ihe = (struct ipaccess_head_ext*) (resp->l1h + sizeof(*ih));
		if (ih->proto == IPAC_PROTO_OSMO && ihe->proto == IPAC_PROTO_EXT_CTRL) {
			/* Ensure data is NULL terminated */
			tmp = msgb_put(resp, 1);
			*tmp = '\0';
			return resp;
		} else {
			fprintf(stderr, "unknown IPA message %s\n", msgb_hexdump(resp));
			msgb_free(resp);
		}
	}
}

static int simple_ctrl_send(struct simple_ctrl_handle *sch, struct msgb *msg)
{
	int rc;

	ipa_prepend_header_ext(msg, IPAC_PROTO_EXT_CTRL);
	ipa_prepend_header(msg, IPAC_PROTO_OSMO);

	rc = write_timeout(sch->fd, msg->data, msg->len, sch->tout_msec);
	if (rc < 0) {
		fprintf(stderr, "CTRL: Error during write: %d\n", rc);
		return rc;
	} else if (rc < msg->len) {
		fprintf(stderr, "CTRL: ERROR: short write\n");
		msgb_free(msg);
		return -1;
	} else {
		msgb_free(msg);
		return 0;
	}
}

static struct msgb *simple_ctrl_xceive(struct simple_ctrl_handle *sch, struct msgb *msg)
{
	int rc;

	rc = simple_ctrl_send(sch, msg);
	if (rc < 0)
		return NULL;

	/* FIXME: ignore any TRAP */
	return simple_ctrl_receive(sch);
}

char *simple_ctrl_get(struct simple_ctrl_handle *sch, const char *var)
{
	struct msgb *msg = msgb_alloc_headroom(512+8, 8, "CTRL GET");
	struct msgb *resp;
	unsigned int rx_id;
	char *rx_var, *rx_val;
	int rc;

	if (!msg)
		return NULL;

	rc = msgb_printf(msg, "GET %u %s", sch->next_id++, var);
	if (rc < 0) {
		msgb_free(msg);
		return NULL;
	}
	resp = simple_ctrl_xceive(sch, msg);
	if (!resp)
		return NULL;

	rc = sscanf(msgb_l2(resp), "GET_REPLY %u %ms %ms", &rx_id, &rx_var, &rx_val);
	if (rc == 3) {
		if (rx_id == sch->next_id-1 && !strcmp(var, rx_var)) {
			free(rx_var);
			msgb_free(resp);
			return rx_val;
		}
		free(rx_var);
		free(rx_val);
	} else {
		fprintf(stderr, "CTRL: ERROR: GET(%s) results in '%s'\n", var, (char *)msgb_l2(resp));
	}

	msgb_free(resp);
	return NULL;
}

int simple_ctrl_set(struct simple_ctrl_handle *sch, const char *var, const char *val)
{
	struct msgb *msg = msgb_alloc_headroom(512+8, 8, "CTRL SET");
	struct msgb *resp;
	unsigned int rx_id;
	char *rx_var, *rx_val;
	int rc;

	if (!msg)
		return -1;

	rc = msgb_printf(msg, "SET %u %s %s", sch->next_id++, var, val);
	if (rc < 0) {
		msgb_free(msg);
		return -1;
	}
	resp = simple_ctrl_xceive(sch, msg);
	if (!resp)
		return -1;

	if (sscanf(msgb_l2(resp), "SET_REPLY %u %ms %ms", &rx_id, &rx_var, &rx_val) == 3) {
		if (rx_id == sch->next_id-1 && !strcmp(var, rx_var) && !strcmp(val, rx_val)) {
			free(rx_val);
			free(rx_var);
			msgb_free(resp);
			return 0;
		} else {
			free(rx_val);
			free(rx_var);
		}
	} else {
		fprintf(stderr, "CTRL: ERROR: SET(%s=%s) results in '%s'\n", var, val, (char *) msgb_l2(resp));
	}

	msgb_free(resp);
	return -1;
}
