/*
 * bt_packet_logger.c
 * com.apple.bluetooth.BTPacketLogger service implementation.
 *
 * Copyright (c) 2021 Geoffrey Kruse, All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <stdlib.h>

#include "bt_packet_logger.h"
#include "lockdown.h"
#include "common/debug.h"
struct bt_packet_logger_worker_thread {
	bt_packet_logger_client_t client;
	bt_packet_logger_receive_cb_t cbfunc;
	void *user_data;
	uint8_t rxbuff[BT_MAX_PACKET_SIZE];
};

#define SZ_READ_TIMEOUT 100
#define PAYLOAD_READ_TIMEOUT 500

/**
 * Convert a service_error_t value to a bt_packet_logger_error_t value.
 * Used internally to get correct error codes.
 *
 * @param err An service_error_t error code
 *
 * @return A matching bt_packet_logger_error_t error code,
 *     BT_PACKET_LOGGER_E_UNKNOWN_ERROR otherwise.
 */
static bt_packet_logger_error_t bt_packet_logger_error(service_error_t err)
{
	switch (err) {
		case SERVICE_E_SUCCESS:
			return BT_PACKET_LOGGER_E_SUCCESS;
		case SERVICE_E_INVALID_ARG:
			return BT_PACKET_LOGGER_E_INVALID_ARG;
		case SERVICE_E_MUX_ERROR:
			return BT_PACKET_LOGGER_E_MUX_ERROR;
		case SERVICE_E_SSL_ERROR:
			return BT_PACKET_LOGGER_E_SSL_ERROR;
		case SERVICE_E_NOT_ENOUGH_DATA:
			return BT_PACKET_LOGGER_E_NOT_ENOUGH_DATA;
		case SERVICE_E_TIMEOUT:
			return BT_PACKET_LOGGER_E_TIMEOUT;
		default:
			break;
	}
	return BT_PACKET_LOGGER_E_UNKNOWN_ERROR;
}

LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_client_new(idevice_t device, lockdownd_service_descriptor_t service, bt_packet_logger_client_t * client)
{
	if (!device || !service || service->port == 0 || !client || *client) {
		debug_info("Incorrect parameter passed to bt_packet_logger_client_new.");
		return BT_PACKET_LOGGER_E_INVALID_ARG;
	}

	debug_info("Creating bt_packet_logger_client, port = %d.", service->port);

	service_client_t parent = NULL;
	bt_packet_logger_error_t ret = bt_packet_logger_error(service_client_new(device, service, &parent));
	if (ret != BT_PACKET_LOGGER_E_SUCCESS) {
		debug_info("Creating base service client failed. Error: %i", ret);
		return ret;
	}

	bt_packet_logger_client_t client_loc = (bt_packet_logger_client_t) malloc(sizeof(struct bt_packet_logger_client_private));
	client_loc->parent = parent;
	client_loc->worker = THREAD_T_NULL;

	*client = client_loc;

	debug_info("bt_packet_logger_client successfully created.");
	return 0;
}

LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_client_start_service(idevice_t device, bt_packet_logger_client_t * client, const char* label)
{
	bt_packet_logger_error_t err = BT_PACKET_LOGGER_E_UNKNOWN_ERROR;
	service_client_factory_start_service(device, BT_PACKETLOGGER_SERVICE_NAME, (void**)client, label, SERVICE_CONSTRUCTOR(bt_packet_logger_client_new), &err);
	return err;
}

LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_client_free(bt_packet_logger_client_t client)
{
	if (!client)
		return BT_PACKET_LOGGER_E_INVALID_ARG;
	bt_packet_logger_stop_capture(client);
	bt_packet_logger_error_t err = bt_packet_logger_error(service_client_free(client->parent));
	free(client);

	return err;
}

LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_receive_with_timeout(bt_packet_logger_client_t client, char* data, uint32_t size, uint32_t *received, unsigned int timeout)
{
	bt_packet_logger_error_t res = BT_PACKET_LOGGER_E_UNKNOWN_ERROR;
	int bytes = 0;

	if (!client || !data || (size == 0)) {
		return BT_PACKET_LOGGER_E_INVALID_ARG;
	}

	res = bt_packet_logger_error(service_receive_with_timeout(client->parent, data, size, (uint32_t*)&bytes, timeout));
	if (res != BT_PACKET_LOGGER_E_SUCCESS && res != BT_PACKET_LOGGER_E_TIMEOUT && res != BT_PACKET_LOGGER_E_NOT_ENOUGH_DATA) {
		debug_info("Could not read data, error %d", res);
	}
	if (received) {
		*received = (uint32_t)bytes;
	}

	return res;
}

void *bt_packet_logger_worker(void *arg)
{
	bt_packet_logger_error_t ret = BT_PACKET_LOGGER_E_UNKNOWN_ERROR;
	struct bt_packet_logger_worker_thread *btwt = (struct bt_packet_logger_worker_thread*)arg;

	if (!btwt) {
		return NULL;
	}

	debug_info("Running");

	while (btwt->client->parent) {
		uint32_t bytes = 0;
		uint16_t len;

		ret = bt_packet_logger_receive_with_timeout(btwt->client, (char*)&len, 2, &bytes, SZ_READ_TIMEOUT);

		if (ret == BT_PACKET_LOGGER_E_TIMEOUT || ret == BT_PACKET_LOGGER_E_NOT_ENOUGH_DATA || ((bytes == 0) && (ret == BT_PACKET_LOGGER_E_SUCCESS))) {
			continue;
		} else if (ret < 0) {
			debug_info("Connection to bt packet logger interrupted");
			break;
		}

		// sanity check received length
		if(bytes > 0 && len > sizeof(bt_packet_logger_header_t)) {
			debug_info("Reading %u bytes\n", len);
			ret = bt_packet_logger_receive_with_timeout(btwt->client, (char *)btwt->rxbuff, len, &bytes, PAYLOAD_READ_TIMEOUT);

			if(len != bytes) {
				debug_info("Failed Read Expected %u, Received %u\n", len, bytes);
				continue;
			}

			if (ret == BT_PACKET_LOGGER_E_TIMEOUT || ret == BT_PACKET_LOGGER_E_NOT_ENOUGH_DATA || ((bytes == 0) && (ret == BT_PACKET_LOGGER_E_SUCCESS))) {
				continue;
			} else if (ret < 0) {
				debug_info("Connection to bt packet logger interrupted");
				break;
			}

			btwt->cbfunc(btwt->rxbuff, len, btwt->user_data);
		}
	}

	// null check performed above
	free(btwt);

	debug_info("Exiting");

	return NULL;
}

LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_start_capture(bt_packet_logger_client_t client, bt_packet_logger_receive_cb_t callback, void* user_data)
{
	if (!client || !callback)
		return BT_PACKET_LOGGER_E_INVALID_ARG;

	bt_packet_logger_error_t res = BT_PACKET_LOGGER_E_UNKNOWN_ERROR;

	if (client->worker) {
		debug_info("Another syslog capture thread appears to be running already.");
		return res;
	}

	/* start worker thread */
	struct bt_packet_logger_worker_thread *btwt = (struct bt_packet_logger_worker_thread*)malloc(sizeof(struct bt_packet_logger_worker_thread));
	if (btwt) {
		btwt->client = client;
		btwt->cbfunc = callback;
		btwt->user_data = user_data;

		if (thread_new(&client->worker, bt_packet_logger_worker, btwt) == 0) {
			res = BT_PACKET_LOGGER_E_SUCCESS;
		}
	}

	return res;
}


LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_stop_capture(bt_packet_logger_client_t client)
{
	if (client->worker) {
		/* notify thread to finish */
		service_client_t parent = client->parent;
		client->parent = NULL;
		/* join thread to make it exit */
		thread_join(client->worker);
		thread_free(client->worker);
		client->worker = THREAD_T_NULL;
		client->parent = parent;
	}

	return BT_PACKET_LOGGER_E_SUCCESS;
}
