Sync to upstream.
diff --git a/src/libmtp.c b/src/libmtp.c
index b06c484..fa4fa9f 100644
--- a/src/libmtp.c
+++ b/src/libmtp.c
@@ -957,6 +957,7 @@
 }
 
 
+/*
 struct {
   uint16_t opcode;
   const char *name;
@@ -1040,6 +1041,7 @@
   }
   return snprintf (txt, spaceleft,"Unknown(%04x)", opcode);
 }
+*/
 
 
 /**
diff --git a/src/ptp-pack.c b/src/ptp-pack.c
index 655fbd1..277c7ad 100644
--- a/src/ptp-pack.c
+++ b/src/ptp-pack.c
@@ -249,7 +249,7 @@
 	uint8_t len;
 	unsigned int totallen;
 	
-	di->StaqndardVersion = dtoh16a(&data[PTP_di_StandardVersion]);
+	di->StandardVersion = dtoh16a(&data[PTP_di_StandardVersion]);
 	di->VendorExtensionID =
 		dtoh32a(&data[PTP_di_VendorExtensionID]);
 	di->VendorExtensionVersion =
@@ -965,3 +965,140 @@
 	}
 	return len;
 }
+
+#define ptp_canon_dir_version	0x00
+#define ptp_canon_dir_ofc	0x02
+#define ptp_canon_dir_unk1	0x04
+#define ptp_canon_dir_objectid	0x08
+#define ptp_canon_dir_parentid	0x0c
+#define ptp_canon_dir_previd	0x10	/* in same dir */
+#define ptp_canon_dir_nextid	0x14	/* in same dir */
+#define ptp_canon_dir_nextchild	0x18	/* down one dir */
+#define ptp_canon_dir_storageid	0x1c	/* only in storage entry */
+#define ptp_canon_dir_name	0x20
+#define ptp_canon_dir_flags	0x2c
+#define ptp_canon_dir_size	0x30
+#define ptp_canon_dir_unixtime	0x34
+#define ptp_canon_dir_year	0x38
+#define ptp_canon_dir_month	0x39
+#define ptp_canon_dir_mday	0x3a
+#define ptp_canon_dir_hour	0x3b
+#define ptp_canon_dir_minute	0x3c
+#define ptp_canon_dir_second	0x3d
+#define ptp_canon_dir_unk2	0x3e
+#define ptp_canon_dir_thumbsize	0x40
+#define ptp_canon_dir_width	0x44
+#define ptp_canon_dir_height	0x48
+
+static inline uint16_t
+ptp_unpack_canon_directory (
+	PTPParams		*params,
+	unsigned char		*dir,
+	uint32_t		cnt,
+	PTPObjectHandles	*handles,
+	PTPObjectInfo		**oinfos,	/* size(handles->n) */
+	uint32_t		**flags		/* size(handles->n) */
+) {
+	unsigned int	i, j, nrofobs = 0, curob = 0;
+
+#define ISOBJECT(ptr) (dtoh32a((ptr)+ptp_canon_dir_storageid) == 0xffffffff)
+	for (i=0;i<cnt;i++)
+		if (ISOBJECT(dir+i*0x4c)) nrofobs++;
+	handles->n = nrofobs;
+	handles->Handler = calloc(sizeof(handles->Handler[0]),nrofobs);
+	if (!handles->Handler) return PTP_RC_GeneralError;
+	*oinfos = calloc(sizeof((*oinfos)[0]),nrofobs);
+	if (!*oinfos) return PTP_RC_GeneralError;
+	*flags  = calloc(sizeof((*flags)[0]),nrofobs);
+	if (!*flags) return PTP_RC_GeneralError;
+
+	/* Migrate data into objects ids, handles into
+	 * the object handler array.
+	 */
+	curob = 0;
+	for (i=0;i<cnt;i++) {
+		unsigned char	*cur = dir+i*0x4c;
+		PTPObjectInfo	*oi = (*oinfos)+curob;
+
+		if (!ISOBJECT(cur))
+			continue;
+
+		handles->Handler[curob] = dtoh32a(cur + ptp_canon_dir_objectid);
+		oi->StorageID		= 0xffffffff;
+		oi->ObjectFormat	= dtoh16a(cur + ptp_canon_dir_ofc);
+		oi->ParentObject	= dtoh32a(cur + ptp_canon_dir_parentid);
+		oi->Filename		= strdup((char*)(cur + ptp_canon_dir_name));
+		oi->ObjectCompressedSize= dtoh32a(cur + ptp_canon_dir_size);
+		oi->ThumbCompressedSize	= dtoh32a(cur + ptp_canon_dir_thumbsize);
+		oi->ImagePixWidth	= dtoh32a(cur + ptp_canon_dir_width);
+		oi->ImagePixHeight	= dtoh32a(cur + ptp_canon_dir_height);
+		oi->CaptureDate		= oi->ModificationDate = dtoh32a(cur + ptp_canon_dir_unixtime);
+		(*flags)[curob]		= dtoh32a(cur + ptp_canon_dir_flags);
+		curob++;
+	}
+	/* Walk over Storage ID entries and distribute the IDs to
+	 * the parent objects. */
+	for (i=0;i<cnt;i++) {
+		unsigned char	*cur = dir+i*0x4c;
+		uint32_t	nextchild = dtoh32a(cur + ptp_canon_dir_nextchild);
+
+		if (ISOBJECT(cur))
+			continue;
+		for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break;
+		if (j == handles->n) continue;
+		(*oinfos)[j].StorageID = dtoh32a(cur + ptp_canon_dir_storageid);
+	}
+	/* Walk over all objects and distribute the storage ids */
+	while (1) {
+		int changed = 0;
+		for (i=0;i<cnt;i++) {
+			unsigned char	*cur = dir+i*0x4c;
+			uint32_t	oid = dtoh32a(cur + ptp_canon_dir_objectid);
+			uint32_t	nextoid = dtoh32a(cur + ptp_canon_dir_nextid);
+			uint32_t	nextchild = dtoh32a(cur + ptp_canon_dir_nextchild);
+			uint32_t	storageid;
+
+			if (!ISOBJECT(cur))
+				continue;
+			for (j=0;j<handles->n;j++) if (oid == handles->Handler[j]) break;
+			if (j == handles->n) {
+				/*fprintf(stderr,"did not find oid in lookup pass for current oid\n");*/
+				continue;
+			}
+	 		storageid = (*oinfos)[j].StorageID;
+			if (storageid == 0xffffffff) continue;
+			if (nextoid != 0xffffffff) {
+				for (j=0;j<handles->n;j++) if (nextoid == handles->Handler[j]) break;
+				if (j == handles->n) {
+					/*fprintf(stderr,"did not find oid in lookup pass for next oid\n");*/
+					continue;
+				}
+				if ((*oinfos)[j].StorageID == 0xffffffff) {
+					(*oinfos)[j].StorageID = storageid;
+					changed++;
+				}
+			}
+			if (nextchild != 0xffffffff) {
+				for (j=0;j<handles->n;j++) if (nextchild == handles->Handler[j]) break;
+				if (j == handles->n) {
+					/*fprintf(stderr,"did not find oid in lookup pass for next child\n");*/
+					continue;
+				}
+				if ((*oinfos)[j].StorageID == 0xffffffff) {
+					(*oinfos)[j].StorageID = storageid;
+					changed++;
+				}
+			}
+		}
+		/* Check if we:
+		 * - changed no entry (nothing more to do)
+		 * - changed all of them at once (usually happens)
+		 * break if we do.
+		 */
+		if (!changed || (changed==nrofobs-1))
+			break;
+	}
+#undef ISOBJECT
+	return PTP_RC_OK;
+}
+
diff --git a/src/ptp.c b/src/ptp.c
index 645e1b3..7d9af5c 100644
--- a/src/ptp.c
+++ b/src/ptp.c
@@ -449,7 +449,13 @@
 	}
 	/* get response */
 	CHECK_PTP_RC(params->getresp_func(params, ptp));
-
+	if (ptp->Transaction_ID != params->transaction_id-1) {
+		ptp_error (params,
+			"PTP: Sequence number mismatch %d vs expected %d.",
+			ptp->Transaction_ID, params->transaction_id-1
+		);
+		return PTP_ERROR_BADPARAM;
+	}
 	return ptp->Code;
 }
 
@@ -506,10 +512,21 @@
 	}
 	if (ret!=PTP_RC_OK) {
 		ptp_error (params,
-			"PTP: reading event an error 0x%04x occured", ret);
+			"PTP: reading event an error 0x%04x occurred", ret);
 		ret = PTP_ERROR_IO;
 		/* reading event error is nonfatal (for example timeout) */
 	} 
+	while (dtoh32(usbevent.length) > rlen) {
+		unsigned int newrlen = 0;
+
+		ret=params->check_int_fast_func(((unsigned char*)&usbevent)+rlen,
+			dtoh32(usbevent.length)-rlen,params->data,&newrlen
+		);
+		if (ret != PTP_RC_OK) {
+			break;
+		}
+		rlen+=newrlen;
+	} 
 	/* if we read anything over interrupt endpoint it must be an event */
 	/* build an appropriate PTPContainer */
 	event->Code=dtoh16(usbevent.code);
@@ -518,7 +535,6 @@
 	event->Param1=dtoh32(usbevent.param1);
 	event->Param2=dtoh32(usbevent.param2);
 	event->Param3=dtoh32(usbevent.param3);
-
 	return ret;
 }
 
@@ -1305,28 +1321,31 @@
 
 
 /**
- * ptp_canon_getobjectsize:
+ * ptp_canon_getpartialobjectinfo:
  * params:	PTPParams*
  *		uint32_t handle		- ObjectHandle
- *		uint32_t p2 		- Yet unknown parameter,
- *					  value 0 works.
+ *		uint32_t p2 		- Not fully understood parameter
+ *					  0 - returns full size
+ *					  1 - returns thumbnail size (or EXIF?)
  * 
  * Gets form the responder the size of the specified object.
  *
  * Return values: Some PTP_RC_* code.
  * Upon success : uint32_t* size	- The object size
- *		  uint32_t  rp2		- Yet unknown parameter
+ *		  uint32_t* rp2		- Still unknown return parameter
+ *                                        (perhaps upper 32bit of size)
+ *
  *
  **/
 uint16_t
-ptp_canon_getobjectsize (PTPParams* params, uint32_t handle, uint32_t p2, 
+ptp_canon_getpartialobjectinfo (PTPParams* params, uint32_t handle, uint32_t p2, 
 			uint32_t* size, uint32_t* rp2) 
 {
 	uint16_t ret;
 	PTPContainer ptp;
 	
 	PTP_CNT_INIT(ptp);
-	ptp.Code=PTP_OC_CANON_GetObjectSize;
+	ptp.Code=PTP_OC_CANON_GetPartialObjectInfo;
 	ptp.Param1=handle;
 	ptp.Param2=p2;
 	ptp.Nparam=2;
@@ -1337,6 +1356,87 @@
 }
 
 /**
+ * ptp_canon_get_mac_address:
+ * params:	PTPParams*
+ *					  value 0 works.
+ * Gets the MAC address of the wireless transmitter.
+ *
+ * Return values: Some PTP_RC_* code.
+ * Upon success : unsigned char* mac	- The MAC address
+ *
+ **/
+uint16_t
+ptp_canon_get_mac_address (PTPParams* params, unsigned char **mac)
+{
+	PTPContainer ptp;
+	unsigned int size = 0;
+
+	PTP_CNT_INIT(ptp);
+	ptp.Code=PTP_OC_CANON_GetMACAddress;
+	ptp.Nparam=0;
+	*mac = NULL;
+	return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, mac, &size);
+}
+
+/**
+ * ptp_canon_get_directory:
+ * params:	PTPParams*
+
+ * Gets the full directory of the camera.
+ *
+ * Return values: Some PTP_RC_* code.
+ * Upon success : PTPObjectHandles        *handles	- filled out with handles
+ * 		  PTPObjectInfo           **oinfos	- allocated array of PTP Object Infos
+ * 		  uint32_t                **flags	- allocated array of CANON Flags
+ *
+ **/
+uint16_t
+ptp_canon_get_directory (PTPParams* params,
+	PTPObjectHandles	*handles,
+	PTPObjectInfo		**oinfos,	/* size(handles->n) */
+	uint32_t		**flags		/* size(handles->n) */
+) {
+	PTPContainer	ptp;
+	unsigned char	*dir = NULL;
+	unsigned int	size = 0;
+	uint16_t	ret;
+
+	PTP_CNT_INIT(ptp);
+	ptp.Code=PTP_OC_CANON_GetDirectory;
+	ptp.Nparam=0;
+	ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &dir, &size);
+	if (ret != PTP_RC_OK)
+		return ret;
+	ret = ptp_unpack_canon_directory(params, dir, ptp.Param1, handles, oinfos, flags);
+	free (dir);
+	return ret;
+}
+
+/**
+ * ptp_canon_setobjectarchive:
+ *
+ * params:	PTPParams*
+ *		uint32_t	objectid
+ *		uint32_t	flags
+ *
+ * Return values: Some PTP_RC_* code.
+ *
+ **/
+uint16_t
+ptp_canon_setobjectarchive (PTPParams* params, uint32_t oid, uint32_t flags)
+{
+	PTPContainer ptp;
+
+	PTP_CNT_INIT(ptp);
+	ptp.Code=PTP_OC_CANON_SetObjectArchive;
+	ptp.Nparam=2;
+	ptp.Param1=oid;
+	ptp.Param2=flags;
+	return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
+}
+
+
+/**
  * ptp_canon_startshootingmode:
  * params:	PTPParams*
  * 
@@ -1360,6 +1460,74 @@
 }
 
 /**
+ * ptp_canon_initiate_direct_transfer:
+ * params:	PTPParams*
+ *              uint32_t *out
+ * 
+ * Switches the camera display to on and lets the user
+ * select what to transfer. Sends a 0xc011 event when started 
+ * and 0xc013 if direct transfer aborted.
+ *
+ * Return values: Some PTP_RC_* code.
+ *
+ **/
+uint16_t
+ptp_canon_initiate_direct_transfer (PTPParams* params, uint32_t *out)
+{
+	PTPContainer ptp;
+	uint16_t ret;
+
+	PTP_CNT_INIT(ptp);
+	ptp.Code   = PTP_OC_CANON_InitiateDirectTransferEx2;
+	ptp.Nparam = 1;
+	ptp.Param1 = 0xf;
+	ret = ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
+	if ((ret == PTP_RC_OK) && (ptp.Nparam>0))
+		*out = ptp.Param1;
+	return ret;
+}
+
+/**
+ * ptp_canon_get_target_handles:
+ * params:	PTPParams*
+ *              PTPCanon_directtransfer_entry **out
+ *              unsigned int *outsize
+ * 
+ * Retrieves direct transfer entries specifying the images to transfer
+ * from the camera (to be retrieved after 0xc011 event).
+ *
+ * Return values: Some PTP_RC_* code.
+ *
+ **/
+uint16_t
+ptp_canon_get_target_handles (PTPParams* params,
+	PTPCanon_directtransfer_entry **entries, unsigned int *cnt)
+{
+	PTPContainer ptp;
+	uint16_t ret;
+	unsigned char *out = NULL, *cur;
+	int i;
+	unsigned int size;
+	
+	PTP_CNT_INIT(ptp);
+	ptp.Code   = PTP_OC_CANON_GetTargetHandles;
+	ptp.Nparam = 0;
+	ret = ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &out, &size);
+	if (ret != PTP_RC_OK)
+		return ret;
+	*cnt = dtoh32a(out);
+	*entries = malloc(sizeof(PTPCanon_directtransfer_entry)*(*cnt));
+	cur = out+4;
+	for (i=0;i<*cnt;i++) {
+		unsigned char len;
+		(*entries)[i].oid = dtoh32a(cur);
+		(*entries)[i].str = ptp_unpack_string(params, cur, 4, &len);
+		cur += 4+(cur[4]*2+1);
+	}
+	free (out);
+	return PTP_RC_OK;
+}
+/**
  * ptp_canon_endshootingmode:
  * params:	PTPParams*
  * 
@@ -1429,26 +1597,23 @@
 }
 
 /**
- * ptp_canon_reflectchanges:
+ * ptp_canon_aeafawb:
  * params:	PTPParams*
  * 		uint32_t p1 	- Yet unknown parameter,
  * 				  value 7 works
  * 
- * Make viewfinder reflect changes.
- * There is a button for this operation in the Remote Capture app.
- * What it does exactly I don't know. This operation is followed
- * by the CANON_GetChanges(?) operation in the log.
+ * Called AeAfAwb (auto exposure, focus, white balance)
  *
  * Return values: Some PTP_RC_* code.
  *
  **/
 uint16_t
-ptp_canon_reflectchanges (PTPParams* params, uint32_t p1)
+ptp_canon_aeafawb (PTPParams* params, uint32_t p1)
 {
 	PTPContainer ptp;
 	
 	PTP_CNT_INIT(ptp);
-	ptp.Code=PTP_OC_CANON_ReflectChanges;
+	ptp.Code=PTP_OC_CANON_DoAeAfAwb;
 	ptp.Param1=p1;
 	ptp.Nparam=1;
 	return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
@@ -1614,7 +1779,7 @@
 	unsigned int len;
 	
 	PTP_CNT_INIT(ptp);
-	ptp.Code=PTP_OC_CANON_GetPartialObject;
+	ptp.Code=PTP_OC_CANON_GetPartialObjectEx;
 	ptp.Param1=handle;
 	ptp.Param2=offset;
 	ptp.Param3=size;
@@ -1697,7 +1862,7 @@
 }
 
 /**
- * ptp_canon_getfolderentries:
+ * ptp_canon_getobjectinfo:
  *
  * This command reads a specified object's record in a device's filesystem,
  * or the records of all objects belonging to a specified folder (association).
@@ -1720,7 +1885,7 @@
  *
  **/
 uint16_t
-ptp_canon_getfolderentries (PTPParams* params, uint32_t store, uint32_t p2, 
+ptp_canon_getobjectinfo (PTPParams* params, uint32_t store, uint32_t p2, 
 			    uint32_t parent, uint32_t handle, 
 			    PTPCANONFolderEntry** entries, uint32_t* entnum)
 {
@@ -1730,7 +1895,7 @@
 	unsigned int len;
 	
 	PTP_CNT_INIT(ptp);
-	ptp.Code=PTP_OC_CANON_GetFolderEntries;
+	ptp.Code=PTP_OC_CANON_GetObjectInfoEx;
 	ptp.Param1=store;
 	ptp.Param2=p2;
 	ptp.Param3=parent;
@@ -1756,7 +1921,7 @@
 }
 
 /**
- * ptp_canon_lookup_object:
+ * ptp_canon_get_objecthandle_by_name:
  *
  * This command looks up the specified object on the camera.
  *
@@ -1773,7 +1938,7 @@
  *
  **/
 uint16_t
-ptp_canon_lookup_object (PTPParams* params, char* name, uint32_t* objectid)
+ptp_canon_get_objecthandle_by_name (PTPParams* params, char* name, uint32_t* objectid)
 {
 	uint16_t ret;
 	PTPContainer ptp;
@@ -1781,7 +1946,7 @@
 	uint8_t len;
 
 	PTP_CNT_INIT (ptp);
-	ptp.Code=PTP_OC_CANON_LookupObject;
+	ptp.Code=PTP_OC_CANON_GetObjectHandleByName;
 	ptp.Nparam=0;
 	len=0;
 	data = malloc (2*(strlen(name)+1)+2);
@@ -1794,7 +1959,7 @@
 }
 
 /**
- * ptp_canon_theme_download:
+ * ptp_canon_get_customize_data:
  *
  * This command downloads the specified theme slot, including jpegs
  * and wav files.
@@ -1808,7 +1973,7 @@
  *
  **/
 uint16_t
-ptp_canon_theme_download (PTPParams* params, uint32_t themenr,
+ptp_canon_get_customize_data (PTPParams* params, uint32_t themenr,
 		unsigned char **data, unsigned int *size)
 {
 	PTPContainer ptp;
@@ -1816,7 +1981,7 @@
 	*data = NULL;
 	*size = 0;
 	PTP_CNT_INIT(ptp);
-	ptp.Code	= PTP_OC_CANON_ThemeDownload;
+	ptp.Code	= PTP_OC_CANON_GetCustomizeData;
 	ptp.Param1	= themenr;
 	ptp.Nparam	= 1;
 	return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, data, size); 
@@ -3255,6 +3420,82 @@
 }
 
 struct {
+	uint16_t opcode;
+	const char *name;
+} ptp_opcode_trans[] = {
+	{PTP_OC_Undefined,N_("Undefined")},
+	{PTP_OC_GetDeviceInfo,N_("get device info")},
+	{PTP_OC_OpenSession,N_("Open session")},
+	{PTP_OC_CloseSession,N_("Close session")},
+	{PTP_OC_GetStorageIDs,N_("Get storage IDs")},
+	{PTP_OC_GetStorageInfo,N_("Get storage info")},
+	{PTP_OC_GetNumObjects,N_("Get number of objects")},
+	{PTP_OC_GetObjectHandles,N_("Get object handles")},
+	{PTP_OC_GetObjectInfo,N_("Get object info")},
+	{PTP_OC_GetObject,N_("Get object")},
+	{PTP_OC_GetThumb,N_("Get thumbnail")},
+	{PTP_OC_DeleteObject,N_("Delete object")},
+	{PTP_OC_SendObjectInfo,N_("Send object info")},
+	{PTP_OC_SendObject,N_("Send object")},
+	{PTP_OC_InitiateCapture,N_("Initiate capture")},
+	{PTP_OC_FormatStore,N_("Format storage")},
+	{PTP_OC_ResetDevice,N_("Reset device")},
+	{PTP_OC_SelfTest,N_("Self test device")},
+	{PTP_OC_SetObjectProtection,N_("Set object protection")},
+	{PTP_OC_PowerDown,N_("Power down device")},
+	{PTP_OC_GetDevicePropDesc,N_("Get device property description")},
+	{PTP_OC_GetDevicePropValue,N_("Get device property value")},
+	{PTP_OC_SetDevicePropValue,N_("Set device property value")},
+	{PTP_OC_ResetDevicePropValue,N_("Reset device property value")},
+	{PTP_OC_TerminateOpenCapture,N_("Terminate open capture")},
+	{PTP_OC_MoveObject,N_("Move object")},
+	{PTP_OC_CopyObject,N_("Copy object")},
+	{PTP_OC_GetPartialObject,N_("Get partial object")},
+	{PTP_OC_InitiateOpenCapture,N_("Initiate open capture")}
+};
+
+struct {
+	uint16_t opcode;
+	const char *name;
+} ptp_opcode_mtp_trans[] = {
+	{PTP_OC_MTP_GetObjectPropsSupported,N_("Get object properties supported")},
+	{PTP_OC_MTP_GetObjectPropDesc,N_("Get object property description")},
+	{PTP_OC_MTP_GetObjectPropValue,N_("Get object property value")},
+	{PTP_OC_MTP_SetObjectPropValue,N_("Set object property value")},
+	{PTP_OC_MTP_GetObjPropList,N_("Get object property list")},
+	{PTP_OC_MTP_SetObjPropList,N_("Set object property list")},
+	{PTP_OC_MTP_GetInterdependendPropdesc,N_("Get interdependent property description")},
+	{PTP_OC_MTP_SendObjectPropList,N_("Send object property list")},
+	{PTP_OC_MTP_GetObjectReferences,N_("Get object references")},
+	{PTP_OC_MTP_SetObjectReferences,N_("Set object references")},
+	{PTP_OC_MTP_UpdateDeviceFirmware,N_("Update device firmware")},
+	{PTP_OC_MTP_Skip,N_("Skip to next position in playlist")}
+};
+
+int
+ptp_render_opcode(PTPParams* params, uint16_t opcode, int spaceleft, char *txt)
+{
+	int i;
+
+	if (!(opcode & 0x8000)) {
+		for (i=0;i<sizeof(ptp_opcode_trans)/sizeof(ptp_opcode_trans[0]);i++)
+			if (opcode == ptp_opcode_trans[i].opcode)
+				return snprintf(txt, spaceleft,_(ptp_opcode_trans[i].name));
+	} else {
+		switch (params->deviceinfo.VendorExtensionID) {
+		case PTP_VENDOR_MICROSOFT:
+			for (i=0;i<sizeof(ptp_opcode_mtp_trans)/sizeof(ptp_opcode_mtp_trans[0]);i++)
+				if (opcode == ptp_opcode_mtp_trans[i].opcode)
+					return snprintf(txt, spaceleft,_(ptp_opcode_mtp_trans[i].name));
+			break;
+		default:break;
+		}
+	}
+	return snprintf (txt, spaceleft,_("Unknown(%04x)"), opcode);
+}
+
+
+struct {
 	uint16_t id;
 	const char *name;
 } ptp_opc_trans[] = {
diff --git a/src/ptp.h b/src/ptp.h
index c7fed0c..93dda32 100644
--- a/src/ptp.h
+++ b/src/ptp.h
@@ -92,6 +92,11 @@
 };
 typedef struct _PTPUSBEventContainer PTPUSBEventContainer;
 
+struct _PTPCanon_directtransfer_entry {
+	uint32_t	oid;
+	char		*str;
+};
+typedef struct _PTPCanon_directtransfer_entry PTPCanon_directtransfer_entry;
 
 /* USB container types */
 
@@ -176,47 +181,63 @@
 #define PTP_OC_EK_SetText		0x9008
 
 /* Canon extension Operation Codes */
-#define PTP_OC_CANON_GetObjectSize	0x9001
-#define PTP_OC_CANON_9002		0x9002
+#define PTP_OC_CANON_GetPartialObjectInfo	0x9001
+#define PTP_OC_CANON_SetObjectArchive		0x9002
 /* 9002 - sends 2 uint32, nothing back  */
-#define PTP_OC_CANON_9003		0x9003
+#define PTP_OC_CANON_9003			0x9003
 /* 9003 - sends nothing, nothing back  */
 /* no 9004 observed yet */
 /* no 9005 observed yet */
-#define PTP_OC_CANON_LookupObject	0x9006
+#define PTP_OC_CANON_GetObjectHandleByName	0x9006
 /* no 9007 observed yet */
-#define PTP_OC_CANON_StartShootingMode	0x9008
-#define PTP_OC_CANON_EndShootingMode	0x9009
+#define PTP_OC_CANON_StartShootingMode		0x9008
+#define PTP_OC_CANON_EndShootingMode		0x9009
 /* 900a - sends nothing, nothing back */
-#define PTP_OC_CANON_900a		0x900A
-#define PTP_OC_CANON_ViewfinderOn	0x900B
-#define PTP_OC_CANON_ViewfinderOff	0x900C
-#define PTP_OC_CANON_ReflectChanges	0x900D
+#define PTP_OC_CANON_900a			0x900A
+#define PTP_OC_CANON_ViewfinderOn		0x900B
+#define PTP_OC_CANON_ViewfinderOff		0x900C
+#define PTP_OC_CANON_DoAeAfAwb			0x900D
 
-/* 900e - send nothing, gets 5 uint16t in 32bit entities back in 20byte datablob 
- * GetFlashDevParam?
- */
-#define PTP_OC_CANON_900e		0x900E
-/* 900f - gets data ... hmm, object handles ? */
-#define PTP_OC_CANON_900f		0x900F
-
-#define PTP_OC_CANON_ThemeDownload	0x9010
-#define PTP_OC_CANON_ThemeUpload	0x9011
+/* 900e - send nothing, gets 5 uint16t in 32bit entities back in 20byte datablob */
+#define PTP_OC_CANON_GetCustomizeSpec		0x900E
+#define PTP_OC_CANON_GetCustomizeItemInfo	0x900F
+#define PTP_OC_CANON_GetCustomizeData		0x9010
+#define PTP_OC_CANON_SetCustomizeData		0x9011
 
 /* initiate movie capture:
    9010 startmoviecapture?
    9003 stopmoviecapture?
 */
 
-#define PTP_OC_CANON_CheckEvent		0x9013
-#define PTP_OC_CANON_FocusLock		0x9014
-#define PTP_OC_CANON_FocusUnlock	0x9015
+#define PTP_OC_CANON_CheckEvent			0x9013
+#define PTP_OC_CANON_FocusLock			0x9014
+#define PTP_OC_CANON_FocusUnlock		0x9015
 #define PTP_OC_CANON_InitiateCaptureInMemory	0x901A
-#define PTP_OC_CANON_GetPartialObject	0x901B
-#define PTP_OC_CANON_GetViewfinderImage	0x901d
-	/* Viewfinder Auto functions */
-#define PTP_OC_CANON_GetChanges		0x9020
-#define PTP_OC_CANON_GetFolderEntries	0x9021
+#define PTP_OC_CANON_GetPartialObjectEx		0x901B
+#define PTP_OC_CANON_SetObjectTime		0x901C
+#define PTP_OC_CANON_GetViewfinderImage		0x901D
+#define PTP_OC_CANON_ChangeUSBProtocol		0x901F
+#define PTP_OC_CANON_GetChanges			0x9020
+#define PTP_OC_CANON_GetObjectInfoEx		0x9021
+
+#define PTP_OC_CANON_TerminateDirectTransfer 	0x9023
+
+#define PTP_OC_CANON_InitiateDirectTransferEx2 	0x9028
+#define PTP_OC_CANON_GetTargetHandles 		0x9029
+#define PTP_OC_CANON_NotifyProgress 		0x902A
+#define PTP_OC_CANON_NotifyCancelAccepted	0x902B
+/* 902c: no parms, read 3 uint32 in data, no response parms */
+#define PTP_OC_CANON_902C			0x902C
+#define PTP_OC_CANON_GetDirectory		0x902D
+
+#define PTP_OC_CANON_SetPairingInfo		0x9030
+#define PTP_OC_CANON_GetPairingInfo		0x9031
+#define PTP_OC_CANON_DeletePairingInfo		0x9032
+#define PTP_OC_CANON_GetMACAddress		0x9033
+/* 9034: 1 param, no parms returned */
+#define PTP_OC_CANON_SetDisplayMonitor		0x9034
+#define PTP_OC_CANON_PairingComplete		0x9035
+#define PTP_OC_CANON_GetWirelessMAXChannel	0x9036
 
 /* Nikon extension Operation Codes */
 #define PTP_OC_NIKON_GetProfileAllData	0x9006
@@ -335,6 +356,9 @@
 #define PTP_EC_CANON_RequestObjectTransfer	0xC009
 #define PTP_EC_CANON_CameraModeChanged		0xC00C
 
+#define PTP_EC_CANON_StartDirectTransfer	0xC011
+#define PTP_EC_CANON_StopDirectTransfer		0xC013
+
 /* Nikon extension Event Codes */
 #define PTP_EC_Nikon_ObjectAddedInSDRAM		0xC101
 /* Gets 1 parameter, objectid pointing to DPOF object */
@@ -348,7 +372,7 @@
 /* PTP device info structure (returned by GetDevInfo) */
 
 struct _PTPDeviceInfo {
-	uint16_t StaqndardVersion;
+	uint16_t StandardVersion;
 	uint32_t VendorExtensionID;
 	uint16_t VendorExtensionVersion;
 	char	*VendorExtensionDesc;
@@ -546,7 +570,6 @@
 
 union _PTPPropertyValue {
 	char		*str;	/* common string, malloced */
-	uint16_t        *unistr; /* UCS2 unicode string, malloced */
 	uint8_t		u8;
 	int8_t		i8;
 	uint16_t	u16;
@@ -1097,6 +1120,9 @@
 	PTPObjectInfo * objectinfo;
 	PTPDeviceInfo deviceinfo;
 
+	/* Canon specific flags list */
+	uint32_t	*canon_flags; /* size(handles.n) */
+
 	/* Wifi profiles */
 	uint8_t  wifi_profiles_version;
 	uint8_t  wifi_profiles_number;
@@ -1213,16 +1239,19 @@
 
 /* Canon PTP extensions */
 uint16_t ptp_canon_9012 (PTPParams* params);
-uint16_t ptp_canon_getobjectsize (PTPParams* params, uint32_t handle,
+uint16_t ptp_canon_initiate_direct_transfer (PTPParams* params, uint32_t* out);
+uint16_t ptp_canon_get_target_handles (PTPParams* params, PTPCanon_directtransfer_entry**, unsigned int*cnt);
+uint16_t ptp_canon_getpartialobjectinfo (PTPParams* params, uint32_t handle,
 				uint32_t p2, uint32_t* size, uint32_t* rp2);
 
+uint16_t ptp_canon_get_mac_address (PTPParams* params, unsigned char **mac);
 uint16_t ptp_canon_startshootingmode (PTPParams* params);
 uint16_t ptp_canon_endshootingmode (PTPParams* params);
 
 uint16_t ptp_canon_viewfinderon (PTPParams* params);
 uint16_t ptp_canon_viewfinderoff (PTPParams* params);
 
-uint16_t ptp_canon_reflectchanges (PTPParams* params, uint32_t p1);
+uint16_t ptp_canon_aeafawb (PTPParams* params, uint32_t p1);
 uint16_t ptp_canon_checkevent (PTPParams* params, 
 				PTPUSBEventContainer* event, int* isevent);
 uint16_t ptp_canon_focuslock (PTPParams* params);
@@ -1236,15 +1265,18 @@
 				uint32_t* size);
 uint16_t ptp_canon_getchanges (PTPParams* params, uint16_t** props,
 				uint32_t* propnum); 
-uint16_t ptp_canon_getfolderentries (PTPParams* params, uint32_t store,
+uint16_t ptp_canon_getobjectinfo (PTPParams* params, uint32_t store,
 				uint32_t p2, uint32_t parenthandle,
 				uint32_t handle, 
 				PTPCANONFolderEntry** entries,
 				uint32_t* entnum);
-uint16_t ptp_canon_lookup_object (PTPParams* params, char* name, uint32_t* objectid);
-uint16_t ptp_canon_theme_download (PTPParams* params, uint32_t themenr,
+uint16_t ptp_canon_get_objecthandle_by_name (PTPParams* params, char* name, uint32_t* objectid);
+uint16_t ptp_canon_get_directory (PTPParams* params, PTPObjectHandles *handles, PTPObjectInfo **oinfos, uint32_t **flags);
+uint16_t ptp_canon_setobjectarchive (PTPParams* params, uint32_t oid, uint32_t flags);
+uint16_t ptp_canon_get_customize_data (PTPParams* params, uint32_t themenr,
 				unsigned char **data, unsigned int *size);
 
+
 uint16_t ptp_nikon_curve_download (PTPParams* params, 
 				unsigned char **data, unsigned int *size);
 uint16_t ptp_nikon_getptpipinfo (PTPParams* params, unsigned char **data, unsigned int *size);
@@ -1276,6 +1308,7 @@
 ptp_render_property_value(PTPParams* params, uint16_t dpc,
                           PTPDevicePropDesc *dpd, int length, char *out);
 int ptp_render_ofc(PTPParams* params, uint16_t ofc, int spaceleft, char *txt);
+int ptp_render_opcode(PTPParams* params, uint16_t opcode, int spaceleft, char *txt);
 int ptp_render_mtp_propname(uint16_t propid, int spaceleft, char *txt);
 
 /* ptpip.c */