summaryrefslogtreecommitdiffstats
path: root/utils/MTP
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2009-02-22 13:54:46 +0000
committerDave Chapman <dave@dchapman.com>2009-02-22 13:54:46 +0000
commitc06071e2e705095e49207f92b941edd3b5ada46c (patch)
tree28e6b326720a12f26c56ff098ea12fea50838808 /utils/MTP
parent65d404ff6a78c6e2135f3e4f1f9d5634bed0dfce (diff)
downloadrockbox-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/MTP')
-rw-r--r--utils/MTP/beastpatcher/Makefile52
-rw-r--r--utils/MTP/beastpatcher/README61
-rw-r--r--utils/MTP/beastpatcher/TODO17
-rw-r--r--utils/MTP/beastpatcher/beastpatcher.c221
-rw-r--r--utils/MTP/beastpatcher/mtp_common.h71
-rw-r--r--utils/MTP/beastpatcher/mtp_libmtp.c174
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 @@
+CFLAGS=-Wall -W
+
+ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
+OUTPUT=beastpatcher.exe
+CROSS=
+else
+OUTPUT=beastpatcher
+CROSS=i586-mingw32msvc-
+endif
+
+ifeq ($(OUTPUT),beastpatcher)
+LIBS = /usr/lib/libmtp.a /usr/lib/libusb.a
+CFLAGS += $(shell printf \
+ '\#include <libmtp.h>\nlibmtp version: LIBMTP_VERSION\n' | \
+ gcc -E -P - -o - | grep -q '^libmtp version: 0\.2' && echo '-DOLDMTP')
+else
+CFLAGS+=-mno-cygwin
+LIBS = ../MTP_DLL.dll
+endif
+
+NATIVECC = gcc
+CC = $(CROSS)gcc
+
+all: $(OUTPUT)
+
+beastpatcher: beastpatcher.c bootimg.c mtp_common.h mtp_libmtp.c
+ gcc $(CFLAGS) -o beastpatcher beastpatcher.c bootimg.c mtp_libmtp.c $(LIBS)
+ strip beastpatcher
+
+beastpatcher.exe: beastpatcher.c bootimg.c mtp_common.h mtp_win32.c $(LIBS)
+ $(CROSS)$(CC) $(CFLAGS) $(LIBS) -o beastpatcher.exe beastpatcher.c bootimg.c
+ $(CROSS)strip beastpatcher.exe
+
+beastpatcher-mac: beastpatcher-i386 beastpatcher-ppc
+ lipo -create beastpatcher-ppc beastpatcher-i386 -output beastpatcher-mac
+
+beastpatcher-i386: beastpatcher.c bootimg.c usb.h libusb-i386.a
+ $(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
+ strip beastpatcher-i386
+
+beastpatcher-ppc: beastpatcher.c bootimg.c usb.h libusb-ppc.a
+ $(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
+ strip beastpatcher-ppc
+
+bin2c: ../../../rbutil/sansapatcher/bin2c.c
+ $(NATIVECC) $(CFLAGS) -o bin2c ../../../rbutil/sansapatcher/bin2c.c
+
+bootimg.c: bootloader.bin bin2c
+ ./bin2c bootloader.bin bootimg
+
+clean:
+ 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 @@
+beastpatcher - a tool for installing the Rockbox bootloader on the Gigabeat S
+
+Unlike most other parts of the Rockbox project, this tool is
+distributed under the BSD license. This is due to the fact that the
+Windows version links with the Microsoft MTP library.
+
+
+
+Building instructions - All OSes
+--------------------------------
+
+For all versions, you need to copy a "bootloader.bin" file (containing
+the Rockbox bootloader) into this directory.
+
+This can be built from the Rockbox source by selecting "41" and then
+"B" when running tools/configure.
+
+You need the Rockbox toolchain to build any Rockbox target binaries -
+this can be downloaded and built with the tools/rockboxdev.sh script.
+
+The latest officially released bootloader can always be downloaded from:
+
+http://download.rockbox.org/bootloader/gigabeat-s/
+
+
+
+Linux
+-----
+
+The Unix versions requires libmtp, which in turn requires libusb.
+
+beastpatcher is built to statically link to these libraries and
+expects them to exist as /usr/lib/libmtp.a and /usr/lib/libusb.a
+respectively. Change the definition of LIBS in the Makefile if this
+is not the case for your system.
+
+After this, just type "make" to get a
+
+
+
+OS X
+----
+
+[Not yet implemented]
+
+The OS X build is a universal binary statically linked with libusb and libmtp.
+
+
+
+Windows
+-------
+
+[Not yet implemented]
+
+The MTP_DLL.dll requires VC2005 to compile - see instructions in
+MTP_DLL/README
+
+To compile beastpatcher itself, you can either cross-compile from
+Linux using the mingw32 package, or compile in Cygwin. Just type
+"make beastpatcher.exe" (in Linux) or "make" (in Cygwin).
+
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 @@
+Basic implementation:
+
+* Windows support - need to expand API provided by MTP_DLL.dll
+* OS X support - need to statically link against libusb and libmtp
+* Load bootloader.bin from a file
+
+Ideas for future features:
+
+* Dual-boot. Look for nk.bin in current directory, and check its
+ md5sum to confirm it's an original firmware. Possibly include
+ override for user-modified OFs, and option for user to specify an
+ alternate location.
+
+ This will give the user three options - rockbox only, OF only
+ (i.e. uninstall) or dual-boot. It would be easy to give the choice
+ of two boot orders (RB on hold or OF on hold) if that was desired.
+
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * $Id:$
+ *
+ * Copyright (c) 2009, Dave Chapman
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "mtp_common.h"
+#include "bootimg.h"
+
+#define VERSION "1.0 with v1 bootloader"
+
+void print_usage(void)
+{
+ fprintf(stderr,"Usage: beastpatcher [action]\n");
+ fprintf(stderr,"\n");
+ fprintf(stderr,"Where [action] is one of the following options:\n");
+ fprintf(stderr," --install (default)\n");
+ fprintf(stderr," -?, --help\n");
+ fprintf(stderr,"\n");
+}
+
+/* Code to create a single-boot bootloader.
+ Based on tools/gigabeats.c by Will Robertson.
+*/
+
+/* Entry point (and load address) for the main Rockbox bootloader */
+#define BL_ENTRY_POINT 0x8a000000
+
+static void put_uint32le(uint32_t x, unsigned char* p)
+{
+ p[0] = x & 0xff;
+ p[1] = (x >> 8) & 0xff;
+ p[2] = (x >> 16) & 0xff;
+ p[3] = (x >> 24) & 0xff;
+}
+
+static uint32_t calc_csum(const unsigned char* pb, int cb)
+{
+ uint32_t l = 0;
+ while (cb--)
+ l += *pb++;
+ return l;
+}
+
+static void create_single_boot(unsigned char* boot, int bootlen,
+ unsigned char** fwbuf, int* fwsize)
+{
+ unsigned char* buf;
+
+ /* 15 bytes for header, 16 for signature bypass,
+ * 12 for record header, size of bootloader, 12 for footer */
+ *fwsize = 15 + 16 + 12 + bootlen + 12;
+ *fwbuf = malloc(*fwsize);
+
+ if(buf == NULL) {
+ fprintf(stderr, "[ERR] Cannot allocate memory.\n" );
+ *fwbuf = NULL;
+ *fwsize = 0;
+ return;
+ }
+
+ buf = *fwbuf;
+
+ /* Copy bootloader image. */
+ memcpy(buf + 43, boot, bootlen);
+
+ /* Step 2: Create the file header */
+ sprintf((char *)buf, "B000FF\n");
+ put_uint32le(0x88200000, buf+7);
+
+ /* If the value below is too small, the update will attempt to flash.
+ * Be careful when changing this (leaving it as is won't cause issues) */
+ put_uint32le(0xCC0CD8, buf+11);
+
+ /* Step 3: Add the signature bypass record */
+ put_uint32le(0x88065A10, buf+15);
+ put_uint32le(4, buf+19);
+ put_uint32le(0xE3A00001, buf+27);
+ put_uint32le(calc_csum(buf+27,4), buf+23);
+
+ /* Step 4: Create a record for the actual code */
+ put_uint32le(BL_ENTRY_POINT, buf+31);
+ put_uint32le(bootlen, buf+35);
+ put_uint32le(calc_csum(buf + 43, bootlen), buf+39);
+
+ /* Step 5: Write the footer */
+ put_uint32le(0, buf+*fwsize-12);
+ put_uint32le(BL_ENTRY_POINT, buf+*fwsize-8);
+ put_uint32le(0, buf+*fwsize-4);
+
+ return;
+}
+
+int beastpatcher(int argc, char* argv[])
+{
+ char yesno[4];
+ unsigned char* fwbuf;
+ int fwsize;
+ struct mtp_info_t mtp_info;
+
+ (void)argv;
+
+ fprintf(stderr,"beastpatcher v" VERSION " - (C) 2009 by the Rockbox developers\n");
+ fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n");
+ fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
+
+ /* No options are currently implemented, so just display help if any are
+ provided. */
+
+ if (argc > 1) {
+ print_usage();
+ return 1;
+ }
+
+ if (mtp_init(&mtp_info) < 0) {
+ fprintf(stderr,"[ERR] Can not init MTP\n");
+ return 1;
+ }
+
+ /* Scan for attached MTP devices. */
+ if (mtp_scan(&mtp_info) < 0)
+ {
+ fprintf(stderr,"[ERR] No devices found\n");
+ return 1;
+ }
+
+ printf("[INFO] Found device \"%s - %s\"\n", mtp_info.manufacturer,
+ mtp_info.modelname);
+ printf("[INFO] Device version: \"%s\"\n",mtp_info.version);
+
+
+ printf("\nEnter i to install the Rockbox bootloader or c to cancel and do nothing (i/c): ");
+
+ if (fgets(yesno,4,stdin))
+ {
+ if (yesno[0]=='i')
+ {
+ /* Create a single-boot bootloader from the embedded bootloader */
+ create_single_boot(bootimg, LEN_bootimg, &fwbuf, &fwsize);
+
+ if (fwbuf == NULL)
+ return 1;
+
+ if (mtp_send_firmware(&mtp_info, fwbuf, fwsize) == 0)
+ {
+ fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
+ }
+ else
+ {
+ fprintf(stderr,"[ERR] Bootloader install failed.\n");
+ }
+
+ /* We are now done with the firmware image */
+ free(fwbuf);
+ }
+ else
+ {
+ fprintf(stderr,"[INFO] Installation cancelled.\n");
+ }
+ }
+
+ mtp_finished(&mtp_info);
+
+ return 0;
+}
+
+
+int main(int argc, char* argv[])
+{
+ int res;
+ char yesno[4];
+
+ res = beastpatcher(argc, argv);
+
+ printf("\nPress ENTER to exit beastpatcher: ");
+ fgets(yesno,4,stdin);
+
+ return res;
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * $Id:$
+ *
+ * Copyright (c) 2009, Dave Chapman
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef _MTP_COMMON_H
+#define _MTP_COMMON_H
+
+#ifdef __WIN32__
+#error Windows support not yet implemented
+#else
+#include "libmtp.h"
+#endif
+
+struct mtp_info_t
+{
+ /* Generic data */
+ char manufacturer[200];
+ char modelname[200];
+ char version[200];
+
+ /* OS-Specific data */
+#ifdef __WIN32__
+#else
+ LIBMTP_mtpdevice_t *device;
+#endif
+};
+
+/* Common functions for both libMTP and win32 */
+
+int mtp_init(struct mtp_info_t* mtp_info);
+int mtp_finished(struct mtp_info_t* mtp_info);
+int mtp_scan(struct mtp_info_t* mtp_info);
+int mtp_send_firmware(struct mtp_info_t* mtp_info, unsigned char* fwbuf,
+ int fwsize);
+
+#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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * $Id:$
+ *
+ * Copyright (c) 2009, Dave Chapman
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <libgen.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include "libmtp.h"
+#include "mtp_common.h"
+
+int mtp_init(struct mtp_info_t* mtp_info)
+{
+ /* Fill the info struct with zeros - mainly for the strings */
+ memset(mtp_info, 0, sizeof(struct mtp_info_t));
+
+ LIBMTP_Init();
+
+ return 0;
+
+}
+
+int mtp_finished(struct mtp_info_t* mtp_info)
+{
+ LIBMTP_Release_Device(mtp_info->device);
+
+ return 0;
+}
+
+int mtp_scan(struct mtp_info_t* mtp_info)
+{
+ char* str;
+
+ mtp_info->device = LIBMTP_Get_First_Device();
+
+ if (mtp_info->device == NULL)
+ {
+ return -1;
+ }
+ else
+ {
+ /* NOTE: These strings are filled with zeros in mtp_init() */
+
+ if ((str = LIBMTP_Get_Manufacturername(mtp_info->device)))
+ {
+ strncpy(mtp_info->manufacturer, str, sizeof(mtp_info->manufacturer)-1);
+ }
+
+ if ((str = LIBMTP_Get_Modelname(mtp_info->device)))
+ {
+ strncpy(mtp_info->modelname, str, sizeof(mtp_info->modelname)-1);
+ }
+
+ if ((str = LIBMTP_Get_Deviceversion(mtp_info->device)))
+ {
+ strncpy(mtp_info->version, str, sizeof(mtp_info->version)-1);
+ }
+
+ return 0;
+ }
+}
+
+static int progress(uint64_t const sent, uint64_t const total,
+ void const *const data)
+{
+ (void)data;
+
+ int percent = (sent * 100) / total;
+#ifdef __WIN32__
+ printf("Progress: %I64u of %I64u (%d%%)\r", sent, total, percent);
+#else
+ printf("Progress: %"PRIu64" of %"PRIu64" (%d%%)\r", sent, total, percent);
+#endif
+ fflush(stdout);
+ return 0;
+}
+
+
+int mtp_send_firmware(struct mtp_info_t* mtp_info, unsigned char* fwbuf,
+ int fwsize)
+{
+ LIBMTP_file_t *genfile;
+ int ret;
+ size_t n;
+ FILE* fwfile;
+
+ /* Open a temporary file - this will be automatically deleted when closed */
+ fwfile = tmpfile();
+
+ if (fwfile == NULL)
+ {
+ fprintf(stderr,"[ERR] Could not create temporary file.\n");
+ return -1;
+ }
+
+ n = fwrite(fwbuf, 1, fwsize, fwfile);
+ if ((int)n < fwsize)
+ {
+ fprintf(stderr,"[ERR] Could not write to temporary file - n = %d.\n",(int)n);
+ fclose(fwfile);
+ return -1;
+ }
+
+ /* Reset file pointer */
+ fseek(fwfile, SEEK_SET, 0);
+
+ /* Prepare for uploading firmware */
+ genfile = LIBMTP_new_file_t();
+ genfile->filetype = LIBMTP_FILETYPE_FIRMWARE;
+ genfile->filename = strdup("nk.bin");
+ genfile->filesize = fwsize;
+
+#ifdef OLDMTP
+ ret = LIBMTP_Send_File_From_File_Descriptor(mtp_info->device,
+ fileno(fwfile), genfile, progress, NULL, 0);
+#else
+ ret = LIBMTP_Send_File_From_File_Descriptor(mtp_info->device,
+ fileno(fwfile), genfile, progress, NULL);
+#endif
+
+ /* Keep the progress line onscreen */
+ printf("\n");
+
+ /* NOTE: According to the docs, a value of ret != 0 means error, but libMTP
+ seems to return that even when successful. So we can't check the return
+ code.
+ */
+
+ /* Cleanup */
+ LIBMTP_destroy_file_t(genfile);
+
+ /* Close the temporary file - this also deletes it. */
+ fclose(fwfile);
+
+ return 0;
+}