diff options
| author | 2013-12-12 01:30:04 +0100 | |
|---|---|---|
| committer | 2013-12-12 01:30:04 +0100 | |
| commit | 01cb5daf51612f9b949cd9643a584e7da6ff8c98 (patch) | |
| tree | 13d4a7711a5ab1cf7d780409fea8efc78c892498 /src | |
| parent | 42802fb96990578053c6da30e31bd68dda0fc558 (diff) | |
| download | libusbmuxd-01cb5daf51612f9b949cd9643a584e7da6ff8c98.tar.gz libusbmuxd-01cb5daf51612f9b949cd9643a584e7da6ff8c98.tar.bz2 | |
implement ListDevices command and use it in usbmuxd_get_device_list()
Diffstat (limited to 'src')
| -rw-r--r-- | src/libusbmuxd.c | 162 | 
1 files changed, 131 insertions, 31 deletions
| diff --git a/src/libusbmuxd.c b/src/libusbmuxd.c index 352a578..cc228b7 100644 --- a/src/libusbmuxd.c +++ b/src/libusbmuxd.c @@ -97,6 +97,7 @@ static int listenfd = -1;  static int use_tag = 0;  #ifdef HAVE_PLIST  static int proto_version = 1; +static int try_list_devices = 1;  #else  static int proto_version = 0;  #endif @@ -129,6 +130,49 @@ static int connect_usbmuxd_socket()  #endif  } +#ifdef HAVE_PLIST +static struct usbmuxd_device_record* device_record_from_plist(plist_t props) +{ +	struct usbmuxd_device_record* dev = NULL; +	plist_t n = NULL; +	uint64_t val = 0; +	char *strval = NULL; + +	dev = (struct usbmuxd_device_record*)malloc(sizeof(struct usbmuxd_device_record)); +	if (!dev) +		return NULL; +	memset(dev, 0, sizeof(struct usbmuxd_device_record)); + +	n = plist_dict_get_item(props, "DeviceID"); +	if (n && plist_get_node_type(n) == PLIST_UINT) { +		plist_get_uint_val(n, &val); +		dev->device_id = (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); +		dev->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) { +			strncpy(dev->serial_number, strval, 255); +			free(strval); +		} +	} +	n = plist_dict_get_item(props, "LocationID"); +	if (n && plist_get_node_type(n) == PLIST_UINT) { +		plist_get_uint_val(n, &val); +		dev->location = (uint32_t)val; +	} + +	return dev; +} +#endif +  static int receive_packet(int sfd, struct usbmuxd_header *header, void **payload, int timeout)  {  	int recv_len; @@ -200,27 +244,14 @@ static int receive_packet(int sfd, struct usbmuxd_header *header, void **payload  					plist_free(plist);  					return -EBADMSG;  				} -				dev = (struct usbmuxd_device_record*)malloc(sizeof(struct usbmuxd_device_record)); -				memset(dev, 0, sizeof(struct usbmuxd_device_record)); - -				plist_t n = plist_dict_get_item(props, "DeviceID"); -				plist_get_uint_val(n, &val); -				dev->device_id = (uint32_t)val; -				n = plist_dict_get_item(props, "ProductID"); -				plist_get_uint_val(n, &val); -				dev->product_id = (uint32_t)val; - -				n = plist_dict_get_item(props, "SerialNumber"); -				char *strval = NULL; -				plist_get_string_val(n, &strval); -				if (strval) { -					strncpy(dev->serial_number, strval, 255); -					free(strval); +				dev = device_record_from_plist(props); +				if (!dev) { +					DEBUG(1, "%s: Could not create device record object from properties!\n", __func__); +					free(message); +					plist_free(plist); +					return -EBADMSG;  				} -				n = plist_dict_get_item(props, "LocationID"); -				plist_get_uint_val(n, &val); -				dev->location = (uint32_t)val;  				*payload = (void*)dev;  				hdr.length = sizeof(hdr) + sizeof(struct usbmuxd_device_record);  				hdr.message = MESSAGE_DEVICE_ADD; @@ -416,6 +447,21 @@ static int send_connect_packet(int sfd, uint32_t tag, uint32_t device_id, uint16  	return res;  } +#ifdef HAVE_PLIST +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; +} +#endif +  /**   * Generates an event, i.e. calls the callback function.   * A reference to a populated usbmuxd_event_t with information about the event @@ -727,6 +773,29 @@ int usbmuxd_unsubscribe()  	return 0;  } +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) { +		DEBUG(1, "%s: Out of memory!\n", __func__); +		return NULL; +	} + +	devinfo->handle = dev->device_id; +	devinfo->product_id = dev->product_id; +	memset(devinfo->udid, '\0', sizeof(devinfo->udid)); +	memcpy(devinfo->udid, dev->serial_number, sizeof(devinfo->udid)); + +	if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) { +		sprintf(devinfo->udid + 32, "%08x", devinfo->handle); +	} + +	return devinfo; +} +  int usbmuxd_get_device_list(usbmuxd_device_info_t **device_list)  {  	int sfd; @@ -752,6 +821,43 @@ retry:  	use_tag++;  	LOCK; +#ifdef HAVE_PLIST +	if ((proto_version == 1) && (try_list_devices)) { +		if (send_list_devices_packet(sfd, use_tag) > 0) { +			plist_t list = NULL; +			if (usbmuxd_get_result(sfd, use_tag, &res, &list) && (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"); +						dev = device_record_from_plist(props); +						usbmuxd_device_info_t *devinfo = device_info_from_device_record(dev); +						if (!devinfo) { +							UNLOCK; +							DEBUG(1, "%s: can't create device info object\n", __func__); +							free(payload); +							return -1; +						} +						collection_add(&tmpdevs, devinfo); +					} +					goto got_device_list; +				} +			} else { +				if (res == RESULT_BADVERSION) { +					proto_version = 0; +				} +				UNLOCK; +				close_socket(sfd); +				try_list_devices = 0; +				goto retry; +			} +		} +	} +#endif  	if (send_listen_packet(sfd, use_tag) > 0) {  		res = -1;  		// get response @@ -784,23 +890,14 @@ retry:  		if (receive_packet(sfd, &hdr, &payload, 100) > 0) {  			if (hdr.message == MESSAGE_DEVICE_ADD) {  				dev = payload; -				usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t)); + +				usbmuxd_device_info_t *devinfo = device_info_from_device_record(dev);  				if (!devinfo) {  					UNLOCK; -					DEBUG(1, "%s: Out of memory!\n", __func__); +					DEBUG(1, "%s: can't create device info object\n", __func__);  					free(payload);  					return -1;  				} - -				devinfo->handle = dev->device_id; -				devinfo->product_id = dev->product_id; -				memset(devinfo->udid, '\0', sizeof(devinfo->udid)); -				memcpy(devinfo->udid, dev->serial_number, sizeof(devinfo->udid)); - -				if (strcasecmp(devinfo->udid, "ffffffffffffffffffffffffffffffffffffffff") == 0) { -					sprintf(devinfo->udid + 32, "%08x", devinfo->handle); -				} -  				collection_add(&tmpdevs, devinfo);  			} else if (hdr.message == MESSAGE_DEVICE_REMOVE) { @@ -830,6 +927,9 @@ retry:  			break;  		}  	} +#ifdef HAVE_PLIST +got_device_list: +#endif  	UNLOCK;  	// explicitly close connection | 
