/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2012  Intel Corporation. All rights reserved.
 *  Copyright (C) 2011	ProFUSION embedded systems
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#define CONNMAN_SERVICE "net.connman"

#define MANAGER_PATH	"/"
#define MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <gdbus.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/poll.h>
#include <sys/signalfd.h>
#include <unistd.h>

#include <dbus/dbus.h>

#ifndef DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD -1
#endif

static int release_private_network(DBusConnection *conn)
{
	DBusMessage *msg, *reply;
	DBusError error;

	msg = dbus_message_new_method_call(CONNMAN_SERVICE, MANAGER_PATH,
				MANAGER_INTERFACE, "ReleasePrivateNetwork");

	dbus_error_init(&error);

	printf("Releasing private-network...\n");
	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1,
									&error);
	dbus_message_unref(msg);

	if (!reply) {
		if (dbus_error_is_set(&error)) {
			fprintf(stderr, "1. %s\n", error.message);
			dbus_error_free(&error);
		} else {
			fprintf(stderr, "Release() failed");
		}

		return -1;
	}

	return 0;
}

static void request_private_network(DBusConnection *conn, int *out_fd,
					char **out_server_ip,
					char **out_peer_ip,
					char **out_primary_dns,
					char **out_secondary_dns)
{
	DBusMessageIter array, dict, entry;
	DBusMessage *msg, *reply;
	DBusError error;

	msg = dbus_message_new_method_call(CONNMAN_SERVICE, MANAGER_PATH,
				MANAGER_INTERFACE, "RequestPrivateNetwork");

	dbus_error_init(&error);

	printf("Requesting private-network...\n");
	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1,
									&error);
	dbus_message_unref(msg);

	if (!reply) {
		if (dbus_error_is_set(&error)) {
			fprintf(stderr, "1. %s\n", error.message);
			dbus_error_free(&error);
		} else {
			fprintf(stderr, "Request() failed");
		}
		return;
	}

	if (dbus_message_iter_init(reply, &array) == FALSE)
		goto done;

	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_UNIX_FD)
		goto done;

	dbus_message_iter_get_basic(&array, out_fd);
	printf("Fildescriptor = %d\n", *out_fd);

	dbus_message_iter_next(&array);

	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
		goto done;

	dbus_message_iter_recurse(&array, &dict);

	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
		DBusMessageIter iter;
		const char *key;
		int type;

		dbus_message_iter_recurse(&dict, &entry);

		dbus_message_iter_get_basic(&entry, &key);

		printf("key %s", key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &iter);

		type = dbus_message_iter_get_arg_type(&iter);
		if (type != DBUS_TYPE_STRING)
			break;

		if (g_str_equal(key, "ServerIPv4")
				&& type == DBUS_TYPE_STRING) {
			dbus_message_iter_get_basic(&iter, out_server_ip);
			printf(" = %s\n", *out_server_ip);

		} else if (g_str_equal(key, "PeerIPv4")
				&& type == DBUS_TYPE_STRING) {
			dbus_message_iter_get_basic(&iter, out_peer_ip);
			printf(" = %s\n", *out_peer_ip);

		} else if (g_str_equal(key, "PrimaryDNS")
				&& type == DBUS_TYPE_STRING) {
			dbus_message_iter_get_basic(&iter, out_primary_dns);
			printf(" = %s\n", *out_primary_dns);

		} else if (g_str_equal(key, "SecondaryDNS")
				&& type == DBUS_TYPE_STRING) {
			dbus_message_iter_get_basic(&iter, out_secondary_dns);
			printf(" = %s\n", *out_secondary_dns);
		}

		dbus_message_iter_next(&dict);
	}

done:
	dbus_message_unref(reply);
}

int main(int argc, char *argv[])
{
	DBusConnection *conn;
	int fd = -1;
	char *server_ip;
	char *peer_ip;
	char *primary_dns;
	char *secondary_dns;

	/*
	 * IP packet: src: 192.168.219.2 dst www.connman.net
	 * HTTP GET / request
	 */
	int buf1[81] = { 0x45, 0x00, 0x00, 0x51, 0x5a, 0xbe, 0x00, 0x00, 0x40,
			 0x06, 0x50, 0x73, 0xc0, 0xa8, 0xdb, 0x01, 0x3e, 0x4b,
			 0xf5, 0x80, 0x30, 0x3b, 0x00, 0x50, 0x00, 0x00, 0x00,
			 0x28, 0x04, 0xfd, 0xac, 0x9b, 0x50, 0x18, 0x02, 0x00,
			 0xa1, 0xb3, 0x00, 0x00, 0x47, 0x45, 0x54, 0x20, 0x2f,
			 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
			 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x77,
			 0x77, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x6d, 0x61,
			 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x0d, 0x0a, 0x0d, 0x0a};


	int buf2[81] = { 0x45, 0x00, 0x00, 0x51, 0x57, 0x9d, 0x00, 0x00, 0x40,
			 0x06, 0x53, 0x93, 0xc0, 0xa8, 0xdb, 0x02, 0x3e, 0x4b,
			 0xf5, 0x80, 0x30, 0x3b, 0x00, 0x50, 0x00, 0x00, 0x00,
			 0x28, 0x17, 0xdb, 0x2e, 0x6d, 0x50, 0x18, 0x02, 0x00,
			 0x0d, 0x03, 0x00, 0x00, 0x47, 0x45, 0x54, 0x20, 0x2f,
			 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
			 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x77,
			 0x77, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x6d, 0x61,
			 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x0d, 0x0a, 0x0d, 0x0a};

	if (DBUS_TYPE_UNIX_FD < 0) {
		fprintf(stderr, "File-descriptor passing not supported\n");
		exit(1);
	}

	conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
	if (!conn) {
		fprintf(stderr, "Can't get on system bus\n");
		exit(1);
	}

	request_private_network(conn, &fd, &server_ip, &peer_ip,
					&primary_dns, &secondary_dns);
	if (fd < 0)
		return -1;

	fcntl(fd, F_SETFL, O_NONBLOCK);

	printf("Press ENTER to write data to the network.\n");
	getchar();


	if (!fork()) {
		if (write(fd, buf1, sizeof(buf1)) < 0) {
			fprintf(stderr, "err on write() buf1\n");
			return -1;
		}

		if (write(fd, buf2, sizeof(buf2)) < 0) {
			fprintf(stderr, "err on write() buf2\n");
			return -1;
		}

		printf("Press ENTER to release private network.\n");
		getchar();

		if (release_private_network(conn) < 0)
			return -1;

		close(fd);

		dbus_connection_unref(conn);

	} else {
		struct pollfd p;
		char buf[1500];
		int len;

		p.fd = fd;
		p.events = POLLIN | POLLERR | POLLHUP;

		while (1) {
			p.revents = 0;
			if (poll(&p, 1, -1) <= 0)
				return -1;

			if (p.revents & (POLLERR | POLLHUP))
				return -1;

			len = read(fd, buf, sizeof(buf));
			if (len < 0)
				return -1;

			printf("%d bytes received\n", len);
		}
	}

	return 0;
}
