diff options
author | Dave Chapman <dave@dchapman.com> | 2009-02-22 13:54:46 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2009-02-22 13:54:46 +0000 |
commit | c06071e2e705095e49207f92b941edd3b5ada46c (patch) | |
tree | 28e6b326720a12f26c56ff098ea12fea50838808 /utils | |
parent | 65d404ff6a78c6e2135f3e4f1f9d5634bed0dfce (diff) | |
download | rockbox-c06071e2e705095e49207f92b941edd3b5ada46c.tar.gz rockbox-c06071e2e705095e49207f92b941edd3b5ada46c.zip |
Initial version of a BSD-licensed beastpatcher utility for Gigabeat S installation. Currently only compiles on Linux, but Windows and OS X support are planned.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20083 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils')
-rw-r--r-- | utils/MTP/beastpatcher/Makefile | 52 | ||||
-rw-r--r-- | utils/MTP/beastpatcher/README | 61 | ||||
-rw-r--r-- | utils/MTP/beastpatcher/TODO | 17 | ||||
-rw-r--r-- | utils/MTP/beastpatcher/beastpatcher.c | 221 | ||||
-rw-r--r-- | utils/MTP/beastpatcher/mtp_common.h | 71 | ||||
-rw-r--r-- | utils/MTP/beastpatcher/mtp_libmtp.c | 174 |
6 files changed, 596 insertions, 0 deletions
diff --git a/utils/MTP/beastpatcher/Makefile b/utils/MTP/beastpatcher/Makefile new file mode 100644 index 0000000000..edd08b1248 --- /dev/null +++ b/utils/MTP/beastpatcher/Makefile | |||
@@ -0,0 +1,52 @@ | |||
1 | CFLAGS=-Wall -W | ||
2 | |||
3 | ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) | ||
4 | OUTPUT=beastpatcher.exe | ||
5 | CROSS= | ||
6 | else | ||
7 | OUTPUT=beastpatcher | ||
8 | CROSS=i586-mingw32msvc- | ||
9 | endif | ||
10 | |||
11 | ifeq ($(OUTPUT),beastpatcher) | ||
12 | LIBS = /usr/lib/libmtp.a /usr/lib/libusb.a | ||
13 | CFLAGS += $(shell printf \ | ||
14 | '\#include <libmtp.h>\nlibmtp version: LIBMTP_VERSION\n' | \ | ||
15 | gcc -E -P - -o - | grep -q '^libmtp version: 0\.2' && echo '-DOLDMTP') | ||
16 | else | ||
17 | CFLAGS+=-mno-cygwin | ||
18 | LIBS = ../MTP_DLL.dll | ||
19 | endif | ||
20 | |||
21 | NATIVECC = gcc | ||
22 | CC = $(CROSS)gcc | ||
23 | |||
24 | all: $(OUTPUT) | ||
25 | |||
26 | beastpatcher: beastpatcher.c bootimg.c mtp_common.h mtp_libmtp.c | ||
27 | gcc $(CFLAGS) -o beastpatcher beastpatcher.c bootimg.c mtp_libmtp.c $(LIBS) | ||
28 | strip beastpatcher | ||
29 | |||
30 | beastpatcher.exe: beastpatcher.c bootimg.c mtp_common.h mtp_win32.c $(LIBS) | ||
31 | $(CROSS)$(CC) $(CFLAGS) $(LIBS) -o beastpatcher.exe beastpatcher.c bootimg.c | ||
32 | $(CROSS)strip beastpatcher.exe | ||
33 | |||
34 | beastpatcher-mac: beastpatcher-i386 beastpatcher-ppc | ||
35 | lipo -create beastpatcher-ppc beastpatcher-i386 -output beastpatcher-mac | ||
36 | |||
37 | beastpatcher-i386: beastpatcher.c bootimg.c usb.h libusb-i386.a | ||
38 | $(CC) -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -framework iokit -framework coreservices -arch i386 $(CFLAGS) -o beastpatcher-i386 beastpatcher.c bootimg.c -I. libusb-i386.a | ||
39 | strip beastpatcher-i386 | ||
40 | |||
41 | beastpatcher-ppc: beastpatcher.c bootimg.c usb.h libusb-ppc.a | ||
42 | $(CC) -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -framework iokit -framework coreservices -arch ppc $(CFLAGS) -o beastpatcher-ppc beastpatcher.c bootimg.c -I. libusb-ppc.a | ||
43 | strip beastpatcher-ppc | ||
44 | |||
45 | bin2c: ../../../rbutil/sansapatcher/bin2c.c | ||
46 | $(NATIVECC) $(CFLAGS) -o bin2c ../../../rbutil/sansapatcher/bin2c.c | ||
47 | |||
48 | bootimg.c: bootloader.bin bin2c | ||
49 | ./bin2c bootloader.bin bootimg | ||
50 | |||
51 | clean: | ||
52 | rm -f beastpatcher.exe beastpatcher-mac beastpatcher-i386 beastpatcher-ppc beastpatcher bin2c bootimg.c bootimg.h *~ | ||
diff --git a/utils/MTP/beastpatcher/README b/utils/MTP/beastpatcher/README new file mode 100644 index 0000000000..85a039268a --- /dev/null +++ b/utils/MTP/beastpatcher/README | |||
@@ -0,0 +1,61 @@ | |||
1 | beastpatcher - a tool for installing the Rockbox bootloader on the Gigabeat S | ||
2 | |||
3 | Unlike most other parts of the Rockbox project, this tool is | ||
4 | distributed under the BSD license. This is due to the fact that the | ||
5 | Windows version links with the Microsoft MTP library. | ||
6 | |||
7 | |||
8 | |||
9 | Building instructions - All OSes | ||
10 | -------------------------------- | ||
11 | |||
12 | For all versions, you need to copy a "bootloader.bin" file (containing | ||
13 | the Rockbox bootloader) into this directory. | ||
14 | |||
15 | This can be built from the Rockbox source by selecting "41" and then | ||
16 | "B" when running tools/configure. | ||
17 | |||
18 | You need the Rockbox toolchain to build any Rockbox target binaries - | ||
19 | this can be downloaded and built with the tools/rockboxdev.sh script. | ||
20 | |||
21 | The latest officially released bootloader can always be downloaded from: | ||
22 | |||
23 | http://download.rockbox.org/bootloader/gigabeat-s/ | ||
24 | |||
25 | |||
26 | |||
27 | Linux | ||
28 | ----- | ||
29 | |||
30 | The Unix versions requires libmtp, which in turn requires libusb. | ||
31 | |||
32 | beastpatcher is built to statically link to these libraries and | ||
33 | expects them to exist as /usr/lib/libmtp.a and /usr/lib/libusb.a | ||
34 | respectively. Change the definition of LIBS in the Makefile if this | ||
35 | is not the case for your system. | ||
36 | |||
37 | After this, just type "make" to get a | ||
38 | |||
39 | |||
40 | |||
41 | OS X | ||
42 | ---- | ||
43 | |||
44 | [Not yet implemented] | ||
45 | |||
46 | The OS X build is a universal binary statically linked with libusb and libmtp. | ||
47 | |||
48 | |||
49 | |||
50 | Windows | ||
51 | ------- | ||
52 | |||
53 | [Not yet implemented] | ||
54 | |||
55 | The MTP_DLL.dll requires VC2005 to compile - see instructions in | ||
56 | MTP_DLL/README | ||
57 | |||
58 | To compile beastpatcher itself, you can either cross-compile from | ||
59 | Linux using the mingw32 package, or compile in Cygwin. Just type | ||
60 | "make beastpatcher.exe" (in Linux) or "make" (in Cygwin). | ||
61 | |||
diff --git a/utils/MTP/beastpatcher/TODO b/utils/MTP/beastpatcher/TODO new file mode 100644 index 0000000000..717a77e7c8 --- /dev/null +++ b/utils/MTP/beastpatcher/TODO | |||
@@ -0,0 +1,17 @@ | |||
1 | Basic implementation: | ||
2 | |||
3 | * Windows support - need to expand API provided by MTP_DLL.dll | ||
4 | * OS X support - need to statically link against libusb and libmtp | ||
5 | * Load bootloader.bin from a file | ||
6 | |||
7 | Ideas for future features: | ||
8 | |||
9 | * Dual-boot. Look for nk.bin in current directory, and check its | ||
10 | md5sum to confirm it's an original firmware. Possibly include | ||
11 | override for user-modified OFs, and option for user to specify an | ||
12 | alternate location. | ||
13 | |||
14 | This will give the user three options - rockbox only, OF only | ||
15 | (i.e. uninstall) or dual-boot. It would be easy to give the choice | ||
16 | of two boot orders (RB on hold or OF on hold) if that was desired. | ||
17 | |||
diff --git a/utils/MTP/beastpatcher/beastpatcher.c b/utils/MTP/beastpatcher/beastpatcher.c new file mode 100644 index 0000000000..8043ebadc2 --- /dev/null +++ b/utils/MTP/beastpatcher/beastpatcher.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * $Id:$ | ||
10 | * | ||
11 | * Copyright (c) 2009, Dave Chapman | ||
12 | * All rights reserved. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions are | ||
16 | * met: | ||
17 | * | ||
18 | * * Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * | ||
21 | * * Redistributions in binary form must reproduce the above | ||
22 | * copyright notice, this list of conditions and the following | ||
23 | * disclaimer in the documentation and/or other materials provided | ||
24 | * with the distribution. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
27 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
28 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
29 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
30 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
32 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
37 | * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #include <stdio.h> | ||
41 | #include <unistd.h> | ||
42 | #include <fcntl.h> | ||
43 | #include <string.h> | ||
44 | #include <stdlib.h> | ||
45 | #include <inttypes.h> | ||
46 | #include <sys/types.h> | ||
47 | #include <sys/stat.h> | ||
48 | |||
49 | #include "mtp_common.h" | ||
50 | #include "bootimg.h" | ||
51 | |||
52 | #define VERSION "1.0 with v1 bootloader" | ||
53 | |||
54 | void print_usage(void) | ||
55 | { | ||
56 | fprintf(stderr,"Usage: beastpatcher [action]\n"); | ||
57 | fprintf(stderr,"\n"); | ||
58 | fprintf(stderr,"Where [action] is one of the following options:\n"); | ||
59 | fprintf(stderr," --install (default)\n"); | ||
60 | fprintf(stderr," -?, --help\n"); | ||
61 | fprintf(stderr,"\n"); | ||
62 | } | ||
63 | |||
64 | /* Code to create a single-boot bootloader. | ||
65 | Based on tools/gigabeats.c by Will Robertson. | ||
66 | */ | ||
67 | |||
68 | /* Entry point (and load address) for the main Rockbox bootloader */ | ||
69 | #define BL_ENTRY_POINT 0x8a000000 | ||
70 | |||
71 | static void put_uint32le(uint32_t x, unsigned char* p) | ||
72 | { | ||
73 | p[0] = x & 0xff; | ||
74 | p[1] = (x >> 8) & 0xff; | ||
75 | p[2] = (x >> 16) & 0xff; | ||
76 | p[3] = (x >> 24) & 0xff; | ||
77 | } | ||
78 | |||
79 | static uint32_t calc_csum(const unsigned char* pb, int cb) | ||
80 | { | ||
81 | uint32_t l = 0; | ||
82 | while (cb--) | ||
83 | l += *pb++; | ||
84 | return l; | ||
85 | } | ||
86 | |||
87 | static void create_single_boot(unsigned char* boot, int bootlen, | ||
88 | unsigned char** fwbuf, int* fwsize) | ||
89 | { | ||
90 | unsigned char* buf; | ||
91 | |||
92 | /* 15 bytes for header, 16 for signature bypass, | ||
93 | * 12 for record header, size of bootloader, 12 for footer */ | ||
94 | *fwsize = 15 + 16 + 12 + bootlen + 12; | ||
95 | *fwbuf = malloc(*fwsize); | ||
96 | |||
97 | if(buf == NULL) { | ||
98 | fprintf(stderr, "[ERR] Cannot allocate memory.\n" ); | ||
99 | *fwbuf = NULL; | ||
100 | *fwsize = 0; | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | buf = *fwbuf; | ||
105 | |||
106 | /* Copy bootloader image. */ | ||
107 | memcpy(buf + 43, boot, bootlen); | ||
108 | |||
109 | /* Step 2: Create the file header */ | ||
110 | sprintf((char *)buf, "B000FF\n"); | ||
111 | put_uint32le(0x88200000, buf+7); | ||
112 | |||
113 | /* If the value below is too small, the update will attempt to flash. | ||
114 | * Be careful when changing this (leaving it as is won't cause issues) */ | ||
115 | put_uint32le(0xCC0CD8, buf+11); | ||
116 | |||
117 | /* Step 3: Add the signature bypass record */ | ||
118 | put_uint32le(0x88065A10, buf+15); | ||
119 | put_uint32le(4, buf+19); | ||
120 | put_uint32le(0xE3A00001, buf+27); | ||
121 | put_uint32le(calc_csum(buf+27,4), buf+23); | ||
122 | |||
123 | /* Step 4: Create a record for the actual code */ | ||
124 | put_uint32le(BL_ENTRY_POINT, buf+31); | ||
125 | put_uint32le(bootlen, buf+35); | ||
126 | put_uint32le(calc_csum(buf + 43, bootlen), buf+39); | ||
127 | |||
128 | /* Step 5: Write the footer */ | ||
129 | put_uint32le(0, buf+*fwsize-12); | ||
130 | put_uint32le(BL_ENTRY_POINT, buf+*fwsize-8); | ||
131 | put_uint32le(0, buf+*fwsize-4); | ||
132 | |||
133 | return; | ||
134 | } | ||
135 | |||
136 | int beastpatcher(int argc, char* argv[]) | ||
137 | { | ||
138 | char yesno[4]; | ||
139 | unsigned char* fwbuf; | ||
140 | int fwsize; | ||
141 | struct mtp_info_t mtp_info; | ||
142 | |||
143 | (void)argv; | ||
144 | |||
145 | fprintf(stderr,"beastpatcher v" VERSION " - (C) 2009 by the Rockbox developers\n"); | ||
146 | fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); | ||
147 | fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); | ||
148 | |||
149 | /* No options are currently implemented, so just display help if any are | ||
150 | provided. */ | ||
151 | |||
152 | if (argc > 1) { | ||
153 | print_usage(); | ||
154 | return 1; | ||
155 | } | ||
156 | |||
157 | if (mtp_init(&mtp_info) < 0) { | ||
158 | fprintf(stderr,"[ERR] Can not init MTP\n"); | ||
159 | return 1; | ||
160 | } | ||
161 | |||
162 | /* Scan for attached MTP devices. */ | ||
163 | if (mtp_scan(&mtp_info) < 0) | ||
164 | { | ||
165 | fprintf(stderr,"[ERR] No devices found\n"); | ||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | printf("[INFO] Found device \"%s - %s\"\n", mtp_info.manufacturer, | ||
170 | mtp_info.modelname); | ||
171 | printf("[INFO] Device version: \"%s\"\n",mtp_info.version); | ||
172 | |||
173 | |||
174 | printf("\nEnter i to install the Rockbox bootloader or c to cancel and do nothing (i/c): "); | ||
175 | |||
176 | if (fgets(yesno,4,stdin)) | ||
177 | { | ||
178 | if (yesno[0]=='i') | ||
179 | { | ||
180 | /* Create a single-boot bootloader from the embedded bootloader */ | ||
181 | create_single_boot(bootimg, LEN_bootimg, &fwbuf, &fwsize); | ||
182 | |||
183 | if (fwbuf == NULL) | ||
184 | return 1; | ||
185 | |||
186 | if (mtp_send_firmware(&mtp_info, fwbuf, fwsize) == 0) | ||
187 | { | ||
188 | fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | fprintf(stderr,"[ERR] Bootloader install failed.\n"); | ||
193 | } | ||
194 | |||
195 | /* We are now done with the firmware image */ | ||
196 | free(fwbuf); | ||
197 | } | ||
198 | else | ||
199 | { | ||
200 | fprintf(stderr,"[INFO] Installation cancelled.\n"); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | mtp_finished(&mtp_info); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | |||
210 | int main(int argc, char* argv[]) | ||
211 | { | ||
212 | int res; | ||
213 | char yesno[4]; | ||
214 | |||
215 | res = beastpatcher(argc, argv); | ||
216 | |||
217 | printf("\nPress ENTER to exit beastpatcher: "); | ||
218 | fgets(yesno,4,stdin); | ||
219 | |||
220 | return res; | ||
221 | } | ||
diff --git a/utils/MTP/beastpatcher/mtp_common.h b/utils/MTP/beastpatcher/mtp_common.h new file mode 100644 index 0000000000..2fb52a9e81 --- /dev/null +++ b/utils/MTP/beastpatcher/mtp_common.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * $Id:$ | ||
10 | * | ||
11 | * Copyright (c) 2009, Dave Chapman | ||
12 | * All rights reserved. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions are | ||
16 | * met: | ||
17 | * | ||
18 | * * Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * | ||
21 | * * Redistributions in binary form must reproduce the above | ||
22 | * copyright notice, this list of conditions and the following | ||
23 | * disclaimer in the documentation and/or other materials provided | ||
24 | * with the distribution. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
27 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
28 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
29 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
30 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
32 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
37 | * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #ifndef _MTP_COMMON_H | ||
41 | #define _MTP_COMMON_H | ||
42 | |||
43 | #ifdef __WIN32__ | ||
44 | #error Windows support not yet implemented | ||
45 | #else | ||
46 | #include "libmtp.h" | ||
47 | #endif | ||
48 | |||
49 | struct mtp_info_t | ||
50 | { | ||
51 | /* Generic data */ | ||
52 | char manufacturer[200]; | ||
53 | char modelname[200]; | ||
54 | char version[200]; | ||
55 | |||
56 | /* OS-Specific data */ | ||
57 | #ifdef __WIN32__ | ||
58 | #else | ||
59 | LIBMTP_mtpdevice_t *device; | ||
60 | #endif | ||
61 | }; | ||
62 | |||
63 | /* Common functions for both libMTP and win32 */ | ||
64 | |||
65 | int mtp_init(struct mtp_info_t* mtp_info); | ||
66 | int mtp_finished(struct mtp_info_t* mtp_info); | ||
67 | int mtp_scan(struct mtp_info_t* mtp_info); | ||
68 | int mtp_send_firmware(struct mtp_info_t* mtp_info, unsigned char* fwbuf, | ||
69 | int fwsize); | ||
70 | |||
71 | #endif /* !_MTP_COMMON_H */ | ||
diff --git a/utils/MTP/beastpatcher/mtp_libmtp.c b/utils/MTP/beastpatcher/mtp_libmtp.c new file mode 100644 index 0000000000..7e8579ac99 --- /dev/null +++ b/utils/MTP/beastpatcher/mtp_libmtp.c | |||
@@ -0,0 +1,174 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * $Id:$ | ||
10 | * | ||
11 | * Copyright (c) 2009, Dave Chapman | ||
12 | * All rights reserved. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions are | ||
16 | * met: | ||
17 | * | ||
18 | * * Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * | ||
21 | * * Redistributions in binary form must reproduce the above | ||
22 | * copyright notice, this list of conditions and the following | ||
23 | * disclaimer in the documentation and/or other materials provided | ||
24 | * with the distribution. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
27 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
28 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
29 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
30 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
32 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
37 | * | ||
38 | * | ||
39 | ****************************************************************************/ | ||
40 | |||
41 | #include <string.h> | ||
42 | #include <libgen.h> | ||
43 | #include <sys/stat.h> | ||
44 | #include <sys/types.h> | ||
45 | #include <fcntl.h> | ||
46 | #include <inttypes.h> | ||
47 | #include "libmtp.h" | ||
48 | #include "mtp_common.h" | ||
49 | |||
50 | int mtp_init(struct mtp_info_t* mtp_info) | ||
51 | { | ||
52 | /* Fill the info struct with zeros - mainly for the strings */ | ||
53 | memset(mtp_info, 0, sizeof(struct mtp_info_t)); | ||
54 | |||
55 | LIBMTP_Init(); | ||
56 | |||
57 | return 0; | ||
58 | |||
59 | } | ||
60 | |||
61 | int mtp_finished(struct mtp_info_t* mtp_info) | ||
62 | { | ||
63 | LIBMTP_Release_Device(mtp_info->device); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | int mtp_scan(struct mtp_info_t* mtp_info) | ||
69 | { | ||
70 | char* str; | ||
71 | |||
72 | mtp_info->device = LIBMTP_Get_First_Device(); | ||
73 | |||
74 | if (mtp_info->device == NULL) | ||
75 | { | ||
76 | return -1; | ||
77 | } | ||
78 | else | ||
79 | { | ||
80 | /* NOTE: These strings are filled with zeros in mtp_init() */ | ||
81 | |||
82 | if ((str = LIBMTP_Get_Manufacturername(mtp_info->device))) | ||
83 | { | ||
84 | strncpy(mtp_info->manufacturer, str, sizeof(mtp_info->manufacturer)-1); | ||
85 | } | ||
86 | |||
87 | if ((str = LIBMTP_Get_Modelname(mtp_info->device))) | ||
88 | { | ||
89 | strncpy(mtp_info->modelname, str, sizeof(mtp_info->modelname)-1); | ||
90 | } | ||
91 | |||
92 | if ((str = LIBMTP_Get_Deviceversion(mtp_info->device))) | ||
93 | { | ||
94 | strncpy(mtp_info->version, str, sizeof(mtp_info->version)-1); | ||
95 | } | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | static int progress(uint64_t const sent, uint64_t const total, | ||
102 | void const *const data) | ||
103 | { | ||
104 | (void)data; | ||
105 | |||
106 | int percent = (sent * 100) / total; | ||
107 | #ifdef __WIN32__ | ||
108 | printf("Progress: %I64u of %I64u (%d%%)\r", sent, total, percent); | ||
109 | #else | ||
110 | printf("Progress: %"PRIu64" of %"PRIu64" (%d%%)\r", sent, total, percent); | ||
111 | #endif | ||
112 | fflush(stdout); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | |||
117 | int mtp_send_firmware(struct mtp_info_t* mtp_info, unsigned char* fwbuf, | ||
118 | int fwsize) | ||
119 | { | ||
120 | LIBMTP_file_t *genfile; | ||
121 | int ret; | ||
122 | size_t n; | ||
123 | FILE* fwfile; | ||
124 | |||
125 | /* Open a temporary file - this will be automatically deleted when closed */ | ||
126 | fwfile = tmpfile(); | ||
127 | |||
128 | if (fwfile == NULL) | ||
129 | { | ||
130 | fprintf(stderr,"[ERR] Could not create temporary file.\n"); | ||
131 | return -1; | ||
132 | } | ||
133 | |||
134 | n = fwrite(fwbuf, 1, fwsize, fwfile); | ||
135 | if ((int)n < fwsize) | ||
136 | { | ||
137 | fprintf(stderr,"[ERR] Could not write to temporary file - n = %d.\n",(int)n); | ||
138 | fclose(fwfile); | ||
139 | return -1; | ||
140 | } | ||
141 | |||
142 | /* Reset file pointer */ | ||
143 | fseek(fwfile, SEEK_SET, 0); | ||
144 | |||
145 | /* Prepare for uploading firmware */ | ||
146 | genfile = LIBMTP_new_file_t(); | ||
147 | genfile->filetype = LIBMTP_FILETYPE_FIRMWARE; | ||
148 | genfile->filename = strdup("nk.bin"); | ||
149 | genfile->filesize = fwsize; | ||
150 | |||
151 | #ifdef OLDMTP | ||
152 | ret = LIBMTP_Send_File_From_File_Descriptor(mtp_info->device, | ||
153 | fileno(fwfile), genfile, progress, NULL, 0); | ||
154 | #else | ||
155 | ret = LIBMTP_Send_File_From_File_Descriptor(mtp_info->device, | ||
156 | fileno(fwfile), genfile, progress, NULL); | ||
157 | #endif | ||
158 | |||
159 | /* Keep the progress line onscreen */ | ||
160 | printf("\n"); | ||
161 | |||
162 | /* NOTE: According to the docs, a value of ret != 0 means error, but libMTP | ||
163 | seems to return that even when successful. So we can't check the return | ||
164 | code. | ||
165 | */ | ||
166 | |||
167 | /* Cleanup */ | ||
168 | LIBMTP_destroy_file_t(genfile); | ||
169 | |||
170 | /* Close the temporary file - this also deletes it. */ | ||
171 | fclose(fwfile); | ||
172 | |||
173 | return 0; | ||
174 | } | ||