/*
 * libusbmuxd.c
 *
 * Copyright (C) 2009-2018 Nikias Bassen <nikias@gmx.li>
 * Copyright (C) 2009-2014 Martin Szulecki <m.szulecki@libimobiledevice.org>
 * Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
 *
 * 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 <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#ifdef WIN32
  #define USBMUXD_API __declspec( dllexport )
#else
  #ifdef HAVE_FVISIBILITY
    #define USBMUXD_API __attribute__((visibility("default")))
  #else
    #define USBMUXD_API
  #endif
#endif

#ifndef EPROTO
#define EPROTO 134
#endif
#ifndef EBADMSG
#define EBADMSG 104
#endif

#include <unistd.h>
#include <signal.h>

#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#ifndef HAVE_SLEEP
#define sleep(x) Sleep(x*1000)
#endif
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME) && !defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME_ERRNO_H)
extern char *program_invocation_short_name;
#endif
#ifdef __APPLE__
extern int _NSGetExecutablePath(char* buf, uint32_t* bufsize);
#include <sys/stat.h>
#endif
#endif

#ifdef HAVE_INOTIFY
#include <sys/inotify.h>
#define EVENT_SIZE  (sizeof (struct inotify_event))
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
#define USBMUXD_DIRNAME "/var/run"
#define USBMUXD_SOCKET_NAME "usbmuxd"
#endif /* HAVE_INOTIFY */

#ifndef HAVE_STPNCPY
static char* stpncpy(char *dst, const char *src, size_t len)
{
	size_t n = strlen(src);
	if (n > len)
		n = len;
	return strncpy(dst, src, len) + n;
}
#endif

#include <plist/plist.h>
#define PLIST_CLIENT_VERSION_STRING PACKAGE_STRING
#define PLIST_LIBUSBMUX_VERSION 3

static char *bundle_id = NULL;
static char *prog_name = NULL;

// usbmuxd public interface
#include "usbmuxd.h"
// usbmuxd protocol
#include "usbmuxd-proto.h"
// socket utility functions
#include "socket.h"
// misc utility functions
#include "collection.h"

static int libusbmuxd_debug = 0;
#ifndef PACKAGE
#define PACKAGE "libusbmuxd"
#endif
#define LIBUSBMUXD_DEBUG(level, format, ...) if (level <= libusbmuxd_debug) fprintf(stderr, ("[" PACKAGE "] " format), __VA_ARGS__); fflush(stderr);
#define LIBUSBMUXD_ERROR(format, ...) LIBUSBMUXD_DEBUG(0, format, __VA_ARGS__)

static struct collection devices;
static usbmuxd_event_cb_t event_cb = NULL;
#ifdef WIN32
HANDLE devmon = NULL;
#else
pthread_t devmon;
#endif
static int listenfd = -1;

static volatile int use_tag = 0;
static volatile int proto_version = 1;
static volatile int try_list_devices = 1;

/**
 * Finds a device info record by its handle.
 * if the record is not found, NULL is returned.
 */
static usbmuxd_device_info_t *devices_find(uint32_t handle)
{
	FOREACH(usbmuxd_device_info_t *dev, &devices) {
		if (dev && dev->handle == handle) {
			return dev;
		}
	} ENDFOREACH
	return NULL;
}

/**
 * Creates a socket connection to usbmuxd.
 * For Mac/Linux it is a unix domain socket,
 * for Windows it is a tcp socket.
 */
static int connect_usbmuxd_socket()
{
	char *usbmuxd_socket_addr = getenv("USBMUXD_SOCKET_ADDRESS");
	if (usbmuxd_socket_addr) {
		if (strncmp(usbmuxd_socket_addr, "UNIX:", 5) == 0) {
#if defined(WIN32) || defined(__CYGWIN__)
			/* not supported, ignore */
#else
			if (usbmuxd_socket_addr[5] != '\0') {
				return socket_connect_unix(usbmuxd_socket_addr+5);
			}
#endif
		} else {
			uint16_t port = 0;
			char *p = strrchr(usbmuxd_socket_addr, ':');
			if (p) {
				char *endp = NULL;
				long l_port = strtol(p+1, &endp, 10);
				if (endp && *endp == '\0') {
					if (l_port > 0 && l_port < 65536) {
						port = (uint16_t)l_port;
					}
				}
			}
			if (p && port > 0) {
				char *connect_addr = NULL;
				if (usbmuxd_socket_addr[0] == '[') {
					connect_addr = strdup(usbmuxd_socket_addr+1);
					connect_addr[p - usbmuxd_socket_addr - 1] = '\0';
					p = strrchr(connect_addr, ']');
					if (p) {
						*p = '\0';
					}
				} else {
					connect_addr = strdup(usbmuxd_socket_addr);
					connect_addr[p - usbmuxd_socket_addr] = '\0';
				}
				if (connect_addr && *connect_addr != '\0') {
					int res = socket_connect(connect_addr, port);
					free(connect_addr);
					return res;
				}
				free(connect_addr);
			}
		}
	}
#if defined(WIN32) || defined(__CYGWIN__)
	return socket_connect("127.0.0.1", USBMUXD_SOCKET_PORT);
#else
	return socket_connect_unix(USBMUXD_SOCKET_FILE);
#endif
}

static usbmuxd_device_info_t *device_info_from_plist(plist_t props)
{
	usbmuxd_device_info_t* devinfo = NULL;
	plist_t n = NULL;
	uint64_t val = 0;
	char *strval = NULL;

	devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t));
	if (!devinfo)
		return NULL;
	memset(devinfo, 0, sizeof(usbmuxd_device_info_t));

	n = plist_dict_get_item(props, "DeviceID");
	if (n && plist_get_node_type(n) == PLIST_UINT) {
		plist_get_uint_val(n, &val);
		devinfo->handle = (uint32_t)val;
	}

	n = plist_dict_get_item(props, "ProductID");
	if (n && plist_get_node_type(n) == PLIST_UINT) {
		plist_get_uint_val(n, &val);
		devinfo->product_id = (uint32_t)val;
	}

	n = plist_dict_get_item(props, "SerialNumber");
	if (n && plist_get_node_type(n) == PLIST_STRING) {
		plist_get_string_val(n, &strval);
		if (strval) {
			char *t = stpncpy(devinfo->udid, strval, sizeof(devinfo->udid)-1);
			*t = '\0';
			if (strlen(devinfo->udid) == 24) {
				memmove(&devinfo->udid[9], &devinfo->udid[8], 17);
				devinfo->udid[8] = '-';
			}
			if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) {
				sprintf(devinfo->udid + 32, "%08x", devinfo->handle);
			}
			free(strval);
		}
	}

	n = plist_dict_get_item(props, "ConnectionType");
	if (n && plist_get_node_type(n) == PLIST_STRING) {
		plist_get_string_val(n, &strval);
		if (strval) {
			if (strcmp(strval, "USB") == 0) {
				devinfo->conn_type = CONNECTION_TYPE_USB;
			} else if (strcmp(strval, "Network") == 0) {
				devinfo->conn_type = CONNECTION_TYPE_NETWORK;
				n = plist_dict_get_item(props, "NetworkAddress");
				if (n && plist_get_node_type(n) == PLIST_DATA) {
					char *netaddr = NULL;
					uint64_t addr_len = 0;
					plist_get_data_val(n, &netaddr, &addr_len);
					if (netaddr && addr_len > 0 && addr_len < sizeof(devinfo->conn_data)) {
						memcpy(devinfo->conn_data, netaddr, addr_len);
					}
					free(netaddr);
				}
			} else {
				LIBUSBMUXD_ERROR("%s: Unexpected ConnectionType '%s'\n", __func__, strval);
			}
			free(strval);
		}
	}

	if (!devinfo->udid[0]) {
		LIBUSBMUXD_ERROR("%s: Failed to get SerialNumber (UDID)!\n", __func__);
		free(devinfo);
		devinfo = NULL;
	}
	if (!devinfo->conn_type) {
		LIBUSBMUXD_ERROR("%s: Failed to get ConnectionType!\n", __func__);
		free(devinfo);
		devinfo = NULL;
	} else if (devinfo->conn_type == CONNECTION_TYPE_NETWORK && !devinfo->conn_data[0]) {
		LIBUSBMUXD_ERROR("%s: Failed to get EscapedFullServiceName!\n", __func__);
		free(devinfo);
		devinfo = NULL;
	}

	return devinfo;
}

static usbmuxd_device_info_t *device_info_from_device_record(struct usbmuxd_device_record *dev)
{
	if (!dev) {
		return NULL;
	}
	usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t));
	if (!devinfo) {
		LIBUSBMUXD_ERROR("%s: Out of memory while allocating device info object\n", __func__);
		return NULL;
	}

	devinfo->handle = dev->device_id;
	devinfo->product_id = dev->product_id;
	char *t = stpncpy(devinfo->udid, dev->serial_number, sizeof(devinfo->udid)-2);
	*t = '\0';
	if (strlen(devinfo->udid) == 24) {
		memmove(&devinfo->udid[9], &devinfo->udid[8], 17);
		devinfo->udid[8] = '-';
	}
	if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) {
		sprintf(devinfo->udid + 32, "%08x", devinfo->handle);
	}

	return devinfo;
}

static int receive_packet(int sfd, struct usbmuxd_header *header, void **payload, int timeout)
{
	int recv_len;
	struct usbmuxd_header hdr;
	char *payload_loc = NULL;

	header->length = 0;
	header->version = 0;
	header->message = 0;
	header->tag = 0;

	recv_len = socket_receive_timeout(sfd, &hdr, sizeof(hdr), 0, timeout);
	if (recv_len < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error receiving packet: %d\n", __func__, recv_len);
		return recv_len;
	} else if ((size_t)recv_len < sizeof(hdr)) {
		LIBUSBMUXD_DEBUG(1, "%s: Received packet is too small, got %d bytes!\n", __func__, recv_len);
		return recv_len;
	}

	uint32_t payload_size = hdr.length - sizeof(hdr);
	if (payload_size > 0) {
		payload_loc = (char*)malloc(payload_size);
		uint32_t rsize = 0;
		do {
			int res = socket_receive_timeout(sfd, payload_loc + rsize, payload_size - rsize, 0, 5000);
			if (res < 0) {
				break;
			}
			rsize += res;
		} while (rsize < payload_size);
		if (rsize != payload_size) {
			LIBUSBMUXD_DEBUG(1, "%s: Error receiving payload of size %d (bytes received: %d)\n", __func__, payload_size, rsize);
			free(payload_loc);
			return -EBADMSG;
		}
	}

	if (hdr.message == MESSAGE_PLIST) {
		char *message = NULL;
		plist_t plist = NULL;
		plist_from_xml(payload_loc, payload_size, &plist);
		free(payload_loc);

		if (!plist) {
			LIBUSBMUXD_DEBUG(1, "%s: Error getting plist from payload!\n", __func__);
			return -EBADMSG;
		}

		plist_t node = plist_dict_get_item(plist, "MessageType");
		if (!node || plist_get_node_type(node) != PLIST_STRING) {
			*payload = plist;
			hdr.length = sizeof(hdr);
			memcpy(header, &hdr, sizeof(hdr));
			return hdr.length;
		}

		plist_get_string_val(node, &message);
		if (message) {
			uint64_t val = 0;
			if (strcmp(message, "Result") == 0) {
				/* result message */
				uint32_t dwval = 0;
				plist_t n = plist_dict_get_item(plist, "Number");
				plist_get_uint_val(n, &val);
				*payload = malloc(sizeof(uint32_t));
				dwval = val;
				memcpy(*payload, &dwval, sizeof(dwval));
				hdr.length = sizeof(hdr) + sizeof(dwval);
				hdr.message = MESSAGE_RESULT;
			} else if (strcmp(message, "Attached") == 0) {
				/* device add message */
				usbmuxd_device_info_t *devinfo = NULL;
				plist_t props = plist_dict_get_item(plist, "Properties");
				if (!props) {
					LIBUSBMUXD_DEBUG(1, "%s: Could not get properties for message '%s' from plist!\n", __func__, message);
					free(message);
					plist_free(plist);
					return -EBADMSG;
				}

				devinfo = device_info_from_plist(props);
				if (!devinfo) {
					LIBUSBMUXD_DEBUG(1, "%s: Could not create device info object from properties!\n", __func__);
					free(message);
					plist_free(plist);
					return -EBADMSG;
				}
				*payload = (void*)devinfo;
				hdr.length = sizeof(hdr) + sizeof(usbmuxd_device_info_t);
				hdr.message = MESSAGE_DEVICE_ADD;
			} else if (strcmp(message, "Detached") == 0) {
				/* device remove message */
				uint32_t dwval = 0;
				plist_t n = plist_dict_get_item(plist, "DeviceID");
				if (n) {
					plist_get_uint_val(n, &val);
					*payload = malloc(sizeof(uint32_t));
					dwval = val;
					memcpy(*payload, &dwval, sizeof(dwval));
					hdr.length = sizeof(hdr) + sizeof(dwval);
					hdr.message = MESSAGE_DEVICE_REMOVE;
				}
			} else if (strcmp(message, "Paired") == 0) {
				/* device pair message */
				uint32_t dwval = 0;
				plist_t n = plist_dict_get_item(plist, "DeviceID");
				if (n) {
					plist_get_uint_val(n, &val);
					*payload = malloc(sizeof(uint32_t));
					dwval = val;
					memcpy(*payload, &dwval, sizeof(dwval));
					hdr.length = sizeof(hdr) + sizeof(dwval);
					hdr.message = MESSAGE_DEVICE_PAIRED;
				}
			} else {
				char *xml = NULL;
				uint32_t len = 0;
				plist_to_xml(plist, &xml, &len);
				LIBUSBMUXD_DEBUG(1, "%s: Unexpected message '%s' in plist:\n%s\n", __func__, message, xml);
				free(xml);
				free(message);
				plist_free(plist);
				return -EBADMSG;
			}
			free(message);
		}
		plist_free(plist);
	} else if (hdr.message == MESSAGE_DEVICE_ADD) {
		usbmuxd_device_info_t *devinfo = device_info_from_device_record((struct usbmuxd_device_record*)payload_loc);
		free(payload_loc);
		*payload = devinfo;
	} else {
		*payload = payload_loc;
	}

	memcpy(header, &hdr, sizeof(hdr));

	return hdr.length;
}

/**
 * Retrieves the result code to a previously sent request.
 */
static int usbmuxd_get_result(int sfd, uint32_t tag, uint32_t *result, void **result_plist)
{
	struct usbmuxd_header hdr;
	int recv_len;
	uint32_t *res = NULL;

	if (!result) {
		return -EINVAL;
	}
	*result = -1;
	if (result_plist) {
		*result_plist = NULL;
	}

	recv_len = receive_packet(sfd, &hdr, (void**)&res, 5000);
	if (recv_len < 0 || (size_t)recv_len < sizeof(hdr)) {
		free(res);
		return (recv_len < 0 ? recv_len : -EPROTO);
	}

	if (hdr.message == MESSAGE_RESULT) {
		int ret = 0;
		if (hdr.tag != tag) {
			LIBUSBMUXD_DEBUG(1, "%s: WARNING: tag mismatch (%d != %d). Proceeding anyway.\n", __func__, hdr.tag, tag);
		}
		if (res) {
			memcpy(result, res, sizeof(uint32_t));
			ret = 1;
		}
		if (res)
			free(res);
		return ret;
	} else if (hdr.message == MESSAGE_PLIST) {
		if (!result_plist) {
			LIBUSBMUXD_DEBUG(1, "%s: MESSAGE_PLIST result but result_plist pointer is NULL!\n", __func__);
			return -1;
		}
		*result_plist = (plist_t)res;
		*result = RESULT_OK;
		return 1;
	}

	LIBUSBMUXD_DEBUG(1, "%s: Unexpected message of type %d received!\n", __func__, hdr.message);
	if (res)
		free(res);
	return -EPROTO;
}

static int send_packet(int sfd, uint32_t message, uint32_t tag, void *payload, uint32_t payload_size)
{
	struct usbmuxd_header header;

	header.length = sizeof(struct usbmuxd_header);
	header.version = proto_version;
	header.message = message;
	header.tag = tag;
	if (payload && (payload_size > 0)) {
		header.length += payload_size;
	}
	int sent = socket_send(sfd, &header, sizeof(header));
	if (sent != sizeof(header)) {
		LIBUSBMUXD_DEBUG(1, "%s: ERROR: could not send packet header\n", __func__);
		return -1;
	}
	if (payload && (payload_size > 0)) {
		uint32_t ssize = 0;
		do {
			int res = socket_send(sfd, (char*)payload + ssize, payload_size - ssize);
			if (res < 0) {
				break;
			}
			ssize += res;
		} while (ssize < payload_size);
		sent += ssize;
	}
	if (sent != (int)header.length) {
		LIBUSBMUXD_DEBUG(1, "%s: ERROR: could not send whole packet (sent %d of %d)\n", __func__, sent, header.length);
		socket_close(sfd);
		return -1;
	}
	return sent;
}

static int send_plist_packet(int sfd, uint32_t tag, plist_t message)
{
	int res;
	char *payload = NULL;
	uint32_t payload_size = 0;

	plist_to_xml(message, &payload, &payload_size);
	res = send_packet(sfd, MESSAGE_PLIST, tag, payload, payload_size);
	free(payload);

	return res;
}

static void get_bundle_id()
{
#if defined (__APPLE__)
	char CONTENTS_INFO_PLIST[] = "Contents/Info.plist";
	char* execpath = malloc(1024);
	uint32_t size = 1024;
	if (_NSGetExecutablePath(execpath, &size) != 0) {
		free(execpath);
		return;
	}
	// strip off executable name
	char *p = execpath + strlen(execpath) - 1;
	while (p > execpath && *p != '/') p--;
	if (*p == '/') *p = '\0';
	// now walk back trying to find "/Contents/MacOS", and strip it off
	int macos_found = 0;
	while (p > execpath) {
		p--;
		if (*p != '/') continue;
		if (strcmp(p, "/.") == 0) {
			*p = '\0';
		} else if (!macos_found && strcmp(p, "/MacOS") == 0) {
			*p = '\0';
			macos_found++;
		} else if (macos_found && strcmp(p, "/Contents") == 0) {
			*p = '\0';
			break;
		} else {
			break;
		}
	}
	// now just append "/Contents/Info.plist"
	size_t len = strlen(execpath) + sizeof(CONTENTS_INFO_PLIST) + 1;
	char *infopl = malloc(len);
	snprintf(infopl, len, "%s/%s", execpath, CONTENTS_INFO_PLIST);
	free(execpath);
	struct stat fst;
	fst.st_size = 0;
	if (stat(infopl, &fst) != 0) {
		free(infopl);
		return;
	}
	size_t fsize = fst.st_size;
	if (fsize < 8) {
		free(infopl);
		return;
	}
	FILE *f = fopen(infopl, "r");
	free(infopl);
	if (!f)
		return;
	char *buf = malloc(fsize);
	if (!buf)
		return;
	if (fread(buf, 1, fsize, f) == fsize) {
		plist_t pl = NULL;
		if (memcmp(buf, "bplist00", 8) == 0) {
			plist_from_bin(buf, fst.st_size, &pl);
		} else {
			plist_from_xml(buf, fst.st_size, &pl);
		}
		if (pl) {
			plist_t bid = plist_dict_get_item(pl, "CFBundleIdentifier");
			if (plist_get_node_type(bid) == PLIST_STRING) {
				plist_get_string_val(bid, &bundle_id);
			}
			plist_free(pl);
		}
	}
	free(buf);
	fclose(f);
#endif
}

static void get_prog_name()
{
#if defined(__APPLE__) || defined(__FreeBSD__)
	const char *pname = getprogname();
	if (pname) {
		prog_name = strdup(pname);
	}
#elif defined (WIN32)
	TCHAR *_pname = malloc((MAX_PATH+1) * sizeof(TCHAR));
	if (GetModuleFileName(NULL, _pname, MAX_PATH+1) > 0) {
		char* pname = NULL;
	#if defined(UNICODE) || defined(_UNICODE)
		char* __pname = NULL;
		int l = WideCharToMultiByte(CP_UTF8, 0, _pname, -1, NULL, 0, NULL, NULL);
		if (l > 0) {
			__pname = malloc(l);
			if (WideCharToMultiByte(CP_UTF8, 0, _pname, -1, __pname, l, NULL, NULL) > 0) {
				pname = __pname;
			}
		}
	#else
		pname = _pname;
	#endif
		if (pname) {
			char *p = pname+strlen(pname)-1;
			while (p > pname && *p != '\\' && *p != '/') p--;
			if (*p == '\\' || *p == '/') p++;
			prog_name = strdup(p);
		}
	#if defined(UNICODE) || defined(_UNICODE)
		free(__pname);
	#endif
	}
	free(_pname);
#elif defined (HAVE_PROGRAM_INVOCATION_SHORT_NAME)
	char *pname = program_invocation_short_name;
	if (pname) {
		prog_name = strdup(pname);
	}
#elif defined (__linux__)
	FILE *f = fopen("/proc/self/stat", "r");
	if (!f) {
		return;
	}
	char *tmpbuf = malloc(512);
	size_t r = fread(tmpbuf, 1, 512, f);
	if (r > 0) {
		char *p = tmpbuf;
		while ((p-tmpbuf < r) && (*p != '(') && (*p != '\0')) p++;
		if (*p == '(') {
			p++;
			char *pname = p;
			while ((p-tmpbuf < r) && (*p != ')') && (*p != '\0')) p++;
			if (*p == ')') {
				*p = '\0';
				prog_name = strdup(pname);
			}
		}
	}
	free(tmpbuf);
	fclose(f);
#else
	#warning FIXME: no method to determine program name
#endif
}

static plist_t create_plist_message(const char* message_type)
{
	if (!bundle_id) {
		get_bundle_id();
	}
	if (!prog_name) {
		get_prog_name();
	}
	plist_t plist = plist_new_dict();
	if (bundle_id) {
		plist_dict_set_item(plist, "BundleID", plist_new_string(bundle_id));
	}
	plist_dict_set_item(plist, "ClientVersionString", plist_new_string(PLIST_CLIENT_VERSION_STRING));
	plist_dict_set_item(plist, "MessageType", plist_new_string(message_type));
	if (prog_name) {
		plist_dict_set_item(plist, "ProgName", plist_new_string(prog_name));
	}
	plist_dict_set_item(plist, "kLibUSBMuxVersion", plist_new_uint(PLIST_LIBUSBMUX_VERSION));
	return plist;
}

static int send_listen_packet(int sfd, uint32_t tag)
{
	int res = 0;
	if (proto_version == 1) {
		/* construct message plist */
		plist_t plist = create_plist_message("Listen");

		res = send_plist_packet(sfd, tag, plist);
		plist_free(plist);
	} else {
		/* binary packet */
		res = send_packet(sfd, MESSAGE_LISTEN, tag, NULL, 0);
	}
	return res;
}

static int send_connect_packet(int sfd, uint32_t tag, uint32_t device_id, uint16_t port)
{
	int res = 0;
	if (proto_version == 1) {
		/* construct message plist */
		plist_t plist = create_plist_message("Connect");
		plist_dict_set_item(plist, "DeviceID", plist_new_uint(device_id));
		plist_dict_set_item(plist, "PortNumber", plist_new_uint(htons(port)));

		res = send_plist_packet(sfd, tag, plist);
		plist_free(plist);
	} else {
		/* binary packet */
		struct {
			uint32_t device_id;
			uint16_t port;
			uint16_t reserved;
		} conninfo;

		conninfo.device_id = device_id;
		conninfo.port = htons(port);
		conninfo.reserved = 0;

		res = send_packet(sfd, MESSAGE_CONNECT, tag, &conninfo, sizeof(conninfo));
	}
	return res;
}

static int send_list_devices_packet(int sfd, uint32_t tag)
{
	int res = -1;

	/* construct message plist */
	plist_t plist = create_plist_message("ListDevices");

	res = send_plist_packet(sfd, tag, plist);
	plist_free(plist);

	return res;
}

static int send_read_buid_packet(int sfd, uint32_t tag)
{
	int res = -1;

	/* construct message plist */
	plist_t plist = create_plist_message("ReadBUID");

	res = send_plist_packet(sfd, tag, plist);
	plist_free(plist);

	return res;
}

static int send_pair_record_packet(int sfd, uint32_t tag, const char* msgtype, const char* pair_record_id, uint32_t device_id, plist_t data)
{
	int res = -1;

	/* construct message plist */
	plist_t plist = create_plist_message(msgtype);
	plist_dict_set_item(plist, "PairRecordID", plist_new_string(pair_record_id));
	if (data) {
		plist_dict_set_item(plist, "PairRecordData", plist_copy(data));
	}
	if (device_id > 0) {
		plist_dict_set_item(plist, "DeviceID", plist_new_uint(device_id));
	}
	
	res = send_plist_packet(sfd, tag, plist);
	plist_free(plist);

	return res;
}

/**
 * Generates an event, i.e. calls the callback function.
 * A reference to a populated usbmuxd_event_t with information about the event
 * and the corresponding device will be passed to the callback function.
 */
static void generate_event(usbmuxd_event_cb_t callback, const usbmuxd_device_info_t *dev, enum usbmuxd_event_type event, void *user_data)
{
	usbmuxd_event_t ev;

	if (!callback || !dev) {
		return;
	}

	ev.event = event;
	memcpy(&ev.device, dev, sizeof(usbmuxd_device_info_t));

	callback(&ev, user_data);
}

static int usbmuxd_listen_poll()
{
	int sfd;

	sfd = connect_usbmuxd_socket();
	if (sfd < 0) {
		while (event_cb) {
			if ((sfd = connect_usbmuxd_socket()) >= 0) {
				break;
			}
			sleep(1);
		}
	}

	return sfd;
}

#ifdef HAVE_INOTIFY
static int use_inotify = 1;

static int usbmuxd_listen_inotify()
{
	int inot_fd;
	int watch_d;
	int sfd;

	if (!use_inotify) {
		return -2;
	}

	sfd = connect_usbmuxd_socket();
	if (sfd >= 0)
		return sfd;

	sfd = -1;
	inot_fd = inotify_init ();
	if (inot_fd < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Failed to setup inotify\n", __func__);
		return -2;
	}

	/* inotify is setup, listen for events that concern us */
	watch_d = inotify_add_watch (inot_fd, USBMUXD_DIRNAME, IN_CREATE);
	if (watch_d < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Failed to setup watch descriptor for socket dir\n", __func__);
		close (inot_fd);
		return -2;
	}

	while (1) {
		ssize_t len, i;
		char buff[EVENT_BUF_LEN] = {0};

		i = 0;
		len = read (inot_fd, buff, EVENT_BUF_LEN -1);
		if (len < 0)
			goto end;
		while (i < len) {
			struct inotify_event *pevent = (struct inotify_event *) & buff[i];

			/* check that it's ours */
			if (pevent->mask & IN_CREATE &&
			    pevent->len &&
			    pevent->name[0] != 0 &&
			    strcmp(pevent->name, USBMUXD_SOCKET_NAME) == 0) {
				/* retry if usbmuxd isn't ready yet */
				int retry = 10;
				while (--retry >= 0) {
					if ((sfd = connect_usbmuxd_socket ()) >= 0) {
						break;
					}
					sleep(1);
				}
				goto end;
			}
			i += EVENT_SIZE + pevent->len;
		}
	}

end:
	inotify_rm_watch(inot_fd, watch_d);
	close(inot_fd);

	return sfd;
}
#endif /* HAVE_INOTIFY */

/**
 * Tries to connect to usbmuxd and wait if it is not running.
 */
static int usbmuxd_listen()
{
	int sfd;
	uint32_t res = -1;
	int tag;

retry:

#ifdef HAVE_INOTIFY
	sfd = usbmuxd_listen_inotify();
	if (sfd == -2)
		sfd = usbmuxd_listen_poll();
#else
	sfd = usbmuxd_listen_poll();
#endif

	if (sfd < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: ERROR: usbmuxd was supposed to be running here...\n", __func__);
		return sfd;
	}

	tag = ++use_tag;
	if (send_listen_packet(sfd, tag) <= 0) {
		LIBUSBMUXD_DEBUG(1, "%s: ERROR: could not send listen packet\n", __func__);
		socket_close(sfd);
		return -1;
	}
	if ((usbmuxd_get_result(sfd, tag, &res, NULL) == 1) && (res != 0)) {
		socket_close(sfd);
		if ((res == RESULT_BADVERSION) && (proto_version == 1)) {
			proto_version = 0;
			goto retry;
		}
		LIBUSBMUXD_DEBUG(1, "%s: ERROR: did not get OK but %d\n", __func__, res);
		return -1;
	}
	return sfd;
}

/**
 * Waits for an event to occur, i.e. a packet coming from usbmuxd.
 * Calls generate_event to pass the event via callback to the client program.
 */
static int get_next_event(int sfd, usbmuxd_event_cb_t callback, void *user_data)
{
	struct usbmuxd_header hdr;
	void *payload = NULL;

	/* block until we receive something */
	if (receive_packet(sfd, &hdr, &payload, 0) < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error in usbmuxd connection, disconnecting all devices!\n", __func__);
		// when then usbmuxd connection fails,
		// generate remove events for every device that
		// is still present so applications know about it
		FOREACH(usbmuxd_device_info_t *dev, &devices) {
			generate_event(callback, dev, UE_DEVICE_REMOVE, user_data);
			collection_remove(&devices, dev);
			free(dev);
		} ENDFOREACH
		return -EIO;
	}

	if ((hdr.length > sizeof(hdr)) && !payload) {
		LIBUSBMUXD_DEBUG(1, "%s: Invalid packet received, payload is missing!\n", __func__);
		return -EBADMSG;
	}

	if (hdr.message == MESSAGE_DEVICE_ADD) {
		usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)payload;
		collection_add(&devices, devinfo);
		generate_event(callback, devinfo, UE_DEVICE_ADD, user_data);
		payload = NULL;
	} else if (hdr.message == MESSAGE_DEVICE_REMOVE) {
		uint32_t handle;
		usbmuxd_device_info_t *devinfo;

		memcpy(&handle, payload, sizeof(uint32_t));

		devinfo = devices_find(handle);
		if (!devinfo) {
			LIBUSBMUXD_DEBUG(1, "%s: WARNING: got device remove message for handle %d, but couldn't find the corresponding handle in the device list. This event will be ignored.\n", __func__, handle);
		} else {
			generate_event(callback, devinfo, UE_DEVICE_REMOVE, user_data);
			collection_remove(&devices, devinfo);
			free(devinfo);
		}
	} else if (hdr.message == MESSAGE_DEVICE_PAIRED) {
		uint32_t handle;
		usbmuxd_device_info_t *devinfo;

		memcpy(&handle, payload, sizeof(uint32_t));

		devinfo = devices_find(handle);
		if (!devinfo) {
			LIBUSBMUXD_DEBUG(1, "%s: WARNING: got paired message for device handle %d, but couldn't find the corresponding handle in the device list. This event will be ignored.\n", __func__, handle);
		} else {
			generate_event(callback, devinfo, UE_DEVICE_PAIRED, user_data);
		}
	} else if (hdr.length > 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Unexpected message type %d length %d received!\n", __func__, hdr.message, hdr.length);
	}
	if (payload) {
		free(payload);
	}
	return 0;
}

static void device_monitor_cleanup(void* data)
{
	FOREACH(usbmuxd_device_info_t *dev, &devices) {
		collection_remove(&devices, dev);
		free(dev);
	} ENDFOREACH
	collection_free(&devices);

	socket_close(listenfd);
	listenfd = -1;
}

/**
 * Device Monitor thread function.
 *
 * This function sets up a connection to usbmuxd
 */
static void *device_monitor(void *data)
{
	collection_init(&devices);

#ifndef WIN32
	pthread_cleanup_push(device_monitor_cleanup, NULL);
#endif
	while (event_cb) {

		listenfd = usbmuxd_listen();
		if (listenfd < 0) {
			continue;
		}

		while (event_cb) {
			int res = get_next_event(listenfd, event_cb, data);
			if (res < 0) {
			    break;
			}
		}
	}

#ifndef WIN32
	pthread_cleanup_pop(1);
#else
	device_monitor_cleanup(NULL);
#endif
	return NULL;
}

USBMUXD_API int usbmuxd_subscribe(usbmuxd_event_cb_t callback, void *user_data)
{
	int res;

	if (!callback) {
		return -EINVAL;
	}
	event_cb = callback;

#ifdef WIN32
	res = 0;
	devmon = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)device_monitor, user_data, 0, NULL);
	if (devmon == NULL) {
		res = GetLastError();
	}
#else
	res = pthread_create(&devmon, NULL, device_monitor, user_data);
#endif
	if (res != 0) {
		LIBUSBMUXD_DEBUG(1, "%s: ERROR: Could not start device watcher thread!\n", __func__);
		return res;
	}
	return 0;
}

USBMUXD_API int usbmuxd_unsubscribe()
{
	int res;
	event_cb = NULL;

	socket_shutdown(listenfd, SHUT_RDWR);

#ifdef WIN32
	if (devmon != NULL) {
		res = WaitForSingleObject(devmon, INFINITE);
		if (res != 0) {
			return res;
		}
	}
#else
	res = pthread_kill(devmon, 0);
	if (res == 0) {
		pthread_cancel(devmon);
		res = pthread_join(devmon, NULL);
	}
	if ((res != 0) && (res != ESRCH)) {
		return res;
	}
#endif

	return 0;
}

USBMUXD_API int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list)
{
	int sfd;
	int tag;
	int listen_success = 0;
	uint32_t res;
	struct collection tmpdevs;
	usbmuxd_device_info_t *newlist = NULL;
	struct usbmuxd_header hdr;
	int dev_cnt = 0;
	void *payload = NULL;

	*device_list = NULL;

retry:
	sfd = connect_usbmuxd_socket();
	if (sfd < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: error opening socket!\n", __func__);
		return sfd;
	}

	tag = ++use_tag;
	if ((proto_version == 1) && (try_list_devices)) {
		if (send_list_devices_packet(sfd, tag) > 0) {
			plist_t list = NULL;
			if ((usbmuxd_get_result(sfd, tag, &res, &list) == 1) && (res == 0)) {
				plist_t devlist = plist_dict_get_item(list, "DeviceList");
				if (devlist && plist_get_node_type(devlist) == PLIST_ARRAY) {
					collection_init(&tmpdevs);
					uint32_t numdevs = plist_array_get_size(devlist);
					uint32_t i;
					for (i = 0; i < numdevs; i++) {
						plist_t pdev = plist_array_get_item(devlist, i);
						plist_t props = plist_dict_get_item(pdev, "Properties");
						usbmuxd_device_info_t *devinfo = device_info_from_plist(props);
						if (!devinfo) {
							socket_close(sfd);
							LIBUSBMUXD_DEBUG(1, "%s: Could not create device info object from properties!\n", __func__);
							plist_free(list);
							return -1;
						}
						collection_add(&tmpdevs, devinfo);
					}
					plist_free(list);
					goto got_device_list;
				}
			} else {
				if (res == RESULT_BADVERSION) {
					proto_version = 0;
				}
				socket_close(sfd);
				try_list_devices = 0;
				plist_free(list);
				goto retry;
			}
			plist_free(list);
		}
	}

	tag = ++use_tag;
	if (send_listen_packet(sfd, tag) > 0) {
		res = -1;
		// get response
		if ((usbmuxd_get_result(sfd, tag, &res, NULL) == 1) && (res == 0)) {
			listen_success = 1;
		} else {
			socket_close(sfd);
			if ((res == RESULT_BADVERSION) && (proto_version == 1)) {
				proto_version = 0;
				goto retry;
			}
			LIBUSBMUXD_DEBUG(1, "%s: Did not get response to scan request (with result=0)...\n", __func__);
			return res;
		}
	}

	if (!listen_success) {
		socket_close(sfd);
		LIBUSBMUXD_DEBUG(1, "%s: Could not send listen request!\n", __func__);
		return -1;
	}

	collection_init(&tmpdevs);

	// receive device list
	while (1) {
		if (receive_packet(sfd, &hdr, &payload, 100) > 0) {
			if (hdr.message == MESSAGE_DEVICE_ADD) {
				usbmuxd_device_info_t *devinfo = payload;
				collection_add(&tmpdevs, devinfo);
				payload = NULL;
			} else if (hdr.message == MESSAGE_DEVICE_REMOVE) {
				uint32_t handle;
				usbmuxd_device_info_t *devinfo = NULL;

				memcpy(&handle, payload, sizeof(uint32_t));

				FOREACH(usbmuxd_device_info_t *di, &tmpdevs) {
					if (di && di->handle == handle) {
						devinfo = di;
						break;
					}
				} ENDFOREACH
				if (devinfo) {
					collection_remove(&tmpdevs, devinfo);
					free(devinfo);
				}
			} else {
				LIBUSBMUXD_DEBUG(1, "%s: Unexpected message %d\n", __func__, hdr.message);
			}
			if (payload)
				free(payload);
		} else {
			// we _should_ have all of them now.
			// or perhaps an error occured.
			break;
		}
	}

got_device_list:

	// explicitly close connection
	socket_close(sfd);

	// create copy of device info entries from collection
	newlist = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t) * (collection_count(&tmpdevs) + 1));
	dev_cnt = 0;
	FOREACH(usbmuxd_device_info_t *di, &tmpdevs) {
		if (di) {
			memcpy(&newlist[dev_cnt], di, sizeof(usbmuxd_device_info_t));
			free(di);
			dev_cnt++;
		}
	} ENDFOREACH
	collection_free(&tmpdevs);

	memset(&newlist[dev_cnt], 0, sizeof(usbmuxd_device_info_t));
	*device_list = newlist;

	return dev_cnt;
}

USBMUXD_API int usbmuxd_device_list_free(usbmuxd_device_info_t **device_list)
{
	if (device_list) {
		free(*device_list);
	}
	return 0;
}

USBMUXD_API int usbmuxd_get_device_by_udid(const char *udid, usbmuxd_device_info_t *device)
{
	usbmuxd_device_info_t *dev_list = NULL;
	usbmuxd_device_info_t *dev = NULL;
	int result = 0;
	int i;

	if (!device) {
		return -EINVAL;
	}
	if (usbmuxd_get_device_list(&dev_list) < 0) {
		return -ENODEV;
	}

	for (i = 0; dev_list[i].handle > 0; i++) {
	 	if (!udid) {
			if (dev_list[i].conn_type == CONNECTION_TYPE_USB) {
				dev = &dev_list[i];
				break;
			}
		} else if (!strcmp(udid, dev_list[i].udid)) {
			if (dev_list[i].conn_type == CONNECTION_TYPE_USB) {
				dev = &dev_list[i];
				break;
			}
		}
	}

	if (dev) {
		device->handle = dev->handle;
		device->product_id = dev->product_id;
		char *t = stpncpy(device->udid, dev->udid, sizeof(device->udid)-1);
		*t = '\0';
		device->conn_type = dev->conn_type;
		memcpy(device->conn_data, dev->conn_data, sizeof(device->conn_data));
		result = 1;
	}

	usbmuxd_device_list_free(&dev_list);

	return result;
}

USBMUXD_API int usbmuxd_get_device(const char *udid, usbmuxd_device_info_t *device, enum usbmux_lookup_options options)
{
	usbmuxd_device_info_t *dev_list = NULL;
	usbmuxd_device_info_t *dev_network = NULL;
	usbmuxd_device_info_t *dev_usbmuxd = NULL;
	usbmuxd_device_info_t *dev = NULL;
	int result = 0;
	int i;

	if (!device) {
		return -EINVAL;
	}
	if (usbmuxd_get_device_list(&dev_list) < 0) {
		return -ENODEV;
	}

	if (options == 0) {
		options = DEVICE_LOOKUP_USBMUX;
	}

	for (i = 0; dev_list[i].handle > 0; i++) {
		if (!udid) {
			if ((options & DEVICE_LOOKUP_USBMUX) && (dev_list[i].conn_type == CONNECTION_TYPE_USB)) {
				dev_usbmuxd = &dev_list[i];
				break;
			} else if ((options & DEVICE_LOOKUP_NETWORK) && (dev_list[i].conn_type == CONNECTION_TYPE_NETWORK)) {
				dev_network = &dev_list[i];
				break;
			}
		} else if (!strcmp(udid, dev_list[i].udid)) {
			if ((options & DEVICE_LOOKUP_USBMUX) && (dev_list[i].conn_type == CONNECTION_TYPE_USB)) {
				dev_usbmuxd = &dev_list[i];
			} else if ((options & DEVICE_LOOKUP_NETWORK) && (dev_list[i].conn_type == CONNECTION_TYPE_NETWORK)) {
				dev_network = &dev_list[i];
			}
		}
		if (dev_usbmuxd && dev_network) {
			break;
		}
	}

	if (dev_network && dev_usbmuxd) {
		dev = (options & DEVICE_LOOKUP_PREFER_NETWORK) ? dev_network : dev_usbmuxd;
	} else if (dev_network) {
		dev = dev_network;
	} else if (dev_usbmuxd) {
		dev = dev_usbmuxd;
	}

	if (dev) {
		device->handle = dev->handle;
		device->product_id = dev->product_id;
		char *t = stpncpy(device->udid, dev->udid, sizeof(device->udid)-1);
		*t = '\0';
		device->conn_type = dev->conn_type;
		memcpy(device->conn_data, dev->conn_data, sizeof(device->conn_data));
		result = 1;
	}

	free(dev_list);

	return result;
}

USBMUXD_API int usbmuxd_connect(const uint32_t handle, const unsigned short port)
{
	int sfd;
	int tag;
	int connected = 0;
	uint32_t res = -1;

retry:
	sfd = connect_usbmuxd_socket();
	if (sfd < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n",
				__func__, strerror(errno));
		return sfd;
	}

	tag = ++use_tag;
	if (send_connect_packet(sfd, tag, (uint32_t)handle, (uint16_t)port) <= 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error sending connect message!\n", __func__);
	} else {
		// read ACK
		LIBUSBMUXD_DEBUG(2, "%s: Reading connect result...\n", __func__);
		if (usbmuxd_get_result(sfd, tag, &res, NULL) == 1) {
			if (res == 0) {
				LIBUSBMUXD_DEBUG(2, "%s: Connect success!\n", __func__);
				connected = 1;
			} else {
				if ((res == RESULT_BADVERSION) && (proto_version == 1)) {
					proto_version = 0;
					socket_close(sfd);
					goto retry;
				}
				LIBUSBMUXD_DEBUG(1, "%s: Connect failed, Error code=%d\n", __func__, res);
			}
		}
	}

	if (connected) {
		return sfd;
	}

	socket_close(sfd);

	return -1;
}

USBMUXD_API int usbmuxd_disconnect(int sfd)
{
	return socket_close(sfd);
}

USBMUXD_API int usbmuxd_send(int sfd, const char *data, uint32_t len, uint32_t *sent_bytes)
{
	int num_sent;

	if (sfd < 0) {
		return -EINVAL;
	}
	
	num_sent = socket_send(sfd, (void*)data, len);
	if (num_sent < 0) {
		*sent_bytes = 0;
		num_sent = errno;
		LIBUSBMUXD_DEBUG(1, "%s: Error %d when sending: %s\n", __func__, num_sent, strerror(num_sent));
		return -num_sent;
	} else if ((uint32_t)num_sent < len) {
		LIBUSBMUXD_DEBUG(1, "%s: Warning: Did not send enough (only %d of %d)\n", __func__, num_sent, len);
	}

	*sent_bytes = num_sent;

	return 0;
}

USBMUXD_API int usbmuxd_recv_timeout(int sfd, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout)
{
	int num_recv = socket_receive_timeout(sfd, (void*)data, len, 0, timeout);
	if (num_recv < 0) {
		*recv_bytes = 0;
		return num_recv;
	}

	*recv_bytes = num_recv;

	return 0;
}

USBMUXD_API int usbmuxd_recv(int sfd, char *data, uint32_t len, uint32_t *recv_bytes)
{
	return usbmuxd_recv_timeout(sfd, data, len, recv_bytes, 5000);
}

USBMUXD_API int usbmuxd_read_buid(char **buid)
{
	int sfd;
	int tag;
	int ret = -1;

	if (!buid) {
		return -EINVAL;
	}
	*buid = NULL;

	sfd = connect_usbmuxd_socket();
	if (sfd < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n", __func__, strerror(errno));
		return sfd;
	}

	proto_version = 1;
	tag = ++use_tag;
	if (send_read_buid_packet(sfd, tag) <= 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error sending ReadBUID message!\n", __func__);
	} else {
		uint32_t rc = 0;
		plist_t pl = NULL;
		ret = usbmuxd_get_result(sfd, tag, &rc, &pl);
		if ((ret == 1) && (rc == 0)) {
			plist_t node = plist_dict_get_item(pl, "BUID");
			if (node && plist_get_node_type(node) == PLIST_STRING) {
				plist_get_string_val(node, buid);
			}
			ret = 0;
		} else if (ret == 1) {
			ret = -(int)rc;
		}
		plist_free(pl);
	}
	socket_close(sfd);

	return ret;
}

USBMUXD_API int usbmuxd_read_pair_record(const char* record_id, char **record_data, uint32_t *record_size)
{
	int sfd;
	int tag;
	int ret = -1;

	if (!record_id || !record_data || !record_size) {
		return -EINVAL;
	}
	*record_data = NULL;
	*record_size = 0;

	sfd = connect_usbmuxd_socket();
	if (sfd < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n",
				__func__, strerror(errno));
		return sfd;
	}

	proto_version = 1;
	tag = ++use_tag;

	if (send_pair_record_packet(sfd, tag, "ReadPairRecord", record_id, 0, NULL) <= 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error sending ReadPairRecord message!\n", __func__);
	} else {
		uint32_t rc = 0;
		plist_t pl = NULL;
		ret = usbmuxd_get_result(sfd, tag, &rc, &pl);
		if ((ret == 1) && (rc == 0)) {
			plist_t node = plist_dict_get_item(pl, "PairRecordData");
			if (node && plist_get_node_type(node) == PLIST_DATA) {
				uint64_t int64val = 0;
				plist_get_data_val(node, record_data, &int64val);
				if (*record_data && int64val > 0) {
					*record_size = (uint32_t)int64val;
					ret = 0;
				}
			}
		} else if (ret == 1) {
			ret = -(int)rc;
		}
		plist_free(pl);
	}
	socket_close(sfd);

	return ret;
}

USBMUXD_API int usbmuxd_save_pair_record_with_device_id(const char* record_id, uint32_t device_id, const char *record_data, uint32_t record_size)
{
	int sfd;
	int tag;
	int ret = -1;

	if (!record_id || !record_data || !record_size) {
		return -EINVAL;
	}

	sfd = connect_usbmuxd_socket();
	if (sfd < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n",
				__func__, strerror(errno));
		return sfd;
	}

	proto_version = 1;
	tag = ++use_tag;

	plist_t data = plist_new_data(record_data, record_size);
	if (send_pair_record_packet(sfd, tag, "SavePairRecord", record_id, device_id, data) <= 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error sending SavePairRecord message!\n", __func__);
	} else {
		uint32_t rc = 0;
		ret = usbmuxd_get_result(sfd, tag, &rc, NULL);
		if ((ret == 1) && (rc == 0)) {
			ret = 0;
		} else if (ret == 1) {
			ret = -(int)rc;
			LIBUSBMUXD_DEBUG(1, "%s: Error: saving pair record failed: %d\n", __func__, ret);
		}
	}
	plist_free(data);
	socket_close(sfd);

	return ret;
}

USBMUXD_API int usbmuxd_save_pair_record(const char* record_id, const char *record_data, uint32_t record_size)
{
	return usbmuxd_save_pair_record_with_device_id(record_id, 0, record_data, record_size);
}

USBMUXD_API int usbmuxd_delete_pair_record(const char* record_id)
{
	int sfd;
	int tag;
	int ret = -1;

	if (!record_id) {
		return -EINVAL;
	}

	sfd = connect_usbmuxd_socket();
	if (sfd < 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error: Connection to usbmuxd failed: %s\n",
				__func__, strerror(errno));
		return sfd;
	}

	proto_version = 1;
	tag = ++use_tag;

	if (send_pair_record_packet(sfd, tag, "DeletePairRecord", record_id, 0, NULL) <= 0) {
		LIBUSBMUXD_DEBUG(1, "%s: Error sending DeletePairRecord message!\n", __func__);
	} else {
		uint32_t rc = 0;
		ret = usbmuxd_get_result(sfd, tag, &rc, NULL);
		if ((ret == 1) && (rc == 0)) {
			ret = 0;
		} else if (ret == 1) {
			ret = -(int)rc;
			LIBUSBMUXD_DEBUG(1, "%s: Error: deleting pair record failed: %d\n", __func__, ret);
		}
	}
	socket_close(sfd);

	return ret;
}

USBMUXD_API void libusbmuxd_set_use_inotify(int set)
{
#ifdef HAVE_INOTIFY
	use_inotify = set;
#endif
	return;
}

USBMUXD_API void libusbmuxd_set_debug_level(int level)
{
	libusbmuxd_debug = level;
	socket_set_verbose(level);
}
