| Index: tools/ipoddfu_c/dfu.c | 
| — | — | @@ -0,0 +1,71 @@ | 
|  | 2 | +#include <stdio.h> | 
|  | 3 | +#include <string.h> | 
|  | 4 | + | 
|  | 5 | +#include <libusb-1.0/libusb.h> | 
|  | 6 | + | 
|  | 7 | +#include "usb.h" | 
|  | 8 | + | 
|  | 9 | +int dfu_write(const unsigned char i, const unsigned int length, const unsigned char *data) { | 
|  | 10 | +	return usb_control_transfer(0x21, 1, i, 0, (unsigned char *) data, length); | 
|  | 11 | +} | 
|  | 12 | + | 
|  | 13 | +int dfu_read(unsigned char result[6]) { | 
|  | 14 | +	return usb_control_transfer(0xa1, 3, 0, 0, result, 6); | 
|  | 15 | +} | 
|  | 16 | + | 
|  | 17 | +int dfu_send(const unsigned long int size, const unsigned char *data) { | 
|  | 18 | +	unsigned char result[6]; | 
|  | 19 | +	unsigned int i; | 
|  | 20 | +	int res; | 
|  | 21 | + | 
|  | 22 | +	printf("Uploading... "); | 
|  | 23 | +	fflush(stdout); | 
|  | 24 | + | 
|  | 25 | +	for (i = 0; i < (size + 4 + 2047) / 2048; ++i) { | 
|  | 26 | +		res = dfu_write(i, ((i + 1) * 2048 > size + 4) ? (size + 4) - (i * 2048) : 2048, (unsigned char *) (data + (i * 2048))); | 
|  | 27 | + | 
|  | 28 | +		if (LIBUSB_SUCCESS > res) { | 
|  | 29 | +			return res; | 
|  | 30 | +		} | 
|  | 31 | + | 
|  | 32 | +		memset(result, 0, sizeof(result)); | 
|  | 33 | + | 
|  | 34 | +		while ('\x05' != result[4]) { | 
|  | 35 | +			res = dfu_read(result); | 
|  | 36 | + | 
|  | 37 | +			if (LIBUSB_SUCCESS > res) { | 
|  | 38 | +				return res; | 
|  | 39 | +			} | 
|  | 40 | +		} | 
|  | 41 | + | 
|  | 42 | +		printf("#"); | 
|  | 43 | +		fflush(stdout); | 
|  | 44 | +	} | 
|  | 45 | + | 
|  | 46 | +	res = dfu_write(i, 0, NULL); | 
|  | 47 | + | 
|  | 48 | +	if (LIBUSB_SUCCESS > res) { | 
|  | 49 | +		return res; | 
|  | 50 | +	} | 
|  | 51 | + | 
|  | 52 | +	memset(result, 0, sizeof(result)); | 
|  | 53 | + | 
|  | 54 | +	i = 0; | 
|  | 55 | + | 
|  | 56 | +	while ('\x02' != result[4] && i++ < 1000) { | 
|  | 57 | +		dfu_read(result); | 
|  | 58 | + | 
|  | 59 | +		if (LIBUSB_SUCCESS > res) { | 
|  | 60 | +			return res; | 
|  | 61 | +		} | 
|  | 62 | +	} | 
|  | 63 | + | 
|  | 64 | +	if (1000 == i || '\x02' == result[4]) { | 
|  | 65 | +		printf(" failed: %d / %d\n", result[4], result[0]); | 
|  | 66 | +	} | 
|  | 67 | +	else { | 
|  | 68 | +		printf(" OK\n"); | 
|  | 69 | +	} | 
|  | 70 | + | 
|  | 71 | +	return 0; | 
|  | 72 | +} | 
| Index: tools/ipoddfu_c/usb.h | 
| — | — | @@ -0,0 +1,7 @@ | 
|  | 2 | +int usb_init(void); | 
|  | 3 | +int usb_find(unsigned char *reattach); | 
|  | 4 | +int usb_open(libusb_device *dev, unsigned char *reattach); | 
|  | 5 | +int usb_bulk_transfer(const unsigned char endpoint, unsigned char *data, const unsigned int length); | 
|  | 6 | +int usb_control_transfer(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength); | 
|  | 7 | +int usb_close(const unsigned char reattach); | 
|  | 8 | +void usb_exit(void); | 
| Index: tools/ipoddfu_c/ipoddfu.h | 
| — | — | @@ -0,0 +1,2 @@ | 
|  | 2 | +libusb_context *usb_ctx; | 
|  | 3 | +libusb_device_handle *usb_handle; | 
| Index: tools/ipoddfu_c/misc.h | 
| — | — | @@ -0,0 +1,3 @@ | 
|  | 2 | +long int fgetsize(FILE *fp); | 
|  | 3 | +void dump_packet(const unsigned char *data, const unsigned int length); | 
|  | 4 | +void print_error(const int code); | 
| Index: tools/ipoddfu_c/crc32.h | 
| — | — | @@ -0,0 +1,22 @@ | 
|  | 2 | +/* | 
|  | 3 | + * CRC32 functions | 
|  | 4 | + * Based on public domain implementation by Finn Yannick Jacobs. | 
|  | 5 | + */ | 
|  | 6 | + | 
|  | 7 | +#ifndef _CRC32_H_ | 
|  | 8 | +#define _CRC32_H_ | 
|  | 9 | + | 
|  | 10 | +#include <stdint.h> | 
|  | 11 | + | 
|  | 12 | +#define CRC32_DEFAULT_SEED 0xffffffff | 
|  | 13 | + | 
|  | 14 | +/* Calculate crc32. | 
|  | 15 | + * Standard seed is 0xffffffff or 0. | 
|  | 16 | + * Some implementations xor result with 0xffffffff after calculation. | 
|  | 17 | + */ | 
|  | 18 | +uint32_t crc32 (void *data, unsigned int len, uint32_t seed); | 
|  | 19 | + | 
|  | 20 | +/* Calculate crc32table */ | 
|  | 21 | +void crc32_init(); | 
|  | 22 | + | 
|  | 23 | +#endif | 
| Index: tools/ipoddfu_c/dfu.h | 
| — | — | @@ -0,0 +1 @@ | 
|  | 2 | +int dfu_send(const unsigned long int size, const unsigned char *data); | 
| Index: tools/ipoddfu_c/usb.c | 
| — | — | @@ -0,0 +1,268 @@ | 
|  | 2 | +#include <stdio.h> | 
|  | 3 | + | 
|  | 4 | +#include <libusb-1.0/libusb.h> | 
|  | 5 | + | 
|  | 6 | +#include "misc.h" | 
|  | 7 | +#include "usb.h" | 
|  | 8 | + | 
|  | 9 | +libusb_context *usb_ctx = NULL; | 
|  | 10 | +libusb_device_handle *usb_handle = NULL; | 
|  | 11 | + | 
|  | 12 | +int usb_init(void) { | 
|  | 13 | +	int res; | 
|  | 14 | + | 
|  | 15 | +	printf("Initialising USB library... "); | 
|  | 16 | + | 
|  | 17 | +	res = libusb_init(&usb_ctx); | 
|  | 18 | + | 
|  | 19 | +	if (LIBUSB_SUCCESS != res) { | 
|  | 20 | +		return res; | 
|  | 21 | +	} | 
|  | 22 | + | 
|  | 23 | +	printf("OK\n"); | 
|  | 24 | + | 
|  | 25 | +#ifdef DEBUG | 
|  | 26 | +	libusb_set_debug(usb_ctx, 3); | 
|  | 27 | +#endif | 
|  | 28 | + | 
|  | 29 | +	return LIBUSB_SUCCESS; | 
|  | 30 | +} | 
|  | 31 | + | 
|  | 32 | +int usb_find(unsigned char *reattach) { | 
|  | 33 | +	libusb_device **devs, *dev; | 
|  | 34 | +	ssize_t devs_cnt; | 
|  | 35 | +	int res, i; | 
|  | 36 | +	struct libusb_device_descriptor dev_desc; | 
|  | 37 | +	unsigned char found = 0; | 
|  | 38 | +	struct libusb_config_descriptor *cfg_desc; | 
|  | 39 | +	const struct libusb_interface *iface; | 
|  | 40 | +	const struct libusb_interface_descriptor *iface_desc; | 
|  | 41 | + | 
|  | 42 | +	printf("Getting USB device list... "); | 
|  | 43 | + | 
|  | 44 | +	devs_cnt = libusb_get_device_list(usb_ctx, &devs); | 
|  | 45 | + | 
|  | 46 | +	if (devs_cnt < 0) { | 
|  | 47 | +		return devs_cnt; | 
|  | 48 | +	} | 
|  | 49 | + | 
|  | 50 | +	printf("Found %d USB devices!\n", devs_cnt); | 
|  | 51 | + | 
|  | 52 | +	for (i = 0; i < devs_cnt; ++i) { | 
|  | 53 | +		dev = devs[i]; | 
|  | 54 | + | 
|  | 55 | +		printf("Getting device descriptor of USB device %d...\n", i); | 
|  | 56 | + | 
|  | 57 | +		res = libusb_get_device_descriptor(dev, &dev_desc); | 
|  | 58 | + | 
|  | 59 | +		if (LIBUSB_SUCCESS != res) { | 
|  | 60 | +			fprintf(stderr, "Unable to get device descriptor of device %d!\n", i); | 
|  | 61 | + | 
|  | 62 | +			continue; | 
|  | 63 | +		} | 
|  | 64 | + | 
|  | 65 | +		printf("[%04x:%04x] bus %d, device %d, USB ver. %04x\n", dev_desc.idVendor, | 
|  | 66 | +			dev_desc.idProduct, libusb_get_bus_number(dev), | 
|  | 67 | +			libusb_get_device_address(dev), dev_desc.bcdUSB); | 
|  | 68 | + | 
|  | 69 | +		if (0x05ac == dev_desc.idVendor && ( | 
|  | 70 | +			/* DFU */ | 
|  | 71 | +			0x1220 == dev_desc.idProduct || /* iPod Nano 2G */ | 
|  | 72 | +			0x1223 == dev_desc.idProduct || /* iPod Classic 1G */ | 
|  | 73 | +			0x1224 == dev_desc.idProduct || /* iPod Nano 3G */ | 
|  | 74 | +			0x1225 == dev_desc.idProduct || /* iPod Nano 4G */ | 
|  | 75 | +			0x1231 == dev_desc.idProduct || /* iPod Nano 5G */ | 
|  | 76 | +			0x1232 == dev_desc.idProduct || /* iPod Nano 6G */ | 
|  | 77 | +			0x1233 == dev_desc.idProduct || /* iPod Shuffle 4G */ | 
|  | 78 | +			/* WTF */ | 
|  | 79 | +			0x1240 == dev_desc.idProduct || /* iPod Nano 2G */ | 
|  | 80 | +			0x1241 == dev_desc.idProduct || /* iPod Classic 1G */ | 
|  | 81 | +			0x1242 == dev_desc.idProduct || /* iPod Nano 3G */ | 
|  | 82 | +			0x1243 == dev_desc.idProduct || /* iPod Nano 4G */ | 
|  | 83 | +			0x1245 == dev_desc.idProduct || /* iPod Classic 2G */ | 
|  | 84 | +			0x1246 == dev_desc.idProduct || /* iPod Nano 5G */ | 
|  | 85 | +			0x1247 == dev_desc.idProduct || /* iPod Classic 3G */ | 
|  | 86 | +			0x1248 == dev_desc.idProduct    /* iPod Nano 6G */ | 
|  | 87 | +		)) { | 
|  | 88 | +			printf("Found DFU USB device!\n"); | 
|  | 89 | + | 
|  | 90 | +			if (1 != dev_desc.bNumConfigurations) { | 
|  | 91 | +				fprintf(stderr, "Number of configs is different than 1, not the right device...\n"); | 
|  | 92 | + | 
|  | 93 | +				continue; | 
|  | 94 | +			} | 
|  | 95 | + | 
|  | 96 | +			printf("Getting config descriptor 0 of device...\n"); | 
|  | 97 | + | 
|  | 98 | +			res = libusb_get_config_descriptor(dev, 0, &cfg_desc); | 
|  | 99 | + | 
|  | 100 | +			if (LIBUSB_SUCCESS != res) { | 
|  | 101 | +				return res; | 
|  | 102 | +			} | 
|  | 103 | + | 
|  | 104 | +			if (1 != cfg_desc->bNumInterfaces) { | 
|  | 105 | +				fprintf(stderr, "Wrong USB device, it should have exactly 1 interface\n"); | 
|  | 106 | + | 
|  | 107 | +				continue; | 
|  | 108 | +			} | 
|  | 109 | + | 
|  | 110 | +			iface = &cfg_desc->interface[0]; | 
|  | 111 | + | 
|  | 112 | +			if (1 != iface->num_altsetting) { | 
|  | 113 | +				fprintf(stderr, "Wrong USB device, it should have exactly 1 altsetting\n"); | 
|  | 114 | + | 
|  | 115 | +				continue; | 
|  | 116 | +			} | 
|  | 117 | + | 
|  | 118 | +			iface_desc = &iface->altsetting[0]; | 
|  | 119 | + | 
|  | 120 | +			if (0 != iface_desc->bNumEndpoints) { | 
|  | 121 | +				fprintf(stderr, "Wrong USB device, it should have no endpoints\n"); | 
|  | 122 | + | 
|  | 123 | +				continue; | 
|  | 124 | +			} | 
|  | 125 | + | 
|  | 126 | +			found = 1; | 
|  | 127 | +		} | 
|  | 128 | +	} | 
|  | 129 | + | 
|  | 130 | +	if (found) { | 
|  | 131 | +		res = usb_open(dev, reattach); | 
|  | 132 | +	} | 
|  | 133 | +	else { | 
|  | 134 | +		fprintf(stderr, "DFU USB device not found!\n"); | 
|  | 135 | + | 
|  | 136 | +		res = 1; // not found | 
|  | 137 | +	} | 
|  | 138 | + | 
|  | 139 | +	printf("Freeing device list...\n"); | 
|  | 140 | + | 
|  | 141 | +	libusb_free_device_list(devs, 1); | 
|  | 142 | + | 
|  | 143 | +	return res; | 
|  | 144 | +} | 
|  | 145 | + | 
|  | 146 | +int usb_open(libusb_device *dev, unsigned char *reattach) { | 
|  | 147 | +	int res; | 
|  | 148 | + | 
|  | 149 | +	printf("Opening USB device... "); | 
|  | 150 | + | 
|  | 151 | +	res = libusb_open(dev, &usb_handle); | 
|  | 152 | + | 
|  | 153 | +	if (LIBUSB_SUCCESS != res) { | 
|  | 154 | +		return res; | 
|  | 155 | +	} | 
|  | 156 | + | 
|  | 157 | +	printf("OK\n"); | 
|  | 158 | + | 
|  | 159 | +	printf("Setting USB configuration 1... "); | 
|  | 160 | + | 
|  | 161 | +	res = libusb_set_configuration(usb_handle, 1); | 
|  | 162 | + | 
|  | 163 | +	if (LIBUSB_SUCCESS != res) { | 
|  | 164 | +		return res; | 
|  | 165 | +	} | 
|  | 166 | + | 
|  | 167 | +	printf("OK\n"); | 
|  | 168 | + | 
|  | 169 | +	res = libusb_kernel_driver_active(usb_handle, 0); | 
|  | 170 | + | 
|  | 171 | +	if (1 == res) { | 
|  | 172 | +		printf("Kernel driver active, detaching... "); | 
|  | 173 | + | 
|  | 174 | +		*reattach = 1; | 
|  | 175 | + | 
|  | 176 | +		res = libusb_detach_kernel_driver(usb_handle, 0); | 
|  | 177 | + | 
|  | 178 | +		if (LIBUSB_SUCCESS == res) { | 
|  | 179 | +			printf("OK\n"); | 
|  | 180 | +		} | 
|  | 181 | +	} | 
|  | 182 | + | 
|  | 183 | +	if (LIBUSB_SUCCESS != res) { | 
|  | 184 | +		return res; | 
|  | 185 | +	} | 
|  | 186 | + | 
|  | 187 | +	printf("Claiming interface 0... "); | 
|  | 188 | + | 
|  | 189 | +	res = libusb_claim_interface(usb_handle, 0); | 
|  | 190 | + | 
|  | 191 | +	if (LIBUSB_SUCCESS != res) { | 
|  | 192 | +		return res; | 
|  | 193 | +	} | 
|  | 194 | + | 
|  | 195 | +	printf("OK\n"); | 
|  | 196 | + | 
|  | 197 | +	return LIBUSB_SUCCESS; | 
|  | 198 | +} | 
|  | 199 | + | 
|  | 200 | +int usb_bulk_transfer(const unsigned char endpoint, unsigned char *data, const unsigned int length) { | 
|  | 201 | +	int transferred; | 
|  | 202 | +	int res; | 
|  | 203 | + | 
|  | 204 | +	res = libusb_bulk_transfer(usb_handle, endpoint, data, length, &transferred, 30000); | 
|  | 205 | + | 
|  | 206 | +	if (LIBUSB_SUCCESS != res) { | 
|  | 207 | +		return res; | 
|  | 208 | +	} | 
|  | 209 | + | 
|  | 210 | +	if ((unsigned int) transferred != length) { | 
|  | 211 | +		return 2; // incomplete | 
|  | 212 | +	} | 
|  | 213 | + | 
|  | 214 | +	return LIBUSB_SUCCESS; | 
|  | 215 | +} | 
|  | 216 | + | 
|  | 217 | +int usb_control_transfer(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength) { | 
|  | 218 | +	int res; | 
|  | 219 | + | 
|  | 220 | +	res = libusb_control_transfer(usb_handle, bmRequestType, bRequest, wValue, wIndex, data, wLength, 30000); | 
|  | 221 | + | 
|  | 222 | +	if (LIBUSB_SUCCESS != res) { | 
|  | 223 | +		return res; | 
|  | 224 | +	} | 
|  | 225 | + | 
|  | 226 | +	return LIBUSB_SUCCESS; | 
|  | 227 | +} | 
|  | 228 | + | 
|  | 229 | +int usb_close(const unsigned char reattach) { | 
|  | 230 | +	int res; | 
|  | 231 | + | 
|  | 232 | +	printf("Releasing USB interface... "); | 
|  | 233 | + | 
|  | 234 | +	res = libusb_release_interface(usb_handle, 0); | 
|  | 235 | + | 
|  | 236 | +	if (LIBUSB_SUCCESS != res) { | 
|  | 237 | +		return res; | 
|  | 238 | +	} | 
|  | 239 | + | 
|  | 240 | +	printf("OK\n"); | 
|  | 241 | + | 
|  | 242 | +	if (reattach) { | 
|  | 243 | +		printf("Reattaching kernel driver... "); | 
|  | 244 | + | 
|  | 245 | +		res = libusb_attach_kernel_driver(usb_handle, 0); | 
|  | 246 | + | 
|  | 247 | +		if (LIBUSB_SUCCESS == res) { | 
|  | 248 | +			printf("OK\n"); | 
|  | 249 | +		} | 
|  | 250 | +		else { | 
|  | 251 | +			printf("\n"); | 
|  | 252 | +			print_error(res); | 
|  | 253 | + | 
|  | 254 | +			res = LIBUSB_SUCCESS; | 
|  | 255 | +		} | 
|  | 256 | +	} | 
|  | 257 | + | 
|  | 258 | +	printf("Closing USB device handle...\n"); | 
|  | 259 | + | 
|  | 260 | +	libusb_close(usb_handle); | 
|  | 261 | + | 
|  | 262 | +	return res; | 
|  | 263 | +} | 
|  | 264 | + | 
|  | 265 | +void usb_exit(void) { | 
|  | 266 | +	printf("Deinitializing USB library...\n"); | 
|  | 267 | + | 
|  | 268 | +	libusb_exit(usb_ctx); | 
|  | 269 | +} | 
| Index: tools/ipoddfu_c/ipoddfu.c | 
| — | — | @@ -0,0 +1,91 @@ | 
|  | 2 | +#include <stdlib.h> | 
|  | 3 | +#include <stdio.h> | 
|  | 4 | +#include <string.h> | 
|  | 5 | + | 
|  | 6 | +#include <libusb-1.0/libusb.h> | 
|  | 7 | + | 
|  | 8 | +#include "usb.h" | 
|  | 9 | +#include "dfu.h" | 
|  | 10 | +#include "crc32.h" | 
|  | 11 | +#include "misc.h" | 
|  | 12 | +#include "ipoddfu.h" | 
|  | 13 | + | 
|  | 14 | +int main(int argc, char *argv[]) { | 
|  | 15 | +	int res = 0; | 
|  | 16 | +	unsigned char reattach = 0, *data; | 
|  | 17 | +	FILE *fp; | 
|  | 18 | +	long int size; | 
|  | 19 | +	unsigned int checksum; | 
|  | 20 | + | 
|  | 21 | +	if (2 != argc) { | 
|  | 22 | +		fprintf(stderr, "usage: %s <file>\n", argv[0]); | 
|  | 23 | + | 
|  | 24 | +		return 1; | 
|  | 25 | +	} | 
|  | 26 | + | 
|  | 27 | +	fp = fopen(argv[1], "r"); | 
|  | 28 | + | 
|  | 29 | +	if (!fp) { | 
|  | 30 | +		perror("fopen"); | 
|  | 31 | + | 
|  | 32 | +		return 1; | 
|  | 33 | +	} | 
|  | 34 | + | 
|  | 35 | +	size = fgetsize(fp); | 
|  | 36 | + | 
|  | 37 | +	if (-1L == size) { | 
|  | 38 | +		return 1; | 
|  | 39 | +	} | 
|  | 40 | + | 
|  | 41 | +	data = (unsigned char *) malloc(size + 4); | 
|  | 42 | + | 
|  | 43 | +	if ((unsigned long int) size != fread(data, sizeof(unsigned char), size, fp)) { | 
|  | 44 | +		perror("fread"); | 
|  | 45 | + | 
|  | 46 | +		return 1; | 
|  | 47 | +	} | 
|  | 48 | + | 
|  | 49 | +	if (fclose(fp)) { | 
|  | 50 | +		perror("fclose"); | 
|  | 51 | + | 
|  | 52 | +		return 1; | 
|  | 53 | +	} | 
|  | 54 | + | 
|  | 55 | +	crc32_init(); | 
|  | 56 | + | 
|  | 57 | +	checksum = crc32(data, size, CRC32_DEFAULT_SEED); | 
|  | 58 | + | 
|  | 59 | +	memcpy(data + size, &checksum, 4); | 
|  | 60 | + | 
|  | 61 | +	res = usb_init(); | 
|  | 62 | + | 
|  | 63 | +	if (LIBUSB_SUCCESS == res) { | 
|  | 64 | +		res = usb_find(&reattach); | 
|  | 65 | +	} | 
|  | 66 | + | 
|  | 67 | +	if (LIBUSB_SUCCESS == res) { | 
|  | 68 | +		res = dfu_send((unsigned long int) size + 4, data); | 
|  | 69 | +	} | 
|  | 70 | + | 
|  | 71 | +	if (data) { | 
|  | 72 | +		free(data); | 
|  | 73 | +	} | 
|  | 74 | + | 
|  | 75 | +	if (0 != res) { | 
|  | 76 | +		print_error(res); | 
|  | 77 | +	} | 
|  | 78 | + | 
|  | 79 | +	if (usb_handle) { | 
|  | 80 | +		usb_close(reattach); | 
|  | 81 | +	} | 
|  | 82 | + | 
|  | 83 | +	if (usb_ctx) { | 
|  | 84 | +		usb_exit(); | 
|  | 85 | +	} | 
|  | 86 | + | 
|  | 87 | +	if (res < 0) { | 
|  | 88 | +		res = -res; | 
|  | 89 | +	} | 
|  | 90 | + | 
|  | 91 | +	return res; | 
|  | 92 | +} | 
| Index: tools/ipoddfu_c/misc.c | 
| — | — | @@ -0,0 +1,82 @@ | 
|  | 2 | +#include <stdio.h> | 
|  | 3 | + | 
|  | 4 | +#include <libusb-1.0/libusb.h> | 
|  | 5 | + | 
|  | 6 | +#include "misc.h" | 
|  | 7 | + | 
|  | 8 | +const char *libusb_error_messages[13] = { | 
|  | 9 | +	"No error",					/* LIBUSB_SUCCESS = 0 */ | 
|  | 10 | +	"Input/output error",		/* LIBUSB_ERROR_IO = -1 */ | 
|  | 11 | +	"Invalid parameter",		/* LIBUSB_ERROR_INVALID_PARAM = -2 */ | 
|  | 12 | +	"Access denied",			/* LIBUSB_ERROR_ACCESS = -3 */ | 
|  | 13 | +	"No such device",			/* LIBUSB_ERROR_NO_DEVICE = -4 */ | 
|  | 14 | +	"Entity not found",			/* LIBUSB_ERROR_NOT_FOUND = -5 */ | 
|  | 15 | +	"Resource busy",			/* LIBUSB_ERROR_BUSY = -6 */ | 
|  | 16 | +	"Operation timed out",		/* LIBUSB_ERROR_TIMEOUT = -7 */ | 
|  | 17 | +	"Overflow",					/* LIBUSB_ERROR_OVERFLOW = -8 */ | 
|  | 18 | +	"Pipe error",				/* LIBUSB_ERROR_PIPE = -9 */ | 
|  | 19 | +	"System call interrupted",	/* LIBUSB_ERROR_INTERRUPTED = -10 */ | 
|  | 20 | +	"Insufficient memory",		/* LIBUSB_ERROR_NO_MEM = -11 */ | 
|  | 21 | +	"Operation not supported",	/* LIBUSB_ERROR_NOT_SUPPORTED = -12 */ | 
|  | 22 | +}; | 
|  | 23 | + | 
|  | 24 | +long int fgetsize(FILE *fp) { | 
|  | 25 | +	static long int pos, size; | 
|  | 26 | + | 
|  | 27 | +	if (-1L == (pos = ftell(fp))) { | 
|  | 28 | +		perror("ftell"); | 
|  | 29 | + | 
|  | 30 | +		return -1L; | 
|  | 31 | +	} | 
|  | 32 | + | 
|  | 33 | +	if(fseek(fp, 0L, SEEK_END)) { | 
|  | 34 | +		perror("fseek"); | 
|  | 35 | + | 
|  | 36 | +		return -1L; | 
|  | 37 | +	} | 
|  | 38 | + | 
|  | 39 | +	if (-1L == (size = ftell(fp))) { | 
|  | 40 | +		perror("ftell"); | 
|  | 41 | + | 
|  | 42 | +		return -1L; | 
|  | 43 | +	} | 
|  | 44 | + | 
|  | 45 | +	if (fseek(fp, pos, SEEK_SET)) { | 
|  | 46 | +		perror("fseek"); | 
|  | 47 | + | 
|  | 48 | +		return -1L; | 
|  | 49 | +	} | 
|  | 50 | + | 
|  | 51 | +	return size; | 
|  | 52 | +} | 
|  | 53 | + | 
|  | 54 | +void dump_packet(const unsigned char *data, const unsigned int length) { | 
|  | 55 | +	static unsigned int i; | 
|  | 56 | + | 
|  | 57 | +	for (i = 0; i < length; ++i) { | 
|  | 58 | +		printf("%02x ", data[i]); | 
|  | 59 | + | 
|  | 60 | +		if (i % 4 == 3) { | 
|  | 61 | +			printf(" "); | 
|  | 62 | +		} | 
|  | 63 | + | 
|  | 64 | +		if (i % 16 == 15 && i + 1 < length) { | 
|  | 65 | +			printf("\n"); | 
|  | 66 | +		} | 
|  | 67 | +	} | 
|  | 68 | + | 
|  | 69 | +	printf("\n"); | 
|  | 70 | +} | 
|  | 71 | + | 
|  | 72 | +void print_error(const int code) { | 
|  | 73 | +	if (code > 0) { | 
|  | 74 | +		fprintf(stderr, "error: code %d\n", code); | 
|  | 75 | +	} | 
|  | 76 | +	else { | 
|  | 77 | +		fprintf(stderr, "libusb error: %s (code %d)\n", ( | 
|  | 78 | +			LIBUSB_ERROR_OTHER == code || code > 0 ? | 
|  | 79 | +				"unspecified" : | 
|  | 80 | +				libusb_error_messages[-code] | 
|  | 81 | +		), code); | 
|  | 82 | +	} | 
|  | 83 | +} | 
| Index: tools/ipoddfu_c/Makefile | 
| — | — | @@ -0,0 +1,12 @@ | 
|  | 2 | +CFLAGS := -O2 -Wall -Wextra -Werror -g -lusb-1.0 | 
|  | 3 | + | 
|  | 4 | +all: build ipoddfu | 
|  | 5 | + | 
|  | 6 | +ipoddfu: | 
|  | 7 | +	gcc $(CFLAGS) -o build/ipoddfu usb.c dfu.c crc32.c misc.c ipoddfu.c | 
|  | 8 | + | 
|  | 9 | +build: | 
|  | 10 | +	@mkdir $@ | 
|  | 11 | + | 
|  | 12 | +clean: | 
|  | 13 | +	@rm -rf build | 
| Index: tools/ipoddfu_c/crc32.c | 
| — | — | @@ -0,0 +1,45 @@ | 
|  | 2 | +/* | 
|  | 3 | + * CRC32 functions | 
|  | 4 | + * Based on public domain implementation by Finn Yannick Jacobs. | 
|  | 5 | + */ | 
|  | 6 | + | 
|  | 7 | +/* Written and copyright 1999 by Finn Yannick Jacobs | 
|  | 8 | + * No rights were reserved to this, so feel free to | 
|  | 9 | + * manipulate or do with it, what you want or desire :) | 
|  | 10 | + */ | 
|  | 11 | + | 
|  | 12 | +#include "crc32.h" | 
|  | 13 | + | 
|  | 14 | +/* crc32table[] built by crc32_init() */ | 
|  | 15 | +static unsigned long crc32table[256]; | 
|  | 16 | + | 
|  | 17 | +/* Calculate crc32. Little endian. | 
|  | 18 | + * Standard seed is 0xffffffff or 0. | 
|  | 19 | + * Some implementations xor result with 0xffffffff after calculation. | 
|  | 20 | + */ | 
|  | 21 | +uint32_t crc32(void *data, unsigned int len, uint32_t seed) { | 
|  | 22 | +	uint8_t *d = data; | 
|  | 23 | + | 
|  | 24 | +	while (len--) { | 
|  | 25 | +		seed = ((seed >> 8) & 0x00FFFFFF) ^ crc32table [(seed ^ *d++) & 0xFF]; | 
|  | 26 | +	} | 
|  | 27 | + | 
|  | 28 | +	return seed; | 
|  | 29 | +} | 
|  | 30 | + | 
|  | 31 | +/* Calculate crc32table */ | 
|  | 32 | +void crc32_init() { | 
|  | 33 | +	uint32_t poly = 0xEDB88320L; | 
|  | 34 | +	uint32_t crc; | 
|  | 35 | +	int i, j; | 
|  | 36 | + | 
|  | 37 | +	for (i = 0; i < 256; ++i) { | 
|  | 38 | +		crc = i; | 
|  | 39 | + | 
|  | 40 | +		for (j = 8; j > 0; --j) { | 
|  | 41 | +			crc = (crc >> 1) ^ ((crc & 1) ? poly : 0); | 
|  | 42 | +		} | 
|  | 43 | + | 
|  | 44 | +		crc32table[i] = crc; | 
|  | 45 | +	} | 
|  | 46 | +} | 
| Index: tools/ipoddfu_c | 
| Property changes on: tools/ipoddfu_c | 
| ___________________________________________________________________ | 
| Added: svn:ignore | 
| ## -0,0 +1 ## | 
|  | 47 | +build |