/*
 * idevicebt_packet_logger.c
 * Capture Bluetooth HCI traffic to native PKLG or PCAP
 *
 * Copyright (c) 2021 Geoffrey Kruse, All Rights Reserved.
 * Copyright (c) 2022 Matthias Ringwald, 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

#define TOOL_NAME "idevicebtlogger"

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <assert.h>
#include <fcntl.h>

#ifdef WIN32
#include <windows.h>
#define sleep(x) Sleep(x*1000)
#else
#include <arpa/inet.h>
#endif


#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/bt_packet_logger.h>

typedef enum {
	HCI_COMMAND = 0x00,
	HCI_EVENT = 0x01,
	SENT_ACL_DATA = 0x02,
	RECV_ACL_DATA = 0x03,
	SENT_SCO_DATA = 0x08,
	RECV_SCO_DATA = 0x09,
} PacketLoggerPacketType;

static int quit_flag = 0;
static int exit_on_disconnect = 0;

static char* udid = NULL;
static idevice_t device = NULL;
static bt_packet_logger_client_t bt_packet_logger = NULL;
static int use_network = 0;
static char* out_filename = NULL;
static char* log_format_string = NULL;
static FILE * packetlogger_file = NULL;

static enum {
	LOG_FORMAT_PACKETLOGGER,
	LOG_FORMAT_PCAP
} log_format = LOG_FORMAT_PACKETLOGGER;

const uint8_t pcap_file_header[] = {
	// Magic Number
	0xA1, 0xB2, 0xC3, 0xD4,
	// Major / Minor Version
	0x00, 0x02, 0x00, 0x04,
	// Reserved1
	0x00, 0x00, 0x00, 0x00,
	// Reserved2
	0x00, 0x00, 0x00, 0x00,
	// Snaplen == max packet size - use 2kB (larger than any ACL)
	0x00, 0x00, 0x08, 0x00,
	// LinkType: DLT_BLUETOOTH_HCI_H4_WITH_PHDR
	0x00, 0x00, 0x00, 201,
};

static uint32_t big_endian_read_32(const uint8_t * buffer, int position)
{
	return ((uint32_t) buffer[position+3]) | (((uint32_t)buffer[position+2]) << 8) | (((uint32_t)buffer[position+1]) << 16) | (((uint32_t) buffer[position]) << 24);
}

static void big_endian_store_32(uint8_t * buffer, uint16_t position, uint32_t value)
{
	uint16_t pos = position;
	buffer[pos++] = (uint8_t)(value >> 24);
	buffer[pos++] = (uint8_t)(value >> 16);
	buffer[pos++] = (uint8_t)(value >> 8);
	buffer[pos++] = (uint8_t)(value);
}

/**
 * Callback from the packet logger service to handle packets and log to PacketLogger format
 */
static void bt_packet_logger_callback_packetlogger(uint8_t * data, uint16_t len, void *user_data)
{
	(void) fwrite(data, 1, len, packetlogger_file);
}

/**
 * Callback from the packet logger service to handle packets and log to pcap
 */
static void bt_packet_logger_callback_pcap(uint8_t * data, uint16_t len, void *user_data)
{
	// check len
	if (len < 13) {
		return;
	}

	// parse packet header (ignore len field)
	uint32_t ts_secs = big_endian_read_32(data, 4);
	uint32_t ts_us   = big_endian_read_32(data, 8);
	uint8_t packet_type = data[12];
	data += 13;
	len  -= 13;

	// map PacketLogger packet type onto PCAP direction flag and hci_h4_type
	uint8_t direction_in = 0;
	uint8_t hci_h4_type  = 0xff;
	switch(packet_type) {
		case HCI_COMMAND:
			hci_h4_type = 0x01;
			direction_in = 0;
			break;
		case SENT_ACL_DATA:
			hci_h4_type = 0x02;
			direction_in = 0;
			break;
		case RECV_ACL_DATA:
			hci_h4_type = 0x02;
			direction_in = 1;
			break;
		case SENT_SCO_DATA:
			hci_h4_type = 0x03;
			direction_in = 0;
			break;
		case RECV_SCO_DATA:
			hci_h4_type = 0x03;
			direction_in = 1;
			break;
		case HCI_EVENT:
			hci_h4_type = 0x04;
			direction_in = 1;
			break;
		default:
			// unknown packet logger type, drop packet
			return;
	}

	// setup pcap record header, 4 byte direction flag, 1 byte HCI H4 packet type, data
	uint8_t pcap_record_header[21];
	big_endian_store_32(pcap_record_header,  0, ts_secs);       // Timestamp seconds
	big_endian_store_32(pcap_record_header,  4, ts_us);         // Timestamp microseconds
	big_endian_store_32(pcap_record_header,  8, 4 + 1 + len);   // Captured  Packet Length
	big_endian_store_32(pcap_record_header, 12, 4 + 1 + len);   // Original Packet Length
	big_endian_store_32(pcap_record_header, 16, direction_in);  // Direction: Incoming = 1
	pcap_record_header[20] = hci_h4_type;

	// write header
	(void) fwrite(pcap_record_header, 1, sizeof(pcap_record_header), packetlogger_file);

	// write packet
	(void) fwrite(data, 1, len, packetlogger_file);

	// flush
	(void) fflush(packetlogger_file);
}

/**
 * Disable HCI log capture
 */
static void stop_logging(void)
{
	fflush(NULL);

	if (bt_packet_logger) {
		bt_packet_logger_client_free(bt_packet_logger);
		bt_packet_logger = NULL;
	}

	if (device) {
		idevice_free(device);
		device = NULL;
	}
}

/**
 * Enable HCI log capture
 */
static int start_logging(void)
{
	idevice_error_t ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
	if (ret != IDEVICE_E_SUCCESS) {
		fprintf(stderr, "Device with udid %s not found!?\n", udid);
		return -1;
	}

	lockdownd_client_t lockdown = NULL;
	lockdownd_error_t lerr = lockdownd_client_new_with_handshake(device, &lockdown, TOOL_NAME);
	if (lerr != LOCKDOWN_E_SUCCESS) {
		fprintf(stderr, "ERROR: Could not connect to lockdownd: %d\n", lerr);
		idevice_free(device);
		device = NULL;
		return -1;
	}

	/* start bt_packet_logger service */
	bt_packet_logger_client_start_service(device, &bt_packet_logger, TOOL_NAME);

	/* start capturing bt_packet_logger */
	void (*callback)(uint8_t * data, uint16_t len, void *user_data);
	switch (log_format){
		case LOG_FORMAT_PCAP:
			callback = bt_packet_logger_callback_pcap;
			break;
		case LOG_FORMAT_PACKETLOGGER:
			callback = bt_packet_logger_callback_packetlogger;
			break;
		default:
			assert(0);
			return 0;
	}
	bt_packet_logger_error_t serr = bt_packet_logger_start_capture(bt_packet_logger, callback, NULL);
	if (serr != BT_PACKET_LOGGER_E_SUCCESS) {
		fprintf(stderr, "ERROR: Unable to start capturing bt_packet_logger.\n");
		bt_packet_logger_client_free(bt_packet_logger);
		bt_packet_logger = NULL;
		idevice_free(device);
		device = NULL;
		return -1;
	}

	fprintf(stderr, "[connected:%s]\n", udid);
	fflush(stderr);

	return 0;
}

/**
 * Callback for device events
 */
static void device_event_cb(const idevice_event_t* event, void* userdata)
{
	if (use_network && event->conn_type != CONNECTION_NETWORK) {
		return;
	} else if (!use_network && event->conn_type != CONNECTION_USBMUXD) {
		return;
	}
	if (event->event == IDEVICE_DEVICE_ADD) {
		if (!bt_packet_logger) {
			if (!udid) {
				udid = strdup(event->udid);
			}
			if (strcmp(udid, event->udid) == 0) {
				if (start_logging() != 0) {
					fprintf(stderr, "Could not start logger for udid %s\n", udid);
				}
			}
		}
	} else if (event->event == IDEVICE_DEVICE_REMOVE) {
		if (bt_packet_logger && (strcmp(udid, event->udid) == 0)) {
			stop_logging();
			fprintf(stderr, "[disconnected:%s]\n", udid);
			if (exit_on_disconnect) {
				quit_flag++;
			}
		}
	}
}

/**
 * signal handler function for cleaning up properly
 */
static void clean_exit(int sig)
{
	fprintf(stderr, "\nExiting...\n");
	quit_flag++;
}

/**
 * print usage information
 */
static void print_usage(int argc, char **argv, int is_error)
{
	char *name = NULL;
	name = strrchr(argv[0], '/');
	fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] <FILE>\n", (name ? name + 1: argv[0]));
	fprintf(is_error ? stderr : stdout,
		"\n" \
		"Capture HCI packets from a connected device.\n" \
		"\n" \
		"OPTIONS:\n" \
		"  -u, --udid UDID     target specific device by UDID\n" \
		"  -n, --network       connect to network device\n" \
		"  -f, --format FORMAT logging format: packetlogger (default) or pcap\n" \
		"  -x, --exit          exit when device disconnects\n" \
		"  -h, --help          prints usage information\n" \
		"  -d, --debug         enable communication debugging\n" \
		"  -v, --version       prints version information\n" \
		"\n" \
		"Homepage:    <" PACKAGE_URL ">\n"
		"Bug Reports: <" PACKAGE_BUGREPORT ">\n"
	);
}

/**
 * Program entry
 */
int main(int argc, char *argv[])
{
	int c = 0;
	const struct option longopts[] = {
		{ "debug", no_argument, NULL, 'd' },
		{ "help", no_argument, NULL, 'h' },
		{ "udid", required_argument, NULL, 'u' },
		{ "format", required_argument, NULL, 'f' },
		{ "network", no_argument, NULL, 'n' },
		{ "exit", no_argument, NULL, 'x' },
		{ "version", no_argument, NULL, 'v' },
		{ NULL, 0, NULL, 0}
	};

	signal(SIGINT, clean_exit);
	signal(SIGTERM, clean_exit);
#ifndef WIN32
	signal(SIGQUIT, clean_exit);
	signal(SIGPIPE, SIG_IGN);
#endif

	while ((c = getopt_long(argc, argv, "dhu:f:nxv", longopts, NULL)) != -1) {
		switch (c) {
		case 'd':
			idevice_set_debug_level(1);
			break;
		case 'u':
			if (!*optarg) {
				fprintf(stderr, "ERROR: UDID must not be empty!\n");
				print_usage(argc, argv, 1);
				return 2;
			}
			free(udid);
			udid = strdup(optarg);
			break;
		case 'f':
			if (!*optarg) {
				fprintf(stderr, "ERROR: FORMAT must not be empty!\n");
				print_usage(argc, argv, 1);
				return 2;
			}
			free(log_format_string);
			log_format_string = strdup(optarg);
			break;
		case 'n':
			use_network = 1;
			break;
		case 'x':
			exit_on_disconnect = 1;
			break;
		case 'h':
			print_usage(argc, argv, 0);
			return 0;
		case 'v':
			printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
			return 0;
		default:
			print_usage(argc, argv, 1);
			return 2;
		}
	}

	if (optind < argc) {
		out_filename = argv[optind];
		// printf("Output File: %s\n", out_filename);
	}
	else {
		print_usage(argc, argv, 1);
		return 2;
	}

	if (log_format_string != NULL){
		if (strcmp("packetlogger", log_format_string) == 0){
			log_format = LOG_FORMAT_PACKETLOGGER;
		} else if (strcmp("pcap", log_format_string) == 0){
			log_format = LOG_FORMAT_PCAP;
		} else {
			printf("Unknown logging format: '%s'\n", log_format_string);
			print_usage(argc, argv, 1);
			return 2;
		}
	}

	int num = 0;
	idevice_info_t *devices = NULL;
	idevice_get_device_list_extended(&devices, &num);
	idevice_device_list_extended_free(devices);
	if (num == 0) {
		if (!udid) {
			fprintf(stderr, "No device found. Plug in a device or pass UDID with -u to wait for device to be available.\n");
			return -1;
		} else {
			fprintf(stderr, "Waiting for device with UDID %s to become available...\n", udid);
		}
	}

	// support streaming to stdout
	if (strcmp(out_filename, "-") == 0){
		packetlogger_file = stdout;
	} else {
		packetlogger_file = fopen(out_filename, "wb");
	}


	if (packetlogger_file == NULL){
		fprintf(stderr, "Failed to open file %s, errno = %d\n", out_filename, errno);
		return -2;
	}

	switch (log_format){
		case LOG_FORMAT_PCAP:
			// printf("Output Format: PCAP\n");
			// write PCAP file header
			(void) fwrite(&pcap_file_header, 1, sizeof(pcap_file_header), packetlogger_file);
			break;
		case LOG_FORMAT_PACKETLOGGER:
			printf("Output Format: PacketLogger\n");
			break;
		default:
			assert(0);
			return -2;
	}
	idevice_subscription_context_t context = NULL;
	idevice_events_subscribe(&context, device_event_cb, NULL);

	while (!quit_flag) {
		sleep(1);
	}

	idevice_events_unsubscribe(context);
	stop_logging();

	fclose(packetlogger_file);

	free(udid);

	return 0;
}
