13aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/**
23aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * \file detect.c
33aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Example program to detect a device and list capabilities.
43aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *
53aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2005-2008 Linus Walleij <triad@df.lth.se>
63aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2007 Ted Bullock <tbullock@canada.com>
73aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *
83aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This library is free software; you can redistribute it and/or
93aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * modify it under the terms of the GNU Lesser General Public
103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * License as published by the Free Software Foundation; either
113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * version 2 of the License, or (at your option) any later version.
123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *
133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This library is distributed in the hope that it will be useful,
143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * but WITHOUT ANY WARRANTY; without even the implied warranty of
153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Lesser General Public License for more details.
173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *
183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * You should have received a copy of the GNU Lesser General Public
193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * License along with this library; if not, write to the
203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Boston, MA 02111-1307, USA.
223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */
233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "common.h"
243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "util.h"
253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <unistd.h>
263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <stdlib.h>
273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <stdio.h>
283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <string.h>
293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <errno.h>
303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#define XML_BUFSIZE 0x10000
323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void dump_xml_fragment(uint8_t *buf, uint32_t len)
343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{
353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  static int endianness = 0; // 0 = LE, 1 = BE
363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  uint32_t bp = 0;
373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  while (bp < len) {
393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (buf[bp+0] == 0xFF && buf[bp+1] == 0xFE) {
403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      endianness = 0;
413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    } else if (buf[bp+0] == 0xFE && buf[bp+1] == 0xff) {
423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      endianness = 1;
433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    } else {
443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      uint16_t tmp;
453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      if (endianness == 0) {
473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	tmp = buf[bp+1] << 8 | buf[bp+0];
483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      } else {
493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	tmp = buf[bp+0] << 8 | buf[bp+1];
503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      }
513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      // Fix this some day, we only print ISO 8859-1 correctly here,
523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      // should atleast support UTF-8.
533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("%c", (uint8_t) tmp);
543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    bp += 2;
563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  }
573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  printf("\n");
583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev}
593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint main (int argc, char **argv)
613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{
623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  LIBMTP_raw_device_t * rawdevices;
633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  int numrawdevices;
643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  LIBMTP_error_number_t err;
653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  int i;
663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  LIBMTP_Init();
683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  fprintf(stdout, "libmtp version: " LIBMTP_VERSION_STRING "\n\n");
703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  fprintf(stdout, "Listing raw device(s)\n");
723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  err = LIBMTP_Detect_Raw_Devices(&rawdevices, &numrawdevices);
733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  switch(err) {
743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case LIBMTP_ERROR_NO_DEVICE_ATTACHED:
753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    fprintf(stdout, "   No raw devices found.\n");
763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    return 0;
773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case LIBMTP_ERROR_CONNECTING:
783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    fprintf(stderr, "Detect: There has been an error connecting. Exiting\n");
793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    return 1;
803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case LIBMTP_ERROR_MEMORY_ALLOCATION:
813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    fprintf(stderr, "Detect: Encountered a Memory Allocation Error. Exiting\n");
823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    return 1;
833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case LIBMTP_ERROR_NONE:
843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    {
853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      int i;
863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "   Found %d device(s):\n", numrawdevices);
883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      for (i = 0; i < numrawdevices; i++) {
893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	if (rawdevices[i].device_entry.vendor != NULL ||
903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	    rawdevices[i].device_entry.product != NULL) {
913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  fprintf(stdout, "   %s: %s (%04x:%04x) @ bus %d, dev %d\n",
923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].device_entry.vendor,
933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].device_entry.product,
943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].device_entry.vendor_id,
953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].device_entry.product_id,
963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].bus_location,
973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].devnum);
983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	} else {
993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  fprintf(stdout, "   %04x:%04x @ bus %d, dev %d\n",
1003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].device_entry.vendor_id,
1013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].device_entry.product_id,
1023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].bus_location,
1033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  rawdevices[i].devnum);
1043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	}
1053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      }
1063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    break;
1083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case LIBMTP_ERROR_GENERAL:
1093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  default:
1103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    fprintf(stderr, "Unknown connection error.\n");
1113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    return 1;
1123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  }
1133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  /* Iterate over connected MTP devices */
1153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  fprintf(stdout, "Attempting to connect device(s)\n");
1163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  for (i = 0; i < numrawdevices; i++) {
1173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    LIBMTP_mtpdevice_t *device;
1183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    LIBMTP_file_t *files;
1193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    char *friendlyname;
1203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    char *syncpartner;
1213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    char *sectime;
1223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    char *devcert;
1233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    uint16_t *filetypes;
1243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    uint16_t filetypes_len;
1253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    uint8_t maxbattlevel;
1263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    uint8_t currbattlevel;
1273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    int ret;
1283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    device = LIBMTP_Open_Raw_Device(&rawdevices[i]);
1303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (device == NULL) {
1313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stderr, "Unable to open raw device %d\n", i);
1323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      continue;
1333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    LIBMTP_Dump_Errorstack(device);
1363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    LIBMTP_Clear_Errorstack(device);
1373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    LIBMTP_Dump_Device_Info(device);
1383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("MTP-specific device properties:\n");
1403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    // The friendly name
1413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    friendlyname = LIBMTP_Get_Friendlyname(device);
1423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (friendlyname == NULL) {
1433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "   Friendly name: (NULL)\n");
1443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    } else {
1453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "   Friendly name: %s\n", friendlyname);
1463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      free(friendlyname);
1473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    syncpartner = LIBMTP_Get_Syncpartner(device);
1493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (syncpartner == NULL) {
1503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "   Synchronization partner: (NULL)\n");
1513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    } else {
1523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "   Synchronization partner: %s\n", syncpartner);
1533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      free(syncpartner);
1543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    // Some battery info
1573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    ret = LIBMTP_Get_Batterylevel(device, &maxbattlevel, &currbattlevel);
1583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (ret == 0) {
1593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "   Battery level %d of %d (%d%%)\n",currbattlevel, maxbattlevel,
1603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      (int) ((float) currbattlevel/ (float) maxbattlevel * 100.0));
1613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    } else {
1623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      // Silently ignore. Some devices does not support getting the
1633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      // battery level.
1643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_Clear_Errorstack(device);
1653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    ret = LIBMTP_Get_Supported_Filetypes(device, &filetypes, &filetypes_len);
1683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (ret == 0) {
1693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      uint16_t i;
1703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("libmtp supported (playable) filetypes:\n");
1723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      for (i = 0; i < filetypes_len; i++) {
1733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	fprintf(stdout, "   %s\n", LIBMTP_Get_Filetype_Description(filetypes[i]));
1743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      }
1753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    } else {
1763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_Dump_Errorstack(device);
1773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_Clear_Errorstack(device);
1783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    // Secure time XML fragment
1813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    ret = LIBMTP_Get_Secure_Time(device, &sectime);
1823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (ret == 0 && sectime != NULL) {
1833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "\nSecure Time:\n%s\n", sectime);
1843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      free(sectime);
1853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    } else {
1863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      // Silently ignore - there may be devices not supporting secure time.
1873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_Clear_Errorstack(device);
1883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    // Device certificate XML fragment
1913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    ret = LIBMTP_Get_Device_Certificate(device, &devcert);
1923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (ret == 0 && devcert != NULL) {
1933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "\nDevice Certificate:\n%s\n", devcert);
1943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      free(devcert);
1953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    } else {
1963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      fprintf(stdout, "Unable to acquire device certificate, perhaps this device "
1973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      "does not support this\n");
1983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_Dump_Errorstack(device);
1993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_Clear_Errorstack(device);
2003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
2013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    // Try to get Media player device info XML file...
2033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    files = LIBMTP_Get_Filelisting_With_Callback(device, NULL, NULL);
2043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    if (files != NULL) {
2053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_file_t *file, *tmp;
2063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      file = files;
2073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      while (file != NULL) {
2083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	if (!strcmp(file->filename, "WMPInfo.xml") ||
2093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	    !strcmp(file->filename, "WMPinfo.xml") ||
2103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	    !strcmp(file->filename, "default-capabilities.xml")) {
2113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	    if (file->item_id != 0) {
2123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      /* Dump this file */
2133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      FILE *xmltmp = tmpfile();
2143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      int tmpfiledescriptor = fileno(xmltmp);
2153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      if (tmpfiledescriptor != -1) {
2173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		int ret = LIBMTP_Get_Track_To_File_Descriptor(device,
2183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev							      file->item_id,
2193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev							      tmpfiledescriptor,
2203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev							      NULL,
2213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev							      NULL);
2223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		if (ret == 0) {
2233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  uint8_t *buf = NULL;
2243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  uint32_t readbytes;
2253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  buf = malloc(XML_BUFSIZE);
2273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  if (buf == NULL) {
2283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    printf("Could not allocate %08x bytes...\n", XML_BUFSIZE);
2293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    LIBMTP_Dump_Errorstack(device);
2303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    LIBMTP_Clear_Errorstack(device);
2313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    free(rawdevices);
2323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    return 1;
2333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  }
2343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  lseek(tmpfiledescriptor, 0, SEEK_SET);
2363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  readbytes = read(tmpfiledescriptor, (void*) buf, XML_BUFSIZE);
2373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  if (readbytes >= 2 && readbytes < XML_BUFSIZE) {
2393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    fprintf(stdout, "\n%s file contents:\n", file->filename);
2403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    dump_xml_fragment(buf, readbytes);
2413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  } else {
2423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    perror("Unable to read file");
2433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    LIBMTP_Dump_Errorstack(device);
2443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		    LIBMTP_Clear_Errorstack(device);
2453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  }
2463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  free(buf);
2473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		} else {
2483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  LIBMTP_Dump_Errorstack(device);
2493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		  LIBMTP_Clear_Errorstack(device);
2503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		}
2513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev		fclose(xmltmp);
2523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      }
2533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	    }
2543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	}
2553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	tmp = file;
2563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	file = file->next;
2573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	LIBMTP_destroy_file_t(tmp);
2583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      }
2593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
2603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    LIBMTP_Release_Device(device);
2613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  } /* End For Loop */
2623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  free(rawdevices);
2643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  printf("OK.\n");
2663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  return 0;
2683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev}
269