/* 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 <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 ssize_t read_timeout(int fd, void *buf, size_t count, uint32_t tout_msec)
{
	struct timeval tout;
	fd_set readset;
	int rc;

	FD_ZERO(&readset);
	FD_SET(fd, &readset);
	if (tout_msec) {
		tout.tv_sec = tout_msec/1000;
		tout.tv_usec = (tout_msec%1000)*1000;
	}

	rc = select(fd+1, &readset, NULL, NULL, tout_msec ? &tout : NULL);
	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)
{
	struct timeval tout;
	fd_set writeset;
	int rc;

	FD_ZERO(&writeset);
	FD_SET(fd, &writeset);
	if (tout_msec) {
		tout.tv_sec = tout_msec/1000;
		tout.tv_usec = (tout_msec%1000)*1000;
	}

	rc = select(fd+1, NULL, &writeset, NULL, tout_msec ? &tout : NULL);
	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;
	int rc;

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

	sch = talloc_zero(ctx, struct simple_ctrl_handle);
	if (!sch) {
		close(rc);
		return NULL;
	}
	sch->fd = rc;
	sch->tout_msec = tout_msec;
	return sch;
}

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;
}
