freemyipod r693 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r692‎ | r693 | r694 >
Date:23:01, 6 April 2011
Author:user890104
Status:new
Tags:
Comment:
ipoddfu_c: initial import
Modified paths:
  • /tools/ipoddfu_c (added) (history)
  • /tools/ipoddfu_c/Makefile (added) (history)
  • /tools/ipoddfu_c/crc32.c (added) (history)
  • /tools/ipoddfu_c/crc32.h (added) (history)
  • /tools/ipoddfu_c/dfu.c (added) (history)
  • /tools/ipoddfu_c/dfu.h (added) (history)
  • /tools/ipoddfu_c/ipoddfu.c (added) (history)
  • /tools/ipoddfu_c/ipoddfu.h (added) (history)
  • /tools/ipoddfu_c/misc.c (added) (history)
  • /tools/ipoddfu_c/misc.h (added) (history)
  • /tools/ipoddfu_c/usb.c (added) (history)
  • /tools/ipoddfu_c/usb.h (added) (history)

Diff [purge]

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