Sync to upstream.
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[] = {