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

struct simple_ctrl_handle {
	int fd;
	uint32_t next_id;
};

struct simple_ctrl_handle *simple_ctrl_open(void *ctx, const char *host, uint16_t dport)
{
	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;
	return sch;
}

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(sch->fd, (uint8_t *) &hh, sizeof(hh));
	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;
}

static 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(sch->fd, msg->data, msg->len);

	if (rc < msg->len) {
		fprintf(stderr, "CTRL: ERROR: short write\n");
		msgb_free(msg);
		return rc;
	} 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);

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