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

	/* 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)
			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 */
	/* FIXME: check string is zero-terminated */
	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 (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;
}
